internal static byte[] GetProperty <T>(T algorithm, string property) where T : SafeHandle { BCryptPropertyGetter <T> getter = null; if (typeof(T) == typeof(SafeBCryptAlgorithmHandle)) { getter = new BCryptPropertyGetter <SafeBCryptAlgorithmHandle>(UnsafeNativeMethods.BCryptGetAlgorithmProperty) as BCryptPropertyGetter <T>; } else if (typeof(T) == typeof(SafeBCryptHashHandle)) { getter = new BCryptPropertyGetter <SafeBCryptHashHandle>(UnsafeNativeMethods.BCryptGetHashProperty) as BCryptPropertyGetter <T>; } int pcbResult = 0; ErrorCode code = getter(algorithm, property, null, 0, ref pcbResult, 0); if ((code != ErrorCode.BufferToSmall) && (code != ErrorCode.Success)) { throw new CryptographicException((int)code); } byte[] pbOutput = new byte[pcbResult]; code = getter(algorithm, property, pbOutput, pbOutput.Length, ref pcbResult, 0); if (code != ErrorCode.Success) { throw new CryptographicException((int)code); } return(pbOutput); }
internal static byte[] GetProperty <T>(T bcryptObject, string property) where T : SafeHandle { Debug.Assert(bcryptObject != null, "bcryptObject != null"); Debug.Assert(!bcryptObject.IsClosed && !bcryptObject.IsInvalid, "!bcryptObject.IsClosed && !bcryptObject.IsInvalid"); Debug.Assert(!String.IsNullOrEmpty(property), "!String.IsNullOrEmpty(property)"); // Figure out which P/Invoke to use for the specific SafeHandle type we were given. For now we // only need to get properties of BCrypt algorithms, so we only check for SafeBCryptAlgorithmHandles. BCryptPropertyGetter <T> propertyGetter = null; if (typeof(T) == typeof(SafeBCryptAlgorithmHandle)) { propertyGetter = new BCryptPropertyGetter <SafeBCryptAlgorithmHandle>(UnsafeNativeMethods.BCryptGetAlgorithmProperty) as BCryptPropertyGetter <T>; } else if (typeof(T) == typeof(SafeBCryptHashHandle)) { propertyGetter = new BCryptPropertyGetter <SafeBCryptHashHandle>(UnsafeNativeMethods.BCryptGetHashProperty) as BCryptPropertyGetter <T>; } Debug.Assert(propertyGetter != null, "Unknown bcrypt object type"); // Figure out how big of a buffer is needed to hold the property int propertySize = 0; ErrorCode error = propertyGetter(bcryptObject, property, null, 0, ref propertySize, 0); if (error != ErrorCode.Success && error != ErrorCode.BufferToSmall) { throw new CryptographicException((int)error); } // Get the property value byte[] propertyValue = new byte[propertySize]; error = propertyGetter(bcryptObject, property, propertyValue, propertyValue.Length, ref propertySize, 0); if (error != ErrorCode.Success) { throw new CryptographicException((int)error); } return(propertyValue); }
internal static byte[] GetProperty <T>(T algorithm, string property) where T : SafeHandle { Contract.Requires(algorithm != null); Contract.Requires(!String.IsNullOrEmpty(property)); Contract.Ensures(Contract.Result <byte[]>() != null); BCryptPropertyGetter <T> getter = null; if (typeof(T) == typeof(SafeBCryptAlgorithmHandle)) { getter = new BCryptPropertyGetter <SafeBCryptAlgorithmHandle>(UnsafeNativeMethods.BCryptGetAlgorithmProperty) as BCryptPropertyGetter <T>; } else if (typeof(T) == typeof(SafeBCryptHashHandle)) { getter = new BCryptPropertyGetter <SafeBCryptHashHandle>(UnsafeNativeMethods.BCryptGetHashProperty) as BCryptPropertyGetter <T>; } Debug.Assert(getter != null, "Unknown handle type"); // Figure out how big the property is int bufferSize = 0; ErrorCode error = getter(algorithm, property, null, 0, ref bufferSize, 0); if (error != ErrorCode.BufferToSmall && error != ErrorCode.Success) { throw new CryptographicException((int)error); } // Allocate the buffer, and return the property Debug.Assert(bufferSize > 0, "bufferSize > 0"); byte[] buffer = new byte[bufferSize]; error = getter(algorithm, property, buffer, buffer.Length, ref bufferSize, 0); if (error != ErrorCode.Success) { throw new CryptographicException((int)error); } return(buffer); }