Exemple #1
0
        /// <summary>
        /// Returns a <see cref="HashAlgorithm"/> for a specific algorithm.
        /// </summary>
        /// <param name="algorithm">the name of the hash algorithm to create.</param>
        /// <returns>A <see cref="HashAlgorithm"/></returns>
        /// <remarks>When finished with the <see cref="HashAlgorithm"/> call <see cref="ReleaseHashAlgorithm(HashAlgorithm)"/>.</remarks>
        /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
        /// <exception cref="InvalidOperationException">'algorithm' is not supported.</exception>
        public virtual HashAlgorithm CreateHashAlgorithm(HashAlgorithmName algorithm)
        {
            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm.Name))
            {
                if (!(CustomCryptoProvider.Create(algorithm.Name) is HashAlgorithm hashAlgorithm))
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10647, algorithm, typeof(HashAlgorithm))));
                }

                _typeToAlgorithmMap[hashAlgorithm.GetType().ToString()] = algorithm.Name;

                return(hashAlgorithm);
            }

            if (algorithm == HashAlgorithmName.SHA256)
            {
                return(SHA256.Create());
            }

            if (algorithm == HashAlgorithmName.SHA384)
            {
                return(SHA384.Create());
            }

            if (algorithm == HashAlgorithmName.SHA512)
            {
                return(SHA512.Create());
            }

            throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10640, algorithm)));
        }
Exemple #2
0
        /// <summary>
        /// Creates an instance of <see cref="AuthenticatedEncryptionProvider"/> for a specific &lt;SecurityKey, Algorithm>.
        /// </summary>
        /// <param name="key">the <see cref="SecurityKey"/> to use.</param>
        /// <param name="algorithm">the algorithm to use.</param>
        /// <returns>an instance of <see cref="AuthenticatedEncryptionProvider"/></returns>
        /// <exception cref="ArgumentNullException">'key' is null.</exception>
        /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
        /// <exception cref="ArgumentException">'key' is not a <see cref="SymmetricSecurityKey"/>.</exception>
        /// <exception cref="ArgumentException">'algorithm, key' pair is not supported.</exception>
        public virtual AuthenticatedEncryptionProvider CreateAuthenticatedEncryptionProvider(SecurityKey key, string algorithm)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key))
            {
                var cryptoProvider = CustomCryptoProvider.Create(algorithm, key) as AuthenticatedEncryptionProvider;
                if (cryptoProvider == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10646, algorithm, key, typeof(AuthenticatedEncryptionProvider))));
                }

                return(cryptoProvider);
            }

            if (SupportedAlgorithms.IsSupportedAuthenticatedEncryptionAlgorithm(algorithm, key))
            {
                return(new AuthenticatedEncryptionProvider(key, algorithm));
            }

            throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10652, algorithm), nameof(algorithm)));
        }
        /// <summary>
        /// Checks if an 'algorithm, key' pair is supported.
        /// </summary>
        /// <param name="algorithm">the algorithm to check.</param>
        /// <param name="key">the <see cref="SecurityKey"/>.</param>
        /// <returns>true if 'algorithm, key' pair is supported.</returns>
        public virtual bool IsSupportedAlgorithm(string algorithm, SecurityKey key)
        {
            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key))
            {
                return(true);
            }

            if (key as RsaSecurityKey != null)
            {
                return(IsSupportedRsaAlgorithm(algorithm));
            }

            if (key is X509SecurityKey x509Key)
            {
#if NETSTANDARD1_4
                if (x509Key.PublicKey as RSA == null)
                {
                    return(false);
                }
#else
                if (x509Key.PublicKey as RSACryptoServiceProvider == null)
                {
                    return(false);
                }
#endif
                return(IsSupportedRsaAlgorithm(algorithm));
            }

            if (key is JsonWebKey jsonWebKey)
            {
                if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
                {
                    return(IsSupportedRsaAlgorithm(algorithm));
                }
                else if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                {
                    return(IsSupportedEcdsaAlgorithm(algorithm));
                }
                else if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                {
                    return(IsSupportedSymmetricAlgorithm(algorithm));
                }

                return(false);
            }

            if (key is ECDsaSecurityKey ecdsaSecurityKey)
            {
                return(IsSupportedEcdsaAlgorithm(algorithm));
            }

            if (key as SymmetricSecurityKey != null)
            {
                return(IsSupportedSymmetricAlgorithm(algorithm));
            }

            return(false);
        }
