Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/ocsp/ocsp_ext.c
Line
Count
Source (jump to first uncovered line)
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 <stdio.h>
11
#include "internal/cryptlib.h"
12
#include <openssl/objects.h>
13
#include <openssl/x509.h>
14
#include <openssl/ocsp.h>
15
#include "ocsp_lcl.h"
16
#include <openssl/rand.h>
17
#include <openssl/x509v3.h>
18
19
/* Standard wrapper functions for extensions */
20
21
/* OCSP request extensions */
22
23
int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
24
0
{
25
0
    return X509v3_get_ext_count(x->tbsRequest.requestExtensions);
26
0
}
27
28
int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
29
0
{
30
0
    return (X509v3_get_ext_by_NID
31
0
            (x->tbsRequest.requestExtensions, nid, lastpos));
32
0
}
33
34
int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj,
35
                                int lastpos)
36
0
{
37
0
    return (X509v3_get_ext_by_OBJ
38
0
            (x->tbsRequest.requestExtensions, obj, lastpos));
39
0
}
40
41
int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
42
0
{
43
0
    return (X509v3_get_ext_by_critical
44
0
            (x->tbsRequest.requestExtensions, crit, lastpos));
45
0
}
46
47
X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
48
0
{
49
0
    return X509v3_get_ext(x->tbsRequest.requestExtensions, loc);
50
0
}
51
52
X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
53
0
{
54
0
    return X509v3_delete_ext(x->tbsRequest.requestExtensions, loc);
55
0
}
56
57
void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
58
0
{
59
0
    return X509V3_get_d2i(x->tbsRequest.requestExtensions, nid, crit, idx);
60
0
}
61
62
int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
63
                              unsigned long flags)
64
0
{
65
0
    return X509V3_add1_i2d(&x->tbsRequest.requestExtensions, nid, value,
66
0
                           crit, flags);
67
0
}
68
69
int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
70
0
{
71
0
    return (X509v3_add_ext(&(x->tbsRequest.requestExtensions), ex, loc) !=
72
0
            NULL);
73
0
}
74
75
/* Single extensions */
76
77
int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
78
0
{
79
0
    return X509v3_get_ext_count(x->singleRequestExtensions);
80
0
}
81
82
int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
83
0
{
84
0
    return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos);
85
0
}
86
87
int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj,
88
                               int lastpos)
89
0
{
90
0
    return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos);
91
0
}
92
93
int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
94
0
{
95
0
    return (X509v3_get_ext_by_critical
96
0
            (x->singleRequestExtensions, crit, lastpos));
97
0
}
98
99
X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
100
0
{
101
0
    return X509v3_get_ext(x->singleRequestExtensions, loc);
102
0
}
103
104
X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
105
0
{
106
0
    return X509v3_delete_ext(x->singleRequestExtensions, loc);
107
0
}
108
109
void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
110
0
{
111
0
    return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
112
0
}
113
114
int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
115
                             unsigned long flags)
116
0
{
117
0
    return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
118
0
                           flags);
119
0
}
120
121
int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
122
0
{
123
0
    return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
124
0
}
125
126
/* OCSP Basic response */
127
128
int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
129
0
{
130
0
    return X509v3_get_ext_count(x->tbsResponseData.responseExtensions);
131
0
}
132
133
int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
134
0
{
135
0
    return (X509v3_get_ext_by_NID
136
0
            (x->tbsResponseData.responseExtensions, nid, lastpos));
137
0
}
138
139
int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj,
140
                                  int lastpos)
141
0
{
142
0
    return (X509v3_get_ext_by_OBJ
143
0
            (x->tbsResponseData.responseExtensions, obj, lastpos));
144
0
}
145
146
int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
147
                                       int lastpos)
148
0
{
149
0
    return (X509v3_get_ext_by_critical
150
0
            (x->tbsResponseData.responseExtensions, crit, lastpos));
151
0
}
152
153
X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
154
0
{
155
0
    return X509v3_get_ext(x->tbsResponseData.responseExtensions, loc);
156
0
}
157
158
X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
159
0
{
160
0
    return X509v3_delete_ext(x->tbsResponseData.responseExtensions, loc);
161
0
}
162
163
void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
164
                                  int *idx)
165
0
{
166
0
    return X509V3_get_d2i(x->tbsResponseData.responseExtensions, nid, crit,
167
0
                          idx);
168
0
}
169
170
int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
171
                                int crit, unsigned long flags)
