Пример #1
0
        /// <summary>
        /// Gets the Thumbprint of the certificate that signed another
        /// </summary>
        /// <param name="CertContent">Certificate to check signer of</param>
        /// <param name="CAContent">List of possible signers</param>
        /// <returns>Thumbprint of signer, null if not found</returns>
        public static string GetSignerCertHash(string CertContent, string[] CAContent)
        {
            var CAs  = CAContent.Select(m => GetCert(m)).ToArray();
            var Cert = GetCert(CertContent);

            if (CAs.All(m => m != null) && Cert != null)
            {
                X509Chain chain = new X509Chain();
                chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
                chain.ChainPolicy.RevocationFlag    = X509RevocationFlag.ExcludeRoot;
                chain.ChainPolicy.VerificationFlags =
                    //Allow our own CA
                    X509VerificationFlags.AllowUnknownCertificateAuthority |
                    //Don't care if one of the certs has expired
                    X509VerificationFlags.IgnoreNotTimeValid |
                    //Don't care if the client cert validity is outside of the root cert
                    X509VerificationFlags.IgnoreNotTimeNested;
                chain.ChainPolicy.VerificationTime    = DateTime.Now;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);

                chain.ChainPolicy.ExtraStore.AddRange(CAs);

                if (!chain.Build(Cert))
                {
                    string[] errors = chain.ChainStatus
                                      .Select(x => string.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))
                                      .ToArray();
                    string certificateErrorsString = "Unknown errors.";

                    if (errors != null && errors.Length > 0)
                    {
                        certificateErrorsString = string.Join(", ", errors);
                    }
                    Logger.Error("Unable to construct Certificate Chain. Error: {0}", certificateErrorsString);
                }
                else
                {
                    if (chain.ChainElements.Count > 1)
                    {
                        var T = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.Thumbprint;
                        if (CAs.Any(m => m.Thumbprint == T))
                        {
                            Logger.Debug("Thumbprint found: {0}", T);
                            chain.Reset();
                            return(T);
                        }
                        else
                        {
                            Logger.Warn("Chain completed by a CA certificate from the system, not our own");
                        }
                    }
                }
                Logger.Warn("Attempted to find CA but none was available. Maybe it was deleted");
                chain.Reset();
            }
            return(null);
        }
