Esempio n. 1
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbSubjectPublicKeyInfo, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            KrbAlgorithmIdentifier.Decode <KrbAlgorithmIdentifier>(sequenceReader, out decoded.Algorithm);

            if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSubjectPublicKey))
            {
                decoded.SubjectPublicKey = tmpSubjectPublicKey;
            }
            else
            {
                decoded.SubjectPublicKey = sequenceReader.ReadBitString(out _);
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 2
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificateAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.X509Certificates.Asn1.TbsCertificateAsn.Decode(sequenceReader, out decoded.TbsCertificate);
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm);

            if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSignatureValue))
            {
                decoded.SignatureValue = tmpSignatureValue;
            }
            else
            {
                decoded.SignatureValue = sequenceReader.ReadBitString(out _);
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 3
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbDiffieHellmanValidationParameters, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);


            if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSeed))
            {
                decoded.Seed = tmpSeed;
            }
            else
            {
                decoded.Seed = sequenceReader.ReadBitString(out _);
            }

            decoded.PGenOutput = sequenceReader.ReadInteger();

            sequenceReader.ThrowIfNotEmpty();
        }
        public static void TryCopyBitStringBytes_ExtremelyNested()
        {
            byte[] dataBytes = new byte[4 * 16384];

            // This will build 2^14 nested indefinite length values.
            // In the end, none of them contain any content.
            //
            // For what it's worth, the initial algorithm succeeded at 1017, and StackOverflowed with 1018.
            int end = dataBytes.Length / 2;

            // UNIVERSAL BIT STRING [Constructed]
            const byte Tag = 0x20 | (byte)UniversalTagNumber.BitString;

            for (int i = 0; i < end; i += 2)
            {
                dataBytes[i] = Tag;
                // Indefinite length
                dataBytes[i + 1] = 0x80;
            }

            AsnReader reader = new AsnReader(dataBytes, AsnEncodingRules.BER);

            int bytesWritten;
            int unusedBitCount;

            Assert.True(
                reader.TryReadBitString(Span <byte> .Empty, out unusedBitCount, out bytesWritten));

            Assert.Equal(0, bytesWritten);
            Assert.Equal(0, unusedBitCount);

            reader = new AsnReader(dataBytes, AsnEncodingRules.BER);
            byte[] output = reader.ReadBitString(out unusedBitCount);
            Assert.Equal(0, unusedBitCount);

            // It's Same (ReferenceEqual) on .NET Core, but just Equal on .NET Framework
            Assert.Equal(Array.Empty <byte>(), output);
        }
