X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Fsslapitest.c;h=074232db7764e4653488601ba2820fd449d4ad52;hp=3504eea63e47643be3c6adaa734b2439e9f6896d;hb=db26ec80873e8faa8d40795120bc15c37d36ac98;hpb=7c3a7561b536264b282f604efc959edad18807d7 diff --git a/test/sslapitest.c b/test/sslapitest.c index 3504eea63e..074232db77 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -2960,8 +2960,13 @@ static int early_data_skip_helper(int testtype, int idx) if (testtype == 1 || testtype == 2) { /* Force an HRR to occur */ +#if defined(OPENSSL_NO_EC) + if (!TEST_true(SSL_set1_groups_list(serverssl, "ffdhe3072"))) + goto end; +#else if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256"))) goto end; +#endif } else if (idx == 2) { /* * We force early_data rejection by ensuring the PSK identity is @@ -3735,6 +3740,172 @@ static int test_ciphersuite_change(void) return testresult; } +/* + * Test Key exchange + * Test 0 = Test ECDHE Key exchange with TLSv1.3 client and server + * Test 1 = Test ECDHE with TLSv1.2 client and server + * Test 2 = Test FFDHE Key exchange with TLSv1.3 client and server + * Test 3 = Test FFDHE with TLSv1.2 client and server + * Test 4 = Test NID_X9_62_prime256v1 with TLSv1.3 client and server + * Test 5 = Test NID_secp384r1 with TLSv1.3 client and server + * Test 6 = Test NID_secp521r1 with TLSv1.3 client and server + * Test 7 = Test NID_X25519 with TLSv1.3 client and server + * Test 8 = Test NID_X448 with TLSv1.3 client and server + * Test 9 = Test NID_ffdhe2048 with TLSv1.3 client and server + * Test 10 = Test NID_ffdhe3072 with TLSv1.3 client and server + * Test 11 = Test NID_ffdhe4096 with TLSv1.3 client and server + * Test 12 = Test NID_ffdhe6144 with TLSv1.3 client and server + * Test 13 = Test NID_ffdhe8192 with TLSv1.3 client and server + */ +static int test_key_exchange(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; +#if !defined(OPENSSL_NO_EC) + int ecdhe_kexch_groups[] = {NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, + NID_X25519, NID_X448}; +#endif +#ifndef OPENSSL_NO_DH + int ffdhe_kexch_groups[] = {NID_ffdhe2048, NID_ffdhe3072, NID_ffdhe4096, + NID_ffdhe6144, NID_ffdhe8192}; +#endif + int kexch_alg; + int *kexch_groups = &kexch_alg; + int kexch_groups_size = 1; + int max_version = TLS1_3_VERSION; + int want_err = SSL_ERROR_NONE; + int expected_err_reason = 0; + + switch (idx) { +#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_TLS1_2 + case 1: + max_version = TLS1_2_VERSION; +# endif + /* Fall through */ + case 0: + kexch_groups = ecdhe_kexch_groups; + kexch_groups_size = OSSL_NELEM(ecdhe_kexch_groups); + break; + case 4: + kexch_alg = NID_X9_62_prime256v1; + break; + case 5: + kexch_alg = NID_secp384r1; + break; + case 6: + kexch_alg = NID_secp521r1; + break; + case 7: + kexch_alg = NID_X25519; + break; + case 8: + kexch_alg = NID_X448; + break; +#endif +#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_TLS1_2 + case 3: + max_version = TLS1_2_VERSION; +# endif + /* Fall through */ + case 2: + kexch_groups = ffdhe_kexch_groups; + kexch_groups_size = OSSL_NELEM(ffdhe_kexch_groups); + break; + case 9: + kexch_alg = NID_ffdhe2048; + break; + case 10: + kexch_alg = NID_ffdhe3072; + break; + case 11: + kexch_alg = NID_ffdhe4096; + break; + case 12: + kexch_alg = NID_ffdhe6144; + break; + case 13: + kexch_alg = NID_ffdhe8192; + break; +#endif + default: + /* We're skipping this test */ + return 1; + } + + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, max_version, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, TLS1_3_RFC_AES_128_GCM_SHA256))) + goto end; + + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, TLS1_3_RFC_AES_128_GCM_SHA256))) + goto end; + + if (!TEST_true(SSL_CTX_set_cipher_list(sctx, TLS1_TXT_RSA_WITH_AES_128_SHA))) + goto end; + + /* + * Must include an EC ciphersuite so that we send supported groups in + * TLSv1.2 + */ + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM ":" + TLS1_TXT_RSA_WITH_AES_128_SHA))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + if (!TEST_true(SSL_set1_groups(serverssl, kexch_groups, kexch_groups_size)) + || !TEST_true(SSL_set1_groups(clientssl, kexch_groups, kexch_groups_size))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, want_err))) { + /* Fail only if no error is expected in handshake */ + if (expected_err_reason == 0) + goto end; + } + + /* Fail if expected error is not happening for failure testcases */ + if (expected_err_reason != 0) { + unsigned long err_code = ERR_get_error(); + + ERR_print_errors_fp(stdout); + if (TEST_int_eq(ERR_GET_REASON(err_code), expected_err_reason)) + testresult = 1; + goto end; + } + + /* + * If Handshake succeeds the negotiated kexch alg should the first one in + * configured, except in the case of FFDHE groups which are TLSv1.3 only + * so we expect no shared group to exist. + */ + if (!TEST_int_eq(SSL_get_shared_group(serverssl, 0), + idx == 3 ? 0 : kexch_groups[0])) + goto end; + if (max_version == TLS1_3_VERSION) { + if (!TEST_int_eq(SSL_get_negotiated_group(serverssl), kexch_groups[0])) + goto end; + if (!TEST_int_eq(SSL_get_negotiated_group(clientssl), kexch_groups[0])) + goto end; + } + + testresult = 1; + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + /* * Test TLSv1.3 PSKs * Test 0 = Test new style callbacks @@ -3878,8 +4049,13 @@ static int test_tls13_psk(int idx) goto end; /* Force an HRR */ +#if defined(OPENSSL_NO_EC) + if (!TEST_true(SSL_set1_groups_list(serverssl, "ffdhe3072"))) + goto end; +#else if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256"))) goto end; +#endif /* * Check we can create a connection, the PSK is used and the callbacks are @@ -4737,7 +4913,95 @@ static int test_key_update(void) || !TEST_int_eq(SSL_read(serverssl, buf, sizeof(buf)), strlen(mess))) goto end; + + if (!TEST_int_eq(SSL_write(serverssl, mess, strlen(mess)), strlen(mess)) + || !TEST_int_eq(SSL_read(clientssl, buf, sizeof(buf)), + strlen(mess))) + goto end; + } + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +/* + * Test we can handle a KeyUpdate (update requested) message while write data + * is pending. + * Test 0: Client sends KeyUpdate while Server is writing + * Test 1: Server sends KeyUpdate while Client is writing + */ +static int test_key_update_in_write(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + char buf[20]; + static char *mess = "A test message"; + BIO *bretry = BIO_new(bio_s_always_retry()); + BIO *tmp = NULL; + SSL *peerupdate = NULL, *peerwrite = NULL; + + if (!TEST_ptr(bretry) + || !TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), + TLS1_3_VERSION, + 0, + &sctx, &cctx, cert, privkey)) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + peerupdate = tst == 0 ? clientssl : serverssl; + peerwrite = tst == 0 ? serverssl : clientssl; + + if (!TEST_true(SSL_key_update(peerupdate, SSL_KEY_UPDATE_REQUESTED)) + || !TEST_true(SSL_do_handshake(peerupdate))) + goto end; + + /* Swap the writing endpoint's write BIO to force a retry */ + tmp = SSL_get_wbio(peerwrite); + if (!TEST_ptr(tmp) || !TEST_true(BIO_up_ref(tmp))) { + tmp = NULL; + goto end; } + SSL_set0_wbio(peerwrite, bretry); + bretry = NULL; + + /* Write data that we know will fail with SSL_ERROR_WANT_WRITE */ + if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), -1) + || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_WRITE)) + goto end; + + /* Reinstate the original writing endpoint's write BIO */ + SSL_set0_wbio(peerwrite, tmp); + tmp = NULL; + + /* Now read some data - we will read the key update */ + if (!TEST_int_eq(SSL_read(peerwrite, buf, sizeof(buf)), -1) + || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_READ)) + goto end; + + /* + * Complete the write we started previously and read it from the other + * endpoint + */ + if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess)) + || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess))) + goto end; + + /* Write more data to ensure we send the KeyUpdate message back */ + if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess)) + || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess))) + goto end; testresult = 1; @@ -4746,6 +5010,8 @@ static int test_key_update(void) SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); + BIO_free(bretry); + BIO_free(tmp); return testresult; } @@ -6023,6 +6289,9 @@ static int cert_cb_cnt; static int cert_cb(SSL *s, void *arg) { SSL_CTX *ctx = (SSL_CTX *)arg; + BIO *in = NULL; + EVP_PKEY *pkey = NULL; + X509 *x509 = NULL; if (cert_cb_cnt == 0) { /* Suspend the handshake */ @@ -6043,9 +6312,39 @@ static int cert_cb(SSL *s, void *arg) return 0; cert_cb_cnt++; return 1; + } else if (cert_cb_cnt == 3) { + int rv; + if (!TEST_ptr(in = BIO_new(BIO_s_file())) + || !TEST_int_ge(BIO_read_filename(in, cert), 0) + || !TEST_ptr(x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) + goto out; + BIO_free(in); + if (!TEST_ptr(in = BIO_new(BIO_s_file())) + || !TEST_int_ge(BIO_read_filename(in, privkey), 0) + || !TEST_ptr(pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL))) + goto out; + rv = SSL_check_chain(s, x509, pkey, NULL); + /* + * If the cert doesn't show as valid here (e.g., because we don't + * have any shared sigalgs), then we will not set it, and there will + * be no certificate at all on the SSL or SSL_CTX. This, in turn, + * will cause tls_choose_sigalgs() to fail the connection. + */ + if ((rv & CERT_PKEY_VALID)) { + if (!SSL_use_cert_and_key(s, x509, pkey, NULL, 1)) + goto out; + } + BIO_free(in); + EVP_PKEY_free(pkey); + X509_free(x509); + return 1; } /* Abort the handshake */ + out: + BIO_free(in); + EVP_PKEY_free(pkey); + X509_free(x509); return 0; } @@ -6070,6 +6369,8 @@ static int test_cert_cb_int(int prot, int tst) if (tst == 0) cert_cb_cnt = -1; + else if (tst == 3) + cert_cb_cnt = 3; else cert_cb_cnt = 0; if (tst == 2) @@ -6082,7 +6383,8 @@ static int test_cert_cb_int(int prot, int tst) ret = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE); if (!TEST_true(tst == 0 ? !ret : ret) - || (tst > 0 && !TEST_int_eq(cert_cb_cnt, 2))) { + || (tst > 0 + && !TEST_int_eq((cert_cb_cnt - 2) * (cert_cb_cnt - 3), 0))) { goto end; } @@ -6446,6 +6748,7 @@ int setup_tests(void) #else ADD_ALL_TESTS(test_tls13_psk, 4); #endif /* OPENSSL_NO_PSK */ + ADD_ALL_TESTS(test_key_exchange, 14); ADD_ALL_TESTS(test_custom_exts, 5); ADD_TEST(test_stateless); ADD_TEST(test_pha_key_update); @@ -6457,6 +6760,7 @@ int setup_tests(void) #ifndef OPENSSL_NO_TLS1_3 ADD_ALL_TESTS(test_export_key_mat_early, 3); ADD_TEST(test_key_update); + ADD_ALL_TESTS(test_key_update_in_write, 2); #endif ADD_ALL_TESTS(test_ssl_clear, 2); ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test)); @@ -6468,7 +6772,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data)); ADD_ALL_TESTS(test_ticket_callbacks, 12); ADD_ALL_TESTS(test_shutdown, 7); - ADD_ALL_TESTS(test_cert_cb, 3); + ADD_ALL_TESTS(test_cert_cb, 4); ADD_ALL_TESTS(test_client_cert_cb, 2); ADD_ALL_TESTS(test_ca_names, 3); return 1; @@ -6477,4 +6781,5 @@ int setup_tests(void) void cleanup_tests(void) { bio_s_mempacket_test_free(); + bio_s_always_retry_free(); }