private static TAlgorithm DecodeECPublicKey <TAlgorithm>( CertificatePal certificatePal, Func <CngKey, TAlgorithm> factory, Action <TAlgorithm, ECParameters> import, CryptImportPublicKeyInfoFlags importFlags = CryptImportPublicKeyInfoFlags.NONE) where TAlgorithm : AsymmetricAlgorithm, new() { TAlgorithm key; using (SafeBCryptKeyHandle bCryptKeyHandle = ImportPublicKeyInfo(certificatePal.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); using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat)) { key = factory(cngKey); } } else { blobFormat = CngKeyBlobFormat.EccPublicBlob; keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); ECParameters ecparams = default; ExportNamedCurveParameters(ref ecparams, keyBlob, false); ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName); key = new TAlgorithm(); import(key, ecparams); } } return(key); }
private static SafeBCryptKeyHandle ImportPublicKeyInfo(SafeCertContextHandle certContext, CryptImportPublicKeyInfoFlags importFlags) { unsafe { SafeBCryptKeyHandle bCryptKeyHandle; bool mustRelease = false; certContext.DangerousAddRef(ref mustRelease); try { unsafe { bool success = Interop.crypt32.CryptImportPublicKeyInfoEx2(Interop.Crypt32.CertEncodingType.X509_ASN_ENCODING, &(certContext.CertContext->pCertInfo->SubjectPublicKeyInfo), importFlags, null, out bCryptKeyHandle); if (!success) { throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); } return(bCryptKeyHandle); } } finally { if (mustRelease) { certContext.DangerousRelease(); } } } }
public static unsafe partial bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pInfo, CryptImportPublicKeyInfoFlags dwFlags, void *pvAuxInfo, out SafeBCryptKeyHandle phKey);