Пример #2
0
        public void Build_Twice_WithReset()
        {
            X509Chain c = new X509Chain();

            Assert.IsFalse(c.Build(cert1), "Build-1");
            c.Reset();
            Assert.IsFalse(c.Build(cert2), "Build-2");
            c.Reset();
            CheckDefaultChain(c);
        }
        private static bool ValidateServerCertificateChain(object sender, X509Certificate pfxFormattedCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
            {
                return(true);
            }
            System.Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

            var serverCert                  = _spineConfiguration.server_ca_certchain;
            var serverCertData              = CertificateHelper.ExtractCertInstances(serverCert);
            var x509ServerCertificateSubCa  = new X509Certificate2(serverCertData[0]);
            var x509ServerCertificateRootCa = new X509Certificate2(serverCertData[1]);

            chain.Reset();
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreRootRevocationUnknown;
            chain.ChainPolicy.RevocationMode    = X509RevocationMode.Online;
            chain.ChainPolicy.ExtraStore.Add(x509ServerCertificateSubCa);
            chain.ChainPolicy.ExtraStore.Add(x509ServerCertificateRootCa);

            //if (chain.Build(pfxFormattedCertificate)) return true;
            if (chain.ChainStatus.Where(chainStatus => chainStatus.Status != X509ChainStatusFlags.NoError).All(chainStatus => chainStatus.Status != X509ChainStatusFlags.UntrustedRoot))
            {
                return(false);
            }
            var providedRoot = chain.ChainElements[^ 1];
Пример #4
0
        /// <summary>
        /// Adds key recovery agent (KRA) certificates to the CA. This method do not writes them to a Certification Authority.
        /// </summary>
        /// <param name="certs">One or more <see cref="X509Certificate2"/> object to add.</param>
        /// <exception cref="ArgumentNullException">The <strong>certs</strong> parameter is null or empty array.</exception>
        /// <remarks>
        /// If <see cref="Certificate"/> property already contains the certificate passed in <strong>certs</strong> parameter,
        /// the method skips the certificate.
        /// </remarks>
        public void Add(X509Certificate2[] certs)
        {
            if (certs == null || certs.Length == 0)
            {
                throw new ArgumentNullException(nameof(certs));
            }

            Int32     before = _certs.Count;
            X509Chain chain  = new X509Chain();

            chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.4.1.311.21.6"));
            foreach (X509Certificate2 cert in certs.Where(chain.Build))
            {
                if (
                    !String.IsNullOrEmpty(cert.Thumbprint) &&
                    Certificate.Find(X509FindType.FindByThumbprint, cert.Thumbprint, false).Count == 0
                    )
                {
                    _certs.Add(cert);
                }
                chain.Reset();
            }
            if (_certs.Count > before)
            {
                IsModified = true;
            }
        }
Пример #5
0
        static CertInfo ToCertInfo(X509Certificate2 cert)
        {
            var chain = new X509Chain();

            chain.Build(cert);

            CertInfo certInfo = null;

            for (int i = chain.ChainElements.Count - 1; i >= 0; i--)
            {
                var certElement = chain.ChainElements[i];
                certInfo = new CertInfo(
                    certElement.Certificate.FriendlyName,
                    certElement.Certificate.Subject,
                    certElement.Certificate.Thumbprint,
                    certElement.Certificate.SerialNumber,
                    certElement.Certificate.NotBefore,
                    certElement.Certificate.NotAfter,
                    certInfo,
                    certElement.Certificate.Verify(),
                    certElement.ChainElementStatus.Select(x => x.StatusInformation.ToString()).ToArray());
            }

            chain.Reset();
            return(certInfo);
        }
Пример #6
0
        public static void TestResetMethod()
        {
            using (var sampleCert = new X509Certificate2(TestData.DssCer))
                using (var chainHolder = new ChainHolder())
                {
                    X509Chain chain = chainHolder.Chain;

                    chain.ChainPolicy.ExtraStore.Add(sampleCert);
                    bool valid = chain.Build(sampleCert);
                    Assert.False(valid);
                    chainHolder.DisposeChainElements();

                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
                    chain.ChainPolicy.VerificationTime  = new DateTime(2015, 10, 15, 12, 01, 01, DateTimeKind.Local);
                    chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;

                    valid = chain.Build(sampleCert);
                    Assert.True(valid, "Chain built validly");

                    Assert.Equal(1, chain.ChainElements.Count);
                    chainHolder.DisposeChainElements();

                    chain.Reset();
                    Assert.Equal(0, chain.ChainElements.Count);

                    // ChainPolicy did not reset (for desktop compat)
                    Assert.Equal(X509VerificationFlags.AllowUnknownCertificateAuthority, chain.ChainPolicy.VerificationFlags);

                    valid = chain.Build(sampleCert);
                    Assert.Equal(1, chain.ChainElements.Count);
                    // This succeeds because ChainPolicy did not reset
                    Assert.True(valid, "Chain built validly after reset");
                }
        }
Пример #7
0
        public void Build_Cert1_X509RevocationMode_NoCheck()
        {
            X509Chain c = new X509Chain();

            c.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            foreach (X509VerificationFlags vf in Enum.GetValues(typeof(X509VerificationFlags)))
            {
                c.ChainPolicy.VerificationFlags = vf;
                CheckCert1(c);
                c.Reset();
            }
        }
Пример #8
0
        public void Build_Cert2()
        {
            X509Chain c = new X509Chain();

            foreach (X509VerificationFlags vf in Enum.GetValues(typeof(X509VerificationFlags)))
            {
                c.ChainPolicy.VerificationFlags = vf;
                CheckCert2(c);
                c.Reset();
            }
            // minimal criteria for success
            c.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid | X509VerificationFlags.AllowUnknownCertificateAuthority;
            CheckCert2(c);
        }
 private void Reset ()
 {
     filename = null;
     entry = null;
     hash = null;
     signedHash = null;
     signingCertificate = null;
     reason = -1;
     trustedRoot = false;
     trustedTimestampRoot = false;
     signerChain.Reset ();
     timestampChain.Reset ();
     timestamp = DateTime.MinValue;
 }
Пример #10
0
        public static X509Certificate2[] CompleteChain(this X509Certificate2[] certs)
        {
            X509Chain chain = null;

            try
            {
                chain = GetChainFromCerts(certs);
                chain.Build(certs[0]);
                return(chain.ChainElements.Cast <X509ChainElement>().Select(x => x.Certificate).ToArray());
            }
            finally
            {
                chain?.Reset();
            }
        }
Пример #11
0
        public static (IList <X509Certificate2>, Option <string>) BuildCertificateList(X509Certificate2 cert, Option <IList <X509Certificate2> > additionalCACertificates)
        {
            var chain = new X509Chain
            {
                ChainPolicy =
                {
                    // For performance reasons do not check revocation status.
                    RevocationMode    = X509RevocationMode.NoCheck,
                    // Does not check revocation status of the root certificate (sounds like it is meaningless with the option above - ask Simon or Alex)
                    RevocationFlag    = X509RevocationFlag.ExcludeRoot,
                    // Certificate Authority can be unknown if it is not issued directly by a well-known CA
                    VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority
                }
            };

            if (additionalCACertificates.HasValue)
            {
                foreach (X509Certificate2 additionalCertificate in additionalCACertificates.GetOrElse(new List <X509Certificate2>()))
                {
                    if (additionalCertificate != null)
                    {
                        chain.ChainPolicy.ExtraStore.Add(additionalCertificate);
                    }
                }
            }

            try
            {
                bool chainBuildSucceeded              = chain.Build(cert);
                X509ChainStatusFlags   flags          = X509ChainStatusFlags.UntrustedRoot | X509ChainStatusFlags.PartialChain;
                List <X509ChainStatus> filteredStatus = chain.ChainStatus.Where(cs => !flags.HasFlag(cs.Status)).ToList();
                if (!chainBuildSucceeded || filteredStatus.Count > 0)
                {
                    string errors = $"Certificate with subject: {cert.Subject} failed with errors: ";
                    string s      = filteredStatus
                                    .Select(c => c.StatusInformation)
                                    .Aggregate(errors, (prev, curr) => $"{prev} {curr}");
                    return(new List <X509Certificate2>(), Option.Some(s));
                }

                IList <X509Certificate2> chainElements = GetCertificatesFromChain(chain);
                return(chainElements, Option.None <string>());
            }
            finally
            {
                chain.Reset();
            }
        }
Пример #12
0
        static bool VerifyCrl(X509Crl crl)
        {
            X509Certificate issuer = FindCrlIssuer(crl);

            if (issuer == null)
            {
                return(false);
            }

            if (!crl.VerifySignature(issuer))
            {
                return(false);
            }

            chain.Reset();
            return(chain.Build(issuer));
        }
        private static bool ValidateServerCertificateChain(X509Chain chain, X509Certificate2 x509ServerCertificateSubCa,
                                                           X509Certificate2 x509ServerCertificateRootCa, X509Certificate2 pfxFormattedCertificate)
        {
            chain.Reset();
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreRootRevocationUnknown;
            chain.ChainPolicy.RevocationMode    = X509RevocationMode.Online;
            chain.ChainPolicy.ExtraStore.Add(x509ServerCertificateSubCa);
            chain.ChainPolicy.ExtraStore.Add(x509ServerCertificateRootCa);

            if (chain.Build(pfxFormattedCertificate))
            {
                return(true);
            }
            if (chain.ChainStatus.Where(chainStatus => chainStatus.Status != X509ChainStatusFlags.NoError).All(chainStatus => chainStatus.Status != X509ChainStatusFlags.UntrustedRoot))
            {
                return(false);
            }
            var providedRoot = chain.ChainElements[^ 1];
Пример #14
0
        void buildSignerCertChain()
        {
            X509Chain chain = new X509Chain {
                ChainPolicy = { RevocationMode = X509RevocationMode.NoCheck }
            };

            chain.Build(SignerCertificate);
            for (Int32 index = 0; index < chain.ChainElements.Count; index++)
            {
                X509Certificate2 cert = chain.ChainElements[index].Certificate;
                if (index > 0 && cert.Subject == cert.Issuer)
                {
                    break;
                }
                _signerChain.Add(cert);
            }
            chain.Reset();
        }
        public static X509Certificate2 GetIssuer(X509Certificate2 leafCert)
        {
            if (leafCert.Subject == leafCert.Issuer)
            {
                return(leafCert);
            }
            X509Chain chain = new X509Chain();

            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            chain.Build(leafCert);
            X509Certificate2 issuer = null;

            if (chain.ChainElements.Count > 1)
            {
                issuer = chain.ChainElements[1].Certificate;
            }
            chain.Reset();
            return(issuer);
        }
Пример #16
0
        /// <summary>
        /// Validates the client certificate by checking whether it has been signed by the server.
        /// </summary>
        /// <param name="sender">The sender of the callback.</param>
        /// <param name="certificate">The client certificate to validate.</param>
        /// <param name="chain">The X.509 chain.</param>
        /// <param name="sslPolicyErrors">The SSL policy errors.</param>
        /// <returns>Returns <value>true</value> when the validation was successful, otherwise <value>false</value>.</returns>
        public bool ValidateClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
#if DEBUG
            // for debugging don't validate client certificate
            return(true);
#else
            // if client does not provide a certificate, don't accept connection
            if (certificate == null)
            {
                return(false);
            }

            chain.Reset();
            chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
            chain.ChainPolicy.VerificationTime  = DateTime.UtcNow;
            chain.ChainPolicy.ExtraStore.Add(_serverCertificate);

            chain.Build(new X509Certificate2(certificate));

            bool result = true;

            foreach (var status in chain.ChainStatus)
            {
                if (status.Status == X509ChainStatusFlags.UntrustedRoot)
                {
                    // self-signed certificates with an untrusted root are valid.
                    continue;
                }
                else
                {
                    if (status.Status != X509ChainStatusFlags.NoError)
                    {
                        // if there are any other errors in the certificate chain, the certificate is invalid.
                        result = false;
                    }
                }
            }

            return(result);
#endif
        }
Пример #17
0
        public static bool ValidateChain(this X509Certificate2[] certs)
        {
            if ((certs?.Length ?? 0) == 0)
            {
                return(false);
            }

            // TODO: spravit cache pre validacie; vyprazdnit ak bola menej ako cca 1 minuta

            X509Chain chain = null;

            try
            {
                chain = GetChainFromCerts(certs);
                return(chain.Build(certs[0]));
            }
            finally
            {
                chain?.Reset();
            }
        }
Пример #18
0
        /// <summary>
        /// Validates the certificate when <see cref="SslStream"/>.AuthenticateAsClient() is called.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns>True when the certificate is valid, False when the certificate is invalid.</returns>
        protected virtual bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if (_allowUntrustedRootCa)
            {
                // remove this line if commercial CAs are not allowed to issue certificate for your service.
                if ((sslPolicyErrors & SslPolicyErrors.None) > 0)
                {
                    return(true);
                }

                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) > 0 || (sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) > 0)
                {
                    return(false);
                }

                // execute certificate chaining engine and ignore only "UntrustedRoot" error
                X509Chain customChain = new X509Chain
                {
                    ChainPolicy =
                    {
                        VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority
                    }
                };
                Boolean retValue = customChain.Build(chain.ChainElements[0].Certificate);
                // RELEASE unmanaged resources behind X509Chain class.
                customChain.Reset();
                return(retValue);
            }

            //Full Certificate-Validation
            if (sslPolicyErrors == SslPolicyErrors.None)
            {
                return(true);
            }

            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

            // Do not allow this client to communicate with unauthenticated servers.
            return(false);
        }
