Пример #1
0
        public static void TagMustBeCorrect_Custom_Indefinite(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = "A58005000000".HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

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

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

            Assert.Throws <CryptographicException>(() => reader.ReadSetOf());

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

            Assert.Throws <CryptographicException>(
                () => reader.ReadSetOf(new Asn1Tag(TagClass.Application, 5)));

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

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

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

            AsnReader seq = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 5));

            Assert.Equal("0500", seq.GetEncodedValue().ByteArrayToHex());

            Assert.False(reader.HasData, "HasData after reading value");
        }
Пример #2
0
        public static void ReadSetOf_DataSorting(
            AsnEncodingRules ruleSet,
            string inputHex,
            bool expectSuccess,
            int lastTagValue)
        {
            byte[] inputData = inputHex.HexToByteArray();

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

            AsnReader laxReader = new AsnReader(
                inputData,
                ruleSet,
                new AsnReaderOptions {
                SkipSetSortOrderVerification = true
            });

            if (expectSuccess)
            {
                setOf = reader.ReadSetOf();
            }
            else
            {
                AsnReader alsoReader = new AsnReader(inputData, ruleSet);
                Assert.Throws <AsnContentException>(() => alsoReader.ReadSetOf());
                Assert.Throws <AsnContentException>(() => laxReader.ReadSetOf(false));

                setOf = reader.ReadSetOf(skipSortOrderValidation: true);
            }

            int lastTag = -1;

            while (setOf.HasData)
            {
                Asn1Tag tag = setOf.PeekTag();
                lastTag = tag.TagValue;

                // Ignore the return, just drain it.
                setOf.ReadEncodedValue();
            }

            Assert.Equal(lastTagValue, lastTag);

            setOf   = laxReader.ReadSetOf();
            lastTag = -1;

            while (setOf.HasData)
            {
                Asn1Tag tag = setOf.PeekTag();
                lastTag = tag.TagValue;

                // Ignore the return, just drain it.
                setOf.ReadEncodedValue();
            }

            Assert.Equal(lastTagValue, lastTag);
        }
Пример #3
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OriginatorInfoAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for CertificateSet
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>();
                    System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem;

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

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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for RevocationInfoChoices
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        tmpItem = collectionReader.GetEncodedValue();
                        tmpList.Add(tmpItem);
                    }

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


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #4
0
        private static IEnumerable <KeyValuePair <string, string> > ReadReverseRdns(X500DistinguishedName name)
        {
            AsnReader x500NameReader = new AsnReader(name.RawData, AsnEncodingRules.DER);
            AsnReader sequenceReader = x500NameReader.ReadSequence();
            var       rdnReaders     = new Stack <AsnReader>();

            x500NameReader.ThrowIfNotEmpty();

            while (sequenceReader.HasData)
            {
                rdnReaders.Push(sequenceReader.ReadSetOf());
            }

            while (rdnReaders.Count > 0)
            {
                AsnReader rdnReader = rdnReaders.Pop();
                while (rdnReader.HasData)
                {
                    AsnReader tavReader = rdnReader.ReadSequence();
                    string    oid       = tavReader.ReadObjectIdentifierAsString();
                    string    value     = tavReader.ReadAnyAsnString();
                    tavReader.ThrowIfNotEmpty();
                    yield return(new KeyValuePair <string, string>(oid, value));
                }
            }
        }
Пример #5
0
        private SignerInfoCollection GetCounterSigners(AttributeAsn[] unsignedAttrs)
        {
            // Since each "attribute" can have multiple "attribute values" there's no real
            // correlation to a predictive size here.
            List <SignerInfo> signerInfos = new List <SignerInfo>();

            foreach (AttributeAsn attributeAsn in unsignedAttrs)
            {
                if (attributeAsn.AttrType.Value == Oids.CounterSigner)
                {
                    AsnReader reader     = new AsnReader(attributeAsn.AttrValues, AsnEncodingRules.BER);
                    AsnReader collReader = reader.ReadSetOf();

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

                    while (collReader.HasData)
                    {
                        SignerInfoAsn parsedData =
                            AsnSerializer.Deserialize <SignerInfoAsn>(collReader.GetEncodedValue(), AsnEncodingRules.BER);

                        SignerInfo signerInfo = new SignerInfo(ref parsedData, _document)
                        {
                            _parentSignerInfo = this
                        };

                        signerInfos.Add(signerInfo);
                    }
                }
            }

            return(new SignerInfoCollection(signerInfos.ToArray()));
        }
