Ejemplo n.º 1
0
 public Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, SafeBCryptAlgorithmHandle handle)
     : this()
 {
     HashAlgorithmId = hashAlgorithmId;
     Flags = flags;
     Handle = handle;
 }
Ejemplo n.º 2
0
 public Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, SafeBCryptAlgorithmHandle handle)
     : this()
 {
     HashAlgorithmId = hashAlgorithmId;
     Flags           = flags;
     Handle          = handle;
 }
Ejemplo n.º 3
0
         /// <summary>
         ///     Return a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it!
         /// </summary>
         public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags)
         {
             // There aren't that many hash algorithms around so rather than use a LowLevelDictionary and guard it with a lock,
             // we'll use a simple list. To avoid locking, we'll recreate the entire list each time an entry is added and replace it atomically.
             //
             // This does mean that on occasion, racing threads may create two handles of the same type, but this is ok.
 
             // Latch the _cache value into a local so we aren't disrupted by concurrent changes to it.
             Entry[] cache = _cache;
             foreach (Entry entry in cache)
             {
                 if (entry.HashAlgorithmId == hashAlgorithmId && entry.Flags == flags)
                     return entry.Handle;
             }
 
             SafeBCryptAlgorithmHandle safeBCryptAlgorithmHandle;
             NTSTATUS ntStatus = Interop.BCrypt.BCryptOpenAlgorithmProvider(out safeBCryptAlgorithmHandle, hashAlgorithmId, null, flags);
             if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                 throw Interop.BCrypt.CreateCryptographicException(ntStatus);
 
             Entry[] newCache = new Entry[cache.Length + 1];
             Entry newEntry = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle);
             Array.Copy(cache, 0, newCache, 0, cache.Length);
             newCache[newCache.Length - 1] = newEntry;
 
             // Atomically overwrite the cache with our new cache. It's possible some other thread raced to add a new entry with us - if so, one of the new entries
             // will be lost and the next guy that requests it will have to allocate it again. That's considered acceptable collateral damage.
             _cache = newCache;
             return newEntry.Handle;
         }
Ejemplo n.º 4
0
        /// <summary>
        /// Loads and initializes a CNG provider.
        /// </summary>
        /// <param name="pszAlgId">
        /// A pointer to a null-terminated Unicode string that identifies the requested
        /// cryptographic algorithm. This can be one of the standard
        /// CNG Algorithm Identifiers defined in <see cref="AlgorithmIdentifiers"/>
        /// or the identifier for another registered algorithm.
        /// </param>
        /// <param name="pszImplementation">
        /// <para>
        /// A pointer to a null-terminated Unicode string that identifies the specific provider
        /// to load. This is the registered alias of the cryptographic primitive provider.
        /// This parameter is optional and can be NULL if it is not needed. If this parameter
        /// is NULL, the default provider for the specified algorithm will be loaded.
        /// </para>
        /// <para>
        /// Note If the <paramref name="pszImplementation"/> parameter value is NULL, CNG attempts to open each
        /// registered provider, in order of priority, for the algorithm specified by the
        /// <paramref name="pszAlgId"/> parameter and returns the handle of the first provider that is successfully
        /// opened.For the lifetime of the handle, any BCrypt*** cryptographic APIs will use the
        /// provider that was successfully opened.
        /// </para>
        /// </param>
        /// <param name="dwFlags">Options for the function.</param>
        /// <returns>
        /// A pointer to a BCRYPT_ALG_HANDLE variable that receives the CNG provider handle.
        /// When you have finished using this handle, release it by passing it to the
        /// BCryptCloseAlgorithmProvider function.
        /// </returns>
        public static SafeAlgorithmHandle BCryptOpenAlgorithmProvider(
            string pszAlgId,
            string pszImplementation = null,
            BCryptOpenAlgorithmProviderFlags dwFlags = BCryptOpenAlgorithmProviderFlags.None)
        {
            SafeAlgorithmHandle handle;

            BCryptOpenAlgorithmProvider(
                out handle,
                pszAlgId,
                pszImplementation,
                dwFlags).ThrowOnError();
            return(handle);
        }
 internal static extern NTSTATUS BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags);
Ejemplo n.º 6
0
            /// <summary>
            ///     Return a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it!
            /// </summary>
            public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, out int hashSizeInBytes)
            {
                // There aren't that many hash algorithms around so rather than use a LowLevelDictionary and guard it with a lock,
                // we'll use a simple list. To avoid locking, we'll recreate the entire list each time an entry is added and replace it atomically.
                //
                // This does mean that on occasion, racing threads may create two handles of the same type, but this is ok.

                // Latch the _cache value into a local so we aren't disrupted by concurrent changes to it.
                Entry[] cache = _cache;
                foreach (Entry entry in cache)
                {
                    if (entry.HashAlgorithmId == hashAlgorithmId && entry.Flags == flags)
                    {
                        hashSizeInBytes = entry.HashSizeInBytes;
                        return(entry.Handle);
                    }
                }

                SafeBCryptAlgorithmHandle safeBCryptAlgorithmHandle;
                NTSTATUS ntStatus = Interop.BCrypt.BCryptOpenAlgorithmProvider(out safeBCryptAlgorithmHandle, hashAlgorithmId, null, flags);

                if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }

                Array.Resize(ref cache, cache.Length + 1);
                Entry newEntry = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle);

                cache[^ 1] = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle);
 internal static extern NTSTATUS BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags);
