/// <summary>
        /// Convert RSA security key into json web key.
        /// </summary>
        /// <param name="key">RSA security key</param>
        /// <returns>json web key</returns>
        public static JsonWebKey ConvertFromRSASecurityKey(RsaSecurityKey key)
        {
            var jsonWebKey = new JsonWebKey();
            var parameters = new RSAParameters();

            jsonWebKey.Kty = JsonWebAlgorithmsKeyTypes.RSA;
            jsonWebKey.Kid = key.KeyId;

            // get Parameters
            if (key.Rsa != null)
            {
                parameters = key.Rsa.ExportParameters(true);
            }
            else
            {
                parameters = key.Parameters;
            }

            jsonWebKey.N = parameters.Modulus != null?Base64UrlEncoder.Encode(parameters.Modulus) : null;

            jsonWebKey.E = parameters.Exponent != null?Base64UrlEncoder.Encode(parameters.Exponent) : null;

            jsonWebKey.D = parameters.D != null?Base64UrlEncoder.Encode(parameters.D) : null;

            jsonWebKey.P = parameters.P != null?Base64UrlEncoder.Encode(parameters.P) : null;

            jsonWebKey.Q = parameters.Q != null?Base64UrlEncoder.Encode(parameters.Q) : null;

            jsonWebKey.DP = parameters.DP != null?Base64UrlEncoder.Encode(parameters.DP) : null;

            jsonWebKey.DQ = parameters.DQ != null?Base64UrlEncoder.Encode(parameters.DQ) : null;

            jsonWebKey.QI = parameters.InverseQ != null?Base64UrlEncoder.Encode(parameters.InverseQ) : null;

            return(jsonWebKey);
        }
        internal RSAParameters CreateRsaParameters()
        {
            if (string.IsNullOrEmpty(N))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10700, this, "Modulus")));
            }

            if (string.IsNullOrEmpty(E))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10700, this, "Exponent")));
            }

            return(new RSAParameters
            {
                Modulus = Base64UrlEncoder.DecodeBytes(N),
                Exponent = Base64UrlEncoder.DecodeBytes(E),
                D = string.IsNullOrEmpty(D) ? null : Base64UrlEncoder.DecodeBytes(D),
                P = string.IsNullOrEmpty(P) ? null : Base64UrlEncoder.DecodeBytes(P),
                Q = string.IsNullOrEmpty(Q) ? null : Base64UrlEncoder.DecodeBytes(Q),
                DP = string.IsNullOrEmpty(DP) ? null : Base64UrlEncoder.DecodeBytes(DP),
                DQ = string.IsNullOrEmpty(DQ) ? null : Base64UrlEncoder.DecodeBytes(DQ),
                InverseQ = string.IsNullOrEmpty(QI) ? null : Base64UrlEncoder.DecodeBytes(QI)
            });
        }
Example #3
0
        /// <summary>
        /// Computes a sha256 hash over the <see cref="RsaSecurityKey"/>.
        /// </summary>
        /// <returns>A JWK thumbprint.</returns>
        /// <remarks>https://tools.ietf.org/html/rfc7638</remarks>
        public override byte[] ComputeJwkThumbprint()
        {
            var rsaParameters = Parameters;

            if (rsaParameters.Exponent == null || rsaParameters.Modulus == null)
            {
                rsaParameters = Rsa.ExportParameters(false);
            }

            var canonicalJwk = $@"{{""{JsonWebKeyParameterNames.E}"":""{Base64UrlEncoder.Encode(rsaParameters.Exponent)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.RSA}"",""{JsonWebKeyParameterNames.N}"":""{Base64UrlEncoder.Encode(rsaParameters.Modulus)}""}}";

            return(Utility.GenerateSha256Hash(canonicalJwk));
        }
 /// <summary>
 /// Instantiates a <see cref="X509SecurityKey"/> using a <see cref="X509Certificate2"/>.
 /// </summary>
 /// <param name="certificate">The <see cref="X509Certificate2"/> to use.</param>
 /// <param name="keyId">The value to set for the KeyId</param>
 /// <exception cref="ArgumentNullException">if <paramref name="certificate"/> is null.</exception>
 /// <exception cref="ArgumentNullException">if <paramref name="keyId"/> is null or empty.</exception>
 public X509SecurityKey(X509Certificate2 certificate, string keyId)
 {
     Certificate = certificate ?? throw LogHelper.LogArgumentNullException(nameof(certificate));
     KeyId       = string.IsNullOrEmpty(keyId) ? throw LogHelper.LogArgumentNullException(nameof(keyId)) : keyId;
     X5t         = Base64UrlEncoder.Encode(certificate.GetCertHash());
 }
 /// <summary>
 /// Instantiates a <see cref="X509SecurityKey"/> using a <see cref="X509Certificate2"/>
 /// </summary>
 /// <param name="certificate">The <see cref="X509Certificate2"/> to use.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="certificate"/> is null.</exception>
 public X509SecurityKey(X509Certificate2 certificate)
 {
     Certificate = certificate ?? throw LogHelper.LogArgumentNullException(nameof(certificate));
     KeyId       = certificate.Thumbprint;
     X5t         = Base64UrlEncoder.Encode(certificate.GetCertHash());
 }