Пример #6
0
        internal static void Decode(AsnReader reader, out SignedAttributesSet decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for SignedAttributes
                {
                    collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>();
                    System.Security.Cryptography.Asn1.AttributeAsn tmpItem;

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

                    decoded.SignedAttributes = tmpList.ToArray();
                }
            }
            else
            {
                throw new CryptographicException();
            }
        }
Пример #7
0
        public static AttributeAsn[] NormalizeAttributeSet(
            AttributeAsn[] setItems,
            Action <byte[]> encodedValueProcessor = null)
        {
            byte[] normalizedValue;

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                writer.PushSetOf();
                foreach (AttributeAsn item in setItems)
                {
                    item.Encode(writer);
                }
                writer.PopSetOf();
                normalizedValue = writer.Encode();
                if (encodedValueProcessor != null)
                {
                    encodedValueProcessor(normalizedValue);
                }
            }

            AsnReader reader    = new AsnReader(normalizedValue, AsnEncodingRules.DER);
            AsnReader setReader = reader.ReadSetOf();

            AttributeAsn[] decodedSet = new AttributeAsn[setItems.Length];
            int            i          = 0;

            while (setReader.HasData)
            {
                AttributeAsn.Decode(setReader, out AttributeAsn item);
                decodedSet[i] = item;
                i++;
            }
            return(decodedSet);
        }
Пример #8
0
        public static void ReadSetOf_Success(
            PublicEncodingRules ruleSet,
            string inputHex,
            bool expectDataRemaining,
            int expectedSequenceTagNumber)
        {
            byte[] inputData = inputHex.HexToByteArray();

            AsnReader reader   = new AsnReader(inputData, (AsnEncodingRules)ruleSet);
            AsnReader sequence = reader.ReadSetOf();

            if (expectDataRemaining)
            {
                Assert.True(reader.HasData, "reader.HasData");
            }
            else
            {
                Assert.False(reader.HasData, "reader.HasData");
            }

            if (expectedSequenceTagNumber < 0)
            {
                Assert.False(sequence.HasData, "sequence.HasData");
            }
            else
            {
                Assert.True(sequence.HasData, "sequence.HasData");

                Asn1Tag firstTag = sequence.PeekTag();
                Assert.Equal(expectedSequenceTagNumber, firstTag.TagValue);
            }
        }
        public static IReadOnlyList <string> GetNameInfo(this X509Certificate2 certificate, string nameTypeOid, X509NameSource nameSource)
        {
            ThrowHelpers.CheckNullOrEempty(nameof(nameTypeOid), nameTypeOid);

            byte[] nameBytes = nameSource switch
            {
                X509NameSource.Issuer => certificate.IssuerName.RawData,
                X509NameSource.Subject => certificate.SubjectName.RawData,
                _ => ThrowHelpers.NotSupport <byte[], X509NameSource>(nameSource)
            };

            List <string> result = new List <string>();

            AsnReader nameReader   = new AsnReader(nameBytes, AsnEncodingRules.DER);
            AsnReader mainSequence = nameReader.ReadSequence();

            while (mainSequence.HasData)
            {
                AsnReader x509Name = mainSequence.ReadSetOf().ReadSequence();
                string    oid      = x509Name.ReadObjectIdentifierAsString();
                if (string.Equals(nameTypeOid, oid, StringComparison.Ordinal))
                {
                    result.Add(x509Name.GetCharacterString(UniversalTagNumber.PrintableString));
                }
            }

            return(result);
        }
    }
Пример #10
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out X501AttributeAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            decoded.AttrId = sequenceReader.ReadObjectIdentifier();

            // Decode SEQUENCE OF for AttrValues
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <ReadOnlyMemory <byte> >();
                ReadOnlyMemory <byte> tmpItem;

                while (collectionReader.HasData)
                {
                    tmpItem = collectionReader.GetEncodedValue();
                    tmpList.Add(tmpItem);
                }

                decoded.AttrValues = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #11
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignerInfoAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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

            System.Security.Cryptography.Pkcs.Asn1.SignerIdentifierAsn.Decode(sequenceReader, out decoded.Sid);
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.DigestAlgorithm);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                decoded.SignedAttributes = sequenceReader.ReadEncodedValue();
            }

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

            if (sequenceReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpSignatureValue))
            {
                decoded.SignatureValue = tmpSignatureValue;
            }
            else
            {
                decoded.SignatureValue = sequenceReader.ReadOctetString();
            }


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

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

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


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #12
0
        public static void ReadSetOf_Throws(
            string description,
            PublicEncodingRules ruleSet,
            string inputHex)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            Assert.Throws <CryptographicException>(() => reader.ReadSetOf());
        }
