kopia lustrzana https://github.com/dl2alf/AirScout
197 wiersze
5.7 KiB
C#
197 wiersze
5.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Diagnostics;
|
|
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Asn1
|
|
{
|
|
public class BerOctetString
|
|
: DerOctetString, IEnumerable
|
|
{
|
|
private const int DefaultSegmentLimit = 1000;
|
|
|
|
public static BerOctetString FromSequence(Asn1Sequence seq)
|
|
{
|
|
int count = seq.Count;
|
|
Asn1OctetString[] v = new Asn1OctetString[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
v[i] = GetInstance(seq[i]);
|
|
}
|
|
return new BerOctetString(v);
|
|
}
|
|
|
|
internal static byte[] FlattenOctetStrings(Asn1OctetString[] octetStrings)
|
|
{
|
|
int count = octetStrings.Length;
|
|
switch (count)
|
|
{
|
|
case 0:
|
|
return EmptyOctets;
|
|
case 1:
|
|
return octetStrings[0].contents;
|
|
default:
|
|
{
|
|
int totalOctets = 0;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
totalOctets += octetStrings[i].contents.Length;
|
|
}
|
|
|
|
byte[] str = new byte[totalOctets];
|
|
int pos = 0;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
byte[] octets = octetStrings[i].contents;
|
|
Array.Copy(octets, 0, str, pos, octets.Length);
|
|
pos += octets.Length;
|
|
}
|
|
|
|
Debug.Assert(pos == totalOctets);
|
|
return str;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static Asn1OctetString[] ToOctetStringArray(IEnumerable e)
|
|
{
|
|
IList list = Platform.CreateArrayList(e);
|
|
|
|
int count = list.Count;
|
|
Asn1OctetString[] v = new Asn1OctetString[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
v[i] = GetInstance(list[i]);
|
|
}
|
|
return v;
|
|
}
|
|
|
|
private readonly int segmentLimit;
|
|
private readonly Asn1OctetString[] elements;
|
|
|
|
[Obsolete("Will be removed")]
|
|
public BerOctetString(IEnumerable e)
|
|
: this(ToOctetStringArray(e))
|
|
{
|
|
}
|
|
|
|
public BerOctetString(byte[] contents)
|
|
: this(contents, DefaultSegmentLimit)
|
|
{
|
|
}
|
|
|
|
public BerOctetString(Asn1OctetString[] elements)
|
|
: this(elements, DefaultSegmentLimit)
|
|
{
|
|
}
|
|
|
|
public BerOctetString(byte[] contents, int segmentLimit)
|
|
: this(contents, null, segmentLimit)
|
|
{
|
|
}
|
|
|
|
public BerOctetString(Asn1OctetString[] elements, int segmentLimit)
|
|
: this(FlattenOctetStrings(elements), elements, segmentLimit)
|
|
{
|
|
}
|
|
|
|
private BerOctetString(byte[] contents, Asn1OctetString[] elements, int segmentLimit)
|
|
: base(contents)
|
|
{
|
|
this.elements = elements;
|
|
this.segmentLimit = segmentLimit;
|
|
}
|
|
|
|
/**
|
|
* return the DER octets that make up this string.
|
|
*/
|
|
public IEnumerator GetEnumerator()
|
|
{
|
|
if (elements == null)
|
|
return new ChunkEnumerator(contents, segmentLimit);
|
|
|
|
return elements.GetEnumerator();
|
|
}
|
|
|
|
[Obsolete("Use GetEnumerator() instead")]
|
|
public IEnumerator GetObjects()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
internal override IAsn1Encoding GetEncoding(int encoding)
|
|
{
|
|
if (Asn1OutputStream.EncodingBer != encoding)
|
|
return base.GetEncoding(encoding);
|
|
|
|
if (null == elements)
|
|
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.OctetString, contents);
|
|
|
|
return new ConstructedILEncoding(Asn1Tags.Universal, Asn1Tags.OctetString,
|
|
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
|
}
|
|
|
|
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
|
{
|
|
if (Asn1OutputStream.EncodingBer != encoding)
|
|
return base.GetEncodingImplicit(encoding, tagClass, tagNo);
|
|
|
|
if (null == elements)
|
|
return new PrimitiveEncoding(tagClass, tagNo, contents);
|
|
|
|
return new ConstructedILEncoding(tagClass, tagNo,
|
|
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
|
}
|
|
|
|
private class ChunkEnumerator
|
|
: IEnumerator
|
|
{
|
|
private readonly byte[] octets;
|
|
private readonly int segmentLimit;
|
|
|
|
private DerOctetString currentSegment = null;
|
|
private int nextSegmentPos = 0;
|
|
|
|
internal ChunkEnumerator(byte[] octets, int segmentLimit)
|
|
{
|
|
this.octets = octets;
|
|
this.segmentLimit = segmentLimit;
|
|
}
|
|
|
|
public object Current
|
|
{
|
|
get
|
|
{
|
|
if (null == currentSegment)
|
|
throw new InvalidOperationException();
|
|
|
|
return currentSegment;
|
|
}
|
|
}
|
|
|
|
public bool MoveNext()
|
|
{
|
|
if (nextSegmentPos >= octets.Length)
|
|
{
|
|
this.currentSegment = null;
|
|
return false;
|
|
}
|
|
|
|
int length = System.Math.Min(octets.Length - nextSegmentPos, segmentLimit);
|
|
byte[] segment = new byte[length];
|
|
Array.Copy(octets, nextSegmentPos, segment, 0, length);
|
|
this.currentSegment = new DerOctetString(segment);
|
|
this.nextSegmentPos += length;
|
|
return true;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
this.currentSegment = null;
|
|
this.nextSegmentPos = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|