Esempio n. 1
0
        //
        //
        // obj is SslStream
        public bool ValidateClientCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            m_log.InfoFormat("[NSL CERT VERIFY]: ValidateClientCertificate: Policy is ({0})", sslPolicyErrors);

            X509Certificate2 certificate2 = new X509Certificate2(certificate);
            string           simplename   = certificate2.GetNameInfo(X509NameType.SimpleName, false);

            //m_log.InfoFormat("[NSL CERT VERIFY]: ValidateClientCertificate: Simple Name is \"{0}\"", simplename);

/*
 *                      // RemoteCertificateNotAvailableはエラーとする.
 *                      if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable)==SslPolicyErrors.RemoteCertificateNotAvailable) {
 *                              m_log.InfoFormat("[NSL CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
 *                              return false;
 *                      }
 */
            // None, ChainErrors 以外は全てエラーとする.
            if (sslPolicyErrors != SslPolicyErrors.None && sslPolicyErrors != SslPolicyErrors.RemoteCertificateChainErrors)
            {
                m_log.InfoFormat("[NSL CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
                return(false);
            }

            // check CRL
            if (m_clientcrl != null)
            {
                Mono.Security.X509.X509Certificate      monocert = new Mono.Security.X509.X509Certificate(certificate.GetRawCertData());
                Mono.Security.X509.X509Crl.X509CrlEntry entry    = m_clientcrl.GetCrlEntry(monocert);
                if (entry != null)
                {
                    m_log.InfoFormat("[NSL CERT VERIFY]: Common Name \"{0}\" was revoked at {1}", simplename, entry.RevocationDate.ToString());
                    return(false);
                }
            }

            bool valid = CheckPrivateChain(certificate2);

            if (valid)
            {
                m_log.InfoFormat("[NSL CERT VERIFY]: Valid Client Certification for \"{0}\"", simplename);
            }
            else
            {
                m_log.InfoFormat("[NSL CERT VERIFY]: Failed to Verify Client Certification for \"{0}\"", simplename);
            }
            return(valid);
        }
Esempio n. 2
0
        /// <summary>
        /// Validate Client Certificate Callback Function
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        public bool ValidateClientCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Start.");

            if (certificate == null)
            {
                m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Client does not have a Certificate!");
                return(false);
            }

            X509Certificate2 certificate2 = new X509Certificate2(certificate);
            string           commonname   = certificate2.GetNameInfo(X509NameType.SimpleName, false);

            m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Common Name is \"{0}\"", commonname);

            // None, ChainErrors 以外は全てエラーとする.
            if (sslPolicyErrors != SslPolicyErrors.None && sslPolicyErrors != SslPolicyErrors.RemoteCertificateChainErrors)
            {
                m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
                return(false);
            }

            // check CRL
            if (m_clientcrl != null)
            {
                Mono.Security.X509.X509Certificate      monocert = new Mono.Security.X509.X509Certificate(certificate.GetRawCertData());
                Mono.Security.X509.X509Crl.X509CrlEntry entry    = m_clientcrl.GetCrlEntry(monocert);
                if (entry != null)
                {
                    m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Common Name \"{0}\" was revoked at {1}", commonname, entry.RevocationDate.ToString());
                    return(false);
                }
            }

            bool valid = CheckPrivateChain(certificate2);

            if (valid)
            {
                m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Valid Client Certification for \"{0}\"", commonname);
            }
            else
            {
                m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Failed to Verify Client Certification for \"{0}\"", commonname);
            }
            return(valid);
        }
        private bool ProcessCrlEntryExtensions(MX.X509Crl.X509CrlEntry entry)
        {
            foreach (MX.X509Extension ext in entry.Extensions)
            {
                if (ext.Critical)
                {
                    switch (ext.Oid)
                    {
                    case "2.5.29.21": // cRLReason
                        // we processed/know about this extension
                        break;

                    default:
                        return(false);
                    }
                }
            }
            return(true);
        }
        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);
                }

                MX.X509Crl.X509CrlEntry entry = crl.GetCrlEntry(certificate.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);
        }