Пример #13
0
        public static void ReadSetOf_Throws(
            string description,
            AsnEncodingRules ruleSet,
            string inputHex)
        {
            _ = description;
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            Assert.Throws <AsnContentException>(() => reader.ReadSetOf());
        }
Пример #14
0
        private List <IFilterChoice> DecodeRecursiveFilterSets(AsnReader reader)
        {
            AsnReader            subReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, reader.PeekTag().TagValue));
            List <IFilterChoice> filters   = new List <IFilterChoice>();

            while (subReader.HasData)
            {
                filters.Add(DecodeSearchFilter(subReader));
            }

            return(filters);
        }
Пример #15
0
        public static void TagMustBeCorrect_Universal_Indefinite(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = "318005000000".HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            Assert.Throws <ArgumentException>(
                "expectedTag",
                () => reader.ReadSetOf(Asn1Tag.Null));

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

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

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

            AsnReader seq = reader.ReadSetOf();

            Assert.Equal("0500", seq.ReadEncodedValue().ByteArrayToHex());

            Assert.False(reader.HasData, "HasData after read");
        }
Пример #16
0
        public static void ReadSetOf_DataSorting(
            PublicEncodingRules ruleSet,
            string inputHex,
            bool expectSuccess,
            int lastTagValue)
        {
            byte[] inputData = inputHex.HexToByteArray();

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

            if (expectSuccess)
            {
                setOf = reader.ReadSetOf();
            }
            else
            {
                AsnReader alsoReader = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

                Assert.Throws <CryptographicException>(() => alsoReader.ReadSetOf());

                setOf = reader.ReadSetOf(skipSortOrderValidation: true);
            }

            int lastTag = -1;

            while (setOf.HasData)
            {
                Asn1Tag tag = setOf.PeekTag();
                lastTag = tag.TagValue;

                // Ignore the return, just drain it.
                setOf.GetEncodedValue();
            }

            Assert.Equal(lastTagValue, lastTag);
        }
Пример #17
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1PartialAttribute decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


            if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpType))
            {
                decoded.Type = tmpType;
            }
            else
            {
                decoded.Type = sequenceReader.ReadOctetString();
            }


            // Decode SEQUENCE OF for Values
            {
                collectionReader = sequenceReader.ReadSetOf();
                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.Values = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal static T[] ReadSetOf <T>(this AsnReader reader, Func <AsnReader, T> readElement)
        {
            IEnumerable <T> ReadSetOfCore()
            {
                var set = reader.ReadSetOf();

                while (set.HasData)
                {
                    yield return(readElement(set));
                }
                set.ThrowIfNotEmpty();
            }

            // ToArray to ensure immediate materialization. If done lazily, it will break integrity validation, as the data wont be consumed.
            return(ReadSetOfCore().ToArray());
        }
        private static IEnumerable <KeyValuePair <string, string> > ReadReverseRdns(X500DistinguishedName name)
        {
            Stack <AsnReader> rdnReaders;

            try
            {
                AsnReader x500NameReader = new AsnReader(name.RawData, AsnEncodingRules.DER);
                AsnReader sequenceReader = x500NameReader.ReadSequence();
                x500NameReader.ThrowIfNotEmpty();
                rdnReaders = new Stack <AsnReader>();

                while (sequenceReader.HasData)
                {
                    rdnReaders.Push(sequenceReader.ReadSetOf());
                }
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }

            while (rdnReaders.Count > 0)
            {
                AsnReader rdnReader = rdnReaders.Pop();
                while (rdnReader.HasData)
                {
                    string oid;
                    string value;

                    try
                    {
                        AsnReader tavReader = rdnReader.ReadSequence();
                        oid   = tavReader.ReadObjectIdentifier();
                        value = tavReader.ReadAnyAsnString();
                        tavReader.ThrowIfNotEmpty();
                    }
                    catch (AsnContentException e)
                    {
                        throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
                    }

                    yield return(new KeyValuePair <string, string>(oid, value));
                }
            }
        }
Пример #20
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);

            AsnReader val1 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, true));

            Assert.False(reader.HasData);

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

            AsnReader val2 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, false));

            Assert.False(reader.HasData);

            Assert.Equal(val1.GetEncodedValue().ByteArrayToHex(), val2.GetEncodedValue().ByteArrayToHex());
        }
