diff options
Diffstat (limited to 'src/mongo/util/net/ssl_manager_openssl.cpp')
| -rw-r--r-- | src/mongo/util/net/ssl_manager_openssl.cpp | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp index 48461e4120d..f2ddee148c7 100644 --- a/src/mongo/util/net/ssl_manager_openssl.cpp +++ b/src/mongo/util/net/ssl_manager_openssl.cpp @@ -123,7 +123,12 @@ struct X509StackDeleter { } } }; -using UniqueStackOfX509 = std::unique_ptr<STACK_OF(X509), X509StackDeleter>; + +// 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 = { @@ -319,6 +324,25 @@ X509* X509_OBJECT_get0_X509(const X509_OBJECT* a) { return a->data.x509; } +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)); + UniqueX509 peer(SSL_get_peer_certificate(s)); + auto* peerChain = SSL_get_peer_cert_chain(s); + + UniqueX509StoreCtx ctx(X509_STORE_CTX_new()); + if (!X509_STORE_CTX_init(ctx.get(), store, peer.get(), peerChain)) { + return nullptr; + } + + if (X509_verify_cert(ctx.get()) <= 0) { + return nullptr; + } + + return X509_STORE_CTX_get1_chain(ctx.get()); +} + const OCSP_CERTID* OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP* single) { return single->certId; } @@ -351,23 +375,14 @@ static ASN1OID tlsFeatureOID("1.3.6.1.5.5.7.1.24", "tlsfeature", "TLS Feature"); static int const NID_tlsfeature = OBJ_create(tlsFeatureOID.identifier.c_str(), tlsFeatureOID.shortDescription.c_str(), tlsFeatureOID.longDescription.c_str()); -#endif - -UniqueStackOfX509 SSLgetVerifiedChain(SSL* s) { - auto* store = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)); - auto* peerChain = SSL_get_peer_cert_chain(s); - UniqueX509 peer(SSL_get_peer_certificate(s)); - UniqueX509StoreCtx ctx(X509_STORE_CTX_new()); - if (!X509_STORE_CTX_init(ctx.get(), store, peer.get(), peerChain)) { - return nullptr; - } +#else +using UniqueVerifiedChainPolyfill = std::unique_ptr<STACK_OF(X509), X509StackDeleterNoOp>; - if (X509_verify_cert(ctx.get()) <= 0) { - return nullptr; - } +#endif - return UniqueStackOfX509(X509_STORE_CTX_get1_chain(ctx.get())); +UniqueVerifiedChainPolyfill SSLgetVerifiedChain(SSL* s) { + return UniqueVerifiedChainPolyfill(SSL_get0_verified_chain(s)); } SSLX509Name convertX509ToSSLX509Name(X509_NAME* x509Name) { @@ -641,7 +656,7 @@ std::vector<std::vector<unsigned char>> convertStackOfX509ToDERVec(STACK_OF(X509 } struct OCSPCacheKey { - OCSPCacheKey(UniqueX509 cert, SSL_CTX* context, UniqueStackOfX509 intermediateCerts) + OCSPCacheKey(UniqueX509 cert, SSL_CTX* context, UniqueVerifiedChainPolyfill intermediateCerts) : peerCert(std::move(cert)), context(context), intermediateCerts(std::move(intermediateCerts)), @@ -2539,8 +2554,6 @@ Status SSLManagerOpenSSL::initSSLContext(SSL_CTX* context, } } - // If the user has specified --setParameter tlsUseSystemCA=true, then no params.sslCAFile nor - // params.sslClusterCAFile will be defined, and the SSL Manager will fall back to the System CA. std::string cafile = params.sslCAFile; if (direction == ConnectionDirection::kIncoming && !params.sslClusterCAFile.empty()) { cafile = params.sslClusterCAFile; @@ -2955,6 +2968,7 @@ Status SSLManagerOpenSSL::_setupCA(SSL_CTX* context, const std::string& caFile) // Set SSL to require peer (client) certificate verification // if a certificate is presented SSL_CTX_set_verify(context, SSL_VERIFY_PEER, &SSLManagerOpenSSL::verify_cb); + _sslConfiguration.hasCA = true; return Status::OK(); } @@ -2979,7 +2993,7 @@ Status SSLManagerOpenSSL::_setupSystemCA(SSL_CTX* context) { << "(default certificate file: " << X509_get_default_cert_file() << ", " << "default certificate path: " << X509_get_default_cert_dir() << ")"}; } - SSL_CTX_set_verify(context, SSL_VERIFY_PEER, &SSLManagerOpenSSL::verify_cb); + return Status::OK(); } @@ -3219,6 +3233,9 @@ Future<SSLPeerInfo> SSLManagerOpenSSL::parseAndValidatePeerCertificate( recordTLSVersion(tlsVersionStatus.getValue(), hostForLogging); + if (!_sslConfiguration.hasCA && isSSLServer) + return SSLPeerInfo(sni); + UniqueX509 peerCert(SSL_get_peer_certificate(conn)); if (nullptr == peerCert) { // no certificate presented by peer @@ -3271,11 +3288,11 @@ Future<SSLPeerInfo> SSLManagerOpenSSL::parseAndValidatePeerCertificate( // TODO: check optional cipher restriction, using cert. auto peerSubject = getCertificateSubjectX509Name(peerCert.get()); - const auto cipher = SSL_get_current_cipher(conn); - LOGV2_INFO(6723801, - "Accepted TLS connection from peer", - "peerSubject"_attr = peerSubject, - "cipher"_attr = SSL_CIPHER_get_name(cipher)); + LOGV2_DEBUG(23229, + 2, + "Accepted TLS connection from peer: {peerSubject}", + "Accepted TLS connection from peer", + "peerSubject"_attr = peerSubject); StatusWith<stdx::unordered_set<RoleName>> swPeerCertificateRoles = _parsePeerRoles(peerCert.get()); |
