Coverage Report

Created: 2022-08-24 06:37

/src/wolfssl-openssl-api/src/ocsp.c
Line
Count
Source (jump to first uncovered line)
1
/* ocsp.c
2
 *
3
 * Copyright (C) 2006-2022 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
23
  /* Name change compatibility layer no longer needs to be included here */
24
25
#ifdef HAVE_CONFIG_H
26
    #include <config.h>
27
#endif
28
29
#include <wolfssl/wolfcrypt/settings.h>
30
31
#ifndef WOLFCRYPT_ONLY
32
#ifdef HAVE_OCSP
33
34
#include <wolfssl/error-ssl.h>
35
#include <wolfssl/ocsp.h>
36
#include <wolfssl/internal.h>
37
38
#ifdef NO_INLINE
39
    #include <wolfssl/wolfcrypt/misc.h>
40
#else
41
    #define WOLFSSL_MISC_INCLUDED
42
    #include <wolfcrypt/src/misc.c>
43
#endif
44
45
46
int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
47
0
{
48
0
    WOLFSSL_ENTER("InitOCSP");
49
50
0
    ForceZero(ocsp, sizeof(WOLFSSL_OCSP));
51
52
0
    if (wc_InitMutex(&ocsp->ocspLock) != 0)
53
0
        return BAD_MUTEX_E;
54
55
0
    ocsp->cm = cm;
56
57
0
    return 0;
58
0
}
59
60
61
static int InitOcspEntry(OcspEntry* entry, OcspRequest* request)
62
0
{
63
0
    WOLFSSL_ENTER("InitOcspEntry");
64
65
0
    ForceZero(entry, sizeof(OcspEntry));
66
67
0
    XMEMCPY(entry->issuerHash,    request->issuerHash,    OCSP_DIGEST_SIZE);
68
0
    XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE);
69
70
0
    return 0;
71
0
}
72
73
74
static void FreeOcspEntry(OcspEntry* entry, void* heap)
75
0
{
76
0
    CertStatus *status, *next;
77
78
0
    if (entry == NULL || !entry->ownStatus)
79
0
        return;
80
81
0
    WOLFSSL_ENTER("FreeOcspEntry");
82
83
0
    for (status = entry->status; status; status = next) {
84
0
        next = status->next;
85
86
0
        if (status->rawOcspResponse)
87
0
            XFREE(status->rawOcspResponse, heap, DYNAMIC_TYPE_OCSP_STATUS);
88
89
0
#ifdef OPENSSL_EXTRA
90
0
        if (status->serialInt) {
91
0
            if (status->serialInt->isDynamic) {
92
0
                XFREE(status->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
93
0
            }
94
0
            XFREE(status->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
95
0
        }
96
0
        status->serialInt = NULL;
97
0
#endif
98
99
0
        XFREE(status, heap, DYNAMIC_TYPE_OCSP_STATUS);
100
0
    }
101
102
0
    (void)heap;
103
0
}
104
105
106
void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
107
0
{
108
0
    OcspEntry *entry, *next;
109
110
0
    WOLFSSL_ENTER("FreeOCSP");
111
112
0
    for (entry = ocsp->ocspList; entry; entry = next) {
113
0
        next = entry->next;
114
0
        FreeOcspEntry(entry, ocsp->cm->heap);
115
0
        XFREE(entry, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
116
0
    }
117
118
0
    wc_FreeMutex(&ocsp->ocspLock);
119
120
0
    if (dynamic)
121
0
        XFREE(ocsp, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
122
123
0
}
124
125
126
static int xstat2err(int st)
127
0
{
128
0
    switch (st) {
129
0
        case CERT_GOOD:
130
0
            return 0;
131
0
        case CERT_REVOKED:
132
0
            return OCSP_CERT_REVOKED;
133
0
        default:
134
0
            return OCSP_CERT_UNKNOWN;
135
0
    }
136
0
}
137
138
int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer, WOLFSSL* ssl)
139
0
{
140
0
    int ret = OCSP_LOOKUP_FAIL;
141
142
0
#ifdef WOLFSSL_SMALL_STACK
143
0
    OcspRequest* ocspRequest;
144
#else
145
    OcspRequest ocspRequest[1];
146
#endif
147
148
0
    WOLFSSL_ENTER("CheckCertOCSP");
149
150
151
0
#ifdef WOLFSSL_SMALL_STACK
152
0
    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
153
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
154
0
    if (ocspRequest == NULL) {
155
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
156
0
        return MEMORY_E;
157
0
    }
158
0
#endif
159
160
0
    if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
161
0
                                                         ocsp->cm->heap) == 0) {
162
0
        ocspRequest->ssl = ssl;
163
0
        ret = CheckOcspRequest(ocsp, ocspRequest, responseBuffer);
164
165
0
        FreeOcspRequest(ocspRequest);
166
0
    }
167
168
0
#ifdef WOLFSSL_SMALL_STACK
169
0
    XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
170
0
#endif
171
172
0
    WOLFSSL_LEAVE("CheckCertOCSP", ret);
173
0
    return ret;
174
0
}
175
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer)
176
0
{
177
0
    return CheckCertOCSP_ex(ocsp, cert, responseBuffer, NULL);
178
0
}
179
180
static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
181
                                                              OcspEntry** entry)
182
0
{
183
0
    WOLFSSL_ENTER("GetOcspEntry");
184
185
0
    *entry = NULL;
186
187
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
188
0
        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
189
0
        return BAD_MUTEX_E;
190
0
    }
191
192
0
    for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next)
193
0
        if (XMEMCMP((*entry)->issuerHash,    request->issuerHash,
194
0
                                                         OCSP_DIGEST_SIZE) == 0
195
0
        &&  XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash,
196
0
                                                         OCSP_DIGEST_SIZE) == 0)
197
0
            break;
198
199
0
    if (*entry == NULL) {
200
0
        *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry),
201
0
                                       ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
202
0
        if (*entry) {
203
0
            InitOcspEntry(*entry, request);
204
0
            (*entry)->next = ocsp->ocspList;
205
0
            ocsp->ocspList = *entry;
206
0
        }
