X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=test%2Fdtlstest.c;h=c41aac8319cbd0d7a4a8b7ec5738b03812256fab;hb=79c2c741303ed188214b9299a51c837635f7e9a8;hp=4d497af1afe9e849126351f21c9bccf918528842;hpb=52a03d2a5e28a379d94d38c629d05b2a3ab0ff19;p=oweals%2Fopenssl.git diff --git a/test/dtlstest.c b/test/dtlstest.c index 4d497af1af..c41aac8319 100644 --- a/test/dtlstest.c +++ b/test/dtlstest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,7 @@ static char *cert = NULL; static char *privkey = NULL; +static unsigned int timer_cb_count; #define NUM_TESTS 2 @@ -40,6 +41,16 @@ static unsigned char certstatus[] = { #define RECORD_SEQUENCE 10 +static unsigned int timer_cb(SSL *s, unsigned int timer_us) +{ + ++timer_cb_count; + + if (timer_us == 0) + return 50000; + else + return 2 * timer_us; +} + static int test_dtls_unprocessed(int testidx) { SSL_CTX *sctx = NULL, *cctx = NULL; @@ -47,31 +58,27 @@ static int test_dtls_unprocessed(int testidx) BIO *c_to_s_fbio, *c_to_s_mempacket; int testresult = 0; - printf("Starting Test %d\n", testidx); + timer_cb_count = 0; - if (!create_ssl_ctx_pair(DTLS_server_method(), DTLS_client_method(), &sctx, - &cctx, cert, privkey)) { - printf("Unable to create SSL_CTX pair\n"); + if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), + DTLS_client_method(), + DTLS1_VERSION, DTLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) return 0; - } - if (!SSL_CTX_set_cipher_list(cctx, "ECDHE-RSA-AES256-SHA384")) { - printf("Failed setting cipher list\n"); - } + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA"))) + goto end; c_to_s_fbio = BIO_new(bio_f_tls_dump_filter()); - if (c_to_s_fbio == NULL) { - printf("Failed to create filter BIO\n"); + if (!TEST_ptr(c_to_s_fbio)) goto end; - } /* BIO is freed by create_ssl_connection on error */ - if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, - c_to_s_fbio)) { - printf("Unable to create SSL objects\n"); - ERR_print_errors_fp(stdout); + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, + NULL, c_to_s_fbio))) goto end; - } + + DTLS_set_timer_cb(clientssl1, timer_cb); if (testidx == 1) certstatus[RECORD_SEQUENCE] = 0xff; @@ -88,9 +95,12 @@ static int test_dtls_unprocessed(int testidx) mempacket_test_inject(c_to_s_mempacket, (char *)certstatus, sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ); - if (!create_ssl_connection(serverssl1, clientssl1)) { - printf("Unable to create SSL connection\n"); - ERR_print_errors_fp(stdout); + if (!TEST_true(create_ssl_connection(serverssl1, clientssl1, + SSL_ERROR_NONE))) + goto end; + + if (timer_cb_count == 0) { + printf("timer_callback was not called.\n"); goto end; } @@ -104,39 +114,146 @@ static int test_dtls_unprocessed(int testidx) return testresult; } -int main(int argc, char *argv[]) +#define CLI_TO_SRV_EPOCH_0_RECS 3 +#define CLI_TO_SRV_EPOCH_1_RECS 1 +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) +# define SRV_TO_CLI_EPOCH_0_RECS 12 +#else +/* + * In this case we have no ServerKeyExchange message, because we don't have + * ECDHE or DHE. When it is present it gets fragmented into 3 records in this + * test. + */ +# define SRV_TO_CLI_EPOCH_0_RECS 9 +#endif +#define SRV_TO_CLI_EPOCH_1_RECS 1 +#define TOTAL_FULL_HAND_RECORDS \ + (CLI_TO_SRV_EPOCH_0_RECS + CLI_TO_SRV_EPOCH_1_RECS + \ + SRV_TO_CLI_EPOCH_0_RECS + SRV_TO_CLI_EPOCH_1_RECS) + +#define CLI_TO_SRV_RESUME_EPOCH_0_RECS 3 +#define CLI_TO_SRV_RESUME_EPOCH_1_RECS 1 +#define SRV_TO_CLI_RESUME_EPOCH_0_RECS 2 +#define SRV_TO_CLI_RESUME_EPOCH_1_RECS 1 +#define TOTAL_RESUME_HAND_RECORDS \ + (CLI_TO_SRV_RESUME_EPOCH_0_RECS + CLI_TO_SRV_RESUME_EPOCH_1_RECS + \ + SRV_TO_CLI_RESUME_EPOCH_0_RECS + SRV_TO_CLI_RESUME_EPOCH_1_RECS) + +#define TOTAL_RECORDS (TOTAL_FULL_HAND_RECORDS + TOTAL_RESUME_HAND_RECORDS) + +static int test_dtls_drop_records(int idx) { - BIO *err = NULL; - int testresult = 1; + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO *c_to_s_fbio, *mempackbio; + int testresult = 0; + int epoch = 0; + SSL_SESSION *sess = NULL; + int cli_to_srv_epoch0, cli_to_srv_epoch1, srv_to_cli_epoch0; - if (argc != 3) { - printf("Invalid argument count\n"); - return 1; + if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), + DTLS_client_method(), + DTLS1_VERSION, DTLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + if (idx >= TOTAL_FULL_HAND_RECORDS) { + /* We're going to do a resumption handshake. Get a session first. */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_ptr(sess = SSL_get1_session(clientssl))) + goto end; + + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + cli_to_srv_epoch0 = CLI_TO_SRV_RESUME_EPOCH_0_RECS; + cli_to_srv_epoch1 = CLI_TO_SRV_RESUME_EPOCH_1_RECS; + srv_to_cli_epoch0 = SRV_TO_CLI_RESUME_EPOCH_0_RECS; + idx -= TOTAL_FULL_HAND_RECORDS; + } else { + cli_to_srv_epoch0 = CLI_TO_SRV_EPOCH_0_RECS; + cli_to_srv_epoch1 = CLI_TO_SRV_EPOCH_1_RECS; + srv_to_cli_epoch0 = SRV_TO_CLI_EPOCH_0_RECS; } - cert = argv[1]; - privkey = argv[2]; + c_to_s_fbio = BIO_new(bio_f_tls_dump_filter()); + if (!TEST_ptr(c_to_s_fbio)) + goto end; + + /* BIO is freed by create_ssl_connection on error */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, c_to_s_fbio))) + goto end; - err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + if (sess != NULL) { + if (!TEST_true(SSL_set_session(clientssl, sess))) + goto end; + } - CRYPTO_set_mem_debug(1); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + DTLS_set_timer_cb(clientssl, timer_cb); + DTLS_set_timer_cb(serverssl, timer_cb); - ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS); + /* Work out which record to drop based on the test number */ + if (idx >= cli_to_srv_epoch0 + cli_to_srv_epoch1) { + mempackbio = SSL_get_wbio(serverssl); + idx -= cli_to_srv_epoch0 + cli_to_srv_epoch1; + if (idx >= srv_to_cli_epoch0) { + epoch = 1; + idx -= srv_to_cli_epoch0; + } + } else { + mempackbio = SSL_get_wbio(clientssl); + if (idx >= cli_to_srv_epoch0) { + epoch = 1; + idx -= cli_to_srv_epoch0; + } + mempackbio = BIO_next(mempackbio); + } + BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_EPOCH, epoch, NULL); + BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_REC, idx, NULL); - testresult = run_tests(argv[0]); + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; - bio_f_tls_dump_filter_free(); - bio_s_mempacket_test_free(); + if (sess != NULL && !TEST_true(SSL_session_reused(clientssl))) + goto end; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (CRYPTO_mem_leaks(err) <= 0) - testresult = 1; -#endif - BIO_free(err); + /* If the test did what we planned then it should have dropped a record */ + if (!TEST_int_eq((int)BIO_ctrl(mempackbio, MEMPACKET_CTRL_GET_DROP_REC, 0, + NULL), -1)) + goto end; - if (!testresult) - printf("PASS\n"); + testresult = 1; + end: + SSL_SESSION_free(sess); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); return testresult; } + +int setup_tests(void) +{ + if (!TEST_ptr(cert = test_get_argument(0)) + || !TEST_ptr(privkey = test_get_argument(1))) + return 0; + + ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS); + ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS); + + return 1; +} + +void cleanup_tests(void) +{ + bio_f_tls_dump_filter_free(); + bio_s_mempacket_test_free(); +}