Ejemplo n.º 1
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.WriteInteger(Version);
            // Validator for tag constraint for Subject
            {
                if (!Asn1Tag.TryParse(Subject.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            writer.WriteEncodedValue(Subject);
            SubjectPublicKeyInfo.Encode(writer);

            writer.PushSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
            for (int i = 0; i < Attributes.Length; i++)
            {
                Attributes[i].Encode(writer);
            }
            writer.PopSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));

            writer.PopSequence(tag);
        }
Ejemplo n.º 2
0
        public static void ParseValidTag(
            PublicTagClass tagClass,
            bool isConstructed,
            int tagValue,
            string inputHex)
        {
            byte[] inputBytes = inputHex.HexToByteArray();

            bool parsed = Asn1Tag.TryParse(inputBytes, out Asn1Tag tag, out int bytesRead);

            Assert.True(parsed, "Asn1Tag.TryParse");
            Assert.Equal(inputBytes.Length, bytesRead);
            Assert.Equal((TagClass)tagClass, tag.TagClass);
            Assert.Equal(tagValue, tag.TagValue);

            if (isConstructed)
            {
                Assert.True(tag.IsConstructed, "tag.IsConstructed");
            }
            else
            {
                Assert.False(tag.IsConstructed, "tag.IsConstructed");
            }

            byte[] secondBytes = new byte[inputBytes.Length];
            int    written;

            Assert.False(tag.TryWrite(secondBytes.AsSpan().Slice(0, inputBytes.Length - 1), out written));
            Assert.Equal(0, written);
            Assert.True(tag.TryWrite(secondBytes, out written));
            Assert.Equal(inputBytes.Length, written);
            Assert.Equal(inputHex, secondBytes.ByteArrayToHex());
        }
Ejemplo n.º 3
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.WriteInteger(Status);

            if (StatusString.HasValue)
            {
                // Validator for tag constraint for StatusString
                {
                    if (!Asn1Tag.TryParse(StatusString.Value.Span, out Asn1Tag validateTag, out _) ||
                        !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                    {
                        throw new CryptographicException();
                    }
                }

                writer.WriteEncodedValue(StatusString.Value);
            }


            if (FailInfo.HasValue)
            {
                writer.WriteNamedBitList(FailInfo.Value);
            }

            writer.PopSequence(tag);
        }
Ejemplo n.º 4
0
        public static void ParseTagWithMoreData(
            PublicTagClass tagClass,
            bool isConstructed,
            int tagValue,
            string inputHex)
        {
            byte[] inputBytes = inputHex.HexToByteArray();
            Array.Resize(ref inputBytes, inputBytes.Length + 3);

            bool parsed = Asn1Tag.TryParse(inputBytes, out Asn1Tag tag, out int bytesRead);

            Assert.True(parsed, "Asn1Tag.TryParse");
            Assert.Equal(inputHex.Length / 2, bytesRead);
            Assert.Equal((TagClass)tagClass, tag.TagClass);
            Assert.Equal(tagValue, tag.TagValue);

            if (isConstructed)
            {
                Assert.True(tag.IsConstructed, "tag.IsConstructed");
            }
            else
            {
                Assert.False(tag.IsConstructed, "tag.IsConstructed");
            }
        }
