Asn1Dump.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using System.Text;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
  7. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Utilities
  8. {
  9. public static class Asn1Dump
  10. {
  11. private const string Tab = " ";
  12. private const int SampleSize = 32;
  13. /**
  14. * dump a Der object as a formatted string with indentation
  15. *
  16. * @param obj the Asn1Object to be dumped out.
  17. */
  18. private static void AsString(string indent, bool verbose, Asn1Object obj, StringBuilder buf)
  19. {
  20. if (obj is Asn1Null)
  21. {
  22. buf.Append(indent);
  23. buf.AppendLine("NULL");
  24. }
  25. else if (obj is Asn1Sequence asn1Sequence)
  26. {
  27. buf.Append(indent);
  28. if (asn1Sequence is BerSequence)
  29. {
  30. buf.AppendLine("BER Sequence");
  31. }
  32. else if (!(asn1Sequence is DLSequence))
  33. {
  34. buf.AppendLine("DER Sequence");
  35. }
  36. else
  37. {
  38. buf.AppendLine("Sequence");
  39. }
  40. string elementsIndent = indent + Tab;
  41. for (int i = 0, count = asn1Sequence.Count; i < count; ++i)
  42. {
  43. AsString(elementsIndent, verbose, asn1Sequence[i].ToAsn1Object(), buf);
  44. }
  45. }
  46. else if (obj is Asn1Set asn1Set)
  47. {
  48. buf.Append(indent);
  49. if (asn1Set is BerSet)
  50. {
  51. buf.AppendLine("BER Set");
  52. }
  53. else if (!(asn1Set is DLSet))
  54. {
  55. buf.AppendLine("DER Set");
  56. }
  57. else
  58. {
  59. buf.AppendLine("Set");
  60. }
  61. string elementsIndent = indent + Tab;
  62. for (int i = 0, count = asn1Set.Count; i < count; ++i)
  63. {
  64. AsString(elementsIndent, verbose, asn1Set[i].ToAsn1Object(), buf);
  65. }
  66. }
  67. else if (obj is Asn1TaggedObject taggedObject)
  68. {
  69. buf.Append(indent);
  70. if (taggedObject is BerTaggedObject)
  71. {
  72. buf.Append("BER Tagged ");
  73. }
  74. else if (!(taggedObject is DLTaggedObject))
  75. {
  76. buf.Append("DER Tagged ");
  77. }
  78. else
  79. {
  80. buf.Append("Tagged ");
  81. }
  82. buf.Append(Asn1Utilities.GetTagText(taggedObject));
  83. if (!taggedObject.IsExplicit())
  84. {
  85. buf.Append(" IMPLICIT ");
  86. }
  87. buf.AppendLine();
  88. string baseIndent = indent + Tab;
  89. AsString(baseIndent, verbose, taggedObject.GetBaseObject().ToAsn1Object(), buf);
  90. }
  91. else if (obj is DerObjectIdentifier oid)
  92. {
  93. buf.Append(indent);
  94. buf.AppendLine("ObjectIdentifier(" + oid.Id + ")");
  95. }
  96. else if (obj is Asn1RelativeOid relativeOid)
  97. {
  98. buf.Append(indent);
  99. buf.AppendLine("RelativeOID(" + relativeOid.Id + ")");
  100. }
  101. else if (obj is DerBoolean derBoolean)
  102. {
  103. buf.Append(indent);
  104. buf.AppendLine("Boolean(" + derBoolean.IsTrue + ")");
  105. }
  106. else if (obj is DerInteger derInteger)
  107. {
  108. buf.Append(indent);
  109. buf.AppendLine("Integer(" + derInteger.Value + ")");
  110. }
  111. else if (obj is Asn1OctetString oct)
  112. {
  113. byte[] octets = oct.GetOctets();
  114. buf.Append(indent);
  115. if (obj is BerOctetString)
  116. {
  117. buf.AppendLine("BER Octet String[" + octets.Length + "]");
  118. }
  119. else
  120. {
  121. buf.AppendLine("DER Octet String[" + octets.Length + "]");
  122. }
  123. if (verbose)
  124. {
  125. DumpBinaryDataAsString(buf, indent, octets);
  126. }
  127. }
  128. else if (obj is DerBitString bitString)
  129. {
  130. byte[] bytes = bitString.GetBytes();
  131. int padBits = bitString.PadBits;
  132. buf.Append(indent);
  133. if (bitString is BerBitString)
  134. {
  135. buf.AppendLine("BER Bit String[" + bytes.Length + ", " + padBits + "]");
  136. }
  137. else if (bitString is DLBitString)
  138. {
  139. buf.AppendLine("DL Bit String[" + bytes.Length + ", " + padBits + "]");
  140. }
  141. else
  142. {
  143. buf.AppendLine("DER Bit String[" + bytes.Length + ", " + padBits + "]");
  144. }
  145. if (verbose)
  146. {
  147. DumpBinaryDataAsString(buf, indent, bytes);
  148. }
  149. }
  150. else if (obj is DerIA5String ia5String)
  151. {
  152. buf.Append(indent);
  153. buf.AppendLine("IA5String(" + ia5String.GetString() + ")");
  154. }
  155. else if (obj is DerUtf8String utf8String)
  156. {
  157. buf.Append(indent);
  158. buf.AppendLine("UTF8String(" + utf8String.GetString() + ")");
  159. }
  160. else if (obj is DerPrintableString printableString)
  161. {
  162. buf.Append(indent);
  163. buf.AppendLine("PrintableString(" + printableString.GetString() + ")");
  164. }
  165. else if (obj is DerVisibleString visibleString)
  166. {
  167. buf.Append(indent);
  168. buf.AppendLine("VisibleString(" + visibleString.GetString() + ")");
  169. }
  170. else if (obj is DerBmpString bmpString)
  171. {
  172. buf.Append(indent);
  173. buf.AppendLine("BMPString(" + bmpString.GetString() + ")");
  174. }
  175. else if (obj is DerT61String t61String)
  176. {
  177. buf.Append(indent);
  178. buf.AppendLine("T61String(" + t61String.GetString() + ")");
  179. }
  180. else if (obj is DerGraphicString graphicString)
  181. {
  182. buf.Append(indent);
  183. buf.AppendLine("GraphicString(" + graphicString.GetString() + ")");
  184. }
  185. else if (obj is DerVideotexString videotexString)
  186. {
  187. buf.Append(indent);
  188. buf.AppendLine("VideotexString(" + videotexString.GetString() + ")");
  189. }
  190. else if (obj is Asn1UtcTime utcTime)
  191. {
  192. buf.Append(indent);
  193. buf.AppendLine("UTCTime(" + utcTime.TimeString + ")");
  194. }
  195. else if (obj is Asn1GeneralizedTime generalizedTime)
  196. {
  197. buf.Append(indent);
  198. buf.AppendLine("GeneralizedTime(" + generalizedTime.TimeString + ")");
  199. }
  200. else if (obj is DerEnumerated en)
  201. {
  202. buf.Append(indent);
  203. buf.AppendLine("DER Enumerated(" + en.Value + ")");
  204. }
  205. else if (obj is DerExternal ext)
  206. {
  207. buf.Append(indent);
  208. buf.AppendLine("External ");
  209. string tab = indent + Tab;
  210. if (ext.DirectReference != null)
  211. {
  212. buf.Append(tab);
  213. buf.AppendLine("Direct Reference: " + ext.DirectReference.Id);
  214. }
  215. if (ext.IndirectReference != null)
  216. {
  217. buf.Append(tab);
  218. buf.AppendLine("Indirect Reference: " + ext.IndirectReference.ToString());
  219. }
  220. if (ext.DataValueDescriptor != null)
  221. {
  222. AsString(tab, verbose, ext.DataValueDescriptor, buf);
  223. }
  224. buf.Append(tab);
  225. buf.AppendLine("Encoding: " + ext.Encoding);
  226. AsString(tab, verbose, ext.ExternalContent, buf);
  227. }
  228. else
  229. {
  230. buf.Append(indent);
  231. buf.Append(obj);
  232. buf.AppendLine();
  233. }
  234. }
  235. /// <summary>Parse ASN.1 objects from input <see cref="Stream"/>, and write them to the output.</summary>
  236. public static void Dump(Stream input, TextWriter output)
  237. {
  238. Asn1InputStream asn1InputStream = new Asn1InputStream(input);
  239. Asn1Object asn1Object;
  240. while ((asn1Object = asn1InputStream.ReadObject()) != null)
  241. {
  242. output.Write(DumpAsString(asn1Object));
  243. }
  244. }
  245. /**
  246. * dump out a DER object as a formatted string, in non-verbose mode
  247. *
  248. * @param obj the Asn1Encodable to be dumped out.
  249. * @return the resulting string.
  250. */
  251. public static string DumpAsString(Asn1Encodable obj)
  252. {
  253. return DumpAsString(obj, false);
  254. }
  255. /**
  256. * Dump out the object as a string
  257. *
  258. * @param obj the Asn1Encodable to be dumped out.
  259. * @param verbose if true, dump out the contents of octet and bit strings.
  260. * @return the resulting string.
  261. */
  262. public static string DumpAsString(Asn1Encodable obj, bool verbose)
  263. {
  264. StringBuilder buf = new StringBuilder();
  265. AsString("", verbose, obj.ToAsn1Object(), buf);
  266. return buf.ToString();
  267. }
  268. private static void DumpBinaryDataAsString(StringBuilder buf, string indent, byte[] bytes)
  269. {
  270. if (bytes.Length < 1)
  271. return;
  272. indent += Tab;
  273. for (int i = 0; i < bytes.Length; i += SampleSize)
  274. {
  275. int remaining = bytes.Length - i;
  276. int chunk = System.Math.Min(remaining, SampleSize);
  277. buf.Append(indent);
  278. buf.Append(Hex.ToHexString(bytes, i, chunk));
  279. for (int j = chunk; j < SampleSize; ++j)
  280. {
  281. buf.Append(" ");
  282. }
  283. buf.Append(Tab);
  284. AppendAscString(buf, bytes, i, chunk);
  285. buf.AppendLine();
  286. }
  287. }
  288. private static void AppendAscString(StringBuilder buf, byte[] bytes, int off, int len)
  289. {
  290. for (int i = off; i != off + len; i++)
  291. {
  292. char c = (char)bytes[i];
  293. if (c >= ' ' && c <= '~')
  294. {
  295. buf.Append(c);
  296. }
  297. }
  298. }
  299. }
  300. }
  301. #pragma warning restore
  302. #endif