/// <summary>
 /// Returns a <see cref="SignatureProvider"/> instance supports the <see cref="SecurityKey"/> and algorithm.
 /// </summary>
 /// <param name="key">The <see cref="SecurityKey"/> to use for signing.</param>
 /// <param name="algorithm">The algorithm to use for verifying.</param>
 /// <exception cref="ArgumentNullException">'key' is null.</exception>
 /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><see cref="AsymmetricSecurityKey"/> is too small.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><see cref="SymmetricSecurityKey"/> is too small.</exception>
 /// <exception cref="ArgumentException"><see cref="SecurityKey"/>' is not a <see cref="AsymmetricSecurityKey"/> or a <see cref="SymmetricSecurityKey"/>.</exception>
 /// <remarks>When finished with the <see cref="SignatureProvider"/> call <see cref="ReleaseSignatureProvider(SignatureProvider)"/>.</remarks>
 public virtual SignatureProvider CreateForVerifying(SecurityKey key, string algorithm)
 {
     return(CreateSignatureProvider(key, algorithm, false));
 }
        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));
            }

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

                return(signatureProvider);
            }

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

            AsymmetricSecurityKey asymmetricKey = key as AsymmetricSecurityKey;

            if (asymmetricKey != null)
            {
                return(new AsymmetricSignatureProvider(asymmetricKey, algorithm, willCreateSignatures));
            }

            SymmetricSecurityKey symmetricKey = key as SymmetricSecurityKey;

            if (symmetricKey != null)
            {
                return(new SymmetricSignatureProvider(symmetricKey, algorithm));
            }

            JsonWebKey jsonWebKey = key as JsonWebKey;

            if (jsonWebKey != null)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        return(new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures));
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        return(new SymmetricSignatureProvider(key, algorithm));
                    }
                }
            }

            // TODO improve this message. Nothing about JsonWebKey is mentioned.
            throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10600, typeof(SignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType())));
        }
 /// <summary>
 /// Creates a <see cref="SignatureProvider"/> that supports the <see cref="SecurityKey"/> and algorithm.
 /// </summary>
 /// <param name="key">The <see cref="SecurityKey"/> to use for signing.</param>
 /// <param name="algorithm">The algorithm to use for signing.</param>
 /// <exception cref="ArgumentNullException">'key' is null.</exception>
 /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><see cref="AsymmetricSecurityKey"/>' is too small.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><see cref="SymmetricSecurityKey"/> is too small.</exception>
 /// <exception cref="ArgumentException"><see cref="SecurityKey"/> is not a <see cref="AsymmetricSecurityKey"/> or a <see cref="SymmetricSecurityKey"/>.</exception>
 /// <remarks>
 /// AsymmetricSignatureProviders require access to a PrivateKey for Signing.
 /// <para>When finished with the <see cref="SignatureProvider"/> call <see cref="ReleaseSignatureProvider(SignatureProvider)"/>.</para>
 /// </remarks>
 public virtual SignatureProvider CreateForSigning(SecurityKey key, string algorithm)
 {
     return(CreateSignatureProvider(key, algorithm, true));
 }
 /// <summary>
 /// Creates an instance of <see cref="KeyWrapProvider"/> 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="KeyWrapProvider"/></returns>
 /// <exception cref="ArgumentNullException">'key' is null.</exception>
 /// <exception cref="ArgumentNullException">'algorithm' is null or empty.</exception>
 /// <exception cref="ArgumentException">If <see cref="SecurityKey"/> and algorithm pair are not supported.</exception>
 /// <exception cref="ArgumentException">'key' is not a <see cref="SymmetricSecurityKey"/>.</exception>
 /// <remarks>
 /// <para>When finished with the <see cref="KeyWrapProvider"/> call <see cref="ReleaseKeyWrapProvider(KeyWrapProvider)"/>.</para>
 /// </remarks>
 public virtual KeyWrapProvider CreateKeyWrapProvider(SecurityKey key, string algorithm)
 {
     return(CreateKeyWrapProvider(key, algorithm, false));
 }
        /// <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(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10646, algorithm, key, typeof(AuthenticatedEncryptionProvider))));
                }

                return(cryptoProvider);
            }

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

            throw LogHelper.LogExceptionMessage(new ArgumentException(nameof(algorithm), string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10652, 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(IsRsaAlgorithmSupported(algorithm));
            }

            var x509Key = key as X509SecurityKey;

            if (x509Key != null)
            {
#if NETSTANDARD1_4
                if (x509Key.PublicKey as RSA == null)
                {
                    return(false);
                }
#else
                if (x509Key.PublicKey as RSACryptoServiceProvider == null)
                {
                    return(false);
                }
#endif
                return(IsRsaAlgorithmSupported(algorithm));
            }

            JsonWebKey jsonWebKey = key as JsonWebKey;
            if (jsonWebKey != null)
            {
                if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
                {
                    return(IsRsaAlgorithmSupported(algorithm));
                }
                else if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                {
                    return(IsEcdsaAlgorithmSupported(algorithm));
                }
                else if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                {
                    return(IsSymmetricAlgorithmSupported(algorithm));
                }

                return(false);
            }

            ECDsaSecurityKey ecdsaSecurityKey = key as ECDsaSecurityKey;
            if (ecdsaSecurityKey != null)
            {
                return(IsEcdsaAlgorithmSupported(algorithm));
            }

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

            return(false);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AsymmetricSignatureProvider"/> class used to create and verify signatures.
 /// </summary>
 /// <param name="key">The <see cref="SecurityKey"/> that will be used for signature operations.<see cref="SecurityKey"/></param>
 /// <param name="algorithm">The signature algorithm to apply.</param>
 public AsymmetricSignatureProvider(SecurityKey key, string algorithm)
     : this(key, algorithm, false)
 {
 }