Пример #19
0
        public X509Certificate2 GetIssuerCertificate(X509Certificate2 cert)
        {
            // Self Signed Certificate
            if (cert.Subject == cert.Issuer)
            {
                return(cert);
            }

            var chain = new X509Chain();

            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            chain.Build(cert);
            X509Certificate2 issuer = null;

            if (chain.ChainElements.Count > 1)
            {
                issuer = chain.ChainElements[1].Certificate;
            }
            chain.Reset();

            return(issuer);
        }
Пример #20
0
 public override void Validate(X509Certificate2 cert)
 {
     if (check_peer)
     {
         X509Store store = new X509Store();
         store.Open(OpenFlags.ReadOnly);
         foreach (X509Certificate2 c in store.Certificates)
         {
             if (c.Thumbprint == cert.Thumbprint)
             {
                 return;
             }
         }
     }
     if (check_chain)
     {
         if (chain == null)
         {
             if (use_machine_ctx)
             {
                 chain = X509Chain.Create();
             }
             else
             {
                 chain = new X509Chain();
             }
             chain.ChainPolicy = policy;
         }
         else
         {
             chain.Reset();
         }
         if (chain.Build(cert))
         {
             return;
         }
     }
     throw new ArgumentException("The argument certificate is invalid.");
 }
        Boolean ServerCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            String rootCAThumbprint = "";             // write your code to get your CA's thumbprint

            // remove this line if commercial CAs are not allowed to issue certificate for your service.
            if ((sslPolicyErrors & (SslPolicyErrors.None)) > 0)
            {
                return(true);
            }

            if (
                (sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNameMismatch)) > 0 ||
                (sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNotAvailable)) > 0
                )
            {
                return(false);
            }
            // get last chain element that should contain root CA certificate
            // but this may not be the case in partial chains
            X509Certificate2 projectedRootCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;

            if (projectedRootCert.Thumbprint != rootCAThumbprint)
            {
                return(false);
            }
            // execute certificate chaining engine and ignore only "UntrustedRoot" error
            X509Chain customChain = new X509Chain {
                ChainPolicy =
                {
                    VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority
                }
            };
            Boolean retValue = customChain.Build(chain.ChainElements[0].Certificate);

            // RELEASE unmanaged resources behind X509Chain class.
            chain.Reset();
            return(retValue);
        }
