Copyright consolidation 09/10
[openssl.git] / crypto / ocsp / ocsp_prn.c
1 /*
2  * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/bio.h>
11 #include <openssl/err.h>
12 #include <openssl/ocsp.h>
13 #include "ocsp_lcl.h"
14 #include <openssl/pem.h>
15
16 static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent)
17 {
18     BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
19     indent += 2;
20     BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
21     i2a_ASN1_OBJECT(bp, a->hashAlgorithm.algorithm);
22     BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
23     i2a_ASN1_STRING(bp, &a->issuerNameHash, 0);
24     BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
25     i2a_ASN1_STRING(bp, &a->issuerKeyHash, 0);
26     BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
27     i2a_ASN1_INTEGER(bp, &a->serialNumber);
28     BIO_printf(bp, "\n");
29     return 1;
30 }
31
32 typedef struct {
33     long t;
34     const char *m;
35 } OCSP_TBLSTR;
36
37 static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
38 {
39     const OCSP_TBLSTR *p;
40     for (p = ts; p < ts + len; p++)
41         if (p->t == s)
42             return p->m;
43     return "(UNKNOWN)";
44 }
45
46 const char *OCSP_response_status_str(long s)
47 {
48     static const OCSP_TBLSTR rstat_tbl[] = {
49         {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"},
50         {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"},
51         {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"},
52         {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"},
53         {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"},
54         {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"}
55     };
56     return table2string(s, rstat_tbl, 6);
57 }
58
59 const char *OCSP_cert_status_str(long s)
60 {
61     static const OCSP_TBLSTR cstat_tbl[] = {
62         {V_OCSP_CERTSTATUS_GOOD, "good"},
63         {V_OCSP_CERTSTATUS_REVOKED, "revoked"},
64         {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"}
65     };
66     return table2string(s, cstat_tbl, 3);
67 }
68
69 const char *OCSP_crl_reason_str(long s)
70 {
71     static const OCSP_TBLSTR reason_tbl[] = {
72         {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"},
73         {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"},
74         {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"},
75         {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"},
76         {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"},
77         {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"},
78         {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"},
79         {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"}
80     };
81     return table2string(s, reason_tbl, 8);
82 }
83
84 int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags)
85 {
86     int i;
87     long l;
88     OCSP_CERTID *cid = NULL;
89     OCSP_ONEREQ *one = NULL;
90     OCSP_REQINFO *inf = &o->tbsRequest;
91     OCSP_SIGNATURE *sig = o->optionalSignature;
92
93     if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0)
94         goto err;
95     l = ASN1_INTEGER_get(inf->version);
96     if (BIO_printf(bp, "    Version: %lu (0x%lx)", l + 1, l) <= 0)
97         goto err;
98     if (inf->requestorName != NULL) {
99         if (BIO_write(bp, "\n    Requestor Name: ", 21) <= 0)
100             goto err;
101         GENERAL_NAME_print(bp, inf->requestorName);
102     }
103     if (BIO_write(bp, "\n    Requestor List:\n", 21) <= 0)
104         goto err;
105     for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) {
106         one = sk_OCSP_ONEREQ_value(inf->requestList, i);
107         cid = one->reqCert;
108         ocsp_certid_print(bp, cid, 8);
109         if (!X509V3_extensions_print(bp,
110                                      "Request Single Extensions",
111                                      one->singleRequestExtensions, flags, 8))
112             goto err;
113     }
114     if (!X509V3_extensions_print(bp, "Request Extensions",
115                                  inf->requestExtensions, flags, 4))
116         goto err;
117     if (sig) {
118         X509_signature_print(bp, &sig->signatureAlgorithm, sig->signature);
119         for (i = 0; i < sk_X509_num(sig->certs); i++) {
120             X509_print(bp, sk_X509_value(sig->certs, i));
121             PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i));
122         }
123     }
124     return 1;
125  err:
126     return 0;
127 }
128
129 int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags)
130 {
131     int i, ret = 0;
132     long l;
133     OCSP_CERTID *cid = NULL;
134     OCSP_BASICRESP *br = NULL;
135     OCSP_RESPID *rid = NULL;
136     OCSP_RESPDATA *rd = NULL;
137     OCSP_CERTSTATUS *cst = NULL;
138     OCSP_REVOKEDINFO *rev = NULL;
139     OCSP_SINGLERESP *single = NULL;
140     OCSP_RESPBYTES *rb = o->responseBytes;
141
142     if (BIO_puts(bp, "OCSP Response Data:\n") <= 0)
143         goto err;
144     l = ASN1_ENUMERATED_get(o->responseStatus);
145     if (BIO_printf(bp, "    OCSP Response Status: %s (0x%lx)\n",
146                    OCSP_response_status_str(l), l) <= 0)
147         goto err;
148     if (rb == NULL)
149         return 1;
150     if (BIO_puts(bp, "    Response Type: ") <= 0)
151         goto err;
152     if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
153         goto err;
154     if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
155         BIO_puts(bp, " (unknown response type)\n");
156         return 1;
157     }
158
159     if ((br = OCSP_response_get1_basic(o)) == NULL)
160         goto err;
161     rd = &br->tbsResponseData;
162     l = ASN1_INTEGER_get(rd->version);
163     if (BIO_printf(bp, "\n    Version: %lu (0x%lx)\n", l + 1, l) <= 0)
164         goto err;
165     if (BIO_puts(bp, "    Responder Id: ") <= 0)
166         goto err;
167
168     rid = &rd->responderId;
169     switch (rid->type) {
170     case V_OCSP_RESPID_NAME:
171         X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
172         break;
173     case V_OCSP_RESPID_KEY:
174         i2a_ASN1_STRING(bp, rid->value.byKey, 0);
175         break;
176     }
177
178     if (BIO_printf(bp, "\n    Produced At: ") <= 0)
179         goto err;
180     if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt))
181         goto err;
182     if (BIO_printf(bp, "\n    Responses:\n") <= 0)
183         goto err;
184     for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) {
185         if (!sk_OCSP_SINGLERESP_value(rd->responses, i))
186             continue;
187         single = sk_OCSP_SINGLERESP_value(rd->responses, i);
188         cid = single->certId;
189         if (ocsp_certid_print(bp, cid, 4) <= 0)
190             goto err;
191         cst = single->certStatus;
192         if (BIO_printf(bp, "    Cert Status: %s",
193                        OCSP_cert_status_str(cst->type)) <= 0)
194             goto err;
195         if (cst->type == V_OCSP_CERTSTATUS_REVOKED) {
196             rev = cst->value.revoked;
197             if (BIO_printf(bp, "\n    Revocation Time: ") <= 0)
198                 goto err;
199             if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime))
200                 goto err;
201             if (rev->revocationReason) {
202                 l = ASN1_ENUMERATED_get(rev->revocationReason);
203                 if (BIO_printf(bp,
204                                "\n    Revocation Reason: %s (0x%lx)",
205                                OCSP_crl_reason_str(l), l) <= 0)
206                     goto err;
207             }
208         }
209         if (BIO_printf(bp, "\n    This Update: ") <= 0)
210             goto err;
211         if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
212             goto err;
213         if (single->nextUpdate) {
214             if (BIO_printf(bp, "\n    Next Update: ") <= 0)
215                 goto err;
216             if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate))
217                 goto err;
218         }
219         if (BIO_write(bp, "\n", 1) <= 0)
220             goto err;
221         if (!X509V3_extensions_print(bp,
222                                      "Response Single Extensions",
223                                      single->singleExtensions, flags, 8))
224             goto err;
225         if (BIO_write(bp, "\n", 1) <= 0)
226             goto err;
227     }
228     if (!X509V3_extensions_print(bp, "Response Extensions",
229                                  rd->responseExtensions, flags, 4))
230         goto err;
231     if (X509_signature_print(bp, &br->signatureAlgorithm, br->signature) <= 0)
232         goto err;
233
234     for (i = 0; i < sk_X509_num(br->certs); i++) {
235         X509_print(bp, sk_X509_value(br->certs, i));
236         PEM_write_bio_X509(bp, sk_X509_value(br->certs, i));
237     }
238
239     ret = 1;
240  err:
241     OCSP_BASICRESP_free(br);
242     return ret;
243 }