Ejemplo n.º 5
0
        internal void Encode(AsnWriter writer)
        {
            bool wroteValue = false;

            if (Certificate.HasValue)
            {
                if (wroteValue)
                {
                    throw new CryptographicException();
                }

                // Validator for tag constraint for Certificate
                {
                    if (!Asn1Tag.TryParse(Certificate.Value.Span, out Asn1Tag validateTag, out _) ||
                        !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                    {
                        throw new CryptographicException();
                    }
                }

                writer.WriteEncodedValue(Certificate.Value);
                wroteValue = true;
            }

            if (!wroteValue)
            {
                throw new CryptographicException();
            }
        }
Ejemplo n.º 6
0
        public static void ParseCorruptTag(string description, string inputHex)
        {
            byte[] inputBytes = inputHex.HexToByteArray();

            Assert.False(Asn1Tag.TryParse(inputBytes, out Asn1Tag tag, out var bytesRead));

            Assert.Equal(default(Asn1Tag), tag);
            Assert.Equal(0, bytesRead);
        }
Ejemplo n.º 7
0
        internal void Encode(AsnWriter writer)
        {
            bool wroteValue = false;

            if (FullName != null)
            {
                if (wroteValue)
                {
                    throw new CryptographicException();
                }


                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                for (int i = 0; i < FullName.Length; i++)
                {
                    FullName[i].Encode(writer);
                }
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

                wroteValue = true;
            }

            if (NameRelativeToCRLIssuer.HasValue)
            {
                if (wroteValue)
                {
                    throw new CryptographicException();
                }

                // Validator for tag constraint for NameRelativeToCRLIssuer
                {
                    if (!Asn1Tag.TryParse(NameRelativeToCRLIssuer.Value.Span, out Asn1Tag validateTag, out _) ||
                        !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
                    {
                        throw new CryptographicException();
                    }
                }

                writer.WriteEncodedValue(NameRelativeToCRLIssuer.Value);
                wroteValue = true;
            }

            if (!wroteValue)
            {
                throw new CryptographicException();
            }
        }
Ejemplo n.º 8
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            // Validator for tag constraint for Issuer
            {
                if (!Asn1Tag.TryParse(Issuer.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            writer.WriteEncodedValue(Issuer);
            writer.WriteInteger(SerialNumber.Span);
            writer.PopSequence(tag);
        }
Ejemplo n.º 9
0
        public void VerifyWriteBitString_PrimitiveOrConstructed(
            PublicEncodingRules ruleSet,
            int payloadLength,
            bool expectConstructed)
        {
            byte[] data = new byte[payloadLength];

            Asn1Tag[] tagsToTry =
            {
                new Asn1Tag(UniversalTagNumber.BitString),
                new Asn1Tag(UniversalTagNumber.BitString, isConstructed: true),
                new Asn1Tag(TagClass.Private,                              87),
                new Asn1Tag(TagClass.ContextSpecific,                       13,isConstructed: true),
            };

            byte[] answerBuf = new byte[payloadLength + 100];

            foreach (Asn1Tag toTry in tagsToTry)
            {
                Asn1Tag writtenTag;

                using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet))
                {
                    writer.WriteBitString(toTry, data);

                    Assert.True(writer.TryEncode(answerBuf, out _));
                    Assert.True(Asn1Tag.TryParse(answerBuf, out writtenTag, out _));
                }

                if (expectConstructed)
                {
                    Assert.True(writtenTag.IsConstructed, $"writtenTag.IsConstructed ({toTry})");
                }
                else
                {
                    Assert.False(writtenTag.IsConstructed, $"writtenTag.IsConstructed ({toTry})");
                }

                Assert.Equal(toTry.TagClass, writtenTag.TagClass);
                Assert.Equal(toTry.TagValue, writtenTag.TagValue);
            }
        }
Ejemplo n.º 10
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.WriteInteger(Version);
            Sid.Encode(writer);
            DigestAlgorithm.Encode(writer);

            if (SignedAttributes.HasValue)
            {
                // Validator for tag constraint for SignedAttributes
                {
                    if (!Asn1Tag.TryParse(SignedAttributes.Value.Span, out Asn1Tag validateTag, out _) ||
                        !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
                    {
                        throw new CryptographicException();
                    }
                }

                writer.WriteEncodedValue(SignedAttributes.Value);
            }

            SignatureAlgorithm.Encode(writer);
            writer.WriteOctetString(SignatureValue.Span);

            if (UnsignedAttributes != null)
            {
                writer.PushSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                for (int i = 0; i < UnsignedAttributes.Length; i++)
                {
                    UnsignedAttributes[i].Encode(writer);
                }
                writer.PopSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
            }

            writer.PopSequence(tag);
        }
Ejemplo n.º 11
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.ReadObjectIdentifierAsString());

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

            Assert.True(Asn1Tag.TryParse(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.GetCharacterString((UniversalTagNumber)valueTag.TagValue));
                Assert.False(valueReader.HasData, "valueReader.HasData");
            }

            Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})");
            Assert.False(rdn.HasData, $"rdn.HasData ({label})");
        }
Ejemplo n.º 12
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);


            // DEFAULT value handler for Version.
            {
                using (AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER))
                {
                    tmp.WriteInteger(Version);
                    ReadOnlySpan <byte> encoded = tmp.EncodeAsSpan();

                    if (!encoded.SequenceEqual(s_defaultVersion))
                    {
                        writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                        writer.WriteEncodedValue(encoded.ToArray());
                        writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                    }
                }
            }

            writer.WriteInteger(SerialNumber.Span);
            SignatureAlgorithm.Encode(writer);
            // Validator for tag constraint for Issuer
            {
                if (!Asn1Tag.TryParse(Issuer.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            writer.WriteEncodedValue(Issuer);
            Validity.Encode(writer);
            // Validator for tag constraint for Subject
            {
                if (!Asn1Tag.TryParse(Subject.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            writer.WriteEncodedValue(Subject);
            SubjectPublicKeyInfo.Encode(writer);

            if (IssuerUniqueId.HasValue)
            {
                writer.WriteBitString(new Asn1Tag(TagClass.ContextSpecific, 1), IssuerUniqueId.Value.Span);
            }


            if (SubjectUniqueId.HasValue)
            {
                writer.WriteBitString(new Asn1Tag(TagClass.ContextSpecific, 2), SubjectUniqueId.Value.Span);
            }


            if (Extensions != null)
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3));

                writer.PushSequence();
                for (int i = 0; i < Extensions.Length; i++)
                {
                    Extensions[i].Encode(writer);
                }
                writer.PopSequence();

                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            }

            writer.PopSequence(tag);
        }