Coverage Report

Created: 2026-02-14 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/src/ocsp.c
Line
Count
Source
1
/* ocsp.c
2
 *
3
 * Copyright (C) 2006-2025 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 3 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
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
  /* Name change compatibility layer no longer needs to be included here */
25
26
/*
27
 * WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK:
28
 *     Disable looking for an authorized responder in the verification path of
29
 *     the issuer. This will make the authorized responder only look at the
30
 *     OCSP response signer and direct issuer.
31
 */
32
33
#ifndef WOLFCRYPT_ONLY
34
#ifdef HAVE_OCSP
35
36
#include <wolfssl/error-ssl.h>
37
#include <wolfssl/ocsp.h>
38
#include <wolfssl/internal.h>
39
40
#ifdef NO_INLINE
41
    #include <wolfssl/wolfcrypt/misc.h>
42
#else
43
    #define WOLFSSL_MISC_INCLUDED
44
    #include <wolfcrypt/src/misc.c>
45
#endif
46
47
/* Allocates and initializes a WOLFSSL_OCSP object. Returns pointer on success, NULL on failure. */
48
WOLFSSL_OCSP* wc_NewOCSP(WOLFSSL_CERT_MANAGER* cm)
49
0
{
50
0
    WOLFSSL_OCSP* ocsp = NULL;
51
0
    ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm ? cm->heap : NULL, DYNAMIC_TYPE_OCSP);
52
0
    if (ocsp == NULL)
53
0
        return NULL;
54
0
    if (InitOCSP(ocsp, cm) != 0) {
55
0
        XFREE(ocsp, cm ? cm->heap : NULL, DYNAMIC_TYPE_OCSP);
56
0
        return NULL;
57
0
    }
58
0
    return ocsp;
59
0
}
60
61
/* Frees a WOLFSSL_OCSP object allocated by wc_NewOCSP. */
62
void wc_FreeOCSP(WOLFSSL_OCSP* ocsp)
63
0
{
64
0
    if (ocsp) {
65
0
        FreeOCSP(ocsp, 1);
66
0
    }
67
0
}
68
69
int wc_CheckCertOcspResponse(WOLFSSL_OCSP *ocsp, DecodedCert *cert,
70
        byte *response, int responseSz, void* heap)
71
0
{
72
0
    int ret = WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E);
73
74
0
#ifdef WOLFSSL_SMALL_STACK
75
0
    OcspRequest* ocspRequest;
76
#else
77
    OcspRequest ocspRequest[1];
78
#endif
79
80
81
0
#ifdef WOLFSSL_SMALL_STACK
82
0
    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
83
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
84
0
    if (ocspRequest == NULL) {
85
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
86
0
        return MEMORY_E;
87
0
    }
88
0
#endif
89
90
0
    if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
91
0
                                                         ocsp->cm->heap) == 0) {
92
0
        ret = CheckOcspResponse(ocsp, response, responseSz, NULL, NULL, NULL,
93
0
                ocspRequest, heap);
94
0
        FreeOcspRequest(ocspRequest);
95
0
    }
96
97
0
#ifdef WOLFSSL_SMALL_STACK
98
0
    XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
99
0
#endif
100
101
0
    WOLFSSL_LEAVE("CheckCertOCSP", ret);
102
0
    return ret;
103
0
}
104
105
int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
106
28
{
107
28
    WOLFSSL_ENTER("InitOCSP");
108
109
28
    ForceZero(ocsp, sizeof(WOLFSSL_OCSP));
110
111
28
    if (wc_InitMutex(&ocsp->ocspLock) != 0)
112
0
        return BAD_MUTEX_E;
113
114
28
    ocsp->cm = cm;
115
116
28
    return 0;
117
28
}
118
119
120
static int InitOcspEntry(OcspEntry* entry, OcspRequest* request)
121
0
{
122
0
    WOLFSSL_ENTER("InitOcspEntry");
123
124
0
    ForceZero(entry, sizeof(OcspEntry));
125
126
0
    XMEMCPY(entry->issuerHash,    request->issuerHash,    OCSP_DIGEST_SIZE);
127
0
    XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE);
128
129
0
    return 0;
130
0
}
131
132
133
static void FreeOcspEntry(OcspEntry* entry, void* heap)
134
0
{
135
0
    CertStatus *status, *next;
136
137
0
    if (entry == NULL || !entry->ownStatus)
138
0
        return;
139
140
0
    WOLFSSL_ENTER("FreeOcspEntry");
141
142
0
    for (status = entry->status; status; status = next) {
143
0
        next = status->next;
144
145
0
        XFREE(status->rawOcspResponse, heap, DYNAMIC_TYPE_OCSP_STATUS);
146
147
0
#ifdef OPENSSL_EXTRA
148
0
        if (status->serialInt) {
149
0
            if (status->serialInt->isDynamic) {
150
0
                XFREE(status->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
151
0
            }
152
0
            XFREE(status->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
153
0
        }
154
0
        status->serialInt = NULL;
155
0
#endif
156
157
0
        XFREE(status, heap, DYNAMIC_TYPE_OCSP_STATUS);
158
0
    }
159
160
0
    (void)heap;
161
0
}
162
163
164
void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
165
0
{
166
0
    OcspEntry *entry, *next;
167
168
0
    WOLFSSL_ENTER("FreeOCSP");
169
170
0
    for (entry = ocsp->ocspList; entry; entry = next) {
171
0
        next = entry->next;
172
0
        FreeOcspEntry(entry, ocsp->cm->heap);
173
0
        XFREE(entry, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
174
0
    }
175
176
0
    wc_FreeMutex(&ocsp->ocspLock);
177
178
0
    if (dynamic)
179
0
        XFREE(ocsp, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
180
181
0
}
182
183
184
static int xstat2err(int st)
185
0
{
186
0
    switch (st) {
187
0
        case CERT_GOOD:
188
0
            return 0;
189
0
        case CERT_REVOKED:
190
0
            return OCSP_CERT_REVOKED;
191
0
        default:
192
0
            return OCSP_CERT_UNKNOWN;
193
0
    }
194
0
}
195
196
int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, WOLFSSL* ssl)
197
0
{
198
0
    int ret = WC_NO_ERR_TRACE(OCSP_LOOKUP_FAIL);
199
200
0
    WC_DECLARE_VAR(ocspRequest, OcspRequest, 1, 0);
201
202
0
    WOLFSSL_ENTER("CheckCertOCSP");
203
204
205
0
#ifdef WOLFSSL_SMALL_STACK
206
0
    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
207
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
208
0
    if (ocspRequest == NULL) {
209
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
210
0
        return MEMORY_E;
211
0
    }
212
0
#endif
213
214
0
    if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
215
0
                                                         ocsp->cm->heap) == 0) {
216
0
        ocspRequest->ssl = ssl;
217
0
        ret = CheckOcspRequest(ocsp, ocspRequest, NULL, NULL);
218
219
0
        FreeOcspRequest(ocspRequest);
220
0
    }
221
222
0
    WC_FREE_VAR_EX(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
223
224
0
    WOLFSSL_LEAVE("CheckCertOCSP", ret);
225
0
    return ret;
226
0
}
227
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
228
0
{
229
0
    return CheckCertOCSP_ex(ocsp, cert, NULL);
230
0
}
231
232
static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
233
                                                              OcspEntry** entry)
234
0
{
235
0
    WOLFSSL_ENTER("GetOcspEntry");
236
237
0
    *entry = NULL;
238
239
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
240
0
        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
241
0
        return BAD_MUTEX_E;
242
0
    }
243
244
0
    for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next)
245
0
        if (XMEMCMP((*entry)->issuerHash,    request->issuerHash,
246
0
                                                         OCSP_DIGEST_SIZE) == 0
247
0
        &&  XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash,
248
0
                                                         OCSP_DIGEST_SIZE) == 0)
249
0
            break;
250
251
0
    if (*entry == NULL) {
252
0
        *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry),
253
0
                                       ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
254
0
        if (*entry) {
255
0
            InitOcspEntry(*entry, request);
256
0
            (*entry)->next = ocsp->ocspList;
257
0
            ocsp->ocspList = *entry;
258
0
        }
259
0
    }
260
261
0
    wc_UnLockMutex(&ocsp->ocspLock);
262
263
0
    return *entry ? 0 : MEMORY_ERROR;
264
0
}
265
266
267
/* Mallocs responseBuffer->buffer and is up to caller to free on success
268
 *
269
 * Returns OCSP status
270
 */
271
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
272
                  OcspEntry* entry, CertStatus** status, buffer* responseBuffer,
273
                  void* heap)
274
0
{
275
0
    int ret = WC_NO_ERR_TRACE(OCSP_INVALID_STATUS);
276
277
0
    WOLFSSL_ENTER("GetOcspStatus");
278
279
0
    (void)heap;
280
0
    *status = NULL;
281
282
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
283
0
        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
284
0
        return BAD_MUTEX_E;
285
0
    }
286
287
0
    for (*status = entry->status; *status; *status = (*status)->next)
288
0
        if ((*status)->serialSz == request->serialSz
289
0
        &&  !XMEMCMP((*status)->serial, request->serial, (size_t)(*status)->serialSz))
290
0
            break;
291
292
0
    if (responseBuffer && *status && !(*status)->rawOcspResponse) {
293
        /* force fetching again */
294
0
        ret = OCSP_INVALID_STATUS;
295
0
    }
296
0
    else if (*status) {
297
0
#ifndef NO_ASN_TIME
298
0
        if (XVALIDATE_DATE((*status)->thisDate,
299
0
                           (*status)->thisDateFormat, ASN_BEFORE, MAX_DATE_SIZE)
300
0
        &&  ((*status)->nextDate[0] != 0)
301
0
        &&  XVALIDATE_DATE((*status)->nextDate,
302
0
                           (*status)->nextDateFormat, ASN_AFTER, MAX_DATE_SIZE))
303
0
#endif
304
0
        {
305
0
            ret = xstat2err((*status)->status);
306
307
0
            if (responseBuffer) {
308
0
                responseBuffer->buffer = (byte*)XMALLOC(
309
0
                   (*status)->rawOcspResponseSz, heap,
310
0
                   DYNAMIC_TYPE_TMP_BUFFER);
311
312
0
                if (responseBuffer->buffer) {
313
0
                    responseBuffer->length = (*status)->rawOcspResponseSz;
314
0
                    XMEMCPY(responseBuffer->buffer,
315
0
                            (*status)->rawOcspResponse,
316
0
                            (*status)->rawOcspResponseSz);
317
0
                }
318
0
            }
319
0
        }
320
0
    }
