SignatureSubpacketsReader.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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.Bcpg.Sig;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Bcpg
  9. {
  10. /**
  11. * reader for signature sub-packets
  12. */
  13. public class SignatureSubpacketsParser
  14. {
  15. private readonly Stream input;
  16. public SignatureSubpacketsParser(
  17. Stream input)
  18. {
  19. this.input = input;
  20. }
  21. public SignatureSubpacket ReadPacket()
  22. {
  23. int l = input.ReadByte();
  24. if (l < 0)
  25. return null;
  26. int bodyLen = 0;
  27. bool isLongLength = false;
  28. if (l < 192)
  29. {
  30. bodyLen = l;
  31. }
  32. else if (l <= 223)
  33. {
  34. bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192;
  35. }
  36. else if (l == 255)
  37. {
  38. isLongLength = true;
  39. bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16)
  40. | (input.ReadByte() << 8) | input.ReadByte();
  41. }
  42. else
  43. {
  44. throw new IOException("unexpected length header");
  45. }
  46. int tag = input.ReadByte();
  47. if (tag < 0)
  48. throw new EndOfStreamException("unexpected EOF reading signature sub packet");
  49. if (bodyLen <= 0)
  50. throw new EndOfStreamException("out of range data found in signature sub packet");
  51. byte[] data = new byte[bodyLen - 1];
  52. //
  53. // this may seem a bit strange but it turns out some applications miscode the length
  54. // in fixed length fields, so we check the length we do get, only throwing an exception if
  55. // we really cannot continue
  56. //
  57. int bytesRead = Streams.ReadFully(input, data);
  58. bool isCritical = ((tag & 0x80) != 0);
  59. SignatureSubpacketTag type = (SignatureSubpacketTag)(tag & 0x7f);
  60. if (bytesRead != data.Length)
  61. {
  62. switch (type)
  63. {
  64. case SignatureSubpacketTag.CreationTime:
  65. data = CheckData(data, 4, bytesRead, "Signature Creation Time");
  66. break;
  67. case SignatureSubpacketTag.IssuerKeyId:
  68. data = CheckData(data, 8, bytesRead, "Issuer");
  69. break;
  70. case SignatureSubpacketTag.KeyExpireTime:
  71. data = CheckData(data, 4, bytesRead, "Signature Key Expiration Time");
  72. break;
  73. case SignatureSubpacketTag.ExpireTime:
  74. data = CheckData(data, 4, bytesRead, "Signature Expiration Time");
  75. break;
  76. default:
  77. throw new EndOfStreamException("truncated subpacket data.");
  78. }
  79. }
  80. switch (type)
  81. {
  82. case SignatureSubpacketTag.CreationTime:
  83. return new SignatureCreationTime(isCritical, isLongLength, data);
  84. case SignatureSubpacketTag.KeyExpireTime:
  85. return new KeyExpirationTime(isCritical, isLongLength, data);
  86. case SignatureSubpacketTag.ExpireTime:
  87. return new SignatureExpirationTime(isCritical, isLongLength, data);
  88. case SignatureSubpacketTag.Revocable:
  89. return new Revocable(isCritical, isLongLength, data);
  90. case SignatureSubpacketTag.Exportable:
  91. return new Exportable(isCritical, isLongLength, data);
  92. case SignatureSubpacketTag.IssuerKeyId:
  93. return new IssuerKeyId(isCritical, isLongLength, data);
  94. case SignatureSubpacketTag.TrustSig:
  95. return new TrustSignature(isCritical, isLongLength, data);
  96. case SignatureSubpacketTag.PreferredCompressionAlgorithms:
  97. case SignatureSubpacketTag.PreferredHashAlgorithms:
  98. case SignatureSubpacketTag.PreferredSymmetricAlgorithms:
  99. return new PreferredAlgorithms(type, isCritical, isLongLength, data);
  100. case SignatureSubpacketTag.KeyFlags:
  101. return new KeyFlags(isCritical, isLongLength, data);
  102. case SignatureSubpacketTag.PrimaryUserId:
  103. return new PrimaryUserId(isCritical, isLongLength, data);
  104. case SignatureSubpacketTag.SignerUserId:
  105. return new SignerUserId(isCritical, isLongLength, data);
  106. case SignatureSubpacketTag.NotationData:
  107. return new NotationData(isCritical, isLongLength, data);
  108. }
  109. return new SignatureSubpacket(type, isCritical, isLongLength, data);
  110. }
  111. private byte[] CheckData(byte[] data, int expected, int bytesRead, string name)
  112. {
  113. if (bytesRead != expected)
  114. throw new EndOfStreamException("truncated " + name + " subpacket data.");
  115. return Arrays.CopyOfRange(data, 0, expected);
  116. }
  117. }
  118. }
  119. #pragma warning restore
  120. #endif