Пример #21
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EncryptedDataAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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

            System.Security.Cryptography.Pkcs.Asn1.EncryptedContentInfoAsn.Decode(sequenceReader, out decoded.EncryptedContentInfo);

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

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

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


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #22
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SafeBagAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            decoded.BagId = sequenceReader.ReadObjectIdentifierAsString();

            explicitReader   = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            decoded.BagValue = explicitReader.GetEncodedValue();
            explicitReader.ThrowIfNotEmpty();


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.SetOf))
            {
                // Decode SEQUENCE OF for BagAttributes
                {
                    collectionReader = sequenceReader.ReadSetOf();
                    var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>();
                    System.Security.Cryptography.Asn1.AttributeAsn tmpItem;

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

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


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #23
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificationRequestInfoAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            decoded.Version = sequenceReader.GetInteger();
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

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

            // Decode SEQUENCE OF for Attributes
            {
                collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>();
                System.Security.Cryptography.Asn1.AttributeAsn tmpItem;

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

                decoded.Attributes = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #24
0
        private static void AssertRdn(
            AsnReader reader,
            string atvOid,
            int offset,
            Asn1Tag valueTag,
            byte[] bytes,
            string label,
            string stringValue = null)
        {
            AsnReader rdn = reader.ReadSetOf();
            AsnReader attributeTypeAndValue = rdn.ReadSequence();

            Assert.Equal(atvOid, attributeTypeAndValue.ReadObjectIdentifier());

            ReadOnlyMemory <byte> value     = attributeTypeAndValue.ReadEncodedValue();
            ReadOnlySpan <byte>   valueSpan = value.Span;

            Assert.True(Asn1Tag.TryDecode(valueSpan, out Asn1Tag actualTag, out int bytesRead));
            Assert.Equal(1, bytesRead);
            Assert.Equal(valueTag, actualTag);

            AssertRefSame(
                ref MemoryMarshal.GetReference(valueSpan),
                ref bytes[offset],
                $"{label} is at bytes[{offset}]");

            if (stringValue != null)
            {
                AsnReader valueReader = new AsnReader(value, AsnEncodingRules.DER);
                Assert.Equal(stringValue, valueReader.ReadCharacterString((UniversalTagNumber)valueTag.TagValue));
                Assert.False(valueReader.HasData, "valueReader.HasData");
            }

            Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})");
            Assert.False(rdn.HasData, $"rdn.HasData ({label})");
        }
Пример #25
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignedDataAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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


            // Decode SEQUENCE OF for DigestAlgorithms
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn>();
                System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn tmpItem;

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

                decoded.DigestAlgorithms = tmpList.ToArray();
            }

            System.Security.Cryptography.Pkcs.Asn1.EncapsulatedContentInfoAsn.Decode(sequenceReader, out decoded.EncapContentInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for CertificateSet
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>();
                    System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem;

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

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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Crls
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        tmpItem = collectionReader.ReadEncodedValue();
                        tmpList.Add(tmpItem);
                    }

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


            // Decode SEQUENCE OF for SignerInfos
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn>();
                System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn tmpItem;

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

                decoded.SignerInfos = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Пример #26
