internal void Encode(AsnWriter writer) { bool wroteValue = false; if (Certificate.HasValue) { if (wroteValue) { throw new CryptographicException(); } // Validator for tag constraint for Certificate { if (!Asn1Tag.TryDecode(Certificate.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } writer.WriteEncodedValue(Certificate.Value.Span); wroteValue = true; } if (!wroteValue) { throw new CryptographicException(); } }
internal void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); writer.WriteInteger(Status); if (StatusString.HasValue) { // Validator for tag constraint for StatusString { if (!Asn1Tag.TryDecode(StatusString.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(StatusString.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } 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.TryDecode(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"); } }
public static void ParseValidTag( PublicTagClass tagClass, bool isConstructed, int tagValue, string inputHex) { byte[] inputBytes = inputHex.HexToByteArray(); bool parsed = Asn1Tag.TryDecode(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.TryEncode(secondBytes.AsSpan(0, inputBytes.Length - 1), out written)); Assert.Equal(0, written); Assert.True(tag.TryEncode(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(Version); // Validator for tag constraint for Subject { if (!Asn1Tag.TryDecode(Subject.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } writer.WriteEncodedValue(Subject.Span); 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 VerifyDecode(TagClass tagClass, int tagValue, bool constructed, string inputHex) { Asn1Tag expectedTag = new Asn1Tag(tagClass, tagValue, constructed); byte[] input = inputHex.HexToByteArray(); byte[] padded = input; Array.Resize(ref padded, input.Length + 3); int consumed; Asn1Tag tag; Assert.False(Asn1Tag.TryDecode(input.AsSpan(0, input.Length - 1), out tag, out consumed)); Assert.Equal(0, consumed); Assert.Equal(default(Asn1Tag), tag); Assert.Throws <AsnContentException>(() => Asn1Tag.Decode(input.AsSpan(0, input.Length - 1), out consumed)); Assert.Equal(0, consumed); Assert.True(Asn1Tag.TryDecode(padded, out tag, out consumed)); Assert.Equal(input.Length, consumed); Assert.Equal(expectedTag, tag); Assert.True(Asn1Tag.TryDecode(input, out tag, out consumed)); Assert.Equal(input.Length, consumed); Assert.Equal(expectedTag, tag); tag = Asn1Tag.Decode(padded, out consumed); Assert.Equal(input.Length, consumed); Assert.Equal(expectedTag, tag); tag = Asn1Tag.Decode(input, out consumed); Assert.Equal(input.Length, consumed); Assert.Equal(expectedTag, tag); }
public static void ParseCorruptTag(string description, string inputHex) { byte[] inputBytes = inputHex.HexToByteArray(); Assert.False(Asn1Tag.TryDecode(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.TryDecode(NameRelativeToCRLIssuer.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(NameRelativeToCRLIssuer.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } 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.TryDecode(Issuer.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } writer.WriteEncodedValue(Issuer.Span); writer.WriteInteger(SerialNumber.Span); writer.PopSequence(tag); }
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.TryDecode(SignedAttributes.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(SignedAttributes.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } 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); }
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.TryDecode(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); } }
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})"); }
public static void ParseCorruptTag(string description, string inputHex) { _ = description; byte[] inputBytes = inputHex.HexToByteArray(); Assert.False(Asn1Tag.TryDecode(inputBytes, out Asn1Tag tag, out var bytesRead)); Assert.Equal(default(Asn1Tag), tag); Assert.Equal(0, bytesRead); Assert.False( AsnDecoder.TryReadEncodedValue( inputBytes, AsnEncodingRules.BER, out tag, out int contentOffset, out int contentLength, out int bytesConsumed)); Assert.Equal(0, contentOffset); Assert.Equal(0, contentLength); Assert.Equal(0, bytesConsumed); Assert.Equal(default(Asn1Tag), tag); }
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.TryDecode(Issuer.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } writer.WriteEncodedValue(Issuer.Span); Validity.Encode(writer); // Validator for tag constraint for Subject { if (!Asn1Tag.TryDecode(Subject.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } writer.WriteEncodedValue(Subject.Span); 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); }
internal void Encode(AsnWriter writer) { bool wroteValue = false; if (Certificate.HasValue) { if (wroteValue) { throw new CryptographicException(); } // Validator for tag constraint for Certificate { if (!Asn1Tag.TryDecode(Certificate.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(Certificate.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } wroteValue = true; } if (ExtendedCertificate.HasValue) { if (wroteValue) { throw new CryptographicException(); } // Validator for tag constraint for ExtendedCertificate { if (!Asn1Tag.TryDecode(ExtendedCertificate.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(ExtendedCertificate.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } wroteValue = true; } if (AttributeCertificateV1.HasValue) { if (wroteValue) { throw new CryptographicException(); } // Validator for tag constraint for AttributeCertificateV1 { if (!Asn1Tag.TryDecode(AttributeCertificateV1.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(AttributeCertificateV1.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } wroteValue = true; } if (AttributeCertificateV2.HasValue) { if (wroteValue) { throw new CryptographicException(); } // Validator for tag constraint for AttributeCertificateV2 { if (!Asn1Tag.TryDecode(AttributeCertificateV2.Value.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(AttributeCertificateV2.Value.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } wroteValue = true; } if (OtherCertificateFormat.HasValue) { if (wroteValue) { throw new CryptographicException(); } OtherCertificateFormat.Value.Encode(writer, new Asn1Tag(TagClass.ContextSpecific, 3)); wroteValue = true; } if (!wroteValue) { throw new CryptographicException(); } }
internal void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); // DEFAULT value handler for Version. { AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); tmp.WriteInteger(Version); if (!tmp.EncodedValueEquals(DefaultVersion)) { writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); tmp.CopyTo(writer); writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); } } writer.WriteInteger(SerialNumber.Span); SignatureAlgorithm.Encode(writer); // Validator for tag constraint for Issuer { if (!Asn1Tag.TryDecode(Issuer.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(Issuer.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } Validity.Encode(writer); // Validator for tag constraint for Subject { if (!Asn1Tag.TryDecode(Subject.Span, out Asn1Tag validateTag, out _) || !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } } try { writer.WriteEncodedValue(Subject.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } SubjectPublicKeyInfo.Encode(writer); if (IssuerUniqueId.HasValue) { writer.WriteBitString(IssuerUniqueId.Value.Span, 0, new Asn1Tag(TagClass.ContextSpecific, 1)); } if (SubjectUniqueId.HasValue) { writer.WriteBitString(SubjectUniqueId.Value.Span, 0, new Asn1Tag(TagClass.ContextSpecific, 2)); } 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); }