207
0
    }
208
209
0
    wc_UnLockMutex(&ocsp->ocspLock);
210
211
0
    return *entry ? 0 : MEMORY_ERROR;
212
0
}
213
214
215
/* Mallocs responseBuffer->buffer and is up to caller to free on success
216
 *
217
 * Returns OCSP status
218
 */
219
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
220
                  OcspEntry* entry, CertStatus** status, buffer* responseBuffer)
221
0
{
222
0
    int ret = OCSP_INVALID_STATUS;
223
224
0
    WOLFSSL_ENTER("GetOcspStatus");
225
226
0
    *status = NULL;
227
228
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
229
0
        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
230
0
        return BAD_MUTEX_E;
231
0
    }
232
233
0
    for (*status = entry->status; *status; *status = (*status)->next)
234
0
        if ((*status)->serialSz == request->serialSz
235
0
        &&  !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
236
0
            break;
237
238
0
    if (responseBuffer && *status && !(*status)->rawOcspResponse) {
239
        /* force fetching again */
240
0
        ret = OCSP_INVALID_STATUS;
241
0
    }
242
0
    else if (*status) {
243
0
#ifndef NO_ASN_TIME
244
0
        if (XVALIDATE_DATE((*status)->thisDate,
245
0
                                             (*status)->thisDateFormat, BEFORE)
246
0
        &&  ((*status)->nextDate[0] != 0)
247
0
        &&  XVALIDATE_DATE((*status)->nextDate,
248
0
                                             (*status)->nextDateFormat, AFTER))
249
0
#endif
250
0
        {
251
0
            ret = xstat2err((*status)->status);
252
253
0
            if (responseBuffer) {
254
0
                responseBuffer->buffer = (byte*)XMALLOC(
255
0
                   (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
256
257
0
                if (responseBuffer->buffer) {
258
0
                    responseBuffer->length = (*status)->rawOcspResponseSz;
259
0
                    XMEMCPY(responseBuffer->buffer,
260
0
                            (*status)->rawOcspResponse,
261
0
                            (*status)->rawOcspResponseSz);
262
0
                }
263
0
            }
264
0
        }
265
0
    }
266
267
0
    wc_UnLockMutex(&ocsp->ocspLock);
268
269
0
    return ret;
270
0
}
271
272
/* Check that the response for validity. Store result in status.
273
 *
274
 * ocsp           Context object for OCSP status.
275
 * response       OCSP response message data.
276
 * responseSz     Length of OCSP response message data.
277
 * reponseBuffer  Buffer object to return the response with.
278
 * status         The certificate status object.
279
 * entry          The OCSP entry for this certificate.
280
 * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
281
 */
282
int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
283
                      WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
284
                      OcspEntry *entry, OcspRequest *ocspRequest)
285
0
{
286
0
#ifdef WOLFSSL_SMALL_STACK
287
0
    CertStatus*   newStatus;
288
0
    OcspEntry*    newSingle;
289
0
    OcspResponse* ocspResponse;
290
#else
291
    CertStatus    newStatus[1];
292
    OcspEntry     newSingle[1];
293
    OcspResponse  ocspResponse[1];
294
#endif
295
0
    int           ret;
296
0
    int           validated      = 0;    /* ocsp validation flag */
297
298
0
#ifdef WOLFSSL_SMALL_STACK
299
0
    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
300
0
                                                       DYNAMIC_TYPE_OCSP_STATUS);
301
0
    newSingle = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
302
0
                                                       DYNAMIC_TYPE_OCSP_ENTRY);
303
0
    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
304
0
                                                       DYNAMIC_TYPE_OCSP_REQUEST);
305
306
0
    if (newStatus == NULL || newSingle == NULL || ocspResponse == NULL) {
307
0
        if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_OCSP_STATUS);
308
0
        if (newSingle) XFREE(newSingle, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
309
0
        if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
310
311
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
312
0
        return MEMORY_E;
313
0
    }
314
0
#endif
315
0
    InitOcspResponse(ocspResponse, newSingle, newStatus, response, responseSz,
316
0
                     ocsp->cm->heap);
317
318
0
    ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
319
0
    if (ret != 0) {
320
0
        ocsp->error = ret;
321
0
        WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
322
0
        goto end;
323
0
    }
324
325
0
    if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
326
0
        WOLFSSL_MSG("OcspResponse status bad");
327
0
        goto end;
328
0
    }
329
0
    if (ocspRequest != NULL) {
330
0
        ret = CompareOcspReqResp(ocspRequest, ocspResponse);
331
0
        if (ret != 0) {
332
0
            goto end;
333
0
        }
334
0
    }
335
336
0
    if (responseBuffer) {
337
0
        responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap,
338
0
                                                DYNAMIC_TYPE_TMP_BUFFER);
339
340
0
        if (responseBuffer->buffer) {
341
0
            responseBuffer->length = responseSz;
342
0
            XMEMCPY(responseBuffer->buffer, response, responseSz);
343
0
        }
344
0
    }
345
346
0
    ret = xstat2err(ocspResponse->single->status->status);
347
0
    if (ret == 0) {
348
0
        validated = 1;
349
0
    }
350
351
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
352
0
        ret = BAD_MUTEX_E;
353
0
        goto end;
354
0
    }
355
356
0
    if (status != NULL) {
357
0
        if (status->rawOcspResponse) {
358
0
            XFREE(status->rawOcspResponse, ocsp->cm->heap,
359
0
                  DYNAMIC_TYPE_OCSP_STATUS);
360
0
        }
361
362
        /* Replace existing certificate entry with updated */
363
0
        newSingle->status->next = status->next;
364
0
        XMEMCPY(status, newSingle->status, sizeof(CertStatus));
365
0
    }
