DerOutputStream.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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.IO;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
  7. {
  8. public class DerOutputStream
  9. : FilterStream
  10. {
  11. public DerOutputStream(Stream os)
  12. : base(os)
  13. {
  14. }
  15. private void WriteLength(
  16. int length)
  17. {
  18. if (length > 127)
  19. {
  20. int size = 1;
  21. uint val = (uint)length;
  22. while ((val >>= 8) != 0)
  23. {
  24. size++;
  25. }
  26. WriteByte((byte)(size | 0x80));
  27. for (int i = (size - 1) * 8; i >= 0; i -= 8)
  28. {
  29. WriteByte((byte)(length >> i));
  30. }
  31. }
  32. else
  33. {
  34. WriteByte((byte)length);
  35. }
  36. }
  37. internal void WriteEncoded(
  38. int tag,
  39. byte[] bytes)
  40. {
  41. WriteByte((byte)tag);
  42. WriteLength(bytes.Length);
  43. Write(bytes, 0, bytes.Length);
  44. }
  45. internal void WriteEncoded(
  46. int tag,
  47. byte first,
  48. byte[] bytes)
  49. {
  50. WriteByte((byte)tag);
  51. WriteLength(bytes.Length + 1);
  52. WriteByte(first);
  53. Write(bytes, 0, bytes.Length);
  54. }
  55. internal void WriteEncoded(
  56. int tag,
  57. byte[] bytes,
  58. int offset,
  59. int length)
  60. {
  61. WriteByte((byte)tag);
  62. WriteLength(length);
  63. Write(bytes, offset, length);
  64. }
  65. internal void WriteTag(
  66. int flags,
  67. int tagNo)
  68. {
  69. if (tagNo < 31)
  70. {
  71. WriteByte((byte)(flags | tagNo));
  72. }
  73. else
  74. {
  75. WriteByte((byte)(flags | 0x1f));
  76. if (tagNo < 128)
  77. {
  78. WriteByte((byte)tagNo);
  79. }
  80. else
  81. {
  82. byte[] stack = new byte[5];
  83. int pos = stack.Length;
  84. stack[--pos] = (byte)(tagNo & 0x7F);
  85. do
  86. {
  87. tagNo >>= 7;
  88. stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
  89. }
  90. while (tagNo > 127);
  91. Write(stack, pos, stack.Length - pos);
  92. }
  93. }
  94. }
  95. internal void WriteEncoded(
  96. int flags,
  97. int tagNo,
  98. byte[] bytes)
  99. {
  100. WriteTag(flags, tagNo);
  101. WriteLength(bytes.Length);
  102. Write(bytes, 0, bytes.Length);
  103. }
  104. protected void WriteNull()
  105. {
  106. WriteByte(Asn1Tags.Null);
  107. WriteByte(0x00);
  108. }
  109. [Obsolete("Use version taking an Asn1Encodable arg instead")]
  110. public virtual void WriteObject(
  111. object obj)
  112. {
  113. if (obj == null)
  114. {
  115. WriteNull();
  116. }
  117. else if (obj is Asn1Object)
  118. {
  119. ((Asn1Object)obj).Encode(this);
  120. }
  121. else if (obj is Asn1Encodable)
  122. {
  123. ((Asn1Encodable)obj).ToAsn1Object().Encode(this);
  124. }
  125. else
  126. {
  127. throw new IOException("object not Asn1Object");
  128. }
  129. }
  130. public virtual void WriteObject(
  131. Asn1Encodable obj)
  132. {
  133. if (obj == null)
  134. {
  135. WriteNull();
  136. }
  137. else
  138. {
  139. obj.ToAsn1Object().Encode(this);
  140. }
  141. }
  142. public virtual void WriteObject(
  143. Asn1Object obj)
  144. {
  145. if (obj == null)
  146. {
  147. WriteNull();
  148. }
  149. else
  150. {
  151. obj.Encode(this);
  152. }
  153. }
  154. }
  155. }
  156. #pragma warning restore
  157. #endif