321
322
0
    wc_UnLockMutex(&ocsp->ocspLock);
323
324
0
    return ret;
325
0
}
326
327
/* Check that the response for validity. Store result in status.
328
 *
329
 * ocsp           Context object for OCSP status.
330
 * response       OCSP response message data.
331
 * responseSz     Length of OCSP response message data.
332
 * responseBuffer Buffer object to return the response with.
333
 * status         The certificate status object.
334
 * entry          The OCSP entry for this certificate.
335
 * ocspRequest    Request corresponding to response.
336
 * heap           Heap hint used for responseBuffer
337
 * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
338
 */
339
int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
340
                      WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
341
                      OcspEntry *entry, OcspRequest *ocspRequest, void* heap)
342
0
{
343
0
#ifdef WOLFSSL_SMALL_STACK
344
0
    CertStatus*   newStatus;
345
0
    OcspEntry*    newSingle;
346
0
    OcspResponse* ocspResponse;
347
#else
348
    CertStatus    newStatus[1];
349
    OcspEntry     newSingle[1];
350
    OcspResponse  ocspResponse[1];
351
#endif
352
0
    int           ret;
353
0
    int           validated      = 0;    /* ocsp validation flag */
354
355
0
    (void)heap;
356
357
0
#ifdef WOLFSSL_SMALL_STACK
358
0
    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
359
0
                                                       DYNAMIC_TYPE_OCSP_STATUS);
360
0
    newSingle = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
361
0
                                                       DYNAMIC_TYPE_OCSP_ENTRY);
362
0
    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
363
0
                                                       DYNAMIC_TYPE_OCSP_REQUEST);
364
365
0
    if (newStatus == NULL || newSingle == NULL || ocspResponse == NULL) {
366
0
        XFREE(newStatus, NULL, DYNAMIC_TYPE_OCSP_STATUS);
367
0
        XFREE(newSingle, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
368
0
        XFREE(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
369
370
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
371
0
        return MEMORY_E;
372
0
    }
373
0
#endif
374
0
    InitOcspResponse(ocspResponse, newSingle, newStatus, response,
375
0
                     (word32)responseSz, ocsp->cm->heap);
376
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && !defined(NO_TLS)
377
    if (ocspRequest != NULL && ocspRequest->ssl != NULL &&
378
           TLSX_CSR2_IsMulti(((WOLFSSL*)ocspRequest->ssl)->extensions)) {
379
        ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions);
380
    }
381
#endif
382
0
    ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0, 0);
383
0
    if (ret != 0) {
384
0
        ocsp->error = ret;
385
0
        WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
386
0
        goto end;
387
0
    }
388
389
0
    if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
390
0
        WOLFSSL_MSG("OcspResponse status bad");
391
0
        goto end;
392
0
    }
393
0
    if (ocspRequest != NULL) {
394
        /* Has the chance to bubble up response changing ocspResponse->single to
395
           no longer be pointing at newSingle */
396
0
        ret = CompareOcspReqResp(ocspRequest, ocspResponse);
397
0
        if (ret != 0) {
398
0
            goto end;
399
0
        }
400
0
    }
401
402
0
    if (responseBuffer) {
403
0
        responseBuffer->buffer = (byte*)XMALLOC((size_t)responseSz, heap,
404
0
                                                DYNAMIC_TYPE_TMP_BUFFER);
405
406
0
        if (responseBuffer->buffer) {
407
0
            responseBuffer->length = (unsigned int)responseSz;
408
0
            XMEMCPY(responseBuffer->buffer, response, (size_t)responseSz);
409
0
        }
410
0
    }
411
412
0
    ret = xstat2err(ocspResponse->single->status->status);
413
0
    if (ret == 0) {
414
0
        validated = 1;
415
0
    }
416
417
0
    if (wc_LockMutex(&ocsp->ocspLock) != 0) {
418
0
        ret = BAD_MUTEX_E;
419
0
        goto end;
420
0
    }
421
422
0
    if (status != NULL) {
423
0
        XFREE(status->rawOcspResponse, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
424
425
        /* Replace existing certificate entry with updated */
426
0
        ocspResponse->single->status->next = status->next;
427
0
        XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus));
428
0
    }
429
0
    else if (entry != NULL) {
430
        /* Save new certificate entry */
431
0
        status = (CertStatus*)XMALLOC(sizeof(CertStatus),
432
0
                                      ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
433
0
        if (status != NULL) {
434
0
            XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus));
435
0
            status->next  = entry->status;
436
0
            entry->status = status;
437
0
            entry->ownStatus = 1;
438
0
            entry->totalStatus++;
439
0
        }
440
0
    }
441
442
0
    if (status && responseBuffer && responseBuffer->buffer) {
443
0
        status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
444
0
                                                 ocsp->cm->heap,
445
0
                                                 DYNAMIC_TYPE_OCSP_STATUS);
446
447
0
        if (status->rawOcspResponse) {
448
0
            status->rawOcspResponseSz = responseBuffer->length;
449
0
            XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
450
0
                    responseBuffer->length);
451
0
        }
452
0
    }
453
454
0
    wc_UnLockMutex(&ocsp->ocspLock);
455
456
0
end:
457
0
    if (ret == 0 && validated == 1) {
458
0
        WOLFSSL_MSG("New OcspResponse validated");
459
0
    }
460
0
    else if (ret == WC_NO_ERR_TRACE(OCSP_CERT_REVOKED)) {
461
0
        WOLFSSL_MSG("OCSP revoked");
462
0
    }
463
0
    else if (ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN)) {
464
0
        WOLFSSL_MSG("OCSP unknown");
465
0
    }
466
0
    else {
467
0
        WOLFSSL_MSG("OCSP lookup failure");
468
0
        ret = OCSP_LOOKUP_FAIL;
469
0
    }
470
471
0
    FreeOcspResponse(ocspResponse);
472
0
    WC_FREE_VAR_EX(newStatus, NULL, DYNAMIC_TYPE_OCSP_STATUS);
473
0
    WC_FREE_VAR_EX(newSingle, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
474
0
    WC_FREE_VAR_EX(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
475
0
    return ret;
476
0
}
477
478
/* 0 on success */
479
/* allow user to override the maximum request size at build-time */
480
#ifndef OCSP_MAX_REQUEST_SZ
481
0
#define OCSP_MAX_REQUEST_SZ 2048
482
#endif
483
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
484
                     buffer* responseBuffer, void* heap)
485
0
{
486
0
    OcspEntry*  entry          = NULL;
487
0
    CertStatus* status         = NULL;
488
0
    byte*       request        = NULL;
489
0
    int         requestSz      = OCSP_MAX_REQUEST_SZ;
490
0
    int         responseSz     = 0;
491
0
    byte*       response       = NULL;
492
0
    const char* url            = NULL;
493
0
    int         urlSz          = 0;
494
0
    int         ret            = -1;
495
0
    WOLFSSL*    ssl;
496
0
    void*       ioCtx;
497
498
0
    WOLFSSL_ENTER("CheckOcspRequest");
499
500
0
    if (ocsp == NULL || ocspRequest == NULL)
501
0
        return BAD_FUNC_ARG;
502
503
0
    if (responseBuffer) {
504
0
        responseBuffer->buffer = NULL;
505
0
        responseBuffer->length = 0;
506
0
    }
507
508
0
    ret = GetOcspEntry(ocsp, ocspRequest, &entry);
509
0
    if (ret != 0)
510
0
        return ret;
511
512
0
    ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer,
513
0
                        heap);
514
0
    if (ret != WC_NO_ERR_TRACE(OCSP_INVALID_STATUS))
515
0
        return ret;
516
517
0
    if (responseBuffer) {
518
0
        XFREE(responseBuffer->buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
519
0
        responseBuffer->buffer = NULL;
520
0
    }
521
522
    /* get SSL and IOCtx */
523
0
    ssl = (WOLFSSL*)ocspRequest->ssl;
524
0
    ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
525
0
                                        ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
526
527
0
    if (ocsp->cm->ocspUseOverrideURL) {
528
0
        url = ocsp->cm->ocspOverrideURL;
529
0
        if (url != NULL && url[0] != '\0')
530
0
            urlSz = (int)XSTRLEN(url);
531
0
        else
532
0
            return OCSP_NEED_URL;
533
0
    }
534
0
    else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
535
0
        url = (const char *)ocspRequest->url;
536
0
        urlSz = ocspRequest->urlSz;
537
0
    }
538
0
    else {
539
        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
540
0
        WOLFSSL_MSG("Cert has no OCSP URL, assuming CERT_GOOD");
541
0
        return 0;
542
0
    }
543
544
0
    request = (byte*)XMALLOC((size_t)requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
545
0
    if (request == NULL) {
546
0
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
547
0
        return MEMORY_ERROR;
548
0
    }
549
550
0
    requestSz = EncodeOcspRequest(ocspRequest, request, (word32)requestSz);
551
0
    if (requestSz > 0 && ocsp->cm->ocspIOCb) {
552
0
        responseSz = ocsp->cm->ocspIOCb(ioCtx, url, urlSz,
553
0
                                        request, requestSz, &response);
554
0
    }
555
0
    if (responseSz == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_WANT_READ)) {
556
0
        ret = OCSP_WANT_READ;
557
0
    }
558
0
    else if (responseSz == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_TIMEOUT)){
559
0
        ret = HTTP_TIMEOUT;
560
0
    }
561
562
0
    XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
563
564
0
    if (responseSz >= 0 && response) {
565
0
        ret = CheckOcspResponse(ocsp, response, responseSz, responseBuffer, status,
566
0
                            entry, ocspRequest, heap);
567
0
    }
568
569
0
    if (response != NULL && ocsp->cm->ocspRespFreeCb)
570
0
        ocsp->cm->ocspRespFreeCb(ioCtx, response);
571
572
    /* Keep responseBuffer in the case of getting to response check. Caller
573
     * should free responseBuffer after checking OCSP return value in "ret" */