366
0
    else {
367
        /* Save new certificate entry */
368
0
        status = (CertStatus*)XMALLOC(sizeof(CertStatus),
369
0
                                      ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
370
0
        if (status != NULL) {
371
0
            XMEMCPY(status, newSingle->status, sizeof(CertStatus));
372
0
            status->next  = entry->status;
373
0
            entry->status = status;
374
0
            entry->ownStatus = 1;
375
0
            entry->totalStatus++;
376
0
        }
377
0
    }
378
379
0
    if (status && responseBuffer && responseBuffer->buffer) {
380
0
        status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
381
0
                                                 ocsp->cm->heap,
382
0
                                                 DYNAMIC_TYPE_OCSP_STATUS);
383
384
0
        if (status->rawOcspResponse) {
385
0
            status->rawOcspResponseSz = responseBuffer->length;
386
0
            XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
387
0
                    responseBuffer->length);
388
0
        }
389
0
    }
390
391
0
    wc_UnLockMutex(&ocsp->ocspLock);
392
393
0
end:
394
0
    if (ret == 0 && validated == 1) {
395
0
        WOLFSSL_MSG("New OcspResponse validated");
396
0
    } else if (ret != OCSP_CERT_REVOKED) {
397
0
        ret = OCSP_LOOKUP_FAIL;
398
0
    }
399
400
0
#ifdef WOLFSSL_SMALL_STACK
401
0
    XFREE(newStatus,    NULL, DYNAMIC_TYPE_OCSP_STATUS);
402
0
    XFREE(newSingle,    NULL, DYNAMIC_TYPE_OCSP_ENTRY);
403
0
    XFREE(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
404
0
#endif
405
0
    return ret;
406
0
}
407
408
/* 0 on success */
409
/* allow user to override the maximum request size at build-time */
410
#ifndef OCSP_MAX_REQUEST_SZ
411
0
#define OCSP_MAX_REQUEST_SZ 2048
412
#endif
413
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
414
                                                      buffer* responseBuffer)
415
0
{
416
0
    OcspEntry*  entry          = NULL;
417
0
    CertStatus* status         = NULL;
418
0
    byte*       request        = NULL;
419
0
    int         requestSz      = OCSP_MAX_REQUEST_SZ;
420
0
    int         responseSz     = 0;
421
0
    byte*       response       = NULL;
422
0
    const char* url            = NULL;
423
0
    int         urlSz          = 0;
424
0
    int         ret            = -1;
425
0
    WOLFSSL*    ssl;
426
0
    void*       ioCtx;
427
428
0
    WOLFSSL_ENTER("CheckOcspRequest");
429
430
0
    if (ocsp == NULL || ocspRequest == NULL)
431
0
        return BAD_FUNC_ARG;
432
433
0
    if (responseBuffer) {
434
0
        responseBuffer->buffer = NULL;
435
0
        responseBuffer->length = 0;
436
0
    }
437
438
0
    ret = GetOcspEntry(ocsp, ocspRequest, &entry);
439
0
    if (ret != 0)
440
0
        return ret;
441
442
0
    ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
443
0
    if (ret != OCSP_INVALID_STATUS)
444
0
        return ret;
445
446
    /* get SSL and IOCtx */
447
0
    ssl = (WOLFSSL*)ocspRequest->ssl;
448
0
    ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
449
0
                                        ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
450
451
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
452
0
    if (ocsp->statusCb != NULL && ssl != NULL) {
453
0
        ret = ocsp->statusCb(ssl, ioCtx);
454
0
        if (ret == 0) {
455
0
            ret = wolfSSL_get_ocsp_response(ssl, &response);
456
0
            ret = CheckOcspResponse(ocsp, response, ret, responseBuffer, status,
457
0
                                entry, NULL);
458
0
            if (response != NULL)
459
0
                XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
460
0
            return ret;
461
0
        }
462
0
        WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error);
463
0
        return OCSP_LOOKUP_FAIL;
464
0
    }
465
0
#endif
466
467
0
    if (ocsp->cm->ocspUseOverrideURL) {
468
0
        url = ocsp->cm->ocspOverrideURL;
469
0
        if (url != NULL && url[0] != '\0')
470
0
            urlSz = (int)XSTRLEN(url);
471
0
        else
472
0
            return OCSP_NEED_URL;
473
0
    }
474
0
    else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
475
0
        url = (const char *)ocspRequest->url;
476
0
        urlSz = ocspRequest->urlSz;
477
0
    }
478
0
    else {
479
        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
480
0
        WOLFSSL_MSG("Cert has no OCSP URL, assuming CERT_GOOD");
481
0
        return 0;
482
0
    }
483
484
0
    request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
485
0
    if (request == NULL) {
486
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
487
0
        if (responseBuffer) {
488
0
            XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
489
0
            responseBuffer->buffer = NULL;
490
0
        }
491
0
        return MEMORY_ERROR;
492
0
    }
493
494
0
    requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
495
0
    if (requestSz > 0 && ocsp->cm->ocspIOCb) {
496
0
        responseSz = ocsp->cm->ocspIOCb(ioCtx, url, urlSz,
497
0
                                        request, requestSz, &response);
498
0
    }
499
0
    if (responseSz == WOLFSSL_CBIO_ERR_WANT_READ) {
500
0
        ret = OCSP_WANT_READ;
501
0
    }
502
503
0
    XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
504
505
0
    if (responseSz >= 0 && response) {
506
0
        ret = CheckOcspResponse(ocsp, response, responseSz, responseBuffer, status,
507
0
                            entry, ocspRequest);
508
0
    }
509
510
0
    if (response != NULL && ocsp->cm->ocspRespFreeCb)
511
0
        ocsp->cm->ocspRespFreeCb(ioCtx, response);
512
513
    /* Keep responseBuffer in the case of getting to response check. Caller
514
     * should free responseBuffer after checking OCSP return value in "ret" */
515
0
    WOLFSSL_LEAVE("CheckOcspRequest", ret);
516
0
    return ret;
517
0
}
518
519
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
520
    defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIGHTY)
521
522
int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
523
    WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
524
    WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
525
    WOLFSSL_ASN1_TIME** nextupd)
