/** check_handshake.c * * Integration-style tests for extracting the TLS master secret for various * types of TLS handshakes */ #include #include #include "../flow.h" #include "../crypto.h" #include "../cryptothread.h" #include "../packet.h" #include "../util.h" #include "test_util.h" START_TEST(full_handshake_regular){ flow *f = NULL; uint8_t *data; struct packet_info *info; info = smalloc(sizeof(struct packet_info)); /* Read in ClientHello message */ if(!read_file("data/frame_handshake_regular1.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); //Make sure it recognized the tag ck_assert_int_eq(check_handshake(info), 1); //make sure it saved the flow f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* Read in ServerHello message */ if(!read_file("data/frame_handshake_regular2.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //make sure it's not using the extended master extension ck_assert_int_eq(f->extended_master_secret, 0); free(data); /* Read in Certificate messages */ if(!read_file("data/frame_handshake_regular3.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); if(!read_file("data/frame_handshake_regular4.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* ServerKeyEx, ServerHelloDone */ if(!read_file("data/frame_handshake_regular5.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* ClientKeyEx, CCS, Finished */ if(!read_file("data/frame_handshake_regular6.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Verify Finished received ck_assert_int_eq(f->out_encrypted, 2); free(data); /* CCS, Finished (from the server) */ if(!read_file("data/frame_handshake_regular7.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Make sure both Finished messages were successfully received and decrypted f = check_flow(info); ck_assert_ptr_ne(f, NULL); ck_assert_int_eq(f->in_encrypted, 2); ck_assert_int_eq(f->application, 1); remove_flow(f); free(data); } END_TEST START_TEST(full_handshake_regular_resumed){ flow *f; uint8_t *record; //populate record from file if(!read_file("data/packet_tagged.dat", &record)){ ck_abort(); } } END_TEST START_TEST(full_handshake_extended){ flow *f = NULL; uint8_t *data; struct packet_info *info; info = smalloc(sizeof(struct packet_info)); /* Read in ClientHello message */ if(!read_file("data/frame_handshake_extended1.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); //Make sure it recognized the tag ck_assert_int_eq(check_handshake(info), 1); //make sure it saved the flow f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* Read in ServerHello message */ if(!read_file("data/frame_handshake_extended2.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //make sure it recognized the extended master extension ck_assert_int_eq(f->extended_master_secret, 1); free(data); /* Read in Certificate messages */ if(!read_file("data/frame_handshake_extended3.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); if(!read_file("data/frame_handshake_extended4.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); if(!read_file("data/frame_handshake_extended5.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* ServerKeyEx, ServerHelloDone */ if(!read_file("data/frame_handshake_extended6.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* ClientKeyEx, CCS, Finished */ if(!read_file("data/frame_handshake_extended7.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Verify Finished received ck_assert_int_eq(f->out_encrypted, 2); free(data); /* CCS, Finished (from the server) */ if(!read_file("data/frame_handshake_extended8.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Make sure both Finished messages were successfully received and decrypted f = check_flow(info); ck_assert_ptr_ne(f, NULL); ck_assert_int_eq(f->in_encrypted, 2); ck_assert_int_eq(f->application, 1); remove_flow(f); free(data); } END_TEST /* Note: only run this test if full_handshake_extended is run first */ START_TEST(full_handshake_extended_resumed){ flow *f = NULL; uint8_t *data; struct packet_info *info; info = smalloc(sizeof(struct packet_info)); /* Read in ClientHello message */ if(!read_file("data/frame_handshake_extended_resumed1.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); //Make sure it recognized the tag ck_assert_int_eq(check_handshake(info), 1); //make sure it saved the flow f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); free(data); /* ServerHello, CCS, Finished */ if(!read_file("data/frame_handshake_extended_resumed2.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Verify Finished received ck_assert_int_eq(f->in_encrypted, 2); free(data); /* CCS, Finished (from the client) */ if(!read_file("data/frame_handshake_extended_resumed3.dat", &data)){ ck_abort(); } extract_packet_headers(data, info); f = check_flow(info); ck_assert_ptr_ne(f, NULL); add_packet(f, info); //Make sure both Finished messages were successfully received and decrypted f = check_flow(info); ck_assert_ptr_ne(f, NULL); ck_assert_int_eq(f->out_encrypted, 2); ck_assert_int_eq(f->application, 1); remove_flow(f); free(data); } END_TEST Suite *tag_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Handshake"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, full_handshake_regular); #if OPENSSL_VERSION_NUMBER >= 0x1010000eL tcase_add_test(tc_core, full_handshake_extended); tcase_add_test(tc_core, full_handshake_extended_resumed); #endif suite_add_tcase(s, tc_core); return s; } int main(void){ int number_failed; Suite *s; SRunner *sr; //initialize Slitheen structures if(init_tables()){ exit(1); } if(init_session_cache()){ exit(1); } init_crypto_locks(); s = tag_suite(); sr = srunner_create(s); srunner_set_fork_status(sr, CK_NOFORK); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); crypto_locks_cleanup(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }