| File: System\Net\CertificateValidationPal.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Security\src\System.Net.Security.csproj (System.Net.Security) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Net.Security; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; namespace System.Net { internal static partial class CertificateValidationPal { private static readonly object s_syncObject = new object(); private static X509Store? s_myCertStoreEx; private static X509Store? s_myMachineCertStoreEx; private static X509Chain? s_chain; internal static X509Certificate2? GetRemoteCertificate(SafeDeleteContext? securityContext) => GetRemoteCertificate(securityContext, retrieveChainCertificates: false, ref s_chain, null); internal static X509Certificate2? GetRemoteCertificate(SafeDeleteContext? securityContext, ref X509Chain? chain, X509ChainPolicy? chainPolicy) => GetRemoteCertificate(securityContext, retrieveChainCertificates: true, ref chain, chainPolicy); static partial void CheckSupportsStore(StoreLocation storeLocation, ref bool hasSupport); internal static X509Store? EnsureStoreOpened(bool isMachineStore) { X509Store? store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx; if (store == null) { StoreLocation storeLocation = isMachineStore ? StoreLocation.LocalMachine : StoreLocation.CurrentUser; // On Windows and OSX CheckSupportsStore is not defined, so the call is eliminated and the // if should be folded out. // // On Unix it will prevent the lock from being held and released over and over for the LocalMachine store. bool supportsStore = true; CheckSupportsStore(storeLocation, ref supportsStore); if (!supportsStore) { return null; } lock (s_syncObject) { store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx; if (store == null) { try { // NOTE: that if this call fails we won't keep track and the next time we enter we will try to open the store again. store = OpenStore(storeLocation); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"storeLocation: {storeLocation} returned store {store}"); if (isMachineStore) { s_myMachineCertStoreEx = store; } else { s_myCertStoreEx = store; } } catch (Exception exception) { if (exception is CryptographicException || exception is SecurityException) { Debug.Fail($"Failed to open cert store, location: {storeLocation} exception: {exception}"); return null; } if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, SR.Format(SR.net_log_open_store_failed, storeLocation, exception)); throw; } } } } return store; } } }