526
0
{
527
0
    WOLFSSL_OCSP_SINGLERESP* single;
528
529
0
    if (bs == NULL || id == NULL)
530
0
        return WOLFSSL_FAILURE;
531
532
0
    single = bs->single;
533
0
    while (single != NULL) {
534
0
        if ((XMEMCMP(single->status->serial, id->status->serial, single->status->serialSz) == 0)
535
0
         && (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0)
536
0
         && (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) {
537
0
            break;
538
0
        }
539
0
        single = single->next;
540
0
    }
541
542
0
    if (single == NULL)
543
0
        return WOLFSSL_FAILURE;
544
545
0
    if (status != NULL)
546
0
        *status = single->status->status;
547
0
    if (thisupd != NULL)
548
0
        *thisupd = &single->status->thisDateParsed;
549
0
    if (nextupd != NULL)
550
0
        *nextupd = &single->status->nextDateParsed;
551
552
    /* TODO: Not needed for Nginx or httpd */
553
0
    if (reason != NULL)
554
0
        *reason = 0;
555
0
    if (revtime != NULL)
556
0
        *revtime = NULL;
557
558
0
    return WOLFSSL_SUCCESS;
559
0
}
560
561
const char *wolfSSL_OCSP_cert_status_str(long s)
562
0
{
563
0
    switch (s) {
564
0
        case CERT_GOOD:
565
0
            return "good";
566
0
        case CERT_REVOKED:
567
0
            return "revoked";
568
0
        case CERT_UNKNOWN:
569
0
            return "unknown";
570
0
        default:
571
0
            return "(UNKNOWN)";
572
0
    }
573
0
}
574
575
int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
576
    WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
577
0
{
578
0
    (void)thisupd;
579
0
    (void)nextupd;
580
0
    (void)sec;
581
0
    (void)maxsec;
582
    /* Dates validated in DecodeSingleResponse. */
583
0
    return WOLFSSL_SUCCESS;
584
0
}
585
586
void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
587
0
{
588
0
    FreeOcspEntry(certId, NULL);
589
0
    XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
590
0
}
591
592
WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
593
    const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
594
    const WOLFSSL_X509 *issuer)
595
0
{
596
0
    WOLFSSL_OCSP_CERTID* certId = NULL;
597
0
    CertStatus* certStatus = NULL;
598
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
599
0
    int ret = -1;
600
0
    DerBuffer* derCert = NULL;
601
0
#ifdef WOLFSSL_SMALL_STACK
602
0
    DecodedCert *cert = NULL;
603
#else
604
    DecodedCert cert[1];
605
#endif
606
607
0
    (void)dgst;
608
609
0
    cm = wolfSSL_CertManagerNew();
610
0
    if (cm == NULL
611
0
            || subject == NULL || subject->derCert == NULL
612
0
            || issuer  == NULL || issuer->derCert  == NULL)
613
0
        goto out;
614
615
0
#ifdef WOLFSSL_SMALL_STACK
616
0
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), cm->heap, DYNAMIC_TYPE_DCERT);
617
0
    if (cert == NULL)
618
0
        goto out;
619
0
#endif
620
621
0
    ret = AllocDer(&derCert, issuer->derCert->length,
622
0
        issuer->derCert->type, NULL);
623
0
    if (ret == 0) {
624
        /* AddCA() frees the buffer. */
625
0
        XMEMCPY(derCert->buffer, issuer->derCert->buffer,
626
0
                issuer->derCert->length);
627
0
        ret = AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
628
0
        if (ret != WOLFSSL_SUCCESS) {
629
0
            goto out;
630
0
        }
631
0
        derCert = NULL;
632
0
    }
633
634
0
    ret = -1;
635
636
0
    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
637
0
                                           cm->heap, DYNAMIC_TYPE_OPENSSL);
638
0
    if (certId == NULL)
639
0
        goto out;
640
641
0
    certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), cm->heap,
642
0
                                           DYNAMIC_TYPE_OPENSSL);
643
0
    if (certStatus == NULL)
644
0
        goto out;
645
646
0
    XMEMSET(certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
647
0
    XMEMSET(certStatus, 0, sizeof(CertStatus));
648
649
0
    certId->status = certStatus;
650
0
    certId->ownStatus = 1;
651
652
0
    InitDecodedCert(cert, subject->derCert->buffer,
653
0
                    subject->derCert->length, NULL);
654
0
    if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
655
0
        goto out;
656
0
    }
657
0
    else {
658
0
        XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
659
0
        XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
660
0
        XMEMCPY(certId->status->serial, cert->serial, cert->serialSz);
661
0
        certId->status->serialSz = cert->serialSz;
662
0
        FreeDecodedCert(cert);
663
0
    }
664
665
0
    ret = 0;
666
667
0
out:
668
669
0
    if (ret != 0) {
670
0
        if (derCert != NULL)
671
0
            FreeDer(&derCert);
672
0
        if (certId != NULL)
673
0
            XFREE(certId, cm->heap, DYNAMIC_TYPE_OPENSSL);
674
0
        if (certStatus)
675
0
            XFREE(certStatus, cm->heap, DYNAMIC_TYPE_OPENSSL);
676
0
        return NULL;
677
0
    }
678
679
0
#ifdef WOLFSSL_SMALL_STACK
680
0
    if (cert != NULL)
681
0
        XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
682
0
#endif
683
684
0
    if (cm != NULL)
685
0
        wolfSSL_CertManagerFree(cm);
686
687
0
    return certId;
688
0
}
689
690
void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
691
0
{
692
0
    wolfSSL_OCSP_RESPONSE_free(basicResponse);
693
0
}
694
695
/* Signature verified in DecodeBasicOcspResponse.
696
 * But no store available to verify certificate. */
697
int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
698
    WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
