PemWriter.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO.Pem
  8. {
  9. /**
  10. * A generic PEM writer, based on RFC 1421
  11. */
  12. public class PemWriter
  13. {
  14. private const int LineLength = 64;
  15. private readonly TextWriter writer;
  16. private readonly int nlLength;
  17. private char[] buf = new char[LineLength];
  18. /**
  19. * Base constructor.
  20. *
  21. * @param out output stream to use.
  22. */
  23. public PemWriter(TextWriter writer)
  24. {
  25. if (writer == null)
  26. throw new ArgumentNullException("writer");
  27. this.writer = writer;
  28. this.nlLength = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.NewLine.Length;
  29. }
  30. public TextWriter Writer
  31. {
  32. get { return writer; }
  33. }
  34. /**
  35. * Return the number of bytes or characters required to contain the
  36. * passed in object if it is PEM encoded.
  37. *
  38. * @param obj pem object to be output
  39. * @return an estimate of the number of bytes
  40. */
  41. public int GetOutputSize(PemObject obj)
  42. {
  43. // BEGIN and END boundaries.
  44. int size = (2 * (obj.Type.Length + 10 + nlLength)) + 6 + 4;
  45. if (obj.Headers.Count > 0)
  46. {
  47. foreach (PemHeader header in obj.Headers)
  48. {
  49. size += header.Name.Length + ": ".Length + header.Value.Length + nlLength;
  50. }
  51. size += nlLength;
  52. }
  53. // base64 encoding
  54. int dataLen = ((obj.Content.Length + 2) / 3) * 4;
  55. size += dataLen + (((dataLen + LineLength - 1) / LineLength) * nlLength);
  56. return size;
  57. }
  58. public void WriteObject(PemObjectGenerator objGen)
  59. {
  60. PemObject obj = objGen.Generate();
  61. WritePreEncapsulationBoundary(obj.Type);
  62. if (obj.Headers.Count > 0)
  63. {
  64. foreach (PemHeader header in obj.Headers)
  65. {
  66. writer.Write(header.Name);
  67. writer.Write(": ");
  68. writer.WriteLine(header.Value);
  69. }
  70. writer.WriteLine();
  71. }
  72. WriteEncoded(obj.Content);
  73. WritePostEncapsulationBoundary(obj.Type);
  74. }
  75. private void WriteEncoded(byte[] bytes)
  76. {
  77. bytes = Base64.Encode(bytes);
  78. for (int i = 0; i < bytes.Length; i += buf.Length)
  79. {
  80. int index = 0;
  81. while (index != buf.Length)
  82. {
  83. if ((i + index) >= bytes.Length)
  84. break;
  85. buf[index] = (char)bytes[i + index];
  86. index++;
  87. }
  88. writer.WriteLine(buf, 0, index);
  89. }
  90. }
  91. private void WritePreEncapsulationBoundary(string type)
  92. {
  93. writer.WriteLine("-----BEGIN " + type + "-----");
  94. }
  95. private void WritePostEncapsulationBoundary(string type)
  96. {
  97. writer.WriteLine("-----END " + type + "-----");
  98. }
  99. }
  100. }
  101. #pragma warning restore
  102. #endif