internal static bool TryConvertToX509SecurityKey(JsonWebKey webKey, out SecurityKey key)
        {
            if (webKey.ConvertedSecurityKey is X509SecurityKey)
            {
                key = webKey.ConvertedSecurityKey;
                return(true);
            }

            key = null;
            if (webKey.X5c == null || webKey.X5c.Count == 0)
            {
                return(false);
            }

            try
            {
                // only the first certificate should be used to perform signing operations
                // https://datatracker.ietf.org/doc/html/rfc7517#section-4.7
                key = new X509SecurityKey(webKey);
                return(true);
            }
            catch (Exception ex)
            {
                string convertKeyInfo = LogHelper.FormatInvariant(LogMessages.IDX10813, LogHelper.MarkAsNonPII(typeof(X509SecurityKey)), webKey, ex);
                webKey.ConvertKeyInfo = convertKeyInfo;
                LogHelper.LogExceptionMessage(new InvalidOperationException(convertKeyInfo, ex));
            }

            return(false);
        }
示例#2
0
        /// <summary>
        /// Validates the <see cref="SecurityKey"/> that signed a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="securityKey">The <see cref="SecurityKey"/> that signed the <see cref="SecurityToken"/>.</param>
        /// <param name="securityToken">The <see cref="SecurityToken"/> being validated.</param>
        /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
        /// <exception cref="ArgumentNullException"> if 'securityKey' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'securityToken' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'vaidationParameters' is null.</exception>
        public static void ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(validationParameters));
            }

            if (!validationParameters.ValidateIssuerSigningKey)
            {
                IdentityModelEventSource.Logger.WriteInformation(LogMessages.IDX10237);
                return;
            }

            if (securityKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityKey));
            }

            if (securityToken == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityToken));
            }

            X509SecurityKey x509SecurityKey = securityKey as X509SecurityKey;

            if (x509SecurityKey != null)
            {
                //validationParameters.CertificateValidator.Validate(x509SecurityKey.Certificate);
            }
        }
        private static bool Matches(SecurityKeyIdentifierClause keyIdentifierClause, SecurityKey key, CertMatcher certMatcher, out SecurityToken token)
        {
            token = null;
            if (certMatcher != null)
            {
                X509SecurityKey x509Key = key as X509SecurityKey;
                if (x509Key != null)
                {
                    if (certMatcher(x509Key.Certificate))
                    {
                        token = new X509SecurityToken(x509Key.Certificate);
                        return(true);
                    }
                }
                else
                {
                    X509AsymmetricSecurityKey x509AsymmKey = key as X509AsymmetricSecurityKey;
                    if (x509AsymmKey != null)
                    {
                        X509Certificate2 cert = _certFieldInfo.GetValue(x509AsymmKey) as X509Certificate2;
                        if (cert != null && certMatcher(cert))
                        {
                            token = new X509SecurityToken(cert);
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Converts a <see cref="X509SecurityKey"/> into a <see cref="JsonWebKey"/>.
        /// </summary>
        /// <param name="key">a <see cref="X509SecurityKey"/> to convert.</param>
        /// <param name="representAsRsaKey">
        /// <c>true</c> to represent the <paramref name="key"/> as an <see cref="RsaSecurityKey"/>,
        /// <c>false</c> to represent the <paramref name="key"/> as an <see cref="X509SecurityKey"/>, using the "x5c" parameter.
        /// </param>
        /// <returns>a <see cref="JsonWebKey"/>.</returns>
        /// <exception cref="ArgumentNullException">if <paramref name="key"/>is null.</exception>
        public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key, bool representAsRsaKey)
        {
            if (!representAsRsaKey)
            {
                return(ConvertFromX509SecurityKey(key));
            }

            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            RSA rsaKey;

            if (key.PrivateKeyStatus == PrivateKeyStatus.Exists)
            {
                rsaKey = key.PrivateKey as RSA;
            }
            else
            {
                rsaKey = key.PublicKey as RSA;
            }

            return(ConvertFromRSASecurityKey(new RsaSecurityKey(rsaKey)
            {
                KeyId = key.KeyId
            }));
        }
        /// <summary>
        /// Converts a X509 Certificate to Microsoft JWK.
        /// </summary>
        public static MSTokens.JsonWebKey ToMSJsonWebKey(this X509Certificate2 certificate, bool includePrivateKey = false)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var jwk = new MSTokens.JsonWebKey();

            jwk.Kty = MSTokens.JsonWebAlgorithmsKeyTypes.RSA;

            var securityKey = new MSTokens.X509SecurityKey(certificate);

            jwk.X5c.Add(Convert.ToBase64String(certificate.RawData));
            jwk.X5t = certificate.Thumbprint;
            jwk.Kid = WebEncoders.Base64UrlEncode(certificate.GetCertHash());

            var parameters = (securityKey.PublicKey as RSA).ExportParameters(false);

            jwk.N = WebEncoders.Base64UrlEncode(parameters.Modulus);
            jwk.E = WebEncoders.Base64UrlEncode(parameters.Exponent);

            if (includePrivateKey && securityKey.PrivateKeyStatus == MSTokens.PrivateKeyStatus.Exists)
            {
                parameters = (securityKey.PrivateKey as RSA).ExportParameters(true);
                jwk.D      = WebEncoders.Base64UrlEncode(parameters.D);
                jwk.P      = WebEncoders.Base64UrlEncode(parameters.P);
                jwk.Q      = WebEncoders.Base64UrlEncode(parameters.Q);
                jwk.DP     = WebEncoders.Base64UrlEncode(parameters.DP);
                jwk.DQ     = WebEncoders.Base64UrlEncode(parameters.DQ);
                jwk.QI     = WebEncoders.Base64UrlEncode(parameters.InverseQ);
            }
            return(jwk);
        }
示例#6
0
        /// <summary>
        /// Validates the <see cref="SecurityKey"/> that signed a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="securityKey">The <see cref="SecurityKey"/> that signed the <see cref="SecurityToken"/>.</param>
        /// <param name="securityToken">The <see cref="SecurityToken"/> being validated.</param>
        /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
        /// <exception cref="ArgumentNullException"> if 'securityKey' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'securityToken' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'vaidationParameters' is null.</exception>
        public static void ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(validationParameters));
            }

            if (!validationParameters.ValidateIssuerSigningKey)
            {
                LogHelper.LogInformation(LogMessages.IDX10237);
                return;
            }

            if (validationParameters.IssuerSigningKeyValidator != null)
            {
                if (!validationParameters.IssuerSigningKeyValidator(securityKey, securityToken, validationParameters))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10232, securityKey))
                    {
                        SigningKey = securityKey
                    });
                }
            }

            if (securityKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityKey));
            }

            if (securityToken == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityToken));
            }

            X509SecurityKey x509SecurityKey = securityKey as X509SecurityKey;

            if (x509SecurityKey?.Certificate is X509Certificate2 cert)
            {
                DateTime utcNow       = DateTime.UtcNow;
                var      notBeforeUtc = cert.NotBefore.ToUniversalTime();
                var      notAfterUtc  = cert.NotAfter.ToUniversalTime();

                if (notBeforeUtc > DateTimeUtil.Add(utcNow, validationParameters.ClockSkew))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10248, notBeforeUtc, utcNow)));
                }

                LogHelper.LogInformation(LogMessages.IDX10250, notBeforeUtc, utcNow);

                if (notAfterUtc < DateTimeUtil.Add(utcNow, validationParameters.ClockSkew.Negate()))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10249, notAfterUtc, utcNow)));
                }

                LogHelper.LogInformation(LogMessages.IDX10251, notAfterUtc, utcNow);
            }
        }
