TimeStampResponse.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using System.Text;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  11. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
  12. {
  13. /**
  14. * Base class for an RFC 3161 Time Stamp Response object.
  15. */
  16. public class TimeStampResponse
  17. {
  18. private TimeStampResp resp;
  19. private TimeStampToken timeStampToken;
  20. public TimeStampResponse(
  21. TimeStampResp resp)
  22. {
  23. this.resp = resp;
  24. if (resp.TimeStampToken != null)
  25. {
  26. timeStampToken = new TimeStampToken(resp.TimeStampToken);
  27. }
  28. }
  29. /**
  30. * Create a TimeStampResponse from a byte array containing an ASN.1 encoding.
  31. *
  32. * @param resp the byte array containing the encoded response.
  33. * @throws TspException if the response is malformed.
  34. * @throws IOException if the byte array doesn't represent an ASN.1 encoding.
  35. */
  36. public TimeStampResponse(
  37. byte[] resp)
  38. : this(readTimeStampResp(new Asn1InputStream(resp)))
  39. {
  40. }
  41. /**
  42. * Create a TimeStampResponse from an input stream containing an ASN.1 encoding.
  43. *
  44. * @param input the input stream containing the encoded response.
  45. * @throws TspException if the response is malformed.
  46. * @throws IOException if the stream doesn't represent an ASN.1 encoding.
  47. */
  48. public TimeStampResponse(
  49. Stream input)
  50. : this(readTimeStampResp(new Asn1InputStream(input)))
  51. {
  52. }
  53. private static TimeStampResp readTimeStampResp(
  54. Asn1InputStream input)
  55. {
  56. try
  57. {
  58. return TimeStampResp.GetInstance(input.ReadObject());
  59. }
  60. catch (ArgumentException e)
  61. {
  62. throw new TspException("malformed timestamp response: " + e, e);
  63. }
  64. catch (InvalidCastException e)
  65. {
  66. throw new TspException("malformed timestamp response: " + e, e);
  67. }
  68. }
  69. public int Status
  70. {
  71. get { return resp.Status.Status.IntValue; }
  72. }
  73. public string GetStatusString()
  74. {
  75. if (resp.Status.StatusString == null)
  76. {
  77. return null;
  78. }
  79. StringBuilder statusStringBuf = new StringBuilder();
  80. PkiFreeText text = resp.Status.StatusString;
  81. for (int i = 0; i != text.Count; i++)
  82. {
  83. statusStringBuf.Append(text[i].GetString());
  84. }
  85. return statusStringBuf.ToString();
  86. }
  87. public PkiFailureInfo GetFailInfo()
  88. {
  89. if (resp.Status.FailInfo == null)
  90. {
  91. return null;
  92. }
  93. return new PkiFailureInfo(resp.Status.FailInfo);
  94. }
  95. public TimeStampToken TimeStampToken
  96. {
  97. get { return timeStampToken; }
  98. }
  99. /**
  100. * Check this response against to see if it a well formed response for
  101. * the passed in request. Validation will include checking the time stamp
  102. * token if the response status is GRANTED or GRANTED_WITH_MODS.
  103. *
  104. * @param request the request to be checked against
  105. * @throws TspException if the request can not match this response.
  106. */
  107. public void Validate(
  108. TimeStampRequest request)
  109. {
  110. TimeStampToken tok = this.TimeStampToken;
  111. if (tok != null)
  112. {
  113. TimeStampTokenInfo tstInfo = tok.TimeStampInfo;
  114. if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce))
  115. {
  116. throw new TspValidationException("response contains wrong nonce value.");
  117. }
  118. if (this.Status != (int) PkiStatus.Granted && this.Status != (int) PkiStatus.GrantedWithMods)
  119. {
  120. throw new TspValidationException("time stamp token found in failed request.");
  121. }
  122. if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest()))
  123. {
  124. throw new TspValidationException("response for different message imprint digest.");
  125. }
  126. if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid))
  127. {
  128. throw new TspValidationException("response for different message imprint algorithm.");
  129. }
  130. Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate];
  131. Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
  132. if (scV1 == null && scV2 == null)
  133. {
  134. throw new TspValidationException("no signing certificate attribute present.");
  135. }
  136. if (scV1 != null && scV2 != null)
  137. {
  138. /*
  139. * RFC 5035 5.4. If both attributes exist in a single message,
  140. * they are independently evaluated.
  141. */
  142. }
  143. if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy))
  144. {
  145. throw new TspValidationException("TSA policy wrong for request.");
  146. }
  147. }
  148. else if (this.Status == (int) PkiStatus.Granted || this.Status == (int) PkiStatus.GrantedWithMods)
  149. {
  150. throw new TspValidationException("no time stamp token found and one expected.");
  151. }
  152. }
  153. /**
  154. * return the ASN.1 encoded representation of this object.
  155. */
  156. public byte[] GetEncoded()
  157. {
  158. return resp.GetEncoded();
  159. }
  160. }
  161. }
  162. #pragma warning restore
  163. #endif