Ejemplo n.º 1
0
        public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
        {
            if (string.IsNullOrEmpty(hashAlgorithm.Name))
            {
                throw HashAlgorithmNameNullOrEmpty();
            }
            if (padding == null)
            {
                throw new ArgumentNullException(nameof(padding));
            }

            if (padding == RSASignaturePadding.Pkcs1)
            {
                int           algorithmNid = GetAlgorithmNid(hashAlgorithm);
                SafeRsaHandle rsa          = _key.Value;
                return(Interop.Crypto.RsaVerify(algorithmNid, hash, hash.Length, signature, signature.Length, rsa));
            }
            else if (padding == RSASignaturePadding.Pss)
            {
                RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                SafeRsaHandle       rsa       = _key.Value;

                int requiredBytes = Interop.Crypto.RsaSize(rsa);

                if (signature.Length != requiredBytes)
                {
                    return(false);
                }

                if (hash.Length != processor.HashLength)
                {
                    return(false);
                }

                byte[] rented = ArrayPool <byte> .Shared.Rent(requiredBytes);

                Span <byte> unwrapped = new Span <byte>(rented, 0, requiredBytes);

                try
                {
                    int ret = Interop.Crypto.RsaVerificationPrimitive(signature, unwrapped, rsa);

                    CheckReturn(ret);

                    Debug.Assert(
                        ret == requiredBytes,
                        $"RSA_private_encrypt returned {ret} when {requiredBytes} was expected");

                    return(processor.VerifyPss(hash, unwrapped, KeySize));
                }
                finally
                {
                    unwrapped.Clear();
                    ArrayPool <byte> .Shared.Return(rented);
                }
            }

            throw PaddingModeNotSupported();
        }
Ejemplo n.º 2
0
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm));
                ArgumentNullException.ThrowIfNull(padding);

                ThrowIfDisposed();

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out _);
                    return(Interop.AppleCrypto.VerifySignature(
                               GetKeys().PublicKey,
                               hash,
                               signature,
                               palAlgId,
                               Interop.AppleCrypto.PAL_SignatureAlgorithm.RsaPkcs1));
                }
                else if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    SafeSecKeyRefHandle publicKey = GetKeys().PublicKey;

                    int keySize = KeySize;
                    int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                    if (signature.Length != rsaSize)
                    {
                        return(false);
                    }

                    if (hash.Length != RsaPaddingProcessor.HashLength(hashAlgorithm))
                    {
                        return(false);
                    }

                    byte[]      rented    = CryptoPool.Rent(rsaSize);
                    Span <byte> unwrapped = new Span <byte>(rented, 0, rsaSize);

                    try
                    {
                        if (!Interop.AppleCrypto.TryRsaVerificationPrimitive(
                                publicKey,
                                signature,
                                unwrapped,
                                out int bytesWritten))
                        {
                            Debug.Fail($"TryRsaVerificationPrimitive with a pre-allocated buffer");
                            throw new CryptographicException();
                        }

                        Debug.Assert(bytesWritten == rsaSize);
                        return(RsaPaddingProcessor.VerifyPss(hashAlgorithm, hash, unwrapped, keySize));
                    }
                    finally
                    {
                        CryptographicOperations.ZeroMemory(unwrapped);
                        CryptoPool.Return(rented, clearSize: 0);
                    }
                }

                throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
            }
Ejemplo n.º 3
0
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }
                if (padding == RSASignaturePadding.Pkcs1 && padding == RSASignaturePadding.Pss)
                {
                    throw PaddingModeNotSupported();
                }

                RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                SafeRsaHandle       rsa       = GetKey();

                int requiredBytes = Interop.AndroidCrypto.RsaSize(rsa);

                if (signature.Length != requiredBytes)
                {
                    return(false);
                }

                if (hash.Length != processor.HashLength)
                {
                    return(false);
                }

                byte[]      rented    = CryptoPool.Rent(requiredBytes);
                Span <byte> unwrapped = new Span <byte>(rented, 0, requiredBytes);

                try
                {
                    int ret = Interop.AndroidCrypto.RsaVerificationPrimitive(signature, unwrapped, rsa);

                    CheckReturn(ret);
                    if (ret == 0)
                    {
                        // Return value of 0 from RsaVerificationPrimitive indicates the signature could not be decrypted.
                        return(false);
                    }

                    Debug.Assert(
                        ret == requiredBytes,
                        $"RsaVerificationPrimitive returned {ret} when {requiredBytes} was expected");

                    if (padding == RSASignaturePadding.Pkcs1)
                    {
                        byte[]      repadRent = CryptoPool.Rent(unwrapped.Length);
                        Span <byte> repadded  = repadRent.AsSpan(0, requiredBytes);
                        processor.PadPkcs1Signature(hash, repadded);
                        bool valid = CryptographicOperations.FixedTimeEquals(repadded, unwrapped);
                        CryptoPool.Return(repadRent, requiredBytes);
                        return(valid);
                    }
                    else if (padding == RSASignaturePadding.Pss)
                    {
                        return(processor.VerifyPss(hash, unwrapped, KeySize));
                    }
                    else
                    {
                        Debug.Fail("Padding mode should be checked prior to this point.");
                        throw PaddingModeNotSupported();
                    }
                }
                finally
                {
                    CryptoPool.Return(rented, requiredBytes);
                }

                throw PaddingModeNotSupported();
            }
Ejemplo n.º 4
0
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);
                    return(Interop.AppleCrypto.VerifySignature(GetKeys().PublicKey, hash, signature, palAlgId));
                }
                else if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                    SafeSecKeyRefHandle publicKey = GetKeys().PublicKey;

                    int keySize = KeySize;
                    int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                    if (signature.Length != rsaSize)
                    {
                        return(false);
                    }

                    if (hash.Length != processor.HashLength)
                    {
                        return(false);
                    }

                    byte[] rented = ArrayPool <byte> .Shared.Rent(rsaSize);

                    Span <byte> unwrapped = new Span <byte>(rented, 0, rsaSize);

                    try
                    {
                        if (!Interop.AppleCrypto.TryRsaVerificationPrimitive(
                                publicKey,
                                signature,
                                unwrapped,
                                out int bytesWritten))
                        {
                            Debug.Fail($"TryRsaVerificationPrimitive with a pre-allocated buffer");
                            throw new CryptographicException();
                        }

                        Debug.Assert(bytesWritten == rsaSize);
                        return(processor.VerifyPss(hash, unwrapped, keySize));
                    }
                    finally
                    {
                        unwrapped.Clear();
                        ArrayPool <byte> .Shared.Return(rented);
                    }
                }

                throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
            }