Exemple #4
0
        /// <summary>
        /// Checks if an 'algorithm, key' pair is supported.
        /// </summary>
        /// <param name="algorithm">the algorithm to check.</param>
        /// <param name="key">the <see cref="SecurityKey"/>.</param>
        /// <returns>true if 'algorithm, key' pair is supported.</returns>
        public virtual bool IsSupportedAlgorithm(string algorithm, SecurityKey key)
        {
            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key))
            {
                return(true);
            }

            return(SupportedAlgorithms.IsSupportedAlgorithm(algorithm, key));
        }
Exemple #5
0
        /// <summary>
        /// Answers if an algorithm is supported
        /// </summary>
        /// <param name="algorithm">the name of the cryptographic algorithm</param>
        /// <returns></returns>
        public virtual bool IsSupportedAlgorithm(string algorithm)
        {
            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm))
            {
                return(true);
            }

            return(SupportedAlgorithms.IsSupportedHashAlgorithm(algorithm));
        }
Exemple #6
0
        private KeyWrapProvider CreateKeyWrapProvider(SecurityKey key, string algorithm, bool willUnwrap)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willUnwrap))
            {
                if (!(CustomCryptoProvider.Create(algorithm, key, willUnwrap) is KeyWrapProvider keyWrapProvider))
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider))));
                }

                return(keyWrapProvider);
            }

            if (key is RsaSecurityKey rsaKey && SupportedAlgorithms.IsSupportedRsaAlgorithm(algorithm))
            {
                return(new RsaKeyWrapProvider(key, algorithm, willUnwrap));
            }

            if (key is X509SecurityKey x509Key && SupportedAlgorithms.IsSupportedRsaAlgorithm(algorithm))
            {
                return(new RsaKeyWrapProvider(x509Key, algorithm, willUnwrap));
            }

            if (key is JsonWebKey jsonWebKey)
            {
                if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA && SupportedAlgorithms.IsSupportedRsaAlgorithm(algorithm))
                {
                    return(new RsaKeyWrapProvider(jsonWebKey, algorithm, willUnwrap));
                }
                else if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet && SupportedAlgorithms.IsSupportedSymmetricAlgorithm(algorithm))
                {
                    return(new SymmetricKeyWrapProvider(jsonWebKey, algorithm));
                }
            }

            if (key is SymmetricSecurityKey symmetricKey && SupportedAlgorithms.IsSupportedSymmetricAlgorithm(algorithm))
            {
                return(new SymmetricKeyWrapProvider(symmetricKey, algorithm));
            }

            throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10661, algorithm, key)));
        }
Exemple #7
0
 /// <summary>
 /// When finished with a <see cref="SignatureProvider"/> call this method for cleanup. The default behavior is to call <see cref="SignatureProvider.Dispose()"/>
 /// </summary>
 /// <param name="signatureProvider"><see cref="SignatureProvider"/> to be released.</param>
 public virtual void ReleaseSignatureProvider(SignatureProvider signatureProvider)
 {
     if (signatureProvider == null)
     {
         throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
     }
     else if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(signatureProvider.Algorithm))
     {
         CustomCryptoProvider.Release(signatureProvider);
     }
     else if (signatureProvider.CryptoProviderCache == null)
     {
         signatureProvider.Dispose();
     }
 }
Exemple #8
0
 /// <summary>
 /// When finished with a <see cref="RsaKeyWrapProvider"/> call this method for cleanup."/>
 /// </summary>
 /// <param name="provider"><see cref="RsaKeyWrapProvider"/> to be released.</param>
 public virtual void ReleaseRsaKeyWrapProvider(RsaKeyWrapProvider provider)
 {
     if (provider == null)
     {
         throw LogHelper.LogArgumentNullException(nameof(provider));
     }
     else if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(provider.Algorithm))
     {
         CustomCryptoProvider.Release(provider);
     }
     else
     {
         provider.Dispose();
     }
 }
