Browse Source

added code to check for Extended Master Secret extension

cecylia 7 years ago
parent
commit
0333e8e3f7
3 changed files with 66 additions and 12 deletions
  1. 3 4
      relay_station/crypto.c
  2. 60 7
      relay_station/flow.c
  3. 3 1
      relay_station/flow.h

+ 3 - 4
relay_station/crypto.c

@@ -657,8 +657,8 @@ int compute_master_secret(flow *f){
 		PRF(f, f->key, 16, (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
 				NULL, 0, NULL, 0, NULL, 0, buf, bytes);
 
-#ifdef DEBUG
-		printf("Generated the following rand bytes: ");
+#ifdef DEBUG_HS
+		printf("Generated the client private key [len: %d]: ", bytes);
 		for(int i=0; i< bytes; i++){
 			printf("%02x ", buf[i]);
 		}
@@ -691,7 +691,6 @@ int compute_master_secret(flow *f){
 		if(pre_master_len <= 0) {
 			goto err;
 		}
-
 	}
 
 	/*Generate master secret */
@@ -702,7 +701,7 @@ int compute_master_secret(flow *f){
 		memcpy(f->current_session->master_secret, f->master_secret, SSL3_MASTER_SECRET_SIZE);
 	}
 
-#ifdef DEBUG
+#ifdef DEBUG_HS
 	fprintf(stdout, "Premaster Secret:\n");
 	BIO_dump_fp(stdout, (char *)pre_master_secret, pre_master_len);
 	fprintf(stdout, "Client Random:\n");

+ 60 - 7
relay_station/flow.c

@@ -106,6 +106,7 @@ flow *add_flow(struct packet_info *info) {
 	new_flow->out_encrypted = 0;
 	new_flow->application = 0;
 	new_flow->stall = 0;
+	new_flow->extended_master_secret = 0;
 	new_flow->resume_session = 0;
 	new_flow->current_session = NULL;
 
@@ -250,7 +251,7 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 #ifdef DEBUG_HS
 					printf("Received tagged client hello (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
 #endif
-					if(check_session(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr))){
+					if(check_extensions(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr))){
 						fprintf(stderr, "Error checking session, might cause problems\n");
 					}
 
@@ -268,6 +269,11 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 							fprintf(stderr, "Failed to save session id\n");
 						}
 					}
+                                        
+                                        if(verify_extensions(f,p, HANDSHAKE_MESSAGE_LEN(handshake_hdr))){
+                                            fprintf(stderr, "Failed to verify extensions\n");
+                                        }
+
 					if(extract_server_random(f, p)){
 						fprintf(stderr, "Failed to extract server random nonce\n");
 						remove_flow(f);
@@ -296,11 +302,6 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 #endif
 					if(extract_parameters(f, p)){
 						printf("Error extracting params\n");
-                                                printf("Message:\n");
-                                                for(int i=0; i< RECORD_LEN(record_hdr); i++){
-                                                    printf("%02x ", p[i]);
-                                                }
-                                                printf("\n");
 						remove_flow(f);
 						goto err;
 					}
@@ -805,7 +806,7 @@ int verify_session_id(flow *f, uint8_t *hs){
  *  Output:
  *  	0 if success, 1 if failed
  */
-int check_session(flow *f, uint8_t *hs, uint32_t len){
+int check_extensions(flow *f, uint8_t *hs, uint32_t len){
 
 	uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
 	p += 2; //skip version
@@ -866,6 +867,10 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
 				f->current_session = new_session;
 			}
 		}
+                if(type == 0x17){//Extended Master Secret
+                    f->extended_master_secret = 1;
+                    printf("Extended master secret extension\n");
+                }
 		p += ext_len;
 		extensions_len -= (4 + ext_len);
 	}
@@ -878,6 +883,54 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
 	return 0;
 }
 	
+/* Called from ServerHello. Cycles through extensions and verifies their use
+ * in the flow.
+ *
+ *  Input:
+ *  	f: the tagged flow
+ *  	hs: a pointer to the ServerHello message
+ *
+ *  Output:
+ *  	0 if success, 1 if failed
+ */
+int verify_extensions(flow *f, uint8_t *hs, uint32_t len){
+
+    uint8_t extended_master_secret = 0;
+    uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
+
+    p += 2; //skip version
+    p += SSL3_RANDOM_SIZE; //skip random
+
+    p += (uint8_t) p[0] + 1; //skip session id
+
+    p += 2; //skip cipher suite
+
+    p ++; //skip compression method
+
+    //cycle through extensions
+    uint16_t extensions_len = (p[0] << 8) + p[1];
+    p += 2;
+    while(extensions_len > 0){
+        uint16_t type = (p[0] << 8) + p[1];
+        p += 2;
+        uint16_t ext_len = (p[0] << 8) + p[1];
+        p += 2;
+
+        if(type == 0x17){
+            extended_master_secret = 1;
+        }
+        p += ext_len;
+        extensions_len -= (4 + ext_len);
+    }
+
+    //Check to make sure both client and server included extension
+    if(!f->extended_master_secret || !extended_master_secret){
+        f->extended_master_secret = 0;
+    }
+
+    return 0;
+
+}
 
 /* Called from ServerHello during full handshake. Adds the session id to the
  * cache for later resumptions

+ 3 - 1
relay_station/flow.h

@@ -168,6 +168,7 @@ typedef struct flow_st {
 	const EVP_CIPHER *cipher;
 	const EVP_MD *message_digest;
 	uint8_t keyex_alg;
+        uint8_t extended_master_secret;
 	uint8_t handshake_hash[EVP_MAX_MD_SIZE];
 	EVP_CIPHER_CTX *clnt_read_ctx;
 	EVP_CIPHER_CTX *clnt_write_ctx;
@@ -223,7 +224,8 @@ flow *get_flow(int index);
 
 int init_session_cache (void);
 int verify_session_id(flow *f, uint8_t *hs);
-int check_session(flow *f, uint8_t *hs, uint32_t len);
+int check_extensions(flow *f, uint8_t *hs, uint32_t len);
+int verify_extensions(flow *f, uint8_t *hs, uint32_t len);
 int save_session_id(flow *f, uint8_t *hs);
 int save_session_ticket(flow *f, uint8_t *hs, uint32_t len);