示例#7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SigningCredentials"/> class.
        /// </summary>
        /// <param name="certificate"><see cref="X509Certificate2"/> that will be used for signing.</param>
        /// <param name="algorithm">The signature algorithm to apply.</param>
        /// <remarks>the 'digest method' if needed may be implied from the algorithm. For example <see cref="SecurityAlgorithms.RsaSha256"/> implies Sha256.</remarks>
        /// <exception cref="ArgumentNullException">if 'certificate' is null.</exception>
        /// <exception cref="ArgumentNullException">if 'algorithm' is null or empty.</exception>
        protected SigningCredentials(X509Certificate2 certificate, string algorithm)
        {
            if (certificate == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(certificate));
            }

            Key       = new X509SecurityKey(certificate);
            Algorithm = algorithm;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EncryptingCredentials"/> class.
        /// </summary>
        /// <param name="certificate"><see cref="X509Certificate2"/>.</param>
        /// <param name="alg">A key wrap algorithm to use when encrypting a session key.</param>
        /// <param name="enc">Data encryption algorithm to apply.</param>
        /// <exception cref="ArgumentNullException">if 'certificate' is null.</exception>
        /// <exception cref="ArgumentNullException">if 'alg' is null or empty.</exception>
        /// <exception cref="ArgumentNullException">if 'enc' is null or empty.</exception>
        protected EncryptingCredentials(X509Certificate2 certificate, string alg, string enc)
        {
            if (certificate == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(certificate));
            }

            Key = new X509SecurityKey(certificate);
            Alg = alg;
            Enc = enc;
        }