Exemple #9
0
 /// <summary>
 /// When finished with a <see cref="HashAlgorithm"/> call this method for cleanup. The default behavior is to call <see cref="HashAlgorithm.Dispose()"/>
 /// </summary>
 /// <param name="hashAlgorithm"><see cref="HashAlgorithm"/> to be released.</param>
 public virtual void ReleaseHashAlgorithm(HashAlgorithm hashAlgorithm)
 {
     if (hashAlgorithm == null)
     {
         throw LogHelper.LogArgumentNullException(nameof(hashAlgorithm));
     }
     else if (CustomCryptoProvider != null && _typeToAlgorithmMap.TryGetValue(hashAlgorithm.GetType().ToString(), out var algorithm) && CustomCryptoProvider.IsSupportedAlgorithm(algorithm))
     {
         CustomCryptoProvider.Release(hashAlgorithm);
     }
     else
     {
         hashAlgorithm.Dispose();
     }
 }
        /// <summary>
        /// Returns a <see cref="KeyedHashAlgorithm"/> for a specific algorithm.
        /// </summary>
        /// <param name="algorithm">the keyed hash algorithm to create.</param>
        /// <param name="keyBytes">bytes to use to create the Keyed Hash</param>
        /// <returns>A <see cref="HashAlgorithm"/></returns>
        /// <remarks>When finished with the <see cref="HashAlgorithm"/> call <see cref="ReleaseHashAlgorithm(HashAlgorithm)"/>.</remarks>
        /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
        /// <exception cref="InvalidOperationException">'algorithm' is not supported.</exception>
        public virtual KeyedHashAlgorithm CreateKeyedHashAlgorithm(byte[] keyBytes, string algorithm)
        {
            if (keyBytes == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(keyBytes));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, keyBytes))
            {
                var keyedHashAlgorithm = CustomCryptoProvider.Create(algorithm, keyBytes) as KeyedHashAlgorithm;
                if (keyedHashAlgorithm == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10647, algorithm, typeof(KeyedHashAlgorithm))));
                }

                return(keyedHashAlgorithm);
            }

            switch (algorithm)
            {
            case SecurityAlgorithms.HmacSha256Signature:
            case SecurityAlgorithms.HmacSha256:
                return(new HMACSHA256(keyBytes));

            case SecurityAlgorithms.HmacSha384Signature:
            case SecurityAlgorithms.HmacSha384:
                return(new HMACSHA384(keyBytes));

            case SecurityAlgorithms.HmacSha512Signature:
            case SecurityAlgorithms.HmacSha512:
                return(new HMACSHA512(keyBytes));

            default:
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10666, algorithm)));
            }
        }
        /// <summary>
        /// Returns a <see cref="HashAlgorithm"/> for a specific algorithm.
        /// </summary>
        /// <param name="algorithm">the name of the hash algorithm to create.</param>
        /// <returns>A <see cref="HashAlgorithm"/></returns>
        /// <remarks>When finished with the <see cref="HashAlgorithm"/> call <see cref="ReleaseHashAlgorithm(HashAlgorithm)"/>.</remarks>
        /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
        /// <exception cref="InvalidOperationException">'algorithm' is not supported.</exception>
        public virtual HashAlgorithm CreateHashAlgorithm(string algorithm)
        {
            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm))
            {
                var hashAlgorithm = CustomCryptoProvider.Create(algorithm) as HashAlgorithm;
                if (hashAlgorithm == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10647, algorithm, typeof(HashAlgorithm))));
                }

                _typeToAlgorithmMap[hashAlgorithm.GetType().ToString()] = algorithm;

                return(hashAlgorithm);
            }

            switch (algorithm)
            {
            case SecurityAlgorithms.Sha256:
            case SecurityAlgorithms.Sha256Digest:
                return(SHA256.Create());

            case SecurityAlgorithms.Sha384:
            case SecurityAlgorithms.Sha384Digest:
                return(SHA384.Create());

            case SecurityAlgorithms.Sha512:
            case SecurityAlgorithms.Sha512Digest:
                return(SHA512.Create());
            }

            throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10640, algorithm)));
        }
Exemple #12
0
        private SignatureProvider CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            SignatureProvider signatureProvider = null;

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures))
            {
                signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider;
                if (signatureProvider == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider))));
                }

                return(signatureProvider);
            }

            // types are checked in order of expected occurrence
            string typeofSignatureProvider = null;
            bool   createAsymmetric        = true;

            if (key is AsymmetricSecurityKey asymmetricSecurityKey)
            {
                typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString();
            }
            else if (key is JsonWebKey jsonWebKey)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString();
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString();
                        createAsymmetric        = false;
                    }
                }
            }
            else if (key is SymmetricSecurityKey symmetricSecurityKey)
            {
                typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString();
                createAsymmetric        = false;
            }

            if (typeofSignatureProvider == null)
            {
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10621, typeof(SymmetricSignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType())));
            }

            if (!IsSupportedAlgorithm(algorithm, key))
            {
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, algorithm, key)));
            }

            if (CacheSignatureProviders)
            {
                if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider))
                {
                    return(signatureProvider);
                }

                lock (_cacheLock)
                {
                    if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider))
                    {
                        return(signatureProvider);
                    }

                    if (createAsymmetric)
                    {
                        signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this);
                    }
                    else
                    {
                        signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures);
                    }

                    CryptoProviderCache.TryAdd(signatureProvider);
                }
            }
            else if (createAsymmetric)
            {
                signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures);
            }
            else
            {
                signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures);
            }

            return(signatureProvider);
        }