Exemplo n.º 1
0
        internal static AlgorithmIdentifier ToPresentationObject(this AlgorithmIdentifierAsn asn)
        {
            int keyLength;

            byte[] parameters = Array.Empty <byte>();

            switch (asn.Algorithm.Value)
            {
            case Oids.Rc2Cbc:
            {
                if (asn.Parameters == null)
                {
                    keyLength = 0;
                    break;
                }

                Rc2CbcParameters rc2Params = Rc2CbcParameters.Decode(
                    asn.Parameters.Value,
                    AsnEncodingRules.BER);

                int keySize = rc2Params.GetEffectiveKeyBits();

                // These are the only values .NET Framework would set.
                switch (keySize)
                {
                case 40:
                case 56:
                case 64:
                case 128:
                    keyLength = keySize;
                    break;

                default:
                    keyLength = 0;
                    break;
                }

                break;
            }

            case Oids.Rc4:
            {
                if (asn.Parameters == null)
                {
                    keyLength = 0;
                    break;
                }

                int       saltLen = 0;
                AsnReader reader  = new AsnReader(asn.Parameters.Value, AsnEncodingRules.BER);

                // DER NULL is considered the same as not present.
                // No call to ReadNull() is necessary because the serializer already verified that
                // there's no data after the [AnyValue] value.
                if (reader.PeekTag() != Asn1Tag.Null)
                {
                    if (reader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> contents))
                    {
                        saltLen = contents.Length;
                    }
                    else
                    {
                        Span <byte> salt = stackalloc byte[KeyLengths.Rc4Max_128Bit / 8];

                        if (!reader.TryCopyOctetStringBytes(salt, out saltLen))
                        {
                            throw new CryptographicException();
                        }
                    }
                }

                keyLength = KeyLengths.Rc4Max_128Bit - 8 * saltLen;
                break;
            }

            case Oids.DesCbc:
                keyLength = KeyLengths.Des_64Bit;
                break;

            case Oids.TripleDesCbc:
                keyLength = KeyLengths.TripleDes_192Bit;
                break;

            case Oids.RsaOaep when !asn.HasNullEquivalentParameters():
                keyLength  = 0;
                parameters = asn.Parameters.Value.ToArray();
                break;

            default:
                // .NET Framework doesn't set a keylength for AES, or any other algorithm than the ones
                // listed here.
                keyLength = 0;
                break;
            }

            return(new AlgorithmIdentifier(new Oid(asn.Algorithm), keyLength)
            {
                Parameters = parameters
            });
        }
Exemplo n.º 2
0
        private static bool VerifyX509Signature(
            ReadOnlySpan <byte> toBeSigned,
            ReadOnlySpan <byte> signature,
            PublicKey publicKey,
            AlgorithmIdentifierAsn algorithmIdentifier)
        {
            RSA?  rsa   = publicKey.GetRSAPublicKey();
            ECDsa?ecdsa = publicKey.GetECDsaPublicKey();

            try
            {
                HashAlgorithmName hashAlg;

                if (algorithmIdentifier.Algorithm == Oids.RsaPss)
                {
                    if (rsa is null || !algorithmIdentifier.Parameters.HasValue)
                    {
                        return(false);
                    }

                    PssParamsAsn pssParams = PssParamsAsn.Decode(
                        algorithmIdentifier.Parameters.GetValueOrDefault(),
                        AsnEncodingRules.DER);

                    RSASignaturePadding padding = pssParams.GetSignaturePadding();
                    hashAlg = HashAlgorithmName.FromOid(pssParams.HashAlgorithm.Algorithm);

                    return(rsa.VerifyData(
                               toBeSigned,
                               signature,
                               hashAlg,
                               padding));
                }

                switch (algorithmIdentifier.Algorithm)
                {
                case Oids.RsaPkcs1Sha256:
                case Oids.ECDsaWithSha256:
                    hashAlg = HashAlgorithmName.SHA256;
                    break;

                case Oids.RsaPkcs1Sha384:
                case Oids.ECDsaWithSha384:
                    hashAlg = HashAlgorithmName.SHA384;
                    break;

                case Oids.RsaPkcs1Sha512:
                case Oids.ECDsaWithSha512:
                    hashAlg = HashAlgorithmName.SHA512;
                    break;

                case Oids.RsaPkcs1Sha1:
                case Oids.ECDsaWithSha1:
                    hashAlg = HashAlgorithmName.SHA1;
                    break;

                default:
                    throw new NotSupportedException(
                              SR.Format(SR.Cryptography_UnknownKeyAlgorithm, algorithmIdentifier.Algorithm));
                }

                // All remaining supported algorithms have no defined parameters
                if (!algorithmIdentifier.HasNullEquivalentParameters())
                {
                    return(false);
                }

                switch (algorithmIdentifier.Algorithm)
                {
                case Oids.RsaPkcs1Sha256:
                case Oids.RsaPkcs1Sha384:
                case Oids.RsaPkcs1Sha512:
                case Oids.RsaPkcs1Sha1:
                    if (rsa is null)
                    {
                        return(false);
                    }

                    return(rsa.VerifyData(toBeSigned, signature, hashAlg, RSASignaturePadding.Pkcs1));

                case Oids.ECDsaWithSha256:
                case Oids.ECDsaWithSha384:
                case Oids.ECDsaWithSha512:
                case Oids.ECDsaWithSha1:
                    if (ecdsa is null)
                    {
                        return(false);
                    }

                    return(ecdsa.VerifyData(toBeSigned, signature, hashAlg, DSASignatureFormat.Rfc3279DerSequence));

                default:
                    Debug.Fail(
                        $"Algorithm ID {algorithmIdentifier.Algorithm} was in the first switch, but not the second");
                    return(false);
                }
            }
            catch (AsnContentException)
            {
                return(false);
            }
            catch (CryptographicException)
            {
                return(false);
            }
            finally
            {
                rsa?.Dispose();
                ecdsa?.Dispose();
            }
        }