699
0
{
700
0
    int         ret;
701
0
#ifdef WOLFSSL_SMALL_STACK
702
0
    DecodedCert *cert = (DecodedCert *)
703
0
        XMALLOC(sizeof(*cert), (st && st->cm) ? st->cm->heap : NULL,
704
0
                DYNAMIC_TYPE_DCERT);
705
0
    if (cert == NULL)
706
0
        return WOLFSSL_FAILURE;
707
#else
708
    DecodedCert cert[1];
709
#endif
710
711
0
    (void)certs;
712
713
0
    if (flags & OCSP_NOVERIFY) {
714
0
        ret = WOLFSSL_SUCCESS;
715
0
        goto out;
716
0
    }
717
718
0
#ifdef OPENSSL_EXTRA
719
0
    if (bs->verifyError != OCSP_VERIFY_ERROR_NONE) {
720
0
        ret = WOLFSSL_FAILURE;
721
0
        goto out;
722
0
    }
723
0
#endif
724
725
0
    ret = WOLFSSL_SUCCESS;
726
0
    InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
727
0
    if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0)
728
0
        ret = WOLFSSL_FAILURE;
729
0
    FreeDecodedCert(cert);
730
731
0
out:
732
733
0
#ifdef WOLFSSL_SMALL_STACK
734
0
    XFREE(cert, (st && st->cm) ? st->cm->heap : NULL, DYNAMIC_TYPE_DCERT);
735
0
#endif
736
737
0
    return ret;
738
0
}
739
740
void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
741
0
{
742
0
    if (response == NULL)
743
0
        return;
744
745
0
    if (response->single != NULL) {
746
0
        FreeOcspEntry(response->single, NULL);
747
0
        XFREE(response->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
748
0
    }
749
750
0
    if (response->source != NULL)
751
0
        XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
752
753
0
    XFREE(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
754
0
}
755
756
#ifndef NO_BIO
757
OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
758
    OcspResponse** response)
759
0
{
760
0
    byte*         data;
761
0
    byte*         p;
762
0
    int           len;
763
0
    int           dataAlloced = 0;
764
0
    OcspResponse* ret = NULL;
765
766
0
    if (bio == NULL)
767
0
        return NULL;
768
769
0
    if (bio->type == WOLFSSL_BIO_MEMORY) {
770
0
        len = wolfSSL_BIO_get_mem_data(bio, &data);
771
0
        if (len <= 0 || data == NULL) {
772
0
            return NULL;
773
0
        }
774
0
    }
775
0
#ifndef NO_FILESYSTEM
776
0
    else if (bio->type == WOLFSSL_BIO_FILE) {
777
0
        long fcur;
778
0
        long flen;
779
780
0
        if (bio->ptr == NULL)
781
0
            return NULL;
782
783
0
        fcur = XFTELL((XFILE)bio->ptr);
784
0
        if (fcur < 0)
785
0
            return NULL;
786
0
        if(XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
787
0
            return NULL;
788
0
        flen = XFTELL((XFILE)bio->ptr);
789
0
        if (flen < 0)
790
0
            return NULL;
791
0
        if (XFSEEK((XFILE)bio->ptr, fcur, SEEK_SET) != 0)
792
0
            return NULL;
793
794
        /* check calculated length */
795
0
        fcur = flen - fcur;
796
0
        if (fcur > MAX_WOLFSSL_FILE_SIZE || fcur <= 0)
797
0
            return NULL;
798
799
0
        data = (byte*)XMALLOC(fcur, 0, DYNAMIC_TYPE_TMP_BUFFER);
800
0
        if (data == NULL)
801
0
            return NULL;
802
0
        dataAlloced = 1;
803
804
0
        len = wolfSSL_BIO_read(bio, (char *)data, (int)flen);
805
0
    }
806
0
#endif
807
0
    else
808
0
        return NULL;
809
810
0
    if (len > 0) {
811
0
        p = data;
812
0
        ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p,
813
0
            len);
814
0
    }
815
816
0
    if (dataAlloced)
817
0
        XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
818
819
0
    return ret;
820
0
}
821
#endif /* !NO_BIO */
822
823
OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
824
    const unsigned char** data, int len)
825
0
{
826
0
    OcspResponse *resp = NULL;
827
0
    word32 idx = 0;
828
0
    int length = 0;
829
830
0
    if (data == NULL)
831
0
        return NULL;
832
833
0
    if (response != NULL)
834
0
        resp = *response;
835
0
    if (resp == NULL) {
836
0
        resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
837
0
                                      DYNAMIC_TYPE_OCSP_REQUEST);
838
0
        if (resp == NULL)
839
0
            return NULL;
840
0
        XMEMSET(resp, 0, sizeof(OcspResponse));
841
0
    }
842
843
0
    resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
844
0
    if (resp->source == NULL) {
845
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
846
0
        return NULL;
847
0
    }
848
0
    resp->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
849
0
                                      DYNAMIC_TYPE_OCSP_ENTRY);
850
0
    if (resp->single == NULL) {
851
0
        XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
852
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
853
0
        return NULL;
854
0
    }
855
0
    XMEMSET(resp->single, 0, sizeof(OcspEntry));
856
0
    resp->single->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
857
0
                                      DYNAMIC_TYPE_OCSP_STATUS);
858
0
    resp->single->ownStatus = 1;
859
0
    if (resp->single->status == NULL) {
860
0
        XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
861
0
        XFREE(resp->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
862
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
863
0
        return NULL;
864
0
    }
865
0
    XMEMSET(resp->single->status, 0, sizeof(CertStatus));
866
867
0
    XMEMCPY(resp->source, *data, len);
868
0
    resp->maxIdx = len;
869
870
0
    if (OcspResponseDecode(resp, NULL, NULL, 1) != 0) {
871
0
        wolfSSL_OCSP_RESPONSE_free(resp);
872
0
        return NULL;
873
0
    }
874
875
0
    if (GetSequence(*data, &idx, &length, len) >= 0)
876
0
        (*data) += idx + length;
877
878
0
    return resp;
879
0
}
880
881
int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
882
    unsigned char** data)
