Esempio n. 1
0
        public static void TagMustBeCorrect_Custom(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = { 0x87, 2, 2, 4 };
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(Asn1Tag.Null));

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

            Assert.Throws <CryptographicException>(
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>());

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

            Assert.Throws <CryptographicException>(
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.Application, 0)));

            Assert.True(reader.HasData, "HasData after wrong custom class");

            Assert.Throws <CryptographicException>(
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 1)));

            Assert.True(reader.HasData, "HasData after wrong custom tag value");

            Assert.Equal(
                X509KeyUsageCSharpStyle.KeyCertSign,
                reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 7)));

            Assert.False(reader.HasData, "HasData after reading value");
        }
Esempio n. 2
0
        public static void VerifyGenericReadNamedBitList(PublicEncodingRules ruleSet)
        {
            string    inputHex = "0306078000000080" + "0309010000000080000002";
            AsnReader reader   = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet);

            ULongFlags uLongFlags = reader.GetNamedBitListValue <ULongFlags>();
            LongFlags  longFlags  = reader.GetNamedBitListValue <LongFlags>();

            Assert.False(reader.HasData);
            Assert.Equal(ULongFlags.Mid | ULongFlags.Min, uLongFlags);
            Assert.Equal(LongFlags.Mid | LongFlags.Max, longFlags);
        }
Esempio n. 3
0
        public static void ExpectedTag_IgnoresConstructed(
            PublicEncodingRules ruleSet,
            string inputHex,
            PublicTagClass tagClass,
            int tagValue)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            Assert.Equal(
                X509KeyUsageCSharpStyle.DecipherOnly,
                reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(
                    new Asn1Tag((TagClass)tagClass, tagValue, true)));

            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            Assert.Equal(
                X509KeyUsageCSharpStyle.DecipherOnly,
                reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(
                    new Asn1Tag((TagClass)tagClass, tagValue, false)));

            Assert.False(reader.HasData);
        }
Esempio n. 4
0
        public virtual void DecodeX509KeyUsageExtension(byte[] encoded, out X509KeyUsageFlags keyUsages)
        {
            AsnReader        reader       = new AsnReader(encoded, AsnEncodingRules.BER);
            KeyUsageFlagsAsn keyUsagesAsn = reader.GetNamedBitListValue <KeyUsageFlagsAsn>();

            reader.ThrowIfNotEmpty();

            // DER encodings of BIT_STRING values number the bits as
            // 01234567 89 (big endian), plus a number saying how many bits of the last byte were padding.
            //
            // So digitalSignature (0) doesn't mean 2^0 (0x01), it means the most significant bit
            // is set in this byte stream.
            //
            // BIT_STRING values are compact.  So a value of cRLSign (6) | keyEncipherment (2), which
            // is 0b0010001 => 0b0010 0010 (1 bit padding) => 0x22 encoded is therefore
            // 0x02 (length remaining) 0x01 (1 bit padding) 0x22.
            //
            // We will read that, and return 0x22.  0x22 lines up
            // exactly with X509KeyUsageFlags.CrlSign (0x20) | X509KeyUsageFlags.KeyEncipherment (0x02)
            //
            // Once the decipherOnly (8) bit is added to the mix, the values become:
            // 0b001000101 => 0b0010 0010 1000 0000 (7 bits padding)
            // { 0x03 0x07 0x22 0x80 }
            // And we read new byte[] { 0x22 0x80 }
            //
            // The value of X509KeyUsageFlags.DecipherOnly is 0x8000.  0x8000 in a little endian
            // representation is { 0x00 0x80 }.  This means that the DER storage mechanism has effectively
            // ended up being little-endian for BIT_STRING values.  Untwist the bytes, and now the bits all
            // line up with the existing X509KeyUsageFlags.

            keyUsages =
                (X509KeyUsageFlags)ReverseBitOrder((byte)keyUsagesAsn) |
                (X509KeyUsageFlags)(ReverseBitOrder((byte)(((ushort)keyUsagesAsn >> 8))) << 8);
        }
