From 9863b41989968fd88d1b772ac7e20e3cdaea8beb Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Thu, 13 Jun 2019 12:02:03 -0700 Subject: [PATCH] Add regression test for #9099 Augment the cert_cb sslapitest to include a run that uses SSL_check_chain() to inspect the certificate prior to installing it on the SSL object. If the check shows the certificate as not valid in that context, we do not install a certificate at all, so the handshake will fail later on in processing (tls_choose_sigalg()), exposing the indicated regression. Currently it fails, since we have not yet set the shared sigalgs by the time the cert_cb runs. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/9157) (cherry picked from commit 7cb8fb07e8b71dc1fdcb0de10af7fed4347f6ea4) --- test/sslapitest.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/test/sslapitest.c b/test/sslapitest.c index 577342644d..8c6e16c2fc 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -5662,6 +5662,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 */ @@ -5682,9 +5685,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; } @@ -5709,6 +5742,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) @@ -5721,7 +5756,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; } @@ -6084,7 +6120,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; -- 2.25.1