883
0
{
884
0
    if (data == NULL)
885
0
        return response->maxIdx;
886
887
0
    XMEMCPY(*data, response->source, response->maxIdx);
888
0
    return response->maxIdx;
889
0
}
890
891
int wolfSSL_OCSP_response_status(OcspResponse *response)
892
0
{
893
0
    return response->responseStatus;
894
0
}
895
896
const char *wolfSSL_OCSP_response_status_str(long s)
897
0
{
898
0
    switch (s) {
899
0
        case OCSP_SUCCESSFUL:
900
0
            return "successful";
901
0
        case OCSP_MALFORMED_REQUEST:
902
0
            return "malformedrequest";
903
0
        case OCSP_INTERNAL_ERROR:
904
0
            return "internalerror";
905
0
        case OCSP_TRY_LATER:
906
0
            return "trylater";
907
0
        case OCSP_SIG_REQUIRED:
908
0
            return "sigrequired";
909
0
        case OCSP_UNAUTHORIZED:
910
0
            return "unauthorized";
911
0
        default:
912
0
            return "(UNKNOWN)";
913
0
    }
914
0
}
915
916
WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
917
0
{
918
0
    WOLFSSL_OCSP_BASICRESP* bs;
919
920
0
    bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL,
921
0
                                          DYNAMIC_TYPE_OCSP_REQUEST);
922
0
    if (bs == NULL)
923
0
        return NULL;
924
925
0
    XMEMCPY(bs, response, sizeof(OcspResponse));
926
0
    bs->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
927
0
                                    DYNAMIC_TYPE_OCSP_ENTRY);
928
0
    bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
929
0
    if (bs->single == NULL || bs->source == NULL) {
930
0
        if (bs->single) XFREE(bs->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
931
0
        if (bs->source) XFREE(bs->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
932
0
        wolfSSL_OCSP_RESPONSE_free(bs);
933
0
        bs = NULL;
934
0
    }
935
0
    else {
936
0
        XMEMCPY(bs->single, response->single, sizeof(OcspEntry));
937
0
        XMEMCPY(bs->source, response->source, response->maxIdx);
938
0
        bs->single->ownStatus = 0;
939
0
    }
940
0
    return bs;
941
0
}
942
943
OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
944
0
{
945
0
    OcspRequest* request;
946
947
0
    request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
948
0
                                    DYNAMIC_TYPE_OPENSSL);
949
0
    if (request != NULL)
950
0
        XMEMSET(request, 0, sizeof(OcspRequest));
951
952
0
    return request;
953
0
}
954
955
void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
956
0
{
957
0
    FreeOcspRequest(request);
958
0
    XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL);
959
0
}
960
961
int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
962
0
{
963
0
    int size;
964
965
0
    size = EncodeOcspRequest(request, NULL, 0);
966
0
    if (size <= 0 || data == NULL)
967
0
        return size;
968
969
0
    return EncodeOcspRequest(request, *data, size);
970
0
}
971
972
WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
973
    WOLFSSL_OCSP_CERTID *cid)
974
0
{
975
0
    if (req == NULL || cid == NULL || cid->status == NULL)
976
0
        return NULL;
977
978
0
    XMEMCPY(req->issuerHash, cid->issuerHash, KEYID_SIZE);
979
0
    XMEMCPY(req->issuerKeyHash, cid->issuerKeyHash, KEYID_SIZE);
980
0
    if (cid->status->serialSz > req->serialSz) {
981
0
        if (req->serial != NULL)
982
0
            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
983
0
        req->serial = (byte*)XMALLOC(cid->status->serialSz,
984
0
                req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
985
0
        if (req->serial == NULL)
986
0
            return NULL;
987
0
    }
988
0
    XMEMCPY(req->serial, cid->status->serial, cid->status->serialSz);
989
0
    req->serialSz = cid->status->serialSz;
990
991
0
    return req;
992
0
}
993
994
WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID* id)
995
0
{
996
0
    WOLFSSL_OCSP_CERTID* certId;
997
998
0
    if (id == NULL)
999
0
        return NULL;
1000
1001
0
    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
1002
0
        NULL, DYNAMIC_TYPE_OPENSSL);
1003
0
    if (certId) {
1004
0
        XMEMCPY(certId, id, sizeof(WOLFSSL_OCSP_CERTID));
1005
0
    }
1006
0
    return certId;
1007
0
}
1008
#endif
1009
1010
#if defined(OPENSSL_ALL) || defined(APACHE_HTTPD) || defined(WOLFSSL_HAPROXY)
1011
#ifndef NO_BIO
1012
int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
1013
        WOLFSSL_OCSP_REQUEST *req)
1014
0
{
1015
0
    int size = -1;
1016
0
    unsigned char* data = NULL;
1017
1018
0
    WOLFSSL_ENTER("wolfSSL_i2d_OCSP_REQUEST_bio");
1019
0
    if (out == NULL || req == NULL)
1020
0
        return WOLFSSL_FAILURE;
1021
1022
0
    size = wolfSSL_i2d_OCSP_REQUEST(req, NULL);
1023
0
    if (size > 0) {
1024
0
        data = (unsigned char*) XMALLOC(size, out->heap,
1025
0
                DYNAMIC_TYPE_TMP_BUFFER);
1026
0
    }
1027
1028
0
    if (data != NULL) {
1029
0
        size = wolfSSL_i2d_OCSP_REQUEST(req, &data);
1030
0
    }
1031
1032
0
    if (size <= 0) {
1033
0
        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1034
0
        return WOLFSSL_FAILURE;
1035
0
    }
1036
1037
0
    if (wolfSSL_BIO_write(out, data, size) == (int)size) {
1038
0
        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1039
0
        return WOLFSSL_SUCCESS;
1040
0
    }
1041
1042
0
    XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1043
0
    return WOLFSSL_FAILURE;
1044
0
}
1045
#endif /* !NO_BIO */
1046
1047
int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data)
1048
0
{
1049
0
    if (id == NULL || data == NULL)
1050
0
        return WOLFSSL_FAILURE;
1051
1052
0
    if (*data != NULL) {
1053
0
        XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
1054
0
        *data = *data + id->rawCertIdSize;
1055
0
    }
1056
0
    else {
1057
0
        *data = (unsigned char*)XMALLOC(id->rawCertIdSize, NULL, DYNAMIC_TYPE_OPENSSL);
1058
0
        if (*data == NULL) {
1059
0
            return WOLFSSL_FAILURE;
1060
0
        }
1061
0
        XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
1062
0
    }
1063
1064
0
    return id->rawCertIdSize;
1065
0
}
1066
1067
const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(const WOLFSSL_OCSP_SINGLERESP *single)
1068
0
{
1069
0
    return single;
1070
0
}
1071
1072
/**
1073
 * Compare two WOLFSSL_OCSP_CERTID objects
1074
 * @param a
1075
 * @param b
1076
 * @return 0 on success and when objects have the same id otherwise either
1077
 *         the id's don't match or an error occurred
1078
 */
