public SafeBCryptAlgorithmHandle GetCachedAlgorithmHandle(string algorithm, string implementation) { string handleKey = algorithm + implementation; SafeBCryptAlgorithmHandle algorithmHandle = null; if (m_algorithmHandles.ContainsKey(handleKey)) { algorithmHandle = m_algorithmHandles[handleKey].Target as SafeBCryptAlgorithmHandle; if (algorithmHandle != null) { return(algorithmHandle); } } algorithmHandle = BCryptNative.OpenAlgorithm(algorithm, implementation); m_algorithmHandles[handleKey] = new WeakReference(algorithmHandle); return(algorithmHandle); }
public byte[] HashFinal() { Contract.Ensures(Contract.Result <byte[]>() != null); Contract.Assert(m_hashHandle != null); int hashSize = BCryptNative.GetInt32Property(m_hashHandle, BCryptNative.HashPropertyName.HashLength); byte[] hashValue = new byte[hashSize]; BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptFinishHash(m_hashHandle, hashValue, hashValue.Length, 0); if (error != BCryptNative.ErrorCode.Success) { throw new CryptographicException((int)error); } return(hashValue); }
public void Initialize() { Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed); Contract.Assert(m_algorithmHandle != null); // Try to create a new hash algorithm to use SafeBCryptHashHandle newHashAlgorithm = null; IntPtr hashObjectBuffer = IntPtr.Zero; // Creating a BCRYPT_HASH_HANDLE requires providing a buffer to hold the hash object in, which // is tied to the lifetime of the hash handle. Wrap this in a CER so we can tie the lifetimes together // safely. try { int hashObjectSize = BCryptNative.GetInt32Property(m_algorithmHandle, BCryptNative.ObjectPropertyName.ObjectLength); Debug.Assert(hashObjectSize > 0, "hashObjectSize > 0"); // Allocate in a CER because we could fail between the alloc and the assignment try { } finally { hashObjectBuffer = Marshal.AllocCoTaskMem(hashObjectSize); } BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptCreateHash(m_algorithmHandle, out newHashAlgorithm, hashObjectBuffer, hashObjectSize, IntPtr.Zero, 0, 0); if (error != BCryptNative.ErrorCode.Success) { throw new CryptographicException((int)error); } } finally { // Make sure we've successfully transfered ownership of the hash object buffer to the safe handle if (hashObjectBuffer != IntPtr.Zero) { // If we created the safe handle, it needs to own the buffer and free it in release if (newHashAlgorithm != null) { newHashAlgorithm.HashObject = hashObjectBuffer; } else { Marshal.FreeCoTaskMem(hashObjectBuffer); } } } // If we could create it, dispose of any old hash handle we had and replace it with the new one if (m_hashHandle != null) { m_hashHandle.Dispose(); } m_hashHandle = newHashAlgorithm; }