Ejemplo n.º 8
0
 internal static extern int BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle algorithmHandle, string algIdString, string implementationString, BCryptOpenAlgorithmProviderFlags flags);
Ejemplo n.º 9
0
 public static extern NTStatus BCryptOpenAlgorithmProvider(
     out SafeAlgorithmHandle phAlgorithm,
     string pszAlgId,
     string pszImplementation,
     BCryptOpenAlgorithmProviderFlags dwFlags);
Ejemplo n.º 10
0
            /// <summary>
            ///     Return a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it!
            /// </summary>
            public static SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags)
            {
                // There aren't that many hash algorithms around so rather than use a LowLevelDictionary and guard it with a lock,
                // we'll use a simple list. To avoid locking, we'll recreate the entire list each time an entry is added and replace it atomically.
                //
                // This does mean that on occasion, racing threads may create two handles of the same type, but this is ok.

                // Latch the _cache value into a local so we aren't disrupted by concurrent changes to it.
                Entry[] cache = _cache;
                foreach (Entry entry in cache)
                {
                    if (entry.HashAlgorithmId == hashAlgorithmId && entry.Flags == flags)
                    {
                        return(entry.Handle);
                    }
                }

                SafeBCryptAlgorithmHandle safeBCryptAlgorithmHandle;
                NTSTATUS ntStatus = Interop.BCrypt.BCryptOpenAlgorithmProvider(out safeBCryptAlgorithmHandle, hashAlgorithmId, null, flags);

                if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }

                Entry[] newCache = new Entry[cache.Length + 1];
                Entry   newEntry = new Entry(hashAlgorithmId, flags, safeBCryptAlgorithmHandle);

                Array.Copy(cache, 0, newCache, 0, cache.Length);
                newCache[newCache.Length - 1] = newEntry;

                // Atomically overwrite the cache with our new cache. It's possible some other thread raced to add a new entry with us - if so, one of the new entries
                // will be lost and the next guy that requests it will have to allocate it again. That's considered acceptable collateral damage.
                _cache = newCache;
                return(newEntry.Handle);
            }
Ejemplo n.º 11
0
 public static extern NtStatus BCryptOpenAlgorithmProvider(
     out IntPtr phAlgorithm,
     string pszAlgId,
     string pszImplementation = null,
     BCryptOpenAlgorithmProviderFlags dwFlags = BCryptOpenAlgorithmProviderFlags.None
     );
Ejemplo n.º 12
0
 public static extern NTStatus BCryptOpenAlgorithmProvider(
     out SafeAlgorithmHandle phAlgorithm,
     string pszAlgId,
     string pszImplementation,
     BCryptOpenAlgorithmProviderFlags dwFlags);
Ejemplo n.º 13
0
            /// <summary>
            /// Returns a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it!
            /// </summary>
            public static unsafe SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, out int hashSizeInBytes)
            {
                var key = (hashAlgorithmId, flags);

                while (true)
                {
                    if (s_handles.TryGetValue(key, out (SafeBCryptAlgorithmHandle Handle, int HashSizeInBytes)result))
                    {
                        hashSizeInBytes = result.HashSizeInBytes;
                        return(result.Handle);
                    }

                    NTSTATUS ntStatus = Interop.BCrypt.BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle handle, key.hashAlgorithmId, null, key.flags);
                    if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                    {
                        Exception e = Interop.BCrypt.CreateCryptographicException(ntStatus);
                        handle.Dispose();
                        throw e;
                    }

                    int hashSize;
                    ntStatus = Interop.BCrypt.BCryptGetProperty(
                        handle,
                        Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH,
                        &hashSize,
                        sizeof(int),
                        out int cbHashSize,
                        0);
                    if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                    {
                        Exception e = Interop.BCrypt.CreateCryptographicException(ntStatus);
                        handle.Dispose();
                        throw e;
                    }

                    Debug.Assert(cbHashSize == sizeof(int));
                    Debug.Assert(hashSize > 0);

                    if (!s_handles.TryAdd(key, (handle, hashSize)))
                    {
                        handle.Dispose();
                    }
                }
            }
Ejemplo n.º 14
0
 internal static extern int BCryptOpenAlgorithmProvider(out IntPtr phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags);