Esempio n. 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RsaKeyWrapProvider"/> class used for wrap key and unwrap key.
        /// <param name="key">The <see cref="SecurityKey"/> that will be used for crypto operations.</param>
        /// <param name="algorithm">The KeyWrap algorithm to apply.</param>
        /// <param name="willUnwrap">Whether this <see cref="RsaKeyWrapProvider"/> is required to create decrypts then set this to true.</param>
        /// <exception cref="ArgumentNullException">'key' is null.</exception>
        /// <exception cref="ArgumentNullException">'algorithm' is null.</exception>
        /// <exception cref="ArgumentException">The keysize doesn't match the algorithm.</exception>
        /// <exception cref="ArgumentException">If <see cref="SecurityKey"/> and algorithm pair are not supported.</exception>
        /// <exception cref="InvalidOperationException">Failed to create RSA algorithm with provided key and algorithm.</exception>
        /// </summary>
        public RsaKeyWrapProvider(SecurityKey key, string algorithm, bool willUnwrap)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

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

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

            Algorithm = algorithm;
            Key       = key;

            var rsaAlgorithm = Utility.ResolveRsaAlgorithm(key, algorithm, willUnwrap);

#if NETSTANDARD1_4
            if (rsaAlgorithm != null && rsaAlgorithm.rsa != null)
            {
                _rsa        = rsaAlgorithm.rsa;
                _disposeRsa = rsaAlgorithm.dispose;
                return;
            }
#else
            if (rsaAlgorithm != null)
            {
                if (rsaAlgorithm.rsaCryptoServiceProvider != null)
                {
                    _rsaCryptoServiceProvider = rsaAlgorithm.rsaCryptoServiceProvider;
                    _disposeRsa = rsaAlgorithm.dispose;
                    return;
                }

                if (rsaAlgorithm.rsaCryptoServiceProviderProxy != null)
                {
                    _rsaCryptoServiceProviderProxy = rsaAlgorithm.rsaCryptoServiceProviderProxy;
                    _disposeRsa = rsaAlgorithm.dispose;
                    return;
                }
            }
#endif
            throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10661, algorithm, key)));
        }
Esempio n. 2
0
        private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException("key");
            }

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

            _hashAlgorithm = GetHashAlgorithmString(algorithm);
            RsaAlgorithm rsaAlgorithm = Utility.ResolveRsaAlgorithm(key, algorithm, willCreateSignatures);

            if (rsaAlgorithm != null)
            {
                if (rsaAlgorithm.rsaCryptoServiceProvider != null)
                {
                    _rsaCryptoServiceProvider = rsaAlgorithm.rsaCryptoServiceProvider;
                    _disposeRsa = rsaAlgorithm.dispose;
                    return;
                }
                else if (rsaAlgorithm.rsaCryptoServiceProviderProxy != null)
                {
                    _rsaCryptoServiceProviderProxy = rsaAlgorithm.rsaCryptoServiceProviderProxy;
                    _disposeRsa = rsaAlgorithm.dispose;
                    return;
                }
                else
                {
                    throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10641, key)));
                }
            }

            ECDsaAlgorithm ecdsaAlgorithm = Utility.ResolveECDsaAlgorithm(key, algorithm, willCreateSignatures);

            if (ecdsaAlgorithm != null && ecdsaAlgorithm.ecdsaCng != null)
            {
                _ecdsa = ecdsaAlgorithm.ecdsaCng;
                _ecdsa.HashAlgorithm = new CngAlgorithm(_hashAlgorithm);
                _disposeEcdsa        = ecdsaAlgorithm.dispose;
                return;
            }

            throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10641, key)));
        }
Esempio n. 3
0
        private void InitializeUsingRsa(RSA rsa, string algorithm)
        {
#if NET461 || NETSTANDARD2_0
            if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature, StringComparison.Ordinal))
            {
                RSASignaturePadding = RSASignaturePadding.Pss;
            }
            else
            {
                // default RSASignaturePadding for other supported RSA algorithms is Pkcs1
                RSASignaturePadding = RSASignaturePadding.Pkcs1;
            }
#endif

            // This case is the result of a calling
            // X509Certificate2.GetPrivateKey OR X509Certificate2.GetPublicKey.Key
            // These calls return an AsymmetricAlgorithm which doesn't have API's to do much and need to be cast.
            // RSACryptoServiceProvider is wrapped to support SHA2
            // RSACryptoServiceProviderProxy is only supported on Windows platform
