diff options
author | Shreyas Kalyan <shreyas.kalyan@10gen.com> | 2020-03-30 16:52:20 -0700 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-03 16:43:35 +0000 |
commit | 65d93bcbc3acf6782fce539c3629d2112ec1df1f (patch) | |
tree | 02428fdd1845e24fe47206512108b68d0f2edc55 /src/mongo/util/net | |
parent | 129b8993b6575231509980f29587d3214d56e8e1 (diff) | |
download | mongo-65d93bcbc3acf6782fce539c3629d2112ec1df1f.tar.gz |
SERVER-47051 Investigate OCSP failures on 4.3.4 and on 4.5.0
Diffstat (limited to 'src/mongo/util/net')
-rw-r--r-- | src/mongo/util/net/ssl_manager_openssl.cpp | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp index 22f4170bd92..91b5a7341f0 100644 --- a/src/mongo/util/net/ssl_manager_openssl.cpp +++ b/src/mongo/util/net/ssl_manager_openssl.cpp @@ -97,6 +97,22 @@ using UniqueX509StoreCtx = using UniqueX509 = std::unique_ptr<X509, OpenSSLDeleter<decltype(X509_free), ::X509_free>>; +// This deleter should be used when you have a stack of X509 objects that you own and that +// needs to be deleted. +struct X509StackDeleter { + void operator()(STACK_OF(X509) * chain) { + if (chain) { + sk_X509_pop_free(chain, X509_free); + } + } +}; + +// If we have an X509 Stack that is owned by an internal SSL Object, we need to use this +// deleter. +struct X509StackDeleterNoOp { + void operator()(STACK_OF(X509) * chain) {} +}; + // Modulus for Diffie-Hellman parameter 'ffdhe3072' defined in RFC 7919 constexpr std::array<std::uint8_t, 384> ffdhe3072_p = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, @@ -287,15 +303,7 @@ X509* X509_OBJECT_get0_X509(const X509_OBJECT* a) { return a->data.x509; } -// On OpenSSL < 1.1.0, this chain isn't attached to -// the SSL session, so we need it to dispose of itself. -struct VerifiedChainDeleter { - void operator()(STACK_OF(X509) * chain) { - if (chain) { - sk_X509_pop_free(chain, X509_free); - } - } -}; +using UniqueVerifiedChainPolyfill = std::unique_ptr<STACK_OF(X509), X509StackDeleter>; STACK_OF(X509) * SSL_get0_verified_chain(SSL* s) { auto* store = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)); @@ -348,13 +356,10 @@ static int const NID_tlsfeature = OBJ_create(tlsFeatureOID.identifier.c_str(), tlsFeatureOID.longDescription.c_str()); #else -// No-op deleter for OpenSSL >= 1.1.0 -struct VerifiedChainDeleter { - void operator()(STACK_OF(X509) * chain) {} -}; +using UniqueVerifiedChainPolyfill = std::unique_ptr<STACK_OF(X509), X509StackDeleterNoOp>; + #endif -using UniqueVerifiedChainPolyfill = std::unique_ptr<STACK_OF(X509), VerifiedChainDeleter>; UniqueVerifiedChainPolyfill SSLgetVerifiedChain(SSL* s) { return UniqueVerifiedChainPolyfill(SSL_get0_verified_chain(s)); } @@ -1674,6 +1679,8 @@ Future<void> SSLManagerOpenSSL::ocspClientVerification(SSL* ssl, const ExecutorP return convert(std::move(semifuture)).onCompletion(validate).then(refetchIfInvalidAndReturn); } +using StoreCtxVerifiedChain = std::unique_ptr<STACK_OF(X509), X509StackDeleter>; + #if OPENSSL_VERSION_NUMBER >= 0x10002000L Status SSLManagerOpenSSL::stapleOCSPResponse(SSL_CTX* context) { if (MONGO_unlikely(disableStapling.shouldFail()) || !tlsOCSPEnabled) { @@ -1693,14 +1700,26 @@ Status SSLManagerOpenSSL::stapleOCSPResponse(SSL_CTX* context) { } auto fetchAndStaple = [context, cert]() -> Future<Milliseconds> { - STACK_OF(X509) * intermediateCertsPtr; + // Generate a new verified X509StoreContext to get our own certificate chain + UniqueX509StoreCtx storeCtx(X509_STORE_CTX_new()); + if (!storeCtx) { + return getSSLFailure("Could not create X509 store."); + } + + if (X509_STORE_CTX_init(storeCtx.get(), SSL_CTX_get_cert_store(context), NULL, NULL) == 0) { + return getSSLFailure("Could not initialize the X509 Store Context."); + } + + X509_STORE_CTX_set_cert(storeCtx.get(), cert); - if (SSL_CTX_get0_chain_certs(context, &intermediateCertsPtr) == 0) { - return getSSLFailure("Could not get chain for SSL Context."); + if (X509_verify_cert(storeCtx.get()) <= 0) { + return getSSLFailure("Could not verify X509 certificate store for OCSP Stapling."); } - UniqueVerifiedChainPolyfill intermediateCerts(intermediateCertsPtr); + // Extract the chain from the verified X509StoreCtx + StoreCtxVerifiedChain intermediateCerts(X509_STORE_CTX_get1_chain(storeCtx.get())); + // Continue with OCSP Stapling logic auto swOCSPContext = extractOcspUris(context, cert, intermediateCerts.get()); if (!swOCSPContext.isOK()) { LOGV2_WARNING(23232, "Could not staple OCSP response to outgoing certificate."); |