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); }
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()); }
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); }
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"); } }
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(); } }
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); }
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(); } }
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); }
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); } }
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); }
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})"); }
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); }