Esempio n. 5
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OriginatorPublicKeyAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.Algorithm);

            if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpPublicKey))
            {
                decoded.PublicKey = tmpPublicKey;
            }
            else
            {
                decoded.PublicKey = sequenceReader.ReadBitString(out _);
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out TbsCertificateAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;
            AsnReader defaultReader;
            AsnReader collectionReader;


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

                if (!explicitReader.TryReadInt32(out decoded.Version))
                {
                    explicitReader.ThrowIfNotEmpty();
                }

                explicitReader.ThrowIfNotEmpty();
            }
            else
            {
                defaultReader = new AsnReader(s_defaultVersion, AsnEncodingRules.DER);

                if (!defaultReader.TryReadInt32(out decoded.Version))
                {
                    defaultReader.ThrowIfNotEmpty();
                }
            }

            decoded.SerialNumber = sequenceReader.ReadIntegerBytes();
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Issuer = sequenceReader.ReadEncodedValue();
            System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(sequenceReader, out decoded.Validity);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Subject = sequenceReader.ReadEncodedValue();
            System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 1), out _, out ReadOnlyMemory <byte> tmpIssuerUniqueId))
                {
                    decoded.IssuerUniqueId = tmpIssuerUniqueId;
                }
                else
                {
                    decoded.IssuerUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 1), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 2), out _, out ReadOnlyMemory <byte> tmpSubjectUniqueId))
                {
                    decoded.SubjectUniqueId = tmpSubjectUniqueId;
                }
                else
                {
                    decoded.SubjectUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 2), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));

                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = explicitReader.ReadSequence();
                    var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>();
                    System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Extensions = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        public static void ExpectedTag_IgnoresConstructed(
            AsnEncodingRules ruleSet,
            string inputHex,
            TagClass tagClass,
            int tagValue)
        {
            byte[]    inputData          = inputHex.HexToByteArray();
            AsnReader reader             = new AsnReader(inputData, ruleSet);
            Asn1Tag   correctConstructed = new Asn1Tag(tagClass, tagValue, true);
            Asn1Tag   correctPrimitive   = new Asn1Tag(tagClass, tagValue, false);

            Assert.True(
                reader.TryReadPrimitiveBitString(
                    out int ubc1,
                    out ReadOnlyMemory <byte> val1,
                    correctConstructed));

            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryReadPrimitiveBitString(
                    out int ubc2,
                    out ReadOnlyMemory <byte> val2,
                    correctPrimitive));

            Assert.False(reader.HasData);

            string val1Hex = val1.ByteArrayToHex();

            Assert.Equal(val1Hex, val2.ByteArrayToHex());
            Assert.Equal(ubc1, ubc2);

            reader = new AsnReader(inputData, ruleSet);
            byte[] output1 = new byte[inputData.Length];

            Assert.True(reader.TryReadBitString(output1.AsSpan(1), out ubc1, out int written, correctConstructed));
            Assert.Equal(ubc2, ubc1);
            Assert.Equal(val1Hex, output1.AsSpan(1, written).ByteArrayToHex());
            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(reader.TryReadBitString(output1.AsSpan(2), out ubc1, out written, correctPrimitive));
            Assert.Equal(ubc2, ubc1);
            Assert.Equal(val1Hex, output1.AsSpan(2, written).ByteArrayToHex());
            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);
            byte[] output2 = reader.ReadBitString(out ubc1, correctConstructed);

            Assert.Equal(ubc2, ubc1);
            Assert.Equal(val1Hex, output2.ByteArrayToHex());
            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);
            byte[] output3 = reader.ReadBitString(out ubc1, correctPrimitive);

            Assert.Equal(ubc2, ubc1);
            Assert.Equal(val1Hex, output3.ByteArrayToHex());
            Assert.False(reader.HasData);
        }
        public static void TagMustBeCorrect_Custom(AsnEncodingRules ruleSet)
        {
            byte[]    inputData = { 0x87, 2, 0, 0x80 };
            byte[]    output    = new byte[inputData.Length];
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            Asn1Tag wrongTag1  = new Asn1Tag(TagClass.Application, 0);
            Asn1Tag wrongTag2  = new Asn1Tag(TagClass.ContextSpecific, 1);
            Asn1Tag correctTag = new Asn1Tag(TagClass.ContextSpecific, 7);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.TryReadPrimitiveBitString(out _, out _, Asn1Tag.Null));
            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.TryReadBitString(output, out _, out _, Asn1Tag.Null));
            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.ReadBitString(out _, Asn1Tag.Null));

            Assert.True(reader.HasData, "HasData after bad universal tag");

            Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _));
            Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _));
            Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _));
            Assert.True(reader.HasData, "HasData after default tag");

            Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _, wrongTag1));
            Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _, wrongTag1));
            Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _, wrongTag1));
            Assert.True(reader.HasData, "HasData after wrong custom class");

            Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _, wrongTag2));
            Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _, wrongTag2));
            Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _, wrongTag2));
            Assert.True(reader.HasData, "HasData after wrong custom tag value");

            Assert.True(
                reader.TryReadPrimitiveBitString(
                    out int unusedBitCount,
                    out ReadOnlyMemory <byte> contents,
                    correctTag));

            Assert.Equal("80", contents.ByteArrayToHex());
            Assert.Equal(0, unusedBitCount);
            Assert.False(reader.HasData, "HasData after reading value");

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryReadBitString(
                    output.AsSpan(1),
                    out unusedBitCount,
                    out int written,
                    correctTag));

            Assert.Equal("80", output.AsSpan(1, written).ByteArrayToHex());
            Assert.Equal(0, unusedBitCount);
            Assert.False(reader.HasData, "HasData after reading value");

            reader = new AsnReader(inputData, ruleSet);
            byte[] output2 = reader.ReadBitString(out unusedBitCount, correctTag);

            Assert.Equal("80", output2.ByteArrayToHex());
            Assert.Equal(0, unusedBitCount);
            Assert.False(reader.HasData, "HasData after reading value");
        }
        internal CertificateDataAsn(byte[] rawData)
        {
            AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER).ReadSequence();

            AsnReader tbsCertificate = reader.ReadSequence();

            if (tbsCertificate.PeekTag() == explicit0)
            {
                AsnReader version = tbsCertificate.ReadSequence(explicit0);
                version.TryReadInt32(out Version);
            }
            else if (tbsCertificate.PeekTag() != Asn1Tag.Integer)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }
            else
            {
                Version = 0;
            }

            if (Version < 0 || Version > 2)
            {
                throw new CryptographicException();
            }

            SerialNumber = tbsCertificate.GetIntegerBytes().ToArray();

            AsnReader tbsSignature = tbsCertificate.ReadSequence();

            TbsSignature.AlgorithmId = tbsSignature.ReadObjectIdentifierAsString();
            TbsSignature.Parameters  = tbsSignature.HasData ? tbsSignature.GetEncodedValue().ToArray() : Array.Empty <byte>();

            if (tbsSignature.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            Issuer = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray());

            AsnReader validity = tbsCertificate.ReadSequence();

            NotBefore = validity.GetUtcTime().UtcDateTime;             // FIXME
            NotAfter  = validity.GetUtcTime().UtcDateTime;

            if (validity.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            Subject = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray());

            SubjectPublicKeyInfo = tbsCertificate.GetEncodedValue().ToArray();
            AsnReader subjectPublicKeyInfo = new AsnReader(SubjectPublicKeyInfo, AsnEncodingRules.DER).ReadSequence();
            AsnReader subjectKeyAlgorithm  = subjectPublicKeyInfo.ReadSequence();

            PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadObjectIdentifierAsString();
            PublicKeyAlgorithm.Parameters  = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>();

            if (subjectKeyAlgorithm.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            PublicKey = subjectPublicKeyInfo.ReadBitString();

            if (subjectPublicKeyInfo.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            if (Version > 0 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == explicit1)
            {
                IssuerUniqueId = tbsCertificate.ReadBitString();
            }
            else
            {
                IssuerUniqueId = null;
            }

            if (Version > 0 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == explicit2)
            {
                SubjectUniqueId = tbsCertificate.ReadBitString();
            }
            else
            {
                SubjectUniqueId = null;
            }

            Extensions = new List <X509Extension>();

            if (Version > 1 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == explicit3)
            {
                AsnReader extensions = tbsCertificate.ReadSequence(explicit3);
                extensions = extensions.ReadSequence();

                while (extensions.HasData)
                {
                    AsnReader extensionReader = extensions.ReadSequence();
                    string    oid             = extensionReader.ReadObjectIdentifierAsString();
                    bool      critical        = false;

                    if (extensionReader.PeekTag() == Asn1Tag.Boolean)
                    {
                        critical = extensionReader.ReadBoolean();
                    }

                    byte[] extensionData = extensionReader.ReadOctetString();

                    Extensions.Add(new X509Extension(oid, extensionData, critical));

                    if (extensionReader.HasData)
                    {
                        throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                    }
                }
            }

            if (tbsCertificate.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            AsnReader signatureAlgorithm = reader.ReadSequence();

            SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadObjectIdentifierAsString();
            SignatureAlgorithm.Parameters  = signatureAlgorithm.HasData ? signatureAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>();

            if (signatureAlgorithm.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            SignatureValue = reader.ReadBitString();

            if (reader.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            RawData = rawData;
        }