BEROctetStringGenerator.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  6. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1
  7. {
  8. public class BerOctetStringGenerator
  9. : BerGenerator
  10. {
  11. public BerOctetStringGenerator(Stream outStream)
  12. : base(outStream)
  13. {
  14. WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
  15. }
  16. public BerOctetStringGenerator(
  17. Stream outStream,
  18. int tagNo,
  19. bool isExplicit)
  20. : base(outStream, tagNo, isExplicit)
  21. {
  22. WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
  23. }
  24. public Stream GetOctetOutputStream()
  25. {
  26. return GetOctetOutputStream(new byte[1000]); // limit for CER encoding.
  27. }
  28. public Stream GetOctetOutputStream(
  29. int bufSize)
  30. {
  31. return bufSize < 1
  32. ? GetOctetOutputStream()
  33. : GetOctetOutputStream(new byte[bufSize]);
  34. }
  35. public Stream GetOctetOutputStream(
  36. byte[] buf)
  37. {
  38. return new BufferedBerOctetStream(this, buf);
  39. }
  40. private class BufferedBerOctetStream
  41. : BaseOutputStream
  42. {
  43. private byte[] _buf;
  44. private int _off;
  45. private readonly BerOctetStringGenerator _gen;
  46. private readonly Asn1OutputStream _derOut;
  47. internal BufferedBerOctetStream(
  48. BerOctetStringGenerator gen,
  49. byte[] buf)
  50. {
  51. _gen = gen;
  52. _buf = buf;
  53. _off = 0;
  54. _derOut = Asn1OutputStream.Create(_gen.Out, Asn1Encodable.Der);
  55. }
  56. public override void Write(byte[] buffer, int offset, int count)
  57. {
  58. Streams.ValidateBufferArguments(buffer, offset, count);
  59. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  60. Write(buffer.AsSpan(offset, count));
  61. #else
  62. int bufLen = _buf.Length;
  63. int available = bufLen - _off;
  64. if (count < available)
  65. {
  66. Array.Copy(buffer, offset, _buf, _off, count);
  67. _off += count;
  68. return;
  69. }
  70. int pos = 0;
  71. if (_off > 0)
  72. {
  73. Array.Copy(buffer, offset, _buf, _off, available);
  74. pos = available;
  75. DerOctetString.Encode(_derOut, _buf, 0, bufLen);
  76. //_off = 0;
  77. }
  78. int remaining;
  79. while ((remaining = count - pos) >= bufLen)
  80. {
  81. DerOctetString.Encode(_derOut, buffer, offset + pos, bufLen);
  82. pos += bufLen;
  83. }
  84. Array.Copy(buffer, offset + pos, _buf, 0, remaining);
  85. this._off = remaining;
  86. #endif
  87. }
  88. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  89. public override void Write(ReadOnlySpan<byte> buffer)
  90. {
  91. int bufLen = _buf.Length;
  92. int available = bufLen - _off;
  93. if (buffer.Length < available)
  94. {
  95. buffer.CopyTo(_buf.AsSpan(_off));
  96. _off += buffer.Length;
  97. return;
  98. }
  99. if (_off > 0)
  100. {
  101. DerOctetString.Encode(_derOut, _buf.AsSpan(0, _off), buffer[..available]);
  102. buffer = buffer[available..];
  103. //_off = 0;
  104. }
  105. while (buffer.Length >= bufLen)
  106. {
  107. DerOctetString.Encode(_derOut, buffer[..bufLen]);
  108. buffer = buffer[bufLen..];
  109. }
  110. buffer.CopyTo(_buf.AsSpan());
  111. _off = buffer.Length;
  112. }
  113. #endif
  114. public override void WriteByte(byte value)
  115. {
  116. _buf[_off++] = value;
  117. if (_off == _buf.Length)
  118. {
  119. DerOctetString.Encode(_derOut, _buf, 0, _off);
  120. _off = 0;
  121. }
  122. }
  123. protected override void Dispose(bool disposing)
  124. {
  125. if (disposing)
  126. {
  127. if (_off != 0)
  128. {
  129. DerOctetString.Encode(_derOut, _buf, 0, _off);
  130. }
  131. _derOut.FlushInternal();
  132. _gen.WriteBerEnd();
  133. }
  134. base.Dispose(disposing);
  135. }
  136. }
  137. }
  138. }
  139. #pragma warning restore
  140. #endif