Esempio n. 5
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PkiStatusInfo decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


            if (!sequenceReader.TryReadInt32(out decoded.Status))
            {
                sequenceReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData)
            {
                decoded.StatusString = sequenceReader.GetEncodedValue();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.PrimitiveBitString))
            {
                decoded.FailInfo = sequenceReader.GetNamedBitListValue <System.Security.Cryptography.Pkcs.Asn1.PkiFailureInfo>();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 6
0
        public static void ReadNamedBitList_ExcessiveBits(PublicEncodingRules ruleSet)
        {
            string inputHex = "0303061480";

            AsnReader reader = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet);

            Assert.Throws <CryptographicException>(
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>());

            Assert.True(reader.HasData, "reader.HasData");
        }
Esempio n. 7
0
        public static void ReadNamedBitList_RequiresFlags(PublicEncodingRules ruleSet)
        {
            string    inputHex = "030100";
            AsnReader reader   = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "tFlagsEnum",
                () => reader.GetNamedBitListValue <AsnEncodingRules>());

            Assert.True(reader.HasData, "reader.HasData");
        }
Esempio n. 8
0
        public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = { 3, 2, 1, 2 };
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(Asn1Tag.Null));

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

            Assert.Throws <CryptographicException>(
                () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 0)));

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

            Assert.Equal(
                X509KeyUsageCSharpStyle.CrlSign,
                reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>());
            Assert.False(reader.HasData, "HasData after read");
        }
Esempio n. 9
0
        public static void VerifyReadNamedBitListEncodings(
            PublicEncodingRules ruleSet,
            Type enumType,
            long enumValue,
            string inputHex)
        {
            byte[] inputBytes = inputHex.HexToByteArray();

            AsnReader reader    = new AsnReader(inputBytes, (AsnEncodingRules)ruleSet);
            Enum      readValue = reader.GetNamedBitListValue(enumType);

            Assert.Equal(Enum.ToObject(enumType, enumValue), readValue);
        }
Esempio n. 10
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out DistributionPointAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                System.Security.Cryptography.X509Certificates.Asn1.DistributionPointNameAsn tmpDistributionPoint;
                System.Security.Cryptography.X509Certificates.Asn1.DistributionPointNameAsn.Decode(explicitReader, out tmpDistributionPoint);
                decoded.DistributionPoint = tmpDistributionPoint;

                explicitReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                decoded.Reasons = sequenceReader.GetNamedBitListValue <System.Security.Cryptography.X509Certificates.Asn1.ReasonFlagsAsn>(new Asn1Tag(TagClass.ContextSpecific, 1));
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                // Decode SEQUENCE OF for CRLIssuer
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
                    var tmpList = new List <System.Security.Cryptography.Asn1.GeneralNameAsn>();
                    System.Security.Cryptography.Asn1.GeneralNameAsn tmpItem;

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

                    decoded.CRLIssuer = tmpList.ToArray();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 11