#if DESKTOP
            _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) ||
                                 algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal);

            if (rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
            {
                RsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCryptoServiceProvider);
                SignatureFunction             = SignWithRsaCryptoServiceProviderProxy;
                VerifyFunction = VerifyWithRsaCryptoServiceProviderProxy;
                // RSACryptoServiceProviderProxy will keep track of if it creates a new RSA object.
                // Only if a new RSA was creaated, RSACryptoServiceProviderProxy will call RSA.Dispose().
                _disposeCryptoOperators = true;
                return;
            }
#endif

            // This case required the user to get a RSA object by calling
            // X509Certificate2.GetRSAPrivateKey() OR X509Certificate2.GetRSAPublicKey()
            // This requires 4.6+ to be installed. If a dependent library is targeting 4.5, 4.5.1, 4.5.2 or 4.6
            // they will use Net45, but the type is RSACng.
            // The 'lightup' code will bind to the correct operators.
#if NET45
            else if (rsa.GetType().ToString().Equals(_rsaCngTypeName, StringComparison.Ordinal) && IsRsaCngSupported())
            {
                _lightUpHashAlgorithmName = GetLightUpHashAlgorithmName();
                SignatureFunction         = Pkcs1SignData;
                VerifyFunction            = Pkcs1VerifyData;
                return;
            }
            else
            {
                // In NET45 we only support RSACryptoServiceProvider or "System.Security.Cryptography.RSACng"
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10687, typeof(RSACryptoServiceProvider).ToString(), _rsaCngTypeName, rsa.GetType().ToString())));
            }
#endif

#if NET461 || NETSTANDARD2_0
            // Here we can use RSA straight up.
            _rsaEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal))
                        ? RSAEncryptionPadding.OaepSHA1
                        : RSAEncryptionPadding.Pkcs1;
            RSA = rsa;
            SignatureFunction = SignWithRsa;
            VerifyFunction    = VerifyWithRsa;
#endif
        }
Esempio n. 4
0
 public RsaAlgorithm(RSACryptoServiceProviderProxy rsaCryptoServiceProviderProxy)
 {
     RsaCryptoServiceProviderProxy = rsaCryptoServiceProviderProxy;
 }
Esempio n. 5
0
        private void InitializeUsingRsa(RSA rsa, string algorithm)
        {
            // The return value for X509Certificate2.GetPrivateKey OR X509Certificate2.GetPublicKey.Key is a RSACryptoServiceProvider
            // These calls return an AsymmetricAlgorithm which doesn't have API's to do much and need to be cast.
            // RSACryptoServiceProvider is wrapped with RSACryptoServiceProviderProxy as some CryptoServideProviders (CSP's) do
            // not natively support SHA2.
#if DESKTOP
            if (rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
            {
                _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP) ||
                                     algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap);

                RsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCryptoServiceProvider);
                DecryptFunction   = DecryptWithRsaCryptoServiceProviderProxy;
                EncryptFunction   = EncryptWithRsaCryptoServiceProviderProxy;
                SignatureFunction = SignWithRsaCryptoServiceProviderProxy;
                VerifyFunction    = VerifyWithRsaCryptoServiceProviderProxy;

                // RSACryptoServiceProviderProxy will track if a new RSA object is created and dispose appropriately.
                _disposeCryptoOperators = true;
                return;
            }
#endif

#if NET45
            // This case required the user to get a RSA object by calling
            // X509Certificate2.GetRSAPrivateKey() OR X509Certificate2.GetRSAPublicKey()
            // This requires 4.6+ to be installed. If a dependent library is targeting 4.5, 4.5.1, 4.5.2 or 4.6
            // they will bind to our Net45 target, but the type is RSACng.
            // The 'lightup' code will bind to the correct operators.
            else if (rsa.GetType().ToString().Equals(_rsaCngTypeName) && IsRsaCngSupported())
            {
                _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP) ||
                                     algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap);

                _lightUpHashAlgorithmName = GetLightUpHashAlgorithmName();
                DecryptFunction           = DecryptNet45;
                EncryptFunction           = EncryptNet45;
                SignatureFunction         = Pkcs1SignData;
                VerifyFunction            = Pkcs1VerifyData;
                RSA = rsa;
                return;
            }
            else
            {
                // In NET45 we only support RSACryptoServiceProvider or "System.Security.Cryptography.RSACng"
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10687, LogHelper.MarkAsNonPII(typeof(RSACryptoServiceProvider).ToString()), LogHelper.MarkAsNonPII(_rsaCngTypeName), LogHelper.MarkAsNonPII(rsa.GetType().ToString()))));
            }
#endif

