--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<asn:Choice
+ xmlns:asn="http://schemas.dot.net/asnxml/201808/"
+ name="DirectoryStringAsn"
+ namespace="System.Security.Cryptography.Asn1">
+
+ <!--
+ https://tools.ietf.org/html/rfc5280#section-4.1.2.4
+
+ DirectoryString ::= CHOICE {
+ teletexString TeletexString (SIZE (1..MAX)),
+ printableString PrintableString (SIZE (1..MAX)),
+ universalString UniversalString (SIZE (1..MAX)),
+ utf8String UTF8String (SIZE (1..MAX)),
+ bmpString BMPString (SIZE (1..MAX))
+ }
+ -->
+ <asn:T61String name="TeletexString" />
+ <asn:PrintableString name="PrintableString" />
+ <asn:AnyValue name="UniversalString" universalTagNumber="28" />
+ <asn:UTF8String name="Utf8String" />
+ <asn:BMPString name="BmpString" />
+</asn:Choice>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.Asn1;
+
+namespace System.Security.Cryptography.Asn1
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal partial struct DirectoryStringAsn
+ {
+ internal string TeletexString;
+ internal string PrintableString;
+ internal ReadOnlyMemory<byte>? UniversalString;
+ internal string Utf8String;
+ internal string BmpString;
+
+#if DEBUG
+ static DirectoryStringAsn()
+ {
+ var usedTags = new System.Collections.Generic.Dictionary<Asn1Tag, string>();
+ Action<Asn1Tag, string> ensureUniqueTag = (tag, fieldName) =>
+ {
+ if (usedTags.TryGetValue(tag, out string existing))
+ {
+ throw new InvalidOperationException($"Tag '{tag}' is in use by both '{existing}' and '{fieldName}'");
+ }
+
+ usedTags.Add(tag, fieldName);
+ };
+
+ ensureUniqueTag(new Asn1Tag(UniversalTagNumber.T61String), "TeletexString");
+ ensureUniqueTag(new Asn1Tag(UniversalTagNumber.PrintableString), "PrintableString");
+ ensureUniqueTag(new Asn1Tag((UniversalTagNumber)28), "UniversalString");
+ ensureUniqueTag(new Asn1Tag(UniversalTagNumber.UTF8String), "Utf8String");
+ ensureUniqueTag(new Asn1Tag(UniversalTagNumber.BMPString), "BmpString");
+ }
+#endif
+
+ internal void Encode(AsnWriter writer)
+ {
+ bool wroteValue = false;
+
+ if (TeletexString != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(UniversalTagNumber.T61String, TeletexString);
+ wroteValue = true;
+ }
+
+ if (PrintableString != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(UniversalTagNumber.PrintableString, PrintableString);
+ wroteValue = true;
+ }
+
+ if (UniversalString.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ // Validator for tag constraint for UniversalString
+ {
+ if (!Asn1Tag.TryParse(UniversalString.Value.Span, out Asn1Tag validateTag, out _) ||
+ !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)28)))
+ {
+ throw new CryptographicException();
+ }
+ }
+
+ writer.WriteEncodedValue(UniversalString.Value);
+ wroteValue = true;
+ }
+
+ if (Utf8String != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(UniversalTagNumber.UTF8String, Utf8String);
+ wroteValue = true;
+ }
+
+ if (BmpString != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(UniversalTagNumber.BMPString, BmpString);
+ wroteValue = true;
+ }
+
+ if (!wroteValue)
+ {
+ throw new CryptographicException();
+ }
+ }
+
+ internal static DirectoryStringAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ AsnReader reader = new AsnReader(encoded, ruleSet);
+
+ Decode(reader, out DirectoryStringAsn decoded);
+ reader.ThrowIfNotEmpty();
+ return decoded;
+ }
+
+ internal static void Decode(AsnReader reader, out DirectoryStringAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ decoded = default;
+ Asn1Tag tag = reader.PeekTag();
+
+ if (tag.HasSameClassAndValue(new Asn1Tag(UniversalTagNumber.T61String)))
+ {
+ decoded.TeletexString = reader.GetCharacterString(UniversalTagNumber.T61String);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(UniversalTagNumber.PrintableString)))
+ {
+ decoded.PrintableString = reader.GetCharacterString(UniversalTagNumber.PrintableString);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)28)))
+ {
+ decoded.UniversalString = reader.GetEncodedValue();
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(UniversalTagNumber.UTF8String)))
+ {
+ decoded.Utf8String = reader.GetCharacterString(UniversalTagNumber.UTF8String);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(UniversalTagNumber.BMPString)))
+ {
+ decoded.BmpString = reader.GetCharacterString(UniversalTagNumber.BMPString);
+ }
+ else
+ {
+ throw new CryptographicException();
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<asn:Sequence
+ xmlns:asn="http://schemas.dot.net/asnxml/201808/"
+ name="EdiPartyNameAsn"
+ namespace="System.Security.Cryptography.Asn1">
+
+ <!--
+ https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+
+ EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString OPTIONAL,
+ partyName [1] DirectoryString
+ }
+ -->
+ <asn:AsnType name="NameAssigner" explicitTag="0" typeName="System.Security.Cryptography.Asn1.DirectoryStringAsn" optional="true" />
+ <asn:AsnType name="PartyName" explicitTag="1" typeName="System.Security.Cryptography.Asn1.DirectoryStringAsn" />
+</asn:Sequence>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.Asn1;
+
+namespace System.Security.Cryptography.Asn1
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal partial struct EdiPartyNameAsn
+ {
+ internal System.Security.Cryptography.Asn1.DirectoryStringAsn? NameAssigner;
+ internal System.Security.Cryptography.Asn1.DirectoryStringAsn PartyName;
+
+ internal void Encode(AsnWriter writer)
+ {
+ Encode(writer, Asn1Tag.Sequence);
+ }
+
+ internal void Encode(AsnWriter writer, Asn1Tag tag)
+ {
+ writer.PushSequence(tag);
+
+
+ if (NameAssigner.HasValue)
+ {
+ writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ NameAssigner.Value.Encode(writer);
+ writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ }
+
+ writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
+ PartyName.Encode(writer);
+ writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
+ writer.PopSequence(tag);
+ }
+
+ internal static EdiPartyNameAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ return Decode(Asn1Tag.Sequence, encoded, ruleSet);
+ }
+
+ internal static EdiPartyNameAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ AsnReader reader = new AsnReader(encoded, ruleSet);
+
+ Decode(reader, expectedTag, out EdiPartyNameAsn decoded);
+ reader.ThrowIfNotEmpty();
+ return decoded;
+ }
+
+ internal static void Decode(AsnReader reader, out EdiPartyNameAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ Decode(reader, Asn1Tag.Sequence, out decoded);
+ }
+
+ internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EdiPartyNameAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ decoded = default;
+ AsnReader sequenceReader = reader.ReadSequence(expectedTag);
+ AsnReader explicitReader;
+
+
+ if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
+ {
+ explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ System.Security.Cryptography.Asn1.DirectoryStringAsn tmpNameAssigner;
+ System.Security.Cryptography.Asn1.DirectoryStringAsn.Decode(explicitReader, out tmpNameAssigner);
+ decoded.NameAssigner = tmpNameAssigner;
+
+ explicitReader.ThrowIfNotEmpty();
+ }
+
+
+ explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
+ System.Security.Cryptography.Asn1.DirectoryStringAsn.Decode(explicitReader, out decoded.PartyName);
+ explicitReader.ThrowIfNotEmpty();
+
+
+ sequenceReader.ThrowIfNotEmpty();
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-
-namespace System.Security.Cryptography.Asn1
-{
- // https://tools.ietf.org/html/rfc5280#section-4.2.1.6
- //
- // GeneralName ::= CHOICE {
- // otherName [0] OtherName,
- // rfc822Name [1] IA5String,
- // dNSName [2] IA5String,
- // x400Address [3] ORAddress,
- // directoryName [4] Name,
- // ediPartyName [5] EDIPartyName,
- // uniformResourceIdentifier [6] IA5String,
- // iPAddress [7] OCTET STRING,
- // registeredID [8] OBJECT IDENTIFIER
- // }
- [Choice]
- [StructLayout(LayoutKind.Sequential)]
- internal struct GeneralNameAsn
- {
- [ExpectedTag(0)]
- internal OtherNameAsn? OtherName;
-
- [ExpectedTag(1)]
- [IA5String]
- internal string Rfc822Name;
-
- [ExpectedTag(2)]
- [IA5String]
- internal string DnsName;
-
- [ExpectedTag(3)]
- [AnyValue]
- internal ReadOnlyMemory<byte>? X400Address;
-
- [ExpectedTag(4, ExplicitTag = true)]
- [AnyValue]
- internal ReadOnlyMemory<byte>? DirectoryName;
-
- [ExpectedTag(5)]
- internal EdiPartyNameAsn? EdiPartyName;
-
- [ExpectedTag(6)]
- [IA5String]
- internal string Uri;
-
- [ExpectedTag(7)]
- [OctetString]
- internal ReadOnlyMemory<byte>? IPAddress;
-
- [ExpectedTag(8)]
- [ObjectIdentifier]
- internal string RegisteredId;
-
- internal void Encode(AsnWriter writer)
- {
- AsnSerializer.Serialize(this, writer);
- }
-
- internal static void Decode(AsnReader reader, out GeneralNameAsn decoded)
- {
- if (reader == null)
- throw new ArgumentNullException(nameof(reader));
-
- ReadOnlyMemory<byte> value = reader.GetEncodedValue();
- decoded = AsnSerializer.Deserialize<GeneralNameAsn>(value, reader.RuleSet);
- }
-
- internal static GeneralNameAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
- {
- AsnReader reader = new AsnReader(encoded, ruleSet);
-
- Decode(reader, out GeneralNameAsn decoded);
- reader.ThrowIfNotEmpty();
- return decoded;
- }
- }
-
- // https://tools.ietf.org/html/rfc5280#section-4.2.1.6
- //
- // OtherName ::= SEQUENCE {
- // type-id OBJECT IDENTIFIER,
- // value [0] EXPLICIT ANY DEFINED BY type-id }
- // }
- [StructLayout(LayoutKind.Sequential)]
- internal struct OtherNameAsn
- {
- [ObjectIdentifier]
- internal string TypeId;
-
- [ExpectedTag(0, ExplicitTag = true)]
- [AnyValue]
- internal ReadOnlyMemory<byte> Value;
- }
-
- // https://tools.ietf.org/html/rfc5280#section-4.2.1.6
- //
- // EDIPartyName ::= SEQUENCE {
- // nameAssigner [0] DirectoryString OPTIONAL,
- // partyName [1] DirectoryString
- // }
- [StructLayout(LayoutKind.Sequential)]
- internal struct EdiPartyNameAsn
- {
- [OptionalValue]
- internal DirectoryStringAsn? NameAssigner;
-
- internal DirectoryStringAsn PartyName;
- }
-
- // https://tools.ietf.org/html/rfc5280#section-4.1.2.4
- //
- // DirectoryString ::= CHOICE {
- // teletexString TeletexString (SIZE (1..MAX)),
- // printableString PrintableString (SIZE (1..MAX)),
- // universalString UniversalString (SIZE (1..MAX)),
- // utf8String UTF8String (SIZE (1..MAX)),
- // bmpString BMPString (SIZE (1..MAX))
- // }
- [Choice]
- [StructLayout(LayoutKind.Sequential)]
- internal struct DirectoryStringAsn
- {
- [ExpectedTag(TagClass.Universal, (int)UniversalTagNumber.TeletexString)]
- internal ReadOnlyMemory<byte>? TeletexString;
-
- [PrintableString]
- internal string PrintableString;
-
- [ExpectedTag(TagClass.Universal, (int)UniversalTagNumber.UniversalString)]
- internal ReadOnlyMemory<byte>? UniversalString;
-
- [UTF8String]
- internal string Utf8String;
-
- [BMPString]
- internal string BmpString;
- }
-}
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<asn:Choice
+ xmlns:asn="http://schemas.dot.net/asnxml/201808/"
+ name="GeneralNameAsn"
+ namespace="System.Security.Cryptography.Asn1">
+
+ <!--
+ https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+
+ GeneralName ::= CHOICE {
+ otherName [0] OtherName,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER
+ }
+ -->
+ <asn:AsnType name="OtherName" implicitTag="0" typeName="System.Security.Cryptography.Asn1.OtherNameAsn" />
+ <asn:IA5String name="Rfc822Name" implicitTag="1" />
+ <asn:IA5String name="DnsName" implicitTag="2" />
+ <asn:AnyValue name="X400Address" implicitTag="3" />
+ <asn:AnyValue name="DirectoryName" explicitTag="4" />
+ <asn:AsnType name="EdiPartyName" implicitTag="5" typeName="System.Security.Cryptography.Asn1.EdiPartyNameAsn" />
+ <asn:IA5String name="Uri" implicitTag="6" />
+ <asn:OctetString name="IPAddress" implicitTag="7" />
+ <asn:ObjectIdentifier name="RegisteredId" implicitTag="8" backingType="string" />
+</asn:Choice>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.Asn1;
+
+namespace System.Security.Cryptography.Asn1
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal partial struct GeneralNameAsn
+ {
+ internal System.Security.Cryptography.Asn1.OtherNameAsn? OtherName;
+ internal string Rfc822Name;
+ internal string DnsName;
+ internal ReadOnlyMemory<byte>? X400Address;
+ internal ReadOnlyMemory<byte>? DirectoryName;
+ internal System.Security.Cryptography.Asn1.EdiPartyNameAsn? EdiPartyName;
+ internal string Uri;
+ internal ReadOnlyMemory<byte>? IPAddress;
+ internal string RegisteredId;
+
+#if DEBUG
+ static GeneralNameAsn()
+ {
+ var usedTags = new System.Collections.Generic.Dictionary<Asn1Tag, string>();
+ Action<Asn1Tag, string> ensureUniqueTag = (tag, fieldName) =>
+ {
+ if (usedTags.TryGetValue(tag, out string existing))
+ {
+ throw new InvalidOperationException($"Tag '{tag}' is in use by both '{existing}' and '{fieldName}'");
+ }
+
+ usedTags.Add(tag, fieldName);
+ };
+
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "OtherName");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 1), "Rfc822Name");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 2), "DnsName");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 3), "X400Address");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 4), "DirectoryName");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 5), "EdiPartyName");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 6), "Uri");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 7), "IPAddress");
+ ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 8), "RegisteredId");
+ }
+#endif
+
+ internal void Encode(AsnWriter writer)
+ {
+ bool wroteValue = false;
+
+ if (OtherName.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ OtherName.Value.Encode(writer, new Asn1Tag(TagClass.ContextSpecific, 0));
+ wroteValue = true;
+ }
+
+ if (Rfc822Name != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(new Asn1Tag(TagClass.ContextSpecific, 1), UniversalTagNumber.IA5String, Rfc822Name);
+ wroteValue = true;
+ }
+
+ if (DnsName != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(new Asn1Tag(TagClass.ContextSpecific, 2), UniversalTagNumber.IA5String, DnsName);
+ wroteValue = true;
+ }
+
+ if (X400Address.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ // Validator for tag constraint for X400Address
+ {
+ if (!Asn1Tag.TryParse(X400Address.Value.Span, out Asn1Tag validateTag, out _) ||
+ !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
+ {
+ throw new CryptographicException();
+ }
+ }
+
+ writer.WriteEncodedValue(X400Address.Value);
+ wroteValue = true;
+ }
+
+ if (DirectoryName.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
+ writer.WriteEncodedValue(DirectoryName.Value);
+ writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
+ wroteValue = true;
+ }
+
+ if (EdiPartyName.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ EdiPartyName.Value.Encode(writer, new Asn1Tag(TagClass.ContextSpecific, 5));
+ wroteValue = true;
+ }
+
+ if (Uri != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteCharacterString(new Asn1Tag(TagClass.ContextSpecific, 6), UniversalTagNumber.IA5String, Uri);
+ wroteValue = true;
+ }
+
+ if (IPAddress.HasValue)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteOctetString(new Asn1Tag(TagClass.ContextSpecific, 7), IPAddress.Value.Span);
+ wroteValue = true;
+ }
+
+ if (RegisteredId != null)
+ {
+ if (wroteValue)
+ throw new CryptographicException();
+
+ writer.WriteObjectIdentifier(new Asn1Tag(TagClass.ContextSpecific, 8), RegisteredId);
+ wroteValue = true;
+ }
+
+ if (!wroteValue)
+ {
+ throw new CryptographicException();
+ }
+ }
+
+ internal static GeneralNameAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ AsnReader reader = new AsnReader(encoded, ruleSet);
+
+ Decode(reader, out GeneralNameAsn decoded);
+ reader.ThrowIfNotEmpty();
+ return decoded;
+ }
+
+ internal static void Decode(AsnReader reader, out GeneralNameAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ decoded = default;
+ Asn1Tag tag = reader.PeekTag();
+ AsnReader explicitReader;
+
+ if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
+ {
+ System.Security.Cryptography.Asn1.OtherNameAsn tmpOtherName;
+ System.Security.Cryptography.Asn1.OtherNameAsn.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 0), out tmpOtherName);
+ decoded.OtherName = tmpOtherName;
+
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
+ {
+ decoded.Rfc822Name = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 1), UniversalTagNumber.IA5String);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
+ {
+ decoded.DnsName = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 2), UniversalTagNumber.IA5String);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
+ {
+ decoded.X400Address = reader.GetEncodedValue();
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4)))
+ {
+ explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
+ decoded.DirectoryName = explicitReader.GetEncodedValue();
+ explicitReader.ThrowIfNotEmpty();
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5)))
+ {
+ System.Security.Cryptography.Asn1.EdiPartyNameAsn tmpEdiPartyName;
+ System.Security.Cryptography.Asn1.EdiPartyNameAsn.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 5), out tmpEdiPartyName);
+ decoded.EdiPartyName = tmpEdiPartyName;
+
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6)))
+ {
+ decoded.Uri = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 6), UniversalTagNumber.IA5String);
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7)))
+ {
+
+ if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 7), out ReadOnlyMemory<byte> tmpIPAddress))
+ {
+ decoded.IPAddress = tmpIPAddress;
+ }
+ else
+ {
+ decoded.IPAddress = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 7));
+ }
+
+ }
+ else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8)))
+ {
+ decoded.RegisteredId = reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.ContextSpecific, 8));
+ }
+ else
+ {
+ throw new CryptographicException();
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<asn:Sequence
+ xmlns:asn="http://schemas.dot.net/asnxml/201808/"
+ name="OtherNameAsn"
+ namespace="System.Security.Cryptography.Asn1">
+
+ <!--
+ https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+
+ OtherName ::= SEQUENCE {
+ type-id OBJECT IDENTIFIER,
+ value [0] EXPLICIT ANY DEFINED BY type-id }
+ }
+ -->
+ <asn:ObjectIdentifier name="TypeId" backingType="string" />
+ <asn:AnyValue name="Value" explicitTag="0" />
+</asn:Sequence>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.Asn1;
+
+namespace System.Security.Cryptography.Asn1
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal partial struct OtherNameAsn
+ {
+ internal string TypeId;
+ internal ReadOnlyMemory<byte> Value;
+
+ internal void Encode(AsnWriter writer)
+ {
+ Encode(writer, Asn1Tag.Sequence);
+ }
+
+ internal void Encode(AsnWriter writer, Asn1Tag tag)
+ {
+ writer.PushSequence(tag);
+
+ writer.WriteObjectIdentifier(TypeId);
+ writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ writer.WriteEncodedValue(Value);
+ writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ writer.PopSequence(tag);
+ }
+
+ internal static OtherNameAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ return Decode(Asn1Tag.Sequence, encoded, ruleSet);
+ }
+
+ internal static OtherNameAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+ {
+ AsnReader reader = new AsnReader(encoded, ruleSet);
+
+ Decode(reader, expectedTag, out OtherNameAsn decoded);
+ reader.ThrowIfNotEmpty();
+ return decoded;
+ }
+
+ internal static void Decode(AsnReader reader, out OtherNameAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ Decode(reader, Asn1Tag.Sequence, out decoded);
+ }
+
+ internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OtherNameAsn decoded)
+ {
+ if (reader == null)
+ throw new ArgumentNullException(nameof(reader));
+
+ decoded = default;
+ AsnReader sequenceReader = reader.ReadSequence(expectedTag);
+ AsnReader explicitReader;
+
+ decoded.TypeId = sequenceReader.ReadObjectIdentifierAsString();
+
+ explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
+ decoded.Value = explicitReader.GetEncodedValue();
+ explicitReader.ThrowIfNotEmpty();
+
+
+ sequenceReader.ThrowIfNotEmpty();
+ }
+ }
+}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using System.Security.Cryptography;
+using System.Security.Cryptography.Asn1;
using System.Text;
namespace Internal.Cryptography
return null;
}
- private const string CommaSpace = ", ";
-
- internal enum GeneralNameType
- {
- OtherName = 0,
- Rfc822Name = 1,
- // RFC 822: Standard for the format of ARPA Internet Text Messages.
- // That means "email", and an RFC 822 Name: "Email address"
- Email = Rfc822Name,
- DnsName = 2,
- X400Address = 3,
- DirectoryName = 4,
- EdiPartyName = 5,
- UniformResourceIdentifier = 6,
- IPAddress = 7,
- RegisteredId = 8,
- }
-
private string FormatSubjectAlternativeName(byte[] rawData)
{
// Because SubjectAlternativeName is a commonly parsed structure, we'll
//
// The intent here is to be functionally equivalent to OpenSSL GENERAL_NAME_print.
- // The end size of this string is hard to predict.
- // * dNSName values have a tag that takes four characters to represent ("DNS:")
- // and then their payload is ASCII encoded (so one byte -> one char), so they
- // work out to be about equal (in chars) to their DER encoded length (in bytes).
- // * iPAddress values have a tag that takes 11 characters ("IP Address:") and then
- // grow from 4 bytes to up to 15 characters for IPv4, or 16 bytes to 47 characters
- // for IPv6
- //
- // So use a List<string> and just Concat them all when we're done, and we reduce the
- // number of times we copy the header values (vs pointers to the header values).
- List<string> segments = new List<string>();
-
try
{
- // SubjectAltName ::= GeneralNames
- //
- // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
- //
- // GeneralName ::= CHOICE {
- // otherName [0] OtherName,
- // rfc822Name [1] IA5String,
- // dNSName [2] IA5String,
- // x400Address [3] ORAddress,
- // directoryName [4] Name,
- // ediPartyName [5] EDIPartyName,
- // uniformResourceIdentifier [6] IA5String,
- // iPAddress [7] OCTET STRING,
- // registeredID [8] OBJECT IDENTIFIER }
- //
- // OtherName::= SEQUENCE {
- // type - id OBJECT IDENTIFIER,
- // value[0] EXPLICIT ANY DEFINED BY type - id }
- DerSequenceReader altNameReader = new DerSequenceReader(rawData);
+ StringBuilder output = new StringBuilder();
+ AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER);
+ AsnReader collectionReader = reader.ReadSequence();
+
+ reader.ThrowIfNotEmpty();
- while (altNameReader.HasData)
+ while (collectionReader.HasData)
{
- if (segments.Count != 0)
+ GeneralNameAsn.Decode(collectionReader, out GeneralNameAsn generalName);
+
+ if (output.Length != 0)
{
- segments.Add(CommaSpace);
+ output.Append(", ");
}
- byte tag = altNameReader.PeekTag();
-
- if ((tag & DerSequenceReader.ContextSpecificTagFlag) == 0)
+ if (generalName.OtherName.HasValue)
{
- // All GeneralName values need the ContextSpecific flag.
- return null;
+ output.Append("othername:<unsupported>");
}
-
- GeneralNameType nameType = (GeneralNameType)(tag & DerSequenceReader.TagNumberMask);
-
- bool needsConstructedFlag = false;
-
- switch (nameType)
+ else if (generalName.Rfc822Name != null)
{
- case GeneralNameType.OtherName:
- case GeneralNameType.X400Address:
- case GeneralNameType.DirectoryName:
- case GeneralNameType.EdiPartyName:
- needsConstructedFlag = true;
- break;
+ output.Append("email:");
+ output.Append(generalName.Rfc822Name);
}
-
- if (needsConstructedFlag &&
- (tag & DerSequenceReader.ConstructedFlag) == 0)
+ else if (generalName.DnsName != null)
{
- // All of the SEQUENCE types require the constructed bit,
- // or OpenSSL will have refused to print it.
- return null;
+ output.Append("DNS:");
+ output.Append(generalName.DnsName);
}
-
- switch (nameType)
+ else if (generalName.X400Address != null)
{
- case GeneralNameType.OtherName:
- segments.Add("othername:<unsupported>");
- altNameReader.SkipValue();
- break;
- case GeneralNameType.Rfc822Name:
- segments.Add("email:");
- segments.Add(altNameReader.ReadIA5String());
- break;
- case GeneralNameType.DnsName:
- segments.Add("DNS:");
- segments.Add(altNameReader.ReadIA5String());
- break;
- case GeneralNameType.X400Address:
- segments.Add("X400Name:<unsupported>");
- altNameReader.SkipValue();
- break;
- case GeneralNameType.DirectoryName:
- // OpenSSL supports printing one of these, but the logic lives in X509Certificates,
- // and it isn't very common. So we'll skip this one until someone asks for it.
- segments.Add("DirName:<unsupported>");
- altNameReader.SkipValue();
- break;
- case GeneralNameType.EdiPartyName:
- segments.Add("EdiPartyName:<unsupported>");
- altNameReader.SkipValue();
- break;
- case GeneralNameType.UniformResourceIdentifier:
- segments.Add("URI:");
- segments.Add(altNameReader.ReadIA5String());
- break;
- case GeneralNameType.IPAddress:
- segments.Add("IP Address");
-
- byte[] ipAddressBytes = altNameReader.ReadOctetString();
-
- if (ipAddressBytes.Length == 4)
- {
- // Add the colon and dotted-decimal representation of IPv4.
- segments.Add(
- $":{ipAddressBytes[0]}.{ipAddressBytes[1]}.{ipAddressBytes[2]}.{ipAddressBytes[3]}");
- }
- else if (ipAddressBytes.Length == 16)
- {
- // Print the IP Address value as colon separated UInt16 hex values without leading zeroes.
- // 20 01 0D B8 AC 10 FE 01 00 00 00 00 00 00 00 00
- //
- // IP Address:2001:DB8:AC10:FE01:0:0:0:0
- for (int i = 0; i < ipAddressBytes.Length; i += 2)
- {
- segments.Add($":{ipAddressBytes[i] << 8 | ipAddressBytes[i + 1]:X}");
- }
- }
- else
+ output.Append("X400Name:<unsupported>");
+ }
+ else if (generalName.DirectoryName != null)
+ {
+ // OpenSSL supports printing one of these, but the logic lives in X509Certificates,
+ // and it isn't very common. So we'll skip this one until someone asks for it.
+ output.Append("DirName:<unsupported>");
+ }
+ else if (generalName.EdiPartyName != null)
+ {
+ output.Append("EdiPartyName:<unsupported>");
+ }
+ else if (generalName.Uri != null)
+ {
+ output.Append("URI:");
+ output.Append(generalName.Uri);
+ }
+ else if (generalName.IPAddress.HasValue)
+ {
+ ReadOnlySpan<byte> ipAddressBytes = generalName.IPAddress.Value.Span;
+
+ output.Append("IP Address");
+ if (ipAddressBytes.Length == 4)
+ {
+ // Add the colon and dotted-decimal representation of IPv4.
+ output.Append(
+ $":{ipAddressBytes[0]}.{ipAddressBytes[1]}.{ipAddressBytes[2]}.{ipAddressBytes[3]}");
+ }
+ else if (ipAddressBytes.Length == 16)
+ {
+ // Print the IP Address value as colon separated UInt16 hex values without leading zeroes.
+ // 20 01 0D B8 AC 10 FE 01 00 00 00 00 00 00 00 00
+ //
+ // IP Address:2001:DB8:AC10:FE01:0:0:0:0
+ for (int i = 0; i < ipAddressBytes.Length; i += 2)
{
- segments.Add(":<invalid>");
+ output.Append($":{ipAddressBytes[i] << 8 | ipAddressBytes[i + 1]:X}");
}
-
- break;
- case GeneralNameType.RegisteredId:
- segments.Add("Registered ID:");
- segments.Add(altNameReader.ReadOidAsString());
- break;
- default:
- // A new extension to GeneralName could legitimately hit this,
- // but it's correct to say that until we know what that is that
- // the pretty-print has failed, and we should fall back to hex.
- //
- // But it could also simply be poorly encoded user data.
- return null;
+ }
+ else
+ {
+ output.Append(":<invalid>");
+ }
+ }
+ else if (generalName.RegisteredId != null)
+ {
+ output.Append("Registered ID:");
+ output.Append(generalName.RegisteredId);
+ }
+ else
+ {
+ // A new extension to GeneralName could legitimately hit this,
+ // but it's correct to say that until we know what that is that
+ // the pretty-print has failed, and we should fall back to hex.
+ //
+ // But it could also simply be poorly encoded user data.
+ return null;
}
}
- return string.Concat(segments);
+ return output.ToString();
}
catch (CryptographicException)
{
<data name="Cryptography_SSE_InvalidDataSize" xml:space="preserve">
<value>NoLength of the data to encrypt is invalid.</value>
</data>
+ <data name="Cryptography_Asn_EnumeratedValueRequiresNonFlagsEnum" xml:space="preserve">
+ <value>ASN.1 Enumerated values only apply to enum types without the [Flags] attribute.</value>
+ </data>
+ <data name="Cryptography_Asn_NamedBitListRequiresFlagsEnum" xml:space="preserve">
+ <value>Named bit list operations require an enum with the [Flags] attribute.</value>
+ </data>
+ <data name="Cryptography_Asn_NamedBitListValueTooBig" xml:space="preserve">
+ <value>The encoded named bit list value is larger than the value size of the '{0}' enum.</value>
+ </data>
+ <data name="Cryptography_Asn_UniversalValueIsFixed" xml:space="preserve">
+ <value>Tags with TagClass Universal must have the appropriate TagValue value for the data type being read or written.</value>
+ </data>
+ <data name="Cryptography_Asn_UnusedBitCountRange" xml:space="preserve">
+ <value>Unused bit count must be between 0 and 7, inclusive.</value>
+ </data>
+ <data name="Cryptography_AsnWriter_EncodeUnbalancedStack" xml:space="preserve">
+ <value>Encode cannot be called while a Sequence or SetOf is still open.</value>
+ </data>
+ <data name="Cryptography_AsnWriter_PopWrongTag" xml:space="preserve">
+ <value>Cannot pop the requested tag as it is not currently in progress.</value>
+ </data>
+ <data name="Cryptography_Der_Invalid_Encoding" xml:space="preserve">
+ <value>ASN1 corrupted data.</value>
+ </data>
+ <data name="Cryptography_Invalid_IA5String" xml:space="preserve">
+ <value>The string contains a character not in the 7 bit ASCII character set.</value>
+ </data>
+ <data name="Cryptography_WriteEncodedValue_OneValueAtATime" xml:space="preserve">
+ <value>The input to WriteEncodedValue must represent a single encoded value with no trailing data.</value>
+ </data>
<data name="Arg_RankMultiDimNotSupported" xml:space="preserve">
<value>Only single dimensional arrays are supported for the requested action.</value>
</data>
<data name="ArgumentOutOfRange_NeedNonNegNum" xml:space="preserve">
<value>Non-negative number required.</value>
</data>
+ <data name="Argument_InvalidOidValue" xml:space="preserve">
+ <value>The OID value was invalid.</value>
+ </data>
<data name="Argument_InvalidOffLen" xml:space="preserve">
<value>Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</value>
</data>
<data name="Argument_InvalidValue" xml:space="preserve">
<value>Value was invalid.</value>
</data>
- <data name="Cryptography_Der_Invalid_Encoding" xml:space="preserve">
- <value>ASN1 corrupted data.</value>
- </data>
<data name="ObjectDisposed_Generic" xml:space="preserve">
<value>Cannot access a disposed object.</value>
</data>
<ProjectGuid>{AA81E343-5E54-40B0-9381-C459419BE780}</ProjectGuid>
<AssemblyName>System.Security.Cryptography.Encoding</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DefineConstants Condition="'$(TargetGroup)'=='netcoreapp'">$(DefineConstants);netcoreapp</DefineConstants>
+ <DefineConstants Condition="'$(TargetGroup)'=='uap'">$(DefineConstants);uap</DefineConstants>
<Configurations>netcoreapp-OSX-Debug;netcoreapp-OSX-Release;netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release</Configurations>
</PropertyGroup>
<ItemGroup>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsOSX)' == 'true' ">
- <Compile Include="$(CommonPath)\System\Security\Cryptography\DerSequenceReader.cs">
- <Link>Common\System\Security\Cryptography\DerSequenceReader.cs</Link>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1V2.cs">
+ <Link>Common\System\Security\Cryptography\Asn1V2.cs</Link>
+ </Compile>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\AsnReader.cs">
+ <Link>Common\System\Security\Cryptography\AsnReader.cs</Link>
+ </Compile>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\AsnWriter.cs">
+ <Link>Common\System\Security\Cryptography\AsnWriter.cs</Link>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</DependentUpon>
</Compile>
<Compile Include="Internal\Cryptography\AsnFormatter.OSX.cs" />
<Compile Include="Internal\Cryptography\OidLookup.OSX.cs" />
</ItemGroup>
<ItemGroup>
+ <Reference Include="System.Buffers" />
<Reference Include="System.Collections" />
<Reference Include="System.Collections.Concurrent" />
<Reference Include="System.Diagnostics.Debug" />
const string BmpInputHex = "1E0400480069";
const string Utf8InputHex = "0C024869";
- var ds1 = AsnSerializer.Deserialize<DirectoryStringAsn>(
+ var ds1 = AsnSerializer.Deserialize<DirectoryString>(
BmpInputHex.HexToByteArray(),
AsnEncodingRules.DER);
- var ds2 = AsnSerializer.Deserialize<DirectoryStringAsn>(
+ var ds2 = AsnSerializer.Deserialize<DirectoryString>(
Utf8InputHex.HexToByteArray(),
AsnEncodingRules.DER);
}
}
+ // https://tools.ietf.org/html/rfc5280#section-4.1.2.4
+ //
+ // DirectoryString ::= CHOICE {
+ // teletexString TeletexString (SIZE (1..MAX)),
+ // printableString PrintableString (SIZE (1..MAX)),
+ // universalString UniversalString (SIZE (1..MAX)),
+ // utf8String UTF8String (SIZE (1..MAX)),
+ // bmpString BMPString (SIZE (1..MAX))
+ // }
+ [Choice]
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DirectoryString
+ {
+ [ExpectedTag(TagClass.Universal, (int)UniversalTagNumber.TeletexString)]
+ internal ReadOnlyMemory<byte>? TeletexString;
+
+ [PrintableString]
+ internal string PrintableString;
+
+ [ExpectedTag(TagClass.Universal, (int)UniversalTagNumber.UniversalString)]
+ internal ReadOnlyMemory<byte>? UniversalString;
+
+ [UTF8String]
+ internal string Utf8String;
+
+ [BMPString]
+ internal string BmpString;
+ }
+
[Choice]
[StructLayout(LayoutKind.Sequential)]
internal struct FlexibleString
{
- public DirectoryStringAsn? DirectoryString;
+ public DirectoryString? DirectoryString;
[IA5String]
public string Ascii;
[StructLayout(LayoutKind.Sequential)]
internal sealed class FlexibleStringClassHybrid
{
- public DirectoryStringAsn? DirectoryString;
+ public DirectoryString? DirectoryString;
[IA5String]
public string Ascii;
{
var hybrid = new FlexibleStringClassHybrid
{
- DirectoryString = new DirectoryStringAsn
+ DirectoryString = new DirectoryString
{
Utf8String = "Marco",
},
{
var hybrid = new FlexibleStringClassHybrid
{
- DirectoryString = new DirectoryStringAsn
+ DirectoryString = new DirectoryString
{
BmpString = "Polo",
},
public static void TestSubjectAlternativeName_Unix()
{
byte[] sanExtension = (
- "3081D3A027060A2B0601040182371402" +
+ "3081D1A027060A2B0601040182371402" +
"03A0190C177375626A65637475706E31" +
"406578616D706C652E6F726781157361" +
"6E656D61696C31406578616D706C652E" +
"6F72678218646E73312E7375626A6563" +
"742E6578616D706C652E6F7267A30630" +
- "0441027573A500863168747470733A2F" +
- "2F7777772E6578616D706C652E6F7267" +
- "2F706174682F746F2F612F7265736F75" +
- "72636523616E63686F7287047F000001" +
- "871020010DB8AC10FE01000000000000" +
- "0000870F20010DB8AC10FE0100000000" +
- "0000008704FFFFFFFF8704020F636488" +
- "052901020203").HexToByteArray();
+ "0441027573863168747470733A2F2F77" +
+ "77772E6578616D706C652E6F72672F70" +
+ "6174682F746F2F612F7265736F757263" +
+ "6523616E63686F7287047F0000018710" +
+ "20010DB8AC10FE010000000000000000" +
+ "870F20010DB8AC10FE01000000000000" +
+ "008704FFFFFFFF8704020F6364880529" +
+ "01020203").HexToByteArray();
AsnEncodedData asnData = new AsnEncodedData(
new Oid("2.5.29.17"),
"X400Name:<unsupported>",
// Skip Choice[4]: DirName
// (Supported by OpenSSL, but not by our Apple version)
- // Choice[5]: EdiName
- "EdiPartyName:<unsupported>",
+ // Skip Choice[5]: EdiName
+ // (Buggy parsing in OpenSSL)
// Choice[6]: URI
"URI:https://www.example.org/path/to/a/resource#anchor",
// Choice[7]: IPAddress (IPv4)
Assert.Equal(expected, s);
}
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.OSX)]
+ public static void TestSubjectAlternativeName_Mac()
+ {
+ byte[] sanExtension = "300EA50CA10A13086564695061727479".HexToByteArray();
+
+ AsnEncodedData asnData = new AsnEncodedData(
+ new Oid("2.5.29.17"),
+ sanExtension);
+
+ Assert.Equal("EdiPartyName:<unsupported>", asnData.Format(false));
+ }
}
}
<Compile Include="$(CommonPath)\System\Security\Cryptography\DerSequenceReader.cs">
<Link>Common\System\Security\Cryptography\DerSequenceReader.cs</Link>
</Compile>
- <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.cs">
- <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.cs</Link>
- </Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.cs">
<Link>Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.cs">
<Link>Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.cs</Link>
</Compile>
- <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.cs">
- <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.cs</Link>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</DependentUpon>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\PBEParameter.cs">
<Link>Common\System\Security\Cryptography\Asn1\PBEParameter.cs</Link>
<Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.cs">
<Link>Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.cs</Link>
</Compile>
- <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.cs">
- <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.cs</Link>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml</DependentUpon>
+ </Compile>
+ <AsnXml Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</Link>
+ </AsnXml>
+ <Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs">
+ <Link>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs</Link>
+ <DependentUpon>Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml</DependentUpon>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\Asn1\PssParamsAsn.cs">
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.cs</Link>
try
{
// Verify that the general name can be serialized and store it.
- using (AsnWriter writer = AsnSerializer.Serialize(generalName, AsnEncodingRules.DER))
+ using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
{
+ generalName.Encode(writer);
_encodedNames.Add(writer.Encode());
}
}