Wait for CertificateStatus message to verify certificate.
Applications may require the stapled OCSP response in order to verify
the certificate within the verification callback.
Change-Id: I8002e527f90c3ce7b6a66e3203c0a68371aac5ec
Reviewed-on: https://boringssl-review.googlesource.com/5730
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 97044ab..eb5bdae 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -301,10 +301,29 @@
return 1;
}
-static int SkipVerify(int preverify_ok, X509_STORE_CTX *store_ctx) {
+static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) {
+ SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
+ SSL_get_ex_data_X509_STORE_CTX_idx());
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (!config->expected_ocsp_response.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_ocsp_response(ssl, &data, &len);
+ if (len == 0) {
+ fprintf(stderr, "OCSP response not available in verify callback\n");
+ return 0;
+ }
+ }
+
return 1;
}
+static int VerifyFail(X509_STORE_CTX *store_ctx, void *arg) {
+ store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+ return 0;
+}
+
static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
unsigned int *out_len, void *arg) {
const TestConfig *config = GetConfigPtr(ssl);
@@ -675,6 +694,12 @@
return nullptr;
}
+ if (config->verify_fail) {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifyFail, NULL);
+ } else {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifySucceed, NULL);
+ }
+
return ssl_ctx;
}
@@ -908,6 +933,17 @@
}
}
+ 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->is_server) {
/* Clients should expect a peer certificate chain iff this was not a PSK
* cipher suite. */
@@ -955,7 +991,10 @@
}
if (config->require_any_client_certificate) {
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- SkipVerify);
+ NULL);
+ }
+ if (config->verify_peer) {
+ SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, NULL);
}
if (config->false_start) {
SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 8124382..3c077bf 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2624,6 +2624,7 @@
"-enable-ocsp-stapling",
"-expect-ocsp-response",
base64.StdEncoding.EncodeToString(testOCSPResponse),
+ "-verify-peer",
},
})
@@ -2637,6 +2638,34 @@
},
})
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSucceed",
+ flags: []string{
+ "-verify-peer",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationFail",
+ flags: []string{
+ "-verify-fail",
+ "-verify-peer",
+ },
+ shouldFail: true,
+ expectedError: ":CERTIFICATE_VERIFY_FAILED:",
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSoftFail",
+ flags: []string{
+ "-verify-fail",
+ "-expect-verify-result",
+ },
+ })
+
if protocol == tls {
tests = append(tests, testCase{
name: "Renegotiate-Client",
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 7a87fd5..ad14ed3 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -93,6 +93,9 @@
{ "-check-close-notify", &TestConfig::check_close_notify },
{ "-shim-shuts-down", &TestConfig::shim_shuts_down },
{ "-microsoft-big-sslv3-buffer", &TestConfig::microsoft_big_sslv3_buffer },
+ { "-verify-fail", &TestConfig::verify_fail },
+ { "-verify-peer", &TestConfig::verify_peer },
+ { "-expect-verify-result", &TestConfig::expect_verify_result }
};
const Flag<std::string> kStringFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index a41af49..5776095 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -92,6 +92,9 @@
bool check_close_notify = false;
bool shim_shuts_down = false;
bool microsoft_big_sslv3_buffer = false;
+ bool verify_fail = false;
+ bool verify_peer = false;
+ bool expect_verify_result = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);