예제 #1
0
        public bool Build (X509Certificate2 certificate) {
            lock (m_syncRoot) {
                if (certificate == null || certificate.CertContext.IsInvalid)
                    throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidContextHandle), "certificate");

                // Chain building opens and enumerates the root store to see if the root of the chain is trusted.
                StorePermission sp = new StorePermission(StorePermissionFlags.OpenStore | StorePermissionFlags.EnumerateCertificates);
                sp.Demand();

                X509ChainPolicy chainPolicy = this.ChainPolicy;
                if (chainPolicy.RevocationMode == X509RevocationMode.Online) {
                    if (certificate.Extensions[CAPI.szOID_CRL_DIST_POINTS] != null ||
                        certificate.Extensions[CAPI.szOID_AUTHORITY_INFO_ACCESS] != null) {
                        // If there is a CDP or AIA extension, we demand unrestricted network access and store add permission
                        // since CAPI can download certificates into the CA store from the network.
                        PermissionSet ps = new PermissionSet(PermissionState.None);
                        ps.AddPermission(new WebPermission(PermissionState.Unrestricted));
                        ps.AddPermission(new StorePermission(StorePermissionFlags.AddToStore));
                        ps.Demand();
                    }
                }

                Reset();
                int hr = BuildChain(m_useMachineContext ? new IntPtr(CAPI.HCCE_LOCAL_MACHINE) : new IntPtr(CAPI.HCCE_CURRENT_USER),
                                    certificate.CertContext,
                                    chainPolicy.ExtraStore,
                                    chainPolicy.ApplicationPolicy,
                                    chainPolicy.CertificatePolicy,
                                    chainPolicy.RevocationMode,
                                    chainPolicy.RevocationFlag,
                                    chainPolicy.VerificationTime,
                                    chainPolicy.UrlRetrievalTimeout,
                                    ref m_safeCertChainHandle);

                if (hr != CAPI.S_OK)
                    return false;

                // Init.
                Init();

                // Verify the chain using the specified policy.
                CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA)));
                CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS)));

                PolicyPara.dwFlags = (uint) chainPolicy.VerificationFlags;

                if (!CAPI.CertVerifyCertificateChainPolicy(new IntPtr(CAPI.CERT_CHAIN_POLICY_BASE),
                                                           m_safeCertChainHandle,
                                                           ref PolicyPara,
                                                           ref PolicyStatus))
                    // The API failed.
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                CAPI.SetLastError(PolicyStatus.dwError);
                return (PolicyStatus.dwError == 0);
            }
        }
예제 #2
0
        internal static unsafe int VerifyCertificate (Cryptography.SafeCertContextHandle pCertContext,
                                                      OidCollection applicationPolicy,
                                                      OidCollection certificatePolicy,
                                                      X509RevocationMode revocationMode,
                                                      X509RevocationFlag revocationFlag,
                                                      DateTime verificationTime,
                                                      TimeSpan timeout,
                                                      X509Certificate2Collection extraStore,
                                                      IntPtr pszPolicy,
                                                      IntPtr pdwErrorStatus) {
            if (pCertContext == null || pCertContext.IsInvalid)
                throw new ArgumentException("pCertContext");

            CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA)));
            CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS)));

            // Build the chain.
            SafeX509ChainHandle pChainContext = SafeX509ChainHandle.InvalidHandle;
            int hr = X509Chain.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER),
                                          pCertContext, 
                                          extraStore,
                                          applicationPolicy, 
                                          certificatePolicy,
                                          revocationMode,
                                          revocationFlag,
                                          verificationTime,
                                          timeout,
                                          ref pChainContext);
            if (hr != CAPI.S_OK)
                return hr;

            // Verify the chain using the specified policy.
            if (CAPI.CertVerifyCertificateChainPolicy(pszPolicy, pChainContext, ref PolicyPara, ref PolicyStatus)) {
                if (pdwErrorStatus != IntPtr.Zero)
                    *(uint*) pdwErrorStatus = PolicyStatus.dwError;

                if (PolicyStatus.dwError != 0)
                    return CAPI.S_FALSE;
            } else {
                // The API failed.
                return Marshal.GetHRForLastWin32Error();
            }

            return CAPI.S_OK;
        }
        public bool Build(X509Certificate2 certificate)
        {
            if (certificate == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate");
            if (certificate.Handle == IntPtr.Zero)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("certificate", SR.GetString(SR.ArgumentInvalidCertificate));

            SafeCertChainHandle safeCertChainHandle = SafeCertChainHandle.InvalidHandle;
            X509ChainPolicy chainPolicy = this.ChainPolicy;
            chainPolicy.VerificationTime = DateTime.Now;
            if (chainPolicy.RevocationMode == X509RevocationMode.Online)
            {
                if (certificate.Extensions[CAPI.szOID_CRL_DIST_POINTS] != null ||
                    certificate.Extensions[CAPI.szOID_AUTHORITY_INFO_ACCESS] != null)
                {
                    // If there is a CDP or AIA extension, we demand unrestricted network access and store add permission
                    // since CAPI can download certificates into the CA store from the network.
                    PermissionSet ps = new PermissionSet(PermissionState.None);
                    ps.AddPermission(new WebPermission(PermissionState.Unrestricted));
                    ps.AddPermission(new StorePermission(StorePermissionFlags.AddToStore));
                    ps.Demand();
                }
            }

            BuildChain(this.useMachineContext ? new IntPtr(CAPI.HCCE_LOCAL_MACHINE) : new IntPtr(CAPI.HCCE_CURRENT_USER),
                    certificate.Handle,
                    chainPolicy.ExtraStore,
                    chainPolicy.ApplicationPolicy,
                    chainPolicy.CertificatePolicy,
                    chainPolicy.RevocationMode,
                    chainPolicy.RevocationFlag,
                    chainPolicy.VerificationTime,
                    chainPolicy.UrlRetrievalTimeout,
                    out safeCertChainHandle);

            // Verify the chain using the specified policy.
            CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA)));
            CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS)));

            // Ignore peertrust.  Peer trust caused the chain to succeed out-of-the-box in Vista.
            // This new flag is only available in Vista.
            PolicyPara.dwFlags = (uint)chainPolicy.VerificationFlags | CAPI.CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG;

            if (!CAPI.CertVerifyCertificateChainPolicy(new IntPtr(this.chainPolicyOID),
                                                       safeCertChainHandle,
                                                       ref PolicyPara,
                                                       ref PolicyStatus))
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
            }

            if (PolicyStatus.dwError != CAPI.S_OK)
            {
                int error = (int)PolicyStatus.dwError;
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.X509ChainBuildFail,
                    SecurityUtils.GetCertificateId(certificate), new CryptographicException(error).Message)));
            }

            return true;
        }