1079
int wolfSSL_OCSP_id_cmp(WOLFSSL_OCSP_CERTID *a, WOLFSSL_OCSP_CERTID *b)
1080
0
{
1081
0
    int ret = 0;
1082
0
    if (a == NULL || b == NULL)
1083
0
        return WOLFSSL_FATAL_ERROR;
1084
1085
0
    ret = a->hashAlgoOID != b->hashAlgoOID;
1086
0
    if (ret == 0)
1087
0
        ret = XMEMCMP(a->issuerHash, b->issuerHash, OCSP_DIGEST_SIZE);
1088
0
    if (ret == 0)
1089
0
        ret = XMEMCMP(a->issuerKeyHash, b->issuerKeyHash, OCSP_DIGEST_SIZE);
1090
0
    if (ret == 0) {
1091
0
        if (a->status != NULL && b->status != NULL) {
1092
0
            if (a->status->serialSz == b->status->serialSz)
1093
0
                ret = XMEMCMP(a->status->serial, b->status->serial,
1094
0
                        a->status->serialSz);
1095
0
            else
1096
0
                ret = -1;
1097
0
        }
1098
0
        else if (a->status != b->status) {
1099
            /* If either is not null then return non-zero */
1100
0
            ret = -1;
1101
0
        }
1102
0
    }
1103
0
    return ret;
1104
0
}
1105
1106
int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single,
1107
                                    int *reason,
1108
                                    WOLFSSL_ASN1_TIME **revtime,
1109
                                    WOLFSSL_ASN1_TIME **thisupd,
1110
                                    WOLFSSL_ASN1_TIME **nextupd)
1111
0
{
1112
0
    if (single == NULL)
1113
0
        return WOLFSSL_FAILURE;
1114
1115
0
    if (thisupd != NULL)
1116
0
        *thisupd = &single->status->thisDateParsed;
1117
0
    if (nextupd != NULL)
1118
0
        *nextupd = &single->status->nextDateParsed;
1119
1120
0
    if (reason != NULL)
1121
0
        *reason = 0;
1122
0
    if (revtime != NULL)
1123
0
        *revtime = NULL;
1124
1125
0
    return single->status->status;
1126
0
}
1127
1128
int wolfSSL_OCSP_resp_count(WOLFSSL_OCSP_BASICRESP *bs)
1129
0
{
1130
0
    WOLFSSL_OCSP_SINGLERESP* single;
1131
0
    int count = 0;
1132
1133
0
    if (bs == NULL)
1134
0
        return WOLFSSL_FAILURE;
1135
1136
0
    single = bs->single;
1137
0
    while(single != NULL)
1138
0
    {
1139
0
        ++count;
1140
0
        single = single->next;
1141
0
    }
1142
1143
0
    return count;
1144
0
}
1145
1146
WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0(WOLFSSL_OCSP_BASICRESP *bs, int idx)
1147
0
{
1148
0
    WOLFSSL_OCSP_SINGLERESP* single;
1149
0
    int currIdx = 0;
1150
1151
0
    if (bs == NULL)
1152
0
        return NULL;
1153
1154
0
    single = bs->single;
1155
0
    while(single != NULL && currIdx != idx)
1156
0
    {
1157
0
        single = single->next;
1158
0
        ++currIdx;
1159
0
    }
1160
1161
0
    return single;
1162
0
}
1163
1164
#endif /* OPENSSL_ALL || APACHE_HTTPD || WOLFSSL_HAPROXY */
1165
1166
#ifdef OPENSSL_EXTRA
1167
#ifndef NO_WOLFSSL_STUB
1168
int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext,
1169
        int idx)
1170
0
{
1171
0
    WOLFSSL_STUB("wolfSSL_OCSP_REQUEST_add_ext");
1172
0
    (void)req;
1173
0
    (void)ext;
1174
0
    (void)idx;
1175
0
    return WOLFSSL_FATAL_ERROR;
1176
0
}
1177
#endif
1178
1179
#ifndef NO_WOLFSSL_STUB
1180
OcspResponse* wolfSSL_OCSP_response_create(int status,
1181
    WOLFSSL_OCSP_BASICRESP* bs)
1182
0
{
1183
0
    WOLFSSL_STUB("wolfSSL_OCSP_response_create");
1184
0
    (void)status;
1185
0
    (void)bs;
1186
0
    return NULL;
1187
0
}
1188
#endif
1189
1190
#ifndef NO_WOLFSSL_STUB
1191
const char* wolfSSL_OCSP_crl_reason_str(long s)
1192
0
{
1193
0
    WOLFSSL_STUB("wolfSSL_OCSP_crl_reason_str");
1194
0
    (void)s;
1195
0
    return NULL;
1196
0
}
1197
#endif
1198
1199
/* Returns elements of an OCSP_CERTID struct. Currently only supports
1200
 * returning the serial number, and returns an error if user requests
1201
 * any of name, pmd, and/or keyHash.
1202
 * Return 1 on success, 0 on failure */
1203
int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name,
1204
  WOLFSSL_ASN1_OBJECT **pmd, WOLFSSL_ASN1_STRING **keyHash,
1205
  WOLFSSL_ASN1_INTEGER **serial, WOLFSSL_OCSP_CERTID *cid)