示例#9
0
 private void InitializeUsingX509SecurityKey(X509SecurityKey x509SecurityKey, string algorithm, bool requirePrivateKey)
 {
     if (requirePrivateKey)
     {
         InitializeUsingRsa(x509SecurityKey.PrivateKey as RSA, algorithm);
     }
     else
     {
         InitializeUsingRsa(x509SecurityKey.PublicKey as RSA, algorithm);
     }
 }
        /// <summary>
        /// Returns a bool indicating if this key is equivalent to another key.
        /// </summary>
        /// <return>true if the keys are equal; otherwise, false.</return>
        public override bool Equals(object obj)
        {
            X509SecurityKey other = obj as X509SecurityKey;

            if (other == null)
            {
                return(false);
            }

            return(other.Certificate.Thumbprint.ToString() == _certificate.Thumbprint.ToString());
        }
示例#11
0
        /// <summary>
        /// Validates the <see cref="SecurityKey"/> that signed a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="securityKey">The <see cref="SecurityKey"/> that signed the <see cref="SecurityToken"/>.</param>
        /// <param name="securityToken">The <see cref="SecurityToken"/> being validated.</param>
        /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
        /// <exception cref="ArgumentNullException"> if 'securityKey' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'securityToken' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'vaidationParameters' is null.</exception>
        public static void ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(validationParameters));
            }

            if (!validationParameters.ValidateIssuerSigningKey)
            {
                LogHelper.LogInformation(LogMessages.IDX10237);
                return;
            }

            if (validationParameters.IssuerSigningKeyValidator != null)
            {
                if (!validationParameters.IssuerSigningKeyValidator(securityKey, securityToken, validationParameters))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10232, securityKey))
                    {
                        SigningKey = securityKey
                    });
                }
            }

            if (securityKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityKey));
            }

            if (securityToken == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityToken));
            }

            X509SecurityKey x509SecurityKey = securityKey as X509SecurityKey;

            if (x509SecurityKey != null)
            {
                var      cert   = x509SecurityKey.Certificate;
                DateTime utcNow = DateTime.UtcNow;

                if (cert.NotBefore != null && (cert.NotBefore > DateTimeUtil.Add(utcNow, validationParameters.ClockSkew)))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10248, cert.NotBefore, utcNow)));
                }

                if (cert.NotAfter != null && (cert.NotAfter < DateTimeUtil.Add(utcNow, validationParameters.ClockSkew.Negate())))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10249, cert.NotAfter, utcNow)));
                }
            }
        }
        /// <summary>
        /// Convert X509 security key into json web key.
        /// </summary>
        /// <param name="key">X509 security key</param>
        /// <returns>json web key</returns>
        public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key)
        {
            var jsonWebKey = new JsonWebKey();

            jsonWebKey.Kty = JsonWebAlgorithmsKeyTypes.RSA;
            jsonWebKey.Kid = key.KeyId;
            jsonWebKey.X5t = key.X5t;
            if (key.Certificate.RawData != null)
            {
                jsonWebKey.X5c.Add(Convert.ToBase64String(key.Certificate.RawData));
            }
            return(jsonWebKey);
        }