0
        private static string X500DistinguishedNameDecode(
            byte[] encodedName,
            bool printOid,
            bool reverse,
            bool quoteIfNeeded,
            string dnSeparator,
            string multiValueSeparator,
            bool addTrailingDelimiter)
        {
            try
            {
                AsnReader x500NameReader         = new AsnReader(encodedName, AsnEncodingRules.DER);
                AsnReader x500NameSequenceReader = x500NameReader.ReadSequence();
                var       rdnReaders             = new List <AsnReader>();

                x500NameReader.ThrowIfNotEmpty();

                while (x500NameSequenceReader.HasData)
                {
                    // To match Windows' behavior, permit multi-value RDN SETs to not
                    // be DER sorted.
                    rdnReaders.Add(x500NameSequenceReader.ReadSetOf(skipSortOrderValidation: true));
                }

                // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual
                // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting
                // too much space in the average case.
                //
                // So, let's look at an example of what our output might be.
                //
                // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs):
                //   businessCategory=Private Organization
                //   1.3.6.1.4.1.311.60.2.1.3=US
                //   1.3.6.1.4.1.311.60.2.1.2=Delaware
                //   serialNumber=5157550
                //   street=548 4th Street
                //   postalCode=94107
                //   C=US
                //   ST=California
                //   L=San Francisco
                //   O=GitHub, Inc.
                //   CN=github.com
                //
                // Which comes out to 228 characters using OpenSSL's default pretty-print
                // (openssl x509 -in github.cer -text -noout)
                // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values
                // and round that up to the next programmer number, and you get that 512 should avoid reallocations
                // in all but the most dire of cases.
                StringBuilder decodedName  = new StringBuilder(512);
                int           entryCount   = rdnReaders.Count;
                bool          printSpacing = false;

                for (int i = 0; i < entryCount; i++)
                {
                    int loc = reverse ? entryCount - i - 1 : i;

                    // RelativeDistinguishedName ::=
                    //   SET SIZE (1..MAX) OF AttributeTypeAndValue
                    //
                    // AttributeTypeAndValue::= SEQUENCE {
                    //   type AttributeType,
                    //   value    AttributeValue }
                    //
                    // AttributeType::= OBJECT IDENTIFIER
                    //
                    // AttributeValue ::= ANY-- DEFINED BY AttributeType

                    if (printSpacing)
                    {
                        decodedName.Append(dnSeparator);
                    }
                    else
                    {
                        printSpacing = true;
                    }

                    AsnReader rdnReader = rdnReaders[loc];
                    bool      hadValue  = false;

                    while (rdnReader.HasData)
                    {
                        AsnReader tavReader      = rdnReader.ReadSequence();
                        string    oid            = tavReader.ReadObjectIdentifier();
                        string    attributeValue = tavReader.ReadAnyAsnString();

                        tavReader.ThrowIfNotEmpty();

                        if (hadValue)
                        {
                            decodedName.Append(multiValueSeparator);
                        }
                        else
                        {
                            hadValue = true;
                        }

                        if (printOid)
                        {
                            AppendOid(decodedName, oid);
                        }

                        bool quote = quoteIfNeeded && NeedsQuoting(attributeValue);

                        if (quote)
                        {
                            decodedName.Append('"');

                            // If the RDN itself had a quote within it, that quote needs to be escaped
                            // with another quote.
                            attributeValue = attributeValue.Replace("\"", "\"\"");
                        }

                        decodedName.Append(attributeValue);

                        if (quote)
                        {
                            decodedName.Append('"');
                        }
                    }
                }

                if (addTrailingDelimiter && decodedName.Length > 0)
                {
                    decodedName.Append(dnSeparator);
                }

                return(decodedName.ToString());
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Пример #27
0
        internal static void Decode(AsnReader reader, out Asn1Filter decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for And
                {
                    collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var        tmpList = new List <Asn1Filter>();
                    Asn1Filter tmpItem;

                    while (collectionReader.HasData)
                    {
                        Asn1Filter.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.And = tmpList.ToArray();
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Or
                {
                    collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var        tmpList = new List <Asn1Filter>();
                    Asn1Filter tmpItem;

                    while (collectionReader.HasData)
                    {
                        Asn1Filter.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Or = tmpList.ToArray();
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
                Asn1Filter tmpNot;
                Asn1Filter.Decode(explicitReader, out tmpNot);
                decoded.Not = tmpNot;

                explicitReader.ThrowIfNotEmpty();
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                Asn1AttributeValueAssertion tmpEqualityMatch;
                Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 3), out tmpEqualityMatch);
                decoded.EqualityMatch = tmpEqualityMatch;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4)))
            {
                Asn1SubstringFilter tmpSubstrings;
                Asn1SubstringFilter.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 4), out tmpSubstrings);
                decoded.Substrings = tmpSubstrings;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5)))
            {
                Asn1AttributeValueAssertion tmpGreaterOrEqual;
                Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 5), out tmpGreaterOrEqual);
                decoded.GreaterOrEqual = tmpGreaterOrEqual;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6)))
            {
                Asn1AttributeValueAssertion tmpLessOrEqual;
                Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 6), out tmpLessOrEqual);
                decoded.LessOrEqual = tmpLessOrEqual;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7)))
            {
                if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 7), out ReadOnlyMemory <byte> tmpPresent))
                {
                    decoded.Present = tmpPresent;
                }
                else
                {
                    decoded.Present = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 7));
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8)))
            {
                Asn1AttributeValueAssertion tmpApproxMatch;
                Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 8), out tmpApproxMatch);
                decoded.ApproxMatch = tmpApproxMatch;
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9)))
            {
                Asn1MatchingRuleAssertion tmpExtensibleMatch;
                Asn1MatchingRuleAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 9), out tmpExtensibleMatch);
                decoded.ExtensibleMatch = tmpExtensibleMatch;
            }
            else
            {
                throw new CryptographicException();
            }
        }
Пример #28
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();
        }