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

294 lines
5.9 KiB
C#

using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Asn1;
public abstract class Asn1Set : Asn1Object, IEnumerable
{
private class Asn1SetParserImpl : Asn1SetParser, IAsn1Convertible
{
private readonly Asn1Set outer;
private readonly int max;
private int index;
public Asn1SetParserImpl(Asn1Set outer)
{
this.outer = outer;
max = outer.Count;
}
public IAsn1Convertible ReadObject()
{
if (index == max)
{
return null;
}
Asn1Encodable asn1Encodable = outer[index++];
if (asn1Encodable is Asn1Sequence)
{
return ((Asn1Sequence)asn1Encodable).Parser;
}
if (asn1Encodable is Asn1Set)
{
return ((Asn1Set)asn1Encodable).Parser;
}
return asn1Encodable;
}
public virtual Asn1Object ToAsn1Object()
{
return outer;
}
}
private class DerComparer : IComparer
{
public int Compare(object x, object y)
{
byte[] array = (byte[])x;
byte[] array2 = (byte[])y;
int num = System.Math.Min(array.Length, array2.Length);
for (int i = 0; i != num; i++)
{
byte b = array[i];
byte b2 = array2[i];
if (b != b2)
{
if (b >= b2)
{
return 1;
}
return -1;
}
}
if (array.Length > array2.Length)
{
if (!AllZeroesFrom(array, num))
{
return 1;
}
return 0;
}
if (array.Length < array2.Length)
{
if (!AllZeroesFrom(array2, num))
{
return -1;
}
return 0;
}
return 0;
}
private bool AllZeroesFrom(byte[] bs, int pos)
{
while (pos < bs.Length)
{
if (bs[pos++] != 0)
{
return false;
}
}
return true;
}
}
private readonly IList _set;
public virtual Asn1Encodable this[int index] => (Asn1Encodable)_set[index];
[Obsolete("Use 'Count' property instead")]
public int Size => Count;
public virtual int Count => _set.Count;
public Asn1SetParser Parser => new Asn1SetParserImpl(this);
public static Asn1Set GetInstance(object obj)
{
if (obj == null || obj is Asn1Set)
{
return (Asn1Set)obj;
}
if (obj is Asn1SetParser)
{
return GetInstance(((Asn1SetParser)obj).ToAsn1Object());
}
if (obj is byte[])
{
try
{
return GetInstance(Asn1Object.FromByteArray((byte[])obj));
}
catch (IOException ex)
{
throw new ArgumentException("failed to construct set from byte[]: " + ex.Message);
}
}
if (obj is Asn1Encodable)
{
Asn1Object asn1Object = ((Asn1Encodable)obj).ToAsn1Object();
if (asn1Object is Asn1Set)
{
return (Asn1Set)asn1Object;
}
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
public static Asn1Set GetInstance(Asn1TaggedObject obj, bool explicitly)
{
Asn1Object asn1Object = obj.GetObject();
if (explicitly)
{
if (!obj.IsExplicit())
{
throw new ArgumentException("object implicit - explicit expected.");
}
return (Asn1Set)asn1Object;
}
if (obj.IsExplicit())
{
return new DerSet(asn1Object);
}
if (asn1Object is Asn1Set)
{
return (Asn1Set)asn1Object;
}
if (asn1Object is Asn1Sequence)
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
Asn1Sequence asn1Sequence = (Asn1Sequence)asn1Object;
foreach (Asn1Encodable item in asn1Sequence)
{
asn1EncodableVector.Add(item);
}
return new DerSet(asn1EncodableVector, needsSorting: false);
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
protected internal Asn1Set(int capacity)
{
_set = Platform.CreateArrayList(capacity);
}
public virtual IEnumerator GetEnumerator()
{
return _set.GetEnumerator();
}
[Obsolete("Use GetEnumerator() instead")]
public IEnumerator GetObjects()
{
return GetEnumerator();
}
[Obsolete("Use 'object[index]' syntax instead")]
public Asn1Encodable GetObjectAt(int index)
{
return this[index];
}
public virtual Asn1Encodable[] ToArray()
{
Asn1Encodable[] array = new Asn1Encodable[Count];
for (int i = 0; i < Count; i++)
{
array[i] = this[i];
}
return array;
}
protected override int Asn1GetHashCode()
{
int num = Count;
IEnumerator enumerator = GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object current = enumerator.Current;
num *= 17;
num = ((current != null) ? (num ^ current.GetHashCode()) : (num ^ DerNull.Instance.GetHashCode()));
}
return num;
}
finally
{
IDisposable disposable = enumerator as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
if (!(asn1Object is Asn1Set asn1Set))
{
return false;
}
if (Count != asn1Set.Count)
{
return false;
}
IEnumerator enumerator = GetEnumerator();
IEnumerator enumerator2 = asn1Set.GetEnumerator();
while (enumerator.MoveNext() && enumerator2.MoveNext())
{
Asn1Object asn1Object2 = GetCurrent(enumerator).ToAsn1Object();
Asn1Object obj = GetCurrent(enumerator2).ToAsn1Object();
if (!asn1Object2.Equals(obj))
{
return false;
}
}
return true;
}
private Asn1Encodable GetCurrent(IEnumerator e)
{
Asn1Encodable asn1Encodable = (Asn1Encodable)e.Current;
if (asn1Encodable == null)
{
return DerNull.Instance;
}
return asn1Encodable;
}
protected internal void Sort()
{
if (_set.Count >= 2)
{
Asn1Encodable[] array = new Asn1Encodable[_set.Count];
byte[][] array2 = new byte[_set.Count][];
for (int i = 0; i < _set.Count; i++)
{
array2[i] = (array[i] = (Asn1Encodable)_set[i]).GetEncoded("DER");
}
Array.Sort(array2, array, new DerComparer());
for (int j = 0; j < _set.Count; j++)
{
_set[j] = array[j];
}
}
}
protected internal void AddObject(Asn1Encodable obj)
{
_set.Add(obj);
}
public override string ToString()
{
return CollectionUtilities.ToString(_set);
}
}