Пример #22
0
        static bool ServerCertificateValidationCallback(X509Certificate2 ourCA, object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if ((sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateNotAvailable)) > 0)
            {
                return(false);
            }

            X509Chain customChain = new X509Chain(false);

            customChain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
            customChain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
            customChain.ChainPolicy.ExtraStore.Add(ourCA);
            if (!customChain.Build(chain.ChainElements[0].Certificate))
            {
                return(false);
            }
            var  chainElements = customChain.ChainElements;
            bool valid         = chainElements[chainElements.Count - 1].Certificate.Thumbprint == ourCA.Thumbprint;

            customChain.Reset();

            return(valid);
        }
Пример #23
0
        public void Reset()
        {
            X509Chain c = new X509Chain();

            c.ChainPolicy.ApplicationPolicy.Add(new Oid("1.2.3"));
            c.ChainPolicy.CertificatePolicy.Add(new Oid("1.2.4"));
            c.ChainPolicy.ExtraStore.AddRange(collection);
            c.ChainPolicy.RevocationFlag      = X509RevocationFlag.EntireChain;
            c.ChainPolicy.RevocationMode      = X509RevocationMode.Offline;
            c.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(1000);
            c.ChainPolicy.VerificationFlags   = X509VerificationFlags.IgnoreWrongUsage;
            c.ChainPolicy.VerificationTime    = DateTime.MinValue;
            c.Reset();
            // resetting the chain doesn't reset the policy
            Assert.AreEqual(1, c.ChainPolicy.ApplicationPolicy.Count, "ApplicationPolicy");
            Assert.AreEqual(1, c.ChainPolicy.CertificatePolicy.Count, "CertificatePolicy");
            Assert.AreEqual(2, c.ChainPolicy.ExtraStore.Count, "ExtraStore");
            Assert.AreEqual(X509RevocationFlag.EntireChain, c.ChainPolicy.RevocationFlag, "RevocationFlag");
            Assert.AreEqual(X509RevocationMode.Offline, c.ChainPolicy.RevocationMode, "RevocationMode");
            Assert.AreEqual(1000, c.ChainPolicy.UrlRetrievalTimeout.Ticks, "UrlRetrievalTimeout");
            Assert.AreEqual(X509VerificationFlags.IgnoreWrongUsage, c.ChainPolicy.VerificationFlags, "VerificationFlags");
            Assert.AreEqual(DateTime.MinValue, c.ChainPolicy.VerificationTime, "VerificationTime");
        }
        protected X509Certificate SelectClientCertificate(string[] acceptableIssuers)
        {
            if (Settings.DisallowUnauthenticatedCertificateRequest && !IsAuthenticated)
            {
                return(null);
            }

            if (RemoteCertificate == null)
            {
                throw new TlsException(AlertDescription.InternalError, "Cannot request client certificate before receiving one from the server.");
            }

            /*
             * We need to pass null to the user selection callback during the initial handshake, to allow the callback to distinguish
             * between an authenticated and unauthenticated session.
             */
            X509Certificate certificate;
            var             selected = certificateValidator.SelectClientCertificate(
                TargetHost, ClientCertificates, IsAuthenticated ? RemoteCertificate : null, acceptableIssuers, out certificate);

            if (selected)
            {
                return(certificate);
            }

            if (ClientCertificates == null || ClientCertificates.Count == 0)
            {
                return(null);
            }

            /*
             * .NET actually scans the entire collection to ensure the selected certificate has a private key in it.
             *
             * However, since we do not support private key retrieval from the key store, we require all certificates
             * to have a private key in them (explicitly or implicitly via OS X keychain lookup).
             */
            if (acceptableIssuers == null || acceptableIssuers.Length == 0)
            {
                return(ClientCertificates [0]);
            }

            // Copied from the referencesource implementation in referencesource/System/net/System/Net/_SecureChannel.cs.
            for (int i = 0; i < ClientCertificates.Count; i++)
            {
                var certificate2 = ClientCertificates[i] as X509Certificate2;
                if (certificate2 == null)
                {
                    continue;
                }

                X509Chain chain = null;
                try {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreInvalidName;
                    chain.Build(certificate2);

                    //
                    // We ignore any errors happened with chain.
                    // Consider: try to locate the "best" client cert that has no errors and the lognest validity internal
                    //
                    if (chain.ChainElements.Count == 0)
                    {
                        continue;
                    }
                    for (int ii = 0; ii < chain.ChainElements.Count; ++ii)
                    {
                        var issuer = chain.ChainElements[ii].Certificate.Issuer;
                        if (Array.IndexOf(acceptableIssuers, issuer) != -1)
                        {
                            return(certificate2);
                        }
                    }
                } catch {
                    ;                     // ignore errors
                } finally {
                    if (chain != null)
                    {
                        chain.Reset();
                    }
                }
            }

            // No certificate matches.
            return(null);
        }