#if NET461 || NET472 || NETSTANDARD2_0
            if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512) ||
                algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature))
            {
                RSASignaturePadding = RSASignaturePadding.Pss;
            }
            else
            {
                // default RSASignaturePadding for other supported RSA algorithms is Pkcs1
                RSASignaturePadding = RSASignaturePadding.Pkcs1;
            }

            RSAEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap))
                        ? RSAEncryptionPadding.OaepSHA1
                        : RSAEncryptionPadding.Pkcs1;
            RSA               = rsa;
            DecryptFunction   = DecryptWithRsa;
            EncryptFunction   = EncryptWithRsa;
            SignatureFunction = SignWithRsa;
            VerifyFunction    = VerifyWithRsa;
#endif
        }
Esempio n. 6
0
        private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException("key");
            }

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

            _hashAlgorithm = GetHashAlgorithmString(algorithm);
            RsaSecurityKey rsaKey = key as RsaSecurityKey;

            if (rsaKey != null)
            {
                if (rsaKey.Rsa != null)
                {
                    _rsaCryptoServiceProvider = rsaKey.Rsa as RSACryptoServiceProvider;
                }

                if (_rsaCryptoServiceProvider == null)
                {
                    _rsaCryptoServiceProvider = new RSACryptoServiceProvider();
                    (_rsaCryptoServiceProvider as RSA).ImportParameters(rsaKey.Parameters);
                    _disposeRsa = true;
                }
                return;
            }

            X509SecurityKey x509Key = key as X509SecurityKey;

            if (x509Key != null)
            {
                if (willCreateSignatures)
                {
                    _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PrivateKey as RSACryptoServiceProvider);
                }
                else
                {
                    _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PublicKey as RSACryptoServiceProvider);
                }
                return;
            }

            ECDsaSecurityKey ecdsaKey = key as ECDsaSecurityKey;

            if (ecdsaKey != null)
            {
                if (ecdsaKey.ECDsa != null)
                {
                    _ecdsa = ecdsaKey.ECDsa as ECDsaCng;
                    _ecdsa.HashAlgorithm = new CngAlgorithm(_hashAlgorithm);
                    return;
                }
            }

            JsonWebKey webKey = key as JsonWebKey;

            if (webKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
            {
                RSAParameters parameters = CreateRsaParametersFromJsonWebKey(webKey, willCreateSignatures);
                _rsaCryptoServiceProvider = new RSACryptoServiceProvider();
                (_rsaCryptoServiceProvider as RSA).ImportParameters(parameters);
                return;
            }
            else if (webKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
            {
                CreateECDsaFromJsonWebKey(webKey, willCreateSignatures);
                return;
            }

            throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10641, key)));
        }
        private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException("key");
            }

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

            _hashAlgorithm = GetHashAlgorithmName(algorithm);
            RsaSecurityKey rsaKey = key as RsaSecurityKey;

            if (rsaKey != null)
            {
                if (rsaKey.Rsa != null)
                {
                    _rsa = rsaKey.Rsa;
                    return;
                }

                _rsa = RSA.Create();
                if (_rsa != null)
                {
                    _rsa.ImportParameters(rsaKey.Parameters);
                    _disposeRsa = true;
                    return;
                }
            }

            X509SecurityKey x509Key = key as X509SecurityKey;

            if (x509Key != null)
            {
                if (willCreateSignatures)
                {
                    RSACryptoServiceProvider rsaCsp = x509Key.PrivateKey as RSACryptoServiceProvider;
                    if (rsaCsp != null)
                    {
                        _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCsp);
                    }
                    else
                    {
                        _rsa = x509Key.PrivateKey as RSA;
                    }
                }
                else
                {
                    _rsa = x509Key.PublicKey as RSA;
                }

                return;
            }

            ECDsaSecurityKey ecdsaKey = key as ECDsaSecurityKey;

            if (ecdsaKey != null)
            {
                if (ecdsaKey.ECDsa != null)
                {
                    _ecdsa = ecdsaKey.ECDsa;
                    return;
                }
            }

            JsonWebKey webKey = key as JsonWebKey;

            if (webKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
            {
                RSAParameters parameters = CreateRsaParametersFromJsonWebKey(webKey, willCreateSignatures);

                _rsa = RSA.Create();
                if (_rsa != null)
                {
                    _rsa.ImportParameters(parameters);
                    _disposeRsa = true;
                    return;
                }
            }
            else if (webKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
            {
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    throw new PlatformNotSupportedException();
                }

                CreateECDsaFromJsonWebKey(webKey, willCreateSignatures);
                return;
            }

            throw LogHelper.LogArgumentException <ArgumentOutOfRangeException>(nameof(key), LogMessages.IDX10641, key);
        }