// // Extracts a remote certificate upon request. // internal override X509Certificate2 GetRemoteCertificate(SafeDeleteContext securityContext, out X509Certificate2Collection remoteCertificateStore) { remoteCertificateStore = null; if (securityContext == null) { return(null); } GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}"); X509Certificate2 result = null; SafeFreeCertContext remoteContext = null; try { int errorCode = SSPIWrapper.QueryContextRemoteCertificate(GlobalSSPI.SSPISecureChannel, securityContext, out remoteContext); if (remoteContext != null && !remoteContext.IsInvalid) { result = new X509Certificate2(remoteContext.DangerousGetHandle()); } } finally { if (remoteContext != null && !remoteContext.IsInvalid) { remoteCertificateStore = UnmanagedCertificateContext.GetRemoteCertificatesFromStoreContext(remoteContext); remoteContext.Dispose(); } } if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_remote_certificate, (result == null ? "null" : result.ToString(true)))); } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}", (result == null ? "null" : result.Subject)); return(result); }
// // Extracts a remote certificate upon request. // internal override X509Certificate2 GetRemoteCertificate(SafeDeleteContext securityContext, out X509Certificate2Collection remoteCertificateStore) { remoteCertificateStore = null; bool gotReference = false; if (securityContext == null) { return(null); } GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}"); X509Certificate2 result = null; SafeFreeCertContext remoteContext = null; try { int errorCode = SSPIWrapper.QueryContextRemoteCertificate(GlobalSSPI.SSPISecureChannel, securityContext, out remoteContext); if (remoteContext != null && !remoteContext.IsInvalid) { remoteContext.DangerousAddRef(ref gotReference); result = new X509Certificate2(remoteContext.DangerousGetHandle()); } remoteCertificateStore = new X509Certificate2Collection(); using (SafeSharedX509StackHandle chainStack = Interop.OpenSsl.GetPeerCertificateChain(securityContext.SslContext)) { if (!chainStack.IsInvalid) { int count = Interop.Crypto.GetX509StackFieldCount(chainStack); for (int i = 0; i < count; i++) { IntPtr certPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (certPtr != IntPtr.Zero) { // X509Certificate2(IntPtr) calls X509_dup, so the reference is appropriately tracked. X509Certificate2 chainCert = new X509Certificate2(certPtr); remoteCertificateStore.Add(chainCert); } } } } } finally { if (gotReference) { remoteContext.DangerousRelease(); } if (remoteContext != null) { remoteContext.Dispose(); } } if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_remote_certificate, (result == null ? "null" : result.ToString(true)))); } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}", (result == null ? "null" : result.Subject)); return(result); }