574
0
    WOLFSSL_LEAVE("CheckOcspRequest", ret);
575
0
    return ret;
576
0
}
577
578
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
579
static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
580
0
        void* vp, Signer* pendingCAs) {
581
    /* Attempt to build a chain up to cert's issuer */
582
0
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
583
0
    Signer* ca = NULL;
584
0
    Signer* prev = NULL;
585
0
    int passed = 0;
586
587
    /*
588
     *       Relation between certs:
589
     *                 CA
590
     *        /                 \
591
     *  intermediate(s)   cert in OCSP response
592
     *        |           with OCSP key usage ext
593
     *  issuer of cert
594
     *  in OCSP request
595
     */
596
597
    /* End loop if no more issuers found or if we have found a self
598
     * signed cert (ca == prev) */
599
0
    ca = GetCAByName(cm, single->issuerHash);
600
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
601
    if (ca == NULL && pendingCAs != NULL) {
602
        ca = findSignerByName(pendingCAs, single->issuerHash);
603
    }
604
#else
605
0
    (void)pendingCAs;
606
0
#endif
607
0
    for (; ca != NULL && ca != prev;
608
0
            prev = ca) {
609
0
        if (XMEMCMP(cert->issuerHash, ca->issuerNameHash,
610
0
                OCSP_DIGEST_SIZE) == 0) {
611
0
            WOLFSSL_MSG("\tOCSP Response signed by authorized "
612
0
                    "responder delegated by issuer "
613
0
                    "(found in chain)");
614
0
            passed = 1;
615
0
            break;
616
0
        }
617
0
        ca = GetCAByName(cm, ca->issuerNameHash);
618
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
619
        if (ca == NULL && pendingCAs != NULL) {
620
            ca = findSignerByName(pendingCAs, single->issuerHash);
621
        }
622
#endif
623
0
    }
624
0
    return passed;
625
0
}
626
#endif
627
628
/**
629
 * Enforce https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2
630
 * @param bs   The basic response to verify
631
 * @param cert The decoded bs->cert
632
 * @return
633
 */
634
int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp)
635
0
{
636
0
    int ret = 0;
637
0
    OcspEntry* single;
638
639
    /* Both evaluate to enum values so can't use a pre-processor check */
640
0
    WOLFSSL_ASSERT_EQ(OCSP_DIGEST_SIZE, SIGNER_DIGEST_SIZE);
641
642
0
    (void)vp;
643
644
0
    WOLFSSL_ENTER("CheckOcspResponder");
645
646
    /* In the future if this API is used more then it could be beneficial to
647
     * implement calling InitDecodedCert and ParseCertRelative here
648
     * automatically when cert == NULL. */
649
0
    if (bs == NULL || cert == NULL)
650
0
        return BAD_FUNC_ARG;
651
652
    /* Traverse the list and check that the cert has the authority to provide
653
     * an OCSP response for each entry. */
654
0
    for (single = bs->single; single != NULL; single = single->next) {
655
0
        int passed = 0;
656
657
0
        if (XMEMCMP(cert->subjectHash, single->issuerHash, OCSP_DIGEST_SIZE)
658
0
                == 0) {
659
0
            WOLFSSL_MSG("\tOCSP Response signed by issuer");
660
0
            passed = 1;
661
0
        }
662
0
        else if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) != 0) {
663
0
            if (XMEMCMP(cert->issuerHash, single->issuerHash,
664
0
                        OCSP_DIGEST_SIZE) == 0) {
665
0
                WOLFSSL_MSG("\tOCSP Response signed by authorized responder "
666
0
                            "delegated by issuer");
667
0
                passed = 1;
668
0
            }
669
0
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
670
0
            else if (vp != NULL) {
671
0
                passed = CheckOcspResponderChain(single, cert, vp, bs->pendingCAs);
672
0
            }
673
0
#endif
674
0
        }
675
676
0
        if (!passed) {
677
0
            WOLFSSL_MSG("\tOCSP Responder not authorized");
678
0
            ret = BAD_OCSP_RESPONDER;
679
0
            break;
680
0
        }
681
0
    }
682
0
    return ret;
683
0
}
684
685
686
/* compatibility layer OCSP functions */
687
#ifdef OPENSSL_EXTRA
688
int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
689
    WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
690
    WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
691
    WOLFSSL_ASN1_TIME** nextupd)
692
0
{
693
0
    WOLFSSL_OCSP_SINGLERESP* single;
694
695
0
    if (bs == NULL || id == NULL)
696
0
        return WOLFSSL_FAILURE;
697
698
0
    single = bs->single;
699
0
    while (single != NULL) {
700
0
        if ((XMEMCMP(single->status->serial, id->status->serial, (size_t)single->status->serialSz) == 0)
701
0
         && (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0)
702
0
         && (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) {
703
0
            break;
704
0
        }
705
0
        single = single->next;
706
0
    }
707
708
0
    if (single == NULL)
709
0
        return WOLFSSL_FAILURE;
710
711
0
    if (status != NULL)
712
0
        *status = single->status->status;
713
0
#ifdef WOLFSSL_OCSP_PARSE_STATUS
714
0
    if (thisupd != NULL)
715
0
        *thisupd = &single->status->thisDateParsed;
716
0
    if (nextupd != NULL)
717
0
        *nextupd = &single->status->nextDateParsed;
718
#else
719
    if (thisupd != NULL)
720
        *thisupd = NULL;
721
    if (nextupd != NULL)
722
        *nextupd = NULL;
723
#endif
724
725
    /* TODO: Not needed for Nginx or httpd */
726
0
    if (reason != NULL)
727
0
        *reason = 0;
728
0
    if (revtime != NULL)
729
0
        *revtime = NULL;
730
731
0
    return WOLFSSL_SUCCESS;
732
0
}
733
734
const char *wolfSSL_OCSP_cert_status_str(long s)
735
0
{
736
0
    switch (s) {
737
0
        case CERT_GOOD:
738
0
            return "good";
739
0
        case CERT_REVOKED:
740
0
            return "revoked";
741
0
        case CERT_UNKNOWN:
742
0
            return "unknown";
743
0
        default:
744
0
            return "(UNKNOWN)";
745
0
    }
746
0
}
747
748
int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
749
    WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
750
0
{
751
0
    (void)thisupd;
752
0
    (void)nextupd;
753
0
    (void)sec;
754
0
    (void)maxsec;
755
    /* Dates validated in DecodeSingleResponse. */
756
0
    return WOLFSSL_SUCCESS;
757
0
}
758
759
void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
760
0
{
761
0
    FreeOcspEntry(certId, NULL);
762
0
    XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
763
0
}
764
765
WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
766
    const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
767
    const WOLFSSL_X509 *issuer)
768
0
{
769
0
    WOLFSSL_OCSP_CERTID* certId = NULL;
770
0
    CertStatus* certStatus = NULL;
771
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
772
0
    int ret = -1;
773
0
    DerBuffer* derCert = NULL;
774
0
    int dgstType;
775
0
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
776
777
0
    if (dgst == NULL) {
778
0
        dgstType = WC_HASH_TYPE_SHA;
779
0
    }
780
0
    else if (wolfSSL_EVP_get_hashinfo(dgst, &dgstType, NULL) !=
781
0
             WOLFSSL_SUCCESS) {
782
0
        return NULL;
783
0
    }
784
785
0
    if (dgstType != OCSP_DIGEST)
786
0
        return NULL;
787
788
0
    cm = wolfSSL_CertManagerNew();
789
0
    if (cm == NULL
790
0
            || subject == NULL || subject->derCert == NULL
791
0
            || issuer  == NULL || issuer->derCert  == NULL)
792
0
        goto out;
793
794
0
    WC_ALLOC_VAR_EX(cert, DecodedCert, 1, cm->heap, DYNAMIC_TYPE_DCERT,
795
0
        goto out);
796
797
0
    ret = AllocDer(&derCert, issuer->derCert->length,
798
0
        issuer->derCert->type, NULL);
799
0
    if (ret == 0) {
800
        /* AddCA() frees the buffer. */
801
0
        XMEMCPY(derCert->buffer, issuer->derCert->buffer,
802
0
                issuer->derCert->length);
803
0
        ret = AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
804
0
        if (ret != WOLFSSL_SUCCESS) {
805
0
            goto out;
806
0
        }
807
0
        derCert = NULL;
808
0
    }
809
810
0
    ret = -1;
811
812
0
    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
813
0
                                           cm->heap, DYNAMIC_TYPE_OPENSSL);
814
0
    if (certId == NULL)
815
0
        goto out;
816
817
0
    certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), cm->heap,
818
0
                                           DYNAMIC_TYPE_OPENSSL);
819
0
    if (certStatus == NULL)
820
0
        goto out;
821
822
0
    XMEMSET(certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
823
0
    XMEMSET(certStatus, 0, sizeof(CertStatus));
824
825
0
    certId->status = certStatus;
826
0
    certId->ownStatus = 1;
827
828
0
    InitDecodedCert(cert, subject->derCert->buffer,
829
0
                    subject->derCert->length, NULL);
830
0
    if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm, NULL) != 0) {
831
0
        FreeDecodedCert(cert);
832
0
        goto out;
833
0
    }
834
0
    else {
835
0
        certId->hashAlgoOID = wc_HashGetOID(OCSP_DIGEST);
836
0
        XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
837
0
        XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
838
0
        XMEMCPY(certId->status->serial, cert->serial, (size_t)cert->serialSz);
839
0
        certId->status->serialSz = cert->serialSz;
840
0
        FreeDecodedCert(cert);
841
0
    }
842
843
0
    ret = 0;
844
845
0
out:
846
847
0
    if (ret != 0) {
848
0
        if (derCert != NULL)
849
0
            FreeDer(&derCert);
850
0
        if (cm != NULL) {
851
0
            XFREE(certId, cm->heap, DYNAMIC_TYPE_OPENSSL);
852
0
            certId = NULL;
853
0
            XFREE(certStatus, cm->heap, DYNAMIC_TYPE_OPENSSL);
854
0
        }
855
0
    }
856
857
0
#ifdef WOLFSSL_SMALL_STACK
858
0
    if (cm != NULL)
859
0
        XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
