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