示例#13
0
        private static JwtSecurityToken GenerateJWTFromX509()
        {
            var securityKey = new Microsoft.IdentityModel.Tokens.X509SecurityKey(GetByThumbprint("YOUR-CERT-THUMBPRINT-HERE"));
            var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, "RS256");
            var JWTHeader   = new JwtHeader(credentials);
            var payload     = new JwtPayload {
                { "iss", "Issuer-here" },
                { "exp", (Int32)(DateTime.UtcNow.AddHours(1).Subtract(new DateTime(1970, 1, 1))).TotalSeconds },
                { "iat", (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds }
            };
            var token = new JwtSecurityToken(JWTHeader, payload);

            return(token);
        }
        private bool IsSupportedKeyWrapAlgorithm(string algorithm, SecurityKey key)
        {
            if (key == null)
            {
                return(false);
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                return(false);
            }

            if (algorithm.Equals(SecurityAlgorithms.RsaPKCS1, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) ||
                algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal))
            {
                if (key is RsaSecurityKey)
                {
                    return(true);
                }

                X509SecurityKey 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
                }

                var jsonWebKey = key as JsonWebKey;
                if (jsonWebKey != null && jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
                {
                    return(true);
                }

                return(false);
            }

            return(false);
        }
示例#15
0
        /// <summary>
        /// Converts a <see cref="X509SecurityKey"/> into a <see cref="JsonWebKey"/>
        /// </summary>
        /// <param name="key">a <see cref="X509SecurityKey"/> to convert.</param>
        /// <returns>a <see cref="JsonWebKey"/></returns>
        /// <exception cref="ArgumentNullException">if <paramref name="key"/>is null.</exception>
        public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            var jsonWebKey = new JsonWebKey();

            jsonWebKey.Kty = JsonWebAlgorithmsKeyTypes.RSA;
            jsonWebKey.Kid = key.KeyId;
            jsonWebKey.X5t = key.X5t;
            if (key.Certificate.RawData != null)
            {
                jsonWebKey.X5c.Add(Convert.ToBase64String(key.Certificate.RawData));
            }

            return(jsonWebKey);
        }
示例#16
0
        public string generateJWT(SymConfig config)
        {
            string   jwt       = "";
            DateTime otherTime = DateTime.Now.AddMinutes(4);

            var payload = new JwtPayload
            {
                { "sub", config.botUsername },
                { "exp", ToUtcSeconds(otherTime) }
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var certificate  = new X509Certificate2(config.botPrivateKeyPath + config.botPrivateKeyName, "changeit");
            var securityKey  = new Microsoft.IdentityModel.Tokens.X509SecurityKey(certificate);
            var credentials  = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, SecurityAlgorithms.RsaSha512);
            var header       = new JwtHeader(credentials);
            var secToken     = new JwtSecurityToken(header, payload);
            var handler      = new JwtSecurityTokenHandler();

            var tokenString = handler.WriteToken(secToken);

            return(tokenString);
        }
        public static JwtSecurityToken CreateToken(
            string issuer              = null,
            string audience            = null,
            IEnumerable <string> scope = null,
            int ttl = 360,
            List <Claim> additionalClaims       = null,
            X509Certificate2 signingCertificate = null)
        {
            if (signingCertificate == null)
            {
                signingCertificate = DefaultSigningCertificate;
            }

            if (additionalClaims == null)
            {
                additionalClaims = new List <Claim>();
            }

            if (scope != null && scope.Any())
            {
                scope.ToList().ForEach(s => additionalClaims.Add(new Claim("scope", s)));
            }

            var key        = new Microsoft.IdentityModel.Tokens.X509SecurityKey(signingCertificate);
            var credential = new Microsoft.IdentityModel.Tokens.SigningCredentials(key, SecurityAlgorithms.RsaSha256);

            var token = new JwtSecurityToken(
                issuer ?? DefaultIssuer,
                audience ?? DefaultAudience,
                additionalClaims,
                DateTime.UtcNow,
                DateTime.UtcNow.AddSeconds(ttl),
                credential);

            return(token);
        }