1206
0
{
1207
0
    int i = 0;
1208
0
    WOLFSSL_ASN1_INTEGER* ser;
1209
1210
0
    WOLFSSL_ENTER("wolfSSL_OCSP_id_get0_info");
1211
1212
0
    if (cid == NULL)
1213
0
        return 0;
1214
1215
    /* build up ASN1_INTEGER for serial */
1216
0
    if (serial != NULL) {
1217
0
        ser = wolfSSL_ASN1_INTEGER_new();
1218
0
        if (ser == NULL)
1219
0
            return 0;
1220
1221
0
        if (cid->status->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
1222
            /* allocate data buffer, +2 for type and length */
1223
0
            ser->data = (unsigned char*)XMALLOC(cid->status->serialSz + 2, NULL,
1224
0
                DYNAMIC_TYPE_OPENSSL);
1225
0
            if (ser->data == NULL) {
1226
0
                wolfSSL_ASN1_INTEGER_free(ser);
1227
0
                return 0;
1228
0
            }
1229
0
            ser->dataMax = cid->status->serialSz + 2;
1230
0
            ser->isDynamic = 1;
1231
0
        } else {
1232
            /* Use array instead of dynamic memory */
1233
0
            ser->data    = ser->intData;
1234
0
            ser->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
1235
0
        }
1236
1237
        #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
1238
            /* Serial number starts at 0 index of ser->data */
1239
            XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz);
1240
            ser->length = cid->status->serialSz;
1241
        #else
1242
0
            ser->data[i++] = ASN_INTEGER;
1243
0
            i += SetLength(cid->status->serialSz, ser->data + i);
1244
0
            XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz);
1245
0
            ser->length = i + cid->status->serialSz;
1246
0
        #endif
1247
1248
0
        cid->status->serialInt = ser;
1249
0
        *serial = ser;
1250
0
    }
1251
1252
    /* Not needed for Apache, return error if user is requesting */
1253
0
    if (name != NULL || pmd != NULL || keyHash != NULL) {
1254
0
        if (name != NULL)
1255
0
            *name = NULL;
1256
1257
0
        if (pmd != NULL)
1258
0
            *pmd = NULL;
1259
1260
0
        if (keyHash != NULL)
1261
0
            *keyHash = NULL;
1262
0
        return 0;
1263
0
    }
1264
1265
0
    return 1;
1266
0
}
1267
1268
int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val,
1269
        int sz)
1270
0
{
1271
0
    WC_RNG rng;
1272
1273
0
    WOLFSSL_ENTER("wolfSSL_OCSP_request_add1_nonce");
1274
1275
0
    if (req == NULL || sz > MAX_OCSP_NONCE_SZ) {
1276
0
        WOLFSSL_MSG("Bad parameter");
1277
0
        return WOLFSSL_FAILURE;
1278
0
    }
1279
1280
0
    if (sz <= 0)
1281
0
        sz = MAX_OCSP_NONCE_SZ;
1282
1283
0
    if (val != NULL) {
1284
0
        XMEMCPY(req->nonce, val, sz);
1285
0
    }
1286
0
    else {
1287
0
        if (
1288
0
#ifndef HAVE_FIPS
1289
0
            wc_InitRng_ex(&rng, req->heap, INVALID_DEVID)
1290
#else
1291
            wc_InitRng(&rng)
1292
#endif
1293
0
            != 0) {
1294
0
            WOLFSSL_MSG("RNG init failed");
1295
0
            return WOLFSSL_FAILURE;
1296
0
        }
1297
0
        if (wc_RNG_GenerateBlock(&rng, req->nonce, sz) != 0) {
1298
0
            WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
1299
0
            wc_FreeRng(&rng);
1300
0
            return WOLFSSL_FAILURE;
1301
0
        }
1302
0
        wc_FreeRng(&rng);
1303
0
    }
1304
0
    req->nonceSz = sz;
1305
1306
0
    return WOLFSSL_SUCCESS;
1307
0
}
1308
1309
/* Returns result of OCSP nonce comparison. Return values:
1310
 *  1 - nonces are both present and equal
1311
 *  2 - both nonces are absent
1312
 *  3 - nonce only present in response
1313
 * -1 - nonce only present in request
1314
 *  0 - both nonces present and equal
1315
 */
1316
int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs)
1317
0
{
1318
0
    byte* reqNonce = NULL;
1319
0
    byte* rspNonce = NULL;
1320
0
    int reqNonceSz = 0;
1321
0
    int rspNonceSz = 0;
1322
1323
0
    WOLFSSL_ENTER("wolfSSL_OCSP_check_nonce");
1324
1325
0
    if (req != NULL) {
1326
0
        reqNonce = req->nonce;
1327
0
        reqNonceSz = req->nonceSz;
1328
0
    }
1329
1330
0
    if (bs != NULL) {
1331
0
        rspNonce = bs->nonce;
1332
0
        rspNonceSz = bs->nonceSz;
1333
0
    }
1334
1335
    /* nonce absent in both req and rsp */
1336
0
    if (reqNonce == NULL && rspNonce == NULL)
1337
0
        return 2;
1338
1339
    /* nonce present in rsp only */
1340
0
    if (reqNonce == NULL && rspNonce != NULL)
1341
0
        return 3;
1342
1343
    /* nonce present in req only */
1344
0
    if (reqNonce != NULL && rspNonce == NULL)
1345
0
        return -1;
1346
1347
    /* nonces are present and equal, return 1. Extra NULL check for fixing
1348
        scan-build warning. */
1349
0
    if (reqNonceSz == rspNonceSz && reqNonce && rspNonce) {
1350
0
        if (XMEMCMP(reqNonce, rspNonce, reqNonceSz) == 0)
1351
0
            return 1;
1352
0
    }
1353
1354
    /* nonces are present but not equal */
1355
0
    return 0;
1356
0
}
1357
#endif /* OPENSSL_EXTRA */
1358
1359
#else /* HAVE_OCSP */
1360
1361
1362
#ifdef _MSC_VER
1363
    /* 4206 warning for blank file */
1364
    #pragma warning(disable: 4206)
1365
#endif
1366
1367
1368
#endif /* HAVE_OCSP */
1369
#endif /* WOLFCRYPT_ONLY */