DERExternal.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
  7. {
  8. /**
  9. * Class representing the DER-type External
  10. */
  11. public class DerExternal
  12. : Asn1Object
  13. {
  14. private DerObjectIdentifier directReference;
  15. private DerInteger indirectReference;
  16. private Asn1Object dataValueDescriptor;
  17. private int encoding;
  18. private Asn1Object externalContent;
  19. public DerExternal(
  20. Asn1EncodableVector vector)
  21. {
  22. int offset = 0;
  23. Asn1Object enc = GetObjFromVector(vector, offset);
  24. if (enc is DerObjectIdentifier)
  25. {
  26. directReference = (DerObjectIdentifier)enc;
  27. offset++;
  28. enc = GetObjFromVector(vector, offset);
  29. }
  30. if (enc is DerInteger)
  31. {
  32. indirectReference = (DerInteger) enc;
  33. offset++;
  34. enc = GetObjFromVector(vector, offset);
  35. }
  36. if (!(enc is Asn1TaggedObject))
  37. {
  38. dataValueDescriptor = enc;
  39. offset++;
  40. enc = GetObjFromVector(vector, offset);
  41. }
  42. if (vector.Count != offset + 1)
  43. throw new ArgumentException("input vector too large", "vector");
  44. if (!(enc is Asn1TaggedObject))
  45. throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector");
  46. Asn1TaggedObject obj = (Asn1TaggedObject)enc;
  47. // Use property accessor to include check on value
  48. Encoding = obj.TagNo;
  49. if (encoding < 0 || encoding > 2)
  50. throw new InvalidOperationException("invalid encoding value");
  51. externalContent = obj.GetObject();
  52. }
  53. /**
  54. * Creates a new instance of DerExternal
  55. * See X.690 for more informations about the meaning of these parameters
  56. * @param directReference The direct reference or <code>null</code> if not set.
  57. * @param indirectReference The indirect reference or <code>null</code> if not set.
  58. * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
  59. * @param externalData The external data in its encoded form.
  60. */
  61. public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData)
  62. : this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object())
  63. {
  64. }
  65. /**
  66. * Creates a new instance of DerExternal.
  67. * See X.690 for more informations about the meaning of these parameters
  68. * @param directReference The direct reference or <code>null</code> if not set.
  69. * @param indirectReference The indirect reference or <code>null</code> if not set.
  70. * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
  71. * @param encoding The encoding to be used for the external data
  72. * @param externalData The external data
  73. */
  74. public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData)
  75. {
  76. DirectReference = directReference;
  77. IndirectReference = indirectReference;
  78. DataValueDescriptor = dataValueDescriptor;
  79. Encoding = encoding;
  80. ExternalContent = externalData.ToAsn1Object();
  81. }
  82. internal override void Encode(DerOutputStream derOut)
  83. {
  84. MemoryStream ms = new MemoryStream();
  85. WriteEncodable(ms, directReference);
  86. WriteEncodable(ms, indirectReference);
  87. WriteEncodable(ms, dataValueDescriptor);
  88. WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent));
  89. derOut.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray());
  90. }
  91. protected override int Asn1GetHashCode()
  92. {
  93. int ret = externalContent.GetHashCode();
  94. if (directReference != null)
  95. {
  96. ret ^= directReference.GetHashCode();
  97. }
  98. if (indirectReference != null)
  99. {
  100. ret ^= indirectReference.GetHashCode();
  101. }
  102. if (dataValueDescriptor != null)
  103. {
  104. ret ^= dataValueDescriptor.GetHashCode();
  105. }
  106. return ret;
  107. }
  108. protected override bool Asn1Equals(
  109. Asn1Object asn1Object)
  110. {
  111. if (this == asn1Object)
  112. return true;
  113. DerExternal other = asn1Object as DerExternal;
  114. if (other == null)
  115. return false;
  116. return BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Equals(directReference, other.directReference)
  117. && BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Equals(indirectReference, other.indirectReference)
  118. && BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Equals(dataValueDescriptor, other.dataValueDescriptor)
  119. && externalContent.Equals(other.externalContent);
  120. }
  121. public Asn1Object DataValueDescriptor
  122. {
  123. get { return dataValueDescriptor; }
  124. set { this.dataValueDescriptor = value; }
  125. }
  126. public DerObjectIdentifier DirectReference
  127. {
  128. get { return directReference; }
  129. set { this.directReference = value; }
  130. }
  131. /**
  132. * The encoding of the content. Valid values are
  133. * <ul>
  134. * <li><code>0</code> single-ASN1-type</li>
  135. * <li><code>1</code> OCTET STRING</li>
  136. * <li><code>2</code> BIT STRING</li>
  137. * </ul>
  138. */
  139. public int Encoding
  140. {
  141. get
  142. {
  143. return encoding;
  144. }
  145. set
  146. {
  147. if (encoding < 0 || encoding > 2)
  148. throw new InvalidOperationException("invalid encoding value: " + encoding);
  149. this.encoding = value;
  150. }
  151. }
  152. public Asn1Object ExternalContent
  153. {
  154. get { return externalContent; }
  155. set { this.externalContent = value; }
  156. }
  157. public DerInteger IndirectReference
  158. {
  159. get { return indirectReference; }
  160. set { this.indirectReference = value; }
  161. }
  162. private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index)
  163. {
  164. if (v.Count <= index)
  165. throw new ArgumentException("too few objects in input vector", "v");
  166. return v[index].ToAsn1Object();
  167. }
  168. private static void WriteEncodable(MemoryStream ms, Asn1Encodable e)
  169. {
  170. if (e != null)
  171. {
  172. byte[] bs = e.GetDerEncoded();
  173. ms.Write(bs, 0, bs.Length);
  174. }
  175. }
  176. }
  177. }
  178. #pragma warning restore
  179. #endif