Пример #25
0
        /// <summary>
        /// Submits HTTP request to a remote server and updates current object instance.
        /// </summary>
        public void SendRequest()
        {
            if (Request != null)
            {
                List <String> san   = new List <String>();
                X509Chain     Chain = new X509Chain(!UserContext);
                Pkcs7Chain = new X509Certificate2Collection();
                // add inline delegate definition
                ServicePointManager.ServerCertificateValidationCallback =
                    delegate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
                    // check if web server returns multiple certificates
                    if (chain.ChainElements.Count > 1)
                    {
                        foreach (X509ChainElement item in chain.ChainElements)
                        {
                            Pkcs7Chain.Add(item.Certificate);
                            // add each certificate to X509Chain.ExtraStore, so certificate chaining engine
                            // will be able to use them for chain building
                            Chain.ChainPolicy.ExtraStore.Add(item.Certificate);
                        }
                    }
                    if (((Int32)sslPolicyErrors & (Int32)SslPolicyErrors.RemoteCertificateNameMismatch) == 0)
                    {
                        NameMatch = true;
                    }
                    return(true);
                };
                try {
                    Response    = (HttpWebResponse)Request.GetResponse();
                    ReturnedUri = Response.ResponseUri;
                    if (Request.ServicePoint.Certificate != null)
                    {
                        Certificate = new X509Certificate2(Request.ServicePoint.Certificate);

                        Subject = Certificate.SubjectName;
                        Issuer  = Certificate.IssuerName;
                        if (Certificate.Extensions.Count > 0)
                        {
                            foreach (X509Extension item in Certificate.Extensions)
                            {
                                if (item.Oid.Value == X509CertExtensions.X509SubjectAlternativeNames)
                                {
                                    san.AddRange(item.Format(false).Split(new [] { ", " }, StringSplitOptions.RemoveEmptyEntries));
                                }
                            }
                        }
                        SubjectAlternativeNames = san.ToArray();
                        // add other settings for X509Chain and validate server certificate.
                        Chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1"));
                        CertificateIsValid = Chain.Build(Certificate);
                        ErrorInformation   = Chain.ChainStatus;
                    }
                } catch {
                    if (!Request.HaveResponse)
                    {
                        throw;
                    }
                } finally {
                    Chain.Reset();
                    if (Response.ContentLength > 0)
                    {
                        Response.Close();
                    }
                    ServicePointManager.ServerCertificateValidationCallback = null;
                }
            }
            else
            {
                throw new UninitializedObjectException();
            }
        }
