Esempio n. 1
0
 public void Reset()
 {
     // note: this call doesn't Reset the X509ChainPolicy
     if ((status != null) && (status.Length != 0))
     {
         status = null;
     }
     if (elements.Count > 0)
     {
         elements.Clear();
     }
     if (roots != null)
     {
         roots.Close();
         roots = null;
     }
     if (cas != null)
     {
         cas.Close();
         cas = null;
     }
     collection         = null;
     bce_restriction    = null;
     working_public_key = null;
 }
Esempio n. 2
0
        private void Process(int n)
        {
            X509ChainElement x509ChainElement = this.elements[n];
            X509Certificate2 certificate      = x509ChainElement.Certificate;

            if (n != this.elements.Count - 1 && certificate.MonoCertificate.KeyAlgorithm == "1.2.840.10040.4.1" && certificate.MonoCertificate.KeyAlgorithmParameters == null)
            {
                X509Certificate2 certificate2 = this.elements[n + 1].Certificate;
                certificate.MonoCertificate.KeyAlgorithmParameters = certificate2.MonoCertificate.KeyAlgorithmParameters;
            }
            bool flag = this.working_public_key == null;

            if (!this.IsSignedWith(certificate, (!flag) ? this.working_public_key : certificate.PublicKey.Key) && (flag || n != this.elements.Count - 1 || this.IsSelfIssued(certificate)))
            {
                x509ChainElement.StatusFlags |= X509ChainStatusFlags.NotSignatureValid;
            }
            if (this.ChainPolicy.VerificationTime < certificate.NotBefore || this.ChainPolicy.VerificationTime > certificate.NotAfter)
            {
                x509ChainElement.StatusFlags |= X509ChainStatusFlags.NotTimeValid;
            }
            if (flag)
            {
                return;
            }
            if (!X500DistinguishedName.AreEqual(certificate.IssuerName, this.working_issuer_name))
            {
                x509ChainElement.StatusFlags |= X509ChainStatusFlags.InvalidNameConstraints;
            }
            if (this.IsSelfIssued(certificate) || n != 0)
            {
            }
        }
        private void WrapUp()
        {
            X509ChainElement element     = elements [0];
            X509Certificate2 certificate = element.Certificate;

            // 6.1.5.a - TODO if certificate n (our 0) wasn't self issued and explicit_policy != 0
            if (IsSelfIssued(certificate))
            {
                // TODO... decrement explicit_policy by 1
            }

            // 6.1.5.b - TODO

            // 6.1.5.c,d,e - not required by the X509Chain implementation

            // 6.1.5.f - recognize and process other critical extension present in the certificate
            ProcessCertificateExtensions(element);

            // 6.1.5.g - TODO

            // uncompressed the flags into several elements
            for (int i = elements.Count - 1; i >= 0; i--)
            {
                elements [i].UncompressFlags();
            }
        }
        // This isn't how RFC3280 (section 6.3) deals with CRL, but then we don't (yet) support DP, deltas...
        private X509ChainStatusFlags CheckRevocation(X509Certificate2 certificate, int ca, bool online)
        {
            X509ChainStatusFlags result  = X509ChainStatusFlags.RevocationStatusUnknown;
            X509ChainElement     element = elements [ca];
            X509Certificate2     ca_cert = element.Certificate;

            // find the CRL from the "right" CA
            while (IsSelfIssued(ca_cert) && (ca < elements.Count - 1))
            {
                // try with this self-issued
                result = CheckRevocation(certificate, ca_cert, online);
                if (result != X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    break;
                }
                ca++;
                element = elements [ca];
                ca_cert = element.Certificate;
            }
            if (result == X509ChainStatusFlags.RevocationStatusUnknown)
            {
                result = CheckRevocation(certificate, ca_cert, online);
            }
            return(result);
        }
Esempio n. 5
0
        private void CheckRevocationOnChain(X509ChainStatusFlags flag)
        {
            bool flag2 = (flag & X509ChainStatusFlags.PartialChain) != X509ChainStatusFlags.NoError;
            bool online;

            switch (this.ChainPolicy.RevocationMode)
            {
            case X509RevocationMode.NoCheck:
                return;

            case X509RevocationMode.Online:
                online = true;
                break;

            case X509RevocationMode.Offline:
                online = false;
                break;

            default:
                throw new InvalidOperationException(Locale.GetText("Invalid revocation mode."));
            }
            bool flag3 = flag2;

            for (int i = this.elements.Count - 1; i >= 0; i--)
            {
                bool flag4 = true;
                switch (this.ChainPolicy.RevocationFlag)
                {
                case X509RevocationFlag.EndCertificateOnly:
                    flag4 = (i == 0);
                    break;

                case X509RevocationFlag.EntireChain:
                    flag4 = true;
                    break;

                case X509RevocationFlag.ExcludeRoot:
                    flag4 = (i != this.elements.Count - 1);
                    break;
                }
                X509ChainElement x509ChainElement = this.elements[i];
                if (!flag3)
                {
                    flag3 |= ((x509ChainElement.StatusFlags & X509ChainStatusFlags.NotSignatureValid) != X509ChainStatusFlags.NoError);
                }
                if (flag3)
                {
                    x509ChainElement.StatusFlags |= X509ChainStatusFlags.RevocationStatusUnknown;
                    x509ChainElement.StatusFlags |= X509ChainStatusFlags.OfflineRevocation;
                }
                else if (flag4 && !flag2 && !this.IsSelfIssued(x509ChainElement.Certificate))
                {
                    x509ChainElement.StatusFlags |= this.CheckRevocation(x509ChainElement.Certificate, i + 1, online);
                    flag3 |= ((x509ChainElement.StatusFlags & X509ChainStatusFlags.Revoked) != X509ChainStatusFlags.NoError);
                }
            }
        }
Esempio n. 6
0
        private static bool HasUnsuppressedError(X509VerificationFlags flags, X509ChainElement element, bool isEndEntity)
        {
            foreach (X509ChainStatus status in element.ChainElementStatus)
            {
                if (status.Status == X509ChainStatusFlags.NoError)
                {
                    return(false);
                }

                Debug.Assert(
                    (status.Status & (status.Status - 1)) == 0,
                    $"Only one bit should be set in status.Status ({status})");

                // The Windows certificate store API only checks the time error for a "peer trust" certificate,
                // but we don't have a concept for that in Unix.  If we did, we'd need to do that logic that here.
                // Note also that the logic is skipped if CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG is set.

                X509VerificationFlags?suppressionFlag;

                if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    if (isEndEntity)
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreEndRevocationUnknown;
                    }
                    else if (IsSelfSigned(element.Certificate))
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreRootRevocationUnknown;
                    }
                    else
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                    }
                }
                else if (status.Status == X509ChainStatusFlags.OfflineRevocation)
                {
                    // This is mainly a warning code, it's redundant to RevocationStatusUnknown
                    continue;
                }
                else
                {
                    suppressionFlag = GetSuppressionFlag(status.Status);
                }

                // If an error was found, and we do NOT have the suppression flag for it enabled,
                // we have an unsuppressed error, so return true. (If there's no suppression for a given code,
                // we (by definition) don't have that flag set.
                if (!suppressionFlag.HasValue ||
                    (flags & suppressionFlag) == 0)
                {
                    return(true);
                }
            }

            return(false);
        }
 internal unsafe X509ChainElementCollection (IntPtr pSimpleChain) {
     CAPI.CERT_SIMPLE_CHAIN simpleChain = new CAPI.CERT_SIMPLE_CHAIN(Marshal.SizeOf(typeof(CAPI.CERT_SIMPLE_CHAIN)));
     uint cbSize = (uint) Marshal.ReadInt32(pSimpleChain);
     if (cbSize > Marshal.SizeOf(simpleChain))
         cbSize = (uint) Marshal.SizeOf(simpleChain);
     X509Utils.memcpy(pSimpleChain, new IntPtr(&simpleChain), cbSize);
     m_elements = new X509ChainElement[simpleChain.cElement];
     for (int index = 0; index < m_elements.Length; index++) {
         m_elements[index] = new X509ChainElement(Marshal.ReadIntPtr(new IntPtr((long) simpleChain.rgpElement + index * Marshal.SizeOf(typeof(IntPtr)))));
     }
 }
