Пример #1
0
        public static void ReadNull_Throws(string description, AsnEncodingRules ruleSet, string inputHex)
        {
            _ = description;
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            Assert.Throws <AsnContentException>(() => reader.ReadNull());
        }
Пример #2
0
        public static void ReadNull_Success(AsnEncodingRules ruleSet, string inputHex)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            reader.ReadNull();
            Assert.False(reader.HasData, "reader.HasData");
        }
Пример #3
0
        public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = { 5, 0 };
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.ReadNull(new Asn1Tag(UniversalTagNumber.Integer)));

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

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

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

            reader.ReadNull();
            Assert.False(reader.HasData, "HasData after read");
        }
Пример #4
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1Substring decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            reader.ReadNull(expectedTag);
            Decode(reader, out decoded);
        }
Пример #5
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);

            reader.ReadNull(new Asn1Tag((TagClass)tagClass, tagValue, true));
            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet);
            reader.ReadNull(new Asn1Tag((TagClass)tagClass, tagValue, false));
            Assert.False(reader.HasData);
        }
Пример #6
0
            public DigestAlgorithmIdentifier(AsnReader asnReader)
            {
                asnReader      = asnReader.ReadSequence();
                this.algorithm = asnReader.ReadObjectIdentifier();
                if (asnReader.PeekTag() == Asn1Tag.Null)
                {
                    asnReader.ReadNull();
                    this.parameters = null;
                }
                else
                {
                    this.parameters = asnReader.ReadEncodedValue().ToArray();
                };

                asnReader.ThrowIfNotEmpty();
            }
Пример #7
0
        internal static void Decode(AsnReader reader, out Asn1ProtocolOp decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new Asn1ProtocolOp();
            Asn1Tag   tag = reader.PeekTag();
            AsnReader collectionReader;

            if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 0)))
            {
                Asn1BindRequest tmpBindRequest;
                Asn1BindRequest.Decode(reader, new Asn1Tag(TagClass.Application, 0), out tmpBindRequest);
                decoded.BindRequest = tmpBindRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 1)))
            {
                Asn1BindResponse tmpBindResponse;
                Asn1BindResponse.Decode(reader, new Asn1Tag(TagClass.Application, 1), out tmpBindResponse);
                decoded.BindResponse = tmpBindResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 2)))
            {
                reader.ReadNull(new Asn1Tag(TagClass.Application, 2));
                decoded.UnbindRequest = true;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 3)))
            {
                Asn1SearchRequest tmpSearchRequest;
                Asn1SearchRequest.Decode(reader, new Asn1Tag(TagClass.Application, 3), out tmpSearchRequest);
                decoded.SearchRequest = tmpSearchRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 4)))
            {
                Asn1SearchResultEntry tmpSearchResEntry;
                Asn1SearchResultEntry.Decode(reader, new Asn1Tag(TagClass.Application, 4), out tmpSearchResEntry);
                decoded.SearchResEntry = tmpSearchResEntry;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 5)))
            {
                Asn1LDAPResult tmpSearchResultDone;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 5), out tmpSearchResultDone);
                decoded.SearchResultDone = tmpSearchResultDone;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 19)))
            {
                // Decode SEQUENCE OF for SearchResultReference
                {
                    collectionReader = reader.ReadSequence(new Asn1Tag(TagClass.Application, 19));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        if (collectionReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmp))
                        {
                            tmpItem = tmp;
                        }
                        else
                        {
                            tmpItem = collectionReader.ReadOctetString();
                        }

                        tmpList.Add(tmpItem);
                    }

                    decoded.SearchResultReference = tmpList.ToArray();
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 6)))
            {
                Asn1ModifyRequest tmpModifyRequest;
                Asn1ModifyRequest.Decode(reader, new Asn1Tag(TagClass.Application, 6), out tmpModifyRequest);
                decoded.ModifyRequest = tmpModifyRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 7)))
            {
                Asn1LDAPResult tmpModifyResponse;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 7), out tmpModifyResponse);
                decoded.ModifyResponse = tmpModifyResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 8)))
            {
                Asn1AddRequest tmpAddRequest;
                Asn1AddRequest.Decode(reader, new Asn1Tag(TagClass.Application, 8), out tmpAddRequest);
                decoded.AddRequest = tmpAddRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 9)))
            {
                Asn1LDAPResult tmpAddResponse;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 9), out tmpAddResponse);
                decoded.AddResponse = tmpAddResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 10)))
            {
                if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.Application, 10), out ReadOnlyMemory <byte> tmpDelRequest))
                {
                    decoded.DelRequest = tmpDelRequest;
                }
                else
                {
                    decoded.DelRequest = reader.ReadOctetString(new Asn1Tag(TagClass.Application, 10));
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 11)))
            {
                Asn1LDAPResult tmpDelResponse;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 11), out tmpDelResponse);
                decoded.DelResponse = tmpDelResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 12)))
            {
                Asn1ModifyDNRequest tmpModifyDNRequest;
                Asn1ModifyDNRequest.Decode(reader, new Asn1Tag(TagClass.Application, 12), out tmpModifyDNRequest);
                decoded.ModifyDNRequest = tmpModifyDNRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 13)))
            {
                Asn1LDAPResult tmpModifyDNResponse;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 13), out tmpModifyDNResponse);
                decoded.ModifyDNResponse = tmpModifyDNResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 14)))
            {
                Asn1CompareRequest tmpCompareRequest;
                Asn1CompareRequest.Decode(reader, new Asn1Tag(TagClass.Application, 14), out tmpCompareRequest);
                decoded.CompareRequest = tmpCompareRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 15)))
            {
                Asn1LDAPResult tmpCompareResponse;
                Asn1LDAPResult.Decode(reader, new Asn1Tag(TagClass.Application, 15), out tmpCompareResponse);
                decoded.CompareResponse = tmpCompareResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 16)))
            {
                if (reader.TryReadInt32(new Asn1Tag(TagClass.Application, 16), out int tmpAbandonRequest))
                {
                    decoded.AbandonRequest = tmpAbandonRequest;
                }
                else
                {
                    reader.ThrowIfNotEmpty();
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 23)))
            {
                Asn1ExtendedRequest tmpExtendedRequest;
                Asn1ExtendedRequest.Decode(reader, new Asn1Tag(TagClass.Application, 23), out tmpExtendedRequest);
                decoded.ExtendedRequest = tmpExtendedRequest;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 24)))
            {
                Asn1ExtendedResponse tmpExtendedResponse;
                Asn1ExtendedResponse.Decode(reader, new Asn1Tag(TagClass.Application, 24), out tmpExtendedResponse);
                decoded.ExtendedResponse = tmpExtendedResponse;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.Application, 25)))
            {
                Asn1IntermediateResponse tmpIntermediateResponse;
                Asn1IntermediateResponse.Decode(reader, new Asn1Tag(TagClass.Application, 25), out tmpIntermediateResponse);
                decoded.IntermediateResponse = tmpIntermediateResponse;
            }
            else
            {
                throw new CryptographicException();
            }
        }
