Initial Commit
This commit is contained in:
154
iTechSharp/srcbc/asn1/ASN1StreamParser.cs
Normal file
154
iTechSharp/srcbc/asn1/ASN1StreamParser.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class Asn1StreamParser
|
||||
{
|
||||
private readonly Stream _in;
|
||||
private readonly int _limit;
|
||||
|
||||
public Asn1StreamParser(
|
||||
Stream inStream)
|
||||
: this(inStream, int.MaxValue)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1StreamParser(
|
||||
Stream inStream,
|
||||
int limit)
|
||||
{
|
||||
if (!inStream.CanRead)
|
||||
throw new ArgumentException("Expected stream to be readable", "inStream");
|
||||
|
||||
this._in = inStream;
|
||||
this._limit = limit;
|
||||
}
|
||||
|
||||
public Asn1StreamParser(
|
||||
byte[] encoding)
|
||||
: this(new MemoryStream(encoding, false), encoding.Length)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual IAsn1Convertible ReadObject()
|
||||
{
|
||||
int tag = _in.ReadByte();
|
||||
if (tag == -1)
|
||||
return null;
|
||||
|
||||
// turn of looking for "00" while we resolve the tag
|
||||
Set00Check(false);
|
||||
|
||||
//
|
||||
// calculate tag number
|
||||
//
|
||||
int tagNo = 0;
|
||||
if ((tag & Asn1Tags.Tagged) != 0 || (tag & Asn1Tags.Application) != 0)
|
||||
{
|
||||
tagNo = Asn1InputStream.ReadTagNumber(_in, tag);
|
||||
}
|
||||
|
||||
bool isConstructed = (tag & Asn1Tags.Constructed) != 0;
|
||||
int baseTagNo = tag & ~Asn1Tags.Constructed;
|
||||
|
||||
//
|
||||
// calculate length
|
||||
//
|
||||
int length = Asn1InputStream.ReadLength(_in, _limit);
|
||||
|
||||
if (length < 0) // indefinite length method
|
||||
{
|
||||
if (!isConstructed)
|
||||
throw new IOException("indefinite length primitive encoding encountered");
|
||||
|
||||
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in);
|
||||
|
||||
if ((tag & Asn1Tags.Tagged) != 0)
|
||||
{
|
||||
return new BerTaggedObjectParser(tag, tagNo, indIn);
|
||||
}
|
||||
|
||||
Asn1StreamParser sp = new Asn1StreamParser(indIn);
|
||||
|
||||
// TODO There are other tags that may be constructed (e.g. BitString)
|
||||
switch (baseTagNo)
|
||||
{
|
||||
case Asn1Tags.OctetString:
|
||||
return new BerOctetStringParser(sp);
|
||||
case Asn1Tags.Sequence:
|
||||
return new BerSequenceParser(sp);
|
||||
case Asn1Tags.Set:
|
||||
return new BerSetParser(sp);
|
||||
default:
|
||||
throw new IOException("unknown BER object encountered");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
|
||||
|
||||
if ((tag & Asn1Tags.Application) != 0)
|
||||
{
|
||||
return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray());
|
||||
}
|
||||
|
||||
if ((tag & Asn1Tags.Tagged) != 0)
|
||||
{
|
||||
return new BerTaggedObjectParser(tag, tagNo, defIn);
|
||||
}
|
||||
|
||||
if (isConstructed)
|
||||
{
|
||||
// TODO There are other tags that may be constructed (e.g. BitString)
|
||||
switch (baseTagNo)
|
||||
{
|
||||
case Asn1Tags.OctetString:
|
||||
//
|
||||
// yes, people actually do this...
|
||||
//
|
||||
return new BerOctetStringParser(new Asn1StreamParser(defIn));
|
||||
case Asn1Tags.Sequence:
|
||||
return new DerSequenceParser(new Asn1StreamParser(defIn));
|
||||
case Asn1Tags.Set:
|
||||
return new DerSetParser(new Asn1StreamParser(defIn));
|
||||
default:
|
||||
// TODO Add DerUnknownTagParser class?
|
||||
return new DerUnknownTag(tag, defIn.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Some primitive encodings can be handled by parsers too...
|
||||
switch (baseTagNo)
|
||||
{
|
||||
case Asn1Tags.OctetString:
|
||||
return new DerOctetStringParser(defIn);
|
||||
}
|
||||
|
||||
return Asn1InputStream.CreatePrimitiveDerObject(tag, defIn.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
private void Set00Check(
|
||||
bool enabled)
|
||||
{
|
||||
if (_in is IndefiniteLengthInputStream)
|
||||
{
|
||||
((IndefiniteLengthInputStream) _in).SetEofOn00(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1EncodableVector ReadVector()
|
||||
{
|
||||
Asn1EncodableVector v = new Asn1EncodableVector();
|
||||
|
||||
IAsn1Convertible obj;
|
||||
while ((obj = ReadObject()) != null)
|
||||
{
|
||||
v.Add(obj.ToAsn1Object());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user