public bool Build(X509Certificate2 certificate) { if (certificate == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate"); } if (certificate.Handle == IntPtr.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("certificate", System.IdentityModel.SR.GetString("ArgumentInvalidCertificate")); } System.IdentityModel.SafeCertChainHandle invalidHandle = System.IdentityModel.SafeCertChainHandle.InvalidHandle; X509ChainPolicy chainPolicy = this.ChainPolicy; chainPolicy.VerificationTime = DateTime.Now; BuildChain(this.useMachineContext ? new IntPtr(1L) : new IntPtr(0L), certificate.Handle, chainPolicy.ExtraStore, chainPolicy.ApplicationPolicy, chainPolicy.CertificatePolicy, chainPolicy.RevocationMode, chainPolicy.RevocationFlag, chainPolicy.VerificationTime, chainPolicy.UrlRetrievalTimeout, out invalidHandle); System.IdentityModel.CAPI.CERT_CHAIN_POLICY_PARA pPolicyPara = new System.IdentityModel.CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_POLICY_PARA))); System.IdentityModel.CAPI.CERT_CHAIN_POLICY_STATUS pPolicyStatus = new System.IdentityModel.CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_POLICY_STATUS))); pPolicyPara.dwFlags = (uint)(chainPolicy.VerificationFlags | 0x1000); if (!System.IdentityModel.CAPI.CertVerifyCertificateChainPolicy(new IntPtr((long)this.chainPolicyOID), invalidHandle, ref pPolicyPara, ref pPolicyStatus)) { int hr = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr)); } if (pPolicyStatus.dwError != 0) { int dwError = (int)pPolicyStatus.dwError; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("X509ChainBuildFail", new object[] { System.IdentityModel.SecurityUtils.GetCertificateId(certificate), new CryptographicException(dwError).Message }))); } return(true); }
internal static extern bool CertGetCertificateChain( [In] IntPtr hChainEngine, [In] IntPtr pCertContext, [In] ref FILETIME pTime, [In] SafeCertStoreHandle hAdditionalStore, [In] ref CERT_CHAIN_PARA pChainPara, [In] uint dwFlags, [In] IntPtr pvReserved, [Out] out SafeCertChainHandle ppChainContext );
private static unsafe void BuildChain(IntPtr hChainEngine, IntPtr pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, out System.IdentityModel.SafeCertChainHandle ppChainContext) { System.IdentityModel.SafeCertStoreHandle hAdditionalStore = ExportToMemoryStore(extraStore, pCertContext); System.IdentityModel.CAPI.CERT_CHAIN_PARA pChainPara = new System.IdentityModel.CAPI.CERT_CHAIN_PARA { cbSize = (uint)Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_PARA)) }; SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle; SafeHGlobalHandle handle3 = SafeHGlobalHandle.InvalidHandle; try { if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { pChainPara.RequestedUsage.dwType = 0; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; invalidHandle = CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = invalidHandle.DangerousGetHandle(); } if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { pChainPara.RequestedIssuancePolicy.dwType = 0; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; handle3 = CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long *)&pTime) = verificationTime.ToFileTime(); uint dwFlags = MapRevocationFlags(revocationMode, revocationFlag); if (!System.IdentityModel.CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) { int hr = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr)); } } finally { if (invalidHandle != null) { invalidHandle.Dispose(); } if (handle3 != null) { handle3.Dispose(); } hAdditionalStore.Close(); } }
internal extern static bool CertVerifyCertificateChainPolicy( [In] IntPtr pszPolicyOID, [In] SafeCertChainHandle pChainContext, [In] ref CERT_CHAIN_POLICY_PARA pPolicyPara, [In, Out] ref CERT_CHAIN_POLICY_STATUS pPolicyStatus);
internal static extern bool CertGetCertificateChain([In] IntPtr hChainEngine, [In] IntPtr pCertContext, [In] ref System.Runtime.InteropServices.ComTypes.FILETIME pTime, [In] SafeCertStoreHandle hAdditionalStore, [In] ref CERT_CHAIN_PARA pChainPara, [In] uint dwFlags, [In] IntPtr pvReserved, out SafeCertChainHandle ppChainContext);