GQ_Communicate/GQ_VR/Assets/Best HTTP/Source/SecureProtocol/asn1/Asn1RelativeOid.cs

321 lines
9.7 KiB
C#

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using System.Text;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
{
public class Asn1RelativeOid
: Asn1Object
{
internal class Meta : Asn1UniversalType
{
internal static readonly Asn1UniversalType Instance = new Meta();
private Meta() : base(typeof(Asn1RelativeOid), Asn1Tags.RelativeOid) {}
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
{
return CreatePrimitive(octetString.GetOctets(), false);
}
}
public static Asn1RelativeOid FromContents(byte[] contents)
{
return CreatePrimitive(contents, true);
}
public static Asn1RelativeOid GetInstance(object obj)
{
if (obj == null)
return null;
if (obj is Asn1RelativeOid asn1RelativeOid)
return asn1RelativeOid;
if (obj is IAsn1Convertible asn1Convertible)
{
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
if (asn1Object is Asn1RelativeOid converted)
return converted;
}
else if (obj is byte[] bytes)
{
try
{
return (Asn1RelativeOid)FromByteArray(bytes);
}
catch (IOException e)
{
throw new ArgumentException("failed to construct relative OID from byte[]: " + e.Message);
}
}
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
}
public static Asn1RelativeOid GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return (Asn1RelativeOid)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
}
private const long LongLimit = (long.MaxValue >> 7) - 0x7F;
private readonly string identifier;
private byte[] contents;
public Asn1RelativeOid(string identifier)
{
if (identifier == null)
throw new ArgumentNullException("identifier");
if (!IsValidIdentifier(identifier, 0))
throw new FormatException("string " + identifier + " not a relative OID");
this.identifier = identifier;
}
private Asn1RelativeOid(Asn1RelativeOid oid, string branchID)
{
if (!IsValidIdentifier(branchID, 0))
throw new FormatException("string " + branchID + " not a valid relative OID branch");
this.identifier = oid.Id + "." + branchID;
}
private Asn1RelativeOid(byte[] contents, bool clone)
{
this.identifier = ParseContents(contents);
this.contents = clone ? Arrays.Clone(contents) : contents;
}
public virtual Asn1RelativeOid Branch(string branchID)
{
return new Asn1RelativeOid(this, branchID);
}
public string Id
{
get { return identifier; }
}
public override string ToString()
{
return identifier;
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
Asn1RelativeOid that = asn1Object as Asn1RelativeOid;
return null != that
&& this.identifier == that.identifier;
}
protected override int Asn1GetHashCode()
{
return identifier.GetHashCode();
}
internal override IAsn1Encoding GetEncoding(int encoding)
{
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.RelativeOid, GetContents());
}
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
{
return new PrimitiveEncoding(tagClass, tagNo, GetContents());
}
private void DoOutput(MemoryStream bOut)
{
OidTokenizer tok = new OidTokenizer(identifier);
while (tok.HasMoreTokens)
{
string token = tok.NextToken();
if (token.Length <= 18)
{
WriteField(bOut, long.Parse(token));
}
else
{
WriteField(bOut, new BigInteger(token));
}
}
}
private byte[] GetContents()
{
lock (this)
{
if (contents == null)
{
MemoryStream bOut = new MemoryStream();
DoOutput(bOut);
contents = bOut.ToArray();
}
return contents;
}
}
internal static Asn1RelativeOid CreatePrimitive(byte[] contents, bool clone)
{
return new Asn1RelativeOid(contents, clone);
}
internal static bool IsValidIdentifier(string identifier, int from)
{
int digitCount = 0;
int pos = identifier.Length;
while (--pos >= from)
{
char ch = identifier[pos];
if (ch == '.')
{
if (0 == digitCount || (digitCount > 1 && identifier[pos + 1] == '0'))
return false;
digitCount = 0;
}
else if ('0' <= ch && ch <= '9')
{
++digitCount;
}
else
{
return false;
}
}
if (0 == digitCount || (digitCount > 1 && identifier[pos + 1] == '0'))
return false;
return true;
}
internal static void WriteField(Stream outputStream, long fieldValue)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
Span<byte> result = stackalloc byte[9];
#else
byte[] result = new byte[9];
#endif
int pos = 8;
result[pos] = (byte)((int)fieldValue & 0x7F);
while (fieldValue >= (1L << 7))
{
fieldValue >>= 7;
result[--pos] = (byte)((int)fieldValue | 0x80);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
outputStream.Write(result[pos..]);
#else
outputStream.Write(result, pos, 9 - pos);
#endif
}
internal static void WriteField(Stream outputStream, BigInteger fieldValue)
{
int byteCount = (fieldValue.BitLength + 6) / 7;
if (byteCount == 0)
{
outputStream.WriteByte(0);
}
else
{
BigInteger tmpValue = fieldValue;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
Span<byte> tmp = byteCount <= 16
? stackalloc byte[byteCount]
: new byte[byteCount];
#else
byte[] tmp = new byte[byteCount];
#endif
for (int i = byteCount - 1; i >= 0; i--)
{
tmp[i] = (byte)(tmpValue.IntValue | 0x80);
tmpValue = tmpValue.ShiftRight(7);
}
tmp[byteCount - 1] &= 0x7F;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
outputStream.Write(tmp);
#else
outputStream.Write(tmp, 0, tmp.Length);
#endif
}
}
private static string ParseContents(byte[] contents)
{
StringBuilder objId = new StringBuilder();
long value = 0;
BigInteger bigValue = null;
bool first = true;
for (int i = 0; i != contents.Length; i++)
{
int b = contents[i];
if (value <= LongLimit)
{
value += b & 0x7F;
if ((b & 0x80) == 0)
{
if (first)
{
first = false;
}
else
{
objId.Append('.');
}
objId.Append(value);
value = 0;
}
else
{
value <<= 7;
}
}
else
{
if (bigValue == null)
{
bigValue = BigInteger.ValueOf(value);
}
bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7F));
if ((b & 0x80) == 0)
{
if (first)
{
first = false;
}
else
{
objId.Append('.');
}
objId.Append(bigValue);
bigValue = null;
value = 0;
}
else
{
bigValue = bigValue.ShiftLeft(7);
}
}
}
return objId.ToString();
}
}
}
#pragma warning restore
#endif