860
0
#endif
861
862
0
    if (cm != NULL)
863
0
        wolfSSL_CertManagerFree(cm);
864
865
0
    return certId;
866
0
}
867
868
void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
869
0
{
870
0
    wolfSSL_OCSP_RESPONSE_free(basicResponse);
871
0
}
872
873
/* Calculate ancode CertID DER encoding following RFC 6960:
874
   CertID ::= SEQUENCE {
875
       hashAlgorithm       AlgorithmIdentifier,
876
       issuerNameHash      OCTET STRING,
877
       issuerKeyHash       OCTET STRING,
878
       serialNumber        CertificateSerialNumber }
879
*/
880
static int OcspEncodeCertID(WOLFSSL_OCSP_CERTID* id, byte* output,
881
    word32* totalSz, word32* intSize)
882
0
{
883
0
    word32 idx = 0;
884
0
    int ret;
885
886
0
    if (id == NULL || totalSz == NULL || intSize == NULL ||
887
0
        (output != NULL && (*totalSz == 0 || *totalSz <= *intSize)))
888
0
        return BAD_FUNC_ARG;
889
890
0
    if (output != NULL) {
891
0
        ret = SetSequence(*intSize, output);
892
0
        if (ret < 0)
893
0
            return ret;
894
0
        idx += ret;
895
0
    }
896
897
0
    ret = SetAlgoID(id->hashAlgoOID, ((output != NULL) ? output + idx : output),
898
0
        oidHashType, 0);
899
0
    if (ret <= 0)
900
0
        return -1;
901
0
    idx += ret;
902
903
    /* issuerNameHash */
904
0
    ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
905
0
    if (ret < 0)
906
0
        return ret;
907
0
    idx += ret;
908
0
    if (output != NULL)
909
0
        XMEMCPY(output + idx, id->issuerHash, OCSP_DIGEST_SIZE);
910
0
    idx += OCSP_DIGEST_SIZE;
911
912
    /* issuerKeyHash */
913
0
    ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
914
0
    if (ret < 0)
915
0
        return ret;
916
0
    idx += ret;
917
0
    if (output != NULL)
918
0
        XMEMCPY(output + idx, id->issuerKeyHash, OCSP_DIGEST_SIZE);
919
0
    idx += OCSP_DIGEST_SIZE;
920
921
    /* serialNumber */
922
0
    ret = SetASNInt(id->status->serialSz, id->status->serial[0], ((output != NULL) ? output + idx : output));
923
0
    if (ret < 0)
924
0
        return ret;
925
0
    idx += ret;
926
0
    if (output != NULL)
927
0
        XMEMCPY(output + idx, id->status->serial, id->status->serialSz);
928
0
    idx += id->status->serialSz;
929
930
0
    if (output == NULL) {
931
0
        *intSize = idx;
932
0
        ret = SetSequence(idx, NULL);
933
0
        if (ret < 0)
934
0
            return ret;
935
0
        idx += ret;
936
0
        *totalSz = idx;
937
0
    }
938
0
    else if (idx != *totalSz) {
939
0
        return BUFFER_E;
940
0
    }
941
942
0
    return 0;
943
0
}
944
945
static int OcspRespIdMatches(OcspResponse* resp, const byte* NameHash,
946
    const byte* keyHash)
947
0
{
948
0
    if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) {
949
0
        return XMEMCMP(NameHash, resp->responderId.nameHash,
950
0
                   SIGNER_DIGEST_SIZE) == 0;
951
0
    }
952
0
    else if (resp->responderIdType == OCSP_RESPONDER_ID_KEY) {
953
0
        return XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0;
954
0
    }
955
956
0
    return 0;
957
0
}
958
959
static int OcspFindSigner(WOLFSSL_OCSP_BASICRESP *resp,
960
    WOLF_STACK_OF(WOLFSSL_X509) *certs, DecodedCert **signer, int *embedded,
961
    unsigned long flags)
962
0
{
963
0
    WOLFSSL_X509 *signer_x509 = NULL;
964
0
    DecodedCert *certDecoded;
965
0
    int i;
966
967
0
    certDecoded = (DecodedCert *)XMALLOC(sizeof(*certDecoded), resp->heap,
968
0
                                            DYNAMIC_TYPE_DCERT);
969
0
    if (certDecoded == NULL)
970
0
        return MEMORY_E;
971
972
0
    for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
973
0
        signer_x509 = wolfSSL_sk_X509_value(certs, i);
974
0
        if (signer_x509 == NULL)
975
0
            continue;
976
977
0
        InitDecodedCert(certDecoded, signer_x509->derCert->buffer,
978
0
                       signer_x509->derCert->length, resp->heap);
979
0
        if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY,
980
0
                NULL, NULL) == 0) {
981
0
                if (OcspRespIdMatches(resp, certDecoded->subjectHash,
982
0
                        certDecoded->subjectKeyHash)) {
983
0
                    *signer = certDecoded;
984
0
                    *embedded = 0;
985
0
                    return 0;
986
0
                }
987
0
        }
988
0
        FreeDecodedCert(certDecoded);
989
0
    }
990
991
0
    if (flags & WOLFSSL_OCSP_NOINTERN) {
992
0
        XFREE(certDecoded, resp->heap, DYNAMIC_TYPE_DCERT);
993
0
        return ASN_NO_SIGNER_E;
994
0
    }
995
996
    /* not found in certs, search the cert embedded in the response */
997
0
    InitDecodedCert(certDecoded, resp->cert, resp->certSz, resp->heap);
998
0
    if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY, NULL, NULL) == 0) {
999
0
        if (OcspRespIdMatches(resp, certDecoded->subjectHash,
1000
0
                certDecoded->subjectKeyHash)) {
1001
0
            *signer = certDecoded;
1002
0
            *embedded = 1;
1003
0
            return 0;
1004
0
        }
1005
0
    }
1006
0
    FreeDecodedCert(certDecoded);
1007
1008
0
    XFREE(certDecoded, resp->heap, DYNAMIC_TYPE_DCERT);
1009
0
    return ASN_NO_SIGNER_E;
1010
0
}
1011
1012
static int OcspVerifySigner(WOLFSSL_OCSP_BASICRESP *resp, DecodedCert *cert,
1013
     WOLFSSL_X509_STORE *st, unsigned long flags)
1014
0
{
1015
0
    WC_DECLARE_VAR(c, DecodedCert, 1, 0);
1016
1017
0
    int ret = -1;
1018
0
    if (st == NULL)
1019
0
        return ASN_OCSP_CONFIRM_E;
1020
1021
0
    WC_ALLOC_VAR_EX(c, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
1022
0
        return MEMORY_E);
1023
1024
0
    InitDecodedCert(c, cert->source, cert->maxIdx, NULL);
1025
0
    if (ParseCertRelative(c, CERT_TYPE, VERIFY, st->cm, NULL) != 0) {
1026
0
        ret = ASN_OCSP_CONFIRM_E;
1027
0
        goto err;
1028
0
    }
1029
0
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
1030
0
    if ((flags & WOLFSSL_OCSP_NOCHECKS) == 0) {
1031
0
        ret = CheckOcspResponder(resp, c, st->cm);
1032
0
    }
1033
0
    else {
1034
0
        ret = 0;
1035
0
    }
1036
#else
1037
    (void)resp;
1038
    (void)flags;
1039
    ret = 0;
1040
#endif
1041
1042
0
err:
1043
0
    FreeDecodedCert(c);
1044
0
    WC_FREE_VAR_EX(c, NULL, DYNAMIC_TYPE_DCERT);
1045
0
    return ret;
1046
0
}
1047
/* Signature verified in DecodeBasicOcspResponse.
1048
 * But no store available to verify certificate. */
1049
int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP* bs,
1050
    WOLF_STACK_OF(WOLFSSL_X509) * certs, WOLFSSL_X509_STORE* st,
1051
    unsigned long flags)
1052
0
{
1053
0
    int         ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1054
0
    int embedded;
1055
0
    DecodedCert *cert = NULL;
1056
1057
0
    ret = OcspFindSigner(bs, certs, &cert, &embedded, flags);
1058
0
    if (ret != 0) {
1059
0
        WOLFSSL_MSG("OCSP no signer found");
1060
0
        return WOLFSSL_FAILURE;
1061
0
    }
1062
1063
    /* skip certificate verification if cert in certs and TRUST_OTHER is true */
1064
0
    if (!embedded && (flags & WOLFSSL_OCSP_TRUSTOTHER) != 0)
1065
0
        flags |= WOLFSSL_OCSP_NOVERIFY;
1066
1067
    /* verify response signature */
1068
0
    ret = ConfirmSignature(
1069
0
        &cert->sigCtx,
1070
0
        bs->response, bs->responseSz,
1071
0
        cert->publicKey, cert->pubKeySize, cert->keyOID,
1072
0
        bs->sig, bs->sigSz, bs->sigOID, bs->sigParams, bs->sigParamsSz,
1073
0
        NULL);
1074
1075
0
    if (ret != 0) {
1076
0
        WOLFSSL_MSG("OCSP signature verification failed");
1077
0
        ret = -1;
1078
0
        goto err;
1079
0
    }
1080
1081
0
    if ((flags & WOLFSSL_OCSP_NOVERIFY) == 0) {
1082
0
        ret = OcspVerifySigner(bs, cert, st, flags);
1083
0
    }
1084
1085
0
err:
1086
0
    FreeDecodedCert(cert);
1087
0
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1088
0
    return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1089
0
}
1090
1091
void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
1092
0
{
1093
0
    OcspEntry *s, *sNext;
1094
0
    if (response == NULL)
1095
0
        return;
1096
1097
1098
0
    s = response->single;
1099
0
    while (s != NULL) {
1100
0
        sNext = s->next;
1101
0
        FreeOcspEntry(s, NULL);
1102
0
        XFREE(s, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
1103
0
        s = sNext;
1104
0
    }
1105
1106
0
    XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1107
1108
0
    XFREE(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1109
0
}
1110
1111
#ifndef NO_BIO
1112
OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
1113
    OcspResponse** response)
1114
0
{
1115
0
    byte*         data;
1116
0
    byte*         p;
1117
0
    int           len;
1118
0
    int           dataAlloced = 0;
1119
0
    OcspResponse* ret = NULL;
1120
1121
0
    if (bio == NULL)
1122
0
        return NULL;
1123
1124
0
    if (bio->type == WOLFSSL_BIO_MEMORY) {
1125
0
        len = wolfSSL_BIO_get_mem_data(bio, &data);
1126
0
        if (len <= 0 || data == NULL) {
1127
0
            return NULL;
1128
0
        }
1129
0
    }
1130
0
#ifndef NO_FILESYSTEM
1131
0
    else if (bio->type == WOLFSSL_BIO_FILE) {
1132
0
        long fcur;
1133
0
        long flen;
1134
1135
0
        if (bio->ptr.fh == NULL)
1136
0
            return NULL;
1137
1138
0
        fcur = XFTELL(bio->ptr.fh);
1139
0
        if (fcur < 0)
1140
0
            return NULL;
1141
0
        if(XFSEEK(bio->ptr.fh, 0, SEEK_END) != 0)
1142
0
            return NULL;
1143
0
        flen = XFTELL(bio->ptr.fh);
1144
0
        if (flen < 0)
1145
0
            return NULL;
1146
0
        if (XFSEEK(bio->ptr.fh, fcur, SEEK_SET) != 0)
1147
0
            return NULL;
1148
1149
        /* check calculated length */
1150
0
        fcur = flen - fcur;
1151
0
        if (fcur > MAX_WOLFSSL_FILE_SIZE || fcur <= 0)
1152
0
            return NULL;
1153
1154
0
        data = (byte*)XMALLOC((size_t)fcur, 0, DYNAMIC_TYPE_TMP_BUFFER);
1155
0
        if (data == NULL)
1156
0
            return NULL;
1157
0
        dataAlloced = 1;
1158
1159
0
        len = wolfSSL_BIO_read(bio, (char *)data, (int)flen);
1160
0
    }
1161
0
#endif
1162
0
    else
1163
0
        return NULL;
1164
1165
0
    if (len > 0) {
1166
0
        p = data;
1167
0
        ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p,
1168
0
            len);
1169
0
    }
1170
1171
0
    if (dataAlloced)
1172
0
        XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
1173
1174
0
    return ret;
1175
0
}
1176
#endif /* !NO_BIO */
1177
1178
OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
1179
    const unsigned char** data, int len)