Пример #26
0
        /// <summary>
        /// Checks a certificate status in a CRL.
        /// </summary>
        /// <param name="certificate">The certificate to check</param>
        /// <returns>The RevocationResponse object that contains the result</returns>
        public RevocationResponse CheckCertificate(X509Certificate2 certificate)
        {
            /*
             * Assumptions:
             * - Certificate has an CRL Distribution Points extension value.
             * - An HTTP distribution point is present.
             */

            // create RevocationResponse and set default values
            RevocationResponse response = new RevocationResponse();

            response.IsValid    = true;
            response.NextUpdate = DateTime.MinValue;

            if (certificate != null)
            {
                X509Chain x509Chain = new X509Chain();
                x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                x509Chain.Build(certificate);

                // Iterate though the chain, to get the certificate list
                X509ChainElementCollection             x509ChainElementCollection = x509Chain.ChainElements;
                X509ChainElementEnumerator             enumerator = x509ChainElementCollection.GetEnumerator();
                X509ChainElement                       x509ChainElement;
                X509Certificate2                       x509Certificate2 = null;
                IDictionary <string, X509Certificate2> map  = new Dictionary <string, X509Certificate2>();
                IList <X509Certificate2>               list = new List <X509Certificate2>();

                while (enumerator.MoveNext())
                {
                    x509ChainElement = enumerator.Current;
                    x509Certificate2 = x509ChainElement.Certificate;
                    list.Add(x509Certificate2);
                }

                // now we have a list of the certificate chain
                // list[0] -> the function certificate
                // list[0 .. lsit.Count] -> middel certificates
                //   oces1 : none middle certificate exist
                //   oces2 : one middle certificate exist
                // list[list.Count] - > root certificate
                // we needed to validate all certificates, except the root certificates
                // The question wheather the root certificates is trusted, is validated in MultipleRootX509CertificateValidator
                // However - In the case where the root certificate is not installed,
                // the chain list will only be 1 length, so no validation is perfored at all.


                int index = 0;
                //bool chainValid = true;
                while (index < (list.Count - 1) && response.IsValid == true)
                {
                    // this.logger.Info("CRL validation the certificate: " + list[index].Subject);
                    // Retrieve URL distribution points
                    List <Uri> URLs = this.GetURLs(list[index]);

                    // The list should only contain one element
                    // so we are only interesting in the first CRL list
                    if (URLs.Count > 0)
                    {
                        Uri         url = URLs[0];
                        CrlInstance crl = this.GetInstance(url);

                        try
                        {
                            if (!crl.IsRevoked(certificate))
                            {
                                // so the certificate is not revoked.
                                // remember, that the issueing certificate could be revoked.
                                // So the next update must be the earlist of the all
                                response.IsValid = true;
                                if (response.NextUpdate == DateTime.MinValue)
                                {
                                    response.NextUpdate = crl.getNextUpdate();
                                }
                                else if (response.NextUpdate < crl.getNextUpdate())
                                {
                                    // no new update
                                    // the already registrated 'NextUpdate' is before the crl.getNextUpdate
                                }
                                else
                                {
                                    // new update time
                                    // The already registrated 'NextUpdate', is greater (futher in the future) then crl.getNextUpdate
                                    // so we use the crl.getNextUpdate as next update
                                    response.NextUpdate = crl.getNextUpdate();
                                }
                            }
                            else
                            {
                                response.IsValid = false;
                            }
                        }
                        catch (CheckCertificateRevokedUnexpectedException exception)
                        {
                            // could not validate the certificate - so i don't trust it
                            response.Exception = exception;
                            response.IsValid   = false;
                        }
                    }
                    else
                    {
                        // url server not identified, so we don't trust this certificate
                        response.IsValid = false;
                    }

                    // increase the index, to check the next certificate
                    index++;
                }

                // all the certificate in the chain is now checked.
                if (response.IsValid == true)
                {
                    response.RevocationCheckStatus = RevocationCheckStatus.AllChecksPassed;
                }
                else
                {
                    response.RevocationCheckStatus = RevocationCheckStatus.CertificateRevoked;
                }

                x509Chain.Reset();
            }
            else
            {
                response.IsValid               = false;
                response.Exception             = new CheckCertificateRevokedUnexpectedException(new Exception("Error during CRL lookup. The certificate is null"));//did not have any CRL DistPoints. Certificate: " + certificate));
                response.RevocationCheckStatus = RevocationCheckStatus.UnknownIssue;
            }

            return(response);
        }
        /// <summary>
        /// Validate the PC-EFTPOS Cloud server certificate.
        /// </summary>
        /// <returns>TRUE if the certificate is valid, FALSE otherwise</returns>
        bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
#if (DEBUG)
            return(true);
#endif
            // Certificate chain is valid via a commercial 3rd party chain
            if (sslPolicyErrors == SslPolicyErrors.None)
            {
                Log(LogLevel.Info, tr => tr.Set("Remote certificate validated successfull by installed CA"));
                return(true);
            }

            // Certificate has an invalid CN or isn't available from the server
            if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable || sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                LogRemoteCertificateFailure(certificate, chain, sslPolicyErrors);
                return(false);
            }

            // The certificate is invalid due to an invalid chain. If we have included custom certificates we can attempt to validate here
            if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors && CustomeRootCerts?.Count > 0)
            {
                // Load custom certificates
                var x509Certificates = new List <X509Certificate2>();
                foreach (var certFilename in CustomeRootCerts)
                {
                    try
                    {
                        x509Certificates.Add(new X509Certificate2(certFilename));
                    }
                    catch (System.Security.Cryptography.CryptographicException e)
                    {
                        Log(LogLevel.Error, tr => tr.Set($"Error loading certificate ({certFilename})", e));
                        return(false);
                    }
                }

                var c = new X509Chain();
                try
                {
                    c.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
                    c.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage;
                    c.ChainPolicy.ExtraStore.AddRange(x509Certificates.ToArray());
                    // Check if the chain is valid
                    if (c.Build((X509Certificate2)certificate))
                    {
                        Log(LogLevel.Info, tr => tr.Set($"Remote certificate validated successfull by custom cert chain"));
                        return(true);
                    }
                    // The chain may not be valid, but if the only fault is an UntrustedRoot we can check if we have the custom root
                    else
                    {
                        if (c?.ChainStatus?.Length > 0 && c?.ChainStatus[0].Status == X509ChainStatusFlags.UntrustedRoot)
                        {
                            var root = c.ChainElements[c.ChainElements.Count - 1];
                            if (x509Certificates.Find(x509Certificate => x509Certificate.Thumbprint == root.Certificate.Thumbprint) != null)
                            {
                                Log(LogLevel.Info, tr => tr.Set($"Remote certificate validated successfull by custom cert chain and root"));
                                return(true);
                            }
                        }
                    }
                }
                finally
                {
                    c.Reset();
                }
            }

            LogRemoteCertificateFailure(certificate, chain, sslPolicyErrors);
            return(false);
        }