示例#18
0
        internal static RsaAlgorithm ResolveRsaAlgorithm(SecurityKey key, string algorithm, bool requirePrivateKey)
        {
            if (key == null)
            {
                return(null);
            }

            var rsaAlgorithm = new RsaAlgorithm();
            var rsaKey       = key as RsaSecurityKey;

            if (rsaKey != null)
            {
                if (rsaKey.Rsa != null)
                {
#if NETSTANDARD1_4
                    rsaAlgorithm.rsa = rsaKey.Rsa;
#else
                    rsaAlgorithm.rsaCryptoServiceProvider = rsaKey.Rsa as RSACryptoServiceProvider;
#endif
                    return(rsaAlgorithm);
                }
                else
                {
#if NETSTANDARD1_4
                    rsaAlgorithm.rsa = RSA.Create();
                    rsaAlgorithm.rsa.ImportParameters(rsaKey.Parameters);
                    rsaAlgorithm.dispose = true;
#else
                    rsaAlgorithm.rsaCryptoServiceProvider = new RSACryptoServiceProvider();
                    (rsaAlgorithm.rsaCryptoServiceProvider as RSA).ImportParameters(rsaKey.Parameters);
                    rsaAlgorithm.dispose = true;
#endif
                }

                return(rsaAlgorithm);
            }

            X509SecurityKey x509Key = key as X509SecurityKey;
            if (x509Key != null)
            {
#if NETSTANDARD1_4
                if (requirePrivateKey)
                {
                    rsaAlgorithm.rsa = x509Key.PrivateKey as RSA;
                }
                else
                {
                    rsaAlgorithm.rsa = x509Key.PublicKey as RSA;
                }
#else
                if (requirePrivateKey)
                {
                    rsaAlgorithm.rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PrivateKey as RSACryptoServiceProvider);
                }
                else
                {
                    rsaAlgorithm.rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PublicKey as RSACryptoServiceProvider);
                }
#endif
                return(rsaAlgorithm);
            }

            JsonWebKey webKey = key as JsonWebKey;
            if (webKey != null && webKey.Kty == JsonWebAlgorithmsKeyTypes.RSA)
            {
#if NETSTANDARD1_4
                RSAParameters parameters = webKey.CreateRsaParameters();
                rsaAlgorithm.rsa     = RSA.Create();
                rsaAlgorithm.dispose = true;
                if (rsaAlgorithm.rsa != null)
                {
                    rsaAlgorithm.rsa.ImportParameters(parameters);
                }
#else
                RSAParameters parameters = webKey.CreateRsaParameters();
                rsaAlgorithm.rsaCryptoServiceProvider = new RSACryptoServiceProvider();
                (rsaAlgorithm.rsaCryptoServiceProvider as RSA).ImportParameters(parameters);
#endif
                return(rsaAlgorithm);
            }

            return(null);
        }