1180
0
{
1181
0
    OcspResponse *resp = NULL;
1182
0
    word32 idx = 0;
1183
0
    int length = 0;
1184
0
    int ret;
1185
1186
0
    if (data == NULL)
1187
0
        return NULL;
1188
1189
0
    if (response != NULL)
1190
0
        resp = *response;
1191
0
    if (resp == NULL) {
1192
0
        resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
1193
0
                                      DYNAMIC_TYPE_OCSP_REQUEST);
1194
0
        if (resp == NULL)
1195
0
            return NULL;
1196
0
        XMEMSET(resp, 0, sizeof(OcspResponse));
1197
0
    }
1198
1199
0
    resp->source = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1200
0
    if (resp->source == NULL) {
1201
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1202
0
        return NULL;
1203
0
    }
1204
0
    resp->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
1205
0
                                      DYNAMIC_TYPE_OCSP_ENTRY);
1206
0
    if (resp->single == NULL) {
1207
0
        XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1208
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1209
0
        return NULL;
1210
0
    }
1211
0
    XMEMSET(resp->single, 0, sizeof(OcspEntry));
1212
0
    resp->single->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
1213
0
                                      DYNAMIC_TYPE_OCSP_STATUS);
1214
0
    resp->single->ownStatus = 1;
1215
0
    if (resp->single->status == NULL) {
1216
0
        XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1217
0
        XFREE(resp->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
1218
0
        XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1219
0
        return NULL;
1220
0
    }
1221
0
    XMEMSET(resp->single->status, 0, sizeof(CertStatus));
1222
1223
0
    XMEMCPY(resp->source, *data, (size_t)len);
1224
0
    resp->maxIdx = (word32)len;
1225
1226
0
    ret = OcspResponseDecode(resp, NULL, NULL, 1, 1);
1227
0
    if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E)) {
1228
        /* for just converting from a DER to an internal structure the CA may
1229
         * not yet be known to this function for signature verification */
1230
0
        wolfSSL_OCSP_RESPONSE_free(resp);
1231
0
        return NULL;
1232
0
    }
1233
1234
0
    if (GetSequence(*data, &idx, &length, (word32)len) >= 0)
1235
0
        (*data) += (unsigned char) ((int)idx + length);
1236
1237
0
    if (response != NULL && *response == NULL)
1238
0
        *response = resp;
1239
1240
0
    return resp;
1241
0
}
1242
1243
int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
1244
    unsigned char** data)
1245
0
{
1246
0
    if (data == NULL)
1247
0
        return (int)response->maxIdx;
1248
1249
0
    XMEMCPY(*data, response->source, response->maxIdx);
1250
0
    return (int)response->maxIdx;
1251
0
}
1252
1253
int wolfSSL_OCSP_response_status(OcspResponse *response)
1254
0
{
1255
0
    return response->responseStatus;
1256
0
}
1257
1258
const char *wolfSSL_OCSP_response_status_str(long s)
1259
0
{
1260
0
    switch (s) {
1261
0
        case OCSP_SUCCESSFUL:
1262
0
            return "successful";
1263
0
        case OCSP_MALFORMED_REQUEST:
1264
0
            return "malformedrequest";
1265
0
        case OCSP_INTERNAL_ERROR:
1266
0
            return "internalerror";
1267
0
        case OCSP_TRY_LATER:
1268
0
            return "trylater";
1269
0
        case OCSP_SIG_REQUIRED:
1270
0
            return "sigrequired";
1271
0
        case OCSP_UNAUTHORIZED:
1272
0
            return "unauthorized";
1273
0
        default:
1274
0
            return "(UNKNOWN)";
1275
0
    }
1276
0
}
1277
1278
WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
1279
0
{
1280
0
    WOLFSSL_OCSP_BASICRESP* bs;
1281
0
    const unsigned char *ptr = response->source;
1282
1283
0
    bs = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, response->maxIdx);
1284
0
    return bs;
1285
0
}
1286
1287
OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
1288
0
{
1289
0
    OcspRequest* request;
1290
1291
0
    request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
1292
0
                                    DYNAMIC_TYPE_OPENSSL);
1293
0
    if (request != NULL)
1294
0
        XMEMSET(request, 0, sizeof(OcspRequest));
1295
1296
0
    return request;
1297
0
}
1298
1299
void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
1300
0
{
1301
0
    FreeOcspRequest(request);
1302
0
    XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL);
1303
0
}
1304
1305
int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
1306
0
{
1307
0
    int size;
1308
1309
0
    if (request == NULL)
1310
0
        return BAD_FUNC_ARG;
1311
1312
0
    size = EncodeOcspRequest(request, NULL, 0);
1313
0
    if (size <= 0 || data == NULL)
1314
0
        return size;
1315
1316
0
    return EncodeOcspRequest(request, *data, (word32) size);
1317
0
}
1318
1319
WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
1320
    WOLFSSL_OCSP_CERTID *cid)
1321
0
{
1322
0
    if (req == NULL || cid == NULL || cid->status == NULL)
1323
0
        return NULL;
1324
1325
0
    if (req->cid != NULL)
1326
0
        wolfSSL_OCSP_CERTID_free((WOLFSSL_OCSP_CERTID*)req->cid);
1327
    /* Keep to free */
1328
0
    req->cid = (void*)cid;
1329
1330
0
    XMEMCPY(req->issuerHash, cid->issuerHash, KEYID_SIZE);
1331
0
    XMEMCPY(req->issuerKeyHash, cid->issuerKeyHash, KEYID_SIZE);
1332
0
    if (cid->status->serialSz > req->serialSz) {
1333
0
        XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
1334
0
        req->serial = (byte*)XMALLOC((size_t)cid->status->serialSz,
1335
0
                req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
1336
0
        if (req->serial == NULL)
1337
0
            return NULL;
1338
0
    }
1339
0
    XMEMCPY(req->serial, cid->status->serial, (size_t)cid->status->serialSz);
1340
0
    req->serialSz = cid->status->serialSz;
1341
1342
0
    return req;
1343
0
}
1344
1345
WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID* id)
1346
0
{
1347
0
    WOLFSSL_OCSP_CERTID* certId;
1348
1349
0
    if (id == NULL)
1350
0
        return NULL;
1351
1352
0
    certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
1353
0
        NULL, DYNAMIC_TYPE_OPENSSL);
1354
0
    if (certId) {
1355
0
        XMEMCPY(certId, id, sizeof(WOLFSSL_OCSP_CERTID));
1356
0
    }
1357
0
    return certId;
1358
0
}
1359
1360
#ifndef NO_BIO
1361
int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
1362
        WOLFSSL_OCSP_REQUEST *req)