Пример #8
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.TryReadPrimitiveBitString(
                    out int unusedBitCount,
                    out ReadOnlyMemory <byte> signature),
                "certReader.TryReadPrimitiveBitStringValue");

            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.ReadIntegerBytes();

            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.ReadObjectIdentifier());
            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.ReadUtcTime());
            Assert.Equal(new DateTimeOffset(2016, 10, 15, 23, 59, 59, TimeSpan.Zero), validityReader.ReadUtcTime());
            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.ReadObjectIdentifier());
            spkiAlgorithm.ReadNull();
            Assert.False(spkiAlgorithm.HasData, "spkiAlgorithm.HasData");

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

            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.ReadIntegerBytes(), 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.ReadObjectIdentifier());
            Assert.True(sanExtension.TryReadPrimitiveOctetString(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.ReadCharacterString(UniversalTagNumber.IA5String, dnsName));
            Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.ReadCharacterString(UniversalTagNumber.IA5String, dnsName));
            Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData");

            AsnReader basicConstraints = extensions.ReadSequence();

            Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifier());
            Assert.True(basicConstraints.TryReadPrimitiveOctetString(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.ReadObjectIdentifier());
            Assert.True(keyUsageExtension.ReadBoolean(), "keyUsageExtension.ReadBoolean() (IsCritical)");
            Assert.True(keyUsageExtension.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> keyUsageBytes));

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

            Assert.Equal(
                X509KeyUsageCSharpStyle.DigitalSignature | X509KeyUsageCSharpStyle.KeyEncipherment,
                keyUsagePayload.ReadNamedBitListValue <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.ReadObjectIdentifier());
            sigAlgReader.ReadNull();
            Assert.False(sigAlgReader.HasData);
        }
Пример #9
0
        public static void ReadSequenceOf_PreservesOptions(AsnEncodingRules ruleSet)
        {
            // [5] (UtcTime) 500102123456Z
            // UtcTime 120102235959Z
            //
            // They're sorted backwards, though.
            const string PayloadHex =
                "850D3530303130323132333435365A" +
                "170D3132303130323233353935395A";

            byte[] inputData;

            // Build the rule-specific form of SEQUENCE { [PRIVATE 9] SEQUENCE { SET-OF { dates }, NULL } }
            // The outer Set-Of is also invalid, because the NULL should be first.
            if (ruleSet == AsnEncodingRules.DER)
            {
                inputData = ("3024" + "E922" + "A21E" + PayloadHex + "0500").HexToByteArray();
            }
            else
            {
                string inputHex = "3080" + "E980" + "A280" + PayloadHex + "0000" + "0500" + "0000" + "0000";
                inputData = inputHex.HexToByteArray();
            }

            AsnReaderOptions options = new AsnReaderOptions
            {
                SkipSetSortOrderVerification = true,
                UtcTimeTwoDigitYearMax       = 2011,
            };

            AsnReader initial = new AsnReader(inputData, ruleSet, options);
            AsnReader outer   = initial.ReadSequence();

            Assert.False(initial.HasData);
            AsnReader inner = outer.ReadSequence(new Asn1Tag(TagClass.Private, 9));

            Assert.False(outer.HasData);

            Asn1Tag setTag = new Asn1Tag(TagClass.ContextSpecific, 2);

            if (ruleSet != AsnEncodingRules.BER)
            {
                Assert.Throws <AsnContentException>(() => inner.ReadSetOf(false, setTag));
            }

            // This confirms that we've passed SkipSetOrderVerification this far.
            AsnReader setOf = inner.ReadSetOf(setTag);

            Assert.True(inner.HasData);

            Assert.Equal(
                new DateTimeOffset(1950, 1, 2, 12, 34, 56, TimeSpan.Zero),
                setOf.ReadUtcTime(new Asn1Tag(TagClass.ContextSpecific, 5)));

            // This confirms that we've passed UtcTimeTwoDigitYearMax,
            // the default would call this 2012.
            Assert.Equal(
                new DateTimeOffset(1912, 1, 2, 23, 59, 59, TimeSpan.Zero),
                setOf.ReadUtcTime());

            Assert.False(setOf.HasData);

            inner.ReadNull();
            Assert.False(inner.HasData);

            setOf.ThrowIfNotEmpty();
            inner.ThrowIfNotEmpty();
            outer.ThrowIfNotEmpty();
            initial.ThrowIfNotEmpty();
        }