示例#19
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)));
        }
        /// <summary>
        /// Returns the JsonWebKeys as a <see cref="IList{SecurityKey}"/>.
        /// </summary>
        public IList <SecurityKey> GetSigningKeys()
        {
            List <SecurityKey> keys = new List <SecurityKey>();

            for (int i = 0; i < Keys.Count; i++)
            {
                JsonWebKey webKey = Keys[i];

                if (!StringComparer.Ordinal.Equals(webKey.Kty, JsonWebAlgorithmsKeyTypes.RSA))
                {
                    continue;
                }

                if ((string.IsNullOrWhiteSpace(webKey.Use) || (StringComparer.Ordinal.Equals(webKey.Use, JsonWebKeyUseNames.Sig))))
                {
                    if (webKey.X5c != null)
                    {
                        foreach (var certString in webKey.X5c)
                        {
                            try
                            {
                                // Add chaining
                                SecurityKey key = new X509SecurityKey(new X509Certificate2(Convert.FromBase64String(certString)));
                                key.KeyId = webKey.Kid;
                                keys.Add(key);
                            }
                            catch (CryptographicException ex)
                            {
                                throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10802, webKey.X5c[0]), ex));
                            }
                            catch (FormatException fex)
                            {
                                throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10802, webKey.X5c[0]), fex));
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(webKey.E) && !string.IsNullOrWhiteSpace(webKey.N))
                    {
                        try
                        {
                            SecurityKey key =
                                new RsaSecurityKey
                                (
                                    new RSAParameters
                            {
                                Exponent = Base64UrlEncoder.DecodeBytes(webKey.E),
                                Modulus  = Base64UrlEncoder.DecodeBytes(webKey.N),
                            }

                                );
                            key.KeyId = webKey.Kid;
                            keys.Add(key);
                        }
                        catch (CryptographicException ex)
                        {
                            throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10801, webKey.E, webKey.N), ex));
                        }
                        catch (FormatException ex)
                        {
                            throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10801, webKey.E, webKey.N), ex));
                        }
                    }
                }
            }

            return(keys);
        }
        /// <summary>
        /// Validates the <see cref="SecurityKey"/> that signed a <see cref="SecurityToken"/>.
        /// </summary>
        /// <param name="securityKey">The <see cref="SecurityKey"/> that signed the <see cref="SecurityToken"/>.</param>
        /// <param name="securityToken">The <see cref="SecurityToken"/> being validated.</param>
        /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
        /// <param name="configuration">The <see cref="BaseConfiguration"/> required for issuer and signing key validation.</param>
        /// <exception cref="ArgumentNullException"> if 'securityKey' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'securityToken' is null and ValidateIssuerSigningKey is true.</exception>
        /// <exception cref="ArgumentNullException"> if 'validationParameters' is null.</exception>
        internal static void ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
        {
            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(validationParameters));
            }

            if (validationParameters.IssuerSigningKeyValidatorUsingConfiguration != null)
            {
                if (!validationParameters.IssuerSigningKeyValidatorUsingConfiguration(securityKey, securityToken, validationParameters, configuration))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10232, securityKey))
                    {
                        SigningKey = securityKey
                    });
                }

                return;
            }

            if (validationParameters.IssuerSigningKeyValidator != null)
            {
                if (!validationParameters.IssuerSigningKeyValidator(securityKey, securityToken, validationParameters))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10232, securityKey))
                    {
                        SigningKey = securityKey
                    });
                }

                return;
            }

            if (!validationParameters.ValidateIssuerSigningKey)
            {
                LogHelper.LogInformation(LogMessages.IDX10237);
                return;
            }

            if (!validationParameters.RequireSignedTokens && securityKey == null)
            {
                LogHelper.LogInformation(LogMessages.IDX10252);
                return;
            }
            else if (securityKey == null)
            {
                throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(securityKey), LogMessages.IDX10253));
            }

            if (securityToken == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityToken));
            }

            X509SecurityKey x509SecurityKey = securityKey as X509SecurityKey;

            if (x509SecurityKey?.Certificate is X509Certificate2 cert)
            {
                DateTime utcNow       = DateTime.UtcNow;
                var      notBeforeUtc = cert.NotBefore.ToUniversalTime();
                var      notAfterUtc  = cert.NotAfter.ToUniversalTime();

                if (notBeforeUtc > DateTimeUtil.Add(utcNow, validationParameters.ClockSkew))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10248, LogHelper.MarkAsNonPII(notBeforeUtc), LogHelper.MarkAsNonPII(utcNow))));
                }

                LogHelper.LogInformation(LogMessages.IDX10250, LogHelper.MarkAsNonPII(notBeforeUtc), LogHelper.MarkAsNonPII(utcNow));

                if (notAfterUtc < DateTimeUtil.Add(utcNow, validationParameters.ClockSkew.Negate()))
                {
                    throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSigningKeyException(LogHelper.FormatInvariant(LogMessages.IDX10249, LogHelper.MarkAsNonPII(notAfterUtc), LogHelper.MarkAsNonPII(utcNow))));
                }

                LogHelper.LogInformation(LogMessages.IDX10251, LogHelper.MarkAsNonPII(notAfterUtc), LogHelper.MarkAsNonPII(utcNow));
            }
        }
        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);
        }