Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Asn1Util.cs 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. //+-------------------------------------------------------------------------------+
  2. //| Copyright (c) 2003 Liping Dai. All rights reserved. |
  3. //| Web: www.lipingshare.com |
  4. //| Email: lipingshare@yahoo.com |
  5. //| |
  6. //| Copyright and Permission Details: |
  7. //| ================================= |
  8. //| Permission is hereby granted, free of charge, to any person obtaining a copy |
  9. //| of this software and associated documentation files (the "Software"), to deal |
  10. //| in the Software without restriction, including without limitation the rights |
  11. //| to use, copy, modify, merge, publish, distribute, and/or sell copies of the |
  12. //| Software, subject to the following conditions: |
  13. //| |
  14. //| 1. Redistributions of source code must retain the above copyright notice, this|
  15. //| list of conditions and the following disclaimer. |
  16. //| |
  17. //| 2. Redistributions in binary form must reproduce the above copyright notice, |
  18. //| this list of conditions and the following disclaimer in the documentation |
  19. //| and/or other materials provided with the distribution. |
  20. //| |
  21. //| THE SOFTWARE PRODUCT IS PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, |
  22. //| EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
  23. //| WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR |
  24. //| A PARTICULAR PURPOSE. |
  25. //+-------------------------------------------------------------------------------+
  26. using System;
  27. using System.IO;
  28. using System.Text;
  29. using Microsoft.Win32;
  30. namespace LipingShare.LCLib.Asn1Processor
  31. {
  32. /// <summary>
  33. /// Utility functions.
  34. /// </summary>
  35. internal class Asn1Util
  36. {
  37. /// <summary>
  38. /// Check if the string is ASN.1 encoded hex string.
  39. /// </summary>
  40. /// <param name="dataStr">The string.</param>
  41. /// <returns>true:Yes, false:No.</returns>
  42. public static bool IsAsn1EncodedHexStr(string dataStr)
  43. {
  44. bool retval = false;
  45. try
  46. {
  47. byte[] data = HexStrToBytes(dataStr);
  48. if (data.Length > 0)
  49. {
  50. Asn1Node node = new Asn1Node();
  51. retval = node.LoadData(data);
  52. }
  53. }
  54. catch
  55. {
  56. retval = false;
  57. }
  58. return retval;
  59. }
  60. /// <summary>
  61. /// Format a string to have certain line length and character group length.
  62. /// Sample result FormatString(xstr,32,2):
  63. /// <code>07 AE 0B E7 84 5A D4 6C 6A BD DF 8F 89 88 9E F1</code>
  64. /// </summary>
  65. /// <param name="inStr">source string.</param>
  66. /// <param name="lineLen">line length.</param>
  67. /// <param name="groupLen">group length.</param>
  68. /// <returns></returns>
  69. public static string FormatString(string inStr, int lineLen, int groupLen)
  70. {
  71. char[] tmpCh = new char[inStr.Length * 2];
  72. int i, c = 0, linec = 0;
  73. int gc = 0;
  74. for (i = 0; i < inStr.Length; i++)
  75. {
  76. tmpCh[c++] = inStr[i];
  77. gc++;
  78. linec++;
  79. if (gc >= groupLen && groupLen > 0)
  80. {
  81. tmpCh[c++] = ' ';
  82. gc = 0;
  83. }
  84. if (linec >= lineLen)
  85. {
  86. tmpCh[c++] = '\r';
  87. tmpCh[c++] = '\n';
  88. linec = 0;
  89. }
  90. }
  91. string retval = new string(tmpCh);
  92. retval = retval.TrimEnd('\0');
  93. retval = retval.TrimEnd('\n');
  94. retval = retval.TrimEnd('\r');
  95. return retval;
  96. }
  97. /// <summary>
  98. /// Generate a string by duplicating <see cref="char"/> xch.
  99. /// </summary>
  100. /// <param name="len">duplicate times.</param>
  101. /// <param name="xch">the duplicated character.</param>
  102. /// <returns></returns>
  103. public static string GenStr(int len, char xch)
  104. {
  105. char[] ch = new char[len];
  106. for (int i = 0; i < len; i++)
  107. {
  108. ch[i] = xch;
  109. }
  110. return new string(ch);
  111. }
  112. /// <summary>
  113. /// Convert byte array to a <see cref="long"/> integer.
  114. /// </summary>
  115. /// <param name="bytes"></param>
  116. /// <returns></returns>
  117. public static long BytesToLong(byte[] bytes)
  118. {
  119. long tempInt = 0;
  120. for (int i = 0; i < bytes.Length; i++)
  121. {
  122. tempInt = tempInt << 8 | bytes[i];
  123. }
  124. return tempInt;
  125. }
  126. /// <summary>
  127. /// Convert a ASCII byte array to string, also filter out the null characters.
  128. /// </summary>
  129. /// <param name="bytes"></param>
  130. /// <returns></returns>
  131. public static string BytesToString(byte[] bytes)
  132. {
  133. string retval = "";
  134. if (bytes == null || bytes.Length < 1) return retval;
  135. char[] cretval = new char[bytes.Length];
  136. for (int i = 0, j = 0; i < bytes.Length; i++)
  137. {
  138. if (bytes[i] != '\0')
  139. {
  140. cretval[j++] = (char)bytes[i];
  141. }
  142. }
  143. retval = new string(cretval);
  144. retval = retval.TrimEnd('\0');
  145. return retval;
  146. }
  147. /// <summary>
  148. /// Convert ASCII string to byte array.
  149. /// </summary>
  150. /// <param name="msg"></param>
  151. /// <returns></returns>
  152. public static byte[] StringToBytes(string msg)
  153. {
  154. byte[] retval = new byte[msg.Length];
  155. for (int i = 0; i < msg.Length; i++)
  156. {
  157. retval[i] = (byte)msg[i];
  158. }
  159. return retval;
  160. }
  161. /// <summary>
  162. /// Compare source and target byte array.
  163. /// </summary>
  164. /// <param name="source"></param>
  165. /// <param name="target"></param>
  166. /// <returns></returns>
  167. public static bool IsEqual(byte[] source, byte[] target)
  168. {
  169. if (source == null) return false;
  170. if (target == null) return false;
  171. if (source.Length != target.Length) return false;
  172. for (int i = 0; i < source.Length; i++)
  173. {
  174. if (source[i] != target[i]) return false;
  175. }
  176. return true;
  177. }
  178. /// <summary>
  179. /// Constant hex digits array.
  180. /// </summary>
  181. static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7',
  182. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  183. /// <summary>
  184. /// Convert a byte array to hex string.
  185. /// </summary>
  186. /// <param name="bytes">source array.</param>
  187. /// <returns>hex string.</returns>
  188. public static string ToHexString(byte[] bytes)
  189. {
  190. if (bytes == null) return "";
  191. char[] chars = new char[bytes.Length * 2];
  192. int b, i;
  193. for (i = 0; i < bytes.Length; i++)
  194. {
  195. b = bytes[i];
  196. chars[i * 2] = hexDigits[b >> 4];
  197. chars[i * 2 + 1] = hexDigits[b & 0xF];
  198. }
  199. return new string(chars);
  200. }
  201. /// <summary>
  202. /// Check if the character is a valid hex digits.
  203. /// </summary>
  204. /// <param name="ch">source character.</param>
  205. /// <returns>true:Valid, false:Invalid.</returns>
  206. public static bool IsValidHexDigits(char ch)
  207. {
  208. bool retval = false;
  209. for (int i = 0; i < hexDigits.Length; i++)
  210. {
  211. if (hexDigits[i] == ch)
  212. {
  213. retval = true;
  214. break;
  215. }
  216. }
  217. return retval;
  218. }
  219. /// <summary>
  220. /// Get hex digits value.
  221. /// </summary>
  222. /// <param name="ch">source character.</param>
  223. /// <returns>hex digits value.</returns>
  224. public static byte GetHexDigitsVal(char ch)
  225. {
  226. byte retval = 0;
  227. for (int i = 0; i < hexDigits.Length; i++)
  228. {
  229. if (hexDigits[i] == ch)
  230. {
  231. retval = (byte)i;
  232. break;
  233. }
  234. }
  235. return retval;
  236. }
  237. /// <summary>
  238. /// Convert hex string to byte array.
  239. /// </summary>
  240. /// <param name="hexStr">Source hex string.</param>
  241. /// <returns>return byte array.</returns>
  242. public static byte[] HexStrToBytes(string hexStr)
  243. {
  244. hexStr = hexStr.Replace(" ", "");
  245. hexStr = hexStr.Replace("\r", "");
  246. hexStr = hexStr.Replace("\n", "");
  247. hexStr = hexStr.ToUpper();
  248. if ((hexStr.Length % 2) != 0) throw new Exception("Invalid Hex string: odd length.");
  249. int i;
  250. for (i = 0; i < hexStr.Length; i++)
  251. {
  252. if (!IsValidHexDigits(hexStr[i]))
  253. {
  254. throw new Exception("Invalid Hex string: included invalid character [" +
  255. hexStr[i] + "]");
  256. }
  257. }
  258. int bc = hexStr.Length / 2;
  259. byte[] retval = new byte[bc];
  260. int b1, b2, b;
  261. for (i = 0; i < bc; i++)
  262. {
  263. b1 = GetHexDigitsVal(hexStr[i * 2]);
  264. b2 = GetHexDigitsVal(hexStr[i * 2 + 1]);
  265. b = ((b1 << 4) | b2);
  266. retval[i] = (byte)b;
  267. }
  268. return retval;
  269. }
  270. /// <summary>
  271. /// Check if the source string is a valid hex string.
  272. /// </summary>
  273. /// <param name="hexStr">source string.</param>
  274. /// <returns>true:Valid, false:Invalid.</returns>
  275. public static bool IsHexStr(string hexStr)
  276. {
  277. byte[] bytes = null;
  278. try
  279. {
  280. bytes = HexStrToBytes(hexStr);
  281. }
  282. catch
  283. {
  284. return false;
  285. }
  286. if (bytes == null || bytes.Length < 0)
  287. {
  288. return false;
  289. }
  290. else
  291. {
  292. return true;
  293. }
  294. }
  295. private const string PemStartStr = "-----BEGIN";
  296. private const string PemEndStr = "-----END";
  297. /// <summary>
  298. /// Check if the source string is PEM formated string.
  299. /// </summary>
  300. /// <param name="pemStr">source string.</param>
  301. /// <returns>true:Valid, false:Invalid.</returns>
  302. public static bool IsPemFormated(string pemStr)
  303. {
  304. byte[] data = null;
  305. try
  306. {
  307. data = PemToBytes(pemStr);
  308. }
  309. catch
  310. {
  311. return false;
  312. }
  313. return (data.Length > 0);
  314. }
  315. /// <summary>
  316. /// Check if a file is PEM formated.
  317. /// </summary>
  318. /// <param name="fileName">source file name.</param>
  319. /// <returns>true:Yes, false:No.</returns>
  320. public static bool IsPemFormatedFile(string fileName)
  321. {
  322. bool retval = false;
  323. try
  324. {
  325. FileStream fs = new FileStream(fileName, System.IO.FileMode.Open);
  326. byte[] data = new byte[fs.Length];
  327. fs.Read(data, 0, data.Length);
  328. fs.Close();
  329. string dataStr = Asn1Util.BytesToString(data);
  330. retval = IsPemFormated(dataStr);
  331. }
  332. catch
  333. {
  334. retval = false;
  335. }
  336. return retval;
  337. }
  338. /// <summary>
  339. /// Convert PEM formated string into <see cref="Stream"/> and set the Stream position to 0.
  340. /// </summary>
  341. /// <param name="pemStr">source string.</param>
  342. /// <returns>output stream.</returns>
  343. public static Stream PemToStream(string pemStr)
  344. {
  345. byte[] bytes = PemToBytes(pemStr);
  346. MemoryStream retval = new MemoryStream(bytes);
  347. retval.Position = 0;
  348. return retval;
  349. }
  350. /// <summary>
  351. /// Convert PEM formated string into byte array.
  352. /// </summary>
  353. /// <param name="pemStr">source string.</param>
  354. /// <returns>output byte array.</returns>
  355. public static byte[] PemToBytes(string pemStr)
  356. {
  357. byte[] retval = null;
  358. string[] lines = pemStr.Split('\n');
  359. string base64Str = "";
  360. bool started = false, ended = false;
  361. string cline = "";
  362. for (int i = 0; i < lines.Length; i++)
  363. {
  364. cline = lines[i].ToUpper();
  365. if (cline == "") continue;
  366. if (cline.Length > PemStartStr.Length)
  367. {
  368. if (!started && cline.Substring(0, PemStartStr.Length) == PemStartStr)
  369. {
  370. started = true;
  371. continue;
  372. }
  373. }
  374. if (cline.Length > PemEndStr.Length)
  375. {
  376. if (cline.Substring(0, PemEndStr.Length) == PemEndStr)
  377. {
  378. ended = true;
  379. break;
  380. }
  381. }
  382. if (started)
  383. {
  384. base64Str += lines[i];
  385. }
  386. }
  387. if (!(started && ended))
  388. {
  389. throw new Exception("'BEGIN'/'END' line is missing.");
  390. }
  391. base64Str = base64Str.Replace("\r", "");
  392. base64Str = base64Str.Replace("\n", "");
  393. base64Str = base64Str.Replace("\n", " ");
  394. retval = Convert.FromBase64String(base64Str);
  395. return retval;
  396. }
  397. /// <summary>
  398. /// Convert byte array to PEM formated string.
  399. /// </summary>
  400. /// <param name="data"></param>
  401. /// <returns></returns>
  402. public static string BytesToPem(byte[] data)
  403. {
  404. return BytesToPem(data, "");
  405. }
  406. /// <summary>
  407. /// Retrieve PEM file heading.
  408. /// </summary>
  409. /// <param name="fileName">source file name.</param>
  410. /// <returns>heading string.</returns>
  411. public static string GetPemFileHeader(string fileName)
  412. {
  413. try
  414. {
  415. FileStream fs = new FileStream(fileName, FileMode.Open);
  416. byte[] data = new byte[fs.Length];
  417. fs.Read(data, 0, data.Length);
  418. fs.Close();
  419. string dataStr = Asn1Util.BytesToString(data);
  420. return GetPemHeader(dataStr);
  421. }
  422. catch
  423. {
  424. return "";
  425. }
  426. }
  427. /// <summary>
  428. /// Retrieve PEM heading from a PEM formated string.
  429. /// </summary>
  430. /// <param name="pemStr">source string.</param>
  431. /// <returns>heading string.</returns>
  432. public static string GetPemHeader(string pemStr)
  433. {
  434. string[] lines = pemStr.Split('\n');
  435. bool started = false;
  436. string cline = "";
  437. for (int i = 0; i < lines.Length; i++)
  438. {
  439. cline = lines[i].ToUpper().Replace("\r", "");
  440. if (cline == "") continue;
  441. if (cline.Length > PemStartStr.Length)
  442. {
  443. if (!started && cline.Substring(0, PemStartStr.Length) == PemStartStr)
  444. {
  445. started = true;
  446. string retstr = lines[i].Substring(PemStartStr.Length,
  447. lines[i].Length -
  448. PemStartStr.Length).Replace("-----", "");
  449. return retstr.Replace("\r", "");
  450. }
  451. }
  452. else
  453. {
  454. continue;
  455. }
  456. }
  457. return "";
  458. }
  459. /// <summary>
  460. /// Convert byte array to PEM formated string and set the heading as pemHeader.
  461. /// </summary>
  462. /// <param name="data">source array.</param>
  463. /// <param name="pemHeader">PEM heading.</param>
  464. /// <returns>PEM formated string.</returns>
  465. public static string BytesToPem(byte[] data, string pemHeader)
  466. {
  467. if (pemHeader == null || pemHeader.Length < 1)
  468. {
  469. pemHeader = "ASN.1 Editor Generated PEM File";
  470. }
  471. string retval = "";
  472. if (pemHeader.Length > 0 && pemHeader[0] != ' ')
  473. {
  474. pemHeader = " " + pemHeader;
  475. }
  476. retval = Convert.ToBase64String(data);
  477. retval = FormatString(retval, 64, 0);
  478. retval = "-----BEGIN" + pemHeader + "-----\r\n" +
  479. retval +
  480. "\r\n-----END" + pemHeader + "-----\r\n";
  481. return retval;
  482. }
  483. /// <summary>
  484. /// Calculate how many bits is enough to hold ivalue.
  485. /// </summary>
  486. /// <param name="ivalue">source value.</param>
  487. /// <returns>bits number.</returns>
  488. public static int BitPrecision(ulong ivalue)
  489. {
  490. if (ivalue == 0) return 0;
  491. int l = 0, h = 8 * 4; // 4: sizeof(ulong)
  492. while (h - l > 1)
  493. {
  494. int t = (int)(l + h) / 2;
  495. if ((ivalue >> t) != 0)
  496. l = t;
  497. else
  498. h = t;
  499. }
  500. return h;
  501. }
  502. /// <summary>
  503. /// Calculate how many bytes is enough to hold the value.
  504. /// </summary>
  505. /// <param name="value">input value.</param>
  506. /// <returns>bytes number.</returns>
  507. public static int BytePrecision(ulong value)
  508. {
  509. int i;
  510. for (i = 4; i > 0; --i) // 4: sizeof(ulong)
  511. if ((value >> (i - 1) * 8) != 0)
  512. break;
  513. return i;
  514. }
  515. /// <summary>
  516. /// ASN.1 DER length encoder.
  517. /// </summary>
  518. /// <param name="xdata">result output stream.</param>
  519. /// <param name="length">source length.</param>
  520. /// <returns>result bytes.</returns>
  521. public static int DERLengthEncode(Stream xdata, ulong length)
  522. {
  523. int i = 0;
  524. if (length <= 0x7f)
  525. {
  526. xdata.WriteByte((byte)length);
  527. i++;
  528. }
  529. else
  530. {
  531. xdata.WriteByte((byte)(BytePrecision(length) | 0x80));
  532. i++;
  533. for (int j = BytePrecision((ulong)length); j > 0; --j)
  534. {
  535. xdata.WriteByte((byte)(length >> (j - 1) * 8));
  536. i++;
  537. }
  538. }
  539. return i;
  540. }
  541. /// <summary>
  542. /// ASN.1 DER length decoder.
  543. /// </summary>
  544. /// <param name="bt">Source stream.</param>
  545. /// <param name="isIndefiniteLength">Output parameter.</param>
  546. /// <returns>Output length.</returns>
  547. public static long DerLengthDecode(Stream bt, ref bool isIndefiniteLength)
  548. {
  549. isIndefiniteLength = false;
  550. long length = 0;
  551. byte b;
  552. b = (byte)bt.ReadByte();
  553. if ((b & 0x80) == 0)
  554. {
  555. length = b;
  556. }
  557. else
  558. {
  559. long lengthBytes = b & 0x7f;
  560. if (lengthBytes == 0)
  561. {
  562. isIndefiniteLength = true;
  563. return -2; // Indefinite length.
  564. }
  565. length = 0;
  566. while (lengthBytes-- > 0)
  567. {
  568. if ((length >> (8 * (4 - 1))) > 0) // 4: sizeof(long)
  569. {
  570. return -1; // Length overflow.
  571. }
  572. b = (byte)bt.ReadByte();
  573. length = (length << 8) | b;
  574. }
  575. if (length <= 0x7f)
  576. {
  577. return -1; // Indicated false node
  578. }
  579. }
  580. return length;
  581. }
  582. /// <summary>
  583. /// Decode tag value to return tag name.
  584. /// </summary>
  585. /// <param name="tag">input tag.</param>
  586. /// <returns>tag name.</returns>
  587. static public string GetTagName(byte tag)
  588. {
  589. string retval = "";
  590. if ((tag & Asn1TagClasses.CLASS_MASK) != 0)
  591. {
  592. switch (tag & Asn1TagClasses.CLASS_MASK)
  593. {
  594. case Asn1TagClasses.CONTEXT_SPECIFIC:
  595. retval += "CONTEXT SPECIFIC (" + ((int)(tag & Asn1Tag.TAG_MASK)).ToString() + ")";
  596. break;
  597. case Asn1TagClasses.APPLICATION:
  598. retval += "APPLICATION (" + ((int)(tag & Asn1Tag.TAG_MASK)).ToString() + ")";
  599. break;
  600. case Asn1TagClasses.PRIVATE:
  601. retval += "PRIVATE (" + ((int)(tag & Asn1Tag.TAG_MASK)).ToString() + ")";
  602. break;
  603. case Asn1TagClasses.CONSTRUCTED:
  604. retval += "CONSTRUCTED (" + ((int)(tag & Asn1Tag.TAG_MASK)).ToString() + ")";
  605. break;
  606. case Asn1TagClasses.UNIVERSAL:
  607. retval += "UNIVERSAL (" + ((int)(tag & Asn1Tag.TAG_MASK)).ToString() + ")";
  608. break;
  609. }
  610. }
  611. else
  612. {
  613. switch (tag & Asn1Tag.TAG_MASK)
  614. {
  615. case Asn1Tag.BOOLEAN:
  616. retval += "BOOLEAN";
  617. break;
  618. case Asn1Tag.INTEGER:
  619. retval += "INTEGER";
  620. break;
  621. case Asn1Tag.BIT_STRING:
  622. retval += "BIT STRING";
  623. break;
  624. case Asn1Tag.OCTET_STRING:
  625. retval += "OCTET STRING";
  626. break;
  627. case Asn1Tag.TAG_NULL:
  628. retval += "NULL";
  629. break;
  630. case Asn1Tag.OBJECT_IDENTIFIER:
  631. retval += "OBJECT IDENTIFIER";
  632. break;
  633. case Asn1Tag.OBJECT_DESCRIPTOR:
  634. retval += "OBJECT DESCRIPTOR";
  635. break;
  636. case Asn1Tag.RELATIVE_OID:
  637. retval += "RELATIVE-OID";
  638. break;
  639. case Asn1Tag.EXTERNAL:
  640. retval += "EXTERNAL";
  641. break;
  642. case Asn1Tag.REAL:
  643. retval += "REAL";
  644. break;
  645. case Asn1Tag.ENUMERATED:
  646. retval += "ENUMERATED";
  647. break;
  648. case Asn1Tag.UTF8_STRING:
  649. retval += "UTF8 STRING";
  650. break;
  651. case (Asn1Tag.SEQUENCE):
  652. retval += "SEQUENCE";
  653. break;
  654. case (Asn1Tag.SET):
  655. retval += "SET";
  656. break;
  657. case Asn1Tag.NUMERIC_STRING:
  658. retval += "NUMERIC STRING";
  659. break;
  660. case Asn1Tag.PRINTABLE_STRING:
  661. retval += "PRINTABLE STRING";
  662. break;
  663. case Asn1Tag.T61_STRING:
  664. retval += "T61 STRING";
  665. break;
  666. case Asn1Tag.VIDEOTEXT_STRING:
  667. retval += "VIDEOTEXT STRING";
  668. break;
  669. case Asn1Tag.IA5_STRING:
  670. retval += "IA5 STRING";
  671. break;
  672. case Asn1Tag.UTC_TIME:
  673. retval += "UTC TIME";
  674. break;
  675. case Asn1Tag.GENERALIZED_TIME:
  676. retval += "GENERALIZED TIME";
  677. break;
  678. case Asn1Tag.GRAPHIC_STRING:
  679. retval += "GRAPHIC STRING";
  680. break;
  681. case Asn1Tag.VISIBLE_STRING:
  682. retval += "VISIBLE STRING";
  683. break;
  684. case Asn1Tag.GENERAL_STRING:
  685. retval += "GENERAL STRING";
  686. break;
  687. case Asn1Tag.UNIVERSAL_STRING:
  688. retval += "UNIVERSAL STRING";
  689. break;
  690. case Asn1Tag.BMPSTRING:
  691. retval += "BMP STRING";
  692. break;
  693. default:
  694. retval += "UNKNOWN TAG";
  695. break;
  696. };
  697. }
  698. return retval;
  699. }
  700. #if UNITYIAP_DISABLED
  701. /// <summary>
  702. /// Read registry information from local machine entrys.
  703. /// </summary>
  704. /// <param name="path"></param>
  705. /// <param name="name"></param>
  706. /// <returns></returns>
  707. static public object ReadRegInfo(string path, string name)
  708. {
  709. object retval = null;
  710. Microsoft.Win32.RegistryKey regKey;
  711. regKey = Registry.LocalMachine.OpenSubKey(path, false);
  712. if (regKey!=null)
  713. {
  714. retval = regKey.GetValue(name);
  715. }
  716. return retval;
  717. }
  718. /// <summary>
  719. /// Write information into local machine registry entry.
  720. /// </summary>
  721. /// <param name="path"></param>
  722. /// <param name="name"></param>
  723. /// <param name="data"></param>
  724. static public void WriteRegInfo(string path, string name, object data)
  725. {
  726. Microsoft.Win32.RegistryKey regKey;
  727. regKey = Registry.LocalMachine.OpenSubKey(path, true);
  728. if (regKey == null)
  729. {
  730. regKey = Registry.LocalMachine.CreateSubKey(path);
  731. }
  732. if (regKey != null)
  733. {
  734. regKey.SetValue(name, data);
  735. }
  736. }
  737. #endif
  738. /// <summary>
  739. /// Constructor.
  740. /// </summary>
  741. private Asn1Util()
  742. {
  743. //Private constructor.
  744. }
  745. }
  746. }