Esempio n. 8
0
        private static void SaveIntermediateCertificates(
            X509ChainElement[] chainElements,
            HashSet<X509Certificate2> downloaded)
        {
            List<X509Certificate2> chainDownloaded = new List<X509Certificate2>(chainElements.Length);

            // It should be very unlikely that we would have downloaded something, the chain succeed,
            // and the thing we downloaded not being a part of the chain, but safer is better.
            for (int i = 0; i < chainElements.Length; i++)
            {
                X509Certificate2 elementCert = chainElements[i].Certificate;

                if (downloaded.Contains(elementCert))
                {
                    chainDownloaded.Add(elementCert);
                }
            }

            if (chainDownloaded.Count == 0)
            {
                return;
            }

            using (var userIntermediate = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
            {
                try
                {
                    userIntermediate.Open(OpenFlags.ReadWrite);
                }
                catch (CryptographicException)
                {
                    // Saving is opportunistic, just ignore failures
                    return;
                }

                foreach (X509Certificate2 cert in chainDownloaded)
                {
                    try
                    {
                        userIntermediate.Add(cert);
                    }
                    catch (CryptographicException)
                    {
                        // Saving is opportunistic, just ignore failures
                    }
                    catch (IOException)
                    {
                        // Saving is opportunistic, just ignore failures
                    }
                }
            }
        }
        private static bool HasUnsuppressedError(X509VerificationFlags flags, X509ChainElement element, bool isEndEntity)
        {
            foreach (X509ChainStatus status in element.ChainElementStatus)
            {
                if (status.Status == X509ChainStatusFlags.NoError)
                {
                    return false;
                }

                Debug.Assert(
                    (status.Status & (status.Status - 1)) == 0,
                    "Only one bit is set in status.Status");

                // The Windows certificate store API only checks the time error for a "peer trust" certificate,
                // but we don't have a concept for that in Unix.  If we did, we'd need to do that logic that here.
                // Note also that that logic is skipped if CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG is set.

                X509VerificationFlags? suppressionFlag;

                if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    if (isEndEntity)
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreEndRevocationUnknown;
                    }
                    else if (IsSelfSigned(element.Certificate))
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreRootRevocationUnknown;
                    }
                    else
                    {
                        suppressionFlag = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                    }
                }
                else
                {
                    suppressionFlag = GetSuppressionFlag(status.Status);
                }

                // If an error was found, and we do NOT have the suppression flag for it enabled,
                // we have an unsuppressed error, so return true. (If there's no suppression for a given code,
                // we (by definition) don't have that flag set.
                if (!suppressionFlag.HasValue ||
                    (flags & suppressionFlag) == 0)
                {
                    return true;
                }
            }

            return false;
        }
Esempio n. 10
0
        private void WrapUp()
        {
            X509ChainElement x509ChainElement = elements[0];
            X509Certificate2 certificate      = x509ChainElement.Certificate;

            if (IsSelfIssued(certificate))
            {
            }
            ProcessCertificateExtensions(x509ChainElement);
            for (int num = elements.Count - 1; num >= 0; num--)
            {
                elements[num].UncompressFlags();
            }
        }
 internal void AssignCertificate(X509ChainElement chainElement)
 {
     const int CERT_HEIGHT = 175;
     const int CERT_PADDING = 5;
     var numberOfCertificates = Controls.Count;
     var currentOffset = (numberOfCertificates * CERT_HEIGHT) + (CERT_PADDING * numberOfCertificates) + CERT_PADDING;
     var newCertificate = new CertificateControl();
     newCertificate.Top = currentOffset;
     newCertificate.Height = CERT_HEIGHT;
     newCertificate.Width = this.Width;
     newCertificate.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Left;
     newCertificate.SetCertificate(chainElement);
     Controls.Add(newCertificate);
 }
Esempio n. 12
0
        static bool ChainElementHasProblems(X509ChainElement chainElement, X509ChainStatusFlags problemFlags)
        {
            // If the builder finds problems with the cert, it will provide a list of "status" flags for the cert
            X509ChainStatus[] chainElementStatus = chainElement.ChainElementStatus;

            // If the list is empty or the list is null, then there were NO problems with the cert
            if (chainElementStatus.IsNullOrEmpty())
            {
                return false;
            }

            // Return true if there are any status flags we care about
            return chainElementStatus.Any(s => (s.Status & problemFlags) != 0);
        }
Esempio n. 13
0
        private void WrapUp()
        {
            X509ChainElement x509ChainElement = this.elements[0];
            X509Certificate2 certificate      = x509ChainElement.Certificate;

            if (this.IsSelfIssued(certificate))
            {
            }
            this.ProcessCertificateExtensions(x509ChainElement);
            for (int i = this.elements.Count - 1; i >= 0; i--)
            {
                this.elements[i].UncompressFlags();
            }
        }
Esempio n. 14
0
        private void PrepareForNextCertificate(int n)
        {
            X509ChainElement x509ChainElement = this.elements[n];
            X509Certificate2 certificate      = x509ChainElement.Certificate;

            this.working_issuer_name = certificate.SubjectName;
            this.working_public_key  = certificate.PublicKey.Key;
            X509BasicConstraintsExtension x509BasicConstraintsExtension = (X509BasicConstraintsExtension)certificate.Extensions["2.5.29.19"];

            if (x509BasicConstraintsExtension != null)
            {
                if (!x509BasicConstraintsExtension.CertificateAuthority)
                {
                    x509ChainElement.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                }
            }
            else if (certificate.Version >= 3)
            {
                x509ChainElement.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
            }
            if (!this.IsSelfIssued(certificate))
            {
                if (this.max_path_length > 0)
                {
                    this.max_path_length--;
                }
                else if (this.bce_restriction != null)
                {
                    this.bce_restriction.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                }
            }
            if (x509BasicConstraintsExtension != null && x509BasicConstraintsExtension.HasPathLengthConstraint && x509BasicConstraintsExtension.PathLengthConstraint < this.max_path_length)
            {
                this.max_path_length = x509BasicConstraintsExtension.PathLengthConstraint;
                this.bce_restriction = x509ChainElement;
            }
            X509KeyUsageExtension x509KeyUsageExtension = (X509KeyUsageExtension)certificate.Extensions["2.5.29.15"];

            if (x509KeyUsageExtension != null)
            {
                X509KeyUsageFlags x509KeyUsageFlags = X509KeyUsageFlags.KeyCertSign;
                if ((x509KeyUsageExtension.KeyUsages & x509KeyUsageFlags) != x509KeyUsageFlags)
                {
                    x509ChainElement.StatusFlags |= X509ChainStatusFlags.NotValidForUsage;
                }
            }
            this.ProcessCertificateExtensions(x509ChainElement);
        }
Esempio n. 15
0
        internal unsafe X509ChainElementCollection(IntPtr pSimpleChain)
        {
            CAPI.CERT_SIMPLE_CHAIN simpleChain = new CAPI.CERT_SIMPLE_CHAIN(Marshal.SizeOf(typeof(CAPI.CERT_SIMPLE_CHAIN)));
            uint cbSize = (uint)Marshal.ReadInt32(pSimpleChain);

            if (cbSize > Marshal.SizeOf(simpleChain))
            {
                cbSize = (uint)Marshal.SizeOf(simpleChain);
            }
            X509Utils.memcpy(pSimpleChain, new IntPtr(&simpleChain), cbSize);
            m_elements = new X509ChainElement[simpleChain.cElement];
            for (int index = 0; index < m_elements.Length; index++)
            {
                m_elements[index] = new X509ChainElement(Marshal.ReadIntPtr(new IntPtr((long)simpleChain.rgpElement + index * Marshal.SizeOf(typeof(IntPtr)))));
            }
        }
Esempio n. 16
0
        private void ProcessCertificateExtensions(X509ChainElement element)
        {
            X509ExtensionEnumerator enumerator = element.Certificate.Extensions.GetEnumerator();

            while (enumerator.MoveNext())
            {
                X509Extension current = enumerator.Current;
                if (current.Critical)
                {
                    switch (current.Oid.Value)
                    {
                    case "2.5.29.15":
                    case "2.5.29.19":
                        continue;
                    }
                    element.StatusFlags |= X509ChainStatusFlags.InvalidExtension;
                }
            }
        }
        private void ProcessCertificateExtensions(X509ChainElement element)
        {
            foreach (X509Extension ext in element.Certificate.Extensions)
            {
                if (ext.Critical)
                {
                    switch (ext.Oid.Value)
                    {
                    case "2.5.29.15": // X509KeyUsageExtension
                    case "2.5.29.19": // X509BasicConstraintsExtension
                        // we processed this extension
                        break;

                    default:
                        // note: Under Windows XP MS implementation seems to ignore
                        // certificate with unknown critical extensions.
                        element.StatusFlags |= X509ChainStatusFlags.InvalidExtension;
                        break;
                    }
                }
            }
        }
