internal X509Certificate2 GetRemoteCertificate(out X509Certificate2Collection remoteCertificateStore) { remoteCertificateStore = null; if (this.m_SecurityContext == null) { return(null); } X509Certificate2 certificate = null; SafeFreeCertContext certContext = null; try { certContext = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.RemoteCertificate) as SafeFreeCertContext; if ((certContext != null) && !certContext.IsInvalid) { certificate = new X509Certificate2(certContext.DangerousGetHandle()); } } finally { if (certContext != null) { remoteCertificateStore = UnmanagedCertificateContext.GetStore(certContext); certContext.Close(); } } if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.GetString("net_log_remote_certificate", new object[] { (certificate == null) ? "null" : certificate.ToString(true) })); } return(certificate); }
public static void QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) { var interopConnectionInfo = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO) as SecPkgContext_ConnectionInfo; connectionInfo = new SslConnectionInfo(interopConnectionInfo); }
public static void QueryContextStreamSizes(SafeDeleteContext securityContext, out StreamSizes streamSizes) { var interopStreamSizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES) as SecPkgContext_StreamSizes; streamSizes = new StreamSizes(interopStreamSizes); }
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); }
internal void ProcessHandshakeSuccess() { StreamSizes sizes = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.StreamSizes) as StreamSizes; if (sizes != null) { try { this.m_HeaderSize = sizes.header; this.m_TrailerSize = sizes.trailer; this.m_MaxDataSize = sizes.maximumMessage - (this.m_HeaderSize + this.m_TrailerSize); } catch (Exception exception) { NclUtilities.IsFatal(exception); throw; } } this.m_ConnectionInfo = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.ConnectionInfo) as SslConnectionInfo; }
private unsafe string[] GetIssuers() { string[] strArray = new string[0]; if (this.IsValidContext) { IssuerListInfoEx ex = (IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.IssuerListInfoEx); try { if (ex.cIssuers <= 0) { return(strArray); } uint cIssuers = ex.cIssuers; strArray = new string[ex.cIssuers]; _CERT_CHAIN_ELEMENT *handle = (_CERT_CHAIN_ELEMENT *)ex.aIssuers.DangerousGetHandle(); for (int i = 0; i < cIssuers; i++) { _CERT_CHAIN_ELEMENT *_cert_chain_elementPtr2 = handle + i; uint cbSize = _cert_chain_elementPtr2->cbSize; byte * pCertContext = (byte *)_cert_chain_elementPtr2->pCertContext; byte[] encodedDistinguishedName = new byte[cbSize]; for (int j = 0; j < cbSize; j++) { encodedDistinguishedName[j] = pCertContext[j]; } X500DistinguishedName name = new X500DistinguishedName(encodedDistinguishedName); strArray[i] = name.Name; } } finally { if (ex.aIssuers != null) { ex.aIssuers.Close(); } } } return(strArray); }
internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buffer, int offset, int count, ref byte[] output) { SecPkgContext_Sizes sizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES ) as SecPkgContext_Sizes; // alloc new output buffer if not supplied or too small int resultSize = count + sizes.cbMaxSignature; if (output == null || output.Length < resultSize) { output = new byte[resultSize]; } // make a copy of user data for in-place encryption Buffer.BlockCopy(buffer, offset, output, sizes.cbMaxSignature, count); // setup security buffers for ssp call SecurityBuffer[] securityBuffer = new SecurityBuffer[2]; securityBuffer[0] = new SecurityBuffer(output, 0, sizes.cbMaxSignature, SecurityBufferType.SECBUFFER_TOKEN); securityBuffer[1] = new SecurityBuffer(output, sizes.cbMaxSignature, count, SecurityBufferType.SECBUFFER_DATA); // call SSP Function int errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0); // throw if error if (errorCode != 0) { NetEventSource.Info($"MakeSignature threw error: {errorCode.ToString("x", NumberFormatInfo.InvariantInfo)}"); throw new Win32Exception(errorCode); } // return signed size return(securityBuffer[0].size + securityBuffer[1].size); }
internal static string QueryContextAuthenticationPackage(SafeDeleteContext securityContext) { var negotiationInfoClass = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO) as NegotiationInfoClass; return(negotiationInfoClass?.AuthenticationPackage); }
internal static string QueryContextClientSpecifiedSpn(SafeDeleteContext securityContext) { return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET) as string); }
internal static string QueryContextAssociatedName(SafeDeleteContext securityContext) { return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES) as string); }
internal static int Encrypt( SafeDeleteContext securityContext, byte[] buffer, int offset, int count, bool isConfidential, bool isNtlm, ref byte[] output, uint sequenceNumber) { SecPkgContext_Sizes sizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES ) as SecPkgContext_Sizes; try { int maxCount = checked (Int32.MaxValue - 4 - sizes.cbBlockSize - sizes.cbSecurityTrailer); if (count > maxCount || count < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount)); } } catch (Exception e) when(!ExceptionCheck.IsFatal(e)) { NetEventSource.Fail(null, "Arguments out of range."); throw; } int resultSize = count + sizes.cbSecurityTrailer + sizes.cbBlockSize; if (output == null || output.Length < resultSize + 4) { output = new byte[resultSize + 4]; } // Make a copy of user data for in-place encryption. Buffer.BlockCopy(buffer, offset, output, 4 + sizes.cbSecurityTrailer, count); // Prepare buffers TOKEN(signature), DATA and Padding. var securityBuffer = new SecurityBuffer[3]; securityBuffer[0] = new SecurityBuffer(output, 4, sizes.cbSecurityTrailer, SecurityBufferType.SECBUFFER_TOKEN); securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, count, SecurityBufferType.SECBUFFER_DATA); securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + count, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING); int errorCode; if (isConfidential) { errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } else { if (isNtlm) { securityBuffer[1].type |= SecurityBufferType.SECBUFFER_READONLY; } errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0); } if (errorCode != 0) { Exception e = new Win32Exception(errorCode); if (NetEventSource.IsEnabled) { NetEventSource.Error(null, e); } throw e; } // Compacting the result. resultSize = securityBuffer[0].size; bool forceCopy = false; if (resultSize != sizes.cbSecurityTrailer) { forceCopy = true; Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size); } resultSize += securityBuffer[1].size; if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.cbSecurityTrailer))) { Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size); } resultSize += securityBuffer[2].size; unchecked { output[0] = (byte)((resultSize) & 0xFF); output[1] = (byte)(((resultSize) >> 8) & 0xFF); output[2] = (byte)(((resultSize) >> 16) & 0xFF); output[3] = (byte)(((resultSize) >> 24) & 0xFF); } return(resultSize + 4); }
internal static string QueryContextClientSpecifiedSpn(SafeDeleteContext securityContext) { return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.ClientSpecifiedSpn) as string); }
internal static int Encrypt( SafeDeleteContext securityContext, byte[] buffer, int offset, int count, bool isConfidential, bool isNtlm, ref byte[] output, uint sequenceNumber) { SecSizes sizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.Sizes ) as SecSizes; try { int maxCount = checked (Int32.MaxValue - 4 - sizes.BlockSize - sizes.SecurityTrailer); if (count > maxCount || count < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount)); } } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range."); } throw; } int resultSize = count + sizes.SecurityTrailer + sizes.BlockSize; if (output == null || output.Length < resultSize + 4) { output = new byte[resultSize + 4]; } // Make a copy of user data for in-place encryption. Buffer.BlockCopy(buffer, offset, output, 4 + sizes.SecurityTrailer, count); // Prepare buffers TOKEN(signature), DATA and Padding. var securityBuffer = new SecurityBuffer[3]; securityBuffer[0] = new SecurityBuffer(output, 4, sizes.SecurityTrailer, SecurityBufferType.Token); securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer, count, SecurityBufferType.Data); securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer + count, sizes.BlockSize, SecurityBufferType.Padding); int errorCode; if (isConfidential) { errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } else { if (isNtlm) { securityBuffer[1].type |= SecurityBufferType.ReadOnlyFlag; } errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0); } if (errorCode != 0) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } throw new Win32Exception(errorCode); } // Compacting the result. resultSize = securityBuffer[0].size; bool forceCopy = false; if (resultSize != sizes.SecurityTrailer) { forceCopy = true; Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size); } resultSize += securityBuffer[1].size; if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.SecurityTrailer))) { Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size); } resultSize += securityBuffer[2].size; unchecked { // TODO (Issue #6063): Should be offset by offset output[0] = (byte)((resultSize) & 0xFF); output[1] = (byte)(((resultSize) >> 8) & 0xFF); output[2] = (byte)(((resultSize) >> 16) & 0xFF); output[3] = (byte)(((resultSize) >> 24) & 0xFF); } return(resultSize + 4); }