ocsp_prn.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* ocsp_prn.c */
  2. /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
  3. * project. */
  4. /* History:
  5. This file was originally part of ocsp.c and was transfered to Richard
  6. Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included
  7. in OpenSSL or released as a patch kit. */
  8. /* ====================================================================
  9. * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in
  20. * the documentation and/or other materials provided with the
  21. * distribution.
  22. *
  23. * 3. All advertising materials mentioning features or use of this
  24. * software must display the following acknowledgment:
  25. * "This product includes software developed by the OpenSSL Project
  26. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  27. *
  28. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  29. * endorse or promote products derived from this software without
  30. * prior written permission. For written permission, please contact
  31. * openssl-core@openssl.org.
  32. *
  33. * 5. Products derived from this software may not be called "OpenSSL"
  34. * nor may "OpenSSL" appear in their names without prior written
  35. * permission of the OpenSSL Project.
  36. *
  37. * 6. Redistributions of any form whatsoever must retain the following
  38. * acknowledgment:
  39. * "This product includes software developed by the OpenSSL Project
  40. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  41. *
  42. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  43. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  44. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  45. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  46. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  47. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  48. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  50. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  51. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  52. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  53. * OF THE POSSIBILITY OF SUCH DAMAGE.
  54. * ====================================================================
  55. *
  56. * This product includes cryptographic software written by Eric Young
  57. * (eay@cryptsoft.com). This product includes software written by Tim
  58. * Hudson (tjh@cryptsoft.com).
  59. *
  60. */
  61. #include <openssl/bio.h>
  62. #include <openssl/err.h>
  63. #include <openssl/ocsp.h>
  64. #include <openssl/pem.h>
  65. static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent)
  66. {
  67. BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
  68. indent += 2;
  69. BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
  70. i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm);
  71. BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
  72. i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING);
  73. BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
  74. i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING);
  75. BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
  76. i2a_ASN1_INTEGER(bp, a->serialNumber);
  77. BIO_printf(bp, "\n");
  78. return 1;
  79. }
  80. typedef struct
  81. {
  82. long t;
  83. const char *m;
  84. } OCSP_TBLSTR;
  85. static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
  86. {
  87. const OCSP_TBLSTR *p;
  88. for (p=ts; p < ts + len; p++)
  89. if (p->t == s)
  90. return p->m;
  91. return "(UNKNOWN)";
  92. }
  93. const char *OCSP_response_status_str(long s)
  94. {
  95. static const OCSP_TBLSTR rstat_tbl[] = {
  96. { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
  97. { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
  98. { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
  99. { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" },
  100. { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" },
  101. { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } };
  102. return table2string(s, rstat_tbl, 6);
  103. }
  104. const char *OCSP_cert_status_str(long s)
  105. {
  106. static const OCSP_TBLSTR cstat_tbl[] = {
  107. { V_OCSP_CERTSTATUS_GOOD, "good" },
  108. { V_OCSP_CERTSTATUS_REVOKED, "revoked" },
  109. { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } };
  110. return table2string(s, cstat_tbl, 3);
  111. }
  112. const char *OCSP_crl_reason_str(long s)
  113. {
  114. static const OCSP_TBLSTR reason_tbl[] = {
  115. { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
  116. { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
  117. { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
  118. { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" },
  119. { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" },
  120. { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" },
  121. { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" },
  122. { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } };
  123. return table2string(s, reason_tbl, 8);
  124. }
  125. int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
  126. {
  127. int i;
  128. long l;
  129. OCSP_CERTID* cid = NULL;
  130. OCSP_ONEREQ *one = NULL;
  131. OCSP_REQINFO *inf = o->tbsRequest;
  132. OCSP_SIGNATURE *sig = o->optionalSignature;
  133. if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err;
  134. l=ASN1_INTEGER_get(inf->version);
  135. if (BIO_printf(bp," Version: %lu (0x%lx)",l+1,l) <= 0) goto err;
  136. if (inf->requestorName != NULL)
  137. {
  138. if (BIO_write(bp,"\n Requestor Name: ",21) <= 0)
  139. goto err;
  140. GENERAL_NAME_print(bp, inf->requestorName);
  141. }
  142. if (BIO_write(bp,"\n Requestor List:\n",21) <= 0) goto err;
  143. for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
  144. {
  145. one = sk_OCSP_ONEREQ_value(inf->requestList, i);
  146. cid = one->reqCert;
  147. ocsp_certid_print(bp, cid, 8);
  148. if (!X509V3_extensions_print(bp,
  149. "Request Single Extensions",
  150. one->singleRequestExtensions, flags, 8))
  151. goto err;
  152. }
  153. if (!X509V3_extensions_print(bp, "Request Extensions",
  154. inf->requestExtensions, flags, 4))
  155. goto err;
  156. if (sig)
  157. {
  158. X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
  159. for (i=0; i<sk_X509_num(sig->certs); i++)
  160. {
  161. X509_print(bp, sk_X509_value(sig->certs,i));
  162. PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i));
  163. }
  164. }
  165. return 1;
  166. err:
  167. return 0;
  168. }
  169. int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
  170. {
  171. int i, ret = 0;
  172. long l;
  173. unsigned char *p;
  174. OCSP_CERTID *cid = NULL;
  175. OCSP_BASICRESP *br = NULL;
  176. OCSP_RESPID *rid = NULL;
  177. OCSP_RESPDATA *rd = NULL;
  178. OCSP_CERTSTATUS *cst = NULL;
  179. OCSP_REVOKEDINFO *rev = NULL;
  180. OCSP_SINGLERESP *single = NULL;
  181. OCSP_RESPBYTES *rb = o->responseBytes;
  182. if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err;
  183. l=ASN1_ENUMERATED_get(o->responseStatus);
  184. if (BIO_printf(bp," OCSP Response Status: %s (0x%lx)\n",
  185. OCSP_response_status_str(l), l) <= 0) goto err;
  186. if (rb == NULL) return 1;
  187. if (BIO_puts(bp," Response Type: ") <= 0)
  188. goto err;
  189. if(i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
  190. goto err;
  191. if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
  192. {
  193. BIO_puts(bp," (unknown response type)\n");
  194. return 1;
  195. }
  196. p = ASN1_STRING_data(rb->response);
  197. i = ASN1_STRING_length(rb->response);
  198. if (!(br = OCSP_response_get1_basic(o))) goto err;
  199. rd = br->tbsResponseData;
  200. l=ASN1_INTEGER_get(rd->version);
  201. if (BIO_printf(bp,"\n Version: %lu (0x%lx)\n",
  202. l+1,l) <= 0) goto err;
  203. if (BIO_puts(bp," Responder Id: ") <= 0) goto err;
  204. rid = rd->responderId;
  205. switch (rid->type)
  206. {
  207. case V_OCSP_RESPID_NAME:
  208. X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
  209. break;
  210. case V_OCSP_RESPID_KEY:
  211. i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING);
  212. break;
  213. }
  214. if (BIO_printf(bp,"\n Produced At: ")<=0) goto err;
  215. if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) goto err;
  216. if (BIO_printf(bp,"\n Responses:\n") <= 0) goto err;
  217. for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++)
  218. {
  219. if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) continue;
  220. single = sk_OCSP_SINGLERESP_value(rd->responses, i);
  221. cid = single->certId;
  222. if(ocsp_certid_print(bp, cid, 4) <= 0) goto err;
  223. cst = single->certStatus;
  224. if (BIO_printf(bp," Cert Status: %s",
  225. OCSP_cert_status_str(cst->type)) <= 0)
  226. goto err;
  227. if (cst->type == V_OCSP_CERTSTATUS_REVOKED)
  228. {
  229. rev = cst->value.revoked;
  230. if (BIO_printf(bp, "\n Revocation Time: ") <= 0)
  231. goto err;
  232. if (!ASN1_GENERALIZEDTIME_print(bp,
  233. rev->revocationTime))
  234. goto err;
  235. if (rev->revocationReason)
  236. {
  237. l=ASN1_ENUMERATED_get(rev->revocationReason);
  238. if (BIO_printf(bp,
  239. "\n Revocation Reason: %s (0x%lx)",
  240. OCSP_crl_reason_str(l), l) <= 0)
  241. goto err;
  242. }
  243. }
  244. if (BIO_printf(bp,"\n This Update: ") <= 0) goto err;
  245. if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
  246. goto err;
  247. if (single->nextUpdate)
  248. {
  249. if (BIO_printf(bp,"\n Next Update: ") <= 0)goto err;
  250. if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate))
  251. goto err;
  252. }
  253. if (!BIO_write(bp,"\n",1)) goto err;
  254. if (!X509V3_extensions_print(bp,
  255. "Response Single Extensions",
  256. single->singleExtensions, flags, 8))
  257. goto err;
  258. if (!BIO_write(bp,"\n",1)) goto err;
  259. }
  260. if (!X509V3_extensions_print(bp, "Response Extensions",
  261. rd->responseExtensions, flags, 4))
  262. if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
  263. goto err;
  264. for (i=0; i<sk_X509_num(br->certs); i++)
  265. {
  266. X509_print(bp, sk_X509_value(br->certs,i));
  267. PEM_write_bio_X509(bp,sk_X509_value(br->certs,i));
  268. }
  269. ret = 1;
  270. err:
  271. OCSP_BASICRESP_free(br);
  272. return ret;
  273. }