Esempio n. 18
0
        private X509ChainStatusFlags CheckRevocation(X509Certificate2 certificate, int ca, bool online)
        {
            X509ChainStatusFlags x509ChainStatusFlags = X509ChainStatusFlags.RevocationStatusUnknown;
            X509ChainElement     x509ChainElement     = this.elements[ca];
            X509Certificate2     certificate2         = x509ChainElement.Certificate;

            while (this.IsSelfIssued(certificate2) && ca < this.elements.Count - 1)
            {
                x509ChainStatusFlags = this.CheckRevocation(certificate, certificate2, online);
                if (x509ChainStatusFlags != X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    break;
                }
                ca++;
                x509ChainElement = this.elements[ca];
                certificate2     = x509ChainElement.Certificate;
            }
            if (x509ChainStatusFlags == X509ChainStatusFlags.RevocationStatusUnknown)
            {
                x509ChainStatusFlags = this.CheckRevocation(certificate, certificate2, online);
            }
            return(x509ChainStatusFlags);
        }
 public static CertificateErrors GetCertificateErrors(X509ChainElement chainElement)
 {
     //If the length is not zero and the items aren't "OK", return critical.
     if (chainElement.ChainElementStatus.Length != 0 && !chainElement.ChainElementStatus.All(s => s.Status == X509ChainStatusFlags.NoError))
     {
         return CertificateErrors.Critical;
     }
     //Recheck with revocation
     var chain = new X509Chain();
     chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
     chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
     chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags & ~X509VerificationFlags.IgnoreEndRevocationUnknown;
     var builtChain = chain.Build(chainElement.Certificate);
     if (chain.ChainStatus.Any(s => s.Status == X509ChainStatusFlags.RevocationStatusUnknown))
     {
         return CertificateErrors.UnknownRevocation;
     }
     if (!builtChain)
     {
         return CertificateErrors.Critical;
     }
     return CertificateErrors.None;
 }
Esempio n. 20
0
 public override void Reset()
 {
     // note: this call doesn't Reset the X509ChainPolicy
     if ((status != null) && (status.Length != 0))
     {
         status = null;
     }
     if (elements.Count > 0)
     {
         elements.Clear();
     }
     if (user_root_store != null)
     {
         user_root_store.Close();
         user_root_store = null;
     }
     if (root_store != null)
     {
         root_store.Close();
         root_store = null;
     }
     if (user_ca_store != null)
     {
         user_ca_store.Close();
         user_ca_store = null;
     }
     if (ca_store != null)
     {
         ca_store.Close();
         ca_store = null;
     }
     roots              = null;
     cas                = null;
     collection         = null;
     bce_restriction    = null;
     working_public_key = null;
 }
Esempio n. 21
0
 private void ProcessCertificateExtensions(X509ChainElement element)
 {
     foreach (X509Extension x509Extension in element.Certificate.Extensions)
     {
         if (x509Extension.Critical)
         {
             string value = x509Extension.Oid.Value;
             if (value != null)
             {
                 if (X509Chain.< > f__switch$mapB == null)
                 {
                     X509Chain.< > f__switch$mapB = new Dictionary <string, int>(2)
                     {
                         {
                             "2.5.29.15",
                             0
                         },
                         {
                             "2.5.29.19",
                             0
                         }
                     };
                 }
                 int num;
                 if (X509Chain.< > f__switch$mapB.TryGetValue(value, out num))
                 {
                     if (num == 0)
                     {
                         continue;
                     }
                 }
             }
             element.StatusFlags |= X509ChainStatusFlags.InvalidExtension;
         }
     }
 }
Esempio n. 22
0
 /// <summary>Clears the current <see cref="T:System.Security.Cryptography.X509Certificates.X509Chain" /> object.</summary>
 public void Reset()
 {
     if (this.status != null && this.status.Length != 0)
     {
         this.status = null;
     }
     if (this.elements.Count > 0)
     {
         this.elements.Clear();
     }
     if (this.roots != null)
     {
         this.roots.Close();
         this.roots = null;
     }
     if (this.cas != null)
     {
         this.cas.Close();
         this.cas = null;
     }
     this.collection         = null;
     this.bce_restriction    = null;
     this.working_public_key = null;
 }
Esempio n. 23
0
 /// <summary>Clears the current <see cref="T:System.Security.Cryptography.X509Certificates.X509Chain" /> object.</summary>
 public void Reset()
 {
     if (status != null && status.Length != 0)
     {
         status = null;
     }
     if (elements.Count > 0)
     {
         elements.Clear();
     }
     if (roots != null)
     {
         roots.Close();
         roots = null;
     }
     if (cas != null)
     {
         cas.Close();
         cas = null;
     }
     collection         = null;
     bce_restriction    = null;
     working_public_key = null;
 }
Esempio n. 24
0
 void NotifyProblem(X509ChainElement chainElement)
 {
     if (this.Problem != null)
     {
         try
         {
             this.Problem(chainElement);
         }
         catch
         {
         }
     }
 }
Esempio n. 25
0
 public void CopyTo(X509ChainElement[] array, int index)
 {
     ((ICollection)this).CopyTo(array, index);
 }
Esempio n. 26
0
 internal X509ChainElementCollection(X509ChainElement[] chainElements)
 {
     Debug.Assert(chainElements != null, "chainElements != null");
     _elements = chainElements;
 }
