diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index 811e2cc2a64d9d..d94c4516944483 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -1053,7 +1053,13 @@ int32_t CryptoNative_SslAddExtraChainCert(SSL* ssl, X509* x509) return 0; } - if (SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 1,(void*)x509) == 1) + // larg must be 0 (SSL_add0_chain_cert), not 1 (SSL_add1_chain_cert). The caller, + // Interop.Ssl.AddExtraChainCertificates, up-refs and then calls SetHandleAsInvalid to + // hand its reference over, which is the add0 contract and matches + // CryptoNative_SslCtxAddExtraChainCert above. With add1 libssl takes a reference of its + // own and the caller's is abandoned rather than released, leaking one X509 per + // intermediate per SSL handle. + if (SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 0,(void*)x509) == 1) { return 1; }