Example #6
0
        internal ECDsaCng CreateECDsa(string algorithm, bool usePrivateKey)
        {
            if (Crv == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(Crv));
            }

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

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

            GCHandle keyBlobHandle = new GCHandle();

            try
            {
                uint   dwMagic = GetMagicValue(Crv, usePrivateKey);
                uint   cbKey   = GetKeyByteCount(Crv);
                byte[] keyBlob;
                if (usePrivateKey)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }

                keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned);
                IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject();
                byte[] x          = Base64UrlEncoder.DecodeBytes(X);
                byte[] y          = Base64UrlEncoder.DecodeBytes(Y);

                Marshal.WriteInt64(keyBlobPtr, 0, dwMagic);
                Marshal.WriteInt64(keyBlobPtr, 4, cbKey);

                int index = 8;
                foreach (byte b in x)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                foreach (byte b in y)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

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

                    byte[] d = Base64UrlEncoder.DecodeBytes(D);
                    foreach (byte b in d)
                    {
                        Marshal.WriteByte(keyBlobPtr, index++, b);
                    }

                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob))
                    {
                        if (Utility.ValidateECDSAKeySize(cngKey.KeySize, algorithm))
                        {
                            return(new ECDsaCng(cngKey));
                        }
                        else
                        {
                            throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("key.KeySize", String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10671, cngKey, ECDsaAlgorithm.DefaultECDsaKeySizeInBitsMap[algorithm], cngKey.KeySize)));
                        }
                    }
                }
                else
                {
                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob))
                    {
                        if (Utility.ValidateECDSAKeySize(cngKey.KeySize, algorithm))
                        {
                            return(new ECDsaCng(cngKey));
                        }
                        else
                        {
                            throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("key.KeySize", String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10671, cngKey, ECDsaAlgorithm.DefaultECDsaKeySizeInBitsMap[algorithm], cngKey.KeySize)));
                        }
                    }
                }
            }
            finally
            {
                if (keyBlobHandle != null)
                {
                    keyBlobHandle.Free();
                }
            }
        }
Example #7
0
        /// <summary>
        /// Computes a sha256 hash over the <see cref="ECDsaSecurityKey"/>.
        /// </summary>
        /// <returns>A JWK thumbprint.</returns>
        /// <remarks>https://tools.ietf.org/html/rfc7638</remarks>
        public override byte[] ComputeJwkThumbprint()
        {
#if NET472 || NETSTANDARD2_0
            if (ECDsaAdapter.SupportsECParameters())
            {
                ECParameters parameters   = ECDsa.ExportParameters(false);
                var          canonicalJwk = $@"{{""{JsonWebKeyParameterNames.Crv}"":""{ECDsaAdapter.GetCrvParameterValue(parameters.Curve)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.EllipticCurve}"",""{JsonWebKeyParameterNames.X}"":""{Base64UrlEncoder.Encode(parameters.Q.X)}"",""{JsonWebKeyParameterNames.Y}"":""{Base64UrlEncoder.Encode(parameters.Q.Y)}""}}";
                return(Utility.GenerateSha256Hash(canonicalJwk));
            }
#endif
            throw LogHelper.LogExceptionMessage(new PlatformNotSupportedException(LogMessages.IDX10695));
        }
Example #8
0
        /// <summary>
        /// Computes a sha256 hash over the <see cref="SymmetricSecurityKey"/>.
        /// </summary>
        /// <returns>A JWK thumbprint.</returns>
        /// <remarks>https://datatracker.ietf.org/doc/html/rfc7638</remarks>
        public override byte[] ComputeJwkThumbprint()
        {
            var canonicalJwk = $@"{{""{JsonWebKeyParameterNames.K}"":""{Base64UrlEncoder.Encode(Key)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.Octet}""}}";

            return(Utility.GenerateSha256Hash(canonicalJwk));
        }
