Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Asn1/X509/GeneralName.cs
2025-10-09 09:57:24 +09:00

300 lines
7.0 KiB
C#

using System;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Text;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Net;
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;
internal readonly Asn1Encodable obj;
internal readonly int tag;
public int TagNo => tag;
public Asn1Encodable Name => obj;
public GeneralName(X509Name directoryName)
{
obj = directoryName;
tag = 4;
}
public GeneralName(Asn1Object name, int tag)
{
obj = name;
this.tag = tag;
}
public GeneralName(int tag, Asn1Encodable name)
{
obj = name;
this.tag = tag;
}
public GeneralName(int tag, string name)
{
this.tag = tag;
switch (tag)
{
case 1:
case 2:
case 6:
obj = new DerIA5String(name);
break;
case 8:
obj = new DerObjectIdentifier(name);
break;
case 4:
obj = new X509Name(name);
break;
case 7:
{
byte[] array = toGeneralNameEncoding(name);
if (array == null)
{
throw new ArgumentException("IP Address is invalid", "name");
}
obj = new DerOctetString(array);
break;
}
default:
throw new ArgumentException("can't process string for tag: " + tag, "tag");
}
}
public static GeneralName GetInstance(object obj)
{
if (obj == null || obj is GeneralName)
{
return (GeneralName)obj;
}
if (obj is Asn1TaggedObject)
{
Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)obj;
int tagNo = asn1TaggedObject.TagNo;
switch (tagNo)
{
case 0:
return new GeneralName(tagNo, Asn1Sequence.GetInstance(asn1TaggedObject, explicitly: false));
case 1:
return new GeneralName(tagNo, DerIA5String.GetInstance(asn1TaggedObject, isExplicit: false));
case 2:
return new GeneralName(tagNo, DerIA5String.GetInstance(asn1TaggedObject, isExplicit: false));
case 3:
throw new ArgumentException("unknown tag: " + tagNo);
case 4:
return new GeneralName(tagNo, X509Name.GetInstance(asn1TaggedObject, explicitly: true));
case 5:
return new GeneralName(tagNo, Asn1Sequence.GetInstance(asn1TaggedObject, explicitly: false));
case 6:
return new GeneralName(tagNo, DerIA5String.GetInstance(asn1TaggedObject, isExplicit: false));
case 7:
return new GeneralName(tagNo, Asn1OctetString.GetInstance(asn1TaggedObject, isExplicit: false));
case 8:
return new GeneralName(tagNo, DerObjectIdentifier.GetInstance(asn1TaggedObject, explicitly: false));
}
}
if (obj is byte[])
{
try
{
return GetInstance(Asn1Object.FromByteArray((byte[])obj));
}
catch (IOException)
{
throw new ArgumentException("unable to parse encoded general name");
}
}
throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
public static GeneralName GetInstance(Asn1TaggedObject tagObj, bool explicitly)
{
return GetInstance(Asn1TaggedObject.GetInstance(tagObj, explicitly: true));
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(tag);
stringBuilder.Append(": ");
switch (tag)
{
case 1:
case 2:
case 6:
stringBuilder.Append(DerIA5String.GetInstance(obj).GetString());
break;
case 4:
stringBuilder.Append(X509Name.GetInstance(obj).ToString());
break;
default:
stringBuilder.Append(obj.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 = ip.IndexOf('/');
if (num < 0)
{
byte[] array = new byte[16];
int[] parsedIp = parseIPv6(ip);
copyInts(parsedIp, array, 0);
return array;
}
byte[] array2 = new byte[32];
int[] parsedIp2 = parseIPv6(ip.Substring(0, num));
copyInts(parsedIp2, array2, 0);
string text = ip.Substring(num + 1);
parsedIp2 = ((text.IndexOf(':') <= 0) ? parseMask(text) : parseIPv6(text));
copyInts(parsedIp2, array2, 16);
return array2;
}
if (Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv4WithNetmask(ip) || Org.BouncyCastle.Utilities.Net.IPAddress.IsValidIPv4(ip))
{
int num2 = ip.IndexOf('/');
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 (text2.IndexOf('.') > 0)
{
parseIPv4(text2, array4, 4);
}
else
{
parseIPv4Mask(text2, array4, 4);
}
return array4;
}
return null;
}
private void parseIPv4Mask(string mask, byte[] addr, int offset)
{
int num = int.Parse(mask);
for (int i = 0; i != num; i++)
{
byte[] array2;
byte[] array = (array2 = addr);
int num2 = i / 8 + offset;
nint num3 = num2;
array[num2] = (byte)(array2[num3] | (byte)(1 << i % 8));
}
}
private void parseIPv4(string ip, byte[] addr, int offset)
{
string[] array = ip.Split('.', '/');
foreach (string s in array)
{
addr[offset++] = (byte)int.Parse(s);
}
}
private int[] parseMask(string mask)
{
int[] array = new int[8];
int num = int.Parse(mask);
for (int i = 0; i != num; i++)
{
int[] array3;
int[] array2 = (array3 = array);
int num2 = i / 16;
nint num3 = num2;
array2[num2] = array3[num3] | (1 << i % 16);
}
return array;
}
private 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 int[] parseIPv6(string ip)
{
if (Platform.StartsWith(ip, "::"))
{
ip = ip.Substring(1);
}
else if (Platform.EndsWith(ip, "::"))
{
ip = ip.Substring(0, ip.Length - 1);
}
IEnumerator enumerator = ip.Split(new char[1] { ':' }).GetEnumerator();
int num = 0;
int[] array = new int[8];
int num2 = -1;
while (enumerator.MoveNext())
{
string text = (string)enumerator.Current;
if (text.Length == 0)
{
num2 = num;
array[num++] = 0;
continue;
}
if (text.IndexOf('.') < 0)
{
array[num++] = int.Parse(text, NumberStyles.AllowHexSpecifier);
continue;
}
string[] array2 = text.Split(new char[1] { '.' });
array[num++] = (int.Parse(array2[0]) << 8) | int.Parse(array2[1]);
array[num++] = (int.Parse(array2[2]) << 8) | int.Parse(array2[3]);
}
if (num != array.Length)
{
Array.Copy(array, num2, array, array.Length - (num - num2), num - num2);
for (int i = num2; i != array.Length - (num - num2); i++)
{
array[i] = 0;
}
}
return array;
}
public override Asn1Object ToAsn1Object()
{
return new DerTaggedObject(tag == 4, tag, obj);
}
}