private static byte[]? GetNegotiatedApplicationProtocol(SafeDeleteContext context) { Interop.SecPkgContext_ApplicationProtocol alpnContext = default; bool success = SSPIWrapper.QueryBlittableContextAttributes(GlobalSSPI.SSPISecureChannel, context, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL, ref alpnContext); // Check if the context returned is alpn data, with successful negotiation. if (success && alpnContext.ProtoNegoExt == Interop.ApplicationProtocolNegotiationExt.ALPN && alpnContext.ProtoNegoStatus == Interop.ApplicationProtocolNegotiationStatus.Success) { if (alpnContext.Protocol.SequenceEqual(s_http1)) { return(s_http1); } else if (alpnContext.Protocol.SequenceEqual(s_http2)) { return(s_http2); } else if (alpnContext.Protocol.SequenceEqual(s_http3)) { return(s_http3); } return(alpnContext.Protocol.ToArray()); } return(null); }
internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context) { Interop.SecPkgContext_ApplicationProtocol alpnContext = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, context, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL) as Interop.SecPkgContext_ApplicationProtocol; // Check if the context returned is alpn data, with successful negotiation. if (alpnContext == null || alpnContext.ProtoNegoExt != Interop.ApplicationProtocolNegotiationExt.ALPN || alpnContext.ProtoNegoStatus != Interop.ApplicationProtocolNegotiationStatus.Success) { return(null); } return(alpnContext.Protocol); }