|
@@ -1,3 +1,7 @@
|
|
|
|
+/* flow.c by Cecylia Bocovich <cbocovic@uwaterloo.ca>*/
|
|
|
|
+
|
|
|
|
+/* Defines and modifies the flow structure. */
|
|
|
|
+
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
@@ -9,6 +13,7 @@
|
|
#include "crypto.h"
|
|
#include "crypto.h"
|
|
#include "slitheen.h"
|
|
#include "slitheen.h"
|
|
#include "relay.h"
|
|
#include "relay.h"
|
|
|
|
+#include "util.h"
|
|
|
|
|
|
static flow_table *table;
|
|
static flow_table *table;
|
|
static session_cache *sessions;
|
|
static session_cache *sessions;
|
|
@@ -20,13 +25,13 @@ sem_t flow_table_lock;
|
|
/* Initialize the table of tagged flows */
|
|
/* Initialize the table of tagged flows */
|
|
int init_tables(void) {
|
|
int init_tables(void) {
|
|
|
|
|
|
- table = calloc(1, sizeof(flow_table));
|
|
|
|
|
|
+ table = emalloc(sizeof(flow_table));
|
|
table->first_entry = NULL;
|
|
table->first_entry = NULL;
|
|
table->len = 0;
|
|
table->len = 0;
|
|
|
|
|
|
sem_init(&flow_table_lock, 0, 1);
|
|
sem_init(&flow_table_lock, 0, 1);
|
|
|
|
|
|
- clients = calloc(1, sizeof(client_table));
|
|
|
|
|
|
+ clients = emalloc(sizeof(client_table));
|
|
clients->first = NULL;
|
|
clients->first = NULL;
|
|
printf("initialized downstream queue\n");
|
|
printf("initialized downstream queue\n");
|
|
|
|
|
|
@@ -36,13 +41,13 @@ int init_tables(void) {
|
|
|
|
|
|
/* Add a new flow to the tagged flow table */
|
|
/* Add a new flow to the tagged flow table */
|
|
flow *add_flow(struct packet_info *info) {
|
|
flow *add_flow(struct packet_info *info) {
|
|
- flow_entry *entry = calloc(1, sizeof(flow_entry));
|
|
|
|
- flow *new_flow = calloc(1, sizeof(flow));
|
|
|
|
|
|
+ flow_entry *entry = emalloc(sizeof(flow_entry));
|
|
|
|
+
|
|
|
|
+ flow *new_flow = emalloc(sizeof(flow));
|
|
|
|
+
|
|
entry->f = new_flow;
|
|
entry->f = new_flow;
|
|
entry->next = NULL;
|
|
entry->next = NULL;
|
|
|
|
|
|
- printf("there are %d flows in the table\n", table->len);
|
|
|
|
-
|
|
|
|
new_flow->src_ip = info->ip_hdr->src;
|
|
new_flow->src_ip = info->ip_hdr->src;
|
|
new_flow->dst_ip = info->ip_hdr->dst;
|
|
new_flow->dst_ip = info->ip_hdr->dst;
|
|
new_flow->src_port = info->tcp_hdr->src_port;
|
|
new_flow->src_port = info->tcp_hdr->src_port;
|
|
@@ -62,12 +67,14 @@ flow *add_flow(struct packet_info *info) {
|
|
new_flow->resume_session = 0;
|
|
new_flow->resume_session = 0;
|
|
new_flow->current_session = NULL;
|
|
new_flow->current_session = NULL;
|
|
|
|
|
|
- new_flow->us_packet_chain = calloc(1, sizeof(packet_chain));
|
|
|
|
|
|
+ new_flow->us_packet_chain = emalloc(sizeof(packet_chain));
|
|
|
|
+
|
|
new_flow->us_packet_chain->expected_seq_num = ntohl(info->tcp_hdr->sequence_num);
|
|
new_flow->us_packet_chain->expected_seq_num = ntohl(info->tcp_hdr->sequence_num);
|
|
new_flow->us_packet_chain->record_len = 0;
|
|
new_flow->us_packet_chain->record_len = 0;
|
|
new_flow->us_packet_chain->remaining_record_len = 0;
|
|
new_flow->us_packet_chain->remaining_record_len = 0;
|
|
new_flow->us_packet_chain->first_packet = NULL;
|
|
new_flow->us_packet_chain->first_packet = NULL;
|
|
- new_flow->ds_packet_chain = calloc(1, sizeof(packet_chain));
|
|
|
|
|
|
+ new_flow->ds_packet_chain = emalloc(sizeof(packet_chain));
|
|
|
|
+
|
|
new_flow->ds_packet_chain->expected_seq_num = ntohl(info->tcp_hdr->ack_num);
|
|
new_flow->ds_packet_chain->expected_seq_num = ntohl(info->tcp_hdr->ack_num);
|
|
new_flow->ds_packet_chain->record_len = 0;
|
|
new_flow->ds_packet_chain->record_len = 0;
|
|
new_flow->ds_packet_chain->remaining_record_len = 0;
|
|
new_flow->ds_packet_chain->remaining_record_len = 0;
|
|
@@ -117,6 +124,7 @@ flow *add_flow(struct packet_info *info) {
|
|
sem_post(&flow_table_lock);
|
|
sem_post(&flow_table_lock);
|
|
|
|
|
|
return new_flow;
|
|
return new_flow;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
/** Observes TLS handshake messages and updates the state of
|
|
/** Observes TLS handshake messages and updates the state of
|
|
@@ -145,19 +153,25 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
|
|
p += RECORD_HEADER_LEN;
|
|
p += RECORD_HEADER_LEN;
|
|
|
|
|
|
if((incoming && f->in_encrypted) || (!incoming && f->out_encrypted)){
|
|
if((incoming && f->in_encrypted) || (!incoming && f->out_encrypted)){
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Decrypting finished (%d bytes) (%x:%d -> %x:%d)\n", record_len - RECORD_HEADER_LEN, f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Decrypting finished (%d bytes) (%x:%d -> %x:%d)\n", record_len - RECORD_HEADER_LEN, f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
|
|
+#endif
|
|
int32_t n = encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x16, 0);
|
|
int32_t n = encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x16, 0);
|
|
if(n<=0){
|
|
if(n<=0){
|
|
printf("Error decrypting finished (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Error decrypting finished (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
}
|
|
}
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Finished decrypted: (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Finished decrypted: (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
|
|
+#endif
|
|
p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
|
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("record:\n");
|
|
printf("record:\n");
|
|
for(int i=0; i< n; i++){
|
|
for(int i=0; i< n; i++){
|
|
printf("%02x ", p[i]);
|
|
printf("%02x ", p[i]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
if(p[0] != 0x14){
|
|
if(p[0] != 0x14){
|
|
p[0] = 0x20; //trigger error
|
|
p[0] = 0x20; //trigger error
|
|
}
|
|
}
|
|
@@ -171,66 +185,160 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
|
|
|
|
|
|
switch(f->state){
|
|
switch(f->state){
|
|
case TLS_CLNT_HELLO:
|
|
case TLS_CLNT_HELLO:
|
|
|
|
+#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));
|
|
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));
|
|
- update_finish_hash(f, p);
|
|
|
|
- check_session(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr));
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish has with CLNT_HELLO msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if(check_session(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr))){
|
|
|
|
+ fprintf(stderr, "Error checking session, might cause problems\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_SERV_HELLO:
|
|
case TLS_SERV_HELLO:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received server hello (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Received server 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(f->resume_session){
|
|
if(f->resume_session){
|
|
- verify_session_id(f,p);
|
|
|
|
|
|
+ if(verify_session_id(f,p)){
|
|
|
|
+ fprintf(stderr, "Failed to verify session id\n");
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- save_session_id(f,p);
|
|
|
|
|
|
+ if(save_session_id(f,p)){
|
|
|
|
+ fprintf(stderr, "Failed to save session id\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(extract_server_random(f, p)){
|
|
|
|
+ fprintf(stderr, "Failed to extract server random nonce\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with SRVR_HELLO msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
- extract_server_random(f, p);
|
|
|
|
- update_finish_hash(f, p);
|
|
|
|
break;
|
|
break;
|
|
case TLS_NEW_SESS:
|
|
case TLS_NEW_SESS:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received new session\n");
|
|
printf("Received new session\n");
|
|
- save_session_ticket(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr));
|
|
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(save_session_ticket(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr))){
|
|
|
|
+ fprintf(stderr, "Failed to save session ticket\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with NEW_SESS msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_CERT:
|
|
case TLS_CERT:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received cert\n");
|
|
printf("Received cert\n");
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with CERT msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_SRVR_KEYEX:
|
|
case TLS_SRVR_KEYEX:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received server keyex\n");
|
|
printf("Received server keyex\n");
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with SRVR_KEYEX msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
|
|
if(extract_parameters(f, p)){
|
|
if(extract_parameters(f, p)){
|
|
printf("Error extracting params\n");
|
|
printf("Error extracting params\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
|
|
+
|
|
if(compute_master_secret(f)){
|
|
if(compute_master_secret(f)){
|
|
printf("Error computing master secret\n");
|
|
printf("Error computing master secret\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
break;
|
|
break;
|
|
|
|
+
|
|
case TLS_CERT_REQ:
|
|
case TLS_CERT_REQ:
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with CERT_REQ msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_SRVR_HELLO_DONE:
|
|
case TLS_SRVR_HELLO_DONE:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received server hello done\n");
|
|
printf("Received server hello done\n");
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with HELLO_DONE msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_CERT_VERIFY:
|
|
case TLS_CERT_VERIFY:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("received cert verify\n");
|
|
printf("received cert verify\n");
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with CERT_VERIFY msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
|
|
+
|
|
case TLS_CLNT_KEYEX:
|
|
case TLS_CLNT_KEYEX:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received client key exchange\n");
|
|
printf("Received client key exchange\n");
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+#endif
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with CLNT_KEYEX msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TLS_FINISHED:
|
|
case TLS_FINISHED:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Received finished (%d) (%x:%d -> %x:%d)\n", incoming, f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Received finished (%d) (%x:%d -> %x:%d)\n", incoming, f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
|
|
+#endif
|
|
verify_finish_hash(f,p, incoming);
|
|
verify_finish_hash(f,p, incoming);
|
|
- update_finish_hash(f, p);
|
|
|
|
|
|
+
|
|
|
|
+ if(update_finish_hash(f, p)){
|
|
|
|
+ fprintf(stderr, "Error updating finish hash with FINISHED msg\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
|
|
if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
|
|
printf("Handshake complete!\n");
|
|
printf("Handshake complete!\n");
|
|
f->application = 1;
|
|
f->application = 1;
|
|
}
|
|
}
|
|
|
|
+
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
printf("Error? (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Error? (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -238,10 +346,16 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
|
|
printf("Application Data (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("Application Data (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
break;
|
|
break;
|
|
case CCS:
|
|
case CCS:
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("CCS (%x:%d -> %x:%d) \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
printf("CCS (%x:%d -> %x:%d) \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
|
|
|
|
+#endif
|
|
/*Initialize ciphers */
|
|
/*Initialize ciphers */
|
|
if ((!f->in_encrypted) && (!f->out_encrypted)){
|
|
if ((!f->in_encrypted) && (!f->out_encrypted)){
|
|
- init_ciphers(f);
|
|
|
|
|
|
+ if(init_ciphers(f)){
|
|
|
|
+ fprintf(stderr, "Failed to initialize ciphers\n");
|
|
|
|
+ remove_flow(f);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if(incoming){
|
|
if(incoming){
|
|
@@ -269,10 +383,12 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
|
|
fflush(stdout);
|
|
fflush(stdout);
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
+ free(record);
|
|
|
|
+ return 0;
|
|
|
|
|
|
err:
|
|
err:
|
|
free(record);
|
|
free(record);
|
|
- return 0;
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
|
|
/** Removes the tagged flow from the flow table: happens when
|
|
/** Removes the tagged flow from the flow table: happens when
|
|
@@ -287,7 +403,9 @@ err:
|
|
int remove_flow(flow *f) {
|
|
int remove_flow(flow *f) {
|
|
|
|
|
|
EVP_MD_CTX_cleanup(f->finish_md_ctx);
|
|
EVP_MD_CTX_cleanup(f->finish_md_ctx);
|
|
- EVP_MD_CTX_destroy(f->finish_md_ctx);
|
|
|
|
|
|
+ if(f->finish_md_ctx != NULL){
|
|
|
|
+ EVP_MD_CTX_destroy(f->finish_md_ctx);
|
|
|
|
+ }
|
|
//Clean up cipher ctxs
|
|
//Clean up cipher ctxs
|
|
if(f->clnt_read_ctx != NULL){
|
|
if(f->clnt_read_ctx != NULL){
|
|
EVP_CIPHER_CTX_cleanup(f->clnt_read_ctx);
|
|
EVP_CIPHER_CTX_cleanup(f->clnt_read_ctx);
|
|
@@ -467,7 +585,8 @@ flow *check_flow(struct packet_info *info){
|
|
}
|
|
}
|
|
|
|
|
|
int init_session_cache(void){
|
|
int init_session_cache(void){
|
|
- sessions = malloc(sizeof(session_cache));
|
|
|
|
|
|
+ sessions = emalloc(sizeof(session_cache));
|
|
|
|
+
|
|
sessions->length = 0;
|
|
sessions->length = 0;
|
|
sessions->first_session = NULL;
|
|
sessions->first_session = NULL;
|
|
|
|
|
|
@@ -497,19 +616,22 @@ int verify_session_id(flow *f, uint8_t *hs){
|
|
//check to see if it matches flow's session id set by ClientHello
|
|
//check to see if it matches flow's session id set by ClientHello
|
|
if(f->current_session != NULL && f->current_session->session_id_len > 0 && !memcmp(f->current_session->session_id, p, id_len)){
|
|
if(f->current_session != NULL && f->current_session->session_id_len > 0 && !memcmp(f->current_session->session_id, p, id_len)){
|
|
//if it matched, update flow with master secret :D
|
|
//if it matched, update flow with master secret :D
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Session id matched!\n");
|
|
printf("Session id matched!\n");
|
|
printf("First session id (%p->%p):", sessions, sessions->first_session);
|
|
printf("First session id (%p->%p):", sessions, sessions->first_session);
|
|
|
|
+#endif
|
|
session *last = sessions->first_session;
|
|
session *last = sessions->first_session;
|
|
int found = 0;
|
|
int found = 0;
|
|
for(int i=0; ((i<sessions->length) && (!found)); i++){
|
|
for(int i=0; ((i<sessions->length) && (!found)); i++){
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Checking saved session id: ");
|
|
printf("Checking saved session id: ");
|
|
for (int j=0; j< last->session_id_len; j++){
|
|
for (int j=0; j< last->session_id_len; j++){
|
|
printf("%02x ", last->session_id[j]);
|
|
printf("%02x ", last->session_id[j]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
if(!memcmp(last->session_id, f->current_session->session_id, id_len)){
|
|
if(!memcmp(last->session_id, f->current_session->session_id, id_len)){
|
|
memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
- printf("Found session id number!\n");
|
|
|
|
found = 1;
|
|
found = 1;
|
|
}
|
|
}
|
|
last = last->next;
|
|
last = last->next;
|
|
@@ -517,14 +639,18 @@ int verify_session_id(flow *f, uint8_t *hs){
|
|
if((!found) && (f->current_session->session_ticket_len > 0)){
|
|
if((!found) && (f->current_session->session_ticket_len > 0)){
|
|
last = sessions->first_session;
|
|
last = sessions->first_session;
|
|
for(int i=0; ((i<sessions->length) && (!found)); i++){
|
|
for(int i=0; ((i<sessions->length) && (!found)); i++){
|
|
|
|
+ if(last->session_ticket_len == f->current_session->session_ticket_len){
|
|
if(!memcmp(last->session_ticket, f->current_session->session_ticket, f->current_session->session_ticket_len)){
|
|
if(!memcmp(last->session_ticket, f->current_session->session_ticket, f->current_session->session_ticket_len)){
|
|
memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
found = 1;
|
|
found = 1;
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Found new session ticket (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
|
|
printf("Found new session ticket (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
|
|
for(int i=0; i< last->session_ticket_len; i++){
|
|
for(int i=0; i< last->session_ticket_len; i++){
|
|
printf("%02x ", last->session_ticket[i]);
|
|
printf("%02x ", last->session_ticket[i]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
}
|
|
}
|
|
last = last->next;
|
|
last = last->next;
|
|
}
|
|
}
|
|
@@ -556,7 +682,7 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
|
|
p += 2; //skip version
|
|
p += 2; //skip version
|
|
p += SSL3_RANDOM_SIZE; //skip random
|
|
p += SSL3_RANDOM_SIZE; //skip random
|
|
|
|
|
|
- session *new_session = calloc(1, sizeof(session));
|
|
|
|
|
|
+ session *new_session = emalloc(sizeof(session));
|
|
new_session->session_id_len = (uint8_t) p[0];
|
|
new_session->session_id_len = (uint8_t) p[0];
|
|
new_session->session_ticket_len = 0;
|
|
new_session->session_ticket_len = 0;
|
|
p ++;
|
|
p ++;
|
|
@@ -565,12 +691,14 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
|
|
f->resume_session = 1;
|
|
f->resume_session = 1;
|
|
memcpy(new_session->session_id, p, new_session->session_id_len);
|
|
memcpy(new_session->session_id, p, new_session->session_id_len);
|
|
new_session->next = NULL;
|
|
new_session->next = NULL;
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Requested new session (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
|
|
printf("Requested new session (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
|
|
printf("session id: \n");
|
|
printf("session id: \n");
|
|
for(int i=0; i< new_session->session_id_len; i++){
|
|
for(int i=0; i< new_session->session_id_len; i++){
|
|
printf("%02x ", p[i]);
|
|
printf("%02x ", p[i]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
|
|
|
|
f->current_session = new_session;
|
|
f->current_session = new_session;
|
|
}
|
|
}
|
|
@@ -603,7 +731,7 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
|
|
if(ext_len > 0){
|
|
if(ext_len > 0){
|
|
f->resume_session = 1;
|
|
f->resume_session = 1;
|
|
new_session->session_ticket_len = ext_len;
|
|
new_session->session_ticket_len = ext_len;
|
|
- new_session->session_ticket = calloc(1, ext_len);
|
|
|
|
|
|
+ new_session->session_ticket = emalloc(ext_len);
|
|
memcpy(new_session->session_ticket, p, ext_len);
|
|
memcpy(new_session->session_ticket, p, ext_len);
|
|
f->current_session = new_session;
|
|
f->current_session = new_session;
|
|
}
|
|
}
|
|
@@ -632,14 +760,14 @@ int check_session(flow *f, uint8_t *hs, uint32_t len){
|
|
* 0 if success, 1 if failed
|
|
* 0 if success, 1 if failed
|
|
*/
|
|
*/
|
|
int save_session_id(flow *f, uint8_t *hs){
|
|
int save_session_id(flow *f, uint8_t *hs){
|
|
- printf("saving session id\n");
|
|
|
|
|
|
|
|
//increment pointer to point to sessionid
|
|
//increment pointer to point to sessionid
|
|
uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
|
|
uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
|
|
p += 2; //skip version
|
|
p += 2; //skip version
|
|
p += SSL3_RANDOM_SIZE; //skip random
|
|
p += SSL3_RANDOM_SIZE; //skip random
|
|
|
|
|
|
- session *new_session = calloc(1, sizeof(session));
|
|
|
|
|
|
+ session *new_session = emalloc(sizeof(session));
|
|
|
|
+
|
|
new_session->session_id_len = (uint8_t) p[0];
|
|
new_session->session_id_len = (uint8_t) p[0];
|
|
if(new_session->session_id_len <= 0){
|
|
if(new_session->session_id_len <= 0){
|
|
//if this value is zero, the session is non-resumable or the
|
|
//if this value is zero, the session is non-resumable or the
|
|
@@ -702,22 +830,24 @@ int save_session_id(flow *f, uint8_t *hs){
|
|
* 0 if success, 1 if failed
|
|
* 0 if success, 1 if failed
|
|
*/
|
|
*/
|
|
int save_session_ticket(flow *f, uint8_t *hs, uint32_t len){
|
|
int save_session_ticket(flow *f, uint8_t *hs, uint32_t len){
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("TICKET HDR:");
|
|
printf("TICKET HDR:");
|
|
for(int i=0; i< HANDSHAKE_HEADER_LEN; i++){
|
|
for(int i=0; i< HANDSHAKE_HEADER_LEN; i++){
|
|
printf("%02x ", hs[i]);
|
|
printf("%02x ", hs[i]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
|
|
uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
|
|
p += 4; //skip lifetime TODO: add to session struct
|
|
p += 4; //skip lifetime TODO: add to session struct
|
|
- session *new_session = calloc(1,sizeof(session));
|
|
|
|
|
|
+ session *new_session = emalloc(sizeof(session));
|
|
|
|
+
|
|
new_session->session_id_len = 0;
|
|
new_session->session_id_len = 0;
|
|
|
|
|
|
new_session->session_ticket_len = (p[0] << 8) + p[1];
|
|
new_session->session_ticket_len = (p[0] << 8) + p[1];
|
|
- printf("saving ticket of size %d (msg size %d)\n", new_session->session_ticket_len, len);
|
|
|
|
- fflush(stdout);
|
|
|
|
p += 2;
|
|
p += 2;
|
|
|
|
|
|
- uint8_t *ticket = calloc(1, new_session->session_ticket_len);
|
|
|
|
|
|
+ uint8_t *ticket = emalloc(new_session->session_ticket_len);
|
|
|
|
+
|
|
memcpy(ticket, p, new_session->session_ticket_len);
|
|
memcpy(ticket, p, new_session->session_ticket_len);
|
|
new_session->session_ticket = ticket;
|
|
new_session->session_ticket = ticket;
|
|
memcpy(new_session->master_secret, f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
memcpy(new_session->master_secret, f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
@@ -739,6 +869,7 @@ int save_session_ticket(flow *f, uint8_t *hs, uint32_t len){
|
|
|
|
|
|
sessions->length ++;
|
|
sessions->length ++;
|
|
|
|
|
|
|
|
+#ifdef DEBUG_HS
|
|
printf("Saved session ticket:");
|
|
printf("Saved session ticket:");
|
|
for(int i=0; i< new_session->session_ticket_len; i++){
|
|
for(int i=0; i< new_session->session_ticket_len; i++){
|
|
printf(" %02x", p[i]);
|
|
printf(" %02x", p[i]);
|
|
@@ -755,22 +886,25 @@ int save_session_ticket(flow *f, uint8_t *hs, uint32_t len){
|
|
|
|
|
|
printf("THERE ARE NOW %d saved sessions\n", sessions->length);
|
|
printf("THERE ARE NOW %d saved sessions\n", sessions->length);
|
|
fflush(stdout);
|
|
fflush(stdout);
|
|
|
|
+#endif
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* Adds a packet the flow's packet chain. If it can complete a record, gives
|
|
/* Adds a packet the flow's packet chain. If it can complete a record, gives
|
|
* this record to update_flow */
|
|
* this record to update_flow */
|
|
|
|
+//TODO: check all returns and figure out what to do if there is a mem failure
|
|
int add_packet(flow *f, struct packet_info *info){
|
|
int add_packet(flow *f, struct packet_info *info){
|
|
if (info->tcp_hdr == NULL || info->app_data_len <= 0){
|
|
if (info->tcp_hdr == NULL || info->app_data_len <= 0){
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- packet *new_packet = calloc(1, sizeof(packet));
|
|
|
|
|
|
+ packet *new_packet = emalloc(sizeof(packet));
|
|
|
|
+
|
|
new_packet->seq_num = ntohl(info->tcp_hdr->sequence_num);
|
|
new_packet->seq_num = ntohl(info->tcp_hdr->sequence_num);
|
|
new_packet->len = info->app_data_len;
|
|
new_packet->len = info->app_data_len;
|
|
|
|
|
|
- uint8_t *packet_data = calloc(1, new_packet->len);
|
|
|
|
|
|
+ uint8_t *packet_data = emalloc(new_packet->len);
|
|
memcpy(packet_data, info->app_data, new_packet->len);
|
|
memcpy(packet_data, info->app_data, new_packet->len);
|
|
|
|
|
|
new_packet->data = packet_data;
|
|
new_packet->data = packet_data;
|
|
@@ -823,7 +957,7 @@ int add_packet(flow *f, struct packet_info *info){
|
|
//if full record, give to update_flow
|
|
//if full record, give to update_flow
|
|
if(chain->remaining_record_len <= new_packet->len){
|
|
if(chain->remaining_record_len <= new_packet->len){
|
|
chain->remaining_record_len = 0;
|
|
chain->remaining_record_len = 0;
|
|
- uint8_t *record = calloc(1, chain->record_len);
|
|
|
|
|
|
+ uint8_t *record = emalloc(chain->record_len);
|
|
uint32_t record_len = chain->record_len;
|
|
uint32_t record_len = chain->record_len;
|
|
uint32_t tmp_len = chain->record_len;
|
|
uint32_t tmp_len = chain->record_len;
|
|
packet *next = chain->first_packet;
|
|
packet *next = chain->first_packet;
|
|
@@ -847,8 +981,10 @@ int add_packet(flow *f, struct packet_info *info){
|
|
const struct record_header *record_hdr = (struct record_header *) next->data;
|
|
const struct record_header *record_hdr = (struct record_header *) next->data;
|
|
chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
|
|
chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
|
|
chain->remaining_record_len = chain->record_len;
|
|
chain->remaining_record_len = chain->record_len;
|
|
|
|
+#ifdef DEBUG
|
|
printf("Found record of type %d\n", record_hdr->type);
|
|
printf("Found record of type %d\n", record_hdr->type);
|
|
fflush(stdout);
|
|
fflush(stdout);
|
|
|
|
+#endif
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|