Example #1
0
        /// <summary>
        /// Does not throw on error. Returns null ChainPal instead.
        /// </summary>
        public static ChainPal BuildChain(
            bool useMachineContext,
            ICertificatePal cert,
            X509Certificate2Collection extraStore,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            TimeSpan timeout)
        {
            CertificatePal certificatePal = (CertificatePal)cert;

            unsafe
            {
                using (SafeCertStoreHandle extraStoreHandle = ConvertExtraStoreToSafeHandle(extraStore))
                {
                    CERT_CHAIN_PARA chainPara = new CERT_CHAIN_PARA();
                    chainPara.cbSize = Marshal.SizeOf <CERT_CHAIN_PARA>();

                    int applicationPolicyCount;
                    using (SafeHandle applicationPolicyOids = applicationPolicy.ToLpstrArray(out applicationPolicyCount))
                    {
                        if (!applicationPolicyOids.IsInvalid)
                        {
                            chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND;
                            chainPara.RequestedUsage.Usage.cUsageIdentifier     = applicationPolicyCount;
                            chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle();
                        }

                        int certificatePolicyCount;
                        using (SafeHandle certificatePolicyOids = certificatePolicy.ToLpstrArray(out certificatePolicyCount))
                        {
                            if (!certificatePolicyOids.IsInvalid)
                            {
                                chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND;
                                chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier     = certificatePolicyCount;
                                chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle();
                            }

                            chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds);

                            FILETIME       ft          = FILETIME.FromDateTime(verificationTime);
                            CertChainFlags flags       = MapRevocationFlags(revocationMode, revocationFlag);
                            ChainEngine    chainEngine = useMachineContext ? ChainEngine.HCCE_LOCAL_MACHINE : ChainEngine.HCCE_CURRENT_USER;

                            SafeX509ChainHandle chain;
                            if (!Interop.crypt32.CertGetCertificateChain(chainEngine, certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain))
                            {
                                return(null);
                            }
                            return(new ChainPal(chain));
                        }
                    }
                }
            }
        }
Example #2
0
        private static bool CertificateHasLowerPrecedence(X509Store store, ChainEngine engine, string fqdn, X509Certificate2 certificate, out X509Certificate2 best)
        {
            CertificateSelectionOption options = CertificateSelectionOption.WildcardAllowed | CertificateSelectionOption.PreferedNonSelfSigned;

            string[] names = new string[]
            {
                fqdn
            };
            IEnumerable <X509Certificate2> enumerable = TlsCertificateInfo.FindAll(store, names, options, engine, out best);
            bool flag = false;

            foreach (X509Certificate2 x509Certificate in enumerable)
            {
                if (string.Equals(certificate.Thumbprint, x509Certificate.Thumbprint, StringComparison.OrdinalIgnoreCase))
                {
                    flag = true;
                    break;
                }
            }
            return(flag && best != null && !string.Equals(best.Thumbprint, certificate.Thumbprint, StringComparison.OrdinalIgnoreCase));
        }
Example #3
0
        private static void WarnIfNotBestMatch(ExchangeCertificate certificate, IConfigurationSession session, Server server, List <LocalizedString> warningList)
        {
            if (warningList == null)
            {
                return;
            }
            X509Store x509Store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

            try
            {
                x509Store.Open(OpenFlags.ReadOnly);
                using (ChainEngine chainEngine = new ChainEngine())
                {
                    IEnumerable <ManageExchangeCertificate.FqdnConnectors> connectorFQDNs = ManageExchangeCertificate.GetConnectorFQDNs(session, server);
                    foreach (ManageExchangeCertificate.FqdnConnectors fqdnConnectors in connectorFQDNs)
                    {
                        X509Certificate2 x509Certificate;
                        if (ManageExchangeCertificate.CertificateHasLowerPrecedence(x509Store, chainEngine, fqdnConnectors.Fqdn, certificate, out x509Certificate))
                        {
                            if (!new ExchangeCertificate(x509Certificate).IsSelfSigned)
                            {
                                warningList.Add(Strings.WarnCertificateWillNotBeUsedBestIsPKI(x509Certificate.Thumbprint, fqdnConnectors.Fqdn, fqdnConnectors.Connectors));
                            }
                            else
                            {
                                warningList.Add(Strings.WarnCertificateWillNotBeUsed(x509Certificate.Thumbprint, fqdnConnectors.Fqdn, fqdnConnectors.Connectors));
                            }
                        }
                    }
                }
            }
            finally
            {
                if (x509Store != null)
                {
                    x509Store.Close();
                }
            }
        }
