| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System.Diagnostics; |
| | | 5 | | using System.Security.Authentication; |
| | | 6 | | using static Interop.SspiCli; |
| | | 7 | | |
| | | 8 | | namespace System.Net.Security |
| | | 9 | | { |
| | | 10 | | internal partial struct SslConnectionInfo |
| | | 11 | | { |
| | | 12 | | private static byte[]? GetNegotiatedApplicationProtocol(SafeDeleteContext context) |
| | 0 | 13 | | { |
| | 0 | 14 | | Interop.SecPkgContext_ApplicationProtocol alpnContext = default; |
| | 0 | 15 | | bool success = SSPIWrapper.QueryBlittableContextAttributes(GlobalSSPI.SSPISecureChannel, context, Interop.Ss |
| | | 16 | | |
| | | 17 | | // Check if the context returned is alpn data, with successful negotiation. |
| | 0 | 18 | | if (success && |
| | 0 | 19 | | alpnContext.ProtoNegoExt == Interop.ApplicationProtocolNegotiationExt.ALPN && |
| | 0 | 20 | | alpnContext.ProtoNegoStatus == Interop.ApplicationProtocolNegotiationStatus.Success) |
| | 0 | 21 | | { |
| | 0 | 22 | | if (alpnContext.Protocol.SequenceEqual(s_http1)) |
| | 0 | 23 | | { |
| | 0 | 24 | | return s_http1; |
| | | 25 | | } |
| | 0 | 26 | | else if (alpnContext.Protocol.SequenceEqual(s_http2)) |
| | 0 | 27 | | { |
| | 0 | 28 | | return s_http2; |
| | | 29 | | } |
| | 0 | 30 | | else if (alpnContext.Protocol.SequenceEqual(s_http3)) |
| | 0 | 31 | | { |
| | 0 | 32 | | return s_http3; |
| | | 33 | | } |
| | | 34 | | |
| | 0 | 35 | | return alpnContext.Protocol.ToArray(); |
| | | 36 | | } |
| | | 37 | | |
| | 0 | 38 | | return null; |
| | 0 | 39 | | } |
| | | 40 | | |
| | | 41 | | public void UpdateSslConnectionInfo(SafeDeleteContext securityContext) |
| | 0 | 42 | | { |
| | 0 | 43 | | SecPkgContext_ConnectionInfo interopConnectionInfo = default; |
| | 0 | 44 | | bool success = SSPIWrapper.QueryBlittableContextAttributes( |
| | 0 | 45 | | GlobalSSPI.SSPISecureChannel, |
| | 0 | 46 | | securityContext, |
| | 0 | 47 | | Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO, |
| | 0 | 48 | | ref interopConnectionInfo); |
| | 0 | 49 | | Debug.Assert(success); |
| | | 50 | | |
| | 0 | 51 | | TlsCipherSuite cipherSuite = default; |
| | 0 | 52 | | SecPkgContext_CipherInfo cipherInfo = default; |
| | | 53 | | |
| | 0 | 54 | | success = SSPIWrapper.QueryBlittableContextAttributes(GlobalSSPI.SSPISecureChannel, securityContext, Interop |
| | 0 | 55 | | if (success) |
| | 0 | 56 | | { |
| | 0 | 57 | | cipherSuite = (TlsCipherSuite)cipherInfo.dwCipherSuite; |
| | 0 | 58 | | } |
| | | 59 | | |
| | 0 | 60 | | Protocol = interopConnectionInfo.Protocol; |
| | 0 | 61 | | DataCipherAlg = interopConnectionInfo.DataCipherAlg; |
| | 0 | 62 | | DataKeySize = interopConnectionInfo.DataKeySize; |
| | 0 | 63 | | DataHashAlg = interopConnectionInfo.DataHashAlg; |
| | 0 | 64 | | DataHashKeySize = interopConnectionInfo.DataHashKeySize; |
| | 0 | 65 | | KeyExchangeAlg = interopConnectionInfo.KeyExchangeAlg; |
| | 0 | 66 | | KeyExchKeySize = interopConnectionInfo.KeyExchKeySize; |
| | | 67 | | |
| | 0 | 68 | | TlsCipherSuite = cipherSuite; |
| | | 69 | | |
| | | 70 | | // In TLS1.3, Schannel may erroneously report empty ALPN after |
| | | 71 | | // receiving resumption ticket (fake Renegotiation). Avoid updating |
| | | 72 | | // ApplicationProtocol in this case if we already have some, TLS1.3 |
| | | 73 | | // does not allow ALPN changes after the initial handshake. |
| | | 74 | | // |
| | | 75 | | // TLS 1.2 and below theoretically support ALPN changes during |
| | | 76 | | // Renegotiation. |
| | 0 | 77 | | if (ApplicationProtocol == null || (Protocol & (int)SslProtocols.Tls13) == 0) |
| | 0 | 78 | | { |
| | 0 | 79 | | ApplicationProtocol = GetNegotiatedApplicationProtocol(securityContext); |
| | 0 | 80 | | } |
| | | 81 | | |
| | 0 | 82 | | SecPkgContext_SessionInfo info = default; |
| | 0 | 83 | | TlsResumed = SSPIWrapper.QueryBlittableContextAttributes( |
| | 0 | 84 | | GlobalSSPI.SSPISecureChannel, |
| | 0 | 85 | | securityContext, |
| | 0 | 86 | | Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SESSION_INFO, |
| | 0 | 87 | | ref info) && |
| | 0 | 88 | | (info.dwFlags & (uint)SecPkgContext_SessionInfo.Flags.SSL_SESSION_RECONNECT) != 0; |
| | 0 | 89 | | } |
| | | 90 | | } |
| | | 91 | | } |
| | | 92 | | |