internal static SafeBCryptKeyHandle ImportKey(SafeBCryptAlgorithmHandle algorithm, byte[] key) { const int BCRYPT_KEY_DATA_BLOB_MAGIC = 0x4d42444b; // Concatenate the BCRYPT_KEY_DATA_BLOB header and the raw key. byte[] keyBlob = new byte[Marshal.SizeOf(typeof(BCRYPT_KEY_DATA_BLOB)) + key.Length]; unsafe { fixed(byte *pbKeyBlob = keyBlob) { BCRYPT_KEY_DATA_BLOB *pkeyDataBlob = (BCRYPT_KEY_DATA_BLOB *)pbKeyBlob; pkeyDataBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; pkeyDataBlob->dwVersion = 1; pkeyDataBlob->cbKeyData = key.Length; } } Buffer.BlockCopy(key, 0, keyBlob, Marshal.SizeOf(typeof(BCRYPT_KEY_DATA_BLOB)), key.Length); int cbKeyData = BitConverter.ToInt32(GetProperty(algorithm, "ObjectLength"), 0); var pbKeyData = Marshal.AllocCoTaskMem(cbKeyData); ErrorCode error = UnsafeNativeMethods.BCryptImportKey(algorithm, IntPtr.Zero, "KeyDataBlob", out var keyHandle, pbKeyData, cbKeyData, keyBlob, keyBlob.Length, 0); if (error == ErrorCode.Success) { keyHandle.DataBuffer = pbKeyData; return(keyHandle); } else { Marshal.FreeCoTaskMem(pbKeyData); throw new CryptographicException("Failed to import key: error " + error); } }
internal static void SetProperty(SafeBCryptAlgorithmHandle bcryptObject, string property, byte[] value) { ErrorCode error = UnsafeNativeMethods.BCryptSetAlgorithmProperty(bcryptObject, property, value, value.Length, 0); if (error != ErrorCode.Success) { throw new CryptographicException("Property set failed with error " + error); } }
internal static extern ErrorCode BCryptImportKey(SafeBCryptAlgorithmHandle hAlgorithm, IntPtr hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Out] out SafeBCryptKeyHandle phKey, [In, Out] IntPtr pbKeyObject, int cbKeyObject, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbInput, int cbInput, int dwFlags);
internal static byte[] GetProperty(SafeBCryptAlgorithmHandle bcryptObject, string property) { // Query the space requirements. int propertySize = 0; ErrorCode error = UnsafeNativeMethods.BCryptGetAlgorithmProperty(bcryptObject, property, null, 0, ref propertySize, 0); if (error != ErrorCode.Success && error != ErrorCode.BufferTooSmall) { throw new CryptographicException("Failed to get property: error " + error); } // Get the value. byte[] propertyValue = new byte[propertySize]; error = UnsafeNativeMethods.BCryptGetAlgorithmProperty(bcryptObject, property, propertyValue, propertyValue.Length, ref propertySize, 0); if (error != ErrorCode.Success) { throw new CryptographicException("Failed to get property: error " + error); } return(propertyValue); }
internal static extern ErrorCode BCryptOpenAlgorithmProvider([Out] out SafeBCryptAlgorithmHandle phAlgorithm, [MarshalAs(UnmanagedType.LPWStr)] string pszAlgId, [MarshalAs(UnmanagedType.LPWStr)] string pszImplementation, int dwFlags);
internal static extern ErrorCode BCryptSetAlgorithmProperty(SafeBCryptAlgorithmHandle hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbInput, int cbInput, int dwFlags);
internal static extern ErrorCode BCryptGetAlgorithmProperty(SafeBCryptAlgorithmHandle hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, int cbOutput, [In, Out] ref int pcbResult, int flags);