Example #4
0
 public static unsafe bool CertGetCertificateChain(ChainEngine hChainEngine, SafeCertContextHandle pCertContext, FILETIME *pTime, SafeCertStoreHandle hStore, [In] ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext)
 {
     return(CertGetCertificateChain((IntPtr)hChainEngine, pCertContext, pTime, hStore, ref pChainPara, dwFlags, pvReserved, out ppChainContext));
 }
Example #5
0
 public static unsafe bool CertGetCertificateChain(ChainEngine hChainEngine, SafeCertContextHandle pCertContext, FILETIME* pTime, SafeCertStoreHandle hStore, [In] ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext)
 {
     return CertGetCertificateChain((IntPtr)hChainEngine, pCertContext, pTime, hStore, ref pChainPara, dwFlags, pvReserved, out ppChainContext);
 }
Example #6
0
        private void CheckCertificateChainAndCacheProps()
        {
            if (this.status != CertificateStatus.Unknown)
            {
                return;
            }
            if (!string.IsNullOrEmpty(this.CertificateRequest))
            {
                this.status     = CertificateStatus.PendingRequest;
                this.selfSigned = false;
                this.rootCAType = CertificateAuthorityType.Unknown;
                return;
            }
            this.privateKeyExportable = TlsCertificateInfo.IsCertificateExportable(this);
            ChainPolicyParameters options          = new BaseChainPolicyParameters(ChainPolicyOptions.None);
            ChainMatchIssuer      pkixKpServerAuth = AndChainMatchIssuer.PkixKpServerAuth;
            ChainBuildParameter   parameter        = new ChainBuildParameter(pkixKpServerAuth, TimeSpan.FromSeconds(30.0), false, TimeSpan.Zero);

            using (ChainEngine chainEngine = new ChainEngine())
            {
                using (ChainContext chainContext = chainEngine.Build(this, ChainBuildOptions.CacheEndCert | ChainBuildOptions.RevocationCheckChainExcludeRoot | ChainBuildOptions.RevocationAccumulativeTimeout, parameter))
                {
                    if (chainContext == null)
                    {
                        this.status     = CertificateStatus.Unknown;
                        this.selfSigned = false;
                        this.rootCAType = CertificateAuthorityType.Unknown;
                    }
                    else
                    {
                        this.selfSigned = chainContext.IsSelfSigned;
                        if (chainContext.Status == TrustStatus.IsUntrustedRoot)
                        {
                            if (chainContext.IsSelfSigned)
                            {
                                this.status     = CertificateStatus.Valid;
                                this.rootCAType = CertificateAuthorityType.None;
                            }
                            else
                            {
                                this.status     = CertificateStatus.Untrusted;
                                this.rootCAType = CertificateAuthorityType.Unknown;
                            }
                        }
                        else
                        {
                            ChainSummary        chainSummary        = chainContext.Validate(options);
                            ChainValidityStatus chainValidityStatus = chainSummary.Status;
                            if (chainValidityStatus <= (ChainValidityStatus)2148081683U)
                            {
                                if (chainValidityStatus == ChainValidityStatus.Valid)
                                {
                                    this.status = CertificateStatus.Valid;
                                    goto IL_168;
                                }
                                switch (chainValidityStatus)
                                {
                                case (ChainValidityStatus)2148081682U:
                                case (ChainValidityStatus)2148081683U:
                                    break;

                                default:
                                    goto IL_15A;
                                }
                            }
                            else
                            {
                                if (chainValidityStatus == (ChainValidityStatus)2148204801U)
                                {
                                    this.status = CertificateStatus.DateInvalid;
                                    goto IL_168;
                                }
                                switch (chainValidityStatus)
                                {
                                case (ChainValidityStatus)2148204812U:
                                    this.status = CertificateStatus.Revoked;
                                    goto IL_168;

                                case (ChainValidityStatus)2148204813U:
                                    goto IL_15A;

                                case (ChainValidityStatus)2148204814U:
                                    break;

                                default:
                                    goto IL_15A;
                                }
                            }
                            this.status = CertificateStatus.RevocationCheckFailure;
                            goto IL_168;
IL_15A:
                            this.status     = CertificateStatus.Invalid;
                            this.rootCAType = CertificateAuthorityType.Unknown;
IL_168:
                            if (this.status != CertificateStatus.Invalid)
                            {
                                X509Certificate2 rootCertificate = chainContext.RootCertificate;
                                if (rootCertificate == null)
                                {
                                    throw new InvalidOperationException("Root certificate was null!");
                                }
                                this.rootCAType = ExchangeCertificate.RootSource(rootCertificate.Thumbprint);
                            }
                        }
                    }
                }
            }
        }