IetfUtilities.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
  8. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X500.Style
  9. {
  10. public abstract class IetfUtilities
  11. {
  12. public static string ValueToString(Asn1Encodable value)
  13. {
  14. StringBuilder vBuf = new StringBuilder();
  15. if (value is IAsn1String && !(value is DerUniversalString))
  16. {
  17. string v = ((IAsn1String)value).GetString();
  18. if (v.Length > 0 && v[0] == '#')
  19. {
  20. vBuf.Append('\\');
  21. }
  22. vBuf.Append(v);
  23. }
  24. else
  25. {
  26. try
  27. {
  28. vBuf.Append('#');
  29. vBuf.Append(Hex.ToHexString(value.ToAsn1Object().GetEncoded(Asn1Encodable.Der)));
  30. }
  31. catch (IOException e)
  32. {
  33. throw new ArgumentException("Other value has no encoded form", e);
  34. }
  35. }
  36. int end = vBuf.Length;
  37. int index = 0;
  38. if (vBuf.Length >= 2 && vBuf[0] == '\\' && vBuf[1] == '#')
  39. {
  40. index += 2;
  41. }
  42. while (index != end)
  43. {
  44. switch (vBuf[index])
  45. {
  46. case ',':
  47. case '"':
  48. case '\\':
  49. case '+':
  50. case '=':
  51. case '<':
  52. case '>':
  53. case ';':
  54. {
  55. vBuf.Insert(index, "\\");
  56. index += 2;
  57. ++end;
  58. break;
  59. }
  60. default:
  61. {
  62. ++index;
  63. break;
  64. }
  65. }
  66. }
  67. int start = 0;
  68. if (vBuf.Length > 0)
  69. {
  70. while (vBuf.Length > start && vBuf[start] == ' ')
  71. {
  72. vBuf.Insert(start, "\\");
  73. start += 2;
  74. }
  75. }
  76. int endBuf = vBuf.Length - 1;
  77. while (endBuf >= 0 && vBuf[endBuf] == ' ')
  78. {
  79. vBuf.Insert(endBuf, "\\");
  80. endBuf--;
  81. }
  82. return vBuf.ToString();
  83. }
  84. public static string Canonicalize(string s)
  85. {
  86. string value = s.ToLowerInvariant();
  87. if (value.Length > 0 && value[0] == '#')
  88. {
  89. Asn1Object obj = DecodeObject(value);
  90. if (obj is IAsn1String str)
  91. {
  92. value = str.GetString().ToLowerInvariant();
  93. }
  94. }
  95. if (value.Length > 1)
  96. {
  97. int start = 0;
  98. while (start + 1 < value.Length && value[start] == '\\' && value[start + 1] == ' ')
  99. {
  100. start += 2;
  101. }
  102. int end = value.Length - 1;
  103. while (end - 1 > 0 && value[end - 1] == '\\' && value[end] == ' ')
  104. {
  105. end -= 2;
  106. }
  107. if (start > 0 || end < value.Length - 1)
  108. {
  109. value = value.Substring(start, end + 1 - start);
  110. }
  111. }
  112. return StripInternalSpaces(value);
  113. }
  114. public static string CanonicalString(Asn1Encodable value)
  115. {
  116. return Canonicalize(ValueToString(value));
  117. }
  118. private static Asn1Object DecodeObject(string oValue)
  119. {
  120. try
  121. {
  122. return Asn1Object.FromByteArray(Hex.DecodeStrict(oValue, 1, oValue.Length - 1));
  123. }
  124. catch (IOException e)
  125. {
  126. throw new InvalidOperationException("unknown encoding in name: " + e);
  127. }
  128. }
  129. public static string StripInternalSpaces(string str)
  130. {
  131. if (str.IndexOf(" ") < 0)
  132. return str;
  133. StringBuilder res = new StringBuilder();
  134. char c1 = str[0];
  135. res.Append(c1);
  136. for (int k = 1; k < str.Length; k++)
  137. {
  138. char c2 = str[k];
  139. if (!(' ' == c1 && ' ' == c2))
  140. {
  141. res.Append(c2);
  142. c1 = c2;
  143. }
  144. }
  145. return res.ToString();
  146. }
  147. public static bool RdnAreEqual(Rdn rdn1, Rdn rdn2)
  148. {
  149. if (rdn1.Count != rdn2.Count)
  150. return false;
  151. AttributeTypeAndValue[] atvs1 = rdn1.GetTypesAndValues();
  152. AttributeTypeAndValue[] atvs2 = rdn2.GetTypesAndValues();
  153. if (atvs1.Length != atvs2.Length)
  154. return false;
  155. for (int i = 0; i != atvs1.Length; i++)
  156. {
  157. if (!AtvAreEqual(atvs1[i], atvs2[i]))
  158. return false;
  159. }
  160. return true;
  161. }
  162. private static bool AtvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2)
  163. {
  164. if (atv1 == atv2)
  165. return true;
  166. if (null == atv1 || null == atv2)
  167. return false;
  168. DerObjectIdentifier o1 = atv1.Type;
  169. DerObjectIdentifier o2 = atv2.Type;
  170. if (!o1.Equals(o2))
  171. return false;
  172. string v1 = CanonicalString(atv1.Value);
  173. string v2 = CanonicalString(atv2.Value);
  174. if (!v1.Equals(v2))
  175. return false;
  176. return true;
  177. }
  178. }
  179. }
  180. #pragma warning restore
  181. #endif