Browse Source

fixed bug with Finished message hash: add old, unmodified hash to computation and re-encrypt all decrypted finished messages

cecylia 7 years ago
parent
commit
6b0bfac4f3
2 changed files with 45 additions and 25 deletions
  1. 32 0
      relay_station/crypto.c
  2. 13 25
      relay_station/flow.c

+ 32 - 0
relay_station/crypto.c

@@ -494,6 +494,12 @@ int verify_finish_hash(flow *f, uint8_t *hs, int32_t incoming){
 	struct handshake_header *hs_hdr;
 	hs_hdr = (struct handshake_header*) p;
 	uint32_t fin_length = HANDSHAKE_MESSAGE_LEN(hs_hdr);
+
+	//save old finished to update finished mac hash
+	uint8_t *old_finished = ecalloc(1, fin_length);
+	old_finished = malloc(fin_length+ HANDSHAKE_HEADER_LEN);
+	memcpy(old_finished, p, fin_length+HANDSHAKE_HEADER_LEN);
+	
 	p += HANDSHAKE_HEADER_LEN;
 
 	//finalize hash of handshake msgs (have not yet added this one)
@@ -515,6 +521,14 @@ int verify_finish_hash(flow *f, uint8_t *hs, int32_t incoming){
 		goto err;
 	}
 
+#ifdef DEBUG_HS
+	printf("Old finished:\n");
+	for(int i=0; i< fin_length; i++){
+		printf("%02x ", p[i]);
+	}
+	printf("\n");
+#endif
+
 	//now add extra input seeded with client-relay shared secret
 	if(incoming){
 		uint32_t extra_input_len = SSL3_RANDOM_SIZE;
@@ -538,10 +552,26 @@ int verify_finish_hash(flow *f, uint8_t *hs, int32_t incoming){
 		//replace existing MAC with modified one
 		memcpy(p, output, fin_length);
 
+#ifdef DEBUG_HS
+		printf("New finished:\n");
+		for(int i=0; i< fin_length; i++){
+			printf("%02x ", p[i]);
+		}
+		printf("\n");
+#endif
+
 		free(extra_input);
 
 	}
 
+	if(update_finish_hash(f, old_finished)){
+		fprintf(stderr, "Error updating finish hash with FINISHED msg\n");
+		remove_flow(f);
+		goto err;
+	}
+
+	free(old_finished);
+
 	free(output);
 	EVP_MD_CTX_cleanup(&ctx);
 	return 0;
@@ -549,6 +579,8 @@ int verify_finish_hash(flow *f, uint8_t *hs, int32_t incoming){
 err:
 	if(output != NULL)
 		free(output);
+	if(old_finished != NULL)
+		free(old_finished);
 	EVP_MD_CTX_cleanup(&ctx);
 	return 1;
 }

+ 13 - 25
relay_station/flow.c

@@ -353,31 +353,24 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 #endif
 					verify_finish_hash(f,p, incoming);
 					
-					if(update_finish_hash(f, p)){
-						fprintf(stderr, "Error updating finish hash with FINISHED msg\n");
-						remove_flow(f);
-						goto err;
-					}
-
 					//re-encrypt finished message
-					if(incoming){
-						//revert the sequence number
-						memset(f->read_seq, 0, 8);
 
-						int32_t n =  encrypt(f, record+RECORD_HEADER_LEN, record+RECORD_HEADER_LEN, record_len - (RECORD_HEADER_LEN+16), incoming, 0x16, 1);
+					//revert the sequence number
+					memset(f->read_seq, 0, 8);
+
+					int32_t n =  encrypt(f, record+RECORD_HEADER_LEN, record+RECORD_HEADER_LEN, record_len - (RECORD_HEADER_LEN+16), incoming, 0x16, 1);
 
 #ifdef HS_DEBUG
-						printf("New finished ciphertext:\n");
-						for(int i=0; i< record_len; i++){
-							printf("%02x ", record[i]);
-						}
-						printf("\n");
+					printf("New finished ciphertext:\n");
+					for(int i=0; i< record_len; i++){
+						printf("%02x ", record[i]);
+					}
+					printf("\n");
 #endif
 
-						if(n<=0){
-							printf("Error re-encrypting finished  (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port),
-									f->dst_ip.s_addr, ntohs(f->dst_port));
-						}
+					if(n<=0){
+						printf("Error re-encrypting finished  (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port),
+								f->dst_ip.s_addr, ntohs(f->dst_port));
 					}
 
 					if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
@@ -585,11 +578,7 @@ int remove_flow(flow *f) {
  *  	observed: details for the observed flow
  *
  *  Output:
- *  	index of flow in table or -1 if it doesn't exist
-	new_flow->src_ip = info->ip_hdr->src;
-	new_flow->dst_ip = info->ip_hdr->dst;
-	new_flow->src_port = info->tcp_hdr->src_port;
-	new_flow->dst_port = info->tcp_hdr->dst_port;
+ *  	flow struct from table or NULL if it doesn't exist
  */
 flow *check_flow(struct packet_info *info){
 	/* Loop through flows in table and see if it exists */
@@ -1068,7 +1057,6 @@ int add_packet(flow *f, struct packet_info *info){
 					
 					if(f->application == 1){
 						//update packet info and send to replace_packet
-						printf("Packet contains application data!\n");
 						struct packet_info *copy_info = copy_packet_info(info);
 						copy_info->app_data = record;
 						copy_info->app_data_len = record_len;