private static TAlgorithm DecodeECPublicKey <TAlgorithm>( CertificatePal certificatePal, Func <CngKey, TAlgorithm> factory, CryptImportPublicKeyInfoFlags importFlags = CryptImportPublicKeyInfoFlags.NONE) where TAlgorithm : ECAlgorithm, new() { TAlgorithm key; using (SafeCertContextHandle certContext = certificatePal.GetCertContext()) using (SafeBCryptKeyHandle bCryptKeyHandle = ImportPublicKeyInfo(certContext, importFlags)) { CngKeyBlobFormat blobFormat; byte[] keyBlob; string? curveName = GetCurveName(bCryptKeyHandle); if (curveName == null) { if (HasExplicitParameters(bCryptKeyHandle)) { blobFormat = CngKeyBlobFormat.EccFullPublicBlob; } else { blobFormat = CngKeyBlobFormat.EccPublicBlob; } keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); key = factory(CngKey.Import(keyBlob, blobFormat)); } else { blobFormat = CngKeyBlobFormat.EccPublicBlob; keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); ECParameters ecparams = default; ExportNamedCurveParameters(ref ecparams, keyBlob, false); ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName); key = new TAlgorithm(); key.ImportParameters(ecparams); } } return(key); }
internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { CertificatePal certificatePal = (CertificatePal)cert; SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore( CertStoreProvider.CERT_STORE_PROV_MEMORY, Interop.Crypt32.CertEncodingType.All, IntPtr.Zero, Interop.Crypt32.CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, null); using (SafeCertContextHandle certContext = certificatePal.GetCertContext()) { if (certStore.IsInvalid || !Interop.Crypt32.CertAddCertificateLinkToStore(certStore, certContext, Interop.Crypt32.CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero)) { Exception e = Marshal.GetHRForLastWin32Error().ToCryptographicException(); certStore.Dispose(); throw e; } } return(new StorePal(certStore)); }
/// <summary> /// Does not throw on error. Returns null ChainPal instead. /// </summary> internal static partial IChainPal?BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection?customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { CertificatePal certificatePal = (CertificatePal)cert; unsafe { using (SafeChainEngineHandle storeHandle = GetChainEngine(trustMode, customTrustStore, useMachineContext)) using (SafeCertStoreHandle extraStoreHandle = ConvertStoreToSafeHandle(extraStore)) { Interop.Crypt32.CERT_CHAIN_PARA chainPara = default; chainPara.cbSize = Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_PARA>(); int applicationPolicyCount; using (SafeHandle applicationPolicyOids = applicationPolicy !.ToLpstrArray(out applicationPolicyCount)) { if (!applicationPolicyOids.IsInvalid) { chainPara.RequestedUsage.dwType = Interop.Crypt32.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 = Interop.Crypt32.CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount; chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle(); } chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds); Interop.Crypt32.FILETIME ft = Interop.Crypt32.FILETIME.FromDateTime(verificationTime); Interop.Crypt32.CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag, disableAia); SafeX509ChainHandle chain; using (SafeCertContextHandle certContext = certificatePal.GetCertContext()) { if (!Interop.Crypt32.CertGetCertificateChain(storeHandle.DangerousGetHandle(), certContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) { chain.Dispose(); return(null); } } return(new ChainPal(chain)); } } } } }