mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-11 08:38:45 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2000 - 2017 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc7453f14fee55347b287df5490f3c4d
|
||||
timeCreated: 1490202077
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bedc740ef99712e40b82c0c7de92cf9c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Generator
|
||||
{
|
||||
private Stream _out;
|
||||
|
||||
protected Asn1Generator(
|
||||
Stream outStream)
|
||||
{
|
||||
_out = outStream;
|
||||
}
|
||||
|
||||
protected Stream Out
|
||||
{
|
||||
get { return _out; }
|
||||
}
|
||||
|
||||
public abstract void AddObject(Asn1Encodable obj);
|
||||
|
||||
public abstract void AddObject(Asn1Object obj);
|
||||
|
||||
public abstract Stream GetRawOutputStream();
|
||||
|
||||
public abstract void Close();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdc81b96ab45ff94098a67c1dcf27e23
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public interface Asn1OctetStringParser
|
||||
: IAsn1Convertible
|
||||
{
|
||||
/// <summary>Return the content of the OCTET STRING as a <see cref="Stream"/>.</summary>
|
||||
/// <returns>A <see cref="Stream"/> represnting the OCTET STRING's content.</returns>
|
||||
Stream GetOctetStream();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc7b00883ebe075438a06d46defe0b35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public interface Asn1SequenceParser
|
||||
: IAsn1Convertible
|
||||
{
|
||||
IAsn1Convertible ReadObject();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 945f35756f280754580483acdd35d1f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public interface Asn1SetParser
|
||||
: IAsn1Convertible
|
||||
{
|
||||
IAsn1Convertible ReadObject();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5c4059ebe7ac0240878ec76e191d1ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,248 @@
|
||||
#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 Asn1StreamParser
|
||||
{
|
||||
private readonly Stream _in;
|
||||
private readonly int _limit;
|
||||
|
||||
private readonly byte[][] tmpBuffers;
|
||||
|
||||
public Asn1StreamParser(Stream input)
|
||||
: this(input, Asn1InputStream.FindLimit(input))
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1StreamParser(byte[] encoding)
|
||||
: this(new MemoryStream(encoding, false), encoding.Length)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1StreamParser(Stream input, int limit)
|
||||
: this(input, limit, new byte[16][])
|
||||
{
|
||||
}
|
||||
|
||||
internal Asn1StreamParser(Stream input, int limit, byte[][] tmpBuffers)
|
||||
{
|
||||
if (!input.CanRead)
|
||||
throw new ArgumentException("Expected stream to be readable", "input");
|
||||
|
||||
this._in = input;
|
||||
this._limit = limit;
|
||||
this.tmpBuffers = tmpBuffers;
|
||||
}
|
||||
|
||||
public virtual IAsn1Convertible ReadObject()
|
||||
{
|
||||
int tagHdr = _in.ReadByte();
|
||||
if (tagHdr < 0)
|
||||
return null;
|
||||
|
||||
return ImplParseObject(tagHdr);
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ImplParseObject(int tagHdr)
|
||||
{
|
||||
// turn off looking for "00" while we resolve the tag
|
||||
Set00Check(false);
|
||||
|
||||
//
|
||||
// calculate tag number
|
||||
//
|
||||
int tagNo = Asn1InputStream.ReadTagNumber(_in, tagHdr);
|
||||
|
||||
//
|
||||
// calculate length
|
||||
//
|
||||
int length = Asn1InputStream.ReadLength(_in, _limit,
|
||||
tagNo == Asn1Tags.BitString || tagNo == Asn1Tags.OctetString || tagNo == Asn1Tags.Sequence ||
|
||||
tagNo == Asn1Tags.Set || tagNo == Asn1Tags.External);
|
||||
|
||||
if (length < 0) // indefinite-length method
|
||||
{
|
||||
if (0 == (tagHdr & Asn1Tags.Constructed))
|
||||
throw new IOException("indefinite-length primitive encoding encountered");
|
||||
|
||||
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
|
||||
Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit, tmpBuffers);
|
||||
|
||||
int tagClass = tagHdr & Asn1Tags.Private;
|
||||
if (0 != tagClass)
|
||||
return new BerTaggedObjectParser(tagClass, tagNo, sp);
|
||||
|
||||
return sp.ParseImplicitConstructedIL(tagNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
|
||||
|
||||
if (0 == (tagHdr & Asn1Tags.Flags))
|
||||
return ParseImplicitPrimitive(tagNo, defIn);
|
||||
|
||||
Asn1StreamParser sp = new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers);
|
||||
|
||||
int tagClass = tagHdr & Asn1Tags.Private;
|
||||
if (0 != tagClass)
|
||||
{
|
||||
bool isConstructed = (tagHdr & Asn1Tags.Constructed) != 0;
|
||||
|
||||
return new DLTaggedObjectParser(tagClass, tagNo, isConstructed, sp);
|
||||
}
|
||||
|
||||
return sp.ParseImplicitConstructedDL(tagNo);
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1Object LoadTaggedDL(int tagClass, int tagNo, bool constructed)
|
||||
{
|
||||
if (!constructed)
|
||||
{
|
||||
byte[] contentsOctets = ((DefiniteLengthInputStream)_in).ToArray();
|
||||
return Asn1TaggedObject.CreatePrimitive(tagClass, tagNo, contentsOctets);
|
||||
}
|
||||
|
||||
Asn1EncodableVector contentsElements = ReadVector();
|
||||
return Asn1TaggedObject.CreateConstructedDL(tagClass, tagNo, contentsElements);
|
||||
}
|
||||
|
||||
internal Asn1Object LoadTaggedIL(int tagClass, int tagNo)
|
||||
{
|
||||
Asn1EncodableVector contentsElements = ReadVector();
|
||||
return Asn1TaggedObject.CreateConstructedIL(tagClass, tagNo, contentsElements);
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ParseImplicitConstructedDL(int univTagNo)
|
||||
{
|
||||
switch (univTagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
// TODO[asn1] DLConstructedBitStringParser
|
||||
return new BerBitStringParser(this);
|
||||
case Asn1Tags.External:
|
||||
return new DerExternalParser(this);
|
||||
case Asn1Tags.OctetString:
|
||||
// TODO[asn1] DLConstructedOctetStringParser
|
||||
return new BerOctetStringParser(this);
|
||||
case Asn1Tags.Set:
|
||||
return new DerSetParser(this);
|
||||
case Asn1Tags.Sequence:
|
||||
return new DerSequenceParser(this);
|
||||
default:
|
||||
throw new Asn1Exception("unknown DL object encountered: 0x" + univTagNo.ToString("X"));
|
||||
}
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ParseImplicitConstructedIL(int univTagNo)
|
||||
{
|
||||
switch (univTagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return new BerBitStringParser(this);
|
||||
case Asn1Tags.External:
|
||||
// TODO[asn1] BERExternalParser
|
||||
return new DerExternalParser(this);
|
||||
case Asn1Tags.OctetString:
|
||||
return new BerOctetStringParser(this);
|
||||
case Asn1Tags.Sequence:
|
||||
return new BerSequenceParser(this);
|
||||
case Asn1Tags.Set:
|
||||
return new BerSetParser(this);
|
||||
default:
|
||||
throw new Asn1Exception("unknown BER object encountered: 0x" + univTagNo.ToString("X"));
|
||||
}
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ParseImplicitPrimitive(int univTagNo)
|
||||
{
|
||||
return ParseImplicitPrimitive(univTagNo, (DefiniteLengthInputStream)_in);
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ParseImplicitPrimitive(int univTagNo, DefiniteLengthInputStream defIn)
|
||||
{
|
||||
// Some primitive encodings can be handled by parsers too...
|
||||
switch (univTagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return new DLBitStringParser(defIn);
|
||||
case Asn1Tags.External:
|
||||
throw new Asn1Exception("externals must use constructed encoding (see X.690 8.18)");
|
||||
case Asn1Tags.OctetString:
|
||||
return new DerOctetStringParser(defIn);
|
||||
case Asn1Tags.Set:
|
||||
throw new Asn1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
|
||||
case Asn1Tags.Sequence:
|
||||
throw new Asn1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Asn1InputStream.CreatePrimitiveDerObject(univTagNo, defIn, tmpBuffers);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new Asn1Exception("corrupted stream detected", e);
|
||||
}
|
||||
}
|
||||
|
||||
internal IAsn1Convertible ParseObject(int univTagNo)
|
||||
{
|
||||
if (univTagNo < 0 || univTagNo > 30)
|
||||
throw new ArgumentException("invalid universal tag number: " + univTagNo, "univTagNo");
|
||||
|
||||
int tagHdr = _in.ReadByte();
|
||||
if (tagHdr < 0)
|
||||
return null;
|
||||
|
||||
if ((tagHdr & ~Asn1Tags.Constructed) != univTagNo)
|
||||
throw new IOException("unexpected identifier encountered: " + tagHdr);
|
||||
|
||||
return ImplParseObject(tagHdr);
|
||||
}
|
||||
|
||||
internal Asn1TaggedObjectParser ParseTaggedObject()
|
||||
{
|
||||
int tagHdr = _in.ReadByte();
|
||||
if (tagHdr< 0)
|
||||
return null;
|
||||
|
||||
int tagClass = tagHdr & Asn1Tags.Private;
|
||||
if (0 == tagClass)
|
||||
throw new Asn1Exception("no tagged object found");
|
||||
|
||||
return (Asn1TaggedObjectParser)ImplParseObject(tagHdr);
|
||||
}
|
||||
|
||||
// TODO[asn1] Prefer 'LoadVector'
|
||||
internal Asn1EncodableVector ReadVector()
|
||||
{
|
||||
int tagHdr = _in.ReadByte();
|
||||
if (tagHdr < 0)
|
||||
return new Asn1EncodableVector(0);
|
||||
|
||||
Asn1EncodableVector v = new Asn1EncodableVector();
|
||||
do
|
||||
{
|
||||
IAsn1Convertible obj = ImplParseObject(tagHdr);
|
||||
|
||||
v.Add(obj.ToAsn1Object());
|
||||
}
|
||||
while ((tagHdr = _in.ReadByte()) >= 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
private void Set00Check(bool enabled)
|
||||
{
|
||||
if (_in is IndefiniteLengthInputStream indef)
|
||||
{
|
||||
indef.SetEofOn00(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12d648f2463b0b34a8a0756dbb9d6bfb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public interface Asn1TaggedObjectParser
|
||||
: IAsn1Convertible
|
||||
{
|
||||
int TagClass { get; }
|
||||
|
||||
int TagNo { get; }
|
||||
|
||||
bool HasContextTag(int tagNo);
|
||||
|
||||
bool HasTag(int tagClass, int tagNo);
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
IAsn1Convertible ParseBaseUniversal(bool declaredExplicit, int baseTagNo);
|
||||
|
||||
/// <summary>Needed for open types, until we have better type-guided parsing support.</summary>
|
||||
/// <remarks>
|
||||
/// Use sparingly for other purposes, and prefer <see cref="ParseExplicitBaseTagged"/> or
|
||||
/// <see cref="ParseBaseUniversal(bool, int)"/> where possible. Before using, check for matching tag
|
||||
/// <see cref="TagClass">class</see> and <see cref="TagNo">number</see>.
|
||||
/// </remarks>
|
||||
/// <exception cref="IOException"/>
|
||||
IAsn1Convertible ParseExplicitBaseObject();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
Asn1TaggedObjectParser ParseExplicitBaseTagged();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
Asn1TaggedObjectParser ParseImplicitBaseTagged(int baseTagClass, int baseTagNo);
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e183ed6c26f0fac4caebd14e56080e86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public interface Asn1BitStringParser
|
||||
: IAsn1Convertible
|
||||
{
|
||||
/// <summary>Return a <see cref="Stream"/> representing the contents of the BIT STRING. The final byte, if any,
|
||||
/// may include pad bits. See <see cref="PadBits"/>.</summary>
|
||||
/// <returns>A <see cref="Stream"/> with its source as the BIT STRING content.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
Stream GetBitStream();
|
||||
|
||||
/// <summary>Return a <see cref="Stream"/> representing the contents of the BIT STRING, where the content is
|
||||
/// expected to be octet-aligned (this will be automatically checked during parsing).</summary>
|
||||
/// <returns>A <see cref="Stream"/> with its source as the BIT STRING content.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
Stream GetOctetStream();
|
||||
|
||||
/// <summary>Return the number of pad bits, if any, in the final byte, if any, read from
|
||||
/// <see cref="GetBitStream"/>.</summary>
|
||||
/// <remarks>
|
||||
/// This number is in the range zero to seven. That number of the least significant bits of the final byte, if
|
||||
/// any, are not part of the contents and should be ignored. NOTE: Must be called AFTER the stream has been
|
||||
/// fully processed. (Does not need to be called if <see cref="GetOctetStream"/> was used instead of
|
||||
/// <see cref="GetBitStream"/>.
|
||||
/// </remarks>
|
||||
/// <returns>The number of pad bits. In the range zero to seven.</returns>
|
||||
int PadBits { get; }
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24137e6820af97b4bb29831a34398f8f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Encodable
|
||||
: IAsn1Convertible
|
||||
{
|
||||
public const string Der = "DER";
|
||||
public const string Ber = "BER";
|
||||
|
||||
public virtual void EncodeTo(Stream output)
|
||||
{
|
||||
ToAsn1Object().EncodeTo(output);
|
||||
}
|
||||
|
||||
public virtual void EncodeTo(Stream output, string encoding)
|
||||
{
|
||||
ToAsn1Object().EncodeTo(output, encoding);
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
ToAsn1Object().EncodeTo(bOut);
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public byte[] GetEncoded(string encoding)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
ToAsn1Object().EncodeTo(bOut, encoding);
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DER encoding of the object, null if the DER encoding can not be made.
|
||||
*
|
||||
* @return a DER byte array, null otherwise.
|
||||
*/
|
||||
public byte[] GetDerEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetEncoded(Der);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override int GetHashCode()
|
||||
{
|
||||
return ToAsn1Object().CallAsn1GetHashCode();
|
||||
}
|
||||
|
||||
public sealed override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
IAsn1Convertible other = obj as IAsn1Convertible;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
Asn1Object o1 = ToAsn1Object();
|
||||
Asn1Object o2 = other.ToAsn1Object();
|
||||
|
||||
return o1 == o2 || (null != o2 && o1.CallAsn1Equals(o2));
|
||||
}
|
||||
|
||||
public abstract Asn1Object ToAsn1Object();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b69b682df6ac1845b77ec1b6bf0427d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,248 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/**
|
||||
* Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
|
||||
*/
|
||||
public class Asn1EncodableVector
|
||||
: IEnumerable<Asn1Encodable>
|
||||
{
|
||||
internal static readonly Asn1Encodable[] EmptyElements = new Asn1Encodable[0];
|
||||
|
||||
private const int DefaultCapacity = 10;
|
||||
|
||||
private Asn1Encodable[] elements;
|
||||
private int elementCount;
|
||||
private bool copyOnWrite;
|
||||
|
||||
public static Asn1EncodableVector FromEnumerable(IEnumerable<Asn1Encodable> e)
|
||||
{
|
||||
Asn1EncodableVector v = new Asn1EncodableVector();
|
||||
foreach (Asn1Encodable obj in e)
|
||||
{
|
||||
v.Add(obj);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public Asn1EncodableVector()
|
||||
: this(DefaultCapacity)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1EncodableVector(int initialCapacity)
|
||||
{
|
||||
if (initialCapacity < 0)
|
||||
throw new ArgumentException("must not be negative", "initialCapacity");
|
||||
|
||||
this.elements = (initialCapacity == 0) ? EmptyElements : new Asn1Encodable[initialCapacity];
|
||||
this.elementCount = 0;
|
||||
this.copyOnWrite = false;
|
||||
}
|
||||
|
||||
public Asn1EncodableVector(Asn1Encodable element)
|
||||
: this()
|
||||
{
|
||||
Add(element);
|
||||
}
|
||||
|
||||
public Asn1EncodableVector(Asn1Encodable element1, Asn1Encodable element2)
|
||||
: this()
|
||||
{
|
||||
Add(element1);
|
||||
Add(element2);
|
||||
}
|
||||
|
||||
public Asn1EncodableVector(params Asn1Encodable[] v)
|
||||
: this()
|
||||
{
|
||||
Add(v);
|
||||
}
|
||||
|
||||
public void Add(Asn1Encodable element)
|
||||
{
|
||||
if (null == element)
|
||||
throw new ArgumentNullException("element");
|
||||
|
||||
int capacity = elements.Length;
|
||||
int minCapacity = elementCount + 1;
|
||||
if ((minCapacity > capacity) | copyOnWrite)
|
||||
{
|
||||
Reallocate(minCapacity);
|
||||
}
|
||||
|
||||
this.elements[elementCount] = element;
|
||||
this.elementCount = minCapacity;
|
||||
}
|
||||
|
||||
public void Add(Asn1Encodable element1, Asn1Encodable element2)
|
||||
{
|
||||
Add(element1);
|
||||
Add(element2);
|
||||
}
|
||||
|
||||
public void Add(params Asn1Encodable[] objs)
|
||||
{
|
||||
foreach (Asn1Encodable obj in objs)
|
||||
{
|
||||
Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOptional(Asn1Encodable element)
|
||||
{
|
||||
if (element != null)
|
||||
{
|
||||
Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOptional(Asn1Encodable element1, Asn1Encodable element2)
|
||||
{
|
||||
if (element1 != null)
|
||||
{
|
||||
Add(element1);
|
||||
}
|
||||
if (element2 != null)
|
||||
{
|
||||
Add(element2);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOptional(params Asn1Encodable[] elements)
|
||||
{
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (var element in elements)
|
||||
{
|
||||
if (element != null)
|
||||
{
|
||||
Add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOptionalTagged(bool isExplicit, int tagNo, Asn1Encodable obj)
|
||||
{
|
||||
if (null != obj)
|
||||
{
|
||||
Add(new DerTaggedObject(isExplicit, tagNo, obj));
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOptionalTagged(bool isExplicit, int tagClass, int tagNo, Asn1Encodable obj)
|
||||
{
|
||||
if (null != obj)
|
||||
{
|
||||
Add(new DerTaggedObject(isExplicit, tagClass, tagNo, obj));
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAll(Asn1EncodableVector other)
|
||||
{
|
||||
if (null == other)
|
||||
throw new ArgumentNullException("other");
|
||||
|
||||
int otherElementCount = other.Count;
|
||||
if (otherElementCount < 1)
|
||||
return;
|
||||
|
||||
int capacity = elements.Length;
|
||||
int minCapacity = elementCount + otherElementCount;
|
||||
if ((minCapacity > capacity) | copyOnWrite)
|
||||
{
|
||||
Reallocate(minCapacity);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
Asn1Encodable otherElement = other[i];
|
||||
if (null == otherElement)
|
||||
throw new NullReferenceException("'other' elements cannot be null");
|
||||
|
||||
this.elements[elementCount + i] = otherElement;
|
||||
}
|
||||
while (++i < otherElementCount);
|
||||
|
||||
this.elementCount = minCapacity;
|
||||
}
|
||||
|
||||
public Asn1Encodable this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index >= elementCount)
|
||||
throw new IndexOutOfRangeException(index + " >= " + elementCount);
|
||||
|
||||
return elements[index];
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return elementCount; }
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<Asn1Encodable> GetEnumerator()
|
||||
{
|
||||
IEnumerable<Asn1Encodable> e = CopyElements();
|
||||
return e.GetEnumerator();
|
||||
}
|
||||
|
||||
internal Asn1Encodable[] CopyElements()
|
||||
{
|
||||
if (0 == elementCount)
|
||||
return EmptyElements;
|
||||
|
||||
Asn1Encodable[] copy = new Asn1Encodable[elementCount];
|
||||
Array.Copy(elements, 0, copy, 0, elementCount);
|
||||
return copy;
|
||||
}
|
||||
|
||||
internal Asn1Encodable[] TakeElements()
|
||||
{
|
||||
if (0 == elementCount)
|
||||
return EmptyElements;
|
||||
|
||||
if (elements.Length == elementCount)
|
||||
{
|
||||
this.copyOnWrite = true;
|
||||
return elements;
|
||||
}
|
||||
|
||||
Asn1Encodable[] copy = new Asn1Encodable[elementCount];
|
||||
Array.Copy(elements, 0, copy, 0, elementCount);
|
||||
return copy;
|
||||
}
|
||||
|
||||
private void Reallocate(int minCapacity)
|
||||
{
|
||||
int oldCapacity = elements.Length;
|
||||
int newCapacity = System.Math.Max(oldCapacity, minCapacity + (minCapacity >> 1));
|
||||
|
||||
Asn1Encodable[] copy = new Asn1Encodable[newCapacity];
|
||||
Array.Copy(elements, 0, copy, 0, elementCount);
|
||||
|
||||
this.elements = copy;
|
||||
this.copyOnWrite = false;
|
||||
}
|
||||
|
||||
internal static Asn1Encodable[] CloneElements(Asn1Encodable[] elements)
|
||||
{
|
||||
return elements.Length < 1 ? EmptyElements : (Asn1Encodable[])elements.Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3245f80405a56e41ad1c7af42022aea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Exception
|
||||
: IOException
|
||||
{
|
||||
public Asn1Exception()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1Exception(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1Exception(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected Asn1Exception(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbd822b3cbfd4b643a313c46df1ee0a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,266 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/// <summary>GeneralizedTime ASN.1 type</summary>
|
||||
public class Asn1GeneralizedTime
|
||||
: Asn1Object
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1GeneralizedTime), Asn1Tags.GeneralizedTime) { }
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return CreatePrimitive(octetString.GetOctets());
|
||||
}
|
||||
}
|
||||
|
||||
public static Asn1GeneralizedTime GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1GeneralizedTime asn1GeneralizedTime)
|
||||
return asn1GeneralizedTime;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1GeneralizedTime converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1GeneralizedTime)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), nameof(obj));
|
||||
}
|
||||
|
||||
public static Asn1GeneralizedTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1GeneralizedTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
private readonly string m_timeString;
|
||||
private readonly bool m_timeStringCanonical;
|
||||
private readonly DateTime m_dateTime;
|
||||
|
||||
public Asn1GeneralizedTime(string timeString)
|
||||
{
|
||||
m_timeString = timeString ?? throw new ArgumentNullException(nameof(timeString));
|
||||
m_timeStringCanonical = false; // TODO Dynamic check?
|
||||
|
||||
try
|
||||
{
|
||||
m_dateTime = FromString(timeString);
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
throw new ArgumentException("invalid date string: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(DateTime dateTime)
|
||||
{
|
||||
dateTime = dateTime.ToUniversalTime();
|
||||
|
||||
m_dateTime = dateTime;
|
||||
m_timeString = ToStringCanonical(dateTime);
|
||||
m_timeStringCanonical = true;
|
||||
}
|
||||
|
||||
// TODO TimeZoneInfo or other locale-specific constructors?
|
||||
|
||||
internal Asn1GeneralizedTime(byte[] contents)
|
||||
: this(Encoding.ASCII.GetString(contents))
|
||||
{
|
||||
}
|
||||
|
||||
public string TimeString => m_timeString;
|
||||
|
||||
public DateTime ToDateTime()
|
||||
{
|
||||
return m_dateTime;
|
||||
}
|
||||
|
||||
internal byte[] GetContents(int encoding)
|
||||
{
|
||||
if (encoding == Asn1OutputStream.EncodingDer && !m_timeStringCanonical)
|
||||
return Encoding.ASCII.GetBytes(ToStringCanonical(m_dateTime));
|
||||
|
||||
return Encoding.ASCII.GetBytes(m_timeString);
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetContents(encoding));
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
return new PrimitiveEncoding(tagClass, tagNo, GetContents(encoding));
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
if (!(asn1Object is Asn1GeneralizedTime that))
|
||||
return false;
|
||||
|
||||
// TODO Performance
|
||||
return Arrays.AreEqual(
|
||||
this.GetContents(Asn1OutputStream.EncodingDer),
|
||||
that.GetContents(Asn1OutputStream.EncodingDer));
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
// TODO Performance
|
||||
return Arrays.GetHashCode(
|
||||
this.GetContents(Asn1OutputStream.EncodingDer));
|
||||
}
|
||||
|
||||
internal static Asn1GeneralizedTime CreatePrimitive(byte[] contents)
|
||||
{
|
||||
return new Asn1GeneralizedTime(contents);
|
||||
}
|
||||
|
||||
private static DateTime FromString(string s)
|
||||
{
|
||||
if (s.Length < 10)
|
||||
throw new FormatException();
|
||||
|
||||
s = s.Replace(',', '.');
|
||||
|
||||
if (Org.BouncyCastle.Utilities.Platform.EndsWith(s, "Z"))
|
||||
{
|
||||
switch (s.Length)
|
||||
{
|
||||
case 11: return ParseUtc(s, @"yyyyMMddHH\Z");
|
||||
case 13: return ParseUtc(s, @"yyyyMMddHHmm\Z");
|
||||
case 15: return ParseUtc(s, @"yyyyMMddHHmmss\Z");
|
||||
case 17: return ParseUtc(s, @"yyyyMMddHHmmss.f\Z");
|
||||
case 18: return ParseUtc(s, @"yyyyMMddHHmmss.ff\Z");
|
||||
case 19: return ParseUtc(s, @"yyyyMMddHHmmss.fff\Z");
|
||||
case 20: return ParseUtc(s, @"yyyyMMddHHmmss.ffff\Z");
|
||||
case 21: return ParseUtc(s, @"yyyyMMddHHmmss.fffff\Z");
|
||||
case 22: return ParseUtc(s, @"yyyyMMddHHmmss.ffffff\Z");
|
||||
case 23: return ParseUtc(s, @"yyyyMMddHHmmss.fffffff\Z");
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
int signIndex = IndexOfSign(s, System.Math.Max(10, s.Length - 5));
|
||||
|
||||
if (signIndex < 0)
|
||||
{
|
||||
switch (s.Length)
|
||||
{
|
||||
case 10: return ParseLocal(s, @"yyyyMMddHH");
|
||||
case 12: return ParseLocal(s, @"yyyyMMddHHmm");
|
||||
case 14: return ParseLocal(s, @"yyyyMMddHHmmss");
|
||||
case 16: return ParseLocal(s, @"yyyyMMddHHmmss.f");
|
||||
case 17: return ParseLocal(s, @"yyyyMMddHHmmss.ff");
|
||||
case 18: return ParseLocal(s, @"yyyyMMddHHmmss.fff");
|
||||
case 19: return ParseLocal(s, @"yyyyMMddHHmmss.ffff");
|
||||
case 20: return ParseLocal(s, @"yyyyMMddHHmmss.fffff");
|
||||
case 21: return ParseLocal(s, @"yyyyMMddHHmmss.ffffff");
|
||||
case 22: return ParseLocal(s, @"yyyyMMddHHmmss.fffffff");
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
if (signIndex == s.Length - 5)
|
||||
{
|
||||
switch (s.Length)
|
||||
{
|
||||
case 15: return ParseTimeZone(s, @"yyyyMMddHHzzz");
|
||||
case 17: return ParseTimeZone(s, @"yyyyMMddHHmmzzz");
|
||||
case 19: return ParseTimeZone(s, @"yyyyMMddHHmmsszzz");
|
||||
case 21: return ParseTimeZone(s, @"yyyyMMddHHmmss.fzzz");
|
||||
case 22: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffzzz");
|
||||
case 23: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffzzz");
|
||||
case 24: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffffzzz");
|
||||
case 25: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffffzzz");
|
||||
case 26: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffffffzzz");
|
||||
case 27: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffffffzzz");
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
if (signIndex == s.Length - 3)
|
||||
{
|
||||
switch (s.Length)
|
||||
{
|
||||
case 13: return ParseTimeZone(s, @"yyyyMMddHHzz");
|
||||
case 15: return ParseTimeZone(s, @"yyyyMMddHHmmzz");
|
||||
case 17: return ParseTimeZone(s, @"yyyyMMddHHmmsszz");
|
||||
case 19: return ParseTimeZone(s, @"yyyyMMddHHmmss.fzz");
|
||||
case 20: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffzz");
|
||||
case 21: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffzz");
|
||||
case 22: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffffzz");
|
||||
case 23: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffffzz");
|
||||
case 24: return ParseTimeZone(s, @"yyyyMMddHHmmss.ffffffzz");
|
||||
case 25: return ParseTimeZone(s, @"yyyyMMddHHmmss.fffffffzz");
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
private static int IndexOfSign(string s, int startIndex)
|
||||
{
|
||||
int index = Org.BouncyCastle.Utilities.Platform.IndexOf(s, '+', startIndex);
|
||||
if (index < 0)
|
||||
{
|
||||
index = Org.BouncyCastle.Utilities.Platform.IndexOf(s, '-', startIndex);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static DateTime ParseLocal(string s, string format)
|
||||
{
|
||||
return DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeLocal);
|
||||
}
|
||||
|
||||
private static DateTime ParseTimeZone(string s, string format)
|
||||
{
|
||||
return DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal);
|
||||
}
|
||||
|
||||
private static DateTime ParseUtc(string s, string format)
|
||||
{
|
||||
return DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo,
|
||||
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
||||
}
|
||||
|
||||
private static string ToStringCanonical(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToUniversalTime().ToString(@"yyyyMMddHHmmss.FFFFFFFK", DateTimeFormatInfo.InvariantInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d717ef26a13ca4645a37a12bf5d48229
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,471 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/**
|
||||
* a general purpose ASN.1 decoder - note: this class differs from the
|
||||
* others in that it returns null after it has read the last object in
|
||||
* the stream. If an ASN.1 Null is encountered a Der/BER Null object is
|
||||
* returned.
|
||||
*/
|
||||
public class Asn1InputStream
|
||||
: FilterStream
|
||||
{
|
||||
private readonly int limit;
|
||||
|
||||
internal byte[][] tmpBuffers;
|
||||
|
||||
internal static int FindLimit(Stream input)
|
||||
{
|
||||
if (input is LimitedInputStream limited)
|
||||
return limited.Limit;
|
||||
|
||||
if (input is Asn1InputStream asn1)
|
||||
return asn1.Limit;
|
||||
|
||||
if (input is MemoryStream memory)
|
||||
return Convert.ToInt32(memory.Length - memory.Position);
|
||||
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
public Asn1InputStream(Stream input)
|
||||
: this(input, FindLimit(input))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream based on the input byte array. The length of DER objects in
|
||||
* the stream is automatically limited to the length of the input array.
|
||||
*
|
||||
* @param input array containing ASN.1 encoded data.
|
||||
*/
|
||||
public Asn1InputStream(byte[] input)
|
||||
: this(new MemoryStream(input, false), input.Length)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream where no DER object will be longer than limit.
|
||||
*
|
||||
* @param input stream containing ASN.1 encoded data.
|
||||
* @param limit maximum size of a DER encoded object.
|
||||
*/
|
||||
public Asn1InputStream(Stream input, int limit)
|
||||
: this(input, limit, new byte[16][])
|
||||
{
|
||||
}
|
||||
|
||||
internal Asn1InputStream(Stream input, int limit, byte[][] tmpBuffers)
|
||||
: base(input)
|
||||
{
|
||||
this.limit = limit;
|
||||
this.tmpBuffers = tmpBuffers;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
tmpBuffers = null;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/**
|
||||
* build an object given its tag and the number of bytes to construct it from.
|
||||
*/
|
||||
private Asn1Object BuildObject(int tagHdr, int tagNo, int length)
|
||||
{
|
||||
// TODO[asn1] Special-case zero length first?
|
||||
|
||||
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(s, length, limit);
|
||||
|
||||
if (0 == (tagHdr & Asn1Tags.Flags))
|
||||
return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers);
|
||||
|
||||
int tagClass = tagHdr & Asn1Tags.Private;
|
||||
if (0 != tagClass)
|
||||
{
|
||||
bool isConstructed = (tagHdr & Asn1Tags.Constructed) != 0;
|
||||
return ReadTaggedObjectDL(tagClass, tagNo, isConstructed, defIn);
|
||||
}
|
||||
|
||||
switch (tagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return BuildConstructedBitString(ReadVector(defIn));
|
||||
case Asn1Tags.OctetString:
|
||||
return BuildConstructedOctetString(ReadVector(defIn));
|
||||
case Asn1Tags.Sequence:
|
||||
return CreateDLSequence(defIn);
|
||||
case Asn1Tags.Set:
|
||||
return CreateDLSet(defIn);
|
||||
case Asn1Tags.External:
|
||||
return DLSequence.FromVector(ReadVector(defIn)).ToAsn1External();
|
||||
default:
|
||||
throw new IOException("unknown tag " + tagNo + " encountered");
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1Object ReadTaggedObjectDL(int tagClass, int tagNo, bool constructed, DefiniteLengthInputStream defIn)
|
||||
{
|
||||
if (!constructed)
|
||||
{
|
||||
byte[] contentsOctets = defIn.ToArray();
|
||||
return Asn1TaggedObject.CreatePrimitive(tagClass, tagNo, contentsOctets);
|
||||
}
|
||||
|
||||
Asn1EncodableVector contentsElements = ReadVector(defIn);
|
||||
return Asn1TaggedObject.CreateConstructedDL(tagClass, tagNo, contentsElements);
|
||||
}
|
||||
|
||||
internal virtual Asn1EncodableVector ReadVector()
|
||||
{
|
||||
Asn1Object o = ReadObject();
|
||||
if (null == o)
|
||||
return new Asn1EncodableVector(0);
|
||||
|
||||
Asn1EncodableVector v = new Asn1EncodableVector();
|
||||
do
|
||||
{
|
||||
v.Add(o);
|
||||
}
|
||||
while ((o = ReadObject()) != null);
|
||||
return v;
|
||||
}
|
||||
|
||||
internal virtual Asn1EncodableVector ReadVector(DefiniteLengthInputStream defIn)
|
||||
{
|
||||
int remaining = defIn.Remaining;
|
||||
if (remaining < 1)
|
||||
return new Asn1EncodableVector(0);
|
||||
|
||||
return new Asn1InputStream(defIn, remaining, tmpBuffers).ReadVector();
|
||||
}
|
||||
|
||||
internal virtual Asn1Sequence CreateDLSequence(DefiniteLengthInputStream defIn)
|
||||
{
|
||||
return DLSequence.FromVector(ReadVector(defIn));
|
||||
}
|
||||
|
||||
internal virtual Asn1Set CreateDLSet(DefiniteLengthInputStream defIn)
|
||||
{
|
||||
return DLSet.FromVector(ReadVector(defIn));
|
||||
}
|
||||
|
||||
public Asn1Object ReadObject()
|
||||
{
|
||||
int tagHdr = s.ReadByte();
|
||||
if (tagHdr <= 0)
|
||||
{
|
||||
if (tagHdr == 0)
|
||||
throw new IOException("unexpected end-of-contents marker");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
int tagNo = ReadTagNumber(s, tagHdr);
|
||||
int length = ReadLength(s, limit, false);
|
||||
|
||||
if (length >= 0)
|
||||
{
|
||||
// definite-length
|
||||
try
|
||||
{
|
||||
return BuildObject(tagHdr, tagNo, length);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new Asn1Exception("corrupted stream detected", e);
|
||||
}
|
||||
}
|
||||
|
||||
// indefinite-length
|
||||
|
||||
if (0 == (tagHdr & Asn1Tags.Constructed))
|
||||
throw new IOException("indefinite-length primitive encoding encountered");
|
||||
|
||||
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(s, limit);
|
||||
Asn1StreamParser sp = new Asn1StreamParser(indIn, limit, tmpBuffers);
|
||||
|
||||
int tagClass = tagHdr & Asn1Tags.Private;
|
||||
if (0 != tagClass)
|
||||
return sp.LoadTaggedIL(tagClass, tagNo);
|
||||
|
||||
switch (tagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return BerBitStringParser.Parse(sp);
|
||||
case Asn1Tags.OctetString:
|
||||
return BerOctetStringParser.Parse(sp);
|
||||
case Asn1Tags.Sequence:
|
||||
return BerSequenceParser.Parse(sp);
|
||||
case Asn1Tags.Set:
|
||||
return BerSetParser.Parse(sp);
|
||||
case Asn1Tags.External:
|
||||
// TODO[asn1] BerExternalParser
|
||||
return DerExternalParser.Parse(sp);
|
||||
default:
|
||||
throw new IOException("unknown BER object encountered");
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual DerBitString BuildConstructedBitString(Asn1EncodableVector contentsElements)
|
||||
{
|
||||
DerBitString[] bitStrings = new DerBitString[contentsElements.Count];
|
||||
|
||||
for (int i = 0; i != bitStrings.Length; i++)
|
||||
{
|
||||
DerBitString bitString = contentsElements[i] as DerBitString;
|
||||
if (null == bitString)
|
||||
throw new Asn1Exception("unknown object encountered in constructed BIT STRING: "
|
||||
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(contentsElements[i]));
|
||||
|
||||
bitStrings[i] = bitString;
|
||||
}
|
||||
|
||||
return new DLBitString(BerBitString.FlattenBitStrings(bitStrings), false);
|
||||
}
|
||||
|
||||
internal virtual Asn1OctetString BuildConstructedOctetString(Asn1EncodableVector contentsElements)
|
||||
{
|
||||
Asn1OctetString[] octetStrings = new Asn1OctetString[contentsElements.Count];
|
||||
|
||||
for (int i = 0; i != octetStrings.Length; i++)
|
||||
{
|
||||
Asn1OctetString octetString = contentsElements[i] as Asn1OctetString;
|
||||
if (null == octetString)
|
||||
throw new Asn1Exception("unknown object encountered in constructed OCTET STRING: "
|
||||
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(contentsElements[i]));
|
||||
|
||||
octetStrings[i] = octetString;
|
||||
}
|
||||
|
||||
// Note: No DLOctetString available
|
||||
return new DerOctetString(BerOctetString.FlattenOctetStrings(octetStrings));
|
||||
}
|
||||
|
||||
internal virtual int Limit
|
||||
{
|
||||
get { return limit; }
|
||||
}
|
||||
|
||||
internal static int ReadTagNumber(Stream s, int tagHdr)
|
||||
{
|
||||
int tagNo = tagHdr & 0x1f;
|
||||
|
||||
//
|
||||
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
|
||||
//
|
||||
if (tagNo == 0x1f)
|
||||
{
|
||||
int b = s.ReadByte();
|
||||
if (b < 31)
|
||||
{
|
||||
if (b < 0)
|
||||
throw new EndOfStreamException("EOF found inside tag value.");
|
||||
|
||||
throw new IOException("corrupted stream - high tag number < 31 found");
|
||||
}
|
||||
|
||||
tagNo = b & 0x7f;
|
||||
|
||||
// X.690-0207 8.1.2.4.2
|
||||
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
|
||||
if (0 == tagNo)
|
||||
throw new IOException("corrupted stream - invalid high tag number found");
|
||||
|
||||
while ((b & 0x80) != 0)
|
||||
{
|
||||
if (((uint)tagNo >> 24) != 0U)
|
||||
throw new IOException("Tag number more than 31 bits");
|
||||
|
||||
tagNo <<= 7;
|
||||
|
||||
b = s.ReadByte();
|
||||
if (b < 0)
|
||||
throw new EndOfStreamException("EOF found inside tag value.");
|
||||
|
||||
tagNo |= b & 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
return tagNo;
|
||||
}
|
||||
|
||||
internal static int ReadLength(Stream s, int limit, bool isParsing)
|
||||
{
|
||||
int length = s.ReadByte();
|
||||
if (0U == ((uint)length >> 7))
|
||||
{
|
||||
// definite-length short form
|
||||
return length;
|
||||
}
|
||||
if (0x80 == length)
|
||||
{
|
||||
// indefinite-length
|
||||
return -1;
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
throw new EndOfStreamException("EOF found when length expected");
|
||||
}
|
||||
if (0xFF == length)
|
||||
{
|
||||
throw new IOException("invalid long form definite-length 0xFF");
|
||||
}
|
||||
|
||||
int octetsCount = length & 0x7F, octetsPos = 0;
|
||||
|
||||
length = 0;
|
||||
do
|
||||
{
|
||||
int octet = s.ReadByte();
|
||||
if (octet < 0)
|
||||
throw new EndOfStreamException("EOF found reading length");
|
||||
|
||||
if (((uint)length >> 23) != 0U)
|
||||
throw new IOException("long form definite-length more than 31 bits");
|
||||
|
||||
length = (length << 8) + octet;
|
||||
}
|
||||
while (++octetsPos < octetsCount);
|
||||
|
||||
if (length >= limit && !isParsing) // after all we must have read at least 1 byte
|
||||
throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
private static byte[] GetBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
|
||||
{
|
||||
int len = defIn.Remaining;
|
||||
if (len >= tmpBuffers.Length)
|
||||
{
|
||||
return defIn.ToArray();
|
||||
}
|
||||
|
||||
byte[] buf = tmpBuffers[len];
|
||||
if (buf == null)
|
||||
{
|
||||
buf = tmpBuffers[len] = new byte[len];
|
||||
}
|
||||
|
||||
defIn.ReadAllIntoByteArray(buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
private static char[] GetBmpCharBuffer(DefiniteLengthInputStream defIn)
|
||||
{
|
||||
int remainingBytes = defIn.Remaining;
|
||||
if (0 != (remainingBytes & 1))
|
||||
throw new IOException("malformed BMPString encoding encountered");
|
||||
|
||||
char[] str = new char[remainingBytes / 2];
|
||||
int stringPos = 0;
|
||||
|
||||
byte[] buf = new byte[8];
|
||||
while (remainingBytes >= 8)
|
||||
{
|
||||
if (Streams.ReadFully(defIn, buf, 0, 8) != 8)
|
||||
throw new EndOfStreamException("EOF encountered in middle of BMPString");
|
||||
|
||||
str[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
|
||||
str[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
|
||||
str[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
|
||||
str[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
|
||||
stringPos += 4;
|
||||
remainingBytes -= 8;
|
||||
}
|
||||
if (remainingBytes > 0)
|
||||
{
|
||||
if (Streams.ReadFully(defIn, buf, 0, remainingBytes) != remainingBytes)
|
||||
throw new EndOfStreamException("EOF encountered in middle of BMPString");
|
||||
|
||||
int bufPos = 0;
|
||||
do
|
||||
{
|
||||
int b1 = buf[bufPos++] << 8;
|
||||
int b2 = buf[bufPos++] & 0xFF;
|
||||
str[stringPos++] = (char)(b1 | b2);
|
||||
}
|
||||
while (bufPos < remainingBytes);
|
||||
}
|
||||
|
||||
if (0 != defIn.Remaining || str.Length != stringPos)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
internal static Asn1Object CreatePrimitiveDerObject(int tagNo, DefiniteLengthInputStream defIn,
|
||||
byte[][] tmpBuffers)
|
||||
{
|
||||
switch (tagNo)
|
||||
{
|
||||
case Asn1Tags.BmpString:
|
||||
return DerBmpString.CreatePrimitive(GetBmpCharBuffer(defIn));
|
||||
case Asn1Tags.Boolean:
|
||||
return DerBoolean.CreatePrimitive(GetBuffer(defIn, tmpBuffers));
|
||||
case Asn1Tags.Enumerated:
|
||||
// TODO Ideally only clone if we used a buffer
|
||||
return DerEnumerated.CreatePrimitive(GetBuffer(defIn, tmpBuffers), true);
|
||||
case Asn1Tags.ObjectIdentifier:
|
||||
// TODO Ideally only clone if we used a buffer
|
||||
return DerObjectIdentifier.CreatePrimitive(GetBuffer(defIn, tmpBuffers), true);
|
||||
}
|
||||
|
||||
byte[] bytes = defIn.ToArray();
|
||||
|
||||
switch (tagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return DerBitString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.GeneralizedTime:
|
||||
return Asn1GeneralizedTime.CreatePrimitive(bytes);
|
||||
case Asn1Tags.GeneralString:
|
||||
return DerGeneralString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.GraphicString:
|
||||
return DerGraphicString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.IA5String:
|
||||
return DerIA5String.CreatePrimitive(bytes);
|
||||
case Asn1Tags.Integer:
|
||||
return DerInteger.CreatePrimitive(bytes);
|
||||
case Asn1Tags.Null:
|
||||
return Asn1Null.CreatePrimitive(bytes);
|
||||
case Asn1Tags.NumericString:
|
||||
return DerNumericString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.ObjectDescriptor:
|
||||
return Asn1ObjectDescriptor.CreatePrimitive(bytes);
|
||||
case Asn1Tags.OctetString:
|
||||
return Asn1OctetString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.PrintableString:
|
||||
return DerPrintableString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.RelativeOid:
|
||||
return Asn1RelativeOid.CreatePrimitive(bytes, false);
|
||||
case Asn1Tags.T61String:
|
||||
return DerT61String.CreatePrimitive(bytes);
|
||||
case Asn1Tags.UniversalString:
|
||||
return DerUniversalString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.UtcTime:
|
||||
return Asn1UtcTime.CreatePrimitive(bytes);
|
||||
case Asn1Tags.Utf8String:
|
||||
return DerUtf8String.CreatePrimitive(bytes);
|
||||
case Asn1Tags.VideotexString:
|
||||
return DerVideotexString.CreatePrimitive(bytes);
|
||||
case Asn1Tags.VisibleString:
|
||||
return DerVisibleString.CreatePrimitive(bytes);
|
||||
default:
|
||||
throw new IOException("unknown tag " + tagNo + " encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e252ac704e464264d8409a56a0bb3eb3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/**
|
||||
* A Null object.
|
||||
*/
|
||||
public abstract class Asn1Null
|
||||
: Asn1Object
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1Null), Asn1Tags.Null) {}
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return CreatePrimitive(octetString.GetOctets());
|
||||
}
|
||||
}
|
||||
|
||||
public static Asn1Null GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1Null asn1Null)
|
||||
return asn1Null;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1Null converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1Null)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct NULL from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj));
|
||||
}
|
||||
|
||||
public static Asn1Null GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1Null)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
internal Asn1Null()
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
internal static Asn1Null CreatePrimitive(byte[] contents)
|
||||
{
|
||||
if (0 != contents.Length)
|
||||
throw new InvalidOperationException("malformed NULL encoding encountered");
|
||||
|
||||
return DerNull.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b6ffeb7c543040429c96c7fa0041261
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Object
|
||||
: Asn1Encodable
|
||||
{
|
||||
public override void EncodeTo(Stream output)
|
||||
{
|
||||
Asn1OutputStream asn1Out = Asn1OutputStream.Create(output);
|
||||
GetEncoding(asn1Out.Encoding).Encode(asn1Out);
|
||||
asn1Out.FlushInternal();
|
||||
}
|
||||
|
||||
public override void EncodeTo(Stream output, string encoding)
|
||||
{
|
||||
Asn1OutputStream asn1Out = Asn1OutputStream.Create(output, encoding);
|
||||
GetEncoding(asn1Out.Encoding).Encode(asn1Out);
|
||||
asn1Out.FlushInternal();
|
||||
}
|
||||
|
||||
public bool Equals(Asn1Object other)
|
||||
{
|
||||
return this == other || Asn1Equals(other);
|
||||
}
|
||||
|
||||
/// <summary>Create a base ASN.1 object from a byte array.</summary>
|
||||
/// <param name="data">The byte array to parse.</param>
|
||||
/// <returns>The base ASN.1 object represented by the byte array.</returns>
|
||||
/// <exception cref="IOException">
|
||||
/// If there is a problem parsing the data, or parsing an object did not exhaust the available data.
|
||||
/// </exception>
|
||||
public static Asn1Object FromByteArray(
|
||||
byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
MemoryStream input = new MemoryStream(data, false);
|
||||
Asn1InputStream asn1 = new Asn1InputStream(input, data.Length);
|
||||
Asn1Object result = asn1.ReadObject();
|
||||
if (input.Position != input.Length)
|
||||
throw new IOException("extra data found after object");
|
||||
return result;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new IOException("cannot recognise object in byte array");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Read a base ASN.1 object from a stream.</summary>
|
||||
/// <param name="inStr">The stream to parse.</param>
|
||||
/// <returns>The base ASN.1 object represented by the byte array.</returns>
|
||||
/// <exception cref="IOException">If there is a problem parsing the data.</exception>
|
||||
public static Asn1Object FromStream(
|
||||
Stream inStr)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Asn1InputStream(inStr).ReadObject();
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new IOException("cannot recognise object in stream");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override Asn1Object ToAsn1Object()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
internal abstract IAsn1Encoding GetEncoding(int encoding);
|
||||
|
||||
internal abstract IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo);
|
||||
|
||||
protected abstract bool Asn1Equals(Asn1Object asn1Object);
|
||||
protected abstract int Asn1GetHashCode();
|
||||
|
||||
internal bool CallAsn1Equals(Asn1Object obj)
|
||||
{
|
||||
return Asn1Equals(obj);
|
||||
}
|
||||
|
||||
internal int CallAsn1GetHashCode()
|
||||
{
|
||||
return Asn1GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86b4801bceb05f54ab0490784feb75c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,125 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public sealed class Asn1ObjectDescriptor
|
||||
: Asn1Object
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1ObjectDescriptor), Asn1Tags.ObjectDescriptor) {}
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return new Asn1ObjectDescriptor(
|
||||
(DerGraphicString)DerGraphicString.Meta.Instance.FromImplicitPrimitive(octetString));
|
||||
}
|
||||
|
||||
internal override Asn1Object FromImplicitConstructed(Asn1Sequence sequence)
|
||||
{
|
||||
return new Asn1ObjectDescriptor(
|
||||
(DerGraphicString)DerGraphicString.Meta.Instance.FromImplicitConstructed(sequence));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ObjectDescriptor from the passed in object.
|
||||
*
|
||||
* @param obj an ASN1ObjectDescriptor or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1ObjectDescriptor instance, or null.
|
||||
*/
|
||||
public static Asn1ObjectDescriptor GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1ObjectDescriptor asn1ObjectDescriptor)
|
||||
return asn1ObjectDescriptor;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1ObjectDescriptor converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1ObjectDescriptor)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct object descriptor from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ObjectDescriptor from a tagged object.
|
||||
*
|
||||
* @param taggedObject the tagged object holding the object we want.
|
||||
* @param declaredExplicit true if the object is meant to be explicitly tagged, false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot be converted.
|
||||
* @return an ASN1ObjectDescriptor instance, or null.
|
||||
*/
|
||||
public static Asn1ObjectDescriptor GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1ObjectDescriptor)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
private readonly DerGraphicString m_baseGraphicString;
|
||||
|
||||
public Asn1ObjectDescriptor(DerGraphicString baseGraphicString)
|
||||
{
|
||||
if (null == baseGraphicString)
|
||||
throw new ArgumentNullException("baseGraphicString");
|
||||
|
||||
this.m_baseGraphicString = baseGraphicString;
|
||||
}
|
||||
|
||||
public DerGraphicString BaseGraphicString
|
||||
{
|
||||
get { return m_baseGraphicString; }
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
return m_baseGraphicString.GetEncodingImplicit(encoding, Asn1Tags.Universal, Asn1Tags.ObjectDescriptor);
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
return m_baseGraphicString.GetEncodingImplicit(encoding, tagClass, tagNo);
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
return ~m_baseGraphicString.CallAsn1GetHashCode();
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1ObjectDescriptor that = asn1Object as Asn1ObjectDescriptor;
|
||||
return null != that
|
||||
&& this.m_baseGraphicString.Equals(that.m_baseGraphicString);
|
||||
}
|
||||
|
||||
internal static Asn1ObjectDescriptor CreatePrimitive(byte[] contents)
|
||||
{
|
||||
return new Asn1ObjectDescriptor(DerGraphicString.CreatePrimitive(contents));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef670ce0aae993744a256d3bb7362b31
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,136 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1OctetString
|
||||
: Asn1Object, Asn1OctetStringParser
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1OctetString), Asn1Tags.OctetString) {}
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return octetString;
|
||||
}
|
||||
|
||||
internal override Asn1Object FromImplicitConstructed(Asn1Sequence sequence)
|
||||
{
|
||||
return sequence.ToAsn1OctetString();
|
||||
}
|
||||
}
|
||||
|
||||
internal static readonly byte[] EmptyOctets = new byte[0];
|
||||
|
||||
/**
|
||||
* return an Octet string from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception ArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static Asn1OctetString GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1OctetString asn1OctetString)
|
||||
return asn1OctetString;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1OctetString converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1OctetString)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct OCTET STRING from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
/**
|
||||
* return an octet string from a tagged object.
|
||||
*
|
||||
* @param taggedObject the tagged object holding the object we want.
|
||||
* @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise.
|
||||
* @exception ArgumentException if the tagged object cannot be converted.
|
||||
*/
|
||||
public static Asn1OctetString GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1OctetString)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
internal readonly byte[] contents;
|
||||
|
||||
/**
|
||||
* @param string the octets making up the octet string.
|
||||
*/
|
||||
internal Asn1OctetString(byte[] contents)
|
||||
{
|
||||
if (null == contents)
|
||||
throw new ArgumentNullException("contents");
|
||||
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
public Stream GetOctetStream()
|
||||
{
|
||||
return new MemoryStream(contents, false);
|
||||
}
|
||||
|
||||
public Asn1OctetStringParser Parser
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
public virtual byte[] GetOctets()
|
||||
{
|
||||
return contents;
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
return Arrays.GetHashCode(GetOctets());
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(
|
||||
Asn1Object asn1Object)
|
||||
{
|
||||
DerOctetString other = asn1Object as DerOctetString;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return Arrays.AreEqual(GetOctets(), other.GetOctets());
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "#" + Hex.ToHexString(contents);
|
||||
}
|
||||
|
||||
internal static Asn1OctetString CreatePrimitive(byte[] contents)
|
||||
{
|
||||
return new DerOctetString(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 605a6b277ffde7640a895840c2243816
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,192 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
using System.Buffers.Binary;
|
||||
using System.Numerics;
|
||||
#endif
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class Asn1OutputStream
|
||||
: FilterStream
|
||||
{
|
||||
internal const int EncodingBer = 1;
|
||||
internal const int EncodingDer = 2;
|
||||
|
||||
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 DerOutputStream(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Asn1OutputStream(output);
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1OutputStream(Stream os)
|
||||
: base(os)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void WriteObject(Asn1Encodable asn1Encodable)
|
||||
{
|
||||
if (null == asn1Encodable)
|
||||
throw new ArgumentNullException("asn1Encodable");
|
||||
|
||||
asn1Encodable.ToAsn1Object().GetEncoding(this.Encoding).Encode(this);
|
||||
FlushInternal();
|
||||
}
|
||||
|
||||
public virtual void WriteObject(Asn1Object asn1Object)
|
||||
{
|
||||
if (null == asn1Object)
|
||||
throw new ArgumentNullException("asn1Object");
|
||||
|
||||
asn1Object.GetEncoding(this.Encoding).Encode(this);
|
||||
FlushInternal();
|
||||
}
|
||||
|
||||
internal void EncodeContents(IAsn1Encoding[] contentsEncodings)
|
||||
{
|
||||
for (int i = 0, count = contentsEncodings.Length; i < count; ++i)
|
||||
{
|
||||
contentsEncodings[i].Encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual int Encoding
|
||||
{
|
||||
get { return EncodingBer; }
|
||||
}
|
||||
|
||||
internal void FlushInternal()
|
||||
{
|
||||
// Placeholder to support future internal buffering
|
||||
}
|
||||
|
||||
internal void WriteDL(int dl)
|
||||
{
|
||||
if (dl < 128)
|
||||
{
|
||||
Debug.Assert(dl >= 0);
|
||||
WriteByte((byte)dl);
|
||||
return;
|
||||
}
|
||||
|
||||
#if false && (NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_)
|
||||
Span<byte> encoding = stackalloc byte[5];
|
||||
BinaryPrimitives.WriteUInt32BigEndian(encoding[1..], (uint)dl);
|
||||
int leadingZeroBytes = BitOperations.LeadingZeroCount((uint)dl) / 8;
|
||||
encoding[leadingZeroBytes] = (byte)(0x84 - leadingZeroBytes);
|
||||
Write(encoding[leadingZeroBytes..]);
|
||||
#else
|
||||
byte[] stack = new byte[5];
|
||||
int pos = stack.Length;
|
||||
|
||||
do
|
||||
{
|
||||
stack[--pos] = (byte)dl;
|
||||
dl >>= 8;
|
||||
}
|
||||
while (dl > 0);
|
||||
|
||||
int count = stack.Length - pos;
|
||||
stack[--pos] = (byte)(0x80 | count);
|
||||
|
||||
Write(stack, pos, count + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void WriteIdentifier(int tagClass, int tagNo)
|
||||
{
|
||||
if (tagNo < 31)
|
||||
{
|
||||
WriteByte((byte)(tagClass | tagNo));
|
||||
return;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Span<byte> stack = stackalloc byte[6];
|
||||
#else
|
||||
byte[] stack = new byte[6];
|
||||
#endif
|
||||
int pos = stack.Length;
|
||||
|
||||
stack[--pos] = (byte)(tagNo & 0x7F);
|
||||
while (tagNo > 127)
|
||||
{
|
||||
tagNo >>= 7;
|
||||
stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
|
||||
}
|
||||
|
||||
stack[--pos] = (byte)(tagClass | 0x1F);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Write(stack[pos..]);
|
||||
#else
|
||||
Write(stack, pos, stack.Length - pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static IAsn1Encoding[] GetContentsEncodings(int encoding, Asn1Encodable[] elements)
|
||||
{
|
||||
int count = elements.Length;
|
||||
IAsn1Encoding[] contentsEncodings = new IAsn1Encoding[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
contentsEncodings[i] = elements[i].ToAsn1Object().GetEncoding(encoding);
|
||||
}
|
||||
return contentsEncodings;
|
||||
}
|
||||
|
||||
internal static int GetLengthOfContents(IAsn1Encoding[] contentsEncodings)
|
||||
{
|
||||
int contentsLength = 0;
|
||||
for (int i = 0, count = contentsEncodings.Length; i < count; ++i)
|
||||
{
|
||||
contentsLength += contentsEncodings[i].GetLength();
|
||||
}
|
||||
return contentsLength;
|
||||
}
|
||||
|
||||
internal static int GetLengthOfDL(int dl)
|
||||
{
|
||||
if (dl < 128)
|
||||
return 1;
|
||||
|
||||
int length = 2;
|
||||
while ((dl >>= 8) > 0)
|
||||
{
|
||||
++length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
internal static int GetLengthOfIdentifier(int tagNo)
|
||||
{
|
||||
if (tagNo < 31)
|
||||
return 1;
|
||||
|
||||
int length = 2;
|
||||
while ((tagNo >>= 7) > 0)
|
||||
{
|
||||
++length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca2e340a1bd44254cac396effbb16cda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ParsingException
|
||||
: InvalidOperationException
|
||||
{
|
||||
public Asn1ParsingException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1ParsingException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1ParsingException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected Asn1ParsingException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e565a5f2f13a702468596b17c248ac68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,320 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class Asn1RelativeOid
|
||||
: Asn1Object
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1RelativeOid), Asn1Tags.RelativeOid) {}
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return CreatePrimitive(octetString.GetOctets(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public static Asn1RelativeOid FromContents(byte[] contents)
|
||||
{
|
||||
return CreatePrimitive(contents, true);
|
||||
}
|
||||
|
||||
public static Asn1RelativeOid GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1RelativeOid asn1RelativeOid)
|
||||
return asn1RelativeOid;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1RelativeOid converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1RelativeOid)FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct relative OID from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
public static Asn1RelativeOid GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1RelativeOid)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
private const long LongLimit = (long.MaxValue >> 7) - 0x7F;
|
||||
|
||||
private readonly string identifier;
|
||||
private byte[] contents;
|
||||
|
||||
public Asn1RelativeOid(string identifier)
|
||||
{
|
||||
if (identifier == null)
|
||||
throw new ArgumentNullException("identifier");
|
||||
if (!IsValidIdentifier(identifier, 0))
|
||||
throw new FormatException("string " + identifier + " not a relative OID");
|
||||
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
private Asn1RelativeOid(Asn1RelativeOid oid, string branchID)
|
||||
{
|
||||
if (!IsValidIdentifier(branchID, 0))
|
||||
throw new FormatException("string " + branchID + " not a valid relative OID branch");
|
||||
|
||||
this.identifier = oid.Id + "." + branchID;
|
||||
}
|
||||
|
||||
private Asn1RelativeOid(byte[] contents, bool clone)
|
||||
{
|
||||
this.identifier = ParseContents(contents);
|
||||
this.contents = clone ? Arrays.Clone(contents) : contents;
|
||||
}
|
||||
|
||||
public virtual Asn1RelativeOid Branch(string branchID)
|
||||
{
|
||||
return new Asn1RelativeOid(this, branchID);
|
||||
}
|
||||
|
||||
public string Id
|
||||
{
|
||||
get { return identifier; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1RelativeOid that = asn1Object as Asn1RelativeOid;
|
||||
return null != that
|
||||
&& this.identifier == that.identifier;
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
return identifier.GetHashCode();
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.RelativeOid, GetContents());
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
return new PrimitiveEncoding(tagClass, tagNo, GetContents());
|
||||
}
|
||||
|
||||
private void DoOutput(MemoryStream bOut)
|
||||
{
|
||||
OidTokenizer tok = new OidTokenizer(identifier);
|
||||
while (tok.HasMoreTokens)
|
||||
{
|
||||
string token = tok.NextToken();
|
||||
if (token.Length <= 18)
|
||||
{
|
||||
WriteField(bOut, long.Parse(token));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteField(bOut, new BigInteger(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GetContents()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (contents == null)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
DoOutput(bOut);
|
||||
contents = bOut.ToArray();
|
||||
}
|
||||
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Asn1RelativeOid CreatePrimitive(byte[] contents, bool clone)
|
||||
{
|
||||
return new Asn1RelativeOid(contents, clone);
|
||||
}
|
||||
|
||||
internal static bool IsValidIdentifier(string identifier, int from)
|
||||
{
|
||||
int digitCount = 0;
|
||||
|
||||
int pos = identifier.Length;
|
||||
while (--pos >= from)
|
||||
{
|
||||
char ch = identifier[pos];
|
||||
|
||||
if (ch == '.')
|
||||
{
|
||||
if (0 == digitCount || (digitCount > 1 && identifier[pos + 1] == '0'))
|
||||
return false;
|
||||
|
||||
digitCount = 0;
|
||||
}
|
||||
else if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
++digitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == digitCount || (digitCount > 1 && identifier[pos + 1] == '0'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void WriteField(Stream outputStream, long fieldValue)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Span<byte> result = stackalloc byte[9];
|
||||
#else
|
||||
byte[] result = new byte[9];
|
||||
#endif
|
||||
int pos = 8;
|
||||
result[pos] = (byte)((int)fieldValue & 0x7F);
|
||||
while (fieldValue >= (1L << 7))
|
||||
{
|
||||
fieldValue >>= 7;
|
||||
result[--pos] = (byte)((int)fieldValue | 0x80);
|
||||
}
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
outputStream.Write(result[pos..]);
|
||||
#else
|
||||
outputStream.Write(result, pos, 9 - pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void WriteField(Stream outputStream, BigInteger fieldValue)
|
||||
{
|
||||
int byteCount = (fieldValue.BitLength + 6) / 7;
|
||||
if (byteCount == 0)
|
||||
{
|
||||
outputStream.WriteByte(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BigInteger tmpValue = fieldValue;
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Span<byte> tmp = byteCount <= 16
|
||||
? stackalloc byte[byteCount]
|
||||
: new byte[byteCount];
|
||||
#else
|
||||
byte[] tmp = new byte[byteCount];
|
||||
#endif
|
||||
for (int i = byteCount - 1; i >= 0; i--)
|
||||
{
|
||||
tmp[i] = (byte)(tmpValue.IntValue | 0x80);
|
||||
tmpValue = tmpValue.ShiftRight(7);
|
||||
}
|
||||
tmp[byteCount - 1] &= 0x7F;
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
outputStream.Write(tmp);
|
||||
#else
|
||||
outputStream.Write(tmp, 0, tmp.Length);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static string ParseContents(byte[] contents)
|
||||
{
|
||||
StringBuilder objId = new StringBuilder();
|
||||
long value = 0;
|
||||
BigInteger bigValue = null;
|
||||
bool first = true;
|
||||
|
||||
for (int i = 0; i != contents.Length; i++)
|
||||
{
|
||||
int b = contents[i];
|
||||
|
||||
if (value <= LongLimit)
|
||||
{
|
||||
value += b & 0x7F;
|
||||
if ((b & 0x80) == 0)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
objId.Append('.');
|
||||
}
|
||||
|
||||
objId.Append(value);
|
||||
value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value <<= 7;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bigValue == null)
|
||||
{
|
||||
bigValue = BigInteger.ValueOf(value);
|
||||
}
|
||||
bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7F));
|
||||
if ((b & 0x80) == 0)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
objId.Append('.');
|
||||
}
|
||||
|
||||
objId.Append(bigValue);
|
||||
bigValue = null;
|
||||
value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigValue = bigValue.ShiftLeft(7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objId.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae6c5229271568c4f968518558270b85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,284 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Sequence
|
||||
: Asn1Object, IEnumerable<Asn1Encodable>
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1Sequence), Asn1Tags.Sequence) {}
|
||||
|
||||
internal override Asn1Object FromImplicitConstructed(Asn1Sequence sequence)
|
||||
{
|
||||
return sequence;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Asn1Sequence from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception ArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static Asn1Sequence GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1Sequence asn1Sequence)
|
||||
return asn1Sequence;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1Sequence converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1Sequence)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ASN1 sequence from a tagged object. There is a special
|
||||
* case here, if an object appears to have been explicitly tagged on
|
||||
* reading but we were expecting it to be implicitly tagged in the
|
||||
* normal course of events it indicates that we lost the surrounding
|
||||
* sequence - so we need to add it back (this will happen if the tagged
|
||||
* object is a sequence that contains other sequences). If you are
|
||||
* dealing with implicitly tagged sequences you really <b>should</b>
|
||||
* be using this method.
|
||||
*
|
||||
* @param taggedObject the tagged object.
|
||||
* @param declaredExplicit true if the object is meant to be explicitly tagged, false otherwise.
|
||||
* @exception ArgumentException if the tagged object cannot be converted.
|
||||
*/
|
||||
public static Asn1Sequence GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1Sequence)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
// NOTE: Only non-readonly to support LazyDLSequence
|
||||
internal Asn1Encodable[] elements;
|
||||
|
||||
protected internal Asn1Sequence()
|
||||
{
|
||||
this.elements = Asn1EncodableVector.EmptyElements;
|
||||
}
|
||||
|
||||
protected internal Asn1Sequence(Asn1Encodable element)
|
||||
{
|
||||
if (null == element)
|
||||
throw new ArgumentNullException(nameof(element));
|
||||
|
||||
this.elements = new Asn1Encodable[]{ element };
|
||||
}
|
||||
|
||||
protected internal Asn1Sequence(Asn1Encodable element1, Asn1Encodable element2)
|
||||
{
|
||||
if (null == element1)
|
||||
throw new ArgumentNullException(nameof(element1));
|
||||
if (null == element2)
|
||||
throw new ArgumentNullException(nameof(element2));
|
||||
|
||||
this.elements = new Asn1Encodable[]{ element1, element2 };
|
||||
}
|
||||
|
||||
protected internal Asn1Sequence(params Asn1Encodable[] elements)
|
||||
{
|
||||
if (Arrays.IsNullOrContainsNull(elements))
|
||||
throw new NullReferenceException("'elements' cannot be null, or contain null");
|
||||
|
||||
this.elements = Asn1EncodableVector.CloneElements(elements);
|
||||
}
|
||||
|
||||
internal Asn1Sequence(Asn1Encodable[] elements, bool clone)
|
||||
{
|
||||
this.elements = clone ? Asn1EncodableVector.CloneElements(elements) : elements;
|
||||
}
|
||||
|
||||
protected internal Asn1Sequence(Asn1EncodableVector elementVector)
|
||||
{
|
||||
if (null == elementVector)
|
||||
throw new ArgumentNullException("elementVector");
|
||||
|
||||
this.elements = elementVector.TakeElements();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public virtual IEnumerator<Asn1Encodable> GetEnumerator()
|
||||
{
|
||||
IEnumerable<Asn1Encodable> e = elements;
|
||||
return e.GetEnumerator();
|
||||
}
|
||||
|
||||
private class Asn1SequenceParserImpl
|
||||
: Asn1SequenceParser
|
||||
{
|
||||
private readonly Asn1Sequence outer;
|
||||
private readonly int max;
|
||||
private int index;
|
||||
|
||||
public Asn1SequenceParserImpl(
|
||||
Asn1Sequence outer)
|
||||
{
|
||||
this.outer = outer;
|
||||
// NOTE: Call Count here to 'force' a LazyDerSequence
|
||||
this.max = outer.Count;
|
||||
}
|
||||
|
||||
public IAsn1Convertible ReadObject()
|
||||
{
|
||||
if (index == max)
|
||||
return null;
|
||||
|
||||
Asn1Encodable obj = outer[index++];
|
||||
|
||||
if (obj is Asn1Sequence)
|
||||
return ((Asn1Sequence)obj).Parser;
|
||||
|
||||
if (obj is Asn1Set)
|
||||
return ((Asn1Set)obj).Parser;
|
||||
|
||||
// NB: Asn1OctetString implements Asn1OctetStringParser directly
|
||||
// if (obj is Asn1OctetString)
|
||||
// return ((Asn1OctetString)obj).Parser;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Asn1Object ToAsn1Object()
|
||||
{
|
||||
return outer;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Asn1SequenceParser Parser
|
||||
{
|
||||
get { return new Asn1SequenceParserImpl(this); }
|
||||
}
|
||||
|
||||
/**
|
||||
* return the object at the sequence position indicated by index.
|
||||
*
|
||||
* @param index the sequence number (starting at zero) of the object
|
||||
* @return the object at the sequence position indicated by index.
|
||||
*/
|
||||
public virtual Asn1Encodable this[int index]
|
||||
{
|
||||
get { return elements[index]; }
|
||||
}
|
||||
|
||||
public virtual int Count
|
||||
{
|
||||
get { return elements.Length; }
|
||||
}
|
||||
|
||||
public virtual T[] MapElements<T>(Func<Asn1Encodable, T> func)
|
||||
{
|
||||
// NOTE: Call Count here to 'force' a LazyDerSequence
|
||||
int count = Count;
|
||||
T[] result = new T[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
result[i] = func(elements[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual Asn1Encodable[] ToArray()
|
||||
{
|
||||
return Asn1EncodableVector.CloneElements(elements);
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
// NOTE: Call Count here to 'force' a LazyDerSequence
|
||||
int i = Count;
|
||||
int hc = i + 1;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
hc *= 257;
|
||||
hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode();
|
||||
}
|
||||
|
||||
return hc;
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1Sequence that = asn1Object as Asn1Sequence;
|
||||
if (null == that)
|
||||
return false;
|
||||
|
||||
// NOTE: Call Count here (on both) to 'force' a LazyDerSequence
|
||||
int count = this.Count;
|
||||
if (that.Count != count)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
Asn1Object o1 = this.elements[i].ToAsn1Object();
|
||||
Asn1Object o2 = that.elements[i].ToAsn1Object();
|
||||
|
||||
if (!o1.Equals(o2))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return CollectionUtilities.ToString(elements);
|
||||
}
|
||||
|
||||
// TODO[asn1] Preferably return an Asn1BitString[] (doesn't exist yet)
|
||||
internal DerBitString[] GetConstructedBitStrings()
|
||||
{
|
||||
return MapElements(DerBitString.GetInstance);
|
||||
}
|
||||
|
||||
internal Asn1OctetString[] GetConstructedOctetStrings()
|
||||
{
|
||||
return MapElements(Asn1OctetString.GetInstance);
|
||||
}
|
||||
|
||||
// TODO[asn1] Preferably return an Asn1BitString (doesn't exist yet)
|
||||
internal abstract DerBitString ToAsn1BitString();
|
||||
|
||||
// TODO[asn1] Preferably return an Asn1External (doesn't exist yet)
|
||||
internal abstract DerExternal ToAsn1External();
|
||||
|
||||
internal abstract Asn1OctetString ToAsn1OctetString();
|
||||
|
||||
internal abstract Asn1Set ToAsn1Set();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 251efabb5e3250d49ad3fb7b45d68d01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,331 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Set
|
||||
: Asn1Object, IEnumerable<Asn1Encodable>
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1Set), Asn1Tags.Set) {}
|
||||
|
||||
internal override Asn1Object FromImplicitConstructed(Asn1Sequence sequence)
|
||||
{
|
||||
return sequence.ToAsn1Set();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return an ASN1Set from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception ArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static Asn1Set GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1Set asn1Set)
|
||||
return asn1Set;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1Set converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1Set)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct set from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ASN1 set from a tagged object. There is a special
|
||||
* case here, if an object appears to have been explicitly tagged on
|
||||
* reading but we were expecting it to be implicitly tagged in the
|
||||
* normal course of events it indicates that we lost the surrounding
|
||||
* set - so we need to add it back (this will happen if the tagged
|
||||
* object is a sequence that contains other sequences). If you are
|
||||
* dealing with implicitly tagged sets you really <b>should</b>
|
||||
* be using this method.
|
||||
*
|
||||
* @param taggedObject the tagged object.
|
||||
* @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise.
|
||||
* @exception ArgumentException if the tagged object cannot be converted.
|
||||
*/
|
||||
public static Asn1Set GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1Set)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
// NOTE: Only non-readonly to support LazyDLSet
|
||||
internal Asn1Encodable[] elements;
|
||||
internal bool isSorted;
|
||||
|
||||
protected internal Asn1Set()
|
||||
{
|
||||
this.elements = Asn1EncodableVector.EmptyElements;
|
||||
this.isSorted = true;
|
||||
}
|
||||
|
||||
protected internal Asn1Set(Asn1Encodable element)
|
||||
{
|
||||
if (null == element)
|
||||
throw new ArgumentNullException("element");
|
||||
|
||||
this.elements = new Asn1Encodable[]{ element };
|
||||
this.isSorted = true;
|
||||
}
|
||||
|
||||
protected internal Asn1Set(Asn1Encodable[] elements, bool doSort)
|
||||
{
|
||||
if (Arrays.IsNullOrContainsNull(elements))
|
||||
throw new NullReferenceException("'elements' cannot be null, or contain null");
|
||||
|
||||
Asn1Encodable[] tmp = Asn1EncodableVector.CloneElements(elements);
|
||||
if (doSort && tmp.Length >= 2)
|
||||
{
|
||||
tmp = Sort(tmp);
|
||||
}
|
||||
|
||||
this.elements = tmp;
|
||||
this.isSorted = doSort || tmp.Length < 2;
|
||||
}
|
||||
|
||||
protected internal Asn1Set(Asn1EncodableVector elementVector, bool doSort)
|
||||
{
|
||||
if (null == elementVector)
|
||||
throw new ArgumentNullException("elementVector");
|
||||
|
||||
Asn1Encodable[] tmp;
|
||||
if (doSort && elementVector.Count >= 2)
|
||||
{
|
||||
tmp = Sort(elementVector.CopyElements());
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = elementVector.TakeElements();
|
||||
}
|
||||
|
||||
this.elements = tmp;
|
||||
this.isSorted = doSort || tmp.Length < 2;
|
||||
}
|
||||
|
||||
protected internal Asn1Set(bool isSorted, Asn1Encodable[] elements)
|
||||
{
|
||||
this.elements = elements;
|
||||
this.isSorted = isSorted || elements.Length < 2;
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public virtual IEnumerator<Asn1Encodable> GetEnumerator()
|
||||
{
|
||||
IEnumerable<Asn1Encodable> e = elements;
|
||||
return e.GetEnumerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* return the object at the set position indicated by index.
|
||||
*
|
||||
* @param index the set number (starting at zero) of the object
|
||||
* @return the object at the set position indicated by index.
|
||||
*/
|
||||
public virtual Asn1Encodable this[int index]
|
||||
{
|
||||
get { return elements[index]; }
|
||||
}
|
||||
|
||||
public virtual int Count
|
||||
{
|
||||
get { return elements.Length; }
|
||||
}
|
||||
|
||||
public virtual T[] MapElements<T>(Func<Asn1Encodable, T> func)
|
||||
{
|
||||
// NOTE: Call Count here to 'force' a LazyDerSet
|
||||
int count = Count;
|
||||
T[] result = new T[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
result[i] = func(elements[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual Asn1Encodable[] ToArray()
|
||||
{
|
||||
return Asn1EncodableVector.CloneElements(elements);
|
||||
}
|
||||
|
||||
private class Asn1SetParserImpl
|
||||
: Asn1SetParser
|
||||
{
|
||||
private readonly Asn1Set outer;
|
||||
private readonly int max;
|
||||
private int index;
|
||||
|
||||
public Asn1SetParserImpl(
|
||||
Asn1Set outer)
|
||||
{
|
||||
this.outer = outer;
|
||||
// NOTE: Call Count here to 'force' a LazyDerSet
|
||||
this.max = outer.Count;
|
||||
}
|
||||
|
||||
public IAsn1Convertible ReadObject()
|
||||
{
|
||||
if (index == max)
|
||||
return null;
|
||||
|
||||
Asn1Encodable obj = outer[index++];
|
||||
if (obj is Asn1Sequence)
|
||||
return ((Asn1Sequence)obj).Parser;
|
||||
|
||||
if (obj is Asn1Set)
|
||||
return ((Asn1Set)obj).Parser;
|
||||
|
||||
// NB: Asn1OctetString implements Asn1OctetStringParser directly
|
||||
// if (obj is Asn1OctetString)
|
||||
// return ((Asn1OctetString)obj).Parser;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public virtual Asn1Object ToAsn1Object()
|
||||
{
|
||||
return outer;
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1SetParser Parser
|
||||
{
|
||||
get { return new Asn1SetParserImpl(this); }
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
// NOTE: Call Count here to 'force' a LazyDerSet
|
||||
int i = Count;
|
||||
int hc = i + 1;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
hc *= 257;
|
||||
hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode();
|
||||
}
|
||||
|
||||
return hc;
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1Set that = asn1Object as Asn1Set;
|
||||
if (null == that)
|
||||
return false;
|
||||
|
||||
// NOTE: Call Count here (on both) to 'force' a LazyDerSet
|
||||
int count = this.Count;
|
||||
if (that.Count != count)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
Asn1Object o1 = this.elements[i].ToAsn1Object();
|
||||
Asn1Object o2 = that.elements[i].ToAsn1Object();
|
||||
|
||||
if (!o1.Equals(o2))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return CollectionUtilities.ToString(elements);
|
||||
}
|
||||
|
||||
internal static Asn1Encodable[] Sort(Asn1Encodable[] elements)
|
||||
{
|
||||
int count = elements.Length;
|
||||
if (count < 2)
|
||||
return elements;
|
||||
|
||||
byte[][] keys = new byte[count][];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
keys[i] = elements[i].GetEncoded(Der);
|
||||
}
|
||||
Array.Sort(keys, elements, new DerComparer());
|
||||
return elements;
|
||||
}
|
||||
|
||||
private class DerComparer
|
||||
: IComparer<byte[]>
|
||||
{
|
||||
public int Compare(byte[] a, byte[] b)
|
||||
{
|
||||
Debug.Assert(a.Length >= 2 && b.Length >= 2);
|
||||
|
||||
/*
|
||||
* NOTE: Set elements in DER encodings are ordered first according to their tags (class and
|
||||
* number); the CONSTRUCTED bit is not part of the tag.
|
||||
*
|
||||
* For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
|
||||
* either all be in constructed form or all in primitive form, according to that tag. The
|
||||
* elements are effectively ordered according to their content octets.
|
||||
*
|
||||
* For SET, the elements will have distinct tags, and each will be in constructed or
|
||||
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
|
||||
* ordering inversions.
|
||||
*/
|
||||
int a0 = a[0] & ~Asn1Tags.Constructed;
|
||||
int b0 = b[0] & ~Asn1Tags.Constructed;
|
||||
if (a0 != b0)
|
||||
return a0 < b0 ? -1 : 1;
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
int compareLength = System.Math.Min(a.Length, b.Length) - 1;
|
||||
return a.AsSpan(1, compareLength).SequenceCompareTo(b.AsSpan(1, compareLength));
|
||||
#else
|
||||
int len = System.Math.Min(a.Length, b.Length);
|
||||
for (int i = 1; i < len; ++i)
|
||||
{
|
||||
byte ai = a[i], bi = b[i];
|
||||
if (ai != bi)
|
||||
return ai < bi ? -1 : 1;
|
||||
}
|
||||
Debug.Assert(a.Length == b.Length);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db687a85bbc7c7240b1b2f57359d0c46
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal sealed class Asn1Tag
|
||||
{
|
||||
internal static Asn1Tag Create(int tagClass, int tagNo)
|
||||
{
|
||||
return new Asn1Tag(tagClass, tagNo);
|
||||
}
|
||||
|
||||
private readonly int m_tagClass;
|
||||
private readonly int m_tagNo;
|
||||
|
||||
private Asn1Tag(int tagClass, int tagNo)
|
||||
{
|
||||
m_tagClass = tagClass;
|
||||
m_tagNo = tagNo;
|
||||
}
|
||||
|
||||
internal int TagClass
|
||||
{
|
||||
get { return m_tagClass; }
|
||||
}
|
||||
|
||||
internal int TagNo
|
||||
{
|
||||
get { return m_tagNo; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86fc5dd31416c1b4797892dbb3a76111
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,409 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/**
|
||||
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
|
||||
* a [n] where n is some number - these are assumed to follow the construction
|
||||
* rules (as with sequences).
|
||||
*/
|
||||
public abstract class Asn1TaggedObject
|
||||
: Asn1Object, Asn1TaggedObjectParser
|
||||
{
|
||||
private const int DeclaredExplicit = 1;
|
||||
private const int DeclaredImplicit = 2;
|
||||
// TODO It will probably be better to track parsing constructed vs primitive instead
|
||||
private const int ParsedExplicit = 3;
|
||||
private const int ParsedImplicit = 4;
|
||||
|
||||
public static Asn1TaggedObject GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1TaggedObject asn1TaggedObject)
|
||||
return asn1TaggedObject;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1TaggedObject converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CheckedCast(FromByteArray(bytes));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct tagged object from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject GetInstance(object obj, int tagClass)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
Asn1TaggedObject taggedObject = GetInstance(obj);
|
||||
if (tagClass != taggedObject.TagClass)
|
||||
throw new ArgumentException("unexpected tag in GetInstance: " + Asn1Utilities.GetTagText(taggedObject));
|
||||
|
||||
return taggedObject;
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject GetInstance(object obj, int tagClass, int tagNo)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
Asn1TaggedObject taggedObject = GetInstance(obj);
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
throw new ArgumentException("unexpected tag in GetInstance: " + Asn1Utilities.GetTagText(taggedObject));
|
||||
|
||||
return taggedObject;
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
if (Asn1Tags.ContextSpecific != taggedObject.TagClass)
|
||||
throw new InvalidOperationException("this method only valid for CONTEXT_SPECIFIC tags");
|
||||
|
||||
if (declaredExplicit)
|
||||
return taggedObject.GetExplicitBaseTagged();
|
||||
|
||||
throw new ArgumentException("this method not valid for implicitly tagged tagged objects");
|
||||
}
|
||||
|
||||
internal readonly int explicitness;
|
||||
internal readonly int tagClass;
|
||||
internal readonly int tagNo;
|
||||
internal readonly Asn1Encodable obj;
|
||||
|
||||
/**
|
||||
* @param explicitly true if the object is explicitly tagged.
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
protected Asn1TaggedObject(bool isExplicit, int tagNo, Asn1Encodable obj)
|
||||
: this(isExplicit, Asn1Tags.ContextSpecific, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
protected Asn1TaggedObject(bool isExplicit, int tagClass, int tagNo, Asn1Encodable obj)
|
||||
: this(isExplicit ? DeclaredExplicit : DeclaredImplicit, tagClass, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
internal Asn1TaggedObject(int explicitness, int tagClass, int tagNo, Asn1Encodable obj)
|
||||
{
|
||||
if (null == obj)
|
||||
throw new ArgumentNullException("obj");
|
||||
if (Asn1Tags.Universal == tagClass || (tagClass & Asn1Tags.Private) != tagClass)
|
||||
throw new ArgumentException("invalid tag class: " + tagClass, "tagClass");
|
||||
|
||||
this.explicitness = (obj is IAsn1Choice) ? DeclaredExplicit : explicitness;
|
||||
this.tagClass = tagClass;
|
||||
this.tagNo = tagNo;
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1TaggedObject that = asn1Object as Asn1TaggedObject;
|
||||
if (null == that || this.tagNo != that.tagNo || this.tagClass != that.tagClass)
|
||||
return false;
|
||||
|
||||
if (this.explicitness != that.explicitness)
|
||||
{
|
||||
/*
|
||||
* TODO This seems incorrect for some cases of implicit tags e.g. if one is a
|
||||
* declared-implicit SET and the other a parsed object.
|
||||
*/
|
||||
if (this.IsExplicit() != that.IsExplicit())
|
||||
return false;
|
||||
}
|
||||
|
||||
Asn1Object p1 = this.obj.ToAsn1Object();
|
||||
Asn1Object p2 = that.obj.ToAsn1Object();
|
||||
|
||||
if (p1 == p2)
|
||||
return true;
|
||||
|
||||
if (!this.IsExplicit())
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] d1 = this.GetEncoded();
|
||||
byte[] d2 = that.GetEncoded();
|
||||
|
||||
return Arrays.AreEqual(d1, d2);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return p1.CallAsn1Equals(p2);
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
return (tagClass * 7919) ^ tagNo ^ (IsExplicit() ? 0x0F : 0xF0) ^ obj.ToAsn1Object().CallAsn1GetHashCode();
|
||||
}
|
||||
|
||||
public int TagClass
|
||||
{
|
||||
get { return tagClass; }
|
||||
}
|
||||
|
||||
public int TagNo
|
||||
{
|
||||
get { return tagNo; }
|
||||
}
|
||||
|
||||
public bool HasContextTag(int tagNo)
|
||||
{
|
||||
return this.tagClass == Asn1Tags.ContextSpecific && this.tagNo == tagNo;
|
||||
}
|
||||
|
||||
public bool HasTag(int tagClass, int tagNo)
|
||||
{
|
||||
return this.tagClass == tagClass && this.tagNo == tagNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* return whether or not the object may be explicitly tagged.
|
||||
* <p>
|
||||
* Note: if the object has been read from an input stream, the only
|
||||
* time you can be sure if isExplicit is returning the true state of
|
||||
* affairs is if it returns false. An implicitly tagged object may appear
|
||||
* to be explicitly tagged, so you need to understand the context under
|
||||
* which the reading was done as well, see GetObject below.</p>
|
||||
*/
|
||||
public bool IsExplicit()
|
||||
{
|
||||
// TODO New methods like 'IsKnownExplicit' etc. to distinguish uncertain cases?
|
||||
switch (explicitness)
|
||||
{
|
||||
case DeclaredExplicit:
|
||||
case ParsedExplicit:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsParsed()
|
||||
{
|
||||
switch (explicitness)
|
||||
{
|
||||
case ParsedExplicit:
|
||||
case ParsedImplicit:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return whatever was following the tag.
|
||||
* <p>
|
||||
* Note: tagged objects are generally context dependent if you're
|
||||
* trying to extract a tagged object you should be going via the
|
||||
* appropriate GetInstance method.</p>
|
||||
*/
|
||||
public Asn1Object GetObject()
|
||||
{
|
||||
if (Asn1Tags.ContextSpecific != TagClass)
|
||||
throw new InvalidOperationException("this method only valid for CONTEXT_SPECIFIC tags");
|
||||
|
||||
return obj.ToAsn1Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for open types, until we have better type-guided parsing support. Use sparingly for other
|
||||
* purposes, and prefer {@link #getExplicitBaseTagged()}, {@link #getImplicitBaseTagged(int, int)} or
|
||||
* {@link #getBaseUniversal(boolean, int)} where possible. Before using, check for matching tag
|
||||
* {@link #getTagClass() class} and {@link #getTagNo() number}.
|
||||
*/
|
||||
public Asn1Encodable GetBaseObject()
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for open types, until we have better type-guided parsing support. Use
|
||||
* sparingly for other purposes, and prefer {@link #getExplicitBaseTagged()} or
|
||||
* {@link #getBaseUniversal(boolean, int)} where possible. Before using, check
|
||||
* for matching tag {@link #getTagClass() class} and {@link #getTagNo() number}.
|
||||
*/
|
||||
public Asn1Encodable GetExplicitBaseObject()
|
||||
{
|
||||
if (!IsExplicit())
|
||||
throw new InvalidOperationException("object implicit - explicit expected.");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Asn1TaggedObject GetExplicitBaseTagged()
|
||||
{
|
||||
if (!IsExplicit())
|
||||
throw new InvalidOperationException("object implicit - explicit expected.");
|
||||
|
||||
return CheckedCast(obj.ToAsn1Object());
|
||||
}
|
||||
|
||||
public Asn1TaggedObject GetImplicitBaseTagged(int baseTagClass, int baseTagNo)
|
||||
{
|
||||
if (Asn1Tags.Universal == baseTagClass || (baseTagClass & Asn1Tags.Private) != baseTagClass)
|
||||
throw new ArgumentException("invalid base tag class: " + baseTagClass, "baseTagClass");
|
||||
|
||||
switch (explicitness)
|
||||
{
|
||||
case DeclaredExplicit:
|
||||
throw new InvalidOperationException("object explicit - implicit expected.");
|
||||
|
||||
case DeclaredImplicit:
|
||||
{
|
||||
Asn1TaggedObject declared = CheckedCast(obj.ToAsn1Object());
|
||||
return Asn1Utilities.CheckTag(declared, baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
// Parsed; return a virtual tag (i.e. that couldn't have been present in the encoding)
|
||||
default:
|
||||
return ReplaceTag(baseTagClass, baseTagNo);
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1Object GetBaseUniversal(bool declaredExplicit, int tagNo)
|
||||
{
|
||||
Asn1UniversalType universalType = Asn1UniversalTypes.Get(tagNo);
|
||||
if (null == universalType)
|
||||
throw new ArgumentException("unsupported UNIVERSAL tag number: " + tagNo, "tagNo");
|
||||
|
||||
return GetBaseUniversal(declaredExplicit, universalType);
|
||||
}
|
||||
|
||||
internal Asn1Object GetBaseUniversal(bool declaredExplicit, Asn1UniversalType universalType)
|
||||
{
|
||||
if (declaredExplicit)
|
||||
{
|
||||
if (!IsExplicit())
|
||||
throw new InvalidOperationException("object explicit - implicit expected.");
|
||||
|
||||
return universalType.CheckedCast(obj.ToAsn1Object());
|
||||
}
|
||||
|
||||
if (DeclaredExplicit == explicitness)
|
||||
throw new InvalidOperationException("object explicit - implicit expected.");
|
||||
|
||||
Asn1Object baseObject = obj.ToAsn1Object();
|
||||
switch (explicitness)
|
||||
{
|
||||
case ParsedExplicit:
|
||||
return universalType.FromImplicitConstructed(RebuildConstructed(baseObject));
|
||||
case ParsedImplicit:
|
||||
{
|
||||
if (baseObject is Asn1Sequence asn1Sequence)
|
||||
return universalType.FromImplicitConstructed(asn1Sequence);
|
||||
|
||||
return universalType.FromImplicitPrimitive((DerOctetString)baseObject);
|
||||
}
|
||||
default:
|
||||
return universalType.CheckedCast(baseObject);
|
||||
}
|
||||
}
|
||||
|
||||
public IAsn1Convertible ParseBaseUniversal(bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
Asn1Object asn1Object = GetBaseUniversal(declaredExplicit, baseTagNo);
|
||||
|
||||
switch (baseTagNo)
|
||||
{
|
||||
case Asn1Tags.BitString:
|
||||
return ((DerBitString)asn1Object).Parser;
|
||||
case Asn1Tags.OctetString:
|
||||
return ((Asn1OctetString)asn1Object).Parser;
|
||||
case Asn1Tags.Sequence:
|
||||
return ((Asn1Sequence)asn1Object).Parser;
|
||||
case Asn1Tags.Set:
|
||||
return ((Asn1Set)asn1Object).Parser;
|
||||
}
|
||||
|
||||
return asn1Object;
|
||||
}
|
||||
|
||||
public IAsn1Convertible ParseExplicitBaseObject()
|
||||
{
|
||||
return GetExplicitBaseObject();
|
||||
}
|
||||
|
||||
public Asn1TaggedObjectParser ParseExplicitBaseTagged()
|
||||
{
|
||||
return GetExplicitBaseTagged();
|
||||
}
|
||||
|
||||
public Asn1TaggedObjectParser ParseImplicitBaseTagged(int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return GetImplicitBaseTagged(baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Asn1Utilities.GetTagText(tagClass, tagNo) + obj;
|
||||
}
|
||||
|
||||
internal abstract string Asn1Encoding { get; }
|
||||
|
||||
internal abstract Asn1Sequence RebuildConstructed(Asn1Object asn1Object);
|
||||
|
||||
internal abstract Asn1TaggedObject ReplaceTag(int tagClass, int tagNo);
|
||||
|
||||
internal static Asn1Object CreateConstructedDL(int tagClass, int tagNo, Asn1EncodableVector contentsElements)
|
||||
{
|
||||
bool maybeExplicit = (contentsElements.Count == 1);
|
||||
|
||||
return maybeExplicit
|
||||
? new DLTaggedObject(ParsedExplicit, tagClass, tagNo, contentsElements[0])
|
||||
: new DLTaggedObject(ParsedImplicit, tagClass, tagNo, DLSequence.FromVector(contentsElements));
|
||||
}
|
||||
|
||||
internal static Asn1Object CreateConstructedIL(int tagClass, int tagNo, Asn1EncodableVector contentsElements)
|
||||
{
|
||||
bool maybeExplicit = (contentsElements.Count == 1);
|
||||
|
||||
return maybeExplicit
|
||||
? new BerTaggedObject(ParsedExplicit, tagClass, tagNo, contentsElements[0])
|
||||
: new BerTaggedObject(ParsedImplicit, tagClass, tagNo, BerSequence.FromVector(contentsElements));
|
||||
}
|
||||
|
||||
internal static Asn1Object CreatePrimitive(int tagClass, int tagNo, byte[] contentsOctets)
|
||||
{
|
||||
// Note: !CONSTRUCTED => IMPLICIT
|
||||
return new DLTaggedObject(ParsedImplicit, tagClass, tagNo, new DerOctetString(contentsOctets));
|
||||
}
|
||||
|
||||
private static Asn1TaggedObject CheckedCast(Asn1Object asn1Object)
|
||||
{
|
||||
Asn1TaggedObject taggedObject = asn1Object as Asn1TaggedObject;
|
||||
if (null != taggedObject)
|
||||
return taggedObject;
|
||||
|
||||
throw new InvalidOperationException("unexpected object: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(asn1Object));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dc761d7a5e48814998a495824555f3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class Asn1Tags
|
||||
{
|
||||
public const int Boolean = 0x01;
|
||||
public const int Integer = 0x02;
|
||||
public const int BitString = 0x03;
|
||||
public const int OctetString = 0x04;
|
||||
public const int Null = 0x05;
|
||||
public const int ObjectIdentifier = 0x06;
|
||||
public const int ObjectDescriptor = 0x07;
|
||||
public const int External = 0x08;
|
||||
public const int Real = 0x09;
|
||||
public const int Enumerated = 0x0a;
|
||||
public const int EmbeddedPdv = 0x0b;
|
||||
public const int Utf8String = 0x0c;
|
||||
public const int RelativeOid = 0x0d;
|
||||
// NOTE: 14-15 are reserved.
|
||||
public const int Sequence = 0x10;
|
||||
public const int SequenceOf = 0x10; // for completeness
|
||||
public const int Set = 0x11;
|
||||
public const int SetOf = 0x11; // for completeness
|
||||
|
||||
public const int NumericString = 0x12;
|
||||
public const int PrintableString = 0x13;
|
||||
public const int T61String = 0x14;
|
||||
public const int VideotexString = 0x15;
|
||||
public const int IA5String = 0x16;
|
||||
public const int UtcTime = 0x17;
|
||||
public const int GeneralizedTime = 0x18;
|
||||
public const int GraphicString = 0x19;
|
||||
public const int VisibleString = 0x1a;
|
||||
public const int GeneralString = 0x1b;
|
||||
public const int UniversalString = 0x1c;
|
||||
public const int UnrestrictedString = 0x1d;
|
||||
public const int BmpString = 0x1e;
|
||||
|
||||
public const int Constructed = 0x20;
|
||||
|
||||
public const int Universal = 0x00;
|
||||
public const int Application = 0x40;
|
||||
public const int ContextSpecific = 0x80;
|
||||
public const int Private = 0xC0;
|
||||
|
||||
public const int Flags = 0xE0;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d609f8d10b0a5c469fd85eb4b389e30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal abstract class Asn1Type
|
||||
{
|
||||
internal readonly Type m_platformType;
|
||||
|
||||
internal Asn1Type(Type platformType)
|
||||
{
|
||||
m_platformType = platformType;
|
||||
}
|
||||
|
||||
internal Type PlatformType
|
||||
{
|
||||
get { return m_platformType; }
|
||||
}
|
||||
|
||||
public sealed override bool Equals(object that)
|
||||
{
|
||||
return this == that;
|
||||
}
|
||||
|
||||
public sealed override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffac7d6916dbabc449fd3c8f9f3b51c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP
|
||||
using System.TypeFix;
|
||||
#endif
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal abstract class Asn1UniversalType
|
||||
: Asn1Type
|
||||
{
|
||||
internal readonly Asn1Tag m_tag;
|
||||
|
||||
internal Asn1UniversalType(Type platformType, int tagNo)
|
||||
: base(platformType)
|
||||
{
|
||||
m_tag = Asn1Tag.Create(Asn1Tags.Universal, tagNo);
|
||||
}
|
||||
|
||||
internal Asn1Object CheckedCast(Asn1Object asn1Object)
|
||||
{
|
||||
if (PlatformType.IsInstanceOfType(asn1Object))
|
||||
return asn1Object;
|
||||
|
||||
throw new InvalidOperationException("unexpected object: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(asn1Object));
|
||||
}
|
||||
|
||||
internal virtual Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
throw new InvalidOperationException("unexpected implicit primitive encoding");
|
||||
}
|
||||
|
||||
internal virtual Asn1Object FromImplicitConstructed(Asn1Sequence sequence)
|
||||
{
|
||||
throw new InvalidOperationException("unexpected implicit constructed encoding");
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
internal Asn1Object FromByteArray(byte[] bytes)
|
||||
{
|
||||
return CheckedCast(Asn1Object.FromByteArray(bytes));
|
||||
}
|
||||
|
||||
internal Asn1Object GetContextInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
if (Asn1Tags.ContextSpecific != taggedObject.TagClass)
|
||||
throw new InvalidOperationException("this method only valid for CONTEXT_SPECIFIC tags");
|
||||
|
||||
return CheckedCast(taggedObject.GetBaseUniversal(declaredExplicit, this));
|
||||
}
|
||||
|
||||
internal Asn1Tag Tag
|
||||
{
|
||||
get { return m_tag; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1449dc3fb760c69478b79ac2d2d26975
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal sealed class Asn1UniversalTypes
|
||||
{
|
||||
private Asn1UniversalTypes()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Asn1UniversalType Get(int tagNo)
|
||||
{
|
||||
switch (tagNo)
|
||||
{
|
||||
case Asn1Tags.Boolean:
|
||||
return DerBoolean.Meta.Instance;
|
||||
case Asn1Tags.Integer:
|
||||
return DerInteger.Meta.Instance;
|
||||
case Asn1Tags.BitString:
|
||||
return DerBitString.Meta.Instance;
|
||||
case Asn1Tags.OctetString:
|
||||
return Asn1OctetString.Meta.Instance;
|
||||
case Asn1Tags.Null:
|
||||
return Asn1Null.Meta.Instance;
|
||||
case Asn1Tags.ObjectIdentifier:
|
||||
return DerObjectIdentifier.Meta.Instance;
|
||||
case Asn1Tags.ObjectDescriptor: // [UNIVERSAL 7] IMPLICIT GraphicString
|
||||
return Asn1ObjectDescriptor.Meta.Instance;
|
||||
case Asn1Tags.External:
|
||||
return DerExternal.Meta.Instance;
|
||||
case Asn1Tags.Enumerated:
|
||||
return DerEnumerated.Meta.Instance;
|
||||
case Asn1Tags.Utf8String: // [UNIVERSAL 12] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerUtf8String.Meta.Instance;
|
||||
case Asn1Tags.RelativeOid:
|
||||
return Asn1RelativeOid.Meta.Instance;
|
||||
case Asn1Tags.Sequence:
|
||||
return Asn1Sequence.Meta.Instance;
|
||||
case Asn1Tags.Set:
|
||||
return Asn1Set.Meta.Instance;
|
||||
case Asn1Tags.NumericString: // [UNIVERSAL 18] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerNumericString.Meta.Instance;
|
||||
case Asn1Tags.PrintableString: // [UNIVERSAL 19] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerPrintableString.Meta.Instance;
|
||||
case Asn1Tags.T61String: // [UNIVERSAL 20] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerT61String.Meta.Instance;
|
||||
case Asn1Tags.VideotexString: // [UNIVERSAL 21] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerVideotexString.Meta.Instance;
|
||||
case Asn1Tags.IA5String: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerIA5String.Meta.Instance;
|
||||
case Asn1Tags.UtcTime: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values)
|
||||
return Asn1UtcTime.Meta.Instance;
|
||||
case Asn1Tags.GeneralizedTime: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values)
|
||||
return Asn1GeneralizedTime.Meta.Instance;
|
||||
case Asn1Tags.GraphicString: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerGraphicString.Meta.Instance;
|
||||
case Asn1Tags.VisibleString: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerVisibleString.Meta.Instance;
|
||||
case Asn1Tags.GeneralString: // [UNIVERSAL 27] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerGeneralString.Meta.Instance;
|
||||
case Asn1Tags.UniversalString: // [UNIVERSAL 28] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerUniversalString.Meta.Instance;
|
||||
case Asn1Tags.BmpString: // [UNIVERSAL 30] IMPLICIT OCTET STRING (encode as if)
|
||||
return DerBmpString.Meta.Instance;
|
||||
|
||||
case Asn1Tags.Real:
|
||||
case Asn1Tags.EmbeddedPdv:
|
||||
case Asn1Tags.UnrestrictedString:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 839094e1a57356a4eaefab55a4481ef9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,257 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Date;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/// <summary>UTCTime ASN.1 type</summary>
|
||||
public class Asn1UtcTime
|
||||
: Asn1Object
|
||||
{
|
||||
internal class Meta : Asn1UniversalType
|
||||
{
|
||||
internal static readonly Asn1UniversalType Instance = new Meta();
|
||||
|
||||
private Meta() : base(typeof(Asn1UtcTime), Asn1Tags.UtcTime) {}
|
||||
|
||||
internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString)
|
||||
{
|
||||
return CreatePrimitive(octetString.GetOctets());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return a UTC Time from the passed in object.
|
||||
*
|
||||
* @exception ArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static Asn1UtcTime GetInstance(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj is Asn1UtcTime asn1UtcTime)
|
||||
return asn1UtcTime;
|
||||
|
||||
if (obj is IAsn1Convertible asn1Convertible)
|
||||
{
|
||||
Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
|
||||
if (asn1Object is Asn1UtcTime converted)
|
||||
return converted;
|
||||
}
|
||||
else if (obj is byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Asn1UtcTime)Meta.Instance.FromByteArray(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), nameof(obj));
|
||||
}
|
||||
|
||||
public static Asn1UtcTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
|
||||
{
|
||||
return (Asn1UtcTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
|
||||
}
|
||||
|
||||
private readonly string m_timeString;
|
||||
private readonly DateTime m_dateTime;
|
||||
private readonly bool m_dateTimeLocked;
|
||||
private readonly int m_twoDigitYearMax;
|
||||
|
||||
public Asn1UtcTime(string timeString)
|
||||
{
|
||||
m_timeString = timeString ?? throw new ArgumentNullException(nameof(timeString));
|
||||
|
||||
try
|
||||
{
|
||||
m_dateTime = FromString(timeString, out m_twoDigitYearMax);
|
||||
m_dateTimeLocked = false;
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
throw new ArgumentException("invalid date string: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Asn1UtcTime(DateTime dateTime)
|
||||
{
|
||||
dateTime = DateTimeUtilities.WithPrecisionSecond(dateTime.ToUniversalTime());
|
||||
|
||||
m_dateTime = dateTime;
|
||||
m_dateTimeLocked = true;
|
||||
m_timeString = ToStringCanonical(dateTime, out m_twoDigitYearMax);
|
||||
}
|
||||
|
||||
public Asn1UtcTime(DateTime dateTime, int twoDigitYearMax)
|
||||
{
|
||||
dateTime = DateTimeUtilities.WithPrecisionSecond(dateTime.ToUniversalTime());
|
||||
|
||||
Validate(dateTime, twoDigitYearMax);
|
||||
|
||||
m_dateTime = dateTime;
|
||||
m_dateTimeLocked = true;
|
||||
m_timeString = ToStringCanonical(dateTime);
|
||||
m_twoDigitYearMax = twoDigitYearMax;
|
||||
}
|
||||
|
||||
internal Asn1UtcTime(byte[] contents)
|
||||
// NOTE: Non-ASCII characters will produce '?' characters, which will fail DateTime parsing
|
||||
: this(Encoding.ASCII.GetString(contents))
|
||||
{
|
||||
}
|
||||
|
||||
public string TimeString => m_timeString;
|
||||
|
||||
public DateTime ToDateTime()
|
||||
{
|
||||
return m_dateTime;
|
||||
}
|
||||
|
||||
public DateTime ToDateTime(int twoDigitYearMax)
|
||||
{
|
||||
if (InRange(m_dateTime, twoDigitYearMax))
|
||||
return m_dateTime;
|
||||
|
||||
if (m_dateTimeLocked)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
int twoDigitYear = m_dateTime.Year % 100;
|
||||
int twoDigitYearCutoff = twoDigitYearMax % 100;
|
||||
|
||||
int diff = twoDigitYear - twoDigitYearCutoff;
|
||||
int newYear = twoDigitYearMax + diff;
|
||||
if (diff > 0)
|
||||
{
|
||||
newYear -= 100;
|
||||
}
|
||||
|
||||
return m_dateTime.AddYears(newYear - m_dateTime.Year);
|
||||
}
|
||||
|
||||
public DateTime ToDateTime(Calendar calendar)
|
||||
{
|
||||
return ToDateTime(calendar.TwoDigitYearMax);
|
||||
}
|
||||
|
||||
/// <summary>Return an adjusted date in the range of 1950 - 2049.</summary>
|
||||
|
||||
public DateTime ToAdjustedDateTime()
|
||||
{
|
||||
return ToDateTime(2049);
|
||||
}
|
||||
|
||||
public int TwoDigitYearMax => m_twoDigitYearMax;
|
||||
|
||||
internal byte[] GetContents(int encoding)
|
||||
{
|
||||
if (encoding == Asn1OutputStream.EncodingDer && m_timeString.Length != 13)
|
||||
{
|
||||
string canonical = ToStringCanonical(m_dateTime);
|
||||
return Encoding.ASCII.GetBytes(canonical);
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetBytes(m_timeString);
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.UtcTime, GetContents(encoding));
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
return new PrimitiveEncoding(tagClass, tagNo, GetContents(encoding));
|
||||
}
|
||||
|
||||
protected override bool Asn1Equals(Asn1Object asn1Object)
|
||||
{
|
||||
if (!(asn1Object is Asn1UtcTime that))
|
||||
return false;
|
||||
|
||||
// TODO Performance
|
||||
return Arrays.AreEqual(
|
||||
this.GetContents(Asn1OutputStream.EncodingDer),
|
||||
that.GetContents(Asn1OutputStream.EncodingDer));
|
||||
}
|
||||
|
||||
protected override int Asn1GetHashCode()
|
||||
{
|
||||
// TODO Performance
|
||||
return Arrays.GetHashCode(
|
||||
this.GetContents(Asn1OutputStream.EncodingDer));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_timeString;
|
||||
}
|
||||
|
||||
internal static Asn1UtcTime CreatePrimitive(byte[] contents)
|
||||
{
|
||||
return new Asn1UtcTime(contents);
|
||||
}
|
||||
|
||||
private static DateTime FromString(string s, out int twoDigitYearMax)
|
||||
{
|
||||
var provider = DateTimeFormatInfo.InvariantInfo;
|
||||
twoDigitYearMax = provider.Calendar.TwoDigitYearMax;
|
||||
|
||||
switch (s.Length)
|
||||
{
|
||||
case 11:
|
||||
return DateTime.ParseExact(s, @"yyMMddHHmm\Z", provider,
|
||||
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
||||
case 13:
|
||||
return DateTime.ParseExact(s, @"yyMMddHHmmss\Z", provider,
|
||||
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
||||
case 15:
|
||||
return DateTime.ParseExact(s, @"yyMMddHHmmzzz", provider, DateTimeStyles.AdjustToUniversal);
|
||||
case 17:
|
||||
return DateTime.ParseExact(s, @"yyMMddHHmmsszzz", provider, DateTimeStyles.AdjustToUniversal);
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool InRange(DateTime dateTime, int twoDigitYearMax)
|
||||
{
|
||||
return (uint)(twoDigitYearMax - dateTime.Year) < 100;
|
||||
}
|
||||
|
||||
private static string ToStringCanonical(DateTime dateTime, out int twoDigitYearMax)
|
||||
{
|
||||
var provider = DateTimeFormatInfo.InvariantInfo;
|
||||
twoDigitYearMax = provider.Calendar.TwoDigitYearMax;
|
||||
|
||||
Validate(dateTime, twoDigitYearMax);
|
||||
|
||||
return dateTime.ToString(@"yyMMddHHmmss\Z", provider);
|
||||
}
|
||||
|
||||
private static string ToStringCanonical(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString(@"yyMMddHHmmss\Z", DateTimeFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
||||
private static void Validate(DateTime dateTime, int twoDigitYearMax)
|
||||
{
|
||||
if (!InRange(dateTime, twoDigitYearMax))
|
||||
throw new ArgumentOutOfRangeException(nameof(dateTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edf61982cdff33c408181b8d191ae7ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,333 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class Asn1Utilities
|
||||
{
|
||||
internal static Asn1TaggedObject CheckTag(Asn1TaggedObject taggedObject, int tagClass, int tagNo)
|
||||
{
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
{
|
||||
string expected = GetTagText(tagClass, tagNo);
|
||||
string found = GetTagText(taggedObject);
|
||||
throw new InvalidOperationException("Expected " + expected + " tag but found " + found);
|
||||
}
|
||||
return taggedObject;
|
||||
}
|
||||
|
||||
internal static Asn1TaggedObjectParser CheckTag(Asn1TaggedObjectParser taggedObjectParser, int tagClass,
|
||||
int tagNo)
|
||||
{
|
||||
if (!taggedObjectParser.HasTag(tagClass, tagNo))
|
||||
{
|
||||
string expected = GetTagText(tagClass, tagNo);
|
||||
string found = GetTagText(taggedObjectParser);
|
||||
throw new InvalidOperationException("Expected " + expected + " tag but found " + found);
|
||||
}
|
||||
return taggedObjectParser;
|
||||
}
|
||||
|
||||
|
||||
internal static string GetTagText(Asn1Tag tag)
|
||||
{
|
||||
return GetTagText(tag.TagClass, tag.TagNo);
|
||||
}
|
||||
|
||||
public static string GetTagText(Asn1TaggedObject taggedObject)
|
||||
{
|
||||
return GetTagText(taggedObject.TagClass, taggedObject.TagNo);
|
||||
}
|
||||
|
||||
public static string GetTagText(Asn1TaggedObjectParser taggedObjectParser)
|
||||
{
|
||||
return GetTagText(taggedObjectParser.TagClass, taggedObjectParser.TagNo);
|
||||
}
|
||||
|
||||
public static string GetTagText(int tagClass, int tagNo)
|
||||
{
|
||||
switch (tagClass)
|
||||
{
|
||||
case Asn1Tags.Application:
|
||||
return "[APPLICATION " + tagNo + "]";
|
||||
case Asn1Tags.ContextSpecific:
|
||||
return "[CONTEXT " + tagNo + "]";
|
||||
case Asn1Tags.Private:
|
||||
return "[PRIVATE " + tagNo + "]";
|
||||
default:
|
||||
return "[UNIVERSAL " + tagNo + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObject.GetExplicitBaseObject
|
||||
*/
|
||||
|
||||
public static Asn1Encodable GetExplicitBaseObject(Asn1TaggedObject taggedObject, int tagClass, int tagNo)
|
||||
{
|
||||
return CheckTag(taggedObject, tagClass, tagNo).GetExplicitBaseObject();
|
||||
}
|
||||
|
||||
public static Asn1Encodable GetExplicitContextBaseObject(Asn1TaggedObject taggedObject, int tagNo)
|
||||
{
|
||||
return GetExplicitBaseObject(taggedObject, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
public static Asn1Encodable TryGetExplicitBaseObject(Asn1TaggedObject taggedObject, int tagClass, int tagNo)
|
||||
{
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObject.GetExplicitBaseObject();
|
||||
}
|
||||
|
||||
public static Asn1Encodable TryGetExplicitContextBaseObject(Asn1TaggedObject taggedObject, int tagNo)
|
||||
{
|
||||
return TryGetExplicitBaseObject(taggedObject, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObject.GetExplicitBaseTagged
|
||||
*/
|
||||
|
||||
public static Asn1TaggedObject GetExplicitBaseTagged(Asn1TaggedObject taggedObject, int tagClass, int tagNo)
|
||||
{
|
||||
return CheckTag(taggedObject, tagClass, tagNo).GetExplicitBaseTagged();
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject GetExplicitContextBaseTagged(Asn1TaggedObject taggedObject, int tagNo)
|
||||
{
|
||||
return GetExplicitBaseTagged(taggedObject, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject TryGetExplicitBaseTagged(Asn1TaggedObject taggedObject, int tagClass, int tagNo)
|
||||
{
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObject.GetExplicitBaseTagged();
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject TryGetExplicitContextBaseTagged(Asn1TaggedObject taggedObject, int tagNo)
|
||||
{
|
||||
return TryGetExplicitBaseTagged(taggedObject, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObject.GetImplicitBaseTagged
|
||||
*/
|
||||
|
||||
public static Asn1TaggedObject GetImplicitBaseTagged(Asn1TaggedObject taggedObject, int tagClass, int tagNo,
|
||||
int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return CheckTag(taggedObject, tagClass, tagNo).GetImplicitBaseTagged(baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject GetImplicitContextBaseTagged(Asn1TaggedObject taggedObject, int tagNo,
|
||||
int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return GetImplicitBaseTagged(taggedObject, Asn1Tags.ContextSpecific, tagNo, baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject TryGetImplicitBaseTagged(Asn1TaggedObject taggedObject, int tagClass, int tagNo,
|
||||
int baseTagClass, int baseTagNo)
|
||||
{
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObject.GetImplicitBaseTagged(baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1TaggedObject TryGetImplicitContextBaseTagged(Asn1TaggedObject taggedObject, int tagNo,
|
||||
int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return TryGetImplicitBaseTagged(taggedObject, Asn1Tags.ContextSpecific, tagNo, baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObject.GetBaseUniversal
|
||||
*/
|
||||
|
||||
public static Asn1Object GetBaseUniversal(Asn1TaggedObject taggedObject, int tagClass, int tagNo,
|
||||
bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return CheckTag(taggedObject, tagClass, tagNo).GetBaseUniversal(declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1Object GetContextBaseUniversal(Asn1TaggedObject taggedObject, int tagNo,
|
||||
bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return GetBaseUniversal(taggedObject, Asn1Tags.ContextSpecific, tagNo, declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1Object TryGetBaseUniversal(Asn1TaggedObject taggedObject, int tagClass, int tagNo,
|
||||
bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
if (!taggedObject.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObject.GetBaseUniversal(declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
public static Asn1Object TryGetContextBaseUniversal(Asn1TaggedObject taggedObject, int tagNo,
|
||||
bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return TryGetBaseUniversal(taggedObject, Asn1Tags.ContextSpecific, tagNo, declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObjectParser.ParseExplicitBaseTagged
|
||||
*/
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser ParseExplicitBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagClass, int tagNo)
|
||||
{
|
||||
return CheckTag(taggedObjectParser, tagClass, tagNo).ParseExplicitBaseTagged();
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser ParseExplicitContextBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagNo)
|
||||
{
|
||||
return ParseExplicitBaseTagged(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser TryParseExplicitBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagClass, int tagNo)
|
||||
{
|
||||
if (!taggedObjectParser.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObjectParser.ParseExplicitBaseTagged();
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser TryParseExplicitContextBaseTagged(
|
||||
Asn1TaggedObjectParser taggedObjectParser, int tagNo)
|
||||
{
|
||||
return TryParseExplicitBaseTagged(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObjectParser.ParseImplicitBaseTagged
|
||||
*/
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser ParseImplicitBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagClass, int tagNo, int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return CheckTag(taggedObjectParser, tagClass, tagNo).ParseImplicitBaseTagged(baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser ParseImplicitContextBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagNo, int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return ParseImplicitBaseTagged(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo, baseTagClass,
|
||||
baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser TryParseImplicitBaseTagged(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagClass, int tagNo, int baseTagClass, int baseTagNo)
|
||||
{
|
||||
if (!taggedObjectParser.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObjectParser.ParseImplicitBaseTagged(baseTagClass, baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static Asn1TaggedObjectParser TryParseImplicitContextBaseTagged(
|
||||
Asn1TaggedObjectParser taggedObjectParser, int tagNo, int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return TryParseImplicitBaseTagged(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo, baseTagClass,
|
||||
baseTagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObjectParser.ParseBaseUniversal
|
||||
*/
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible ParseBaseUniversal(Asn1TaggedObjectParser taggedObjectParser, int tagClass,
|
||||
int tagNo, bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return CheckTag(taggedObjectParser, tagClass, tagNo).ParseBaseUniversal(declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible ParseContextBaseUniversal(Asn1TaggedObjectParser taggedObjectParser, int tagNo,
|
||||
bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return ParseBaseUniversal(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo, declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible TryParseBaseUniversal(Asn1TaggedObjectParser taggedObjectParser, int tagClass,
|
||||
int tagNo, bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
if (!taggedObjectParser.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObjectParser.ParseBaseUniversal(declaredExplicit, baseTagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible TryParseContextBaseUniversal(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagNo, bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
return TryParseBaseUniversal(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo, declaredExplicit,
|
||||
baseTagNo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for Asn1TaggedObjectParser.ParseExplicitBaseObject
|
||||
*/
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible ParseExplicitBaseObject(Asn1TaggedObjectParser taggedObjectParser, int tagClass,
|
||||
int tagNo)
|
||||
{
|
||||
return CheckTag(taggedObjectParser, tagClass, tagNo).ParseExplicitBaseObject();
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible ParseExplicitContextBaseObject(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagNo)
|
||||
{
|
||||
return ParseExplicitBaseObject(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible TryParseExplicitBaseObject(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagClass, int tagNo)
|
||||
{
|
||||
if (!taggedObjectParser.HasTag(tagClass, tagNo))
|
||||
return null;
|
||||
|
||||
return taggedObjectParser.ParseExplicitBaseObject();
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public static IAsn1Convertible TryParseExplicitContextBaseObject(Asn1TaggedObjectParser taggedObjectParser,
|
||||
int tagNo)
|
||||
{
|
||||
return TryParseExplicitBaseObject(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62e229680bdece24987221dc054bce7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,142 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerBitString
|
||||
: DerBitString
|
||||
{
|
||||
private const int DefaultSegmentLimit = 1000;
|
||||
|
||||
internal static byte[] FlattenBitStrings(DerBitString[] bitStrings)
|
||||
{
|
||||
int count = bitStrings.Length;
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
// No bits
|
||||
return new byte[]{ 0 };
|
||||
case 1:
|
||||
return bitStrings[0].contents;
|
||||
default:
|
||||
{
|
||||
int last = count - 1, totalLength = 0;
|
||||
for (int i = 0; i < last; ++i)
|
||||
{
|
||||
byte[] elementContents = bitStrings[i].contents;
|
||||
if (elementContents[0] != 0)
|
||||
throw new ArgumentException("only the last nested bitstring can have padding", "bitStrings");
|
||||
|
||||
totalLength += elementContents.Length - 1;
|
||||
}
|
||||
|
||||
// Last one can have padding
|
||||
byte[] lastElementContents = bitStrings[last].contents;
|
||||
byte padBits = lastElementContents[0];
|
||||
totalLength += lastElementContents.Length;
|
||||
|
||||
byte[] contents = new byte[totalLength];
|
||||
contents[0] = padBits;
|
||||
|
||||
int pos = 1;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
byte[] elementContents = bitStrings[i].contents;
|
||||
int length = elementContents.Length - 1;
|
||||
Array.Copy(elementContents, 1, contents, pos, length);
|
||||
pos += length;
|
||||
}
|
||||
|
||||
Debug.Assert(pos == totalLength);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly int segmentLimit;
|
||||
private readonly DerBitString[] elements;
|
||||
|
||||
public BerBitString(byte data, int padBits)
|
||||
: base(data, padBits)
|
||||
{
|
||||
this.elements = null;
|
||||
this.segmentLimit = DefaultSegmentLimit;
|
||||
}
|
||||
|
||||
public BerBitString(byte[] data)
|
||||
: this(data, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public BerBitString(byte[] data, int padBits)
|
||||
: this(data, padBits, DefaultSegmentLimit)
|
||||
{
|
||||
}
|
||||
|
||||
public BerBitString(byte[] data, int padBits, int segmentLimit)
|
||||
: base(data, padBits)
|
||||
{
|
||||
this.elements = null;
|
||||
this.segmentLimit = segmentLimit;
|
||||
}
|
||||
|
||||
public BerBitString(int namedBits)
|
||||
: base(namedBits)
|
||||
{
|
||||
this.elements = null;
|
||||
this.segmentLimit = DefaultSegmentLimit;
|
||||
}
|
||||
|
||||
public BerBitString(Asn1Encodable obj)
|
||||
: this(obj.GetDerEncoded(), 0)
|
||||
{
|
||||
}
|
||||
|
||||
public BerBitString(DerBitString[] elements)
|
||||
: this(elements, DefaultSegmentLimit)
|
||||
{
|
||||
}
|
||||
|
||||
public BerBitString(DerBitString[] elements, int segmentLimit)
|
||||
: base(FlattenBitStrings(elements), false)
|
||||
{
|
||||
this.elements = elements;
|
||||
this.segmentLimit = segmentLimit;
|
||||
}
|
||||
|
||||
internal BerBitString(byte[] contents, bool check)
|
||||
: base(contents, check)
|
||||
{
|
||||
this.elements = null;
|
||||
this.segmentLimit = DefaultSegmentLimit;
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncoding(encoding);
|
||||
|
||||
if (null == elements)
|
||||
return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.BitString, contents);
|
||||
|
||||
return new ConstructedILEncoding(Asn1Tags.Universal, Asn1Tags.BitString,
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e6d38188b772c2409c7dad9240d601a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,110 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public abstract class BerGenerator
|
||||
: Asn1Generator
|
||||
{
|
||||
private bool _tagged = false;
|
||||
private bool _isExplicit;
|
||||
private int _tagNo;
|
||||
|
||||
protected BerGenerator(
|
||||
Stream outStream)
|
||||
: base(outStream)
|
||||
{
|
||||
}
|
||||
|
||||
protected BerGenerator(
|
||||
Stream outStream,
|
||||
int tagNo,
|
||||
bool isExplicit)
|
||||
: base(outStream)
|
||||
{
|
||||
_tagged = true;
|
||||
_isExplicit = isExplicit;
|
||||
_tagNo = tagNo;
|
||||
}
|
||||
|
||||
public override void AddObject(Asn1Encodable obj)
|
||||
{
|
||||
obj.EncodeTo(Out);
|
||||
}
|
||||
|
||||
public override void AddObject(Asn1Object obj)
|
||||
{
|
||||
obj.EncodeTo(Out);
|
||||
}
|
||||
|
||||
public override Stream GetRawOutputStream()
|
||||
{
|
||||
return Out;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
WriteBerEnd();
|
||||
}
|
||||
|
||||
private void WriteHdr(
|
||||
int tag)
|
||||
{
|
||||
Out.WriteByte((byte) tag);
|
||||
Out.WriteByte(0x80);
|
||||
}
|
||||
|
||||
protected void WriteBerHeader(
|
||||
int tag)
|
||||
{
|
||||
if (_tagged)
|
||||
{
|
||||
int tagNum = _tagNo | Asn1Tags.ContextSpecific;
|
||||
|
||||
if (_isExplicit)
|
||||
{
|
||||
WriteHdr(tagNum | Asn1Tags.Constructed);
|
||||
WriteHdr(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tag & Asn1Tags.Constructed) != 0)
|
||||
{
|
||||
WriteHdr(tagNum | Asn1Tags.Constructed);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteHdr(tagNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteHdr(tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected void WriteBerBody(
|
||||
Stream contentStream)
|
||||
{
|
||||
Streams.PipeAll(contentStream, Out);
|
||||
}
|
||||
|
||||
protected void WriteBerEnd()
|
||||
{
|
||||
Out.WriteByte(0x00);
|
||||
Out.WriteByte(0x00);
|
||||
|
||||
if (_tagged && _isExplicit) // write extra end for tag header
|
||||
{
|
||||
Out.WriteByte(0x00);
|
||||
Out.WriteByte(0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebf471a1d43735f4aa2425eda406c2d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerOctetStringGenerator
|
||||
: BerGenerator
|
||||
{
|
||||
public BerOctetStringGenerator(Stream outStream)
|
||||
: base(outStream)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
|
||||
}
|
||||
|
||||
public BerOctetStringGenerator(
|
||||
Stream outStream,
|
||||
int tagNo,
|
||||
bool isExplicit)
|
||||
: base(outStream, tagNo, isExplicit)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
|
||||
}
|
||||
|
||||
public Stream GetOctetOutputStream()
|
||||
{
|
||||
return GetOctetOutputStream(new byte[1000]); // limit for CER encoding.
|
||||
}
|
||||
|
||||
public Stream GetOctetOutputStream(
|
||||
int bufSize)
|
||||
{
|
||||
return bufSize < 1
|
||||
? GetOctetOutputStream()
|
||||
: GetOctetOutputStream(new byte[bufSize]);
|
||||
}
|
||||
|
||||
public Stream GetOctetOutputStream(
|
||||
byte[] buf)
|
||||
{
|
||||
return new BufferedBerOctetStream(this, buf);
|
||||
}
|
||||
|
||||
private class BufferedBerOctetStream
|
||||
: BaseOutputStream
|
||||
{
|
||||
private byte[] _buf;
|
||||
private int _off;
|
||||
private readonly BerOctetStringGenerator _gen;
|
||||
private readonly Asn1OutputStream _derOut;
|
||||
|
||||
internal BufferedBerOctetStream(
|
||||
BerOctetStringGenerator gen,
|
||||
byte[] buf)
|
||||
{
|
||||
_gen = gen;
|
||||
_buf = buf;
|
||||
_off = 0;
|
||||
_derOut = Asn1OutputStream.Create(_gen.Out, Asn1Encodable.Der);
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Streams.ValidateBufferArguments(buffer, offset, count);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Write(buffer.AsSpan(offset, count));
|
||||
#else
|
||||
int bufLen = _buf.Length;
|
||||
int available = bufLen - _off;
|
||||
if (count < available)
|
||||
{
|
||||
Array.Copy(buffer, offset, _buf, _off, count);
|
||||
_off += count;
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
if (_off > 0)
|
||||
{
|
||||
Array.Copy(buffer, offset, _buf, _off, available);
|
||||
pos = available;
|
||||
DerOctetString.Encode(_derOut, _buf, 0, bufLen);
|
||||
//_off = 0;
|
||||
}
|
||||
|
||||
int remaining;
|
||||
while ((remaining = count - pos) >= bufLen)
|
||||
{
|
||||
DerOctetString.Encode(_derOut, buffer, offset + pos, bufLen);
|
||||
pos += bufLen;
|
||||
}
|
||||
|
||||
Array.Copy(buffer, offset + pos, _buf, 0, remaining);
|
||||
this._off = remaining;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public override void Write(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
int bufLen = _buf.Length;
|
||||
int available = bufLen - _off;
|
||||
if (buffer.Length < available)
|
||||
{
|
||||
buffer.CopyTo(_buf.AsSpan(_off));
|
||||
_off += buffer.Length;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_off > 0)
|
||||
{
|
||||
DerOctetString.Encode(_derOut, _buf.AsSpan(0, _off), buffer[..available]);
|
||||
buffer = buffer[available..];
|
||||
//_off = 0;
|
||||
}
|
||||
|
||||
while (buffer.Length >= bufLen)
|
||||
{
|
||||
DerOctetString.Encode(_derOut, buffer[..bufLen]);
|
||||
buffer = buffer[bufLen..];
|
||||
}
|
||||
|
||||
buffer.CopyTo(_buf.AsSpan());
|
||||
_off = buffer.Length;
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
_buf[_off++] = value;
|
||||
|
||||
if (_off == _buf.Length)
|
||||
{
|
||||
DerOctetString.Encode(_derOut, _buf, 0, _off);
|
||||
_off = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_off != 0)
|
||||
{
|
||||
DerOctetString.Encode(_derOut, _buf, 0, _off);
|
||||
}
|
||||
|
||||
_derOut.FlushInternal();
|
||||
|
||||
_gen.WriteBerEnd();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5318cc9ca270a547b9434252273ff30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerOctetStringParser
|
||||
: Asn1OctetStringParser
|
||||
{
|
||||
private readonly Asn1StreamParser _parser;
|
||||
|
||||
internal BerOctetStringParser(Asn1StreamParser parser)
|
||||
{
|
||||
_parser = parser;
|
||||
}
|
||||
|
||||
public Stream GetOctetStream()
|
||||
{
|
||||
return new ConstructedOctetStream(_parser);
|
||||
}
|
||||
|
||||
public Asn1Object ToAsn1Object()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Parse(_parser);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static BerOctetString Parse(Asn1StreamParser sp)
|
||||
{
|
||||
return new BerOctetString(Streams.ReadAll(new ConstructedOctetStream(sp)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f349002b9962c3f449219681235b114a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSequenceGenerator
|
||||
: BerGenerator
|
||||
{
|
||||
public BerSequenceGenerator(
|
||||
Stream outStream)
|
||||
: base(outStream)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence);
|
||||
}
|
||||
|
||||
public BerSequenceGenerator(
|
||||
Stream outStream,
|
||||
int tagNo,
|
||||
bool isExplicit)
|
||||
: base(outStream, tagNo, isExplicit)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39e69b682926f0348a2f183f3d1c8913
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSequenceParser
|
||||
: Asn1SequenceParser
|
||||
{
|
||||
private readonly Asn1StreamParser _parser;
|
||||
|
||||
internal BerSequenceParser(Asn1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public IAsn1Convertible ReadObject()
|
||||
{
|
||||
return _parser.ReadObject();
|
||||
}
|
||||
|
||||
public Asn1Object ToAsn1Object()
|
||||
{
|
||||
return Parse(_parser);
|
||||
}
|
||||
|
||||
internal static BerSequence Parse(Asn1StreamParser sp)
|
||||
{
|
||||
return new BerSequence(sp.ReadVector());
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d593cc0e2b63d14a8aeed9ce0369876
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSetGenerator
|
||||
: BerGenerator
|
||||
{
|
||||
public BerSetGenerator(
|
||||
Stream outStream)
|
||||
: base(outStream)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set);
|
||||
}
|
||||
|
||||
public BerSetGenerator(
|
||||
Stream outStream,
|
||||
int tagNo,
|
||||
bool isExplicit)
|
||||
: base(outStream, tagNo, isExplicit)
|
||||
{
|
||||
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fbdbc3f5ccf9f446b5a5b30159adca1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSetParser
|
||||
: Asn1SetParser
|
||||
{
|
||||
private readonly Asn1StreamParser _parser;
|
||||
|
||||
internal BerSetParser(Asn1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public IAsn1Convertible ReadObject()
|
||||
{
|
||||
return _parser.ReadObject();
|
||||
}
|
||||
|
||||
public Asn1Object ToAsn1Object()
|
||||
{
|
||||
return Parse(_parser);
|
||||
}
|
||||
|
||||
internal static BerSet Parse(Asn1StreamParser sp)
|
||||
{
|
||||
return new BerSet(sp.ReadVector());
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0260d4642cd5cf94c965eb9cd0ea9635
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal class BerTaggedObjectParser
|
||||
: Asn1TaggedObjectParser
|
||||
{
|
||||
internal readonly int m_tagClass;
|
||||
internal readonly int m_tagNo;
|
||||
internal readonly Asn1StreamParser m_parser;
|
||||
|
||||
internal BerTaggedObjectParser(int tagClass, int tagNo, Asn1StreamParser parser)
|
||||
{
|
||||
m_tagClass = tagClass;
|
||||
m_tagNo = tagNo;
|
||||
m_parser = parser;
|
||||
}
|
||||
|
||||
public virtual bool IsConstructed
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public int TagClass
|
||||
{
|
||||
get { return m_tagClass; }
|
||||
}
|
||||
|
||||
public int TagNo
|
||||
{
|
||||
get { return m_tagNo; }
|
||||
}
|
||||
|
||||
public bool HasContextTag(int tagNo)
|
||||
{
|
||||
return m_tagClass == Asn1Tags.ContextSpecific && m_tagNo == tagNo;
|
||||
}
|
||||
|
||||
public bool HasTag(int tagClass, int tagNo)
|
||||
{
|
||||
return m_tagClass == tagClass && m_tagNo == tagNo;
|
||||
}
|
||||
|
||||
public virtual IAsn1Convertible ParseBaseUniversal(bool declaredExplicit, int baseTagNo)
|
||||
{
|
||||
if (declaredExplicit)
|
||||
return m_parser.ParseObject(baseTagNo);
|
||||
|
||||
return m_parser.ParseImplicitConstructedIL(baseTagNo);
|
||||
}
|
||||
|
||||
public virtual IAsn1Convertible ParseExplicitBaseObject()
|
||||
{
|
||||
return m_parser.ReadObject();
|
||||
}
|
||||
|
||||
public virtual Asn1TaggedObjectParser ParseExplicitBaseTagged()
|
||||
{
|
||||
return m_parser.ParseTaggedObject();
|
||||
}
|
||||
|
||||
public virtual Asn1TaggedObjectParser ParseImplicitBaseTagged(int baseTagClass, int baseTagNo)
|
||||
{
|
||||
return new BerTaggedObjectParser(baseTagClass, baseTagNo, m_parser);
|
||||
}
|
||||
|
||||
public virtual Asn1Object ToAsn1Object()
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_parser.LoadTaggedIL(TagClass, TagNo);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Asn1ParsingException(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59190053596d8924a9902581e3b94f46
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d565bd50647e32459915b52caf8d736
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,2 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f60af26f2a3ecad4ab67ab32b5796bbe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/// <summary>A parser for indefinite-length BIT STRINGs.</summary>
|
||||
internal class BerBitStringParser
|
||||
: Asn1BitStringParser
|
||||
{
|
||||
private readonly Asn1StreamParser m_parser;
|
||||
|
||||
private ConstructedBitStream m_bitStream;
|
||||
|
||||
internal BerBitStringParser(Asn1StreamParser parser)
|
||||
{
|
||||
m_parser = parser;
|
||||
}
|
||||
|
||||
public Stream GetOctetStream()
|
||||
{
|
||||
return m_bitStream = new ConstructedBitStream(m_parser, true);
|
||||
}
|
||||
|
||||
public Stream GetBitStream()
|
||||
{
|
||||
return m_bitStream = new ConstructedBitStream(m_parser, false);
|
||||
}
|
||||
|
||||
public int PadBits
|
||||
{
|
||||
get { return m_bitStream.PadBits; }
|
||||
}
|
||||
|
||||
public Asn1Object ToAsn1Object()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Parse(m_parser);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static BerBitString Parse(Asn1StreamParser sp)
|
||||
{
|
||||
ConstructedBitStream bitStream = new ConstructedBitStream(sp, false);
|
||||
byte[] data = Streams.ReadAll(bitStream);
|
||||
int padBits = bitStream.PadBits;
|
||||
return new BerBitString(data, padBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0935e7c4731287a488fd95f8f9670666
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,112 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerOctetString
|
||||
: DerOctetString
|
||||
{
|
||||
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 readonly int segmentLimit;
|
||||
private readonly Asn1OctetString[] elements;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d06a07cbd3b71a74f8cb664efab20cd0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4acf00c72bf317e489e931a8c0c3c3da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,101 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSequence
|
||||
: DerSequence
|
||||
{
|
||||
public static new readonly BerSequence Empty = new BerSequence();
|
||||
|
||||
public static new BerSequence FromVector(Asn1EncodableVector elementVector)
|
||||
{
|
||||
return elementVector.Count < 1 ? Empty : new BerSequence(elementVector);
|
||||
}
|
||||
|
||||
/**
|
||||
* create an empty sequence
|
||||
*/
|
||||
public BerSequence()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing one object
|
||||
*/
|
||||
public BerSequence(Asn1Encodable element)
|
||||
: base(element)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing two objects
|
||||
*/
|
||||
public BerSequence(Asn1Encodable element1, Asn1Encodable element2)
|
||||
: base(element1, element2)
|
||||
{
|
||||
}
|
||||
|
||||
public BerSequence(params Asn1Encodable[] elements)
|
||||
: base(elements)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
*/
|
||||
public BerSequence(Asn1EncodableVector elementVector)
|
||||
: base(elementVector)
|
||||
{
|
||||
}
|
||||
|
||||
internal BerSequence(Asn1Encodable[] elements, bool clone)
|
||||
: base(elements, clone)
|
||||
{
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncoding(encoding);
|
||||
|
||||
return new ConstructedILEncoding(Asn1Tags.Universal, Asn1Tags.Sequence,
|
||||
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncodingImplicit(encoding, tagClass, tagNo);
|
||||
|
||||
return new ConstructedILEncoding(tagClass, tagNo,
|
||||
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
||||
}
|
||||
|
||||
internal override DerBitString ToAsn1BitString()
|
||||
{
|
||||
return new BerBitString(GetConstructedBitStrings());
|
||||
}
|
||||
|
||||
internal override DerExternal ToAsn1External()
|
||||
{
|
||||
// TODO There is currently no BerExternal class (or ToDLObject/ToDerObject)
|
||||
//return ((Asn1Sequence)ToDLObject()).ToAsn1External();
|
||||
return new DLSequence(elements).ToAsn1External();
|
||||
}
|
||||
|
||||
internal override Asn1OctetString ToAsn1OctetString()
|
||||
{
|
||||
return new BerOctetString(GetConstructedOctetStrings());
|
||||
}
|
||||
|
||||
internal override Asn1Set ToAsn1Set()
|
||||
{
|
||||
return new BerSet(false, elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5bc0026174da4a4e878a4914a50457b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
public class BerSet
|
||||
: DerSet
|
||||
{
|
||||
public static new readonly BerSet Empty = new BerSet();
|
||||
|
||||
public static new BerSet FromVector(Asn1EncodableVector elementVector)
|
||||
{
|
||||
return elementVector.Count < 1 ? Empty : new BerSet(elementVector);
|
||||
}
|
||||
|
||||
/**
|
||||
* create an empty set
|
||||
*/
|
||||
public BerSet()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a set containing one object
|
||||
*/
|
||||
public BerSet(Asn1Encodable element)
|
||||
: base(element)
|
||||
{
|
||||
}
|
||||
|
||||
public BerSet(params Asn1Encodable[] elements)
|
||||
: base(elements, false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a set containing a vector of objects.
|
||||
*/
|
||||
public BerSet(Asn1EncodableVector elementVector)
|
||||
: base(elementVector, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal BerSet(bool isSorted, Asn1Encodable[] elements)
|
||||
: base(isSorted, elements)
|
||||
{
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncoding(encoding);
|
||||
|
||||
return new ConstructedILEncoding(Asn1Tags.Universal, Asn1Tags.Set,
|
||||
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncodingImplicit(encoding, tagClass, tagNo);
|
||||
|
||||
return new ConstructedILEncoding(tagClass, tagNo,
|
||||
Asn1OutputStream.GetContentsEncodings(encoding, elements));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01890d0dd345cff48bdbba411a658317
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
/**
|
||||
* BER TaggedObject - in ASN.1 notation this is any object preceded by
|
||||
* a [n] where n is some number - these are assumed to follow the construction
|
||||
* rules (as with sequences).
|
||||
*/
|
||||
public class BerTaggedObject
|
||||
: DerTaggedObject
|
||||
{
|
||||
/**
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public BerTaggedObject(int tagNo, Asn1Encodable obj)
|
||||
: base(true, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
public BerTaggedObject(int tagClass, int tagNo, Asn1Encodable obj)
|
||||
: base(true, tagClass, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isExplicit true if an explicitly tagged object.
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public BerTaggedObject(bool isExplicit, int tagNo, Asn1Encodable obj)
|
||||
: base(isExplicit, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
public BerTaggedObject(bool isExplicit, int tagClass, int tagNo, Asn1Encodable obj)
|
||||
: base(isExplicit, tagClass, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
internal BerTaggedObject(int explicitness, int tagClass, int tagNo, Asn1Encodable obj)
|
||||
: base(explicitness, tagClass, tagNo, obj)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string Asn1Encoding
|
||||
{
|
||||
get { return Ber; }
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncoding(int encoding)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncoding(encoding);
|
||||
|
||||
Asn1Object baseObject = GetBaseObject().ToAsn1Object();
|
||||
|
||||
if (!IsExplicit())
|
||||
return baseObject.GetEncodingImplicit(encoding, TagClass, TagNo);
|
||||
|
||||
return new ConstructedILEncoding(TagClass, TagNo, new IAsn1Encoding[]{ baseObject.GetEncoding(encoding) });
|
||||
}
|
||||
|
||||
internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo)
|
||||
{
|
||||
if (Asn1OutputStream.EncodingBer != encoding)
|
||||
return base.GetEncodingImplicit(encoding, tagClass, tagNo);
|
||||
|
||||
Asn1Object baseObject = GetBaseObject().ToAsn1Object();
|
||||
|
||||
if (!IsExplicit())
|
||||
return baseObject.GetEncodingImplicit(encoding, tagClass, tagNo);
|
||||
|
||||
return new ConstructedILEncoding(tagClass, tagNo, new IAsn1Encoding[]{ baseObject.GetEncoding(encoding) });
|
||||
}
|
||||
|
||||
internal override Asn1Sequence RebuildConstructed(Asn1Object asn1Object)
|
||||
{
|
||||
return new BerSequence(asn1Object);
|
||||
}
|
||||
|
||||
internal override Asn1TaggedObject ReplaceTag(int tagClass, int tagNo)
|
||||
{
|
||||
return new BerTaggedObject(explicitness, tagClass, tagNo, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb57ca2d9225e0340bc7c9ef54c0bd13
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,192 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal class ConstructedBitStream
|
||||
: BaseInputStream
|
||||
{
|
||||
private readonly Asn1StreamParser m_parser;
|
||||
private readonly bool m_octetAligned;
|
||||
|
||||
private bool m_first = true;
|
||||
private int m_padBits = 0;
|
||||
|
||||
private Asn1BitStringParser m_currentParser;
|
||||
private Stream m_currentStream;
|
||||
|
||||
internal ConstructedBitStream(Asn1StreamParser parser, bool octetAligned)
|
||||
{
|
||||
m_parser = parser;
|
||||
m_octetAligned = octetAligned;
|
||||
}
|
||||
|
||||
internal int PadBits
|
||||
{
|
||||
get { return m_padBits; }
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Streams.ValidateBufferArguments(buffer, offset, count);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
return Read(buffer.AsSpan(offset, count));
|
||||
#else
|
||||
if (count < 1)
|
||||
return 0;
|
||||
|
||||
if (m_currentStream == null)
|
||||
{
|
||||
if (!m_first)
|
||||
return 0;
|
||||
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
return 0;
|
||||
|
||||
m_first = false;
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
|
||||
int totalRead = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int numRead = m_currentStream.Read(buffer, offset + totalRead, count - totalRead);
|
||||
|
||||
if (numRead > 0)
|
||||
{
|
||||
totalRead += numRead;
|
||||
|
||||
if (totalRead == count)
|
||||
return totalRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_padBits = m_currentParser.PadBits;
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
{
|
||||
m_currentStream = null;
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
if (buffer.IsEmpty)
|
||||
return 0;
|
||||
|
||||
if (m_currentStream == null)
|
||||
{
|
||||
if (!m_first)
|
||||
return 0;
|
||||
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
return 0;
|
||||
|
||||
m_first = false;
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
|
||||
int totalRead = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int numRead = m_currentStream.Read(buffer[totalRead..]);
|
||||
|
||||
if (numRead > 0)
|
||||
{
|
||||
totalRead += numRead;
|
||||
|
||||
if (totalRead == buffer.Length)
|
||||
return totalRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_padBits = m_currentParser.PadBits;
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
{
|
||||
m_currentStream = null;
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
if (m_currentStream == null)
|
||||
{
|
||||
if (!m_first)
|
||||
return -1;
|
||||
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
return -1;
|
||||
|
||||
m_first = false;
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int b = m_currentStream.ReadByte();
|
||||
|
||||
if (b >= 0)
|
||||
return b;
|
||||
|
||||
m_padBits = m_currentParser.PadBits;
|
||||
m_currentParser = GetNextParser();
|
||||
if (m_currentParser == null)
|
||||
{
|
||||
m_currentStream = null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_currentStream = m_currentParser.GetBitStream();
|
||||
}
|
||||
}
|
||||
|
||||
private Asn1BitStringParser GetNextParser()
|
||||
{
|
||||
IAsn1Convertible asn1Obj = m_parser.ReadObject();
|
||||
if (asn1Obj == null)
|
||||
{
|
||||
if (m_octetAligned && m_padBits != 0)
|
||||
throw new IOException("expected octet-aligned bitstring, but found padBits: " + m_padBits);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (asn1Obj is Asn1BitStringParser)
|
||||
{
|
||||
if (m_padBits != 0)
|
||||
throw new IOException("only the last nested bitstring can have padding");
|
||||
|
||||
return (Asn1BitStringParser)asn1Obj;
|
||||
}
|
||||
|
||||
throw new IOException("unknown object encountered: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(asn1Obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86bbb9386c084ce47a3672ac12a5afa1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal class ConstructedDLEncoding
|
||||
: IAsn1Encoding
|
||||
{
|
||||
private readonly int m_tagClass;
|
||||
private readonly int m_tagNo;
|
||||
private readonly IAsn1Encoding[] m_contentsElements;
|
||||
private readonly int m_contentsLength;
|
||||
|
||||
internal ConstructedDLEncoding(int tagClass, int tagNo, IAsn1Encoding[] contentsElements)
|
||||
{
|
||||
m_tagClass = tagClass;
|
||||
m_tagNo = tagNo;
|
||||
m_contentsElements = contentsElements;
|
||||
m_contentsLength = Asn1OutputStream.GetLengthOfContents(contentsElements);
|
||||
}
|
||||
|
||||
void IAsn1Encoding.Encode(Asn1OutputStream asn1Out)
|
||||
{
|
||||
asn1Out.WriteIdentifier(Asn1Tags.Constructed | m_tagClass, m_tagNo);
|
||||
asn1Out.WriteDL(m_contentsLength);
|
||||
asn1Out.EncodeContents(m_contentsElements);
|
||||
}
|
||||
|
||||
int IAsn1Encoding.GetLength()
|
||||
{
|
||||
return Asn1OutputStream.GetLengthOfIdentifier(m_tagNo)
|
||||
+ Asn1OutputStream.GetLengthOfDL(m_contentsLength)
|
||||
+ m_contentsLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95ca1443910ef7d48b13c585349fd261
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
|
||||
{
|
||||
internal class ConstructedILEncoding
|
||||
: IAsn1Encoding
|
||||
{
|
||||
private readonly int m_tagClass;
|
||||
private readonly int m_tagNo;
|
||||
private readonly IAsn1Encoding[] m_contentsElements;
|
||||
|
||||
internal ConstructedILEncoding(int tagClass, int tagNo, IAsn1Encoding[] contentsElements)
|
||||
{
|
||||
m_tagClass = tagClass;
|
||||
m_tagNo = tagNo;
|
||||
m_contentsElements = contentsElements;
|
||||
}
|
||||
|
||||
void IAsn1Encoding.Encode(Asn1OutputStream asn1Out)
|
||||
{
|
||||
asn1Out.WriteIdentifier(Asn1Tags.Constructed | m_tagClass, m_tagNo);
|
||||
asn1Out.WriteByte(0x80);
|
||||
asn1Out.EncodeContents(m_contentsElements);
|
||||
asn1Out.WriteByte(0x00);
|
||||
asn1Out.WriteByte(0x00);
|
||||
}
|
||||
|
||||
int IAsn1Encoding.GetLength()
|
||||
{
|
||||
return Asn1OutputStream.GetLengthOfIdentifier(m_tagNo)
|
||||
+ 3
|
||||
+ Asn1OutputStream.GetLengthOfContents(m_contentsElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user