DerOutputStream.cs 2.8 KB

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