<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

GeneralName

using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Net; using System; using System.Globalization; using System.Text; namespace Org.BouncyCastle.Asn1.X509 { public class GeneralName : Asn1Encodable, IAsn1Choice { public const int OtherName = 0; public const int Rfc822Name = 1; public const int DnsName = 2; public const int X400Address = 3; public const int DirectoryName = 4; public const int EdiPartyName = 5; public const int UniformResourceIdentifier = 6; public const int IPAddress = 7; public const int RegisteredID = 8; private readonly int m_tag; private readonly Asn1Encodable m_object; public int TagNo => m_tag; public Asn1Encodable Name => m_object; public static GeneralName GetInstance(object obj) { return Asn1Utilities.GetInstanceChoice(obj, GetOptional); } public static GeneralName GetInstance(Asn1TaggedObject tagObj, bool explicitly) { return Asn1Utilities.GetInstanceChoice(tagObj, explicitly, GetInstance); } public static GeneralName GetOptional(Asn1Encodable element) { if (element == null) throw new ArgumentNullException("element"); GeneralName generalName = element as GeneralName; if (generalName != null) return generalName; Asn1TaggedObject optional = Asn1TaggedObject.GetOptional(element); if (optional != null) { Asn1Encodable optionalBaseObject = GetOptionalBaseObject(optional); if (optionalBaseObject != null) return new GeneralName(optional.TagNo, optionalBaseObject); } return null; } public static GeneralName GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit) { return Asn1Utilities.GetTaggedChoice(taggedObject, declaredExplicit, GetInstance); } private static Asn1Encodable GetOptionalBaseObject(Asn1TaggedObject taggedObject) { if (taggedObject.HasContextTag()) { switch (taggedObject.TagNo) { case 5: { Asn1Sequence tagged = Asn1Sequence.GetTagged(taggedObject, false); Org.BouncyCastle.Asn1.X509.EdiPartyName.GetInstance(tagged); return tagged; } case 0: case 3: return Asn1Sequence.GetTagged(taggedObject, false); case 1: case 2: case 6: return DerIA5String.GetTagged(taggedObject, false); case 4: return X509Name.GetTagged(taggedObject, true); case 7: return Asn1OctetString.GetTagged(taggedObject, false); case 8: return DerObjectIdentifier.GetTagged(taggedObject, false); } } return null; } public GeneralName(X509Name directoryName) { m_tag = 4; m_object = directoryName; } public GeneralName(Asn1Object name, int tag) { m_tag = tag; m_object = name; } public GeneralName(int tag, Asn1Encodable name) { m_tag = tag; m_object = name; } public GeneralName(int tag, string name) { m_tag = tag; switch (tag) { case 1: case 2: case 6: m_object = new DerIA5String(name); break; case 4: m_object = new X509Name(name); break; case 7: { byte[] array = ToGeneralNameEncoding(name); if (array == null) throw new ArgumentException("IP Address is invalid", "name"); byte[] contents = array; m_object = new DerOctetString(contents); break; } case 8: m_object = new DerObjectIdentifier(name); break; default: throw new ArgumentException($"""{Asn1Utilities.GetTagText(128, tag)}", "tag"); } } public override Asn1Object ToAsn1Object() { return new DerTaggedObject(m_tag == 4, m_tag, m_object); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(m_tag); stringBuilder.Append(": "); switch (m_tag) { case 1: case 2: case 6: stringBuilder.Append(DerIA5String.GetInstance(m_object).GetString()); break; case 4: stringBuilder.Append(X509Name.GetInstance(m_object).ToString()); break; default: stringBuilder.Append(m_object.ToString()); break; } return stringBuilder.ToString(); } private byte[] ToGeneralNameEncoding(string ip) { if (Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv6WithNetmask(ip) || Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv6(ip)) { int num = Platform.IndexOf(ip, '/'); if (num < 0) { byte[] array = new byte[16]; CopyInts(ParseIPv6(ip), array, 0); return array; } byte[] array2 = new byte[32]; int[] parsedIp = ParseIPv6(ip.Substring(0, num)); CopyInts(parsedIp, array2, 0); string text = ip.Substring(num + 1); parsedIp = ((Platform.IndexOf(text, ':') <= 0) ? ParseIPv6Mask(text) : ParseIPv6(text)); CopyInts(parsedIp, array2, 16); return array2; } if (Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv4WithNetmask(ip) || Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv4(ip)) { int num2 = Platform.IndexOf(ip, '/'); if (num2 < 0) { byte[] array3 = new byte[4]; ParseIPv4(ip, array3, 0); return array3; } byte[] array4 = new byte[8]; ParseIPv4(ip.Substring(0, num2), array4, 0); string text2 = ip.Substring(num2 + 1); if (Platform.IndexOf(text2, '.') > 0) ParseIPv4(text2, array4, 4); else ParseIPv4Mask(text2, array4, 4); return array4; } return null; } private static void CopyInts(int[] parsedIp, byte[] addr, int offSet) { for (int i = 0; i != parsedIp.Length; i++) { addr[i * 2 + offSet] = (byte)(parsedIp[i] >> 8); addr[i * 2 + 1 + offSet] = (byte)parsedIp[i]; } } private static void ParseIPv4(string ip, byte[] addr, int offset) { string[] array = ip.Split('.', '/'); foreach (string s in array) { addr[offset++] = (byte)int.Parse(s); } } private static void ParseIPv4Mask(string mask, byte[] addr, int offset) { int num; for (num = int.Parse(mask); num >= 8; num -= 8) { addr[offset++] = byte.MaxValue; } if (num > 0) addr[offset] = (byte)(65280 >> num); } private static int[] ParseIPv6(string ip) { if (Platform.StartsWith(ip, "::")) ip = ip.Substring(1); else if (Platform.EndsWith(ip, "::")) { ip = ip.Substring(0, ip.Length - 1); } int num = 0; int[] array = new int[8]; int num2 = -1; string[] array2 = ip.Split(new char[1] { ':' }); foreach (string text in array2) { if (text.Length == 0) { num2 = num; array[num++] = 0; } else if (Platform.IndexOf(text, '.') < 0) { array[num++] = int.Parse(text, NumberStyles.AllowHexSpecifier); } else { string[] array3 = text.Split(new char[1] { '.' }); array[num++] = ((int.Parse(array3[0]) << 8) | int.Parse(array3[1])); array[num++] = ((int.Parse(array3[2]) << 8) | int.Parse(array3[3])); } } if (num != array.Length) { Array.Copy(array, num2, array, array.Length - (num - num2), num - num2); for (int j = num2; j != array.Length - (num - num2); j++) { array[j] = 0; } } return array; } private static int[] ParseIPv6Mask(string mask) { int[] array = new int[8]; int num = int.Parse(mask); int num2 = 0; while (num >= 16) { array[num2++] = 65535; num -= 16; } if (num > 0) array[num2] = 65535 >> 16 - num; return array; } } }