static int execute_test(SSL_TEST_FIXTURE fixture) { int ret = 0; SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL; SSL_TEST_CTX *test_ctx = NULL; HANDSHAKE_RESULT result; test_ctx = SSL_TEST_CTX_create(conf, fixture.test_app); if (test_ctx == NULL) goto err; #ifndef OPENSSL_NO_DTLS if (test_ctx->method == SSL_TEST_METHOD_DTLS) { server_ctx = SSL_CTX_new(DTLS_server_method()); if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(DTLS_server_method()); OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(DTLS_client_method()); } #endif if (test_ctx->method == SSL_TEST_METHOD_TLS) { server_ctx = SSL_CTX_new(TLS_server_method()); if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(TLS_server_method()); OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(TLS_client_method()); } OPENSSL_assert(server_ctx != NULL && client_ctx != NULL); OPENSSL_assert(CONF_modules_load(conf, fixture.test_app, 0) > 0); if (!SSL_CTX_config(server_ctx, "server") || !SSL_CTX_config(client_ctx, "client")) { goto err; } if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2")) goto err; result = do_handshake(server_ctx, server2_ctx, client_ctx, test_ctx); ret = check_test(result, test_ctx); err: CONF_modules_unload(0); SSL_CTX_free(server_ctx); SSL_CTX_free(server2_ctx); SSL_CTX_free(client_ctx); SSL_TEST_CTX_free(test_ctx); if (ret != 1) ERR_print_errors_fp(stderr); return ret; }
static int test_large_message_dtls(void) { /* * read_ahead is not relevant to DTLS because DTLS always acts as if * read_ahead is set. */ return execute_test_large_message(DTLS_server_method(), DTLS_client_method(), 0); }
static const SSL_METHOD *dtls1_get_server_method(int ver) { if (ver == DTLS_ANY_VERSION) return DTLS_server_method(); else if (ver == DTLS1_VERSION) return DTLSv1_server_method(); else if (ver == DTLS1_2_VERSION) return DTLSv1_2_server_method(); else return NULL; }
Context init_ctx_server(const char *caPath, const char *certPath, const char *keyPath, bool verify) { Context ctx(SSL_CTX_new(DTLS_server_method())); if(loadCertificates(ctx, caPath, certPath, keyPath, verify)) { err::code = err::LIB_SSL; return {}; } return ctx; }
static int test_dtls_unprocessed(int testidx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl1 = NULL, *clientssl1 = NULL; BIO *c_to_s_fbio, *c_to_s_mempacket; int testresult = 0; if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), DTLS_client_method(), &sctx, &cctx, cert, privkey))) return 0; 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 (!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, &serverssl1, &clientssl1, NULL, c_to_s_fbio))) goto end; if (testidx == 1) certstatus[RECORD_SEQUENCE] = 0xff; /* * Inject a dummy record from the next epoch. In test 0, this should never * get used because the message sequence number is too big. In test 1 we set * the record sequence number to be way off in the future. This should not * have an impact on the record replay protection because the record should * be dropped before it is marked as arrived */ c_to_s_mempacket = SSL_get_wbio(clientssl1); c_to_s_mempacket = BIO_next(c_to_s_mempacket); mempacket_test_inject(c_to_s_mempacket, (char *)certstatus, sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ); if (!TEST_true(create_ssl_connection(serverssl1, clientssl1, SSL_ERROR_NONE))) goto end; testresult = 1; end: SSL_free(serverssl1); SSL_free(clientssl1); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
static const SSL_METHOD *dtls1_get_server_method(int ver) { switch (ver) { case DTLS_ANY_VERSION: return DTLS_server_method(); case DTLS1_VERSION: return DTLSv1_server_method(); case DTLS1_2_VERSION: return DTLSv1_2_server_method(); default: return NULL; } }
static const SSL_METHOD *dtls1_get_server_method(int ver) { if (ver == DTLS_ANY_VERSION) return DTLS_server_method(); #ifndef OPENSSL_NO_DTLS1 else if (ver == DTLS1_VERSION) return dtlsv1_server_method(); #endif #ifndef OPENSSL_NO_DTLS1_2 else if (ver == DTLS1_2_VERSION) return dtlsv1_2_server_method(); #endif else return NULL; }
static int test_dtls_drop_records(int idx) { 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 (!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; } 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; if (sess != NULL) { if (!TEST_true(SSL_set_session(clientssl, sess))) goto end; } DTLS_set_timer_cb(clientssl, timer_cb); DTLS_set_timer_cb(serverssl, timer_cb); /* 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); if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) goto end; if (sess != NULL && !TEST_true(SSL_session_reused(clientssl))) goto end; /* 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; testresult = 1; end: SSL_SESSION_free(sess); SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
int main(void) { SSL_CTX *ctx = NULL; SSL *ssl = NULL; BIO *outbio = NULL; BIO *inbio = NULL; BIO_ADDR *peer = BIO_ADDR_new(); char *data; long datalen; int ret, success = 0; size_t i; ctx = SSL_CTX_new(DTLS_server_method()); if (ctx == NULL || peer == NULL) goto err; SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen); SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify); /* Create an SSL object for the connection */ ssl = SSL_new(ctx); if (ssl == NULL) goto err; outbio = BIO_new(BIO_s_mem()); if (outbio == NULL) goto err; SSL_set_wbio(ssl, outbio); success = 1; for (i = 0; i < OSSL_NELEM(testpackets) && success; i++) { inbio = BIO_new_mem_buf((char *)testpackets[i].in, testpackets[i].inlen); if (inbio == NULL) { success = 0; goto err; } /* Set Non-blocking IO behaviour */ BIO_set_mem_eof_return(inbio, -1); SSL_set_rbio(ssl, inbio); /* Process the incoming packet */ ret = DTLSv1_listen(ssl, peer); if (ret < 0) { success = 0; goto err; } datalen = BIO_get_mem_data(outbio, &data); if (testpackets[i].outtype == VERIFY) { if (ret == 0) { if (datalen != sizeof(verify) || (memcmp(data, verify, sizeof(verify)) != 0)) { printf("Test %ld failure: incorrect HelloVerifyRequest\n", i); success = 0; } else { printf("Test %ld success\n", i); } } else { printf ("Test %ld failure: should not have succeeded\n", i); success = 0; } } else if (datalen == 0) { if ((ret == 0 && testpackets[i].outtype == DROP) || (ret == 1 && testpackets[i].outtype == GOOD)) { printf("Test %ld success\n", i); } else { printf("Test %ld failure: wrong return value\n", i); success = 0; } } else { printf("Test %ld failure: Unexpected data output\n", i); success = 0; } (void)BIO_reset(outbio); inbio = NULL; /* Frees up inbio */ SSL_set_rbio(ssl, NULL); } err: if (!success) ERR_print_errors_fp(stderr); /* Also frees up outbio */ SSL_free(ssl); SSL_CTX_free(ctx); BIO_free(inbio); OPENSSL_free(peer); #ifndef OPENSSL_NO_CRYPTO_MDEBUG CRYPTO_mem_leaks_fp(stderr); #endif return success ? 0 : 1; }
static int test_handshake(int idx) { int ret = 0; SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL, *resume_server_ctx = NULL, *resume_client_ctx = NULL; SSL_TEST_CTX *test_ctx = NULL; HANDSHAKE_RESULT *result = NULL; char test_app[MAX_TESTCASE_NAME_LENGTH]; BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx); test_ctx = SSL_TEST_CTX_create(conf, test_app); if (test_ctx == NULL) goto err; #ifndef OPENSSL_NO_DTLS if (test_ctx->method == SSL_TEST_METHOD_DTLS) { server_ctx = SSL_CTX_new(DTLS_server_method()); if (test_ctx->extra.server.servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(DTLS_server_method()); TEST_check(server2_ctx != NULL); } client_ctx = SSL_CTX_new(DTLS_client_method()); if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { resume_server_ctx = SSL_CTX_new(DTLS_server_method()); resume_client_ctx = SSL_CTX_new(DTLS_client_method()); TEST_check(resume_server_ctx != NULL); TEST_check(resume_client_ctx != NULL); } } #endif if (test_ctx->method == SSL_TEST_METHOD_TLS) { server_ctx = SSL_CTX_new(TLS_server_method()); /* SNI on resumption isn't supported/tested yet. */ if (test_ctx->extra.server.servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(TLS_server_method()); TEST_check(server2_ctx != NULL); } client_ctx = SSL_CTX_new(TLS_client_method()); if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { resume_server_ctx = SSL_CTX_new(TLS_server_method()); resume_client_ctx = SSL_CTX_new(TLS_client_method()); TEST_check(resume_server_ctx != NULL); TEST_check(resume_client_ctx != NULL); } } TEST_check(server_ctx != NULL); TEST_check(client_ctx != NULL); TEST_check(CONF_modules_load(conf, test_app, 0) > 0); if (!SSL_CTX_config(server_ctx, "server") || !SSL_CTX_config(client_ctx, "client")) { goto err; } if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2")) goto err; if (resume_server_ctx != NULL && !SSL_CTX_config(resume_server_ctx, "resume-server")) goto err; if (resume_client_ctx != NULL && !SSL_CTX_config(resume_client_ctx, "resume-client")) goto err; result = do_handshake(server_ctx, server2_ctx, client_ctx, resume_server_ctx, resume_client_ctx, test_ctx); ret = check_test(result, test_ctx); err: CONF_modules_unload(0); SSL_CTX_free(server_ctx); SSL_CTX_free(server2_ctx); SSL_CTX_free(client_ctx); SSL_CTX_free(resume_server_ctx); SSL_CTX_free(resume_client_ctx); SSL_TEST_CTX_free(test_ctx); HANDSHAKE_RESULT_free(result); return ret; }