예제 #1
0
        private bool IsSignedWith(X509Certificate2 signed, AsymmetricAlgorithm pubkey)
        {
            if (pubkey == null)
            {
                return(false);
            }
            // Sadly X509Certificate2 doesn't expose the signature nor the tbs (to be signed) structure
            var mx = X509Helper2.GetMonoCertificate(signed);

            return(mx.VerifySignature(pubkey));
        }
 public X509CertificateImpl Import(X509Certificate cert)
 {
     return(X509Helper2.Import(cert));
 }
 public X509CertificateImpl Import(
     byte[] data, string password, X509KeyStorageFlags flags)
 {
     return(X509Helper2.Import(data, password, flags));
 }
예제 #4
0
 internal X509Chain(X509ChainImpl impl)
 {
     X509Helper2.ThrowIfContextInvalid(impl);
     this.impl = impl;
 }
예제 #5
0
 public X509Chain(bool useMachineContext)
 {
     impl = X509Helper2.CreateChainImpl(useMachineContext);
 }
예제 #6
0
 internal void ThrowIfContextInvalid()
 {
     X509Helper2.ThrowIfContextInvalid(impl);
 }
예제 #7
0
        private X509ChainStatusFlags CheckRevocation(X509Certificate2 certificate, X509Certificate2 ca_cert, bool online)
        {
            // change this if/when we support OCSP
            X509KeyUsageExtension kue = (ca_cert.Extensions["2.5.29.15"] as X509KeyUsageExtension);

            if (kue != null)
            {
                // ... verify CrlSign is set
                X509KeyUsageFlags success = X509KeyUsageFlags.CrlSign;
                if ((kue.KeyUsages & success) != success)
                {
                    // FIXME - we should try to find an alternative CA that has the CrlSign bit
                    return(X509ChainStatusFlags.RevocationStatusUnknown);
                }
            }

            MX.X509Crl crl = FindCrl(ca_cert);

            if ((crl == null) && online)
            {
                // FIXME - download and install new CRL
                // then you get a second chance
                // crl = FindCrl (ca_cert, ref valid, ref out_of_date);

                // We need to get the subjectAltName and an URI from there (or use OCSP)
                // X509KeyUsageExtension subjectAltName = (ca_cert.Extensions["2.5.29.17"] as X509KeyUsageExtension);
            }

            if (crl != null)
            {
                // validate the digital signature on the CRL using the CA public key
                // note #1: we can't use X509Crl.VerifySignature(X509Certificate) because it duplicates
                // checks and we loose the "why" of the failure
                // note #2: we do this before other tests as an invalid signature could be a hacked CRL
                // (so anything within can't be trusted)
                if (!crl.VerifySignature(ca_cert.PublicKey.Key))
                {
                    return(X509ChainStatusFlags.RevocationStatusUnknown);
                }

                var monoCertificate           = X509Helper2.GetMonoCertificate(certificate);
                MX.X509Crl.X509CrlEntry entry = crl.GetCrlEntry(monoCertificate);
                if (entry != null)
                {
                    // We have an entry for this CRL that includes an unknown CRITICAL extension
                    // See [X.509 7.3] NOTE 4
                    if (!ProcessCrlEntryExtensions(entry))
                    {
                        return(X509ChainStatusFlags.Revoked);
                    }

                    // FIXME - a little more is involved
                    if (entry.RevocationDate <= ChainPolicy.VerificationTime)
                    {
                        return(X509ChainStatusFlags.Revoked);
                    }
                }

                // are we overdue for a CRL update ? if so we can't be sure of any certificate status
                if (crl.NextUpdate < ChainPolicy.VerificationTime)
                {
                    return(X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation);
                }

                // we have a CRL that includes an unknown CRITICAL extension
                // we put this check at the end so we do not "hide" any Revoked flags
                if (!ProcessCrlExtensions(crl))
                {
                    return(X509ChainStatusFlags.RevocationStatusUnknown);
                }
            }
            else
            {
                return(X509ChainStatusFlags.RevocationStatusUnknown);
            }

            return(X509ChainStatusFlags.NoError);
        }
예제 #8
0
        // System.dll v2 doesn't have a class to deal with the AuthorityKeyIdentifier extension
        static string GetAuthorityKeyIdentifier(X509Certificate2 certificate)
        {
            var monoCertificate = X509Helper2.GetMonoCertificate(certificate);

            return(GetAuthorityKeyIdentifier(monoCertificate.Extensions ["2.5.29.35"]));
        }
예제 #9
0
        private void Process(int n)
        {
            X509ChainElement element     = elements [n];
            X509Certificate2 certificate = element.Certificate;
            var monoCertificate          = X509Helper2.GetMonoCertificate(certificate);

            // pre-step: DSA certificates may inherit the parameters of their CA
            if ((n != elements.Count - 1) && (monoCertificate.KeyAlgorithm == "1.2.840.10040.4.1"))
            {
                if (monoCertificate.KeyAlgorithmParameters == null)
                {
                    var parent = X509Helper2.GetMonoCertificate(elements [n + 1].Certificate);
                    monoCertificate.KeyAlgorithmParameters = parent.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
        }
예제 #10
0
        public override void Import(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
        {
            var impl = X509Helper2.Import(rawData, password, keyStorageFlags);

            ImportHandle(impl);
        }
예제 #11
0
 public X509Certificate2(X509Certificate certificate)
     : base(X509Helper2.Import(certificate))
 {
 }