Пример #28
0
        /// <summary>
        /// Validate the <see cref="X509Certificate2"/> for PSD2 compliance.
        /// </summary>
        /// <param name="certificate"></param>
        /// <param name="type">QC Type identifier. qSeal, qSign, Web. If passed null checks any of the valid ones</param>
        /// <param name="errors"></param>
        public bool Validate(X509Certificate2 certificate, X509Certificates.QcTypeIdentifiers?type, out IEnumerable <string> errors)
        {
            var errorList = new List <string>();

            errors = errorList;
            var authorityKeyId = certificate.GetAuthorityKeyIdentifier();

            if (string.IsNullOrEmpty(authorityKeyId))
            {
                errorList.Add("Missing authority Key Identifier extension");
            }
            var qcStatements = certificate.GetQualifiedCertificateStatements();

            if (qcStatements == null)
            {
                errorList.Add("Missing the QcStatements X509Certivicate extension");
            }
            else
            {
                if (!qcStatements.IsCompliant)
                {
                    errorList.Add($"Although the certificate has the QcStatements X509Certivicate extension it is not a compliant \"European Qualified Certificate\". ");
                }
                if (qcStatements?.Psd2Type == null)
                {
                    errorList.Add("This is not a valid QWAC or QCseal. Missing the PSD2 type QcStatement");
                }
                if (type.HasValue && type.Value != qcStatements.Type)
                {
                    errorList.Add($"{qcStatements.Type} is not a valid QcTypeIdentifier for the current use of this certificate. Expected option {type}");
                }
                else if ((int)qcStatements.Type < 0 && 3 < (int)qcStatements.Type)
                {
                    errorList.Add($"{qcStatements.Type} is not a valid QcTypeIdentifier. Valid options include {QcTypeIdentifiers.Web}, {QcTypeIdentifiers.eSeal} and {QcTypeIdentifiers.eSign}");
                }
                if (!qcStatements.Psd2Type.Roles.Any())
                {
                    errorList.Add("There are no roles defined in this certificate");
                }
                //if (!qcStatements.Psd2Type.AuthorizationId.IsValid) {
                //    errorList.Add($"The NCAId is not in a valid format {qcStatements.Psd2Type.AuthorizationId}");
                //}
            }
            var accessDescriptions = certificate.GetAuthorityInformationAccess();

            if (accessDescriptions == null || !accessDescriptions.Any())
            {
                errorList.Add($"There is no Authority Information Access extension inside the certificate.");
            }
            var policies = certificate.GetCertificatePolicies();

            if (policies == null || !policies.Any(x => x.IsEUQualifiedCertificate))
            {
                errorList.Add($"There is no Certificate Policy that identifies the current certificate as EU Qualified. There should be one in every eIDAs cert. Acceptable policy identifiers include: QCP-n, QCP-l, QCP-n-qscd, QCP-l-qscd, QCP-w");
            }
            var crlDistributionPoints = certificate.GetCRLDistributionPoints();

            if (crlDistributionPoints == null || !crlDistributionPoints.Any())
            {
                errorList.Add($"There is no CRL distribution points extension inside the certificate.");
            }
            var authorizationId = qcStatements.Psd2Type.AuthorizationId;
            var organizationId  = certificate.GetCABForumOrganizationIdentifier();
            var subjectOrgId    = certificate.GetSubjectBuilder().GetOrganizationIdentifier();

            if (string.IsNullOrEmpty(subjectOrgId))
            {
                errorList.Add("The subject must contain the Organization Identifier as defined in PSD2 by the 2.5.4.97 Oid");
            }
            if (organizationId == null)
            {
                errorList.Add("There is no CA/Browser Forum OrganizationIdentifier extension inside the certificate. Oid 2.23.140.3.1");
            }
            if (!string.IsNullOrEmpty(subjectOrgId) && organizationId != null)
            {
                if (!NCAId.TryParse(organizationId.ToString(), out var id) || !id.IsValid)
                {
                    errorList.Add($"The organizationId inside the CA/Browser Forum OrganizationIdentifier has an invalid format. {organizationId}");
                }
                else if (!id.Equals(subjectOrgId))
                {
                    errorList.Add($"The organizationId inside the CA/Browser Forum OrganizationIdentifier is not the same with the one in the subject, {organizationId} != {subjectOrgId}");
                }
            }
            var chain = new X509Chain();

            chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
            chain.Build(certificate);
            X509Certificate2 issuer = null;

            if (chain.ChainElements.Count > 1)
            {
                issuer = chain.ChainElements[1].Certificate;
            }
            chain.Reset();

            return(errorList.Count == 0);
        }
