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