Example #9
0
        /// <summary>
        /// Creates an ECDsa object using the <paramref name="jsonWebKey"/> and <paramref name="usePrivateKey"/>.
        /// 'ECParameters' structure is available in .NET Framework 4.7+, .NET Standard 1.6+, and .NET Core 1.0+.
        /// This method is supported only on Windows as other platforms don't support operations with <see cref="CngKey"/>.
        /// </summary>
        private ECDsa CreateECDsaUsingCNGKey(JsonWebKey jsonWebKey, bool usePrivateKey)
        {
            if (jsonWebKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(jsonWebKey));
            }

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

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

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

            GCHandle keyBlobHandle = new GCHandle();

            try
            {
                uint   dwMagic = GetMagicValue(jsonWebKey.Crv, usePrivateKey);
                uint   cbKey   = GetKeyByteCount(jsonWebKey.Crv);
                byte[] keyBlob;
#if NET45
                if (usePrivateKey)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }
#else
                if (usePrivateKey)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }
#endif

                keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned);
                IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject();

                byte[] x = Base64UrlEncoder.DecodeBytes(jsonWebKey.X);
                if (x.Length > cbKey)
                {
                    throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.X), cbKey, x.Length)));
                }

                byte[] y = Base64UrlEncoder.DecodeBytes(jsonWebKey.Y);
                if (y.Length > cbKey)
                {
                    throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.Y), cbKey, y.Length)));
                }

                Marshal.WriteInt64(keyBlobPtr, 0, dwMagic);
                Marshal.WriteInt64(keyBlobPtr, 4, cbKey);

                int index = 8;
                foreach (byte b in x)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                foreach (byte b in y)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                if (usePrivateKey)
                {
                    if (jsonWebKey.D == null)
                    {
                        throw LogHelper.LogArgumentNullException(nameof(jsonWebKey.D));
                    }

                    byte[] d = Base64UrlEncoder.DecodeBytes(jsonWebKey.D);
                    if (d.Length > cbKey)
                    {
                        throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.D), cbKey, d.Length)));
                    }

                    foreach (byte b in d)
                    {
                        Marshal.WriteByte(keyBlobPtr, index++, b);
                    }

                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob))
                    {
                        return(new ECDsaCng(cngKey));
                    }
                }
                else
                {
                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob))
                    {
                        return(new ECDsaCng(cngKey));
                    }
                }
            }
            catch (Exception ex)
            {
                throw LogHelper.LogExceptionMessage(new CryptographicException(LogMessages.IDX10689, ex));
            }
            finally
            {
                if (keyBlobHandle != null && keyBlobHandle.IsAllocated)
                {
                    keyBlobHandle.Free();
                }
            }
        }
        /// <summary>
        /// Decrypts ciphertext into plaintext
        /// </summary>
        /// <param name="ciphertext">the encrypted text to decrypt.</param>
        /// <param name="authenticatedData">the authenticateData that is used in verification.</param>
        /// <param name="iv">the initialization vector used when creating the ciphertext.</param>
        /// <param name="authenticationTag">the authenticationTag that was created during the encyption.</param>
        /// <returns>decrypted ciphertext</returns>
        /// <exception cref="ArgumentNullException">'ciphertext' is null or empty.</exception>
        /// <exception cref="ArgumentNullException">'authenticatedData' is null or empty.</exception>
        /// <exception cref="ArgumentNullException">'iv' is null or empty.</exception>
        /// <exception cref="ArgumentNullException">'authenticationTag' is null or empty.</exception>
        /// <exception cref="SecurityTokenDecryptionFailedException">signature over authenticationTag fails to verify.</exception>
        /// <exception cref="SecurityTokenDecryptionFailedException">AES crypto operation threw. See inner exception.</exception>
        public virtual byte[] Decrypt(byte[] ciphertext, byte[] authenticatedData, byte[] iv, byte[] authenticationTag)
        {
            if (ciphertext == null || ciphertext.Length == 0)
            {
                throw LogHelper.LogArgumentNullException(nameof(ciphertext));
            }

            if (authenticatedData == null || authenticatedData.Length == 0)
            {
                throw LogHelper.LogArgumentNullException(nameof(authenticatedData));
            }

            if (iv == null || iv.Length == 0)
            {
                throw LogHelper.LogArgumentNullException(nameof(iv));
            }

            if (authenticationTag == null || authenticationTag.Length == 0)
            {
                throw LogHelper.LogArgumentNullException(nameof(authenticationTag));
            }

            // Verify authentication Tag
            byte[] al       = Utility.ConvertToBigEndian(authenticatedData.Length * 8);
            byte[] macBytes = new byte[authenticatedData.Length + iv.Length + ciphertext.Length + al.Length];
            Array.Copy(authenticatedData, 0, macBytes, 0, authenticatedData.Length);
            Array.Copy(iv, 0, macBytes, authenticatedData.Length, iv.Length);
            Array.Copy(ciphertext, 0, macBytes, authenticatedData.Length + iv.Length, ciphertext.Length);
            Array.Copy(al, 0, macBytes, authenticatedData.Length + iv.Length + ciphertext.Length, al.Length);
            if (!_symmetricSignatureProvider.Verify(macBytes, authenticationTag, _authenticatedkeys.HmacKey.Key.Length))
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10650, Base64UrlEncoder.Encode(authenticatedData), Base64UrlEncoder.Encode(iv), Base64UrlEncoder.Encode(authenticationTag))));
            }

            Aes aes = Aes.Create();

            aes.Mode    = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.Key     = _authenticatedkeys.AesKey.Key;
            aes.IV      = iv;
            try
            {
                return(Utility.Transform(aes.CreateDecryptor(), ciphertext, 0, ciphertext.Length));
            }
            catch (Exception ex)
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10654, ex)));
            }
        }
