Coverage Report

Created: 2025-06-13 06:58

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