Ejemplo n.º 1
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);
            }