1363
0
{
1364
0
    int size = -1;
1365
0
    unsigned char* data = NULL;
1366
1367
0
    WOLFSSL_ENTER("wolfSSL_i2d_OCSP_REQUEST_bio");
1368
0
    if (out == NULL || req == NULL)
1369
0
        return WOLFSSL_FAILURE;
1370
1371
0
    size = wolfSSL_i2d_OCSP_REQUEST(req, NULL);
1372
0
    if (size > 0) {
1373
0
        data = (unsigned char*) XMALLOC((size_t)size, out->heap,
1374
0
                DYNAMIC_TYPE_TMP_BUFFER);
1375
0
    }
1376
1377
0
    if (data != NULL) {
1378
0
        size = wolfSSL_i2d_OCSP_REQUEST(req, &data);
1379
0
    }
1380
1381
0
    if (size <= 0) {
1382
0
        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1383
0
        return WOLFSSL_FAILURE;
1384
0
    }
1385
1386
0
    if (wolfSSL_BIO_write(out, data, size) == (int)size) {
1387
0
        XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1388
0
        return WOLFSSL_SUCCESS;
1389
0
    }
1390
1391
0
    XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
1392
0
    return WOLFSSL_FAILURE;
1393
0
}
1394
#endif /* !NO_BIO */
1395
1396
int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data)
1397
0
{
1398
0
    int allocated = 0;
1399
0
    word32 derSz = 0;
1400
0
    word32 intSz = 0;
1401
0
    int ret;
1402
0
    WOLFSSL_ENTER("wolfSSL_i2d_OCSP_CERTID");
1403
1404
0
    if (id == NULL)
1405
0
        return -1;
1406
1407
0
    if (id->rawCertId != NULL) {
1408
0
        derSz = id->rawCertIdSize;
1409
0
    }
1410
0
    else {
1411
0
        ret = OcspEncodeCertID(id, NULL, &derSz, &intSz);
1412
0
        if (ret != 0) {
1413
0
            WOLFSSL_MSG("Failed to calculate CertID size");
1414
0
            return -1;
1415
0
        }
1416
0
    }
1417
1418
0
    if (data == NULL) {
1419
0
        return derSz;
1420
0
    }
1421
1422
0
    if (*data == NULL) {
1423
        /* Allocate buffer for DER encoding */
1424
0
        *data = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
1425
0
        if (*data == NULL) {
1426
0
            WOLFSSL_MSG("Failed to allocate memory for CertID DER encoding");
1427
0
            return -1;
1428
0
        }
1429
0
        allocated = 1;
1430
0
    }
1431
1432
0
    if (id->rawCertId != NULL) {
1433
0
        XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
1434
0
    }
1435
0
    else {
1436
0
        ret = OcspEncodeCertID(id, *data, &derSz, &intSz);
1437
0
        if (ret < 0) {
1438
0
            WOLFSSL_MSG("Failed to encode CertID");
1439
0
            if (allocated) {
1440
0
                XFREE(*data, NULL, DYNAMIC_TYPE_OPENSSL);
1441
0
                *data = NULL;
1442
0
            }
1443
0
            return -1;
1444
0
        }
1445
0
    }
1446
1447
0
    if (!allocated)
1448
0
        *data += derSz;
1449
1450
0
    return derSz;
1451
0
}
1452
1453
WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut,
1454
                                             const unsigned char** derIn,
1455
                                             int length)
1456
0
{
1457
0
    WOLFSSL_OCSP_CERTID *cid = NULL;
1458
0
    int isAllocated = 0;
1459
0
    word32 idx = 0;
1460
0
    int ret;
1461
1462
0
    if (derIn == NULL || *derIn == NULL || length <= 0)
1463
0
        return NULL;
1464
1465
0
    if (cidOut != NULL && *cidOut != NULL) {
1466
0
        cid = *cidOut;
1467
0
        FreeOcspEntry(cid, NULL);
1468
0
    }
1469
0
    else {
1470
0
        cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
1471
0
            DYNAMIC_TYPE_OPENSSL);
1472
0
        if (cid == NULL)
1473
0
            return NULL;
1474
0
        isAllocated = 1;
1475
0
    }
1476
1477
0
    XMEMSET(cid, 0, sizeof(WOLFSSL_OCSP_CERTID));
1478
0
    cid->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
1479
0
        DYNAMIC_TYPE_OCSP_STATUS);
1480
0
    if (cid->status == NULL) {
1481
0
        XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
1482
0
        return NULL;
1483
0
    }
1484
0
    XMEMSET(cid->status, 0, sizeof(CertStatus));
1485
0
    cid->ownStatus = 1;
1486
1487
0
    ret = OcspDecodeCertID(*derIn, &idx, length, cid);
1488
0
    if (ret != 0) {
1489
0
        FreeOcspEntry(cid, NULL);
1490
0
        if (isAllocated) {
1491
0
            XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
1492
0
        }
1493
0
        return NULL;
1494
0
    }
1495
1496
0
    *derIn += idx;
1497
1498
0
    if (isAllocated && cidOut != NULL)
1499
0
        *cidOut = cid;
1500
1501
0
    return cid;
1502
0
}
1503
1504
const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(
1505
    const WOLFSSL_OCSP_SINGLERESP *single)
1506
0
{
1507
0
    return single;
1508
0
}
1509
1510
/**
1511
 * Compare two WOLFSSL_OCSP_CERTID objects
1512
 * @param a
1513
 * @param b
1514
 * @return 0 on success and when objects have the same id otherwise either
1515
 *         the id's don't match or an error occurred
1516
 */
1517
int wolfSSL_OCSP_id_cmp(WOLFSSL_OCSP_CERTID *a, WOLFSSL_OCSP_CERTID *b)
1518
0
{
1519
0
    int ret = 0;
1520
0
    if (a == NULL || b == NULL)
1521
0
        return WOLFSSL_FATAL_ERROR;
1522
1523
0
    ret = a->hashAlgoOID != b->hashAlgoOID;
1524
0
    if (ret == 0)
1525
0
        ret = XMEMCMP(a->issuerHash, b->issuerHash, OCSP_DIGEST_SIZE);
1526
0
    if (ret == 0)
1527
0
        ret = XMEMCMP(a->issuerKeyHash, b->issuerKeyHash, OCSP_DIGEST_SIZE);
1528
0
    if (ret == 0) {
1529
0
        if (a->status != NULL && b->status != NULL) {
1530
0
            if (a->status->serialSz == b->status->serialSz)
1531
0
                ret = XMEMCMP(a->status->serial, b->status->serial,
1532
0
                        (size_t)a->status->serialSz);
1533
0
            else
1534
0
                ret = -1;
1535
0
        }
1536
0
        else if (a->status != b->status) {
1537
            /* If either is not null then return non-zero */
1538
0
            ret = -1;
1539
0
        }
1540
0
    }
1541
0
    return ret;
1542
0
}
1543
1544
int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single,
1545
                                    int *reason,
1546
                                    WOLFSSL_ASN1_TIME **revtime,
1547
                                    WOLFSSL_ASN1_TIME **thisupd,
1548
                                    WOLFSSL_ASN1_TIME **nextupd)
1549
0
{
1550
0
    if (single == NULL)
1551
0
        return WOLFSSL_FAILURE;
1552
1553
0
#ifdef WOLFSSL_OCSP_PARSE_STATUS
1554
0
    if (thisupd != NULL)
1555
0
        *thisupd = &single->status->thisDateParsed;
1556
0
    if (nextupd != NULL)
1557
0
        *nextupd = &single->status->nextDateParsed;
1558
#else
1559
    if (thisupd != NULL)
1560
        *thisupd = NULL;
1561
    if (nextupd != NULL)
1562
        *nextupd = NULL;
1563
#endif
1564
0
    if (reason != NULL)
1565
0
        *reason = 0;
1566
0
    if (revtime != NULL)
1567
0
        *revtime = NULL;
1568
1569
0
    return single->status->status;
1570
0
}
1571
1572
int wolfSSL_OCSP_resp_count(WOLFSSL_OCSP_BASICRESP *bs)
1573
0
{
1574
0
    WOLFSSL_OCSP_SINGLERESP* single;
1575
0
    int count = 0;
1576
1577
0
    if (bs == NULL)
1578
0
        return WOLFSSL_FAILURE;
1579
1580
0
    single = bs->single;
1581
0
    while(single != NULL)
1582
0
    {
1583
0
        ++count;
1584
0
        single = single->next;
1585
0
    }
1586
1587
0
    return count;
1588
0
}
1589
1590
WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0(WOLFSSL_OCSP_BASICRESP *bs, int idx)
1591
0
{
1592
0
    WOLFSSL_OCSP_SINGLERESP* single;
1593
0
    int currIdx = 0;
1594
1595
0
    if (bs == NULL)
1596
0
        return NULL;
1597
1598
0
    single = bs->single;
1599
0
    while(single != NULL && currIdx != idx)
1600
0
    {
1601
0
        single = single->next;
1602
0
        ++currIdx;
1603
0
    }
1604
1605
0
    return single;
1606
0
}
1607
1608
#endif /* OPENSSL_EXTRA */
1609
1610
#ifdef OPENSSL_ALL
1611
1612
/*******************************************************************************
1613
 * START OF WOLFSSL_OCSP_REQ_CTX API
1614
 ******************************************************************************/
1615
1616
enum ocspReqStates {
1617
    ORS_INVALID = 0,
1618
    ORS_HEADER_ADDED,
1619
    ORS_REQ_DONE
1620
};
1621
1622
enum ocspReqIOStates {
1623
    ORIOS_INVALID = 0,
1624
    ORIOS_WRITE,
1625
    ORIOS_READ
1626
};
1627
1628
WOLFSSL_OCSP_REQ_CTX* wolfSSL_OCSP_REQ_CTX_new(WOLFSSL_BIO *bio, int maxline)
1629
0
{
1630
0
    WOLFSSL_OCSP_REQ_CTX* ret = NULL;
1631
1632
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_new");
1633
1634
0
    if (maxline <= 0)
1635
0
        maxline = OCSP_MAX_REQUEST_SZ;
1636
1637
0
    ret = (WOLFSSL_OCSP_REQ_CTX*)XMALLOC(sizeof(*ret), NULL,
1638
0
            DYNAMIC_TYPE_OPENSSL);
1639
0
    if (ret != NULL) {
1640
0
        XMEMSET(ret, 0, sizeof(*ret));
1641
0
        ret->buf = (byte*)XMALLOC((word32)maxline, NULL, DYNAMIC_TYPE_OPENSSL);
1642
0
        if (ret->buf == NULL)
1643
0
            goto error;
1644
0
        ret->reqResp = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
1645
0
        ret->bufLen = maxline;
1646
0
        ret->bio = bio;
1647
0
        ret->ioState = ORIOS_WRITE;
1648
0
    }
1649
1650
0
    return ret;
1651
0
error:
1652
0
    wolfSSL_OCSP_REQ_CTX_free(ret);
1653
0
    return NULL;
1654
0
}
1655
1656
void wolfSSL_OCSP_REQ_CTX_free(WOLFSSL_OCSP_REQ_CTX *ctx)
1657
0
{
1658
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_free");
1659
0
    if (ctx != NULL) {
1660
0
        if (ctx->buf != NULL)
1661
0
            XFREE(ctx->buf, NULL, DYNAMIC_TYPE_OPENSSL);
1662
0
        if (ctx->reqResp != NULL)
1663
0
            wolfSSL_BIO_free(ctx->reqResp);
1664
0
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
1665
0
    }
1666
0
}
1667
1668
WOLFSSL_OCSP_REQ_CTX* wolfSSL_OCSP_sendreq_new(WOLFSSL_BIO *bio,
1669
        const char *path, OcspRequest *req, int maxline)
