summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2020-01-14 22:10:21 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-04 19:03:40 +0000
commitd3262e58c914fd0b5689069c7e8950c508cf1b4a (patch)
tree57adba8ec78610193c92aa5304dc43b7f007eeaf
parent21899f6bd537399e00dd86833d185b1ebd1fffe9 (diff)
downloadmongo-d3262e58c914fd0b5689069c7e8950c508cf1b4a.tar.gz
SERVER-44325 Provide SSL_get0_verified_chain() polyfill for OpenSSL < 1.1.0
(cherry picked from commit d4a93cea2eee5d2823d7a4d0224db06b4cd15b50)
-rw-r--r--src/mongo/util/net/ssl_manager.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index 1951264ce88..70854fd0a50 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -88,6 +88,14 @@ std::string removeFQDNRoot(std::string name) {
return name;
};
+struct UniqueX509StoreCtxDeleter {
+ void operator()(X509_STORE_CTX* ctx) {
+ if (ctx) {
+ ::X509_STORE_CTX_free(ctx);
+ }
+ }
+};
+using UniqueX509StoreCtx = std::unique_ptr<X509_STORE_CTX, UniqueX509StoreCtxDeleter>;
// Because the hostname having a slash is used by `mongo::SockAddr` to determine if a hostname is a
// Unix Domain Socket endpoint, this function uses the same logic. (See
@@ -270,8 +278,46 @@ const STACK_OF(X509_EXTENSION) * X509_get0_extensions(const X509* peerCert) {
inline int X509_NAME_ENTRY_set(const X509_NAME_ENTRY* ne) {
return ne->set;
}
+
+// 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);
+ }
+ }
+};
+
+STACK_OF(X509) * SSL_get0_verified_chain(SSL* s) {
+ auto* store = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s));
+ auto* 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, peerChain)) {
+ return nullptr;
+ }
+
+ if (X509_verify_cert(ctx.get()) <= 0) {
+ return nullptr;
+ }
+
+ return X509_STORE_CTX_get1_chain(ctx.get());
+}
+
+#else
+// No-op deleter for OpenSSL >= 1.1.0
+struct VerifiedChainDeleter {
+ void operator()(STACK_OF(X509) * chain) {}
+};
#endif
+using UniqueVerifiedChainPolyfill = std::unique_ptr<STACK_OF(X509), VerifiedChainDeleter>;
+UniqueVerifiedChainPolyfill SSLgetVerifiedChain(SSL* s) {
+ return UniqueVerifiedChainPolyfill(SSL_get0_verified_chain(s));
+}
+
/**
* Multithreaded Support for SSL.
*