/// <summary> /// Method take BCrypt handle as input and returns the CNGKey /// </summary> /// <param name="bcryptKeyHandle">Accepts BCrypt Handle</param> /// <returns>Returns CNG key with NCrypt Handle</returns> private static CngKey BCryptHandleToNCryptHandle(SafeBCryptKeyHandle bcryptKeyHandle) { byte[] keyBlob = BCryptNative.ExportBCryptKey(bcryptKeyHandle, BCryptNative.BCRYPT_ECCPUBLIC_BLOB); //Now Import the key blob as NCRYPT_KEY_HANDLE CngKey Key = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob); return Key; }
private static byte[]? GetProperty(SafeBCryptKeyHandle cryptHandle, string propertyName) { Debug.Assert(!cryptHandle.IsInvalid); unsafe { int numBytesNeeded; NTSTATUS errorCode = Interop.BCrypt.BCryptGetProperty(cryptHandle, propertyName, null, 0, out numBytesNeeded, 0); if (errorCode != NTSTATUS.STATUS_SUCCESS) { return(null); } byte[] propertyValue = new byte[numBytesNeeded]; fixed(byte *pPropertyValue = propertyValue) { errorCode = Interop.BCrypt.BCryptGetProperty(cryptHandle, propertyName, pPropertyValue, propertyValue.Length, out numBytesNeeded, 0); } if (errorCode != NTSTATUS.STATUS_SUCCESS) { return(null); } Array.Resize(ref propertyValue, numBytesNeeded); return(propertyValue); } }
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 string?GetPropertyAsString(SafeBCryptKeyHandle cryptHandle, string propertyName) { Debug.Assert(!cryptHandle.IsInvalid); byte[]? value = GetProperty(cryptHandle, propertyName); if (value == null || value.Length == 0) { return(null); } unsafe { fixed(byte *pValue = &value[0]) { string?valueAsString = Marshal.PtrToStringUni((IntPtr)pValue); return(valueAsString); } } }
private static byte[] ExportKeyBlob(SafeBCryptKeyHandle bCryptKeyHandle, CngKeyBlobFormat blobFormat) { string blobFormatString = blobFormat.Format; int numBytesNeeded = 0; NTSTATUS ntStatus = Interop.BCrypt.BCryptExportKey(bCryptKeyHandle, IntPtr.Zero, blobFormatString, null, 0, out numBytesNeeded, 0); if (ntStatus != NTSTATUS.STATUS_SUCCESS) { throw new CryptographicException(Interop.Kernel32.GetMessage((int)ntStatus)); } byte[] keyBlob = new byte[numBytesNeeded]; ntStatus = Interop.BCrypt.BCryptExportKey(bCryptKeyHandle, IntPtr.Zero, blobFormatString, keyBlob, keyBlob.Length, out numBytesNeeded, 0); if (ntStatus != NTSTATUS.STATUS_SUCCESS) { throw new CryptographicException(Interop.Kernel32.GetMessage((int)ntStatus)); } Array.Resize(ref keyBlob, numBytesNeeded); return(keyBlob); }
private static string?GetCurveName(SafeBCryptKeyHandle bcryptHandle) { return(GetPropertyAsString(bcryptHandle, BCRYPT_ECC_CURVE_NAME_PROPERTY)); }
private static bool HasExplicitParameters(SafeBCryptKeyHandle bcryptHandle) { byte[]? explicitParams = GetProperty(bcryptHandle, BCRYPT_ECC_PARAMETERS_PROPERTY); return(explicitParams != null && explicitParams.Length > 0); }
public static unsafe partial bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pInfo, CryptImportPublicKeyInfoFlags dwFlags, void *pvAuxInfo, out SafeBCryptKeyHandle phKey);
public static unsafe extern bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO* pInfo, int dwFlags, void* pvAuxInfo, out SafeBCryptKeyHandle phKey);
internal static extern NTSTATUS BCryptExportKey(SafeBCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, [Out] byte[] pbOutput, int cbOutput, out int pcbResult, int dwFlags);