// // Verifies whether a certificate is valid for the specified policy. // S_OK means the certificate is valid for the specified policy. // S_FALSE means the certificate is invalid for the specified policy. // Anything else is an error. // internal static unsafe int VerifyCertificate(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. SafeCertChainHandle pChainContext = SafeCertChainHandle.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) { 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); } }
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); }