private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, package, spn, requestedContextFlags); _tokenSize = NegotiateStreamPal.QueryMaxTokenSize(package); _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Peer SPN-> '{_spn}'"); // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, "using DefaultCredentials"); _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer); } else { _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential); } }
internal SecureChannel(string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate) { if (Logging.On) { Logging.PrintInfo(Logging.Web, this, ".ctor", string.Concat(new object[] { "hostname=", hostname, ", #clientCertificates=", (clientCertificates == null) ? "0" : clientCertificates.Count.ToString(NumberFormatInfo.InvariantInfo), ", encryptionPolicy=", encryptionPolicy })); } SSPIWrapper.GetVerifyPackageInfo(GlobalSSPI.SSPISecureChannel, "Microsoft Unified Security Protocol Provider", true); if (ComNetOS.IsWin9x && (clientCertificates.Count > 0)) { this.m_Destination = hostname + "+" + clientCertificates.GetHashCode(); } else { this.m_Destination = hostname; } this.m_HostName = hostname; this.m_ServerMode = serverMode; if (serverMode) { this.m_ProtocolFlags = protocolFlags & SchProtocols.ServerMask; } else { this.m_ProtocolFlags = protocolFlags & SchProtocols.ClientMask; } this.m_ServerCertificate = serverCertificate; this.m_ClientCertificates = clientCertificates; this.m_RemoteCertRequired = remoteCertRequired; this.m_SecurityContext = null; this.m_CheckCertRevocation = checkCertRevocationStatus; this.m_CheckCertName = checkCertName; this.m_CertSelectionDelegate = certSelectionDelegate; this.m_RefreshCredentialNeeded = true; this.m_EncryptionPolicy = encryptionPolicy; }
public void AcceptSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags) { if (IsEnabled()) { AcceptSecurityContext(IdOf(credential), IdOf(context), inFlags); } }
public void InitializeSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags) { if (IsEnabled()) { InitializeSecurityContext(IdOf(credential), IdOf(context), targetName, inFlags); } }
public SecurityStatus InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero; var retStatus = (SecurityStatus)SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, RequiredFlags | Interop.Secur32.ContextFlags.InitManualCredValidation, Interop.Secur32.Endianness.Native, inputBuffer, null, outputBuffer, ref outFlags); return MapToSecurityStatus((Interop.SecurityStatus)retStatus); }
public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext, byte[] buffer, ref int offset, ref int count) { int resultSize; SecurityStatusPal retVal = EncryptDecryptHelper(securityContext, buffer, offset, count, 0, 0, false, out resultSize); if (SecurityStatusPal.OK == retVal || SecurityStatusPal.Renegotiate == retVal) { count = resultSize; } return retVal; }
public int EncryptMessage(SafeDeleteContext context, Interop.Secur32.SecurityBufferDescriptor inputOutput, uint sequenceNumber) { int status = (int)Interop.SecurityStatus.InvalidHandle; bool ignore = false; context.DangerousAddRef(ref ignore); status = Interop.Secur32.EncryptMessage(ref context._handle, 0, inputOutput, sequenceNumber); context.DangerousRelease(); return status; }
public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext, byte[] buffer, ref int offset, ref int count) { int resultSize; SecurityStatusPal retVal = EncryptDecryptHelper(securityContext, buffer, offset, count, false, ref buffer, out resultSize); if (retVal.ErrorCode == SecurityStatusPalErrorCode.OK || retVal.ErrorCode == SecurityStatusPalErrorCode.Renegotiate) { count = resultSize; } return retVal; }
internal static SecurityStatus AcceptSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "AcceptSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "remoteCertRequired = " + remoteCertRequired); } return SecModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, outputBuffer, remoteCertRequired); }
public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try { bool ignore = false; context.DangerousAddRef(ref ignore); return Interop.SspiCli.EncryptMessage(ref context._handle, 0, inputOutput, sequenceNumber); } finally { context.DangerousRelease(); } }
public int QueryContextStreamSizes(SafeDeleteContext securityContext, out StreamSizes streamSizes) { streamSizes = null; try { streamSizes = new StreamSizes(Interop.libssl.SslSizes.HEADER_SIZE, Interop.libssl.SslSizes.TRAILER_SIZE, Interop.libssl.SslSizes.SSL3_RT_MAX_PLAIN_LENGTH); return 0; } catch { return -1; } }
public int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero; return SafeDeleteContext.AcceptSecurityContext( ref credential, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.Secur32.ContextFlags.MutualAuth : Interop.Secur32.ContextFlags.Zero), Interop.Secur32.Endianness.Native, inputBuffer, null, outputBuffer, ref outFlags ); }
public static int QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) { connectionInfo = null; try { connectionInfo = new SslConnectionInfo(securityContext.SslContext); return 0; } catch { return -1; } }
public unsafe int DecryptMessage(SafeDeleteContext context, Interop.Secur32.SecurityBufferDescriptor inputOutput, uint sequenceNumber) { try { bool ignore = false; context.DangerousAddRef(ref ignore); return Interop.Secur32.DecryptMessage(ref context._handle, inputOutput, sequenceNumber, null); } finally { context.DangerousRelease(); } }
internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName); } SecurityStatus errorCode = SecModule.InitializeSecurityContext(credential, ref context, targetName, inputBuffers, outputBuffer); return errorCode; }
// // Extracts a remote certificate upon request. // internal override X509Certificate2 GetRemoteCertificate(SafeDeleteContext securityContext, out X509Certificate2Collection remoteCertificateStore) { remoteCertificateStore = null; bool gotReference = false; if (securityContext == null) { return null; } GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}"); X509Certificate2 result = null; SafeFreeCertContext remoteContext = null; try { int errorCode = SSPIWrapper.QueryContextRemoteCertificate(GlobalSSPI.SSPISecureChannel, securityContext, out remoteContext); if (remoteContext != null && !remoteContext.IsInvalid) { remoteContext.DangerousAddRef(ref gotReference); result = new X509Certificate2(remoteContext.DangerousGetHandle()); } } finally { if (gotReference) { remoteContext.DangerousRelease(); } if (remoteContext != null) { remoteContext.Dispose(); } // TODO (Issue #3362) Fetch remoteCertificateStore, if applicable for unix remoteCertificateStore = new X509Certificate2Collection(); } if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_remote_certificate, (result == null ? "null" : result.ToString(true)))); } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::RemoteCertificate{get;}", (result == null ? "null" : result.Subject)); return result; }
public static int QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) { string protocolVersion; connectionInfo = null; try { Interop.libssl.SSL_CIPHER cipher = Interop.OpenSsl.GetConnectionInfo(securityContext.SslContext, out protocolVersion); connectionInfo = new SslConnectionInfo(cipher, protocolVersion); return 0; } catch { return -1; } }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPISecureChannel, ref credentialsHandle, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero), Interop.SspiCli.Endianness.Native, inputBuffer, outputBuffer, ref unusedAttributes); return GetSecurityStatusPalFromWin32Int(errorCode); }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, Interop.SspiCli.Endianness.Native, inputBuffers, outputBuffer, ref unusedAttributes); return GetSecurityStatusPalFromWin32Int(errorCode); }
internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName); } SecurityStatus errorCode = SecModule.InitializeSecurityContext(ref credential, ref context, targetName, inputBuffer, outputBuffer); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffer, "InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (SecurityStatus)errorCode)); } return errorCode; }
WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) { this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken; this.isServer = isServer; this.servicePrincipalName = servicePrincipalName; this.securityContext = null; if (isServer) { this.impersonationLevel = TokenImpersonationLevel.Delegation; this.doMutualAuth = false; } else { this.impersonationLevel = impersonationLevel; this.doMutualAuth = doMutualAuth; this.interactiveNegoLogonEnabled = interactiveLogonEnabled; this.clientPackageName = package; this.allowNtlm = ntlmEnabled; } this.credentialsHandle = credentialsHandle; }
// // Extracts a remote certificate upon request. // internal static X509Certificate2 GetRemoteCertificate(SafeDeleteContext securityContext, out X509Certificate2Collection remoteCertificateStore) { remoteCertificateStore = null; if (securityContext == null) { return null; } GlobalLog.Enter("SecureChannel#" + Logging.HashString(securityContext) + "::RemoteCertificate{get;}"); X509Certificate2 result = null; SafeFreeCertContext remoteContext = null; try { int errorCode = SslStreamPal.QueryContextRemoteCertificate(securityContext, out remoteContext); if (remoteContext != null && !remoteContext.IsInvalid) { result = new X509Certificate2(remoteContext.DangerousGetHandle()); } } finally { if (remoteContext != null && !remoteContext.IsInvalid) { remoteCertificateStore = UnmanagedCertificateContext.GetRemoteCertificatesFromStoreContext(remoteContext); remoteContext.Dispose(); } } if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_remote_certificate, (result == null ? "null" : result.ToString(true)))); } GlobalLog.Leave("SecureChannel#" + Logging.HashString(securityContext) + "::RemoteCertificate{get;}", (result == null ? "null" : result.Subject)); return result; }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteContext(credential, isServer, remoteCertRequired); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return done ? SecurityStatusPal.OK : SecurityStatusPal.ContinueNeeded; } catch { // TODO: This Debug.Fail is triggering on Linux in many test cases #4317 // Debug.Fail("Exception Caught. - " + ex); return SecurityStatusPal.InternalError; } }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
private static int GetSecurityContextToken(SafeDeleteContext phContext, out SecurityContextTokenHandle safeHandle) { safeHandle = null; try { bool ignore = false; phContext.DangerousAddRef(ref ignore); return Interop.SspiCli.QuerySecurityContextToken(ref phContext._handle, out safeHandle); } finally { phContext.DangerousRelease(); } }
public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) { return SafeDeleteContext.CompleteAuthToken(ref refContext, inputBuffers); }
public int QuerySecurityContextToken(SafeDeleteContext phContext, out SecurityContextTokenHandle phToken) { return GetSecurityContextToken(phContext, out phToken); }
public int SetContextAttributes(SafeDeleteContext context, Interop.SspiCli.ContextAttribute attribute, byte[] buffer) { throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); }
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) { int status = (int)Interop.SecurityStatus.InvalidHandle; uint qop = 0; try { bool ignore = false; context.DangerousAddRef(ref ignore); status = Interop.SspiCli.DecryptMessage(ref context._handle, inputOutput, sequenceNumber, &qop); } finally { context.DangerousRelease(); } if (status == 0 && qop == Interop.SspiCli.SECQOP_WRAP_NO_ENCRYPT) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("SspiCli.DecryptMessage", "Expected qop = 0, returned value = " + qop.ToString("x", CultureInfo.InvariantCulture)); } throw new InvalidOperationException(SR.net_auth_message_not_encrypted); } return status; }
/// <summary> /// Generate SSPI context /// </summary> /// <param name="handle">SNI connection handle</param> /// <param name="receivedBuff">Receive buffer</param> /// <param name="receivedLength">Received length</param> /// <param name="sendBuff">Send buffer</param> /// <param name="sendLength">Send length</param> /// <param name="serverName">Service Principal Name buffer</param> /// <param name="serverNameLength">Length of Service Principal Name</param> /// <returns>SNI error code</returns> public void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle; string securityPackage = NegotiationInfoClass.Negotiate; if (securityContext == null) { credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(securityPackage, false); } SecurityBuffer[] inSecurityBufferArray = null; if (receivedBuff != null) { inSecurityBufferArray = new SecurityBuffer[] { new SecurityBuffer(receivedBuff, SecurityBufferType.SECBUFFER_TOKEN) }; } else { inSecurityBufferArray = new SecurityBuffer[] { }; } int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(securityPackage); SecurityBuffer outSecurityBuffer = new SecurityBuffer(tokenSize, SecurityBufferType.SECBUFFER_TOKEN); ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection | ContextFlagsPal.Confidentiality | ContextFlagsPal.MutualAuth; string serverSPN = System.Text.Encoding.UTF8.GetString(serverName); SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext( credentialsHandle, ref securityContext, serverSPN, requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref contextFlags); if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded || statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue) { inSecurityBufferArray = new SecurityBuffer[] { outSecurityBuffer }; statusCode = NegotiateStreamPal.CompleteAuthToken(ref securityContext, inSecurityBufferArray); outSecurityBuffer.token = null; } sendBuff = outSecurityBuffer.token; if (sendBuff == null) { sendBuff = Array.Empty <byte>(); } sspiClientContextStatus.SecurityContext = securityContext; sspiClientContextStatus.ContextFlags = contextFlags; sspiClientContextStatus.CredentialsHandle = credentialsHandle; if (IsErrorStatus(statusCode.ErrorCode)) { // Could not access Kerberos Ticket. // // SecurityStatusPalErrorCode.InternalError only occurs in Unix and always comes with a GssApiException, // so we don't need to check for a GssApiException here. if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError) { throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode); } else { throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode); } } }