You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
6.5 KiB
237 lines
6.5 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
using System.IO; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1 |
|
{ |
|
public class Asn1OutputStream |
|
: DerOutputStream |
|
{ |
|
public static Asn1OutputStream Create(Stream output) |
|
{ |
|
return new Asn1OutputStream(output); |
|
} |
|
|
|
public static Asn1OutputStream Create(Stream output, string encoding) |
|
{ |
|
if (Asn1Encodable.Der.Equals(encoding)) |
|
{ |
|
return new DerOutputStreamNew(output); |
|
} |
|
else |
|
{ |
|
return new Asn1OutputStream(output); |
|
} |
|
} |
|
|
|
|
|
public Asn1OutputStream(Stream os) |
|
: base(os) |
|
{ |
|
} |
|
|
|
public override void WriteObject(Asn1Encodable encodable) |
|
{ |
|
if (null == encodable) |
|
throw new IOException("null object detected"); |
|
|
|
WritePrimitive(encodable.ToAsn1Object(), true); |
|
FlushInternal(); |
|
} |
|
|
|
public override void WriteObject(Asn1Object primitive) |
|
{ |
|
if (null == primitive) |
|
throw new IOException("null object detected"); |
|
|
|
WritePrimitive(primitive, true); |
|
FlushInternal(); |
|
} |
|
|
|
internal void FlushInternal() |
|
{ |
|
// Placeholder to support future internal buffering |
|
} |
|
|
|
internal virtual bool IsBer |
|
{ |
|
get { return true; } |
|
} |
|
|
|
internal void WriteDL(int length) |
|
{ |
|
if (length < 128) |
|
{ |
|
WriteByte((byte)length); |
|
} |
|
else |
|
{ |
|
byte[] stack = new byte[5]; |
|
int pos = stack.Length; |
|
|
|
do |
|
{ |
|
stack[--pos] = (byte)length; |
|
length >>= 8; |
|
} |
|
while (length > 0); |
|
|
|
int count = stack.Length - pos; |
|
stack[--pos] = (byte)(0x80 | count); |
|
|
|
Write(stack, pos, count + 1); |
|
} |
|
} |
|
|
|
internal virtual void WriteElements(Asn1Encodable[] elements) |
|
{ |
|
for (int i = 0, count = elements.Length; i < count; ++i) |
|
{ |
|
elements[i].ToAsn1Object().Encode(this, true); |
|
} |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int identifier, byte contents) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteDL(1); |
|
WriteByte(contents); |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int identifier, byte[] contents) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteDL(contents.Length); |
|
Write(contents, 0, contents.Length); |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteDL(contentsLen); |
|
Write(contents, contentsOff, contentsLen); |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int identifier, byte contentsPrefix, byte[] contents, |
|
int contentsOff, int contentsLen) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteDL(1 + contentsLen); |
|
WriteByte(contentsPrefix); |
|
Write(contents, contentsOff, contentsLen); |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen, |
|
byte contentsSuffix) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteDL(contentsLen + 1); |
|
Write(contents, contentsOff, contentsLen); |
|
WriteByte(contentsSuffix); |
|
} |
|
|
|
internal void WriteEncodingDL(bool withID, int flags, int tag, byte[] contents) |
|
{ |
|
WriteIdentifier(withID, flags, tag); |
|
WriteDL(contents.Length); |
|
Write(contents, 0, contents.Length); |
|
} |
|
|
|
internal void WriteEncodingIL(bool withID, int identifier, Asn1Encodable[] elements) |
|
{ |
|
WriteIdentifier(withID, identifier); |
|
WriteByte(0x80); |
|
WriteElements(elements); |
|
WriteByte(0x00); |
|
WriteByte(0x00); |
|
} |
|
|
|
internal void WriteIdentifier(bool withID, int identifier) |
|
{ |
|
if (withID) |
|
{ |
|
WriteByte((byte)identifier); |
|
} |
|
} |
|
|
|
internal void WriteIdentifier(bool withID, int flags, int tag) |
|
{ |
|
if (!withID) |
|
{ |
|
// Don't write the identifier |
|
} |
|
else if (tag < 31) |
|
{ |
|
WriteByte((byte)(flags | tag)); |
|
} |
|
else |
|
{ |
|
byte[] stack = new byte[6]; |
|
int pos = stack.Length; |
|
|
|
stack[--pos] = (byte)(tag & 0x7F); |
|
while (tag > 127) |
|
{ |
|
tag >>= 7; |
|
stack[--pos] = (byte)(tag & 0x7F | 0x80); |
|
} |
|
|
|
stack[--pos] = (byte)(flags | 0x1F); |
|
|
|
Write(stack, pos, stack.Length - pos); |
|
} |
|
} |
|
|
|
internal virtual void WritePrimitive(Asn1Object primitive, bool withID) |
|
{ |
|
primitive.Encode(this, withID); |
|
} |
|
|
|
internal virtual void WritePrimitives(Asn1Object[] primitives) |
|
{ |
|
for (int i = 0, count = primitives.Length; i < count; ++i) |
|
{ |
|
WritePrimitive(primitives[i], true); |
|
} |
|
} |
|
|
|
internal static int GetLengthOfDL(int dl) |
|
{ |
|
if (dl < 128) |
|
return 1; |
|
|
|
int length = 2; |
|
while ((dl >>= 8) > 0) |
|
{ |
|
++length; |
|
} |
|
return length; |
|
} |
|
|
|
internal static int GetLengthOfEncodingDL(bool withID, int contentsLength) |
|
{ |
|
return (withID ? 1 : 0) + GetLengthOfDL(contentsLength) + contentsLength; |
|
} |
|
|
|
internal static int GetLengthOfEncodingDL(bool withID, int tag, int contentsLength) |
|
{ |
|
return (withID ? GetLengthOfIdentifier(tag) : 0) + GetLengthOfDL(contentsLength) + contentsLength; |
|
} |
|
|
|
internal static int GetLengthOfIdentifier(int tag) |
|
{ |
|
if (tag < 31) |
|
return 1; |
|
|
|
int length = 2; |
|
while ((tag >>= 7) > 0) |
|
{ |
|
++length; |
|
} |
|
return length; |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|