Example #1
0
int 
main() {
  /* see http://www.ietf.org/mail-archive/web/tls/current/msg03416.html */
  unsigned char key[] = { 0x9b, 0xbe, 0x43, 0x6b, 0xa9, 0x40, 0xf0, 0x17, 
			  0xb1, 0x76, 0x52, 0x84, 0x9a, 0x71, 0xdb, 0x35 };
  unsigned char label[] = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x61, 0x62, 
			    0x65, 0x6c};
  unsigned char random1[] = { 0xa0, 0xba, 0x9f, 0x93, 0x6c, 0xda, 0x31, 0x18};
  unsigned char random2[] = {0x27, 0xa6, 0xf7, 0x96, 0xff, 0xd5, 0x19, 0x8c
  };
  unsigned char buf[200];
  size_t result;
  
  result = dtls_prf(key, sizeof(key),
		    label, sizeof(label),
		    random1, sizeof(random1),
		    random2, sizeof(random2),
		    buf, 100);

  printf("PRF yields %zu bytes of random data:\n", result);
  hexdump(buf, result);
  printf("\n");
  return 0;
}
Example #2
0
void
handle_packet(const u_char *packet, int length) {
  static int n = 0;
  static unsigned char initial_hello[] = { 
    0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
  };
  uint8 *data; 
  size_t data_length, rlen;
  int i, res;
#if DTLS_VERSION == 0xfeff
#ifndef SHA1_DIGEST_LENGTH
#define SHA1_DIGEST_LENGTH 20
#endif
  uint8 hash_buf[16 + SHA1_DIGEST_LENGTH];
#elif DTLS_VERSION == 0xfefd
  uint8 hash_buf[DTLS_SHA256_DIGEST_LENGTH];
#endif
#define verify_data_length 12
  int is_client;
  n++;

  SKIP_ETH_HEADER(packet, length);
  SKIP_IP_HEADER(packet, length);

  /* determine from port if this is a client */
  is_client = dtls_uint16_to_int(packet) != 20220;

  SKIP_UDP_HEADER(packet, length);

  while (length) {
    rlen = dtls_uint16_to_int(packet + 11) + sizeof(dtls_record_header_t);

    if (!rlen) {
      fprintf(stderr, "invalid length!\n");
      return;
    }

    /* skip packet if it is from a different epoch */
    if (dtls_uint16_to_int(packet + 3) != epoch[is_client])
      goto next;

    res = decrypt_verify(is_client, packet, rlen,
			 &data, &data_length);

    if (res <= 0)
      goto next;
    
    printf("packet %d (from %s):\n", n, is_client ? "client" : "server");
    hexdump(packet, sizeof(dtls_record_header_t));
    printf("\n");
    hexdump(data, data_length);
    printf("\n");
    
    if (packet[0] == 22 && data[0] == 1) { /* ClientHello */
      if (memcmp(packet, initial_hello, sizeof(initial_hello)) == 0)
	goto next;
	
      memcpy(dtls_kb_client_iv(OTHER_CONFIG), data + 14, 32);

	clear_hash();
#if DTLS_VERSION == 0xfeff
      hs_hash[0] = dtls_new_hash(HASH_MD5);
      hs_hash[1] = dtls_new_hash(HASH_SHA1);

      hs_hash[0]->init(hs_hash[0]->data);
      hs_hash[1]->init(hs_hash[1]->data);
#elif DTLS_VERSION == 0xfefd
      dtls_hash_init(hs_hash[0]);
#endif
    }
    
    if (packet[0] == 22 && data[0] == 2) { /* ServerHello */
      memcpy(dtls_kb_server_iv(OTHER_CONFIG), data + 14, 32);
      /* FIXME: search in ciphers */
      OTHER_CONFIG->cipher = TLS_PSK_WITH_AES_128_CCM_8;
    }
    
    if (packet[0] == 20 && data[0] == 1) { /* ChangeCipherSpec */
      printf("client random: ");
      dump(dtls_kb_client_iv(OTHER_CONFIG), 32);
      printf("\nserver random: ");
      dump(dtls_kb_server_iv(OTHER_CONFIG), 32);
      printf("\n");
      master_secret_len = 
	dtls_prf(pre_master_secret, pre_master_len,
		 (unsigned char *)"master secret", 13,
		 dtls_kb_client_iv(OTHER_CONFIG), 32,
		 dtls_kb_server_iv(OTHER_CONFIG), 32,
		 master_secret, DTLS_MASTER_SECRET_LENGTH);
  
      printf("master_secret:\n  ");
      for(i = 0; i < master_secret_len; i++) 
	printf("%02x", master_secret[i]);
      printf("\n");

      /* create key_block from master_secret
       * key_block = PRF(master_secret,
                     "key expansion" + server_random + client_random) */
      dtls_prf(master_secret, master_secret_len,
	       (unsigned char *)"key expansion", 13,
	       dtls_kb_server_iv(OTHER_CONFIG), 32,
	       dtls_kb_client_iv(OTHER_CONFIG), 32,
	       OTHER_CONFIG->key_block, 
	       dtls_kb_size(OTHER_CONFIG));

      OTHER_CONFIG->read_cipher = 
	dtls_cipher_new(OTHER_CONFIG->cipher,
			dtls_kb_client_write_key(OTHER_CONFIG),
			dtls_kb_key_size(OTHER_CONFIG));

      if (!OTHER_CONFIG->read_cipher) {
	warn("cannot create read cipher\n");
      } else {
	dtls_cipher_set_iv(OTHER_CONFIG->read_cipher,
			   dtls_kb_client_iv(OTHER_CONFIG),
			   dtls_kb_iv_size(OTHER_CONFIG));
      }

      OTHER_CONFIG->write_cipher = 
	dtls_cipher_new(OTHER_CONFIG->cipher, 
			dtls_kb_server_write_key(OTHER_CONFIG),
			dtls_kb_key_size(OTHER_CONFIG));
      
      if (!OTHER_CONFIG->write_cipher) {
	warn("cannot create write cipher\n");
      } else {
	dtls_cipher_set_iv(OTHER_CONFIG->write_cipher,
			   dtls_kb_server_iv(OTHER_CONFIG),
			   dtls_kb_iv_size(OTHER_CONFIG));
      }

      /* if (is_client) */
	SWITCH_CONFIG;
      epoch[is_client]++;

      printf("key_block:\n");
      printf("  client_MAC_secret:\t");  
      dump(dtls_kb_client_mac_secret(CURRENT_CONFIG), 
	   dtls_kb_mac_secret_size(CURRENT_CONFIG));
      printf("\n");

      printf("  server_MAC_secret:\t");  
      dump(dtls_kb_server_mac_secret(CURRENT_CONFIG), 
	   dtls_kb_mac_secret_size(CURRENT_CONFIG));
      printf("\n");

      printf("  client_write_key:\t");  
      dump(dtls_kb_client_write_key(CURRENT_CONFIG), 
	   dtls_kb_key_size(CURRENT_CONFIG));
      printf("\n");

      printf("  server_write_key:\t");  
      dump(dtls_kb_server_write_key(CURRENT_CONFIG), 
	   dtls_kb_key_size(CURRENT_CONFIG));
      printf("\n");

      printf("  client_IV:\t\t");  
      dump(dtls_kb_client_iv(CURRENT_CONFIG), 
	   dtls_kb_iv_size(CURRENT_CONFIG));
      printf("\n");
      
      printf("  server_IV:\t\t");  
      dump(dtls_kb_server_iv(CURRENT_CONFIG), 
	   dtls_kb_iv_size(CURRENT_CONFIG));
      printf("\n");
      
    }

    if (packet[0] == 22) {
      if (data[0] == 20) { /* Finished */
	finalize_hash(hash_buf);
	/* clear_hash(); */

	update_hash((unsigned char *)packet, sizeof(dtls_record_header_t),
		    data, data_length);

	dtls_prf(master_secret, master_secret_len,
		 is_client 
		 ? (unsigned char *)"client finished" 
		 : (unsigned char *)"server finished" 
		 , 15,
		 hash_buf, sizeof(hash_buf),
		 NULL, 0,
		 data + sizeof(dtls_handshake_header_t),
		 verify_data_length);
	printf("verify_data:\n");
	dump(data, data_length);
	printf("\n");
      } else {
	update_hash((unsigned char *)packet, sizeof(dtls_record_header_t),
		    data, data_length);
      }
    }

    if (packet[0] == 23) {	/* Application Data */
      printf("Application Data:\n");
      dump(data, data_length);
      printf("\n");
    }

  next:
    length -= rlen;
    packet += rlen;
  }
}