internal bool TryGetCertificateValidator(out X509CertificateValidator validator) { validator = null; if (this.certificateValidationMode == X509CertificateValidationMode.None) { validator = X509CertificateValidator.None; } else if (this.certificateValidationMode == X509CertificateValidationMode.PeerTrust) { validator = X509CertificateValidator.PeerTrust; } else if (this.certificateValidationMode == X509CertificateValidationMode.Custom) { validator = this.customCertificateValidator; } else { bool useMachineContext = this.trustedStoreLocation == StoreLocation.LocalMachine; X509ChainPolicy chainPolicy = new X509ChainPolicy { RevocationMode = this.revocationMode }; if (this.certificateValidationMode == X509CertificateValidationMode.ChainTrust) { validator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); } else { validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, chainPolicy); } } return (validator != null); }
internal X509CertificateValidator GetCertificateValidator() { if (this.certificateValidationMode == X509CertificateValidationMode.None) { return X509CertificateValidator.None; } if (this.certificateValidationMode == X509CertificateValidationMode.PeerTrust) { return X509CertificateValidator.PeerTrust; } if (this.certificateValidationMode == X509CertificateValidationMode.Custom) { if (this.customCertificateValidator == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("MissingCustomCertificateValidator"))); } return this.customCertificateValidator; } bool useMachineContext = this.trustedStoreLocation == StoreLocation.LocalMachine; X509ChainPolicy chainPolicy = new X509ChainPolicy { RevocationMode = this.revocationMode }; if (this.certificateValidationMode == X509CertificateValidationMode.ChainTrust) { return X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); } return X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, chainPolicy); }
private static void TestCertificates() { // Load certificate from cert store (user/computer store = MY = Personal) var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); foreach (var cert in store.Certificates) { // validate certificates var chain = new X509Chain(); var policy = new X509ChainPolicy { RevocationFlag = X509RevocationFlag.EntireChain, RevocationMode = X509RevocationMode.Online, UrlRetrievalTimeout = TimeSpan.FromMilliseconds(10000) }; chain.ChainPolicy = policy; if (!chain.Build(cert)) { // do some work } Console.WriteLine(cert.FriendlyName); } store.Close(); }
private static void Main(string[] args) { // load certificate from cert store (user/computer store = MY = Personal) var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); // ... do work foreach (var cert in store.Certificates) { // validate certificates var chain = new X509Chain(); var policy = new X509ChainPolicy { RevocationFlag = X509RevocationFlag.EntireChain, RevocationMode = X509RevocationMode.Online, UrlRetrievalTimeout = TimeSpan.FromMilliseconds(10000) }; chain.ChainPolicy = policy; if (!chain.Build(cert)) { // do some work } // validation - special class to validate cert var validator = X509CertificateValidator.ChainTrust; validator.Validate(cert); Console.WriteLine(cert.FriendlyName); } store.Close(); }
public ChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy, uint chainPolicyOID) { Contract.Assert(useMachineContext == false, "CoreCLR does not have ctor allowing useMachineContext = true"); _useMachineContext = useMachineContext; _chainPolicy = chainPolicy; _chainPolicyOID = chainPolicyOID; }
public static X509CertificateValidator CreatePeerOrChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy) { if (chainPolicy == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("chainPolicy"); } return new PeerOrChainTrustValidator(useMachineContext, chainPolicy); }
public X509Chain(bool useMachineContext) { this.m_syncRoot = new object(); this.m_status = 0; this.m_chainPolicy = null; this.m_chainStatus = null; this.m_chainElementCollection = new X509ChainElementCollection(); this.m_safeCertChainHandle = SafeCertChainHandle.InvalidHandle; this.m_useMachineContext = useMachineContext; }
private void CheckDefaultPolicy (X509ChainPolicy p) { Assert.AreEqual (0, p.ApplicationPolicy.Count, "ApplicationPolicy"); Assert.AreEqual (0, p.CertificatePolicy.Count, "CertificatePolicy"); Assert.AreEqual (0, p.ExtraStore.Count, "ExtraStore"); Assert.AreEqual (X509RevocationFlag.ExcludeRoot, p.RevocationFlag, "RevocationFlag"); Assert.AreEqual (X509RevocationMode.Online, p.RevocationMode, "RevocationMode"); Assert.AreEqual (0, p.UrlRetrievalTimeout.Ticks, "UrlRetrievalTimeout"); Assert.AreEqual (X509VerificationFlags.NoFlag, p.VerificationFlags, "VerificationFlags"); Assert.IsTrue (p.VerificationTime <= DateTime.Now, "VerificationTime"); }
public static X509Certificate2Collection FilterValidCerts( X509Certificate2Collection certs, X509ChainPolicy policy, X509ChainStatusFlags problemFlags, Action<Exception> notification) { var validCerts = new X509Certificate2Collection(); if (certs == null) return null; foreach (var cert in certs) { X509Chain chainBuilder = new X509Chain(); chainBuilder.ChainPolicy = policy.Clone(); try { // We're using the system class as a helper to merely build the chain // However, we will review each item in the chain ourselves, because we have our own rules... chainBuilder.Build(cert); X509ChainElementCollection chainElements = chainBuilder.ChainElements; // If we don't have a trust chain, then we obviously have a problem... if (chainElements.IsNullOrEmpty()) { notification(new Exception(string.Format("Can't find a trust chain: {0} ", cert.Subject))); return null; } // walk the chain starting at the leaf and see if we hit any issues before the anchor foreach (X509ChainElement chainElement in chainElements) { if (ChainElementHasProblems(chainElement, problemFlags)) { //this.NotifyProblem(chainElement); notification(new Exception(string.Format("Chain Element has problem {0}", Summarize(chainElement, problemFlags)))); // Whoops... problem with at least one cert in the chain. Stop immediately return null; } } } catch (Exception ex) { //this.NotifyError(certificate, ex); // just eat it and drop out to return null notification(ex); return null; } validCerts.Add(cert); } return validCerts; }
public override void Validate(X509Certificate2 certificate) { Trace.Information("Validating certificate"); var x509ChainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.NoCheck, VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority }; x509ChainPolicy.ExtraStore.Add(_caCertificate); CreateChainTrustValidator(false, x509ChainPolicy).Validate(certificate); }
public override void ApplyTo(ChannelFactory channelFactory) { channelFactory.Endpoint.Address = new EndpointAddress(channelFactory.Endpoint.Address.Uri); channelFactory.Credentials.UserName.UserName = _username; channelFactory.Credentials.UserName.Password = _password; channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom; X509ChainPolicy chainPolicy = new X509ChainPolicy(); chainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority | X509VerificationFlags.IgnoreNotTimeValid; channelFactory.Credentials.ServiceCertificate.Authentication.CustomCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(true, chainPolicy); }
static void Main( string[] args ) { //Part I - to access certificate ////example 1 //var cert = new X509Certificate2("c:\\etc\\dropbox"); //example 2 var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); //store.Certificates.Find(); store.Close(); //example 3 //need to install nuget //thinktecture.identity.model core var cert1 = X509.LocalMachine.My.SubjectDistinguishedName.Find("CN=serverdev").First(); //part II - to validate certification //example 1 var chain = new X509Chain(); var policy = new X509ChainPolicy { RevocationFlag = X509RevocationFlag.EntireChain, RevocationMode = X509RevocationMode.Online }; chain.ChainPolicy = policy; if (!chain.Build(cert1)) { foreach (var element in chain.ChainElements) { foreach (var status in element.ChainElementStatus) { Console.WriteLine(status.StatusInformation); } } } //example 2 var validator = X509CertificateValidator.ChainTrust; validator.Validate(cert1); //example 2B validator = X509CertificateValidator.PeerOrChainTrust; validator.Validate(cert1); }
private static X509Certificate2 GetIssuerCertificate(X509Certificate2 subjectCertificate) { // Don't check online for revocation; that's what this spike is attempting to do, so there's no point in letting .NET do it. var policy = new X509ChainPolicy {RevocationMode = X509RevocationMode.NoCheck}; var chain = new X509Chain {ChainPolicy = policy}; // We need the certificate chain, in order to get the certificate and its issuer. chain.Build(subjectCertificate); if (chain.ChainElements.Count == 1) // Self-signed. return chain.ChainElements[0].Certificate; if (chain.ChainElements.Count >= 2) return chain.ChainElements[1].Certificate; throw new InvalidOperationException("Could not discover issuer certificate by building certificate chain."); }
public static IAppBuilder UseClientCertificateAuthentication(this IAppBuilder app, X509RevocationMode revocationMode = X509RevocationMode.Online, bool createExtendedClaims = false) { var policy = new X509ChainPolicy { RevocationMode = revocationMode }; var validator = X509CertificateValidator.CreateChainTrustValidator(true, policy); var options = new ClientCertificateAuthenticationOptions { Validator = validator, CreateExtendedClaimSet = createExtendedClaims }; return app.UseClientCertificateAuthentication(options); }
public X509CertificateValidatorEx( X509CertificateValidationMode certificateValidationMode, X509RevocationMode revocationMode, StoreLocation trustedStoreLocation) { this.certificateValidationMode = certificateValidationMode; switch (this.certificateValidationMode) { case X509CertificateValidationMode.None: { this.validator = X509CertificateValidator.None; break; } case X509CertificateValidationMode.PeerTrust: { this.validator = X509CertificateValidator.PeerTrust; break; } case X509CertificateValidationMode.ChainTrust: { bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; this.chainPolicy = new X509ChainPolicy(); this.chainPolicy.RevocationMode = revocationMode; this.validator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, this.chainPolicy); break; } case X509CertificateValidationMode.PeerOrChainTrust: { bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; this.chainPolicy = new X509ChainPolicy(); this.chainPolicy.RevocationMode = revocationMode; this.validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, this.chainPolicy); break; } case X509CertificateValidationMode.Custom: default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4256))); } }
/// <summary> /// Determines whether the specified certificate is considered valid according to the RFC3280 specification. /// /// </summary> /// <param name="certificate">The certificate to validate.</param> /// <returns> /// <c>true</c> if valid; otherwise, <c>false</c>. /// </returns> public bool IsSatisfiedBy(X509Certificate2 certificate) { bool useMachineContext = false; X509ChainPolicy chainPolicy = new X509ChainPolicy(); chainPolicy.RevocationMode = X509RevocationMode.Online; X509CertificateValidator defaultCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); try { defaultCertificateValidator.Validate(certificate); return true; }catch(Exception e) { Trace.TraceData(TraceEventType.Warning, string.Format(Tracing.CertificateIsNotRFC3280Valid, certificate.SubjectName.Name, certificate.Thumbprint, e)); } return false; }
/// <summary> /// Determines whether the specified certificate is considered valid according to the RFC3280 specification. /// </summary> /// <param name="certificate">The certificate to validate.</param> /// <returns> /// <c>true</c> if valid; otherwise, <c>false</c>. /// </returns> public bool IsSatisfiedBy(X509Certificate2 certificate) { var useMachineContext = false; var chainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.Online }; var defaultCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); try { defaultCertificateValidator.Validate(certificate); return true; } catch (Exception e) { Logging.LoggerProvider.LoggerFor(GetType()).Warn(string.Format(ErrorMessages.CertificateIsNotRFC3280Valid, certificate.SubjectName.Name, certificate.Thumbprint), e); } return false; }
internal X509ChainImplBtls (MonoBtlsX509StoreCtx storeCtx) { this.storeCtx = storeCtx.Copy (); this.chain = storeCtx.GetChain (); policy = new X509ChainPolicy (); untrustedChain = storeCtx.GetUntrusted (); if (untrustedChain != null) { untrusted = new X509Certificate2Collection (); policy.ExtraStore = untrusted; for (int i = 0; i < untrustedChain.Count; i++) { var cert = untrustedChain.GetCertificate (i); using (var impl = new X509CertificateImplBtls (cert)) untrusted.Add (new X509Certificate2 (impl)); } } }
/// <summary> /// Determines whether the specified certificate is considered valid by this specification. /// Always returns true. No online validation attempted. /// </summary> /// <param name="certificate">The certificate to validate.</param> /// <returns> /// <c>true</c>. /// </returns> public bool IsSatisfiedBy(X509Certificate2 certificate) { X509ChainPolicy chainPolicy = new X509ChainPolicy(); chainPolicy.RevocationMode = X509RevocationMode.NoCheck; chainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; X509CertificateValidator defaultCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(false, chainPolicy); try { defaultCertificateValidator.Validate(certificate); return true; } catch (Exception e) { Trace.TraceData(TraceEventType.Warning, string.Format(Tracing.CertificateIsNotRFC3280Valid, certificate.SubjectName.Name, certificate.Thumbprint, e)); } return false; }
public X509CertificateValidatorEx(X509CertificateValidationMode certificateValidationMode, X509RevocationMode revocationMode, StoreLocation trustedStoreLocation) { this.certificateValidationMode = certificateValidationMode; switch (this.certificateValidationMode) { case X509CertificateValidationMode.None: { this.validator = X509CertificateValidator.None; break; } case X509CertificateValidationMode.PeerTrust: { this.validator = X509CertificateValidator.PeerTrust; break; } case X509CertificateValidationMode.ChainTrust: { bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; this.chainPolicy = new X509ChainPolicy(); this.chainPolicy.RevocationMode = revocationMode; this.validator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, this.chainPolicy); break; } case X509CertificateValidationMode.PeerOrChainTrust: { bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; this.chainPolicy = new X509ChainPolicy(); this.chainPolicy.RevocationMode = revocationMode; this.validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, this.chainPolicy); break; } default: throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10637, this.certificateValidationMode)); } }
/// <summary> /// Determines whether the specified certificate is considered valid by this specification. /// Always returns true. No online validation attempted. /// </summary> /// <param name="certificate">The certificate to validate.</param> /// <returns> /// <c>true</c>. /// </returns> public bool IsSatisfiedBy(X509Certificate2 certificate) { var chainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.NoCheck, VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority }; var defaultCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(false, chainPolicy); try { defaultCertificateValidator.Validate(certificate); return true; } catch (Exception e) { Logging.LoggerProvider.LoggerFor(GetType()).Warn(string.Format(ErrorMessages.CertificateIsNotRFC3280Valid, certificate.SubjectName.Name, certificate.Thumbprint, e.Message), e); } return false; }
public bool Build(X509Certificate2 certificate) { lock (m_syncRoot) { if (certificate == null || certificate.CertContext.IsInvalid) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidContextHandle), "certificate"); } #if !FEATURE_CORESYSTEM // Chain building opens and enumerates the root store to see if the root of the chain is trusted. StorePermission sp = new StorePermission(StorePermissionFlags.OpenStore | StorePermissionFlags.EnumerateCertificates); sp.Demand(); #endif X509ChainPolicy chainPolicy = this.ChainPolicy; #if !FEATURE_CORESYSTEM if (chainPolicy.RevocationMode == X509RevocationMode.Online) { if (certificate.Extensions[CAPI.szOID_CRL_DIST_POINTS] != null || certificate.Extensions[CAPI.szOID_AUTHORITY_INFO_ACCESS] != null) { // If there is a CDP or AIA extension, we demand unrestricted network access and store add permission // since CAPI can download certificates into the CA store from the network. PermissionSet ps = new PermissionSet(PermissionState.None); ps.AddPermission(new WebPermission(PermissionState.Unrestricted)); ps.AddPermission(new StorePermission(StorePermissionFlags.AddToStore)); ps.Demand(); } } #endif Reset(); int hr = BuildChain(m_useMachineContext ? new IntPtr(CAPI.HCCE_LOCAL_MACHINE) : new IntPtr(CAPI.HCCE_CURRENT_USER), certificate.CertContext, chainPolicy.ExtraStore, chainPolicy.ApplicationPolicy, chainPolicy.CertificatePolicy, chainPolicy.RevocationMode, chainPolicy.RevocationFlag, chainPolicy.VerificationTime, chainPolicy.UrlRetrievalTimeout, ref m_safeCertChainHandle); if (hr != CAPI.S_OK) { return(false); } // Init. Init(); // Verify the chain using the specified policy. CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA))); CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS))); PolicyPara.dwFlags = (uint)chainPolicy.VerificationFlags; if (!CAPI.CertVerifyCertificateChainPolicy(new IntPtr(CAPI.CERT_CHAIN_POLICY_BASE), m_safeCertChainHandle, ref PolicyPara, ref PolicyStatus)) { // The API failed. throw new CryptographicException(Marshal.GetLastWin32Error()); } CAPI.SetLastError(PolicyStatus.dwError); return(PolicyStatus.dwError == 0); } }
internal X509ChainImplBtls () { chain = new MonoBtlsX509Chain (); elements = new X509ChainElementCollection (); policy = new X509ChainPolicy (); }
internal X509ChainImplBtls (MonoBtlsX509Chain chain) { this.chain = chain.Copy (); policy = new X509ChainPolicy (); }
/// <summary> /// Creates an instance, specifying chain policy and problem flags /// </summary> /// <param name="policy">The <see cref="X509ChainPolicy"/> to use for validating trust chains</param> /// <param name="problemFlags">The status flags that will be treated as invalid in trust verification</param> public TrustChainValidator(X509ChainPolicy policy, X509ChainStatusFlags problemFlags) { m_policy = policy; m_problemFlags = problemFlags; }
/// <summary> /// This is the verify certificate callback method used when initially binding to the /// LDAP server. This manages all certificate validation. /// </summary> /// <param name="conn">The LDAP connection.</param> /// <param name="cert">The server's certificate</param> /// <returns>true if verification succeeds, false otherwise.</returns> private bool VerifyCert(LdapConnection conn, X509Certificate cert) { m_logger.Debug("VerifyCert(...)"); m_logger.DebugFormat("Verifying certificate from host: {0}", conn.SessionOptions.HostName); // Convert to X509Certificate2 X509Certificate2 serverCert = new X509Certificate2(cert); // If we don't need to verify the cert, the verification succeeds if (!m_verifyCert) { m_logger.Debug("Server certificate accepted without verification."); return true; } // If the certificate is null, then we verify against the machine's/user's certificate store if (m_cert == null) { m_logger.Debug("Verifying server cert with Windows store."); // We set the RevocationMode to NoCheck because most custom (self-generated) CAs // do not work properly with revocation lists. This is slightly less secure, but // the most common use case for this plugin probably doesn't rely on revocation // lists. X509ChainPolicy policy = new X509ChainPolicy() { RevocationMode = X509RevocationMode.NoCheck }; // Create a validator using the policy X509CertificateValidator validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(false,policy); try { validator.Validate(serverCert); // If we get here, validation succeeded. m_logger.Debug("Server certificate verification succeeded."); return true; } catch (SecurityTokenValidationException e) { m_logger.ErrorFormat("Server certificate validation failed: {0}", e.Message); return false; } } else { m_logger.Debug("Validating server certificate with provided certificate."); // Verify against the provided cert by comparing the thumbprint bool result = m_cert.Thumbprint == serverCert.Thumbprint; if (result) m_logger.Debug("Server certificate validated."); else m_logger.Debug("Server certificate validation failed."); return result; } }
internal bool Build(X509Certificate2 certificate, bool throwOnException) { lock (_syncRoot) { if (certificate == null || certificate.Pal == null) { throw new ArgumentException(SR.Cryptography_InvalidContextHandle, nameof(certificate)); } if (_chainPolicy != null && _chainPolicy.CustomTrustStore != null) { if (_chainPolicy.TrustMode == X509ChainTrustMode.System && _chainPolicy.CustomTrustStore.Count > 0) { throw new CryptographicException(SR.Cryptography_CustomTrustCertsInSystemMode, nameof(_chainPolicy.TrustMode)); } foreach (X509Certificate2 customCertificate in _chainPolicy.CustomTrustStore) { if (customCertificate == null || customCertificate.Handle == IntPtr.Zero) { throw new CryptographicException(SR.Cryptography_InvalidTrustCertificate, nameof(_chainPolicy.CustomTrustStore)); } } } Reset(); X509ChainPolicy chainPolicy = ChainPolicy; _pal = ChainPal.BuildChain( _useMachineContext, certificate.Pal, chainPolicy._extraStore, chainPolicy._applicationPolicy !, chainPolicy._certificatePolicy !, chainPolicy.RevocationMode, chainPolicy.RevocationFlag, chainPolicy.CustomTrustStore, chainPolicy.TrustMode, chainPolicy.VerificationTime, chainPolicy.UrlRetrievalTimeout, chainPolicy.DisableCertificateDownloads); if (_pal == null) { return(false); } _chainElements = new X509ChainElementCollection(_pal.ChainElements !); Exception?verificationException; bool? verified = _pal.Verify(chainPolicy.VerificationFlags, out verificationException); if (!verified.HasValue) { if (throwOnException) { throw verificationException !; } else { verified = false; } } return(verified.Value); } }
public PeerOrChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy) { this.chain = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); this.peer = (PeerTrustValidator)X509CertificateValidator.PeerTrust; }
public ChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy, uint chainPolicyOID) { this.useMachineContext = useMachineContext; this.chainPolicy = chainPolicy; this.chainPolicyOID = chainPolicyOID; }
public X509Chain(bool useMachineContext) { location = useMachineContext ? StoreLocation.LocalMachine : StoreLocation.CurrentUser; elements = new X509ChainElementCollection(); policy = new X509ChainPolicy(); }
public override void ApplyTo(ChannelFactory channelFactory) { if (!String.IsNullOrEmpty(Domain)) { channelFactory.Credentials.Windows.ClientCredential.Domain = Domain; string host = channelFactory.Endpoint.Address.Uri.Host; if (String.IsNullOrEmpty(host) || host.Equals("localhost", StringComparison.OrdinalIgnoreCase)) host = Environment.MachineName; channelFactory.Endpoint.Address = new EndpointAddress(channelFactory.Endpoint.Address.Uri, EndpointIdentity.CreateSpnIdentity("HOST/" + host)); } if (!String.IsNullOrEmpty(Username)) { channelFactory.Credentials.Windows.ClientCredential.UserName = Username; } if (_password.Length > 0) channelFactory.Credentials.Windows.ClientCredential.Password = GetPassword(); channelFactory.Credentials.Windows.AllowedImpersonationLevel = _tokenImpersonationLevel; channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom; X509ChainPolicy chainPolicy = new X509ChainPolicy(); chainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority | X509VerificationFlags.IgnoreNotTimeValid; channelFactory.Credentials.ServiceCertificate.Authentication.CustomCertificateValidator = X509CertificateValidator.CreateChainTrustValidator(true, chainPolicy); }
public X509Chain (bool useMachineContext) { location = useMachineContext ? StoreLocation.LocalMachine : StoreLocation.CurrentUser; elements = new X509ChainElementCollection (); policy = new X509ChainPolicy (); }
/// <summary> /// Throws an exception if validation fails. /// </summary> /// <param name="certificate">The certificate to be checked.</param> /// <exception cref="ServiceResultException">If certificate cannot be accepted</exception> protected virtual void InternalValidate(X509Certificate2 certificate) { lock (m_lock) { // check for previously validated certificate. X509Certificate2 certificate2 = null; if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2)) { if (Utils.IsEqual(certificate2.RawData, certificate.RawData)) { return; } } CertificateIdentifier trustedCertificate = GetTrustedCertificate(certificate); // get the issuers (checks the revocation lists if using directory stores). List<CertificateIdentifier> issuers = new List<CertificateIdentifier>(); bool isIssuerTrusted = GetIssuers(certificate, issuers); // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.NoCheck; policy.VerificationFlags = X509VerificationFlags.NoFlag; foreach (CertificateIdentifier issuer in issuers) { if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0) { policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; } // we did the revocation check in the GetIssuers call. No need here. policy.RevocationMode = X509RevocationMode.NoCheck; policy.ExtraStore.Add(issuer.Certificate); } // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); // check the chain results. CertificateIdentifier target = trustedCertificate; if (target == null) { target = new CertificateIdentifier(certificate); } for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; CertificateIdentifier issuer = null; if (ii < issuers.Count) { issuer = issuers[ii]; } // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0)); if (ServiceResult.IsBad(result)) { throw new ServiceResultException(result); } } if (issuer != null) { target = issuer; } } // check if certificate is trusted. if (trustedCertificate == null && !isIssuerTrusted) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } } }