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

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

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

            Assert.Throws <AsnContentException>(() => reader.ReadUtcTime());

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

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

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

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

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

            Assert.Equal(
                new DateTimeOffset(2016, 11, 6, 1, 23, 45, TimeSpan.Zero),
                reader.ReadGeneralizedTime(new Asn1Tag(TagClass.ContextSpecific, 5)));

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

            AsnReader berReader = new AsnReader(inputData, AsnEncodingRules.BER);

            Assert.Throws <CryptographicException>(() => berReader.ReadGeneralizedTime(disallowFractions: true));

            // Legit if the fraction is allowed
            berReader.ReadGeneralizedTime();
            Assert.False(berReader.HasData, "berReader.HasData");
        }
Пример #3
0
        public static void ExcessivelyPreciseNonFraction()
        {
            byte[]    inputData = Text.Encoding.ASCII.GetBytes("\u0018\u002A2017092118.012345678901234567890123Q56789Z");
            AsnReader berReader = new AsnReader(inputData, AsnEncodingRules.BER);

            Assert.Throws <AsnContentException>(() => berReader.ReadGeneralizedTime());
        }
Пример #4
0
        public static void MultiSegmentExcessivelyPreciseFraction(AsnEncodingRules ruleSet)
        {
            // This builds "20171207173522.0000...0001Z" where the Z required a second CER segment.
            // This is a bit of nonsense, really, because it is encoding 1e-985 seconds, which is
            // oodles of orders of magnitude smaller than Planck time (~5e-44).
            // But, the spec says "any number of decimal places", and 985 is a number.

            // A0 80 (context specifc 0, constructed, indefinite length)
            //    04 82 03 E8 (octet string, primitive, 1000 bytes)
            //       ASCII("20171207173522." + new string('0', 984) + '1')
            //    04 01 (octet string, primitive, 1 byte)
            //       ASCII("Z")
            //    00 00 (end of contents)
            //
            // 1001 content bytes + 10 bytes of structure.
            byte[] header    = "A080048203E8".HexToByteArray();
            byte[] contents0 = Text.Encoding.ASCII.GetBytes("20171207173522." + new string('0', 984) + "1");
            byte[] cdr       = { 0x04, 0x01, (byte)'Z', 0x00, 0x00 };
            byte[] inputData = header.Concat(contents0).Concat(cdr).ToArray();

            AsnReader      reader   = new AsnReader(inputData, ruleSet);
            DateTimeOffset value    = reader.ReadGeneralizedTime(new Asn1Tag(TagClass.ContextSpecific, 0));
            DateTimeOffset expected = new DateTimeOffset(2017, 12, 7, 17, 35, 22, TimeSpan.Zero);

            Assert.Equal(expected, value);
        }
Пример #5
0
        public static void GetGeneralizedTime_Throws(string description, string inputHex)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, AsnEncodingRules.BER);

            Assert.Throws <CryptographicException>(() => reader.ReadGeneralizedTime());
        }
Пример #6
0
        public static void ExcessivelyPreciseFraction_OneTenthPlusEpsilon()
        {
            byte[] inputData = Text.Encoding.ASCII.GetBytes("\u0018\u002A20170921180044.10000000000000000000000001Z");

            AsnReader      derReader = new AsnReader(inputData, AsnEncodingRules.DER);
            DateTimeOffset value     = derReader.ReadGeneralizedTime();

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

            DateTimeOffset expected = new DateTimeOffset(2017, 9, 21, 18, 0, 44, 100, TimeSpan.Zero);

            Assert.Equal(expected, value);
        }
Пример #7
0
        public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = "180F32303136313130363031323334355A".HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

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

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

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

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

            Assert.Equal(
                new DateTimeOffset(2016, 11, 6, 1, 23, 45, TimeSpan.Zero),
                reader.ReadGeneralizedTime());

            Assert.False(reader.HasData, "HasData after read");
        }
Пример #8
0
        public static void ExcessivelyPreciseFraction()
        {
            byte[] inputData = Text.Encoding.ASCII.GetBytes("\u0018\u002A2017092118.012345678901234567890123456789Z");

            AsnReader      berReader = new AsnReader(inputData, AsnEncodingRules.BER);
            DateTimeOffset value     = berReader.ReadGeneralizedTime();

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

            DateTimeOffset expected = new DateTimeOffset(2017, 9, 21, 18, 0, 44, 444, TimeSpan.Zero);

            expected += new TimeSpan(4440);

            Assert.Equal(expected, value);
        }
Пример #9
0
        public static void MaximumEffectivePrecision(AsnEncodingRules ruleSet, string dateAscii)
        {
            DateTimeOffset expectedTime = new DateTimeOffset(2017, 12, 19, 0, 4, 6, TimeSpan.Zero);

            expectedTime += new TimeSpan(TimeSpan.TicksPerSecond - 9);

            byte[] inputData = new byte[dateAscii.Length + 2];
            inputData[0] = 0x18;
            inputData[1] = (byte)dateAscii.Length;
            Text.Encoding.ASCII.GetBytes(dateAscii, 0, dateAscii.Length, inputData, 2);

            AsnReader reader = new AsnReader(inputData, ruleSet);

            Assert.Equal(expectedTime, reader.ReadGeneralizedTime());
        }
Пример #10
0
        public static void ParseTime_BerOnly(string inputHex)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader cerReader = new AsnReader(inputData, AsnEncodingRules.CER);
            AsnReader derReader = new AsnReader(inputData, AsnEncodingRules.DER);

            Assert.Throws <AsnContentException>(() => cerReader.ReadGeneralizedTime());
            Assert.Throws <AsnContentException>(() => derReader.ReadGeneralizedTime());

            // Prove it was not just corrupt input
            AsnReader berReader = new AsnReader(inputData, AsnEncodingRules.BER);

            berReader.ReadGeneralizedTime();
            Assert.False(berReader.HasData, "berReader.HasData");
            Assert.True(cerReader.HasData, "cerReader.HasData");
            Assert.True(derReader.HasData, "derReader.HasData");
        }
Пример #11
0
        public static void ParseTime_Valid(
            AsnEncodingRules ruleSet,
            string inputHex,
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            int millisecond,
            int?offsetHour,
            int offsetMinute)
        {
            byte[] inputData = inputHex.HexToByteArray();

            AsnReader      reader = new AsnReader(inputData, ruleSet);
            DateTimeOffset value  = reader.ReadGeneralizedTime();

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

            Assert.Equal(year, value.Year);
            Assert.Equal(month, value.Month);
            Assert.Equal(day, value.Day);
            Assert.Equal(hour, value.Hour);
            Assert.Equal(minute, value.Minute);
            Assert.Equal(second, value.Second);
            Assert.Equal(millisecond, value.Millisecond);

            TimeSpan timeOffset;

            if (offsetHour == null)
            {
                // Ask the system what offset it thinks was relevant for that time.
                // Includes DST ambiguity.
                timeOffset = new DateTimeOffset(value.LocalDateTime).Offset;
            }
            else
            {
                timeOffset = new TimeSpan(offsetHour.Value, offsetMinute, 0);
            }

            Assert.Equal(timeOffset, value.Offset);
        }
Пример #12
0
        public static void ExcessivelyPreciseFraction_OneTenthPlusEpsilonAndZero()
        {
            byte[] inputData = Text.Encoding.ASCII.GetBytes("\u0018\u002A20170921180044.10000000000000000000000010Z");

            AsnReader      berReader = new AsnReader(inputData, AsnEncodingRules.BER);
            DateTimeOffset value     = berReader.ReadGeneralizedTime();

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

            DateTimeOffset expected = new DateTimeOffset(2017, 9, 21, 18, 0, 44, 100, TimeSpan.Zero);

            Assert.Equal(expected, value);

            AsnReader cerReader = new AsnReader(inputData, AsnEncodingRules.CER);
            AsnReader derReader = new AsnReader(inputData, AsnEncodingRules.DER);

            Assert.Throws <CryptographicException>(() => cerReader.ReadGeneralizedTime());
            Assert.Throws <CryptographicException>(() => derReader.ReadGeneralizedTime());
        }
Пример #13
0
        public static void ExpectedTag_IgnoresConstructed(
            AsnEncodingRules ruleSet,
            string inputHex,
            TagClass tagClass,
            int tagValue)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            DateTimeOffset val1 = reader.ReadGeneralizedTime(new Asn1Tag(tagClass, tagValue, true));

            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);

            DateTimeOffset val2 = reader.ReadGeneralizedTime(new Asn1Tag(tagClass, tagValue, false));

            Assert.False(reader.HasData);

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

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

            if (tag.HasSameClassAndValue(Asn1Tag.UtcTime))
            {
                decoded.UtcTime = reader.ReadUtcTime();
            }
            else if (tag.HasSameClassAndValue(Asn1Tag.GeneralizedTime))
            {
                decoded.GeneralTime = reader.ReadGeneralizedTime();
            }
            else
            {
                throw new CryptographicException();
            }
        }
Пример #15
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out RecipientKeyIdentifier decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.GeneralizedTime))
            {
                decoded.Date = sequenceReader.ReadGeneralizedTime();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence))
            {
                System.Security.Cryptography.Pkcs.Asn1.OtherKeyAttributeAsn tmpOther;
                System.Security.Cryptography.Pkcs.Asn1.OtherKeyAttributeAsn.Decode(sequenceReader, out tmpOther);
                decoded.Other = tmpOther;
            }


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

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


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

            decoded.Policy = sequenceReader.ReadObjectIdentifier();
            System.Security.Cryptography.Pkcs.Asn1.MessageImprint.Decode(sequenceReader, out decoded.MessageImprint);
            decoded.SerialNumber = sequenceReader.ReadIntegerBytes();
            decoded.GenTime      = sequenceReader.ReadGeneralizedTime();

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence))
            {
                System.Security.Cryptography.Pkcs.Asn1.Rfc3161Accuracy tmpAccuracy;
                System.Security.Cryptography.Pkcs.Asn1.Rfc3161Accuracy.Decode(sequenceReader, out tmpAccuracy);
                decoded.Accuracy = tmpAccuracy;
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean))
            {
                decoded.Ordering = sequenceReader.ReadBoolean();
            }
            else
            {
                defaultReader    = new AsnReader(s_defaultOrdering, AsnEncodingRules.DER);
                decoded.Ordering = defaultReader.ReadBoolean();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer))
            {
                decoded.Nonce = sequenceReader.ReadIntegerBytes();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                System.Security.Cryptography.Asn1.GeneralNameAsn tmpTsa;
                System.Security.Cryptography.Asn1.GeneralNameAsn.Decode(explicitReader, out tmpTsa);
                decoded.Tsa = tmpTsa;

                explicitReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
                    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();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }