source: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/ocsp.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

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