/// <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, X509Certificate2Collection customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout) { CertificatePal certificatePal = (CertificatePal)cert; unsafe { using (SafeChainEngineHandle storeHandle = GetChainEngine(trustMode, customTrustStore, useMachineContext)) using (SafeCertStoreHandle extraStoreHandle = ConvertStoreToSafeHandle(extraStore)) { CERT_CHAIN_PARA chainPara = default; 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); SafeX509ChainHandle chain; if (!Interop.crypt32.CertGetCertificateChain(storeHandle.DangerousGetHandle(), certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) { return(null); } return(new ChainPal(chain)); } } } } }
public byte[] EncodeX509EnhancedKeyUsageExtension(OidCollection usages) { int numUsages; using (SafeHandle usagesSafeHandle = usages.ToLpstrArray(out numUsages)) { unsafe { CERT_ENHKEY_USAGE enhKeyUsage = new CERT_ENHKEY_USAGE() { cUsageIdentifier = numUsages, rgpszUsageIdentifier = (IntPtr *)(usagesSafeHandle.DangerousGetHandle()), }; return(Interop.crypt32.EncodeObject(Oids.EnhancedKeyUsage, &enhKeyUsage)); } } }