Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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;
        }