172
0
{
173
0
    return X509V3_add1_i2d(&x->tbsResponseData.responseExtensions, nid,
174
0
                           value, crit, flags);
175
0
}
176
177
int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
178
0
{
179
0
    return (X509v3_add_ext(&(x->tbsResponseData.responseExtensions), ex, loc)
180
0
            != NULL);
181
0
}
182
183
/* OCSP single response extensions */
184
185
int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
186
0
{
187
0
    return X509v3_get_ext_count(x->singleExtensions);
188
0
}
189
190
int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
191
0
{
192
0
    return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos);
193
0
}
194
195
int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj,
196
                                   int lastpos)
197
0
{
198
0
    return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos);
199
0
}
200
201
int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
202
                                        int lastpos)
203
0
{
204
0
    return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos);
205
0
}
206
207
X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
208
0
{
209
0
    return X509v3_get_ext(x->singleExtensions, loc);
210
0
}
211
212
X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
213
0
{
214
0
    return X509v3_delete_ext(x->singleExtensions, loc);
215
0
}
216
217
void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
218
                                   int *idx)
219
0
{
220
0
    return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
221
0
}
222
223
int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
224
                                 int crit, unsigned long flags)
225
0
{
226
0
    return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
227
0
}
228
229
int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
230
0
{
231
0
    return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
232
0
}
233
234
/* also CRL Entry Extensions */
235
236
/* Nonce handling functions */
237
238
/*
239
 * Add a nonce to an extension stack. A nonce can be specified or if NULL a
240
 * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
241
 * OCTET STRING containing the nonce, previous versions used the raw nonce.
242
 */
243
244
static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
245
                           unsigned char *val, int len)
246
0
{
247
0
    unsigned char *tmpval;
248
0
    ASN1_OCTET_STRING os;
249
0
    int ret = 0;
250
0
    if (len <= 0)
251
0
        len = OCSP_DEFAULT_NONCE_LENGTH;
252
0
    /*
253
0
     * Create the OCTET STRING manually by writing out the header and
254
0
     * appending the content octets. This avoids an extra memory allocation
255
0
     * operation in some cases. Applications should *NOT* do this because it
256
0
     * relies on library internals.
257
0
     */
258
0
    os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
259
0
    if (os.length < 0)
260
0
        return 0;
261
0
262
0
    os.data = OPENSSL_malloc(os.length);
263
0
    if (os.data == NULL)
264
0
        goto err;
265
0
    tmpval = os.data;
266
0
    ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
267
0
    if (val)
268
0
        memcpy(tmpval, val, len);
269
0
    else if (RAND_bytes(tmpval, len) <= 0)
270
0
        goto err;
271
0
    if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
272
0
                         &os, 0, X509V3_ADD_REPLACE))
273
0
        goto err;
274
0
    ret = 1;
275
0
 err:
276
0
    OPENSSL_free(os.data);
277
0
    return ret;
278
0
}
279
280
/* Add nonce to an OCSP request */
281
282
int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
283
0
{
284
0
    return ocsp_add1_nonce(&req->tbsRequest.requestExtensions, val, len);
285
0
}
286
287
/* Same as above but for a response */
288
289
int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
290
0
{
291
0
    return ocsp_add1_nonce(&resp->tbsResponseData.responseExtensions, val,
292
0
                           len);
293
0
}
294
295
/*-
296
 * Check nonce validity in a request and response.
297
 * Return value reflects result:
298
 *  1: nonces present and equal.
299
 *  2: nonces both absent.
300
 *  3: nonce present in response only.
301
 *  0: nonces both present and not equal.
302
 * -1: nonce in request only.
303
 *
304
 *  For most responders clients can check return > 0.
305
 *  If responder doesn't handle nonces return != 0 may be
306
 *  necessary. return == 0 is always an error.
307
 */
308
309
int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
310
0
{
311
0
    /*
312
0
     * Since we are only interested in the presence or absence of
313
0
     * the nonce and comparing its value there is no need to use
314
0
     * the X509V3 routines: this way we can avoid them allocating an
315
0
     * ASN1_OCTET_STRING structure for the value which would be
316
0
     * freed immediately anyway.
317
0
     */
318
0
319
0
    int req_idx, resp_idx;
320
0
    X509_EXTENSION *req_ext, *resp_ext;
321
0
    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
322
0
    resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
323
0
    /* Check both absent */
324
0
    if ((req_idx < 0) && (resp_idx < 0))
325
0
        return 2;
326
0
    /* Check in request only */
327
0
    if ((req_idx >= 0) && (resp_idx < 0))
328
0
        return -1;
329
0
    /* Check in response but not request */
330
0
    if ((req_idx < 0) && (resp_idx >= 0))
331
0
        return 3;
332
0
    /*
333
0
     * Otherwise nonce in request and response so retrieve the extensions
334
0
     */
335
0
    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
336
0
    resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
337
0
    if (ASN1_OCTET_STRING_cmp(X509_EXTENSION_get_data(req_ext),
338
0
                              X509_EXTENSION_get_data(resp_ext)))
339
0
        return 0;
340
0
    return 1;
341
0
}
342
343
/*
344
 * Copy the nonce value (if any) from an OCSP request to a response.
345
 */
