diff options
Diffstat (limited to 'src/ssl/test/bssl_shim.cc')
-rw-r--r-- | src/ssl/test/bssl_shim.cc | 221 |
1 files changed, 124 insertions, 97 deletions
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc index 8f4126e6..71798326 100644 --- a/src/ssl/test/bssl_shim.cc +++ b/src/ssl/test/bssl_shim.cc @@ -115,6 +115,7 @@ struct TestState { bool custom_verify_ready = false; std::string msg_callback_text; bool msg_callback_ok = true; + bool cert_verified = false; }; static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, @@ -699,6 +700,11 @@ static bool CheckVerifyCallback(SSL *ssl) { } } + if (GetTestState(ssl)->cert_verified) { + fprintf(stderr, "Certificate verified twice.\n"); + return false; + } + return true; } @@ -715,6 +721,7 @@ static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { return 0; } + GetTestState(ssl)->cert_verified = true; return 1; } @@ -732,6 +739,7 @@ static ssl_verify_result_t CustomVerifyCallback(SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; } + GetTestState(ssl)->cert_verified = true; return ssl_verify_ok; } @@ -1483,11 +1491,111 @@ static uint16_t GetProtocolVersion(const SSL *ssl) { return 0x0201 + ~version; } +// CheckAuthProperties checks, after the initial handshake is completed or +// after a renegotiation, that authentication-related properties match |config|. +static bool CheckAuthProperties(SSL *ssl, bool is_resume, + const TestConfig *config) { + if (!config->expected_ocsp_response.empty()) { + const uint8_t *data; + size_t len; + SSL_get0_ocsp_response(ssl, &data, &len); + if (config->expected_ocsp_response.size() != len || + OPENSSL_memcmp(config->expected_ocsp_response.data(), data, len) != 0) { + fprintf(stderr, "OCSP response mismatch\n"); + return false; + } + } + + if (!config->expected_signed_cert_timestamps.empty()) { + const uint8_t *data; + size_t len; + SSL_get0_signed_cert_timestamp_list(ssl, &data, &len); + if (config->expected_signed_cert_timestamps.size() != len || + OPENSSL_memcmp(config->expected_signed_cert_timestamps.data(), data, + len) != 0) { + fprintf(stderr, "SCT list mismatch\n"); + return false; + } + } + + if (config->expect_verify_result) { + int expected_verify_result = config->verify_fail ? + X509_V_ERR_APPLICATION_VERIFICATION : + X509_V_OK; + + if (SSL_get_verify_result(ssl) != expected_verify_result) { + fprintf(stderr, "Wrong certificate verification result\n"); + return false; + } + } + + if (!config->expect_peer_cert_file.empty()) { + bssl::UniquePtr<X509> expect_leaf; + bssl::UniquePtr<STACK_OF(X509)> expect_chain; + if (!LoadCertificate(&expect_leaf, &expect_chain, + config->expect_peer_cert_file)) { + return false; + } + + // For historical reasons, clients report a chain with a leaf and servers + // without. + if (!config->is_server) { + if (!sk_X509_insert(expect_chain.get(), expect_leaf.get(), 0)) { + return false; + } + X509_up_ref(expect_leaf.get()); // sk_X509_push takes ownership. + } + + bssl::UniquePtr<X509> leaf(SSL_get_peer_certificate(ssl)); + STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl); + if (X509_cmp(leaf.get(), expect_leaf.get()) != 0) { + fprintf(stderr, "Received a different leaf certificate than expected.\n"); + return false; + } + + if (sk_X509_num(chain) != sk_X509_num(expect_chain.get())) { + fprintf(stderr, "Received a chain of length %zu instead of %zu.\n", + sk_X509_num(chain), sk_X509_num(expect_chain.get())); + return false; + } + + for (size_t i = 0; i < sk_X509_num(chain); i++) { + if (X509_cmp(sk_X509_value(chain, i), + sk_X509_value(expect_chain.get(), i)) != 0) { + fprintf(stderr, "Chain certificate %zu did not match.\n", + i + 1); + return false; + } + } + } + + if (SSL_get_session(ssl)->peer_sha256_valid != + config->expect_sha256_client_cert) { + fprintf(stderr, + "Unexpected SHA-256 client cert state: expected:%d is_resume:%d.\n", + config->expect_sha256_client_cert, is_resume); + return false; + } + + if (config->expect_sha256_client_cert && + SSL_get_session(ssl)->certs != nullptr) { + fprintf(stderr, "Have both client cert and SHA-256 hash: is_resume:%d.\n", + is_resume); + return false; + } + + return true; +} + // CheckHandshakeProperties checks, immediately after |ssl| completes its // initial handshake (or False Starts), whether all the properties are // consistent with the test configuration and invariants. static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, const TestConfig *config) { + if (!CheckAuthProperties(ssl, is_resume, config)) { + return false; + } + if (SSL_get_current_cipher(ssl) == nullptr) { fprintf(stderr, "null cipher after handshake\n"); return false; @@ -1613,40 +1721,6 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, return false; } - if (!config->expected_ocsp_response.empty()) { - const uint8_t *data; - size_t len; - SSL_get0_ocsp_response(ssl, &data, &len); - if (config->expected_ocsp_response.size() != len || - OPENSSL_memcmp(config->expected_ocsp_response.data(), data, len) != 0) { - fprintf(stderr, "OCSP response mismatch\n"); - return false; - } - } - - if (!config->expected_signed_cert_timestamps.empty()) { - const uint8_t *data; - size_t len; - SSL_get0_signed_cert_timestamp_list(ssl, &data, &len); - if (config->expected_signed_cert_timestamps.size() != len || - OPENSSL_memcmp(config->expected_signed_cert_timestamps.data(), data, - len) != 0) { - fprintf(stderr, "SCT list mismatch\n"); - return false; - } - } - - if (config->expect_verify_result) { - int expected_verify_result = config->verify_fail ? - X509_V_ERR_APPLICATION_VERIFICATION : - X509_V_OK; - - if (SSL_get_verify_result(ssl) != expected_verify_result) { - fprintf(stderr, "Wrong certificate verification result\n"); - return false; - } - } - if (config->expect_peer_signature_algorithm != 0 && config->expect_peer_signature_algorithm != SSL_get_peer_signature_algorithm(ssl)) { @@ -1705,65 +1779,6 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, } } - if (!config->expect_peer_cert_file.empty()) { - bssl::UniquePtr<X509> expect_leaf; - bssl::UniquePtr<STACK_OF(X509)> expect_chain; - if (!LoadCertificate(&expect_leaf, &expect_chain, - config->expect_peer_cert_file)) { - return false; - } - - // For historical reasons, clients report a chain with a leaf and servers - // without. - if (!config->is_server) { - if (!sk_X509_insert(expect_chain.get(), expect_leaf.get(), 0)) { - return false; - } - X509_up_ref(expect_leaf.get()); // sk_X509_push takes ownership. - } - - bssl::UniquePtr<X509> leaf(SSL_get_peer_certificate(ssl)); - STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl); - if (X509_cmp(leaf.get(), expect_leaf.get()) != 0) { - fprintf(stderr, "Received a different leaf certificate than expected.\n"); - return false; - } - - if (sk_X509_num(chain) != sk_X509_num(expect_chain.get())) { - fprintf(stderr, "Received a chain of length %zu instead of %zu.\n", - sk_X509_num(chain), sk_X509_num(expect_chain.get())); - return false; - } - - for (size_t i = 0; i < sk_X509_num(chain); i++) { - if (X509_cmp(sk_X509_value(chain, i), - sk_X509_value(expect_chain.get(), i)) != 0) { - fprintf(stderr, "Chain certificate %zu did not match.\n", - i + 1); - return false; - } - } - } - - bool expected_sha256_client_cert = config->expect_sha256_client_cert_initial; - if (is_resume) { - expected_sha256_client_cert = config->expect_sha256_client_cert_resume; - } - - if (SSL_get_session(ssl)->peer_sha256_valid != expected_sha256_client_cert) { - fprintf(stderr, - "Unexpected SHA-256 client cert state: expected:%d is_resume:%d.\n", - expected_sha256_client_cert, is_resume); - return false; - } - - if (expected_sha256_client_cert && - SSL_get_session(ssl)->certs != nullptr) { - fprintf(stderr, "Have both client cert and SHA-256 hash: is_resume:%d.\n", - is_resume); - return false; - } - if (is_resume && config->expect_ticket_age_skew != 0 && SSL_get_ticket_age_skew(ssl) != config->expect_ticket_age_skew) { fprintf(stderr, "Ticket age skew was %" PRId32 ", wanted %d\n", @@ -2006,10 +2021,7 @@ static bool DoConnection(bssl::UniquePtr<SSL_SESSION> *out_session, if (config->max_cert_list > 0) { SSL_set_max_cert_list(ssl.get(), config->max_cert_list); } - if (!is_resume && config->retain_only_sha256_client_cert_initial) { - SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1); - } - if (is_resume && config->retain_only_sha256_client_cert_resume) { + if (config->retain_only_sha256_client_cert) { SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1); } if (config->max_send_fragment > 0) { @@ -2372,6 +2384,21 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl, return false; } + if (SSL_total_renegotiations(ssl) > 0) { + if (!SSL_get_session(ssl)->not_resumable) { + fprintf(stderr, + "Renegotiations should never produce resumable sessions.\n"); + return false; + } + + // Re-check authentication properties after a renegotiation. The reported + // values should remain unchanged even if the server sent different SCT + // lists. + if (!CheckAuthProperties(ssl, is_resume, config)) { + return false; + } + } + if (SSL_total_renegotiations(ssl) != config->expect_total_renegotiations) { fprintf(stderr, "Expected %d renegotiations, got %d\n", config->expect_total_renegotiations, SSL_total_renegotiations(ssl)); |