| File: System\Net\Security\TlsContext.OpenSsl.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 Microsoft.Win32.SafeHandles; namespace System.Net.Security { public sealed partial class TlsContext { // Long-lived OpenSSL SSL_CTX shared by every TlsSession created from this // TlsContext. Allocated lazily on the first session's handshake (via // AttachSharedNativeContext) so we can defer until cipher/protocol/cert // settings on the options bag are finalized. Disposed with the TlsContext. // // Cert/key/ALPN/SNI that are intrinsically per-session continue to live on // the SSL* handle (SafeSslHandle); the SSL_CTX carries only the bits that // are stable across every session: protocol mask, cipher list, encryption // policy, the cert-verify callback wiring, and the session-resume cache. private SafeSslContextHandle? _sslContext; private readonly object _sslContextLock = new object(); partial void AttachSharedNativeContext(SslAuthenticationOptions sessionOptions) { // Wedge mode reuses SslStream's existing per-handshake SSL_CTX caching path; // don't allocate a TlsContext-owned SSL_CTX that would conflict with it. if (_isWedge) { return; } // AllocateSslContext attaches the server cert directly to SSL_CTX. When the // server cert isn't known up front (ServerCertificateSelectionCallback or // deferred SetContext), each session resolves its own cert after the // ClientHello, so a shared SSL_CTX would carry no cert. Fall back to the // per-session allocation path in AllocateSslHandle. SslAuthenticationOptions options = Options; if (options.IsServer && options.CertificateContext is null) { return; } SafeSslContextHandle? ctx = _sslContext; if (ctx is null) { lock (_sslContextLock) { ctx = _sslContext; if (ctx is null) { // allowCached:false bypasses the global SslContextCacheKey lookup; // the handle returned is exclusively owned by this TlsContext. // enableResume honors the AllowTlsResume option on the bag so // server-side session resume works against this owned SSL_CTX. bool enableResume = sessionOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume && sessionOptions.EncryptionPolicy == EncryptionPolicy.RequireEncryption && sessionOptions.CipherSuitesPolicy == null; ctx = Interop.OpenSsl.GetOrCreateSslContextHandle(sessionOptions, allowCached: false, enableResume: enableResume); _sslContext = ctx; } } } sessionOptions.PreallocatedSslContext = ctx; } partial void DisposeNativeContext() { SafeSslContextHandle? ctx = _sslContext; _sslContext = null; ctx?.Dispose(); } } }