Fix safestack issues in x509.h
[openssl.git] / crypto / ocsp / ocsp_srv.c
1 /*
2  * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/objects.h>
13 #include <openssl/x509.h>
14 #include <openssl/pem.h>
15 #include <openssl/x509v3.h>
16 #include <openssl/ocsp.h>
17 #include "ocsp_local.h"
18
19 DEFINE_STACK_OF(OCSP_ONEREQ)
20 DEFINE_STACK_OF(OCSP_SINGLERESP)
21
22 /*
23  * Utility functions related to sending OCSP responses and extracting
24  * relevant information from the request.
25  */
26
27 int OCSP_request_onereq_count(OCSP_REQUEST *req)
28 {
29     return sk_OCSP_ONEREQ_num(req->tbsRequest.requestList);
30 }
31
32 OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
33 {
34     return sk_OCSP_ONEREQ_value(req->tbsRequest.requestList, i);
35 }
36
37 OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
38 {
39     return one->reqCert;
40 }
41
42 int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
43                       ASN1_OCTET_STRING **pikeyHash,
44                       ASN1_INTEGER **pserial, OCSP_CERTID *cid)
45 {
46     if (!cid)
47         return 0;
48     if (pmd)
49         *pmd = cid->hashAlgorithm.algorithm;
50     if (piNameHash)
51         *piNameHash = &cid->issuerNameHash;
52     if (pikeyHash)
53         *pikeyHash = &cid->issuerKeyHash;
54     if (pserial)
55         *pserial = &cid->serialNumber;
56     return 1;
57 }
58
59 int OCSP_request_is_signed(OCSP_REQUEST *req)
60 {
61     if (req->optionalSignature)
62         return 1;
63     return 0;
64 }
65
66 /* Create an OCSP response and encode an optional basic response */
67 OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
68 {
69     OCSP_RESPONSE *rsp = NULL;
70
71     if ((rsp = OCSP_RESPONSE_new()) == NULL)
72         goto err;
73     if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status)))
74         goto err;
75     if (!bs)
76         return rsp;
77     if ((rsp->responseBytes = OCSP_RESPBYTES_new()) == NULL)
78         goto err;
79     rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
80     if (!ASN1_item_pack
81         (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
82          goto err;
83     return rsp;
84  err:
85     OCSP_RESPONSE_free(rsp);
86     return NULL;
87 }
88
89 OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
90                                         OCSP_CERTID *cid,
91                                         int status, int reason,
92                                         ASN1_TIME *revtime,
93                                         ASN1_TIME *thisupd,
94                                         ASN1_TIME *nextupd)
95 {
96     OCSP_SINGLERESP *single = NULL;
97     OCSP_CERTSTATUS *cs;
98     OCSP_REVOKEDINFO *ri;
99
100     if (rsp->tbsResponseData.responses == NULL
101         && (rsp->tbsResponseData.responses
102                 = sk_OCSP_SINGLERESP_new_null()) == NULL)
103         goto err;
104
105     if ((single = OCSP_SINGLERESP_new()) == NULL)
106         goto err;
107
108     if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
109         goto err;
110     if (nextupd &&
111         !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
112         goto err;
113
114     OCSP_CERTID_free(single->certId);
115
116     if ((single->certId = OCSP_CERTID_dup(cid)) == NULL)
117         goto err;
118
119     cs = single->certStatus;
120     switch (cs->type = status) {
121     case V_OCSP_CERTSTATUS_REVOKED:
122         if (!revtime) {
123             OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME);
124             goto err;
125         }
126         if ((cs->value.revoked = ri = OCSP_REVOKEDINFO_new()) == NULL)
127             goto err;
128         if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
129             goto err;
130         if (reason != OCSP_REVOKED_STATUS_NOSTATUS) {
131             if ((ri->revocationReason = ASN1_ENUMERATED_new()) == NULL)
132                 goto err;
133             if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason)))
134                 goto err;
135         }
136         break;
137
138     case V_OCSP_CERTSTATUS_GOOD:
139         if ((cs->value.good = ASN1_NULL_new()) == NULL)
140             goto err;
141         break;
142
143     case V_OCSP_CERTSTATUS_UNKNOWN:
144         if ((cs->value.unknown = ASN1_NULL_new()) == NULL)
145             goto err;
146         break;
147
148     default:
149         goto err;
150
151     }
152     if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData.responses, single)))
153         goto err;
154     return single;
155  err:
156     OCSP_SINGLERESP_free(single);
157     return NULL;
158 }
159
160 /* Add a certificate to an OCSP request */
161
162 int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
163 {
164     return X509_add_cert_new(&resp->certs, cert, X509_ADD_FLAG_UP_REF);
165 }
166
167 /*
168  * Sign an OCSP response using the parameters contained in the digest context,
169  * set the responderID to the subject name in the signer's certificate, and
170  * include one or more optional certificates in the response.
171  */
172
173 int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp,
174                     X509 *signer, EVP_MD_CTX *ctx,
175                     STACK_OF(X509) *certs, unsigned long flags)
176 {
177     int i;
178     OCSP_RESPID *rid;
179     EVP_PKEY *pkey;
180
181     if (ctx == NULL || EVP_MD_CTX_pkey_ctx(ctx) == NULL) {
182         OCSPerr(OCSP_F_OCSP_BASIC_SIGN_CTX, OCSP_R_NO_SIGNER_KEY);
183         goto err;
184     }
185
186     pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
187     if (pkey == NULL || !X509_check_private_key(signer, pkey)) {
188         OCSPerr(OCSP_F_OCSP_BASIC_SIGN_CTX,
189                 OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
190         goto err;
191     }
192
193     if (!(flags & OCSP_NOCERTS)) {
194         if (!OCSP_basic_add1_cert(brsp, signer))
195             goto err;
196         for (i = 0; i < sk_X509_num(certs); i++) {
197             X509 *tmpcert = sk_X509_value(certs, i);
198             if (!OCSP_basic_add1_cert(brsp, tmpcert))
199                 goto err;
200         }
201     }
202
203     rid = &brsp->tbsResponseData.responderId;
204     if (flags & OCSP_RESPID_KEY) {
205         if (!OCSP_RESPID_set_by_key(rid, signer))
206             goto err;
207     } else if (!OCSP_RESPID_set_by_name(rid, signer)) {
208         goto err;
209     }
210
211     if (!(flags & OCSP_NOTIME) &&
212         !X509_gmtime_adj(brsp->tbsResponseData.producedAt, 0))
213         goto err;
214
215     /*
216      * Right now, I think that not doing double hashing is the right thing.
217      * -- Richard Levitte
218      */
219
220     if (!OCSP_BASICRESP_sign_ctx(brsp, ctx, 0))
221         goto err;
222
223     return 1;
224  err:
225     return 0;
226 }
227
228 int OCSP_basic_sign(OCSP_BASICRESP *brsp,
229                     X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
230                     STACK_OF(X509) *certs, unsigned long flags)
231 {
232     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
233     EVP_PKEY_CTX *pkctx = NULL;
234     int i;
235
236     if (ctx == NULL)
237         return 0;
238
239     if (!EVP_DigestSignInit(ctx, &pkctx, dgst, NULL, key)) {
240         EVP_MD_CTX_free(ctx);
241         return 0;
242     }
243     i = OCSP_basic_sign_ctx(brsp, signer, ctx, certs, flags);
244     EVP_MD_CTX_free(ctx);
245     return i;
246 }
247
248 int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert)
249 {
250     if (!X509_NAME_set(&respid->value.byName, X509_get_subject_name(cert)))
251         return 0;
252
253     respid->type = V_OCSP_RESPID_NAME;
254
255     return 1;
256 }
257
258 int OCSP_RESPID_set_by_key_ex(OCSP_RESPID *respid, X509 *cert,
259                               OPENSSL_CTX *libctx, const char *propq)
260 {
261     ASN1_OCTET_STRING *byKey = NULL;
262     unsigned char md[SHA_DIGEST_LENGTH];
263     EVP_MD *sha1 = EVP_MD_fetch(libctx, "SHA1", propq);
264     int ret = 0;
265
266     if (sha1 == NULL)
267         return 0;
268
269     /* RFC2560 requires SHA1 */
270     if (!X509_pubkey_digest(cert, sha1, md, NULL))
271         goto err;
272
273     byKey = ASN1_OCTET_STRING_new();
274     if (byKey == NULL)
275         goto err;
276
277     if (!(ASN1_OCTET_STRING_set(byKey, md, SHA_DIGEST_LENGTH))) {
278         ASN1_OCTET_STRING_free(byKey);
279         goto err;
280     }
281
282     respid->type = V_OCSP_RESPID_KEY;
283     respid->value.byKey = byKey;
284
285     ret = 1;
286  err:
287     EVP_MD_free(sha1);
288     return ret;
289 }
290
291 int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert)
292 {
293     return OCSP_RESPID_set_by_key_ex(respid, cert, NULL, NULL);
294 }
295
296 int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OPENSSL_CTX *libctx,
297                          const char *propq)
298 {
299     EVP_MD *sha1 = NULL;
300     int ret = 0;
301
302     if (respid->type == V_OCSP_RESPID_KEY) {
303         unsigned char md[SHA_DIGEST_LENGTH];
304
305         sha1 = EVP_MD_fetch(libctx, "SHA1", propq);
306         if (sha1 == NULL)
307             goto err;
308
309         if (respid->value.byKey == NULL)
310             goto err;
311
312         /* RFC2560 requires SHA1 */
313         if (!X509_pubkey_digest(cert, sha1, md, NULL))
314             goto err;
315
316         ret = (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH)
317               && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md,
318                          SHA_DIGEST_LENGTH) == 0);
319     } else if (respid->type == V_OCSP_RESPID_NAME) {
320         if (respid->value.byName == NULL)
321             return 0;
322
323         return X509_NAME_cmp(respid->value.byName,
324                              X509_get_subject_name(cert)) == 0;
325     }
326
327  err:
328     EVP_MD_free(sha1);
329     return ret;
330 }
331
332 int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert)
333 {
334     return OCSP_RESPID_match_ex(respid, cert, NULL, NULL);
335 }