/// <summary>
        /// Initializes a new instance of the <see cref="AuthenticatedEncryptionProvider"/> class used for encryption and decryption.
        /// <param name="key">The <see cref="SecurityKey"/> that will be used for crypto operations.</param>
        /// <param name="algorithm">The encryption algorithm to apply.</param>
        /// <exception cref="ArgumentNullException">'key' is null.</exception>
        /// <exception cref="ArgumentNullException">'algorithm' is null or whitespace.</exception>
        /// <exception cref="ArgumentOutOfRangeException">key size is not large enough.</exception>
        /// <exception cref="ArgumentException">'algorithm' is not supported.</exception>
        /// <exception cref="ArgumentException">a symmetricSignatureProvider is not created.</exception>
        /// </summary>
        public AuthenticatedEncryptionProvider(SecurityKey key, string algorithm)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

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

            if (!IsSupportedAlgorithm(key, algorithm))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10668, GetType(), algorithm, key)));
            }

            ValidateKeySize(key, algorithm);
            _authenticatedkeys          = GetAlgorithmParameters(key, algorithm);
            _hmacAlgorithm              = GetHmacAlgorithm(algorithm);
            _symmetricSignatureProvider = key.CryptoProviderFactory.CreateForSigning(_authenticatedkeys.HmacKey, _hmacAlgorithm) as SymmetricSignatureProvider;
            if (_symmetricSignatureProvider == null)
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10649, Algorithm)));
            }

            Key       = key;
            Algorithm = algorithm;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticatedEncryptionProvider"/> class used for encryption and decryption.
        /// <param name="key">The <see cref="SecurityKey"/> that will be used for crypto operations.</param>
        /// <param name="algorithm">The encryption algorithm to apply.</param>
        /// <exception cref="ArgumentNullException">'key' is null.</exception>
        /// <exception cref="ArgumentNullException">'algorithm' is null or whitespace.</exception>
        /// <exception cref="ArgumentOutOfRangeException">key size is not large enough.</exception>
        /// <exception cref="ArgumentException">'algorithm' is not supported.</exception>
        /// <exception cref="ArgumentException">a symmetricSignatureProvider is not created.</exception>
        /// </summary>
        public AuthenticatedEncryptionProvider(SecurityKey key, string algorithm)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

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

            if (!IsSupportedAlgorithm(key, algorithm))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10668, GetType(), algorithm, key)));
            }

            ValidateKeySize(key, algorithm);
            _authenticatedkeys = GetAlgorithmParameters(key, algorithm);
            _hashAlgorithm     = GetHashAlgorithm(algorithm);

            // TODO - should we defer and use CreateForSigning for encrypt, CreateForVerifying for decrypt?
            _symmetricSignatureProvider = key.CryptoProviderFactory.CreateForSigning(_authenticatedkeys.HmacKey, _hashAlgorithm) as SymmetricSignatureProvider;
            if (_symmetricSignatureProvider == null)
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10649, Algorithm)));
            }

            Key       = key;
            Algorithm = algorithm;
        }
Exemple #3
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);
        }