22using System . Collections . Generic ;
33using System . Linq ;
44using System . Net . Security ;
5- using System . Security . Cryptography ;
65using System . Security . Cryptography . X509Certificates ;
76using Couchbase . Core . Compatibility ;
87using Couchbase . Core . Logging ;
@@ -57,26 +56,28 @@ public static ICertificateFactory GetCertificatesFromStore(CertificateStoreSearc
5756 /// <remarks>
5857 /// This in-memory certificate does not work on .NET Framework (legacy) clients.
5958 /// </remarks>
60- internal const string CapellaCaCertPem =
61- @"-----BEGIN CERTIFICATE-----
62- MIIDFTCCAf2gAwIBAgIRANLVkgOvtaXiQJi0V6qeNtswDQYJKoZIhvcNAQELBQAw
63- JDESMBAGA1UECgwJQ291Y2hiYXNlMQ4wDAYDVQQLDAVDbG91ZDAeFw0xOTEyMDYy
64- MjEyNTlaFw0yOTEyMDYyMzEyNTlaMCQxEjAQBgNVBAoMCUNvdWNoYmFzZTEOMAwG
65- A1UECwwFQ2xvdWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfvOIi
66- enG4Dp+hJu9asdxEMRmH70hDyMXv5ZjBhbo39a42QwR59y/rC/sahLLQuNwqif85
67- Fod1DkqgO6Ng3vecSAwyYVkj5NKdycQu5tzsZkghlpSDAyI0xlIPSQjoORA/pCOU
68- WOpymA9dOjC1bo6rDyw0yWP2nFAI/KA4Z806XeqLREuB7292UnSsgFs4/5lqeil6
69- rL3ooAw/i0uxr/TQSaxi1l8t4iMt4/gU+W52+8Yol0JbXBTFX6itg62ppb/Eugmn
70- mQRMgL67ccZs7cJ9/A0wlXencX2ohZQOR3mtknfol3FH4+glQFn27Q4xBCzVkY9j
71- KQ20T1LgmGSngBInAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
72- FJQOBPvrkU2In1Sjoxt97Xy8+cKNMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B
73- AQsFAAOCAQEARgM6XwcXPLSpFdSf0w8PtpNGehmdWijPM3wHb7WZiS47iNen3oq8
74- m2mm6V3Z57wbboPpfI+VEzbhiDcFfVnK1CXMC0tkF3fnOG1BDDvwt4jU95vBiNjY
75- xdzlTP/Z+qr0cnVbGBSZ+fbXstSiRaaAVcqQyv3BRvBadKBkCyPwo+7svQnScQ5P
76- Js7HEHKVms5tZTgKIw1fbmgR2XHleah1AcANB+MAPBCcTgqurqr5G7W2aPSBLLGA
77- fRIiVzm7VFLc7kWbp7ENH39HVG6TZzKnfl9zJYeiklo5vQQhGSMhzBsO70z4RRzi
78- DPFAN/4qZAgD5q3AFNIq2WWADFQGSwVJhg==
79- -----END CERTIFICATE-----" ;
59+ internal static ReadOnlySpan < byte > CapellaCaCertPem =>
60+ """
61+ -----BEGIN CERTIFICATE-----
62+ MIIDFTCCAf2gAwIBAgIRANLVkgOvtaXiQJi0V6qeNtswDQYJKoZIhvcNAQELBQAw
63+ JDESMBAGA1UECgwJQ291Y2hiYXNlMQ4wDAYDVQQLDAVDbG91ZDAeFw0xOTEyMDYy
64+ MjEyNTlaFw0yOTEyMDYyMzEyNTlaMCQxEjAQBgNVBAoMCUNvdWNoYmFzZTEOMAwG
65+ A1UECwwFQ2xvdWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfvOIi
66+ enG4Dp+hJu9asdxEMRmH70hDyMXv5ZjBhbo39a42QwR59y/rC/sahLLQuNwqif85
67+ Fod1DkqgO6Ng3vecSAwyYVkj5NKdycQu5tzsZkghlpSDAyI0xlIPSQjoORA/pCOU
68+ WOpymA9dOjC1bo6rDyw0yWP2nFAI/KA4Z806XeqLREuB7292UnSsgFs4/5lqeil6
69+ rL3ooAw/i0uxr/TQSaxi1l8t4iMt4/gU+W52+8Yol0JbXBTFX6itg62ppb/Eugmn
70+ mQRMgL67ccZs7cJ9/A0wlXencX2ohZQOR3mtknfol3FH4+glQFn27Q4xBCzVkY9j
71+ KQ20T1LgmGSngBInAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
72+ FJQOBPvrkU2In1Sjoxt97Xy8+cKNMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B
73+ AQsFAAOCAQEARgM6XwcXPLSpFdSf0w8PtpNGehmdWijPM3wHb7WZiS47iNen3oq8
74+ m2mm6V3Z57wbboPpfI+VEzbhiDcFfVnK1CXMC0tkF3fnOG1BDDvwt4jU95vBiNjY
75+ xdzlTP/Z+qr0cnVbGBSZ+fbXstSiRaaAVcqQyv3BRvBadKBkCyPwo+7svQnScQ5P
76+ Js7HEHKVms5tZTgKIw1fbmgR2XHleah1AcANB+MAPBCcTgqurqr5G7W2aPSBLLGA
77+ fRIiVzm7VFLc7kWbp7ENH39HVG6TZzKnfl9zJYeiklo5vQQhGSMhzBsO70z4RRzi
78+ DPFAN/4qZAgD5q3AFNIq2WWADFQGSwVJhg==
79+ -----END CERTIFICATE-----
80+ """u8 ;
8081
8182 /// <summary>
8283 /// The certificate to use by default for connecting to *.cloud.couchbase.com.
@@ -87,12 +88,11 @@ public static ICertificateFactory GetCertificatesFromStore(CertificateStoreSearc
8788 [ InterfaceStability ( Level . Volatile ) ]
8889 #if NETSTANDARD2_0 || NETSTANDARD2_1 || NET8_0
8990 internal static readonly X509Certificate2 CapellaCaCert = new X509Certificate2 (
90- rawData : System . Text . Encoding . ASCII . GetBytes ( CapellaCaCertPem ) ,
91+ rawData : CapellaCaCertPem . ToArray ( ) ,
9192 password : ( string ? ) null ) ;
9293 #else
9394 internal static X509Certificate2 CapellaCaCert =
94- X509CertificateLoader . LoadCertificate (
95- System . Text . Encoding . ASCII . GetBytes ( CapellaCaCertPem ) ) ;
95+ X509CertificateLoader . LoadCertificate ( CapellaCaCertPem ) ;
9696 #endif
9797
9898 /// <summary>
@@ -136,15 +136,27 @@ internal static RemoteCertificateValidationCallback GetValidatorWithPredefinedCe
136136 {
137137 // first attempt - validation from system trust store plus whatever certs have been provided
138138 // user supplied or Capella. If self-signed, will not be sufficient and need to be CustomTrustStore
139- foreach ( var defaultCert in certs )
139+
140+ bool built ;
141+ try
140142 {
141- MaybeLogCert ( "X509 adding from certs to ExtraStore" , defaultCert , logger ) ;
142- chain . ChainPolicy . ExtraStore . Add ( defaultCert ) ;
143- }
143+ foreach ( var defaultCert in certs )
144+ {
145+ MaybeLogCert ( "X509 adding from certs to ExtraStore" , defaultCert , logger ) ;
146+ chain . ChainPolicy . ExtraStore . Add ( new X509Certificate2 ( defaultCert ) ) ;
147+ }
144148
145- MaybeLogChainElements ( "X509 chain element cert is" , chain , logger ) ;
149+ MaybeLogChainElements ( "X509 chain element cert is" , chain , logger ) ;
150+
151+ built = chain . Build ( cert2 ) ;
152+ }
153+ finally
154+ {
155+ // Remove the extra certs so they aren't disposed during .NET cleanup after
156+ // the callback completes.
157+ chain . ChainPolicy . ExtraStore . Clear ( ) ;
158+ }
146159
147- var built = chain . Build ( cert2 ) ;
148160 if ( ! built &&
149161 ( chain . ChainStatus . First ( ) . Status ==
150162 X509ChainStatusFlags . UntrustedRoot /* probably Capella self-signed KV */ ||
0 commit comments