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

175 lines
3.7 KiB
C#

using System;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1;
public class DerApplicationSpecific : Asn1Object
{
private readonly bool isConstructed;
private readonly int tag;
private readonly byte[] octets;
public int ApplicationTag => tag;
internal DerApplicationSpecific(bool isConstructed, int tag, byte[] octets)
{
this.isConstructed = isConstructed;
this.tag = tag;
this.octets = octets;
}
public DerApplicationSpecific(int tag, byte[] octets)
: this(isConstructed: false, tag, octets)
{
}
public DerApplicationSpecific(int tag, Asn1Encodable obj)
: this(isExplicit: true, tag, obj)
{
}
public DerApplicationSpecific(bool isExplicit, int tag, Asn1Encodable obj)
{
Asn1Object asn1Object = obj.ToAsn1Object();
byte[] derEncoded = asn1Object.GetDerEncoded();
isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Object);
this.tag = tag;
if (isExplicit)
{
octets = derEncoded;
return;
}
int lengthOfHeader = GetLengthOfHeader(derEncoded);
byte[] array = new byte[derEncoded.Length - lengthOfHeader];
Array.Copy(derEncoded, lengthOfHeader, array, 0, array.Length);
octets = array;
}
public DerApplicationSpecific(int tagNo, Asn1EncodableVector vec)
{
tag = tagNo;
isConstructed = true;
MemoryStream memoryStream = new MemoryStream();
for (int i = 0; i != vec.Count; i++)
{
try
{
byte[] derEncoded = vec[i].GetDerEncoded();
memoryStream.Write(derEncoded, 0, derEncoded.Length);
}
catch (IOException innerException)
{
throw new InvalidOperationException("malformed object", innerException);
}
}
octets = memoryStream.ToArray();
}
private int GetLengthOfHeader(byte[] data)
{
int num = data[1];
if (num == 128)
{
return 2;
}
if (num > 127)
{
int num2 = num & 0x7F;
if (num2 > 4)
{
throw new InvalidOperationException("DER length more than 4 bytes: " + num2);
}
return num2 + 2;
}
return 2;
}
public bool IsConstructed()
{
return isConstructed;
}
public byte[] GetContents()
{
return octets;
}
public Asn1Object GetObject()
{
return Asn1Object.FromByteArray(GetContents());
}
public Asn1Object GetObject(int derTagNo)
{
if (derTagNo >= 31)
{
throw new IOException("unsupported tag number");
}
byte[] encoded = GetEncoded();
byte[] array = ReplaceTagNumber(derTagNo, encoded);
if ((encoded[0] & 0x20) != 0)
{
byte[] array2;
(array2 = array)[0] = (byte)(array2[0] | 0x20);
}
return Asn1Object.FromByteArray(array);
}
internal override void Encode(DerOutputStream derOut)
{
int num = 64;
if (isConstructed)
{
num |= 0x20;
}
derOut.WriteEncoded(num, tag, octets);
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
if (!(asn1Object is DerApplicationSpecific derApplicationSpecific))
{
return false;
}
if (isConstructed == derApplicationSpecific.isConstructed && tag == derApplicationSpecific.tag)
{
return Arrays.AreEqual(octets, derApplicationSpecific.octets);
}
return false;
}
protected override int Asn1GetHashCode()
{
bool flag = isConstructed;
int hashCode = flag.GetHashCode();
int num = tag;
return hashCode ^ num.GetHashCode() ^ Arrays.GetHashCode(octets);
}
private byte[] ReplaceTagNumber(int newTag, byte[] input)
{
int num = input[0] & 0x1F;
int num2 = 1;
if (num == 31)
{
int num3 = input[num2++];
if ((num3 & 0x7F) == 0)
{
throw new IOException("corrupted stream - invalid high tag number found");
}
while ((num3 & 0x80) != 0)
{
num3 = input[num2++];
}
}
int num4 = input.Length - num2;
byte[] array = new byte[1 + num4];
array[0] = (byte)newTag;
Array.Copy(input, num2, array, 1, num4);
return array;
}
}