Пример #29
0
        private bool AcquireClientCredentials(ref byte[] thumbPrint)
        {
            X509Certificate certificate = null;
            ArrayList       list        = new ArrayList();

            string[] acceptableIssuers = null;
            bool     flag = false;

            if (this.m_CertSelectionDelegate != null)
            {
                if (acceptableIssuers == null)
                {
                    acceptableIssuers = this.GetIssuers();
                }
                X509Certificate2 remoteCertificate = null;
                try
                {
                    X509Certificate2Collection certificates;
                    remoteCertificate = this.GetRemoteCertificate(out certificates);
                    certificate       = this.m_CertSelectionDelegate(this.m_HostName, this.ClientCertificates, remoteCertificate, acceptableIssuers);
                }
                finally
                {
                    if (remoteCertificate != null)
                    {
                        remoteCertificate.Reset();
                    }
                }
                if (certificate != null)
                {
                    if (this.m_CredentialsHandle == null)
                    {
                        flag = true;
                    }
                    list.Add(certificate);
                    if (Logging.On)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_got_certificate_from_delegate"));
                    }
                }
                else if (this.ClientCertificates.Count == 0)
                {
                    if (Logging.On)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_delegate_and_have_no_client_cert"));
                    }
                    flag = true;
                }
                else if (Logging.On)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_delegate_but_have_client_cert"));
                }
            }
            else if (((this.m_CredentialsHandle == null) && (this.m_ClientCertificates != null)) && (this.m_ClientCertificates.Count > 0))
            {
                certificate = this.ClientCertificates[0];
                flag        = true;
                if (certificate != null)
                {
                    list.Add(certificate);
                }
                if (Logging.On)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_attempting_restart_using_cert", new object[] { (certificate == null) ? "null" : certificate.ToString(true) }));
                }
            }
            else if ((this.m_ClientCertificates != null) && (this.m_ClientCertificates.Count > 0))
            {
                if (acceptableIssuers == null)
                {
                    acceptableIssuers = this.GetIssuers();
                }
                if (Logging.On)
                {
                    if ((acceptableIssuers == null) || (acceptableIssuers.Length == 0))
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_issuers_try_all_certs"));
                    }
                    else
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_server_issuers_look_for_matching_certs", new object[] { acceptableIssuers.Length }));
                    }
                }
                for (int j = 0; j < this.m_ClientCertificates.Count; j++)
                {
                    if ((acceptableIssuers != null) && (acceptableIssuers.Length != 0))
                    {
                        X509Certificate2 certificate3 = null;
                        X509Chain        chain        = null;
                        try
                        {
                            certificate3 = MakeEx(this.m_ClientCertificates[j]);
                            if (certificate3 == null)
                            {
                                continue;
                            }
                            chain = new X509Chain {
                                ChainPolicy = { RevocationMode = X509RevocationMode.NoCheck, VerificationFlags = X509VerificationFlags.IgnoreInvalidName }
                            };
                            chain.Build(certificate3);
                            bool flag2 = false;
                            if (chain.ChainElements.Count > 0)
                            {
                                for (int k = 0; k < chain.ChainElements.Count; k++)
                                {
                                    string issuer = chain.ChainElements[k].Certificate.Issuer;
                                    flag2 = Array.IndexOf <string>(acceptableIssuers, issuer) != -1;
                                    if (flag2)
                                    {
                                        break;
                                    }
                                }
                            }
                            if (!flag2)
                            {
                                continue;
                            }
                        }
                        finally
                        {
                            if (chain != null)
                            {
                                chain.Reset();
                            }
                            if ((certificate3 != null) && (certificate3 != this.m_ClientCertificates[j]))
                            {
                                certificate3.Reset();
                            }
                        }
                    }
                    if (Logging.On)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_selected_cert", new object[] { this.m_ClientCertificates[j].ToString(true) }));
                    }
                    list.Add(this.m_ClientCertificates[j]);
                }
            }
            X509Certificate2 certificate4 = null;

            certificate = null;
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_n_certs_after_filtering", new object[] { list.Count }));
                if (list.Count != 0)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_finding_matching_certs"));
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                certificate  = list[i] as X509Certificate;
                certificate4 = this.EnsurePrivateKey(certificate);
                if (certificate4 != null)
                {
                    break;
                }
                certificate  = null;
                certificate4 = null;
            }
            try
            {
                byte[] buffer = (certificate4 == null) ? null : certificate4.GetCertHash();
                SafeFreeCredentials credentials = SslSessionsCache.TryCachedCredential(buffer, this.m_ProtocolFlags, this.m_EncryptionPolicy);
                if ((flag && (credentials == null)) && (certificate4 != null))
                {
                    if (certificate != certificate4)
                    {
                        certificate4.Reset();
                    }
                    buffer       = null;
                    certificate4 = null;
                    certificate  = null;
                }
                if (credentials != null)
                {
                    if (Logging.On)
                    {
                        Logging.PrintInfo(Logging.Web, SR.GetString("net_log_using_cached_credential"));
                    }
                    this.m_CredentialsHandle         = credentials;
                    this.m_SelectedClientCertificate = certificate;
                    return(true);
                }
                SecureCredential secureCredential = new SecureCredential(4, certificate4, SecureCredential.Flags.NoDefaultCred | SecureCredential.Flags.ValidateManual, this.m_ProtocolFlags, this.m_EncryptionPolicy);
                this.m_CredentialsHandle = this.AcquireCredentialsHandle(CredentialUse.Outbound, ref secureCredential);
                thumbPrint = buffer;
                this.m_SelectedClientCertificate = certificate;
            }
            finally
            {
                if ((certificate4 != null) && (certificate != certificate4))
                {
                    certificate4.Reset();
                }
            }
            return(false);
        }