346
347
int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
348
0
{
349
0
    X509_EXTENSION *req_ext;
350
0
    int req_idx;
351
0
    /* Check for nonce in request */
352
0
    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
353
0
    /* If no nonce that's OK */
354
0
    if (req_idx < 0)
355
0
        return 2;
356
0
    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
357
0
    return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
358
0
}
359
360
X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim)
361
0
{
362
0
    X509_EXTENSION *x = NULL;
363
0
    OCSP_CRLID *cid = NULL;
364
0
365
0
    if ((cid = OCSP_CRLID_new()) == NULL)
366
0
        goto err;
367
0
    if (url) {
368
0
        if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL)
369
0
            goto err;
370
0
        if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
371
0
            goto err;
372
0
    }
373
0
    if (n) {
374
0
        if ((cid->crlNum = ASN1_INTEGER_new()) == NULL)
375
0
            goto err;
376
0
        if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
377
0
            goto err;
378
0
    }
379
0
    if (tim) {
380
0
        if ((cid->crlTime = ASN1_GENERALIZEDTIME_new()) == NULL)
381
0
            goto err;
382
0
        if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
383
0
            goto err;
384
0
    }
385
0
    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
386
0
 err:
387
0
    OCSP_CRLID_free(cid);
388
0
    return x;
389
0
}
390
391
/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
392
X509_EXTENSION *OCSP_accept_responses_new(char **oids)
393
0
{
394
0
    int nid;
395
0
    STACK_OF(ASN1_OBJECT) *sk = NULL;
396
0
    ASN1_OBJECT *o = NULL;
397
0
    X509_EXTENSION *x = NULL;
398
0
399
0
    if ((sk = sk_ASN1_OBJECT_new_null()) == NULL)
400
0
        goto err;
401
0
    while (oids && *oids) {
402
0
        if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
403
0
            sk_ASN1_OBJECT_push(sk, o);
404
0
        oids++;
405
0
    }
406
0
    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
407
0
 err:
408
0
    sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
409
0
    return x;
410
0
}
411
412
/*  ArchiveCutoff ::= GeneralizedTime */
413
X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
414
0
{
415
0
    X509_EXTENSION *x = NULL;
416
0
    ASN1_GENERALIZEDTIME *gt = NULL;
417
0
418
0
    if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL)
419
0
        goto err;
420
0
    if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
421
0
        goto err;
422
0
    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
423
0
 err:
424
0
    ASN1_GENERALIZEDTIME_free(gt);
425
0
    return x;
426
0
}
427
428
/*
429
 * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
430
 * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This method
431
 * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
432
 */
433
X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls)
434
0
{
435
0
    X509_EXTENSION *x = NULL;
436
0
    ASN1_IA5STRING *ia5 = NULL;
437
0
    OCSP_SERVICELOC *sloc = NULL;
438
0
    ACCESS_DESCRIPTION *ad = NULL;
439
0
440
0
    if ((sloc = OCSP_SERVICELOC_new()) == NULL)
441
0
        goto err;
442
0
    if ((sloc->issuer = X509_NAME_dup(issuer)) == NULL)
443
0
        goto err;
444
0
    if (urls && *urls
445
0
        && (sloc->locator = sk_ACCESS_DESCRIPTION_new_null()) == NULL)
446
0
        goto err;
447
0
    while (urls && *urls) {
448
0
        if ((ad = ACCESS_DESCRIPTION_new()) == NULL)
449
0
            goto err;
450
0
        if ((ad->method = OBJ_nid2obj(NID_ad_OCSP)) == NULL)
451
0
            goto err;
452
0
        if ((ad->location = GENERAL_NAME_new()) == NULL)
453
0
            goto err;
454
0
        if ((ia5 = ASN1_IA5STRING_new()) == NULL)
455
0
            goto err;
456
0
        if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
457
0
            goto err;
458
0
        ad->location->type = GEN_URI;
459
0
        ad->location->d.ia5 = ia5;
460
0
        ia5 = NULL;
461
0
        if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
462
0
            goto err;
463
0
        ad = NULL;
464
0
        urls++;
465
0
    }
466
0
    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
467
0
 err:
468
0
    ASN1_IA5STRING_free(ia5);
469
0
    ACCESS_DESCRIPTION_free(ad);
470
0
    OCSP_SERVICELOC_free(sloc);
471
0
    return x;
472
0
}