35f4b5803aadc9250197af8f5f2eb14844f7ebc2
[openssl.git] / crypto / ocsp / ocsp_cl.c
1 /*
2  * Copyright 2001-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 <stdio.h>
11 #include <time.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/objects.h>
14 #include <openssl/rand.h>
15 #include <openssl/x509.h>
16 #include <openssl/pem.h>
17 #include <openssl/x509v3.h>
18 #include <openssl/ocsp.h>
19 #include "ocsp_lcl.h"
20
21 /*
22  * Utility functions related to sending OCSP requests and extracting relevant
23  * information from the response.
24  */
25
26 /*
27  * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer:
28  * useful if we want to add extensions.
29  */
30
31 OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
32 {
33     OCSP_ONEREQ *one = NULL;
34
35     if ((one = OCSP_ONEREQ_new()) == NULL)
36         goto err;
37     OCSP_CERTID_free(one->reqCert);
38     one->reqCert = cid;
39     if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one))
40         goto err;
41     return one;
42  err:
43     OCSP_ONEREQ_free(one);
44     return NULL;
45 }
46
47 /* Set requestorName from an X509_NAME structure */
48
49 int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
50 {
51     GENERAL_NAME *gen;
52
53     gen = GENERAL_NAME_new();
54     if (gen == NULL)
55         return 0;
56     if (!X509_NAME_set(&gen->d.directoryName, nm)) {
57         GENERAL_NAME_free(gen);
58         return 0;
59     }
60     gen->type = GEN_DIRNAME;
61     GENERAL_NAME_free(req->tbsRequest.requestorName);
62     req->tbsRequest.requestorName = gen;
63     return 1;
64 }
65
66 /* Add a certificate to an OCSP request */
67
68 int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
69 {
70     OCSP_SIGNATURE *sig;
71     if (req->optionalSignature == NULL)
72         req->optionalSignature = OCSP_SIGNATURE_new();
73     sig = req->optionalSignature;
74     if (sig == NULL)
75         return 0;
76     if (cert == NULL)
77         return 1;
78     if (sig->certs == NULL
79         && (sig->certs = sk_X509_new_null()) == NULL)
80         return 0;
81
82     if (!sk_X509_push(sig->certs, cert))
83         return 0;
84     X509_up_ref(cert);
85     return 1;
86 }
87
88 /*
89  * Sign an OCSP request set the requestorName to the subject name of an
90  * optional signers certificate and include one or more optional certificates
91  * in the request. Behaves like PKCS7_sign().
92  */
93
94 int OCSP_request_sign(OCSP_REQUEST *req,
95                       X509 *signer,
96                       EVP_PKEY *key,
97                       const EVP_MD *dgst,
98                       STACK_OF(X509) *certs, unsigned long flags)
99 {
100     int i;
101     X509 *x;
102
103     if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
104         goto err;
105
106     if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL)
107         goto err;
108     if (key) {
109         if (!X509_check_private_key(signer, key)) {
110             OCSPerr(OCSP_F_OCSP_REQUEST_SIGN,
111                     OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
112             goto err;
113         }
114         if (!OCSP_REQUEST_sign(req, key, dgst))
115             goto err;
116     }
117
118     if (!(flags & OCSP_NOCERTS)) {
119         if (!OCSP_request_add1_cert(req, signer))
120             goto err;
121         for (i = 0; i < sk_X509_num(certs); i++) {
122             x = sk_X509_value(certs, i);
123             if (!OCSP_request_add1_cert(req, x))
124                 goto err;
125         }
126     }
127
128     return 1;
129  err:
130     OCSP_SIGNATURE_free(req->optionalSignature);
131     req->optionalSignature = NULL;
132     return 0;
133 }
134
135 /* Get response status */
136
137 int OCSP_response_status(OCSP_RESPONSE *resp)
138 {
139     return ASN1_ENUMERATED_get(resp->responseStatus);
140 }
141
142 /*
143  * Extract basic response from OCSP_RESPONSE or NULL if no basic response
144  * present.
145  */
146
147 OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
148 {
149     OCSP_RESPBYTES *rb;
150     rb = resp->responseBytes;
151     if (!rb) {
152         OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
153         return NULL;
154     }
155     if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
156         OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
157         return NULL;
158     }
159
160     return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
161 }
162
163 ASN1_OCTET_STRING *OCSP_resp_get0_signature(OCSP_BASICRESP *bs)
164 {
165     return bs->signature;
166 }
167
168 /*
169  * Return number of OCSP_SINGLERESP responses present in a basic response.
170  */
171
172 int OCSP_resp_count(OCSP_BASICRESP *bs)
173 {
174     if (!bs)
175         return -1;
176     return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses);
177 }
178
179 /* Extract an OCSP_SINGLERESP response with a given index */
180
181 OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
182 {
183     if (!bs)
184         return NULL;
185     return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx);
186 }
187
188 ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(OCSP_BASICRESP* bs)
189 {
190     if (!bs)
191         return NULL;
192     return bs->tbsResponseData.producedAt;
193 }
194
195 /* Look single response matching a given certificate ID */
196
197 int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
198 {
199     int i;
200     STACK_OF(OCSP_SINGLERESP) *sresp;
201     OCSP_SINGLERESP *single;
202     if (!bs)
203         return -1;
204     if (last < 0)
205         last = 0;
206     else
207         last++;
208     sresp = bs->tbsResponseData.responses;
209     for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
210         single = sk_OCSP_SINGLERESP_value(sresp, i);
211         if (!OCSP_id_cmp(id, single->certId))
212             return i;
213     }
214     return -1;
215 }
216
217 /*
218  * Extract status information from an OCSP_SINGLERESP structure. Note: the
219  * revtime and reason values are only set if the certificate status is
220  * revoked. Returns numerical value of status.
221  */
222
223 int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
224                             ASN1_GENERALIZEDTIME **revtime,
225                             ASN1_GENERALIZEDTIME **thisupd,
226                             ASN1_GENERALIZEDTIME **nextupd)
227 {
228     int ret;
229     OCSP_CERTSTATUS *cst;
230     if (!single)
231         return -1;
232     cst = single->certStatus;
233     ret = cst->type;
234     if (ret == V_OCSP_CERTSTATUS_REVOKED) {
235         OCSP_REVOKEDINFO *rev = cst->value.revoked;
236         if (revtime)
237             *revtime = rev->revocationTime;
238         if (reason) {
239             if (rev->revocationReason)
240                 *reason = ASN1_ENUMERATED_get(rev->revocationReason);
241             else
242                 *reason = -1;
243         }
244     }
245     if (thisupd)
246         *thisupd = single->thisUpdate;
247     if (nextupd)
248         *nextupd = single->nextUpdate;
249     return ret;
250 }
251
252 /*
253  * This function combines the previous ones: look up a certificate ID and if
254  * found extract status information. Return 0 is successful.
255  */
256
257 int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
258                           int *reason,
259                           ASN1_GENERALIZEDTIME **revtime,
260                           ASN1_GENERALIZEDTIME **thisupd,
261                           ASN1_GENERALIZEDTIME **nextupd)
262 {
263     int i;
264     OCSP_SINGLERESP *single;
265     i = OCSP_resp_find(bs, id, -1);
266     /* Maybe check for multiple responses and give an error? */
267     if (i < 0)
268         return 0;
269     single = OCSP_resp_get0(bs, i);
270     i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
271     if (status)
272         *status = i;
273     return 1;
274 }
275
276 /*
277  * Check validity of thisUpdate and nextUpdate fields. It is possible that
278  * the request will take a few seconds to process and/or the time wont be
279  * totally accurate. Therefore to avoid rejecting otherwise valid time we
280  * allow the times to be within 'nsec' of the current time. Also to avoid
281  * accepting very old responses without a nextUpdate field an optional maxage
282  * parameter specifies the maximum age the thisUpdate field can be.
283  */
284
285 int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
286                         ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
287 {
288     int ret = 1;
289     time_t t_now, t_tmp;
290     time(&t_now);
291     /* Check thisUpdate is valid and not more than nsec in the future */
292     if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
293         OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
294         ret = 0;
295     } else {
296         t_tmp = t_now + nsec;
297         if (X509_cmp_time(thisupd, &t_tmp) > 0) {
298             OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
299             ret = 0;
300         }
301
302         /*
303          * If maxsec specified check thisUpdate is not more than maxsec in
304          * the past
305          */
306         if (maxsec >= 0) {
307             t_tmp = t_now - maxsec;
308             if (X509_cmp_time(thisupd, &t_tmp) < 0) {
309                 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
310                 ret = 0;
311             }
312         }
313     }
314
315     if (!nextupd)
316         return ret;
317
318     /* Check nextUpdate is valid and not more than nsec in the past */
319     if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
320         OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
321         ret = 0;
322     } else {
323         t_tmp = t_now - nsec;
324         if (X509_cmp_time(nextupd, &t_tmp) < 0) {
325             OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
326             ret = 0;
327         }
328     }
329
330     /* Also don't allow nextUpdate to precede thisUpdate */
331     if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
332         OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
333                 OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
334         ret = 0;
335     }
336
337     return ret;
338 }
339
340 OCSP_CERTID *OCSP_SINGLERESP_get0_id(OCSP_SINGLERESP *single)
341 {
342     return single->certId;
343 }