Example #11
0
 /// <summary>
 /// Instantiates a <see cref="SecurityKey"/> using a <see cref="X509Certificate2"/>
 /// </summary>
 /// <param name="certificate">The cert to use.</param>
 public X509SecurityKey(X509Certificate2 certificate)
 {
     _certificate = certificate ?? throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(certificate)));
     KeyId        = Base64UrlEncoder.Encode(certificate.GetCertHash());
     X5t          = Base64UrlEncoder.Encode(certificate.GetCertHash());
 }
        /// <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>
        /// Converts a <see cref="RsaSecurityKey"/> into a <see cref="JsonWebKey"/>
        /// </summary>
        /// <param name="key">a <see cref="RsaSecurityKey"/> to convert.</param>
        /// <returns>a <see cref="JsonWebKey"/></returns>
        /// <exception cref="ArgumentNullException">if <paramref name="key"/>is null.</exception>
        public static JsonWebKey ConvertFromRSASecurityKey(RsaSecurityKey key)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            RSAParameters parameters;

            if (key.Rsa != null)
            {
                try
                {
                    parameters = key.Rsa.ExportParameters(true);
                }
                catch
                {
                    parameters = key.Rsa.ExportParameters(false);
                }
            }
            else
            {
                parameters = key.Parameters;
            }

            return(new JsonWebKey
            {
                N = parameters.Modulus != null?Base64UrlEncoder.Encode(parameters.Modulus) : null,
                        E = parameters.Exponent != null?Base64UrlEncoder.Encode(parameters.Exponent) : null,
                                D = parameters.D != null?Base64UrlEncoder.Encode(parameters.D) : null,
                                        P = parameters.P != null?Base64UrlEncoder.Encode(parameters.P) : null,
                                                Q = parameters.Q != null?Base64UrlEncoder.Encode(parameters.Q) : null,
                                                        DP = parameters.DP != null?Base64UrlEncoder.Encode(parameters.DP) : null,
                                                                 DQ = parameters.DQ != null?Base64UrlEncoder.Encode(parameters.DQ) : null,
                                                                          QI = parameters.InverseQ != null?Base64UrlEncoder.Encode(parameters.InverseQ) : null,
                                                                                   Kty = JsonWebAlgorithmsKeyTypes.RSA,
                                                                                   Kid = key.KeyId,
                                                                                   ConvertedSecurityKey = key
            });
        }
Example #14
0
        internal ECDsa CreateECDsa(string algorithm, bool usePrivateKey)
        {
#if !WINDOWS
            throw new NotImplementedException(LogMessages.IDX10676);
#endif
            if (Crv == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(Crv));
            }

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

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

            GCHandle keyBlobHandle = new GCHandle();
            try
            {
                uint   dwMagic = GetMagicValue(Crv, usePrivateKey);
                uint   cbKey   = GetKeyByteCount(Crv);
                byte[] keyBlob;
#if NET45
                if (usePrivateKey)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))];
                }
#else
                if (usePrivateKey)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }
