DERExternal.cs 5.7 KB

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