123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- using System.IO;
- using Org.BouncyCastle.Utilities;
- namespace Org.BouncyCastle.Asn1
- {
- /**
- * Base class for an application specific object
- */
- public class DerApplicationSpecific
- : Asn1Object
- {
- private readonly bool isConstructed;
- private readonly int tag;
- private readonly byte[] octets;
- internal DerApplicationSpecific(
- bool isConstructed,
- int tag,
- byte[] octets)
- {
- this.isConstructed = isConstructed;
- this.tag = tag;
- this.octets = octets;
- }
- public DerApplicationSpecific(
- int tag,
- byte[] octets)
- : this(false, tag, octets)
- {
- }
- public DerApplicationSpecific(
- int tag,
- Asn1Encodable obj)
- : this(true, tag, obj)
- {
- }
- public DerApplicationSpecific(
- bool isExplicit,
- int tag,
- Asn1Encodable obj)
- {
- Asn1Object asn1Obj = obj.ToAsn1Object();
- byte[] data = asn1Obj.GetDerEncoded();
- this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj);
- this.tag = tag;
- if (isExplicit)
- {
- this.octets = data;
- }
- else
- {
- int lenBytes = GetLengthOfHeader(data);
- byte[] tmp = new byte[data.Length - lenBytes];
- Array.Copy(data, lenBytes, tmp, 0, tmp.Length);
- this.octets = tmp;
- }
- }
- public DerApplicationSpecific(
- int tagNo,
- Asn1EncodableVector vec)
- {
- this.tag = tagNo;
- this.isConstructed = true;
- MemoryStream bOut = new MemoryStream();
- for (int i = 0; i != vec.Count; i++)
- {
- try
- {
- byte[] bs = vec[i].GetDerEncoded();
- bOut.Write(bs, 0, bs.Length);
- }
- catch (IOException e)
- {
- throw new InvalidOperationException("malformed object", e);
- }
- }
- this.octets = bOut.ToArray();
- }
- private int GetLengthOfHeader(
- byte[] data)
- {
- int length = data[1]; // TODO: assumes 1 byte tag
- if (length == 0x80)
- {
- return 2; // indefinite-length encoding
- }
- if (length > 127)
- {
- int size = length & 0x7f;
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
- {
- throw new InvalidOperationException("DER length more than 4 bytes: " + size);
- }
- return size + 2;
- }
- return 2;
- }
- public bool IsConstructed()
- {
- return isConstructed;
- }
- public byte[] GetContents()
- {
- return octets;
- }
- public int ApplicationTag
- {
- get { return tag; }
- }
- /**
- * Return the enclosed object assuming explicit tagging.
- *
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public Asn1Object GetObject()
- {
- return FromByteArray(GetContents());
- }
- /**
- * Return the enclosed object assuming implicit tagging.
- *
- * @param derTagNo the type tag that should be applied to the object's contents.
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public Asn1Object GetObject(
- int derTagNo)
- {
- if (derTagNo >= 0x1f)
- throw new IOException("unsupported tag number");
- byte[] orig = this.GetEncoded();
- byte[] tmp = ReplaceTagNumber(derTagNo, orig);
- if ((orig[0] & Asn1Tags.Constructed) != 0)
- {
- tmp[0] |= Asn1Tags.Constructed;
- }
- return FromByteArray(tmp);
- }
- internal override void Encode(
- DerOutputStream derOut)
- {
- int classBits = Asn1Tags.Application;
- if (isConstructed)
- {
- classBits |= Asn1Tags.Constructed;
- }
- derOut.WriteEncoded(classBits, tag, octets);
- }
- protected override bool Asn1Equals(
- Asn1Object asn1Object)
- {
- DerApplicationSpecific other = asn1Object as DerApplicationSpecific;
- if (other == null)
- return false;
- return this.isConstructed == other.isConstructed
- && this.tag == other.tag
- && Arrays.AreEqual(this.octets, other.octets);
- }
- protected override int Asn1GetHashCode()
- {
- return isConstructed.GetHashCode() ^ tag.GetHashCode() ^ Arrays.GetHashCode(octets);
- }
- private byte[] ReplaceTagNumber(
- int newTag,
- byte[] input)
- {
- int tagNo = input[0] & 0x1f;
- int index = 1;
- //
- // with tagged object tag number is bottom 5 bits, or stored at the start of the content
- //
- if (tagNo == 0x1f)
- {
- tagNo = 0;
- int b = input[index++] & 0xff;
- // X.690-0207 8.1.2.4.2
- // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
- {
- throw new InvalidOperationException("corrupted stream - invalid high tag number found");
- }
- while ((b >= 0) && ((b & 0x80) != 0))
- {
- tagNo |= (b & 0x7f);
- tagNo <<= 7;
- b = input[index++] & 0xff;
- }
- tagNo |= (b & 0x7f);
- }
- byte[] tmp = new byte[input.Length - index + 1];
- Array.Copy(input, index, tmp, 1, tmp.Length - 1);
- tmp[0] = (byte)newTag;
- return tmp;
- }
- }
- }
- #endif
|