internal static RemoteCertificateValidationCallback InternalToPublic (string hostname, RemoteCertValidationCallback callback) { if (callback == null) return null; return (s, c, ch, e) => callback (hostname, c, ch, e); }
internal static MSI.MonoRemoteCertificateValidationCallback InternalToMono (RemoteCertValidationCallback callback) { if (callback == null) return null; return (h, c, ch, e) => callback (h, c, (X509Chain)(object)ch, (SslPolicyErrors)e); }
// // The public Client and Server classes enforce the parameters rules before // calling into this .ctor. // internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy) { _innerStream = innerStream; _reader = new FixedSizeReader(innerStream); _certValidationDelegate = certValidationCallback; _certSelectionDelegate = certSelectionCallback; _encryptionPolicy = encryptionPolicy; }
internal static SSPIInterface Create (string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig) { if (userConfig.Settings != null && remoteValidationCallback != null) throw new InvalidOperationException (); var context = userConfig.Provider.CreateTlsContext ( hostname, serverMode, (TlsProtocols)protocolFlags, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, (MonoEncryptionPolicy)encryptionPolicy, userConfig.Settings); return new SSPIInterface (context, userConfig.EventSink); }
public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy) : base(innerStream, leaveInnerStreamOpen) { if (((encryptionPolicy != EncryptionPolicy.RequireEncryption) && (encryptionPolicy != EncryptionPolicy.AllowNoEncryption)) && (encryptionPolicy != EncryptionPolicy.NoEncryption)) { throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "EncryptionPolicy" }), "encryptionPolicy"); } this._userCertificateValidationCallback = userCertificateValidationCallback; this._userCertificateSelectionCallback = userCertificateSelectionCallback; RemoteCertValidationCallback certValidationCallback = new RemoteCertValidationCallback(this.userCertValidationCallbackWrapper); LocalCertSelectionCallback certSelectionCallback = (userCertificateSelectionCallback == null) ? null : new LocalCertSelectionCallback(this.userCertSelectionCallbackWrapper); this._SslState = new SslState(innerStream, certValidationCallback, certSelectionCallback, encryptionPolicy); }
public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy) : base(innerStream, leaveInnerStreamOpen) { if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption) { throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(encryptionPolicy)); } _userCertificateValidationCallback = userCertificateValidationCallback; _userCertificateSelectionCallback = userCertificateSelectionCallback; RemoteCertValidationCallback _userCertValidationCallbackWrapper = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper); LocalCertSelectionCallback _userCertSelectionCallbackWrapper = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper); _sslState = new SslState(innerStream, _userCertValidationCallbackWrapper, _userCertSelectionCallbackWrapper, encryptionPolicy); }
private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?localCallback) { ThrowIfExceptional(); if (_context != null && _context.IsValidContext) { throw new InvalidOperationException(SR.net_auth_reauth); } if (_context != null && IsServer) { throw new InvalidOperationException(SR.net_auth_client_server); } if (sslClientAuthenticationOptions.TargetHost == null) { throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost)); } _exception = null; try { _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback); _context = new SecureChannel(_sslAuthenticationOptions, this); } catch (Win32Exception e) { throw new AuthenticationException(SR.net_auth_SSPI, e); } }
internal unsafe bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { SslPolicyErrors none = SslPolicyErrors.None; bool flag = false; X509Chain chain = null; X509Certificate2 remoteCertificate = null; try { X509Certificate2Collection certificates; remoteCertificate = this.GetRemoteCertificate(out certificates); this.m_IsRemoteCertificateAvailable = remoteCertificate != null; if (remoteCertificate == null) { none |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain { ChainPolicy = { RevocationMode = this.m_CheckCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, RevocationFlag = X509RevocationFlag.ExcludeRoot } }; if (certificates != null) { chain.ChainPolicy.ExtraStore.AddRange(certificates); } if (!chain.Build(remoteCertificate) && (chain.ChainContext == IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (this.m_CheckCertName) { ChainPolicyParameter cpp = new ChainPolicyParameter { cbSize = ChainPolicyParameter.StructSize, dwFlags = 0 }; SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_extra_cert_chain_policy_para = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(this.IsServer); cpp.pvExtraPolicyPara = &ssl_extra_cert_chain_policy_para; fixed (char* str = ((char*) this.m_HostName)) { char* chPtr = str; ssl_extra_cert_chain_policy_para.pwszServerName = chPtr; cpp.dwFlags |= 0xfbf; SafeFreeCertChain chainContext = new SafeFreeCertChain(chain.ChainContext); if (PolicyWrapper.VerifyChainPolicy(chainContext, ref cpp) == 0x800b010f) { none |= SslPolicyErrors.RemoteCertificateNameMismatch; } } } X509ChainStatus[] chainStatus = chain.ChainStatus; if ((chainStatus != null) && (chainStatus.Length != 0)) { none |= SslPolicyErrors.RemoteCertificateChainErrors; } } if (remoteCertValidationCallback != null) { flag = remoteCertValidationCallback(this.m_HostName, remoteCertificate, chain, none); } else if ((none == SslPolicyErrors.RemoteCertificateNotAvailable) && !this.m_RemoteCertRequired) { flag = true; } else { flag = none == SslPolicyErrors.None; } if (!Logging.On) { return flag; } if (none != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_errors")); if ((none & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_not_available")); } if ((none & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_name_mismatch")); } if ((none & SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None) { foreach (X509ChainStatus status in chain.ChainStatus) { Logging.PrintInfo(Logging.Web, this, "\t" + status.StatusInformation); } } } if (flag) { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_valid")); return flag; } Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_no_errors")); return flag; } if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_invalid")); } } finally { if (chain != null) { chain.Reset(); } if (remoteCertificate != null) { remoteCertificate.Reset(); } } return flag; }
internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate"); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // we don't catch exceptions in this method, so it's safe for "accepted" be initialized with true bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = GetRemoteCertificate(out remoteCertificateStore); m_IsRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!m_RemoteCertRequired).ToString()); sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } #if !MONO else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = m_CheckCertRevocation? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); if (!chain.Build(remoteCertificateEx) // Build failed on handle or on policy && chain.ChainContext == IntPtr.Zero) // Build failed to generate a valid handle { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (m_CheckCertName) { unsafe { uint status = 0; ChainPolicyParameter cppStruct = new ChainPolicyParameter(); cppStruct.cbSize = ChainPolicyParameter.StructSize; cppStruct.dwFlags = 0; SSL_EXTRA_CERT_CHAIN_POLICY_PARA eppStruct = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(IsServer); cppStruct.pvExtraPolicyPara = &eppStruct; fixed (char* namePtr = m_HostName) { eppStruct.pwszServerName = namePtr; cppStruct.dwFlags |= (int) (IgnoreCertProblem.none & ~IgnoreCertProblem.invalid_name); SafeFreeCertChain chainContext= new SafeFreeCertChain(chain.ChainContext); status = PolicyWrapper.VerifyChainPolicy(chainContext, ref cppStruct); if ((CertificateProblem) status == CertificateProblem.CertCN_NO_MATCH) sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch; } } } X509ChainStatus[] chainStatusArray = chain.ChainStatus; if (chainStatusArray != null && chainStatusArray.Length != 0) sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(m_HostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !m_RemoteCertRequired) success = true; else success = (sslPolicyErrors == SslPolicyErrors.None); } #else success = SSPIWrapper.CheckRemoteCertificate(m_SecurityContext); #endif if (Logging.On) { if (sslPolicyErrors != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_errors)); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_not_available)); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_name_mismatch)); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) foreach (X509ChainStatus chainStatus in chain.ChainStatus) Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); } if (success) { if (remoteCertValidationCallback != null) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_valid)); else Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_no_errors)); } else { if (remoteCertValidationCallback != null) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_invalid)); } } GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null? "<null>": remoteCertificateEx.ToString(true))); } finally { // At least on Win2k server the chain is found to have dependancies on the original cert context. // So it should be closed first. if (chain != null) { chain.Reset(); } if (remoteCertificateEx != null) remoteCertificateEx.Reset(); } GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); return success; }
private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?localCallback) { // Without setting (or using) these members you will get a build exception in the unit test project. // The code that normally uses these in the main solution is in the implementation of SslStream. if (_nestedWrite == 0) { } _context = null; _exception = null; _internalBuffer = null; _internalBufferCount = 0; _internalOffset = 0; _nestedWrite = 0; _handshakeCompleted = false; }
/*++ VerifyRemoteCertificate - Validates the content of a Remote Certificate checkCRL if true, checks the certificate revocation list for validity. checkCertName, if true checks the CN field of the certificate --*/ //This method validates a remote certificate. //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { if (GlobalLog.IsEnabled) { GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate"); } SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore); _isRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { if (GlobalLog.IsEnabled) { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString()); } sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) { chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); } sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties( chain, remoteCertificateEx, _checkCertName, _serverMode, _hostName); } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired) { success = true; } else { success = (sslPolicyErrors == SslPolicyErrors.None); } } if (SecurityEventSource.Log.IsEnabled()) { if (sslPolicyErrors != SslPolicyErrors.None) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { string chainStatusString = "ChainStatus: "; foreach (X509ChainStatus chainStatus in chain.ChainStatus) { chainStatusString += "\t" + chainStatus.StatusInformation; } SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString); } } if (success) { if (remoteCertValidationCallback != null) { SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this)); } else { SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this)); } } else { if (remoteCertValidationCallback != null) { SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this)); } } } if (GlobalLog.IsEnabled) { GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true))); } } finally { // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Dispose(); } if (remoteCertificateEx != null) { remoteCertificateEx.Dispose(); } } if (GlobalLog.IsEnabled) { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); } return success; }
internal unsafe bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { SslPolicyErrors none = SslPolicyErrors.None; bool flag = false; X509Chain chain = null; X509Certificate2 remoteCertificate = null; try { X509Certificate2Collection certificates; remoteCertificate = this.GetRemoteCertificate(out certificates); this.m_IsRemoteCertificateAvailable = remoteCertificate != null; if (remoteCertificate == null) { none |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain { ChainPolicy = { RevocationMode = this.m_CheckCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, RevocationFlag = X509RevocationFlag.ExcludeRoot } }; if (certificates != null) { chain.ChainPolicy.ExtraStore.AddRange(certificates); } if (!chain.Build(remoteCertificate) && (chain.ChainContext == IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (this.m_CheckCertName) { ChainPolicyParameter cpp = new ChainPolicyParameter { cbSize = ChainPolicyParameter.StructSize, dwFlags = 0 }; SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_extra_cert_chain_policy_para = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(this.IsServer); cpp.pvExtraPolicyPara = &ssl_extra_cert_chain_policy_para; fixed(char *str = ((char *)this.m_HostName)) { char *chPtr = str; ssl_extra_cert_chain_policy_para.pwszServerName = chPtr; cpp.dwFlags |= 0xfbf; SafeFreeCertChain chainContext = new SafeFreeCertChain(chain.ChainContext); if (PolicyWrapper.VerifyChainPolicy(chainContext, ref cpp) == 0x800b010f) { none |= SslPolicyErrors.RemoteCertificateNameMismatch; } } } X509ChainStatus[] chainStatus = chain.ChainStatus; if ((chainStatus != null) && (chainStatus.Length != 0)) { none |= SslPolicyErrors.RemoteCertificateChainErrors; } } if (remoteCertValidationCallback != null) { flag = remoteCertValidationCallback(this.m_HostName, remoteCertificate, chain, none); } else if ((none == SslPolicyErrors.RemoteCertificateNotAvailable) && !this.m_RemoteCertRequired) { flag = true; } else { flag = none == SslPolicyErrors.None; } if (!Logging.On) { return(flag); } if (none != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_errors")); if ((none & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_not_available")); } if ((none & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_name_mismatch")); } if ((none & SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None) { foreach (X509ChainStatus status in chain.ChainStatus) { Logging.PrintInfo(Logging.Web, this, "\t" + status.StatusInformation); } } } if (flag) { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_valid")); return(flag); } Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_no_errors")); return(flag); } if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_invalid")); } } finally { if (chain != null) { chain.Reset(); } if (remoteCertificate != null) { remoteCertificate.Reset(); } } return(flag); }
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback) { }
/*++ * VerifyRemoteCertificate - Validates the content of a Remote Certificate * * checkCRL if true, checks the certificate revocation list for validity. * checkCertName, if true checks the CN field of the certificate * --*/ //This method validates a remote certificate. //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate"); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore); _isRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString()); sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) { chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); } sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties( chain, remoteCertificateEx, _checkCertName, _serverMode, _hostName); } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired) { success = true; } else { success = (sslPolicyErrors == SslPolicyErrors.None); } } if (Logging.On) { if (sslPolicyErrors != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { foreach (X509ChainStatus chainStatus in chain.ChainStatus) { Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); } } } if (success) { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid); } else { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors); } } else { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid); } } } GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true))); } finally { // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Dispose(); } if (remoteCertificateEx != null) { remoteCertificateEx.Dispose(); } } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); return(success); }
internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy, SSPIConfiguration config) : this(innerStream, certValidationCallback, certSelectionCallback, encryptionPolicy) { _Configuration = config; }
/*++ VerifyRemoteCertificate - Validates the content of a Remote Certificate checkCRL if true, checks the certificate revocation list for validity. checkCertName, if true checks the CN field of the certificate --*/ //This method validates a remote certificate. //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback, ref ProtocolToken alertToken) { if (GlobalLog.IsEnabled) { GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate"); } SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore); _isRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { if (GlobalLog.IsEnabled) { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString()); } sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) { chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); } sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties( chain, remoteCertificateEx, _checkCertName, _serverMode, _hostName); } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired) { success = true; } else { success = (sslPolicyErrors == SslPolicyErrors.None); } } if (SecurityEventSource.Log.IsEnabled()) { LogCertificateValidation(remoteCertValidationCallback, sslPolicyErrors, success, chain); } if (GlobalLog.IsEnabled) { GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true))); } if (!success) { alertToken = CreateFatalHandshakeAlertToken(sslPolicyErrors, chain); } } finally { // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Dispose(); } if (remoteCertificateEx != null) { remoteCertificateEx.Dispose(); } } if (GlobalLog.IsEnabled) { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); } return success; }
private void LogCertificateValidation(RemoteCertValidationCallback remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain) { if (sslPolicyErrors != SslPolicyErrors.None) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) { SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { string chainStatusString = "ChainStatus: "; foreach (X509ChainStatus chainStatus in chain.ChainStatus) { chainStatusString += "\t" + chainStatus.StatusInformation; } SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString); } } if (success) { if (remoteCertValidationCallback != null) { SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this)); } else { SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this)); } } else { if (remoteCertValidationCallback != null) { SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this)); } } }
internal static SSPIInterface Create(string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, XX509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig) { if (userConfig.Settings != null && remoteValidationCallback != null) { throw new InvalidOperationException(); } var context = userConfig.Provider.CreateTlsContext( hostname, serverMode, (TlsProtocols)protocolFlags, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, (MonoEncryptionPolicy)encryptionPolicy, userConfig.Settings); return(new SSPIInterface(context, userConfig.EventSink)); }
private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback) { ThrowIfExceptional(); if (_context != null && _context.IsValidContext) { throw new InvalidOperationException(SR.net_auth_reauth); } if (_context != null && IsServer) { throw new InvalidOperationException(SR.net_auth_client_server); } if (sslClientAuthenticationOptions.TargetHost == null) { throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost)); } _exception = null; try { _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback); if (_sslAuthenticationOptions.TargetHost.Length == 0) { _sslAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo); } _context = new SecureChannel(_sslAuthenticationOptions); } catch (Win32Exception e) { throw new AuthenticationException(SR.net_auth_SSPI, e); } }
internal static RemoteCertificateValidationCallback InternalToPublic(string hostname, RemoteCertValidationCallback callback) { if (callback == null) { return(null); } return((s, c, ch, e) => callback(hostname, c, ch, e)); }
// // The public Client and Server classes enforce the parameters rules before // calling into this .ctor. // internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy) { }
/*++ VerifyRemoteCertificate - Validates the content of a Remote Certificate checkCRL if true, checks the certificate revocation list for validity. checkCertName, if true checks the CN field of the certificate --*/ //This method validates a remote certificate. //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate"); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = GetRemoteCertificate(out remoteCertificateStore); _isRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString()); sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) { chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); } if (!chain.Build(remoteCertificateEx) // Build failed on handle or on policy. && chain.SafeHandle.DangerousGetHandle() == IntPtr.Zero) // Build failed to generate a valid handle. { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (_checkCertName) { unsafe { uint status = 0; var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA() { cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA>(), dwAuthType = IsServer ? Interop.Crypt32.AuthType.AUTHTYPE_SERVER : Interop.Crypt32.AuthType.AUTHTYPE_CLIENT, fdwChecks = 0, pwszServerName = null }; var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA() { cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_PARA>(), dwFlags = 0, pvExtraPolicyPara = &eppStruct }; fixed (char* namePtr = _hostName) { eppStruct.pwszServerName = namePtr; cppStruct.dwFlags |= (Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL & ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG); SafeX509ChainHandle chainContext = chain.SafeHandle; status = Verify(chainContext, ref cppStruct); if (status == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH) { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch; } } } } X509ChainStatus[] chainStatusArray = chain.ChainStatus; if (chainStatusArray != null && chainStatusArray.Length != 0) { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired) { success = true; } else { success = (sslPolicyErrors == SslPolicyErrors.None); } } if (Logging.On) { if (sslPolicyErrors != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { foreach (X509ChainStatus chainStatus in chain.ChainStatus) { Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); } } } if (success) { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid); } else { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors); } } else { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid); } } } GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true))); } finally { // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Dispose(); } if (remoteCertificateEx != null) { remoteCertificateEx.Dispose(); } } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); return success; }
internal SecureChannel(string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration config) { GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::.ctor", "hostname:" + hostname + " #clientCertificates=" + ((clientCertificates == null) ? "0" : clientCertificates.Count.ToString(NumberFormatInfo.InvariantInfo))); if (Logging.On) Logging.PrintInfo(Logging.Web, this, ".ctor", "hostname=" + hostname + ", #clientCertificates=" + ((clientCertificates == null) ? "0" : clientCertificates.Count.ToString(NumberFormatInfo.InvariantInfo)) + ", encryptionPolicy=" + encryptionPolicy); m_SecModule = GlobalSSPI.Create(hostname, serverMode, protocolFlags, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, encryptionPolicy, certSelectionDelegate, remoteValidationCallback, config); m_Destination = hostname; GlobalLog.Assert(hostname != null, "SecureChannel#{0}::.ctor()|hostname == null", ValidationHelper.HashString(this)); m_HostName = hostname; m_ServerMode = serverMode; if (serverMode) m_ProtocolFlags = (protocolFlags & SchProtocols.ServerMask); else m_ProtocolFlags = (protocolFlags & SchProtocols.ClientMask); m_ServerCertificate = serverCertificate; m_ClientCertificates = clientCertificates; m_RemoteCertRequired = remoteCertRequired; m_SecurityContext = null; m_CheckCertRevocation = checkCertRevocationStatus; m_CheckCertName = checkCertName; m_CertSelectionDelegate = certSelectionDelegate; m_RefreshCredentialNeeded = true; m_EncryptionPolicy = encryptionPolicy; GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::.ctor"); }
internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?localCallback) { Debug.Assert(sslClientAuthenticationOptions.TargetHost != null); // Common options. AllowRenegotiation = sslClientAuthenticationOptions.AllowRenegotiation; ApplicationProtocols = sslClientAuthenticationOptions.ApplicationProtocols; CertValidationDelegate = remoteCallback; CheckCertName = true; EnabledSslProtocols = FilterOutIncompatibleSslProtocols(sslClientAuthenticationOptions.EnabledSslProtocols); EncryptionPolicy = sslClientAuthenticationOptions.EncryptionPolicy; IsServer = false; RemoteCertRequired = true; TargetHost = sslClientAuthenticationOptions.TargetHost !; // Client specific options. CertSelectionDelegate = localCallback; CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode; ClientCertificates = sslClientAuthenticationOptions.ClientCertificates; CipherSuitesPolicy = sslClientAuthenticationOptions.CipherSuitesPolicy; }
// // SSL related properties // internal void SetCertValidationDelegate(RemoteCertValidationCallback certValidationCallback) { _certValidationDelegate = certValidationCallback; }
/*++ VerifyRemoteCertificate - Validates the content of a Remote Certificate checkCRL if true, checks the certificate revocation list for validity. checkCertName, if true checks the CN field of the certificate --*/ //This method validates a remote certificate. //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) { GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate"); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true. bool success = false; X509Chain chain = null; X509Certificate2 remoteCertificateEx = null; try { X509Certificate2Collection remoteCertificateStore; remoteCertificateEx = CertWrapper.GetRemoteCertificate(_securityContext, out remoteCertificateStore); _isRemoteCertificateAvailable = remoteCertificateEx != null; if (remoteCertificateEx == null) { GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString()); sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { chain = new X509Chain(); chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (remoteCertificateStore != null) { chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore); } // Don't call chain.Build here in the common code, because the Windows version // is potentially going to check for GetLastWin32Error, and that call needs to be // guaranteed to be right after the call to chain.Build. sslPolicyErrors |= CertWrapper.VerifyCertificateProperties( chain, remoteCertificateEx, _checkCertName, _serverMode, _hostName); } if (remoteCertValidationCallback != null) { success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors); } else { if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired) { success = true; } else { success = (sslPolicyErrors == SslPolicyErrors.None); } } if (Logging.On) { if (sslPolicyErrors != SslPolicyErrors.None) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) { Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch); } if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { foreach (X509ChainStatus chainStatus in chain.ChainStatus) { Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); } } } if (success) { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid); } else { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors); } } else { if (remoteCertValidationCallback != null) { Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid); } } } GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true))); } finally { // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Dispose(); } if (remoteCertificateEx != null) { remoteCertificateEx.Dispose(); } } GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); return success; }
internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback) { // Common options. AllowRenegotiation = sslClientAuthenticationOptions.AllowRenegotiation; ApplicationProtocols = sslClientAuthenticationOptions.ApplicationProtocols; CertValidationDelegate = remoteCallback; CheckCertName = true; EnabledSslProtocols = sslClientAuthenticationOptions.EnabledSslProtocols; EncryptionPolicy = sslClientAuthenticationOptions.EncryptionPolicy; IsServer = false; RemoteCertRequired = true; RemoteCertificateValidationCallback = sslClientAuthenticationOptions.RemoteCertificateValidationCallback; TargetHost = sslClientAuthenticationOptions.TargetHost; // Client specific options. CertSelectionDelegate = localCallback; CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode; ClientCertificates = sslClientAuthenticationOptions.ClientCertificates; LocalCertificateSelectionCallback = sslClientAuthenticationOptions.LocalCertificateSelectionCallback; }