#endif

                keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned);
                IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject();

                byte[] x = Base64UrlEncoder.DecodeBytes(X);
                if (x.Length > cbKey)
                {
                    throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("x.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(x), cbKey, x.Length)));
                }

                byte[] y = Base64UrlEncoder.DecodeBytes(Y);
                if (y.Length > cbKey)
                {
                    throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("y.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(y), cbKey, y.Length)));
                }


                Marshal.WriteInt64(keyBlobPtr, 0, dwMagic);
                Marshal.WriteInt64(keyBlobPtr, 4, cbKey);

                int index = 8;
                foreach (byte b in x)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                foreach (byte b in y)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

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

                    byte[] d = Base64UrlEncoder.DecodeBytes(D);
                    if (d.Length > cbKey)
                    {
                        throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("d.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(d), cbKey, d.Length)));
                    }

                    foreach (byte b in d)
                    {
                        Marshal.WriteByte(keyBlobPtr, index++, b);
                    }

                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob))
                    {
                        return(new ECDsaCng(cngKey));
                    }
                }
                else
                {
                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob))
                    {
                        return(new ECDsaCng(cngKey));
                    }
                }
            }
            finally
            {
                if (keyBlobHandle != null)
                {
                    keyBlobHandle.Free();
                }
            }
        }
        private byte[] DecryptWithAesCbc(byte[] ciphertext, byte[] authenticatedData, byte[] iv, byte[] authenticationTag)
        {
            // Verify authentication Tag
            byte[] al       = Utility.ConvertToBigEndian(authenticatedData.Length * 8);
            byte[] macBytes = new byte[authenticatedData.Length + iv.Length + ciphertext.Length + al.Length];
            Array.Copy(authenticatedData, 0, macBytes, 0, authenticatedData.Length);
            Array.Copy(iv, 0, macBytes, authenticatedData.Length, iv.Length);
            Array.Copy(ciphertext, 0, macBytes, authenticatedData.Length + iv.Length, ciphertext.Length);
            Array.Copy(al, 0, macBytes, authenticatedData.Length + iv.Length + ciphertext.Length, al.Length);
            if (!_symmetricSignatureProvider.Value.Verify(macBytes, authenticationTag, _authenticatedkeys.Value.HmacKey.Key.Length))
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(LogMessages.IDX10650, Base64UrlEncoder.Encode(authenticatedData), Base64UrlEncoder.Encode(iv), Base64UrlEncoder.Encode(authenticationTag))));
            }

            using Aes aes = Aes.Create();
            aes.Mode      = CipherMode.CBC;
            aes.Padding   = PaddingMode.PKCS7;
            aes.Key       = _authenticatedkeys.Value.AesKey.Key;
            aes.IV        = iv;
            try
            {
                return(Transform(aes.CreateDecryptor(), ciphertext, 0, ciphertext.Length));
            }
            catch (Exception ex)
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(LogMessages.IDX10654, ex)));
            }
        }
Example #16
0
        private void CreateECDsaFromJsonWebKey(JsonWebKey webKey, bool willCreateSignatures)
        {
            if (webKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(webKey));
            }

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

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

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

            GCHandle keyBlobHandle = new GCHandle();

            try
            {
                uint   dwMagic = GetMagicValue(webKey.Crv, willCreateSignatures);
                uint   cbKey   = GetKeyByteCount(webKey.Crv);
                byte[] keyBlob;
                if (willCreateSignatures)
                {
                    keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }
                else
                {
                    keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()];
                }

                keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned);
                IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject();
                byte[] x          = Base64UrlEncoder.DecodeBytes(webKey.X);
                byte[] y          = Base64UrlEncoder.DecodeBytes(webKey.Y);

                Marshal.WriteInt64(keyBlobPtr, 0, dwMagic);
                Marshal.WriteInt64(keyBlobPtr, 4, cbKey);

                int index = 8;
                foreach (byte b in x)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                foreach (byte b in y)
                {
                    Marshal.WriteByte(keyBlobPtr, index++, b);
                }

                if (willCreateSignatures)
                {
                    if (webKey.D == null)
                    {
                        throw LogHelper.LogArgumentNullException(nameof(webKey.D));
                    }

                    byte[] d = Base64UrlEncoder.DecodeBytes(webKey.D);
                    foreach (byte b in d)
                    {
                        Marshal.WriteByte(keyBlobPtr, index++, b);
                    }

                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob))
                    {
                        _ecdsa        = new ECDsaCng(cngKey);
                        _disposeEcdsa = true;
                    }
                }
                else
                {
                    Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length);
                    using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob))
                    {
                        _ecdsa        = new ECDsaCng(cngKey);
                        _disposeEcdsa = true;
                    }
                }
            }
            finally
            {
                if (keyBlobHandle != null)
                {
                    keyBlobHandle.Free();
                }
            }
        }