0
        public static void ReadMicrosoftComCert()
        {
            byte[]    bytes      = MicrosoftDotComSslCertBytes;
            AsnReader fileReader = new AsnReader(bytes, AsnEncodingRules.DER);

            AsnReader certReader = fileReader.ReadSequence();

            Assert.False(fileReader.HasData, "fileReader.HasData");

            AsnReader tbsCertReader = certReader.ReadSequence();
            AsnReader sigAlgReader  = certReader.ReadSequence();

            Assert.True(
                certReader.TryGetPrimitiveBitStringValue(
                    out int unusedBitCount,
                    out ReadOnlyMemory <byte> signature),
                "certReader.TryGetBitStringBytes");

            Assert.Equal(0, unusedBitCount);
            AssertRefSame(signature, ref bytes[1176], "Signature is a ref to bytes[1176]");

            Assert.False(certReader.HasData, "certReader.HasData");

            AsnReader versionExplicitWrapper = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

            Assert.True(versionExplicitWrapper.TryReadInt32(out int certVersion));
            Assert.Equal(2, certVersion);
            Assert.False(versionExplicitWrapper.HasData, "versionExplicitWrapper.HasData");

            ReadOnlyMemory <byte> serialBytes = tbsCertReader.GetIntegerBytes();

            AssertRefSame(serialBytes, ref bytes[15], "Serial number starts at bytes[15]");

            AsnReader tbsSigAlgReader = tbsCertReader.ReadSequence();

            Assert.Equal("1.2.840.113549.1.1.11", tbsSigAlgReader.ReadObjectIdentifierAsString());
            Assert.True(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData before ReadNull");
            tbsSigAlgReader.ReadNull();
            Assert.False(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData after ReadNull");

            AsnReader issuerReader    = tbsCertReader.ReadSequence();
            Asn1Tag   printableString = new Asn1Tag(UniversalTagNumber.PrintableString);

            AssertRdn(issuerReader, "2.5.4.6", 57, printableString, bytes, "issuer[C]");
            AssertRdn(issuerReader, "2.5.4.10", 70, printableString, bytes, "issuer[O]");
            AssertRdn(issuerReader, "2.5.4.11", 101, printableString, bytes, "issuer[OU]");
            AssertRdn(issuerReader, "2.5.4.3", 134, printableString, bytes, "issuer[CN]");
            Assert.False(issuerReader.HasData, "issuerReader.HasData");

            AsnReader validityReader = tbsCertReader.ReadSequence();

            Assert.Equal(new DateTimeOffset(2014, 10, 15, 0, 0, 0, TimeSpan.Zero), validityReader.GetUtcTime());
            Assert.Equal(new DateTimeOffset(2016, 10, 15, 23, 59, 59, TimeSpan.Zero), validityReader.GetUtcTime());
            Assert.False(validityReader.HasData, "validityReader.HasData");

            AsnReader subjectReader = tbsCertReader.ReadSequence();
            Asn1Tag   utf8String    = new Asn1Tag(UniversalTagNumber.UTF8String);

            AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.3", 220, printableString, bytes, "subject[EV Country]");
            AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.2", 241, utf8String, bytes, "subject[EV State]", "Washington");
            AssertRdn(subjectReader, "2.5.4.15", 262, printableString, bytes, "subject[Business Category]");
            AssertRdn(subjectReader, "2.5.4.5", 293, printableString, bytes, "subject[Serial Number]");
            AssertRdn(subjectReader, "2.5.4.6", 313, printableString, bytes, "subject[C]");
            AssertRdn(subjectReader, "2.5.4.17", 326, utf8String, bytes, "subject[Postal Code]", "98052");
            AssertRdn(subjectReader, "2.5.4.8", 342, utf8String, bytes, "subject[ST]", "Washington");
            AssertRdn(subjectReader, "2.5.4.7", 363, utf8String, bytes, "subject[L]", "Redmond");
            AssertRdn(subjectReader, "2.5.4.9", 381, utf8String, bytes, "subject[Street Address]", "1 Microsoft Way");
            AssertRdn(subjectReader, "2.5.4.10", 407, utf8String, bytes, "subject[O]", "Microsoft Corporation");
            AssertRdn(subjectReader, "2.5.4.11", 439, utf8String, bytes, "subject[OU]", "MSCOM");
            AssertRdn(subjectReader, "2.5.4.3", 455, utf8String, bytes, "subject[CN]", "www.microsoft.com");
            Assert.False(subjectReader.HasData, "subjectReader.HasData");

            AsnReader subjectPublicKeyInfo = tbsCertReader.ReadSequence();
            AsnReader spkiAlgorithm        = subjectPublicKeyInfo.ReadSequence();

            Assert.Equal("1.2.840.113549.1.1.1", spkiAlgorithm.ReadObjectIdentifierAsString());
            spkiAlgorithm.ReadNull();
            Assert.False(spkiAlgorithm.HasData, "spkiAlgorithm.HasData");

            Assert.True(
                subjectPublicKeyInfo.TryGetPrimitiveBitStringValue(
                    out unusedBitCount,
                    out ReadOnlyMemory <byte> encodedPublicKey),
                "subjectPublicKeyInfo.TryGetBitStringBytes");

            Assert.Equal(0, unusedBitCount);
            AssertRefSame(encodedPublicKey, ref bytes[498], "Encoded public key starts at byte 498");

            Assert.False(subjectPublicKeyInfo.HasData, "subjectPublicKeyInfo.HasData");

            AsnReader publicKeyReader    = new AsnReader(encodedPublicKey, AsnEncodingRules.DER);
            AsnReader rsaPublicKeyReader = publicKeyReader.ReadSequence();

            AssertRefSame(rsaPublicKeyReader.GetIntegerBytes(), ref bytes[506], "RSA Modulus is at bytes[502]");
            Assert.True(rsaPublicKeyReader.TryReadInt32(out int rsaExponent));
            Assert.Equal(65537, rsaExponent);
            Assert.False(rsaPublicKeyReader.HasData, "rsaPublicKeyReader.HasData");
            Assert.False(publicKeyReader.HasData, "publicKeyReader.HasData");

            AsnReader extensionsContainer = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            AsnReader extensions          = extensionsContainer.ReadSequence();

            Assert.False(extensionsContainer.HasData, "extensionsContainer.HasData");

            AsnReader sanExtension = extensions.ReadSequence();

            Assert.Equal("2.5.29.17", sanExtension.ReadObjectIdentifierAsString());
            Assert.True(sanExtension.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> sanExtensionBytes));
            Assert.False(sanExtension.HasData, "sanExtension.HasData");

            AsnReader sanExtensionPayload = new AsnReader(sanExtensionBytes, AsnEncodingRules.DER);
            AsnReader sanExtensionValue   = sanExtensionPayload.ReadSequence();

            Assert.False(sanExtensionPayload.HasData, "sanExtensionPayload.HasData");
            Asn1Tag dnsName = new Asn1Tag(TagClass.ContextSpecific, 2);

            Assert.Equal("www.microsoft.com", sanExtensionValue.GetCharacterString(dnsName, UniversalTagNumber.IA5String));
            Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.GetCharacterString(dnsName, UniversalTagNumber.IA5String));
            Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData");

            AsnReader basicConstraints = extensions.ReadSequence();

            Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifierAsString());
            Assert.True(basicConstraints.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> basicConstraintsBytes));

            AsnReader basicConstraintsPayload = new AsnReader(basicConstraintsBytes, AsnEncodingRules.DER);
            AsnReader basicConstraintsValue   = basicConstraintsPayload.ReadSequence();

            Assert.False(basicConstraintsValue.HasData, "basicConstraintsValue.HasData");
            Assert.False(basicConstraintsPayload.HasData, "basicConstraintsPayload.HasData");

            AsnReader keyUsageExtension = extensions.ReadSequence();

            Assert.Equal("2.5.29.15", keyUsageExtension.ReadObjectIdentifierAsString());
            Assert.True(keyUsageExtension.ReadBoolean(), "keyUsageExtension.ReadBoolean() (IsCritical)");
            Assert.True(keyUsageExtension.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> keyUsageBytes));

            AsnReader keyUsagePayload = new AsnReader(keyUsageBytes, AsnEncodingRules.DER);

            Assert.Equal(
                X509KeyUsageCSharpStyle.DigitalSignature | X509KeyUsageCSharpStyle.KeyEncipherment,
                keyUsagePayload.GetNamedBitListValue <X509KeyUsageCSharpStyle>());

            Assert.False(keyUsagePayload.HasData, "keyUsagePayload.HasData");

            AssertExtension(extensions, "2.5.29.37", false, 863, bytes);
            AssertExtension(extensions, "2.5.29.32", false, 894, bytes);
            AssertExtension(extensions, "2.5.29.35", false, 998, bytes);
            AssertExtension(extensions, "2.5.29.31", false, 1031, bytes);
            AssertExtension(extensions, "1.3.6.1.5.5.7.1.1", false, 1081, bytes);
            Assert.False(extensions.HasData, "extensions.HasData");

            Assert.Equal("1.2.840.113549.1.1.11", sigAlgReader.ReadObjectIdentifierAsString());
            sigAlgReader.ReadNull();
            Assert.False(sigAlgReader.HasData);
        }