Esempio n. 27
0
 internal void OnCertificateProblem(X509ChainElement chainElement)
 {
     if (chainElement != null)
     {
         Logger.Error("Chain Element has problem {0}", this.Summarize(chainElement));
     }
 }
        public static IChainPal BuildChain(
            X509Certificate2 leaf,
            HashSet<X509Certificate2> candidates,
            HashSet<X509Certificate2> downloaded,
            HashSet<X509Certificate2> systemTrusted,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            ref TimeSpan remainingDownloadTime)
        {
            X509ChainElement[] elements;
            List<X509ChainStatus> overallStatus = new List<X509ChainStatus>();
            WorkingChain workingChain = new WorkingChain();
            Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback;

            // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to
            // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes.
            //
            // (If you need to think of it as an X509Store, it's a volatile memory store)
            using (SafeX509StoreHandle store = Interop.Crypto.X509StoreCreate())
            using (SafeX509StoreCtxHandle storeCtx = Interop.Crypto.X509StoreCtxCreate())
            {
                Interop.Crypto.CheckValidOpenSslHandle(store);
                Interop.Crypto.CheckValidOpenSslHandle(storeCtx);

                bool lookupCrl = revocationMode != X509RevocationMode.NoCheck;

                foreach (X509Certificate2 cert in candidates)
                {
                    OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal;

                    if (!Interop.Crypto.X509StoreAddCert(store, pal.SafeHandle))
                    {
                        throw Interop.Crypto.CreateOpenSslCryptographicException();
                    }

                    if (lookupCrl)
                    {
                        CrlCache.AddCrlForCertificate(
                            cert,
                            store,
                            revocationMode,
                            verificationTime,
                            ref remainingDownloadTime);

                        // If we only wanted the end-entity certificate CRL then don't look up
                        // any more of them.
                        lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly;
                    }
                }

                if (revocationMode != X509RevocationMode.NoCheck)
                {
                    if (!Interop.Crypto.X509StoreSetRevocationFlag(store, revocationFlag))
                    {
                        throw Interop.Crypto.CreateOpenSslCryptographicException();
                    }
                }

                SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle;

                if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle))
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                Interop.Crypto.X509StoreCtxSetVerifyCallback(storeCtx, workingCallback);
                Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime);

                int verify = Interop.Crypto.X509VerifyCert(storeCtx);

                if (verify < 0)
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the
                // chain is just fine (unless it returned a negative code for an exception)
                Debug.Assert(verify == 1, "verify == 1");

                using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(storeCtx))
                {
                    int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack);
                    elements = new X509ChainElement[chainSize];
                    int maybeRootDepth = chainSize - 1;

                    // The leaf cert is 0, up to (maybe) the root at chainSize - 1
                    for (int i = 0; i < chainSize; i++)
                    {
                        List<X509ChainStatus> status = new List<X509ChainStatus>();

                        List<Interop.Crypto.X509VerifyStatusCode> elementErrors =
                            i < workingChain.Errors.Count ? workingChain.Errors[i] : null;

                        if (elementErrors != null)
                        {
                            AddElementStatus(elementErrors, status, overallStatus);
                        }

                        IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                        if (elementCertPtr == IntPtr.Zero)
                        {
                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                        }

                        // Duplicate the certificate handle
                        X509Certificate2 elementCert = new X509Certificate2(elementCertPtr);

                        // If the last cert is self signed then it's the root cert, do any extra checks.
                        if (i == maybeRootDepth && IsSelfSigned(elementCert))
                        {
                            // If the root certificate was downloaded or the system
                            // doesn't trust it, it's untrusted.
                            if (downloaded.Contains(elementCert) ||
                                !systemTrusted.Contains(elementCert))
                            {
                                AddElementStatus(
                                    Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED,
                                    status,
                                    overallStatus);
                            }
                        }

                        elements[i] = new X509ChainElement(elementCert, status.ToArray(), "");
                    }
                }
            }

            GC.KeepAlive(workingCallback);

            if ((certificatePolicy != null && certificatePolicy.Count > 0) ||
                (applicationPolicy != null && applicationPolicy.Count > 0))
            {
                List<X509Certificate2> certsToRead = new List<X509Certificate2>();

                foreach (X509ChainElement element in elements)
                {
                    certsToRead.Add(element.Certificate);
                }

                CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead);

                bool failsPolicyChecks = false;

                if (certificatePolicy != null)
                {
                    if (!policyChain.MatchesCertificatePolicies(certificatePolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (applicationPolicy != null)
                {
                    if (!policyChain.MatchesApplicationPolicies(applicationPolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (failsPolicyChecks)
                {
                    X509ChainElement leafElement = elements[0];

                    X509ChainStatus chainStatus = new X509ChainStatus
                    {
                        Status = X509ChainStatusFlags.NotValidForUsage,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };

                    var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1);
                    elementStatus.AddRange(leafElement.ChainElementStatus);

                    AddUniqueStatus(elementStatus, ref chainStatus);
                    AddUniqueStatus(overallStatus, ref chainStatus);

                    elements[0] = new X509ChainElement(
                        leafElement.Certificate,
                        elementStatus.ToArray(),
                        leafElement.Information);
                }
            }

            return new OpenSslX509ChainProcessor
            {
                ChainStatus = overallStatus.ToArray(),
                ChainElements = elements,
            };
        }
Esempio n. 29
0
 private CertificateModel AssignCertificate(X509ChainElement chainElement, bool reportOnly, PublicPinnedKeys pinnedKey, X509Chain chain, int index)
 {
     var certificate = chainElement.Certificate;
     var algorithmBits = BitStrengthCalculator.CalculateStrength(certificate);
     var dn = DistinguishedNameParser.Parse(certificate.Subject);
     return new CertificateModel
     {
         CommonName = dn.ContainsKey("cn") ? dn["cn"].FirstOrDefault() ?? certificate.Thumbprint : certificate.Thumbprint,
         Thumbprint = certificate.Thumbprint,
         DistinguishedName = dn,
         SubjectAlternativeName = certificate.Extensions[KnownOids.X509Extensions.SubjectAltNameExtension]?.Format(false) ?? "None",
         PublicKey = new PublicKeyModel
         {
             Algorithm = algorithmBits.AlgorithmName,
             KeySizeBits = algorithmBits.BitSize,
             PublicKey = certificate.PublicKey.EncodedKeyValue.RawData
         },
         BeginDate = certificate.NotBefore,
         EndDate = certificate.NotAfter,
         SerialNumber = certificate.SerialNumber ?? "None",
         SignatureAlgorithm = new SignatureAlgorithmModel
         {
             SignatureAlgorithm = certificate.SignatureAlgorithm,
             IsTrustedRoot = _rootStore.Certificates.Contains(certificate) || _userStore.Certificates.Contains(certificate)
         },
         CertificateType = index == 0 ? GetCertificateType(certificate, chain) : CertificateType.None,
         CertificateCtModel = new AsyncProperty<CertificateCtModel>(Task.Factory.StartNew(() => GetCtModel(certificate))),
         Errors = new AsyncProperty<CertificateErrors>(Task.Factory.StartNew(() => CertificateErrorsCalculator.GetCertificateErrors(chainElement))),
         SpkiHashes = new AsyncProperty<SpkiHashesModel>(Task.Factory.StartNew(() => CalculateHashes(chainElement.Certificate, reportOnly, pinnedKey))),
         InstallCommand = new RelayCommand(parameter => CertificateUI.ShowImportCertificate(chainElement.Certificate, FiddlerApplication.UI)),
         ViewCommand = new RelayCommand(parameter => CertificateUI.ShowCertificate(chainElement.Certificate, FiddlerApplication.UI)),
         BrowseCommand = new RelayCommand(parameter =>
         {
             var uri = parameter as Uri;
             if (uri?.Scheme == Uri.UriSchemeHttps)
             {
                 Process.Start(uri.AbsoluteUri);
             }
         })
     };
 }
Esempio n. 30
0
        private CertificateModel AssignCertificate(X509ChainElement chainElement, bool reportOnly, PublicPinnedKeys pinnedKey)
        {
            var certificate = chainElement.Certificate;

            var algorithmBits = BitStrengthCalculator.CalculateStrength(certificate);
            var dn = DistinguishedNameParser.Parse(certificate.Subject);
            return new CertificateModel
            {
                CommonName = dn.ContainsKey("cn") ? dn["cn"].FirstOrDefault() ?? certificate.Thumbprint : certificate.Thumbprint,
                Thumbprint = certificate.Thumbprint,
                SubjectAlternativeName = certificate.Extensions[KnownOids.X509Extensions.SubjectAltNameExtension]?.Format(false) ?? "None",
                PublicKey = new PublicKeyModel
                {
                    Algorithm = algorithmBits.AlgorithmName,
                    KeySizeBits = algorithmBits.BitSize,
                    PublicKey = certificate.PublicKey.EncodedKeyValue.RawData
                },
                BeginDate = certificate.NotBefore,
                EndDate = certificate.NotAfter,
                SignatureAlgorithm = new SignatureAlgorithmModel
                {
                    SignatureAlgorithm = certificate.SignatureAlgorithm,
                    IsTrustedRoot = _rootStore.Certificates.Contains(certificate) || _userStore.Certificates.Contains(certificate)
                },
                Errors = new AsyncProperty<CertificateErrors>(Task.Factory.StartNew(() => CertificateErrorsCalculator.GetCertificateErrors(chainElement))),
                SpkiHashes = new AsyncProperty<SpkiHashesModel>(Task.Factory.StartNew(() => CalculateHashes(chainElement.Certificate, reportOnly, pinnedKey))),
                InstallCommand = new RelayCommand(parameter => CertificateUI.ShowImportCertificate(chainElement.Certificate)),
                ViewCommand = new RelayCommand(parameter => CertificateUI.ShowCertificate(chainElement.Certificate))
            };
        }
        // we check the revocation only once we have built the complete chain
        private void CheckRevocationOnChain(X509ChainStatusFlags flag)
        {
            bool partial = ((flag & X509ChainStatusFlags.PartialChain) != 0);
            bool online;

            switch (ChainPolicy.RevocationMode)
            {
            case X509RevocationMode.Online:
                // default
                online = true;
                break;

            case X509RevocationMode.Offline:
                online = false;
                break;

            case X509RevocationMode.NoCheck:
                return;

            default:
                throw new InvalidOperationException(Locale.GetText("Invalid revocation mode."));
            }

            bool unknown = partial;

            // from the root down to the end-entity
            for (int i = elements.Count - 1; i >= 0; i--)
            {
                bool check = true;

                switch (ChainPolicy.RevocationFlag)
                {
                case X509RevocationFlag.EndCertificateOnly:
                    check = (i == 0);
                    break;

                case X509RevocationFlag.EntireChain:
                    check = true;
                    break;

                case X509RevocationFlag.ExcludeRoot:
                    // default
                    check = (i != (elements.Count - 1));
                    // anyway, who's gonna sign that the root is invalid ?
                    break;
                }

                X509ChainElement element = elements [i];

                // we can't assume the revocation status if the certificate is bad (e.g. invalid signature)
                if (!unknown)
                {
                    unknown |= ((element.StatusFlags & X509ChainStatusFlags.NotSignatureValid) != 0);
                }

                if (unknown)
                {
                    // we can skip the revocation checks as we can't be sure of them anyway
                    element.StatusFlags |= X509ChainStatusFlags.RevocationStatusUnknown;
                    element.StatusFlags |= X509ChainStatusFlags.OfflineRevocation;
                }
                else if (check && !partial && !IsSelfIssued(element.Certificate))
                {
                    // check for revocation (except for the trusted root and self-issued certs)
                    element.StatusFlags |= CheckRevocation(element.Certificate, i + 1, online);
                    // if revoked, then all others following in the chain are unknown...
                    unknown |= ((element.StatusFlags & X509ChainStatusFlags.Revoked) != 0);
                }
            }
        }
Esempio n. 32
0
 internal string Summarize(X509ChainElement chainElement)
 {
     X509ChainStatusFlags problemFlags = m_agent.SecurityAgent.TrustModel.CertChainValidator.ProblemFlags;
     
     StringBuilder builder = new StringBuilder();
     builder.Append(chainElement.Certificate.ExtractEmailNameOrName());
     builder.Append(";");
     foreach(X509ChainStatus status in chainElement.ChainElementStatus)
     {
         if ((status.Status & problemFlags) != 0)
         {
             builder.Append(status.Status);
         }
     }
     
     return builder.ToString();
 }
Esempio n. 33
0
        public static IChainPal BuildChain(
            X509Certificate2 leaf,
            List<X509Certificate2> candidates,
            List<X509Certificate2> downloaded,
            List<X509Certificate2> systemTrusted,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            ref TimeSpan remainingDownloadTime)
        {
            X509ChainElement[] elements;
            List<X509ChainStatus> overallStatus = new List<X509ChainStatus>();

            // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to
            // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes.
            //
            // (If you need to think of it as an X509Store, it's a volatile memory store)
            using (SafeX509StoreHandle store = Interop.libcrypto.X509_STORE_new())
            using (SafeX509StoreCtxHandle storeCtx = Interop.libcrypto.X509_STORE_CTX_new())
            {
                Interop.libcrypto.CheckValidOpenSslHandle(store);
                Interop.libcrypto.CheckValidOpenSslHandle(storeCtx);

                bool lookupCrl = revocationMode != X509RevocationMode.NoCheck;

                foreach (X509Certificate2 cert in candidates)
                {
                    OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal;

                    if (!Interop.libcrypto.X509_STORE_add_cert(store, pal.SafeHandle))
                    {
                        throw Interop.libcrypto.CreateOpenSslCryptographicException();
                    }

                    if (lookupCrl)
                    {
                        CrlCache.AddCrlForCertificate(
                            cert,
                            store,
                            revocationMode,
                            verificationTime,
                            ref remainingDownloadTime);

                        // If we only wanted the end-entity certificate CRL then don't look up
                        // any more of them.
                        lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly;
                    }
                }

                if (revocationMode != X509RevocationMode.NoCheck)
                {
                    Interop.libcrypto.X509VerifyFlags vfyFlags = Interop.libcrypto.X509VerifyFlags.X509_V_FLAG_CRL_CHECK;

                    if (revocationFlag != X509RevocationFlag.EndCertificateOnly)
                    {
                        vfyFlags |= Interop.libcrypto.X509VerifyFlags.X509_V_FLAG_CRL_CHECK_ALL;
                    }

                    if (!Interop.libcrypto.X509_STORE_set_flags(store, vfyFlags))
                    {
                        throw Interop.libcrypto.CreateOpenSslCryptographicException();
                    }
                }

                // When CRL checking support is added, it should be done before the call to
                // X509_STORE_CTX_init (aka here) by calling X509_STORE_set_flags(store, flags);

                SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle;

                if (!Interop.libcrypto.X509_STORE_CTX_init(storeCtx, store, leafHandle, IntPtr.Zero))
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime);

                int verify = Interop.libcrypto.X509_verify_cert(storeCtx);

                if (verify < 0)
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                using (SafeX509StackHandle chainStack = Interop.libcrypto.X509_STORE_CTX_get1_chain(storeCtx))
                {
                    int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack);
                    int errorDepth = -1;
                    Interop.libcrypto.X509VerifyStatusCode errorCode = 0;

                    if (verify == 0)
                    {
                        errorCode = Interop.libcrypto.X509_STORE_CTX_get_error(storeCtx);
                        errorDepth = Interop.libcrypto.X509_STORE_CTX_get_error_depth(storeCtx);
                    }

                    elements = new X509ChainElement[chainSize];
                    int maybeRootDepth = chainSize - 1;

                    // The leaf cert is 0, up to (maybe) the root at chainSize - 1
                    for (int i = 0; i < chainSize; i++)
                    {
                        List<X509ChainStatus> status = new List<X509ChainStatus>();

                        if (i == errorDepth)
                        {
                            AddElementStatus(errorCode, status, overallStatus);
                        }

                        IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                        if (elementCertPtr == IntPtr.Zero)
                        {
                            throw Interop.libcrypto.CreateOpenSslCryptographicException();
                        }

                        // Duplicate the certificate handle
                        X509Certificate2 elementCert = new X509Certificate2(elementCertPtr);

                        // If the last cert is self signed then it's the root cert, do any extra checks.
                        if (i == maybeRootDepth && IsSelfSigned(elementCert))
                        {
                            // If the root certificate was downloaded or the system
                            // doesn't trust it, it's untrusted.
                            if (downloaded.Contains(elementCert) ||
                                !systemTrusted.Contains(elementCert))
                            {
                                AddElementStatus(
                                    Interop.libcrypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED,
                                    status,
                                    overallStatus);
                            }
                        }

                        elements[i] = new X509ChainElement(elementCert, status.ToArray(), "");
                    }
                }
            }

            if ((certificatePolicy != null && certificatePolicy.Count > 0) ||
                (applicationPolicy != null && applicationPolicy.Count > 0))
            {
                List<X509Certificate2> certsToRead = new List<X509Certificate2>();

                foreach (X509ChainElement element in elements)
                {
                    certsToRead.Add(element.Certificate);
                }

                CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead);

                bool failsPolicyChecks = false;

                if (certificatePolicy != null)
                {
                    if (!policyChain.MatchesCertificatePolicies(certificatePolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (applicationPolicy != null)
                {
                    if (!policyChain.MatchesApplicationPolicies(applicationPolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (failsPolicyChecks)
                {
                    X509ChainElement leafElement = elements[0];

                    X509ChainStatus chainStatus = new X509ChainStatus
                    {
                        Status = X509ChainStatusFlags.InvalidPolicyConstraints,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };

                    var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1);
                    elementStatus.AddRange(leafElement.ChainElementStatus);

                    AddUniqueStatus(elementStatus, ref chainStatus);
                    AddUniqueStatus(overallStatus, ref chainStatus);

                    elements[0] = new X509ChainElement(
                        leafElement.Certificate,
                        elementStatus.ToArray(),
                        leafElement.Information);
                }
            }

            return new OpenSslX509ChainProcessor
            {
                ChainStatus = overallStatus.ToArray(),
                ChainElements = elements,
            };
        }
 /// <summary>
 /// Wraps the X509ChainElement creation method.
 /// </summary>
 /// <param name="element">
 /// The X.509v3 chain element.
 /// </param>
 /// <returns>
 /// The <see cref="IX509ChainElement"/>.
 /// </returns>
 public IX509ChainElement Create(X509ChainElement element)
 {
     return new X509ChainElementWrap(new X509CertificateWrap(this.file, this.path, element.Certificate), element.ChainElementStatus);
 }
		// methods

		public void CopyTo (X509ChainElement[] array, int index) 
		{
			_list.CopyTo ((Array)array, index);
		}
        private void Process(int n)
        {
            X509ChainElement element     = elements [n];
            X509Certificate2 certificate = element.Certificate;

            // pre-step: DSA certificates may inherit the parameters of their CA
            if ((n != elements.Count - 1) && (certificate.MonoCertificate.KeyAlgorithm == "1.2.840.10040.4.1"))
            {
                if (certificate.MonoCertificate.KeyAlgorithmParameters == null)
                {
                    X509Certificate2 parent = elements [n + 1].Certificate;
                    certificate.MonoCertificate.KeyAlgorithmParameters = parent.MonoCertificate.KeyAlgorithmParameters;
                }
            }

            bool root = (working_public_key == null);

            // 6.1.3.a.1 - check signature (with special case to deal with root certificates)
            if (!IsSignedWith(certificate, root ? certificate.PublicKey.Key : working_public_key))
            {
                // another special case where only an end-entity is available and can't be verified.
                // In this case we do not report an invalid signature (since this is unknown)
                if (root || (n != elements.Count - 1) || IsSelfIssued(certificate))
                {
                    element.StatusFlags |= X509ChainStatusFlags.NotSignatureValid;
                }
            }

            // 6.1.3.a.2 - check validity period
            if ((ChainPolicy.VerificationTime < certificate.NotBefore) ||
                (ChainPolicy.VerificationTime > certificate.NotAfter))
            {
                element.StatusFlags |= X509ChainStatusFlags.NotTimeValid;
            }
            // TODO - for X509ChainStatusFlags.NotTimeNested (needs global structure)

            // note: most of them don't apply to the root certificate
            if (root)
            {
                return;
            }

            // 6.1.3.a.3 - revocation check (we're doing at the last stage)
            // note: you revoke a trusted root by removing it from your trusted store (i.e. no CRL can do this job)

            // 6.1.3.a.4 - check certificate issuer name
            if (!X500DistinguishedName.AreEqual(certificate.IssuerName, working_issuer_name))
            {
                // NOTE: this is not the "right" error flag, but it's the closest one defined
                element.StatusFlags |= X509ChainStatusFlags.InvalidNameConstraints;
            }

            if (!IsSelfIssued(certificate) && (n != 0))
            {
                // TODO 6.1.3.b - subject name in the permitted_subtrees ...
                // TODO 6.1.3.c - subject name not within excluded_subtrees...

                // TODO - check for X509ChainStatusFlags.InvalidNameConstraint
                // TODO - check for X509ChainStatusFlags.HasNotSupportedNameConstraint
                // TODO - check for X509ChainStatusFlags.HasNotPermittedNameConstraint
                // TODO - check for X509ChainStatusFlags.HasExcludedNameConstraint
            }

            // TODO 6.1.3.d - check if certificate policies extension is present
            //if (false) {
            // TODO - for X509ChainStatusFlags.InvalidPolicyConstraints
            //	using X509ChainPolicy.ApplicationPolicy and X509ChainPolicy.CertificatePolicy

            // TODO - check for X509ChainStatusFlags.NoIssuanceChainPolicy

            //} else {
            // TODO 6.1.3.e - set valid_policy_tree to NULL
            //}

            // TODO 6.1.3.f - verify explict_policy > 0 if valid_policy_tree != NULL
        }
        public static IChainPal BuildChain(
            X509Certificate2 leaf,
            X509Certificate2Collection candidates,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            DateTime verificationTime)
        {
            X509ChainElement[] elements;
            List<X509ChainStatus> overallStatus = new List<X509ChainStatus>();

            // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to
            // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes.
            //
            // (If you need to think of it as an X509Store, it's a volatile memory store)
            using (SafeX509StoreHandle store = Interop.libcrypto.X509_STORE_new())
            using (SafeX509StoreCtxHandle storeCtx = Interop.libcrypto.X509_STORE_CTX_new())
            {
                Interop.libcrypto.CheckValidOpenSslHandle(store);
                Interop.libcrypto.CheckValidOpenSslHandle(storeCtx);

                foreach (X509Certificate2 cert in candidates)
                {
                    OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal;

                    if (!Interop.libcrypto.X509_STORE_add_cert(store, pal.SafeHandle))
                    {
                        throw Interop.libcrypto.CreateOpenSslCryptographicException();
                    }
                }

                // When CRL checking support is added, it should be done before the call to
                // X509_STORE_CTX_init (aka here) by calling X509_STORE_set_flags(store, flags);

                SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle;

                if (!Interop.libcrypto.X509_STORE_CTX_init(storeCtx, store, leafHandle, IntPtr.Zero))
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime);

                int verify = Interop.libcrypto.X509_verify_cert(storeCtx);

                if (verify < 0)
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                using (SafeX509StackHandle chainStack = Interop.libcrypto.X509_STORE_CTX_get1_chain(storeCtx))
                {
                    int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack);
                    int errorDepth = -1;
                    Interop.libcrypto.X509VerifyStatusCode errorCode = 0;
                    string errorMsg = null;

                    if (verify == 0)
                    {
                        errorCode = Interop.libcrypto.X509_STORE_CTX_get_error(storeCtx);
                        errorDepth = Interop.libcrypto.X509_STORE_CTX_get_error_depth(storeCtx);
                        errorMsg = Interop.libcrypto.X509_verify_cert_error_string(errorCode);
                    }

                    elements = new X509ChainElement[chainSize];

                    for (int i = 0; i < chainSize; i++)
                    {
                        List<X509ChainStatus> status = new List<X509ChainStatus>();

                        if (i == errorDepth)
                        {
                            X509ChainStatus chainStatus = new X509ChainStatus
                            {
                                Status = MapVerifyErrorToChainStatus(errorCode),
                                StatusInformation = errorMsg,
                            };

                            status.Add(chainStatus);
                            AddUniqueStatus(overallStatus, ref chainStatus);
                        }

                        IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                        if (elementCertPtr == IntPtr.Zero)
                        {
                            throw Interop.libcrypto.CreateOpenSslCryptographicException();
                        }

                        // Duplicate the certificate handle
                        X509Certificate2 elementCert = new X509Certificate2(elementCertPtr);

                        elements[i] = new X509ChainElement(elementCert, status.ToArray(), "");
                    }
                }
            }

            if ((certificatePolicy != null && certificatePolicy.Count > 0) ||
                (applicationPolicy != null && applicationPolicy.Count > 0))
            {
                X509Certificate2Collection certsToRead = new X509Certificate2Collection();

                foreach (X509ChainElement element in elements)
                {
                    certsToRead.Add(element.Certificate);
                }

                CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead);

                bool failsPolicyChecks = false;

                if (certificatePolicy != null)
                {
                    if (!policyChain.MatchesCertificatePolicies(certificatePolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (applicationPolicy != null)
                {
                    if (!policyChain.MatchesApplicationPolicies(applicationPolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (failsPolicyChecks)
                {
                    X509ChainElement leafElement = elements[0];

                    X509ChainStatus chainStatus = new X509ChainStatus
                    {
                        Status = X509ChainStatusFlags.InvalidPolicyConstraints,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };

                    var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1);
                    elementStatus.AddRange(leafElement.ChainElementStatus);

                    AddUniqueStatus(elementStatus, ref chainStatus);
                    AddUniqueStatus(overallStatus, ref chainStatus);

                    elements[0] = new X509ChainElement(
                        leafElement.Certificate,
                        elementStatus.ToArray(),
                        leafElement.Information);
                }
            }

            return new OpenSslX509ChainProcessor
            {
                ChainStatus = overallStatus.ToArray(),
                ChainElements = elements,
            };
        }
        // CTL == Certificate Trust List / NOT SUPPORTED
        // TODO - check for X509ChainStatusFlags.CtlNotTimeValid
        // TODO - check for X509ChainStatusFlags.CtlNotSignatureValid
        // TODO - check for X509ChainStatusFlags.CtlNotValidForUsage

        private void PrepareForNextCertificate(int n)
        {
            X509ChainElement element     = elements [n];
            X509Certificate2 certificate = element.Certificate;

            // TODO 6.1.4.a-b

            // 6.1.4.c
            working_issuer_name = certificate.SubjectName;
            // 6.1.4.d-e - our key includes both the public key and it's parameters
            working_public_key = certificate.PublicKey.Key;
            // 6.1.4.f
//			working_public_key_algorithm = certificate.PublicKey.Oid.Value;

            // TODO 6.1.4.g-j

            // 6.1.4.k - Verify that the certificate is a CA certificate
            X509BasicConstraintsExtension bce = (certificate.Extensions["2.5.29.19"] as X509BasicConstraintsExtension);

            if (bce != null)
            {
                if (!bce.CertificateAuthority)
                {
                    element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                }
            }
            else if (certificate.Version >= 3)
            {
                // recent (v3+) CA certificates must include BCE
                element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
            }

            // 6.1.4.l - if the certificate isn't self-issued...
            if (!IsSelfIssued(certificate))
            {
                // ... verify that max_path_length > 0
                if (max_path_length > 0)
                {
                    max_path_length--;
                }
                else
                {
                    // to match MS the reported status must be against the certificate
                    // with the BCE and not where the path is too long. It also means
                    // that this condition has to be reported only once
                    if (bce_restriction != null)
                    {
                        bce_restriction.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                    }
                }
            }

            // 6.1.4.m - if pathLengthConstraint is present...
            if ((bce != null) && (bce.HasPathLengthConstraint))
            {
                // ... and is less that max_path_length, set max_path_length to it's value
                if (bce.PathLengthConstraint < max_path_length)
                {
                    max_path_length = bce.PathLengthConstraint;
                    bce_restriction = element;
                }
            }

            // 6.1.4.n - if key usage extension is present...
            X509KeyUsageExtension kue = (certificate.Extensions["2.5.29.15"] as X509KeyUsageExtension);

            if (kue != null)
            {
                // ... verify keyCertSign is set
                X509KeyUsageFlags success = X509KeyUsageFlags.KeyCertSign;
                if ((kue.KeyUsages & success) != success)
                {
                    element.StatusFlags |= X509ChainStatusFlags.NotValidForUsage;
                }
            }

            // 6.1.4.o - recognize and process other critical extension present in the certificate
            ProcessCertificateExtensions(element);
        }
Esempio n. 39
0
		// CTL == Certificate Trust List / NOT SUPPORTED
		// TODO - check for X509ChainStatusFlags.CtlNotTimeValid
		// TODO - check for X509ChainStatusFlags.CtlNotSignatureValid
		// TODO - check for X509ChainStatusFlags.CtlNotValidForUsage

		private void PrepareForNextCertificate (int n) 
		{
			X509ChainElement element = elements [n];
			X509Certificate2 certificate = element.Certificate;

			// TODO 6.1.4.a-b

			// 6.1.4.c
			working_issuer_name = certificate.SubjectName;
			// 6.1.4.d-e - our key includes both the public key and it's parameters
			working_public_key = certificate.PublicKey.Key;
			// 6.1.4.f
//			working_public_key_algorithm = certificate.PublicKey.Oid.Value;

			// TODO 6.1.4.g-j

			// 6.1.4.k - Verify that the certificate is a CA certificate
			X509BasicConstraintsExtension bce = (certificate.Extensions["2.5.29.19"] as X509BasicConstraintsExtension);
			if (bce != null) {
				if (!bce.CertificateAuthority) {
					element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
				}
			} else if (certificate.Version >= 3) {
				// recent (v3+) CA certificates must include BCE
				element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
			}

			// 6.1.4.l - if the certificate isn't self-issued...
			if (!IsSelfIssued (certificate)) {
				// ... verify that max_path_length > 0
				if (max_path_length > 0) {
					max_path_length--;
				} else {
					// to match MS the reported status must be against the certificate 
					// with the BCE and not where the path is too long. It also means
					// that this condition has to be reported only once
					if (bce_restriction != null) {
						bce_restriction.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
					}
				}
			}

			// 6.1.4.m - if pathLengthConstraint is present...
			if ((bce != null) && (bce.HasPathLengthConstraint)) {
				// ... and is less that max_path_length, set max_path_length to it's value
				if (bce.PathLengthConstraint < max_path_length) {
					max_path_length = bce.PathLengthConstraint;
					bce_restriction = element;
				}
			}

			// 6.1.4.n - if key usage extension is present...
			X509KeyUsageExtension kue = (certificate.Extensions["2.5.29.15"] as X509KeyUsageExtension);
			if (kue != null) {
				// ... verify keyCertSign is set
				X509KeyUsageFlags success = X509KeyUsageFlags.KeyCertSign;
				if ((kue.KeyUsages & success) != success)
					element.StatusFlags |= X509ChainStatusFlags.NotValidForUsage;
			}

			// 6.1.4.o - recognize and process other critical extension present in the certificate
			ProcessCertificateExtensions (element);
		}
 public void CopyTo(X509ChainElement[] array, int index)
 {
 }
Esempio n. 41
0
            internal void Evaluate(
                DateTime verificationTime,
                OidCollection?applicationPolicy,
                OidCollection?certificatePolicy,
                X509RevocationMode revocationMode,
                X509RevocationFlag revocationFlag)
            {
                Debug.Assert(_chainContext != null);

                long timeInMsFromUnixEpoch = new DateTimeOffset(verificationTime).ToUnixTimeMilliseconds();

                _isValid = Interop.AndroidCrypto.X509ChainBuild(_chainContext, timeInMsFromUnixEpoch);
                if (!_isValid)
                {
                    // Android always validates name, time, signature, and trusted root.
                    // There is no way bypass that validation and build a path.
                    ChainElements = Array.Empty <X509ChainElement>();

                    Interop.AndroidCrypto.ValidationError[] errors = Interop.AndroidCrypto.X509ChainGetErrors(_chainContext);
                    var chainStatus = new X509ChainStatus[errors.Length];
                    for (int i = 0; i < errors.Length; i++)
                    {
                        Interop.AndroidCrypto.ValidationError error = errors[i];
                        chainStatus[i] = ValidationErrorToChainStatus(error);
                        Marshal.FreeHGlobal(error.Message);
                    }

                    ChainStatus = chainStatus;
                    return;
                }

                byte checkedRevocation;
                int  res = Interop.AndroidCrypto.X509ChainValidate(_chainContext, revocationMode, revocationFlag, out checkedRevocation);

                if (res != 1)
                {
                    throw new CryptographicException();
                }

                X509Certificate2[]     certs         = Interop.AndroidCrypto.X509ChainGetCertificates(_chainContext);
                List <X509ChainStatus> overallStatus = new List <X509ChainStatus>();

                List <X509ChainStatus>[] statuses = new List <X509ChainStatus> [certs.Length];

                // Android will stop checking after the first error it hits, so we track the first
                // instances of revocation and non-revocation errors to fix-up the status of elements
                // beyond the first error
                int firstNonRevocationErrorIndex = -1;
                int firstRevocationErrorIndex    = -1;
                Dictionary <int, List <X509ChainStatus> > errorsByIndex = GetStatusByIndex(_chainContext);

                foreach (int index in errorsByIndex.Keys)
                {
                    List <X509ChainStatus> errors = errorsByIndex[index];
                    for (int i = 0; i < errors.Count; i++)
                    {
                        X509ChainStatus status = errors[i];
                        AddUniqueStatus(overallStatus, ref status);
                    }

                    // -1 indicates that error is not tied to a specific index
                    if (index != -1)
                    {
                        statuses[index] = errorsByIndex[index];
                        if (errorsByIndex[index].Exists(s => s.Status == X509ChainStatusFlags.Revoked || s.Status == X509ChainStatusFlags.RevocationStatusUnknown))
                        {
                            firstRevocationErrorIndex = Math.Max(index, firstRevocationErrorIndex);
                        }
                        else
                        {
                            firstNonRevocationErrorIndex = Math.Max(index, firstNonRevocationErrorIndex);
                        }
                    }
                }

                if (firstNonRevocationErrorIndex > 0)
                {
                    // Assign PartialChain to everything from the first non-revocation error to the end certificate
                    X509ChainStatus partialChainStatus = new X509ChainStatus
                    {
                        Status            = X509ChainStatusFlags.PartialChain,
                        StatusInformation = SR.Chain_PartialChain,
                    };
                    AddStatusFromIndexToEndCertificate(firstNonRevocationErrorIndex - 1, ref partialChainStatus, statuses, overallStatus);
                }

                if (firstRevocationErrorIndex > 0)
                {
                    // Assign RevocationStatusUnknown to everything from the first revocation error to the end certificate
                    X509ChainStatus revocationUnknownStatus = new X509ChainStatus
                    {
                        Status            = X509ChainStatusFlags.RevocationStatusUnknown,
                        StatusInformation = SR.Chain_RevocationStatusUnknown,
                    };
                    AddStatusFromIndexToEndCertificate(firstRevocationErrorIndex - 1, ref revocationUnknownStatus, statuses, overallStatus);
                }

                if (revocationMode != X509RevocationMode.NoCheck && checkedRevocation == 0)
                {
                    // Revocation checking was requested, but not performed (due to basic validation failing)
                    // Assign RevocationStatusUnknown to everything
                    X509ChainStatus revocationUnknownStatus = new X509ChainStatus
                    {
                        Status            = X509ChainStatusFlags.RevocationStatusUnknown,
                        StatusInformation = SR.Chain_RevocationStatusUnknown,
                    };
                    AddStatusFromIndexToEndCertificate(statuses.Length - 1, ref revocationUnknownStatus, statuses, overallStatus);
                }

                if (!IsPolicyMatch(certs, applicationPolicy, certificatePolicy))
                {
                    // Assign NotValidForUsage to everything
                    X509ChainStatus policyFailStatus = new X509ChainStatus
                    {
                        Status            = X509ChainStatusFlags.NotValidForUsage,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };
                    AddStatusFromIndexToEndCertificate(statuses.Length - 1, ref policyFailStatus, statuses, overallStatus);
                }

                X509ChainElement[] elements = new X509ChainElement[certs.Length];
                for (int i = 0; i < certs.Length; i++)
                {
                    X509ChainStatus[] elementStatus = statuses[i] == null?Array.Empty <X509ChainStatus>() : statuses[i].ToArray();

                    elements[i] = new X509ChainElement(certs[i], elementStatus, string.Empty);
                }

                ChainElements = elements;
                ChainStatus   = overallStatus.ToArray();
            }
        public void SetCertificate(X509ChainElement chainElement)
        {
            _chainElement = chainElement;
            var certificate = chainElement.Certificate;
            var dn = DistinguishedNameParser.Parse(certificate.SubjectName.Name);
            if (dn.ContainsKey("cn"))
            {
                commonNameLabel.Text = $"Issued To: {string.Join(", ", dn["cn"])}";
                var toolTip = new ToolTip {ShowAlways = true};
                toolTip.SetToolTip(commonNameLabel, commonNameLabel.Text);
            }
            else
            {
                commonNameLabel.Text = certificate.Thumbprint;
            }
            subjectAltNameLabel.Text = certificate.Extensions[KnownOids.SubjectAltNameExtension]?.Format(false) ?? "None";
            thumbprintLabel.Text = certificate.Thumbprint;
            if (certificate.PublicKey.Oid.Value == KnownOids.EccPublicKey)
            {
                var parameterOid = OidParser.ReadFromBytes(certificate.PublicKey.EncodedParameters.RawData);
                algorithmLabel.Text = $"{certificate.PublicKey.Oid.FriendlyName} ({parameterOid.FriendlyName})";
                switch (parameterOid.Value)
                {
                    case KnownOids.EcdsaP256:
                        keySizeLabel.Text = "256-bit";
                        break;
                    case KnownOids.EcdsaP384:
                        keySizeLabel.Text = "384-bit";
                        break;
                    case KnownOids.EcdsaP521:
                        keySizeLabel.Text = "521-bit";
                        break;
                    default:
                        keySizeLabel.Text = "Unknown";
                        break;
                }
            }
            else
            {
                algorithmLabel.Text = certificate.PublicKey.Oid.FriendlyName;
                keySizeLabel.Text = $"{certificate.PublicKey.Key.KeySize}-bit";
            }
            validDatesLabel.Text = $"{certificate.NotBefore.ToString("U")} to {certificate.NotAfter.ToString("U")}";
            hashAlgorithmLabel.Text = certificate.SignatureAlgorithm.FriendlyName;
            if (chainElement.ChainElementStatus.Length == 0 || chainElement.ChainElementStatus.All(status => status.Status == X509ChainStatusFlags.NoError))
            {
                certStatusImage.Image = Resources.Security_Shields_Complete_and_ok_16xLG_color;
                certStatusToolTip.SetToolTip(certStatusImage, "Certificate is OK.");
            }
            else if (chainElement.ChainElementStatus.All(status => status.Status == X509ChainStatusFlags.OfflineRevocation || status.Status == X509ChainStatusFlags.RevocationStatusUnknown))
            {
                certStatusImage.Image = Resources.Security_Shields_Alert_16xLG_color;
                certStatusToolTip.SetToolTip(certStatusImage, "Unable to check revocation status.");
            }
            else
            {
                certStatusImage.Image = Resources.Security_Shields_Critical_16xLG_color;
                certStatusToolTip.SetToolTip(certStatusImage, $"Errors: {string.Join(", ", chainElement.ChainElementStatus.Select(status => status.Status))}");
            }

            var hashAlgorithm = CryptoConfig.AllowOnlyFipsAlgorithms ? (SHA256)new SHA256CryptoServiceProvider() : new SHA256Managed();
            var hash = CertificateHashBuilder.BuildHashForPublicKey(chainElement.Certificate, hashAlgorithm);
            keyHashLabel.Text = $@"""{hash}""";
        }
Esempio n. 43
0
        //this code comes from AgentDiagnostics.  Need a better way to hook ino Agent.
        //Agent hooks TrustChainValidator and the build in DnsCertResolver, but the DnsCertResolver is strongly 
        //linked rather than via interface for notifications and exceptions.
        static string Summarize(X509ChainElement chainElement, X509ChainStatusFlags problemFlags)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(chainElement.Certificate.ExtractEmailNameOrName());
            builder.Append(";");
            foreach (X509ChainStatus status in chainElement.ChainElementStatus)
            {
                if ((status.Status & problemFlags) != 0)
                {
                    builder.Append(status.Status);
                }
            }

            return builder.ToString();
        }
Esempio n. 44
0
		public void Reset () 
		{
			// note: this call doesn't Reset the X509ChainPolicy
			if ((status != null) && (status.Length != 0))
				status = null;
			if (elements.Count > 0)
				elements.Clear ();
			if (user_root_store != null) {
				user_root_store.Close ();
				user_root_store = null;
			}
			if (root_store != null) {
				root_store.Close ();
				root_store = null;
			}
			if (user_ca_store != null) {
				user_ca_store.Close ();
				user_ca_store = null;
			}
			if (ca_store != null) {
				ca_store.Close ();
				ca_store = null;
			}
			roots = null;
			cas = null;
			collection = null;
			bce_restriction = null;
			working_public_key = null;
		}
Esempio n. 45
0
        public bool Build(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentException("certificate");
            }
            Reset();
            X509ChainStatusFlags x509ChainStatusFlags;

            try
            {
                x509ChainStatusFlags = BuildChainFrom(certificate);
                ValidateChain(x509ChainStatusFlags);
            }
            catch (CryptographicException innerException)
            {
                throw new ArgumentException("certificate", innerException);
                IL_0038:;
            }
            X509ChainStatusFlags       x509ChainStatusFlags2 = X509ChainStatusFlags.NoError;
            ArrayList                  arrayList             = new ArrayList();
            X509ChainElementEnumerator enumerator            = elements.GetEnumerator();

            while (enumerator.MoveNext())
            {
                X509ChainElement  current            = enumerator.Current;
                X509ChainStatus[] chainElementStatus = current.ChainElementStatus;
                for (int i = 0; i < chainElementStatus.Length; i++)
                {
                    X509ChainStatus x509ChainStatus = chainElementStatus[i];
                    if ((x509ChainStatusFlags2 & x509ChainStatus.Status) != x509ChainStatus.Status)
                    {
                        arrayList.Add(x509ChainStatus);
                        x509ChainStatusFlags2 |= x509ChainStatus.Status;
                    }
                }
            }
            if (x509ChainStatusFlags != 0)
            {
                arrayList.Insert(0, new X509ChainStatus(x509ChainStatusFlags));
            }
            status = (X509ChainStatus[])arrayList.ToArray(typeof(X509ChainStatus));
            if (status.Length == 0 || ChainPolicy.VerificationFlags == X509VerificationFlags.AllFlags)
            {
                return(true);
            }
            bool flag = true;

            X509ChainStatus[] array = status;
            for (int j = 0; j < array.Length; j++)
            {
                X509ChainStatus x509ChainStatus2 = array[j];
                switch (x509ChainStatus2.Status)
                {
                case X509ChainStatusFlags.UntrustedRoot:
                case X509ChainStatusFlags.PartialChain:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.AllowUnknownCertificateAuthority) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.NotTimeValid:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreNotTimeValid) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.NotTimeNested:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreNotTimeNested) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.InvalidBasicConstraints:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreInvalidBasicConstraints) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.InvalidPolicyConstraints:
                case X509ChainStatusFlags.NoIssuanceChainPolicy:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreInvalidPolicy) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.InvalidNameConstraints:
                case X509ChainStatusFlags.HasNotSupportedNameConstraint:
                case X509ChainStatusFlags.HasNotPermittedNameConstraint:
                case X509ChainStatusFlags.HasExcludedNameConstraint:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreInvalidName) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.InvalidExtension:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreWrongUsage) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.CtlNotTimeValid:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreCtlNotTimeValid) != X509VerificationFlags.NoFlag);
                    break;

                case X509ChainStatusFlags.CtlNotValidForUsage:
                    flag &= ((ChainPolicy.VerificationFlags & X509VerificationFlags.IgnoreWrongUsage) != X509VerificationFlags.NoFlag);
                    break;

                default:
                    flag = false;
                    break;

                case X509ChainStatusFlags.CtlNotSignatureValid:
                    break;
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
Esempio n. 46
0
		private void ProcessCertificateExtensions (X509ChainElement element)
		{
			foreach (X509Extension ext in element.Certificate.Extensions) {
				if (ext.Critical) {
					switch (ext.Oid.Value) {
					case "2.5.29.15": // X509KeyUsageExtension
					case "2.5.29.19": // X509BasicConstraintsExtension
						// we processed this extension
						break;
					default:
						// note: Under Windows XP MS implementation seems to ignore 
						// certificate with unknown critical extensions.
						element.StatusFlags |= X509ChainStatusFlags.InvalidExtension;
						break;
					}
				}
			}
		}
Esempio n. 47
0
 internal ChainElement(X509ChainElement source)
     : this()
 {
     this.Certificate = source.Certificate;
     this.ChainElementStatus.AddRange(source.ChainElementStatus);
 }