1670
0
{
1671
0
    WOLFSSL_OCSP_REQ_CTX* ret = NULL;
1672
1673
0
    WOLFSSL_ENTER("wolfSSL_OCSP_sendreq_new");
1674
1675
0
    ret = wolfSSL_OCSP_REQ_CTX_new(bio, maxline);
1676
0
    if (ret == NULL)
1677
0
        return NULL;
1678
1679
0
    if (wolfSSL_OCSP_REQ_CTX_http(ret, "POST", path) != WOLFSSL_SUCCESS)
1680
0
        goto error;
1681
1682
0
    if (req != NULL &&
1683
0
            wolfSSL_OCSP_REQ_CTX_set1_req(ret, req) != WOLFSSL_SUCCESS)
1684
0
        goto error;
1685
1686
0
    return ret;
1687
0
error:
1688
0
    wolfSSL_OCSP_REQ_CTX_free(ret);
1689
0
    return NULL;
1690
0
}
1691
1692
int wolfSSL_OCSP_REQ_CTX_add1_header(WOLFSSL_OCSP_REQ_CTX *ctx,
1693
                             const char *name, const char *value)
1694
0
{
1695
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_add1_header");
1696
1697
0
    if (name == NULL) {
1698
0
        WOLFSSL_MSG("Bad parameter");
1699
0
        return WOLFSSL_FAILURE;
1700
0
    }
1701
0
    if (wolfSSL_BIO_puts(ctx->reqResp, name) <= 0) {
1702
0
        WOLFSSL_MSG("wolfSSL_BIO_puts error");
1703
0
        return WOLFSSL_FAILURE;
1704
0
    }
1705
0
    if (value != NULL) {
1706
0
        if (wolfSSL_BIO_write(ctx->reqResp, ": ", 2) != 2) {
1707
0
            WOLFSSL_MSG("wolfSSL_BIO_write error");
1708
0
            return WOLFSSL_FAILURE;
1709
0
        }
1710
0
        if (wolfSSL_BIO_puts(ctx->reqResp, value) <= 0) {
1711
0
            WOLFSSL_MSG("wolfSSL_BIO_puts error");
1712
0
            return WOLFSSL_FAILURE;
1713
0
        }
1714
0
    }
1715
0
    if (wolfSSL_BIO_write(ctx->reqResp, "\r\n", 2) != 2) {
1716
0
        WOLFSSL_MSG("wolfSSL_BIO_write error");
1717
0
        return WOLFSSL_FAILURE;
1718
0
    }
1719
1720
0
    ctx->state = ORS_HEADER_ADDED;
1721
1722
0
    return WOLFSSL_SUCCESS;
1723
0
}
1724
1725
int wolfSSL_OCSP_REQ_CTX_http(WOLFSSL_OCSP_REQ_CTX *ctx, const char *op,
1726
        const char *path)
1727
0
{
1728
0
    static const char http_hdr[] = "%s %s HTTP/1.0\r\n";
1729
1730
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_http");
1731
1732
0
    if (ctx == NULL || op == NULL) {
1733
0
        WOLFSSL_MSG("Bad parameter");
1734
0
        return WOLFSSL_FAILURE;
1735
0
    }
1736
1737
0
    if (path == NULL)
1738
0
        path = "/";
1739
1740
0
    if (wolfSSL_BIO_printf(ctx->reqResp, http_hdr, op, path) <= 0) {
1741
0
        WOLFSSL_MSG("WOLFSSL_OCSP_REQ_CTX: wolfSSL_BIO_printf error");
1742
0
        return WOLFSSL_FAILURE;
1743
0
    }
1744
1745
0
    ctx->state = ORS_HEADER_ADDED;
1746
1747
0
    return WOLFSSL_SUCCESS;
1748
0
}
1749
1750
int wolfSSL_OCSP_REQ_CTX_set1_req(WOLFSSL_OCSP_REQ_CTX *ctx, OcspRequest *req)
1751
0
{
1752
0
    static const char req_hdr[] =
1753
0
        "Content-Type: application/ocsp-request\r\n"
1754
0
        "Content-Length: %d\r\n\r\n";
1755
    /* Should be enough to hold Content-Length */
1756
0
    char req_hdr_buf[sizeof(req_hdr) + 10];
1757
0
    int req_hdr_buf_len;
1758
0
    int req_len = wolfSSL_i2d_OCSP_REQUEST(req, NULL);
1759
1760
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_set1_req");
1761
1762
0
    if (ctx == NULL || req == NULL) {
1763
0
        WOLFSSL_MSG("Bad parameters");
1764
0
        return WOLFSSL_FAILURE;
1765
0
    }
1766
1767
0
    if (req_len <= 0) {
1768
0
        WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request len error");
1769
0
        return WOLFSSL_FAILURE;
1770
0
    }
1771
1772
0
    req_hdr_buf_len =
1773
0
            XSNPRINTF(req_hdr_buf, sizeof(req_hdr_buf), req_hdr, req_len);
1774
0
    if (req_hdr_buf_len >= (int)sizeof(req_hdr_buf)) {
1775
0
        WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request too long");
1776
0
        return WOLFSSL_FAILURE;
1777
0
    }
1778
1779
0
    if (wolfSSL_BIO_write(ctx->reqResp, req_hdr_buf, req_hdr_buf_len) <= 0) {
1780
0
        WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: wolfSSL_BIO_write error");
1781
0
        return WOLFSSL_FAILURE;
1782
0
    }
1783
1784
0
    if (wolfSSL_i2d_OCSP_REQUEST_bio(ctx->reqResp, req) <= 0) {
1785
0
        WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request i2d error");
1786
0
        return WOLFSSL_FAILURE;
1787
0
    }
1788
1789
0
    ctx->state = ORS_REQ_DONE;
1790
1791
0
    return WOLFSSL_SUCCESS;
1792
0
}
1793
1794
static int OCSP_REQ_CTX_bio_cb(char *buf, int sz, void *ctx)
1795
0
{
1796
0
    return BioReceiveInternal((WOLFSSL_BIO*)ctx, NULL, buf, sz);
1797
0
}
1798
1799
int wolfSSL_OCSP_REQ_CTX_nbio(WOLFSSL_OCSP_REQ_CTX *ctx)
1800
0
{
1801
0
    WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_nbio");
1802
1803
0
    if (ctx == NULL) {
1804
0
        WOLFSSL_MSG("Bad parameters");
1805
0
        return WOLFSSL_FAILURE;
1806
0
    }
1807
1808
0
    switch ((enum ocspReqIOStates)ctx->ioState) {
1809
0
        case ORIOS_WRITE:
1810
0
        case ORIOS_READ:
1811
0
            break;
1812
0
        case ORIOS_INVALID:
1813
0
        default:
1814
0
            WOLFSSL_MSG("Invalid ctx->ioState state");
1815
0
            return WOLFSSL_FAILURE;
1816
0
    }
1817
1818
0
    if (ctx->ioState == ORIOS_WRITE) {
1819
0
        switch ((enum ocspReqStates)ctx->state) {
1820
0
            case ORS_HEADER_ADDED:
1821
                /* Write final new line to complete http header */
1822
0
                if (wolfSSL_BIO_write(ctx->reqResp, "\r\n", 2) != 2) {
1823
0
                    WOLFSSL_MSG("wolfSSL_BIO_write error");
1824
0
                    return WOLFSSL_FAILURE;
1825
0
                }
1826
0
                break;
1827
0
            case ORS_REQ_DONE:
1828
0
                break;
1829
0
            case ORS_INVALID:
1830
0
            default:
1831
0
                WOLFSSL_MSG("Invalid WOLFSSL_OCSP_REQ_CTX state");
1832
0
                return WOLFSSL_FAILURE;
1833
0
        }
1834
0
    }
1835
1836
0
    switch ((enum ocspReqIOStates)ctx->ioState) {
1837
0
        case ORIOS_WRITE:
1838
0
        {
1839
0
            const unsigned char *req;
1840
0
            int reqLen = wolfSSL_BIO_get_mem_data(ctx->reqResp, (void*)&req);
1841
0
            if (reqLen <= 0) {
1842
0
                WOLFSSL_MSG("wolfSSL_BIO_get_mem_data error");
1843
0
                return WOLFSSL_FAILURE;
1844
0
            }
1845
0
            while (ctx->sent < reqLen) {
1846
0
                int sent = wolfSSL_BIO_write(ctx->bio, req + ctx->sent,
1847
0
                        reqLen - ctx->sent);
1848
0
                if (sent <= 0) {
1849
0
                    if (wolfSSL_BIO_should_retry(ctx->bio))
1850
0
                        return WOLFSSL_FATAL_ERROR;
1851
0
                    WOLFSSL_MSG("wolfSSL_BIO_write error");
1852
0
                    ctx->ioState = ORIOS_INVALID;
1853
0
                    return 0;
1854
0
                }
1855
0
                ctx->sent += sent;
1856
0
            }
1857
0
            ctx->sent = 0;
1858
0
            ctx->ioState = ORIOS_READ;
1859
0
            (void)wolfSSL_BIO_reset(ctx->reqResp);
1860
0
            FALL_THROUGH;
1861
0
        }
1862
0
        case ORIOS_READ:
1863
0
        {
1864
0
            byte* resp = NULL;
1865
0
            int respLen;
1866
0
            int ret;
1867
1868
0
            if (ctx->buf == NULL) /* Should be allocated in new call */
1869
0
                return WOLFSSL_FAILURE;
1870
1871
0
            ret = wolfIO_HttpProcessResponseOcspGenericIO(OCSP_REQ_CTX_bio_cb,
1872
0
                    ctx->bio, &resp, ctx->buf, ctx->bufLen, NULL);
1873
0
            if (ret <= 0) {
1874
0
                if (resp != NULL)
1875
0
                    XFREE(resp, NULL, DYNAMIC_TYPE_OCSP);
1876
0
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_WANT_READ) ||
1877
0
                    ret == WC_NO_ERR_TRACE(OCSP_WANT_READ))
1878
0
                {
1879
0
                    return WOLFSSL_FATAL_ERROR;
1880
0
                }
1881
0
                return WOLFSSL_FAILURE;
1882
0
            }
1883
0
            respLen = ret;
1884
0
            ret = wolfSSL_BIO_write(ctx->reqResp, resp, respLen);
1885
0
            XFREE(resp, NULL, DYNAMIC_TYPE_OCSP);
1886
0
            if (ret != respLen) {
1887
0
                WOLFSSL_MSG("wolfSSL_BIO_write error");
1888
0
                return WOLFSSL_FAILURE;
1889
0
            }
1890
0
            break;
1891
0
        }
