summaryrefslogtreecommitdiff
path: root/src/ssl/test/bssl_shim.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/test/bssl_shim.cc')
-rw-r--r--src/ssl/test/bssl_shim.cc221
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));