BasicOCSPRespGenerator.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ocsp;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators;
  11. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  12. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
  13. using Best.HTTP.SecureProtocol.Org.BouncyCastle.X509;
  14. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Ocsp
  15. {
  16. /**
  17. * Generator for basic OCSP response objects.
  18. */
  19. public class BasicOcspRespGenerator
  20. {
  21. private readonly List<ResponseObject> list = new List<ResponseObject>();
  22. private X509Extensions responseExtensions;
  23. private RespID responderID;
  24. private class ResponseObject
  25. {
  26. internal CertificateID certId;
  27. internal CertStatus certStatus;
  28. internal Asn1GeneralizedTime thisUpdate;
  29. internal Asn1GeneralizedTime nextUpdate;
  30. internal X509Extensions extensions;
  31. internal ResponseObject(
  32. CertificateID certId,
  33. CertificateStatus certStatus,
  34. DateTime thisUpdate,
  35. DateTime? nextUpdate,
  36. X509Extensions extensions)
  37. {
  38. this.certId = certId;
  39. if (certStatus == null)
  40. {
  41. this.certStatus = new CertStatus();
  42. }
  43. else if (certStatus is UnknownStatus)
  44. {
  45. this.certStatus = new CertStatus(2, DerNull.Instance);
  46. }
  47. else
  48. {
  49. RevokedStatus rs = (RevokedStatus) certStatus;
  50. CrlReason revocationReason = rs.HasRevocationReason
  51. ? new CrlReason(rs.RevocationReason)
  52. : null;
  53. this.certStatus = new CertStatus(
  54. new RevokedInfo(new Asn1GeneralizedTime(rs.RevocationTime), revocationReason));
  55. }
  56. this.thisUpdate = new DerGeneralizedTime(thisUpdate);
  57. this.nextUpdate = nextUpdate.HasValue ? new DerGeneralizedTime(nextUpdate.Value) : null;
  58. this.extensions = extensions;
  59. }
  60. public SingleResponse ToResponse()
  61. {
  62. return new SingleResponse(certId.ToAsn1Object(), certStatus, thisUpdate, nextUpdate, extensions);
  63. }
  64. }
  65. /**
  66. * basic constructor
  67. */
  68. public BasicOcspRespGenerator(
  69. RespID responderID)
  70. {
  71. this.responderID = responderID;
  72. }
  73. /**
  74. * construct with the responderID to be the SHA-1 keyHash of the passed in public key.
  75. */
  76. public BasicOcspRespGenerator(
  77. AsymmetricKeyParameter publicKey)
  78. {
  79. this.responderID = new RespID(publicKey);
  80. }
  81. /**
  82. * Add a response for a particular Certificate ID.
  83. *
  84. * @param certID certificate ID details
  85. * @param certStatus status of the certificate - null if okay
  86. */
  87. public void AddResponse(
  88. CertificateID certID,
  89. CertificateStatus certStatus)
  90. {
  91. list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null, null));
  92. }
  93. /**
  94. * Add a response for a particular Certificate ID.
  95. *
  96. * @param certID certificate ID details
  97. * @param certStatus status of the certificate - null if okay
  98. * @param singleExtensions optional extensions
  99. */
  100. public void AddResponse(
  101. CertificateID certID,
  102. CertificateStatus certStatus,
  103. X509Extensions singleExtensions)
  104. {
  105. list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null, singleExtensions));
  106. }
  107. /**
  108. * Add a response for a particular Certificate ID.
  109. *
  110. * @param certID certificate ID details
  111. * @param nextUpdate date when next update should be requested
  112. * @param certStatus status of the certificate - null if okay
  113. * @param singleExtensions optional extensions
  114. */
  115. public void AddResponse(
  116. CertificateID certID,
  117. CertificateStatus certStatus,
  118. DateTime? nextUpdate,
  119. X509Extensions singleExtensions)
  120. {
  121. list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, nextUpdate, singleExtensions));
  122. }
  123. /**
  124. * Add a response for a particular Certificate ID.
  125. *
  126. * @param certID certificate ID details
  127. * @param thisUpdate date this response was valid on
  128. * @param nextUpdate date when next update should be requested
  129. * @param certStatus status of the certificate - null if okay
  130. * @param singleExtensions optional extensions
  131. */
  132. public void AddResponse(
  133. CertificateID certID,
  134. CertificateStatus certStatus,
  135. DateTime thisUpdate,
  136. DateTime? nextUpdate,
  137. X509Extensions singleExtensions)
  138. {
  139. list.Add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions));
  140. }
  141. /**
  142. * Set the extensions for the response.
  143. *
  144. * @param responseExtensions the extension object to carry.
  145. */
  146. public void SetResponseExtensions(
  147. X509Extensions responseExtensions)
  148. {
  149. this.responseExtensions = responseExtensions;
  150. }
  151. private BasicOcspResp GenerateResponse(
  152. ISignatureFactory signatureCalculator,
  153. X509Certificate[] chain,
  154. DateTime producedAt)
  155. {
  156. AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails;
  157. DerObjectIdentifier signingAlgorithm = signingAlgID.Algorithm;
  158. Asn1EncodableVector responses = new Asn1EncodableVector();
  159. foreach (ResponseObject respObj in list)
  160. {
  161. try
  162. {
  163. responses.Add(respObj.ToResponse());
  164. }
  165. catch (Exception e)
  166. {
  167. throw new OcspException("exception creating Request", e);
  168. }
  169. }
  170. ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new Asn1GeneralizedTime(producedAt),
  171. new DerSequence(responses), responseExtensions);
  172. DerBitString bitSig;
  173. try
  174. {
  175. IStreamCalculator<IBlockResult> streamCalculator = signatureCalculator.CreateCalculator();
  176. using (Stream sigStream = streamCalculator.Stream)
  177. {
  178. tbsResp.EncodeTo(sigStream, Asn1Encodable.Der);
  179. }
  180. bitSig = new DerBitString(streamCalculator.GetResult().Collect());
  181. }
  182. catch (Exception e)
  183. {
  184. throw new OcspException("exception processing TBSRequest: " + e, e);
  185. }
  186. AlgorithmIdentifier sigAlgId = OcspUtilities.GetSigAlgID(signingAlgorithm);
  187. DerSequence chainSeq = null;
  188. if (chain != null && chain.Length > 0)
  189. {
  190. Asn1EncodableVector v = new Asn1EncodableVector(chain.Length);
  191. try
  192. {
  193. for (int i = 0; i != chain.Length; i++)
  194. {
  195. v.Add(chain[i].CertificateStructure);
  196. }
  197. }
  198. catch (IOException e)
  199. {
  200. throw new OcspException("error processing certs", e);
  201. }
  202. catch (CertificateEncodingException e)
  203. {
  204. throw new OcspException("error encoding certs", e);
  205. }
  206. chainSeq = new DerSequence(v);
  207. }
  208. return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, chainSeq));
  209. }
  210. public BasicOcspResp Generate(
  211. string signingAlgorithm,
  212. AsymmetricKeyParameter privateKey,
  213. X509Certificate[] chain,
  214. DateTime thisUpdate)
  215. {
  216. return Generate(signingAlgorithm, privateKey, chain, thisUpdate, null);
  217. }
  218. public BasicOcspResp Generate(
  219. string signingAlgorithm,
  220. AsymmetricKeyParameter privateKey,
  221. X509Certificate[] chain,
  222. DateTime producedAt,
  223. SecureRandom random)
  224. {
  225. if (signingAlgorithm == null)
  226. {
  227. throw new ArgumentException("no signing algorithm specified");
  228. }
  229. return GenerateResponse(new Asn1SignatureFactory(signingAlgorithm, privateKey, random), chain, producedAt);
  230. }
  231. /// <summary>
  232. /// Generate the signed response using the passed in signature calculator.
  233. /// </summary>
  234. /// <param name="signatureCalculatorFactory">Implementation of signing calculator factory.</param>
  235. /// <param name="chain">The certificate chain associated with the response signer.</param>
  236. /// <param name="producedAt">"produced at" date.</param>
  237. /// <returns></returns>
  238. public BasicOcspResp Generate(
  239. ISignatureFactory signatureCalculatorFactory,
  240. X509Certificate[] chain,
  241. DateTime producedAt)
  242. {
  243. if (signatureCalculatorFactory == null)
  244. {
  245. throw new ArgumentException("no signature calculator specified");
  246. }
  247. return GenerateResponse(signatureCalculatorFactory, chain, producedAt);
  248. }
  249. /**
  250. * Return an IEnumerable of the signature names supported by the generator.
  251. *
  252. * @return an IEnumerable containing recognised names.
  253. */
  254. public IEnumerable<string> SignatureAlgNames
  255. {
  256. get { return OcspUtilities.AlgNames; }
  257. }
  258. }
  259. }
  260. #pragma warning restore
  261. #endif