1892
0
        case ORIOS_INVALID:
1893
0
        default:
1894
0
            WOLFSSL_MSG("Invalid ctx->ioState state");
1895
0
            return WOLFSSL_FAILURE;
1896
0
    }
1897
1898
0
    return WOLFSSL_SUCCESS;
1899
0
}
1900
1901
int wolfSSL_OCSP_sendreq_nbio(OcspResponse **presp, WOLFSSL_OCSP_REQ_CTX *ctx)
1902
0
{
1903
0
    int ret;
1904
0
    int len;
1905
0
    const unsigned char *resp = NULL;
1906
1907
0
    WOLFSSL_ENTER("wolfSSL_OCSP_sendreq_nbio");
1908
1909
0
    if (presp == NULL)
1910
0
        return WOLFSSL_FAILURE;
1911
1912
0
    ret = wolfSSL_OCSP_REQ_CTX_nbio(ctx);
1913
0
    if (ret != WOLFSSL_SUCCESS)
1914
0
        return ret;
1915
1916
0
    len = wolfSSL_BIO_get_mem_data(ctx->reqResp, (void*)&resp);
1917
0
    if (len <= 0)
1918
0
        return WOLFSSL_FAILURE;
1919
0
    return wolfSSL_d2i_OCSP_RESPONSE(presp, &resp, len) != NULL
1920
0
            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1921
0
}
1922
1923
/*******************************************************************************
1924
 * END OF WOLFSSL_OCSP_REQ_CTX API
1925
 ******************************************************************************/
1926
1927
#ifndef NO_WOLFSSL_STUB
1928
int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext,
1929
        int idx)
1930
0
{
1931
0
    WOLFSSL_STUB("wolfSSL_OCSP_REQUEST_add_ext");
1932
0
    (void)req;
1933
0
    (void)ext;
1934
0
    (void)idx;
1935
0
    return WOLFSSL_FATAL_ERROR;
1936
0
}
1937
#endif
1938
1939
#ifndef NO_WOLFSSL_STUB
1940
OcspResponse* wolfSSL_OCSP_response_create(int status,
1941
    WOLFSSL_OCSP_BASICRESP* bs)
1942
0
{
1943
0
    WOLFSSL_STUB("wolfSSL_OCSP_response_create");
1944
0
    (void)status;
1945
0
    (void)bs;
1946
0
    return NULL;
1947
0
}
1948
#endif
1949
1950
#ifndef NO_WOLFSSL_STUB
1951
const char* wolfSSL_OCSP_crl_reason_str(long s)
1952
0
{
1953
0
    WOLFSSL_STUB("wolfSSL_OCSP_crl_reason_str");
1954
0
    (void)s;
1955
0
    return NULL;
1956
0
}
1957
#endif
1958
1959
/* Returns elements of an OCSP_CERTID struct. Currently only supports
1960
 * returning the serial number, and returns an error if user requests
1961
 * any of name, pmd, and/or keyHash.
1962
 * Return 1 on success, 0 on failure */
1963
int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name,
1964
  WOLFSSL_ASN1_OBJECT **pmd, WOLFSSL_ASN1_STRING **keyHash,
1965
  WOLFSSL_ASN1_INTEGER **serial, WOLFSSL_OCSP_CERTID *cid)
1966
0
{
1967
0
    WOLFSSL_ENTER("wolfSSL_OCSP_id_get0_info");
1968
1969
0
    if (cid == NULL)
1970
0
        return 0;
1971
1972
    /* build up ASN1_INTEGER for serial */
1973
0
    if (serial != NULL) {
1974
0
        int i = 0;
1975
0
        WOLFSSL_ASN1_INTEGER* ser;
1976
1977
0
        ser = wolfSSL_ASN1_INTEGER_new();
1978
0
        if (ser == NULL)
1979
0
            return 0;
1980
1981
0
        if (cid->status->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
1982
            /* allocate data buffer, +2 for type and length */
1983
0
            ser->data = (unsigned char*)XMALLOC((size_t)cid->status->serialSz + 2, NULL,
1984
0
                DYNAMIC_TYPE_OPENSSL);
1985
0
            if (ser->data == NULL) {
1986
0
                wolfSSL_ASN1_INTEGER_free(ser);
1987
0
                return 0;
1988
0
            }
1989
0
            ser->dataMax = (unsigned int)cid->status->serialSz + 2;
1990
0
            ser->isDynamic = 1;
1991
0
        } else {
1992
            /* Use array instead of dynamic memory */
1993
0
            ser->data    = ser->intData;
1994
0
            ser->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
1995
0
        }
1996
1997
        #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
1998
            /* Serial number starts at 0 index of ser->data */
1999
            XMEMCPY(&ser->data[i], cid->status->serial,
2000
                (size_t)cid->status->serialSz);
2001
            ser->length = cid->status->serialSz;
2002
        #else
2003
0
            ser->data[i++] = ASN_INTEGER;
2004
0
            i += SetLength(cid->status->serialSz, ser->data + i);
2005
0
            XMEMCPY(&ser->data[i], cid->status->serial,
2006
0
                (size_t)cid->status->serialSz);
2007
0
            ser->length = i + cid->status->serialSz;
2008
0
        #endif
2009
2010
0
        cid->status->serialInt = ser;
2011
0
        *serial = ser;
2012
0
    }
2013
2014
    /* Not needed for Apache, return error if user is requesting */
2015
0
    if (name != NULL || pmd != NULL || keyHash != NULL) {
2016
0
        if (name != NULL)
2017
0
            *name = NULL;
2018
2019
0
        if (pmd != NULL)
2020
0
            *pmd = NULL;
2021
2022
0
        if (keyHash != NULL)
2023
0
            *keyHash = NULL;
2024
0
        return 0;
2025
0
    }
2026
2027
0
    return 1;
2028
0
}
2029
2030
int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val,
2031
        int sz)
2032
0
{
2033
0
    WC_RNG rng;
2034
2035
0
    WOLFSSL_ENTER("wolfSSL_OCSP_request_add1_nonce");
2036
2037
0
    if (req == NULL || sz > MAX_OCSP_NONCE_SZ) {
2038
0
        WOLFSSL_MSG("Bad parameter");
2039
0
        return WOLFSSL_FAILURE;
2040
0
    }
2041
2042
0
    if (sz <= 0)
2043
0
        sz = MAX_OCSP_NONCE_SZ;
2044
2045
0
    if (val != NULL) {
2046
0
        XMEMCPY(req->nonce, val, (size_t)sz);
2047
0
    }
2048
0
    else {
2049
0
        if (
2050
0
#ifndef HAVE_FIPS
2051
0
            wc_InitRng_ex(&rng, req->heap, INVALID_DEVID)
2052
#else
2053
            wc_InitRng(&rng)
2054
#endif
2055
0
            != 0) {
2056
0
            WOLFSSL_MSG("RNG init failed");
2057
0
            return WOLFSSL_FAILURE;
2058
0
        }
2059
0
        if (wc_RNG_GenerateBlock(&rng, req->nonce, (word32)sz) != 0) {
2060
0
            WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
2061
0
            wc_FreeRng(&rng);
2062
0
            return WOLFSSL_FAILURE;
2063
0
        }
2064
0
        wc_FreeRng(&rng);
2065
0
    }
2066
0
    req->nonceSz = sz;
2067
2068
0
    return WOLFSSL_SUCCESS;
2069
0
}
2070
2071
/* Returns result of OCSP nonce comparison. Return values:
2072
 *  1 - nonces are both present and equal
2073
 *  2 - both nonces are absent
2074
 *  3 - nonce only present in response
2075
 * -1 - nonce only present in request
2076
 *  0 - both nonces present and equal
2077
 */
2078
int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs)
2079
0
{
2080
0
    byte* reqNonce = NULL;
2081
0
    byte* rspNonce = NULL;
2082
0
    int reqNonceSz = 0;
2083
0
    int rspNonceSz = 0;
2084
2085
0
    WOLFSSL_ENTER("wolfSSL_OCSP_check_nonce");
2086
2087
0
    if (req != NULL) {
2088
0
        reqNonce = req->nonce;
2089
0
        reqNonceSz = req->nonceSz;
2090
0
    }
2091
2092
0
    if (bs != NULL) {
2093
0
        rspNonce = bs->nonce;
2094
0
        rspNonceSz = bs->nonceSz;
2095
0
    }
2096
2097
    /* nonce absent in both req and rsp */
2098
0
    if (reqNonce == NULL && rspNonce == NULL)
2099
0
        return 2;
2100
2101
    /* nonce present in rsp only */
2102
0
    if (reqNonce == NULL && rspNonce != NULL)
2103
0
        return 3;
2104
2105
    /* nonce present in req only */
2106
0
    if (reqNonce != NULL && rspNonce == NULL)
2107
0
        return WOLFSSL_FATAL_ERROR;
2108
2109
    /* nonces are present and equal, return 1. Extra NULL check for fixing
2110
        scan-build warning. */
2111
0
    if (reqNonceSz == rspNonceSz && reqNonce && rspNonce) {
2112
0
        if (XMEMCMP(reqNonce, rspNonce, (size_t)reqNonceSz) == 0)
2113
0
            return 1;
2114
0
    }
2115
2116
    /* nonces are present but not equal */
2117
0
    return 0;
2118
0
}
2119
2120
#endif /* OPENSSL_ALL */
2121
2122
#else /* HAVE_OCSP */
2123
2124
2125
#ifdef _MSC_VER
2126
    /* 4206 warning for blank file */
2127
    #pragma warning(disable: 4206)
2128
#endif
2129
2130
2131
#endif /* HAVE_OCSP */
2132
#endif /* WOLFCRYPT_ONLY */