source: azure_iot_hub/trunk/wolfssl-3.15.7/src/ocsp.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 24.1 KB
Line 
1/* ocsp.c
2 *
3 * Copyright (C) 2006-2017 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
202static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
203 OcspEntry* entry, CertStatus** status, buffer* responseBuffer)
204{
205 int ret = OCSP_INVALID_STATUS;
206
207 WOLFSSL_ENTER("GetOcspStatus");
208
209 *status = NULL;
210
211 if (wc_LockMutex(&ocsp->ocspLock) != 0) {
212 WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
213 return BAD_MUTEX_E;
214 }
215
216 for (*status = entry->status; *status; *status = (*status)->next)
217 if ((*status)->serialSz == request->serialSz
218 && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
219 break;
220
221 if (responseBuffer && *status && !(*status)->rawOcspResponse) {
222 /* force fetching again */
223 ret = OCSP_INVALID_STATUS;
224 }
225 else if (*status) {
226#ifndef NO_ASN_TIME
227 if (XVALIDATE_DATE((*status)->thisDate,
228 (*status)->thisDateFormat, BEFORE)
229 && ((*status)->nextDate[0] != 0)
230 && XVALIDATE_DATE((*status)->nextDate,
231 (*status)->nextDateFormat, AFTER))
232#endif
233 {
234 ret = xstat2err((*status)->status);
235
236 if (responseBuffer) {
237 responseBuffer->buffer = (byte*)XMALLOC(
238 (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
239
240 if (responseBuffer->buffer) {
241 responseBuffer->length = (*status)->rawOcspResponseSz;
242 XMEMCPY(responseBuffer->buffer,
243 (*status)->rawOcspResponse,
244 (*status)->rawOcspResponseSz);
245 }
246 }
247 }
248 }
249
250 wc_UnLockMutex(&ocsp->ocspLock);
251
252 return ret;
253}
254
255/* Check that the response for validity. Store result in status.
256 *
257 * ocsp Context object for OCSP status.
258 * response OCSP response message data.
259 * responseSz Length of OCSP response message data.
260 * reponseBuffer Buffer object to return the response with.
261 * status The certificate status object.
262 * entry The OCSP entry for this certificate.
263 * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
264 */
265static int CheckResponse(WOLFSSL_OCSP* ocsp, byte* response, int responseSz,
266 buffer* responseBuffer, CertStatus* status,
267 OcspEntry* entry, OcspRequest* ocspRequest)
268{
269#ifdef WOLFSSL_SMALL_STACK
270 CertStatus* newStatus;
271 OcspResponse* ocspResponse;
272#else
273 CertStatus newStatus[1];
274 OcspResponse ocspResponse[1];
275#endif
276 int ret;
277 int validated = 0; /* ocsp validation flag */
278
279#ifdef WOLFSSL_SMALL_STACK
280 newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
281 DYNAMIC_TYPE_TMP_BUFFER);
282 ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
283 DYNAMIC_TYPE_TMP_BUFFER);
284
285 if (newStatus == NULL || ocspResponse == NULL) {
286 if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
287 if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
288
289 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
290 return MEMORY_E;
291 }
292#endif
293 XMEMSET(newStatus, 0, sizeof(CertStatus));
294
295 InitOcspResponse(ocspResponse, newStatus, response, responseSz);
296 ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
297 if (ret != 0) {
298 WOLFSSL_MSG("OcspResponseDecode failed");
299 goto end;
300 }
301
302 if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
303 WOLFSSL_MSG("OcspResponse status bad");
304 goto end;
305 }
306 if (ocspRequest != NULL) {
307 ret = CompareOcspReqResp(ocspRequest, ocspResponse);
308 if (ret != 0) {
309 goto end;
310 }
311 }
312
313 if (responseBuffer) {
314 responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap,
315 DYNAMIC_TYPE_TMP_BUFFER);
316
317 if (responseBuffer->buffer) {
318 responseBuffer->length = responseSz;
319 XMEMCPY(responseBuffer->buffer, response, responseSz);
320 }
321 }
322
323 ret = xstat2err(ocspResponse->status->status);
324 if (ret == 0) {
325 validated = 1;
326 }
327
328 if (wc_LockMutex(&ocsp->ocspLock) != 0) {
329 ret = BAD_MUTEX_E;
330 goto end;
331 }
332
333 if (status != NULL) {
334 if (status->rawOcspResponse) {
335 XFREE(status->rawOcspResponse, ocsp->cm->heap,
336 DYNAMIC_TYPE_OCSP_STATUS);
337 }
338
339 /* Replace existing certificate entry with updated */
340 XMEMCPY(status, newStatus, sizeof(CertStatus));
341 }
342 else {
343 /* Save new certificate entry */
344 status = (CertStatus*)XMALLOC(sizeof(CertStatus),
345 ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
346 if (status != NULL) {
347 XMEMCPY(status, newStatus, sizeof(CertStatus));
348 status->next = entry->status;
349 entry->status = status;
350 entry->totalStatus++;
351 }
352 }
353
354 if (status && responseBuffer && responseBuffer->buffer) {
355 status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
356 ocsp->cm->heap,
357 DYNAMIC_TYPE_OCSP_STATUS);
358
359 if (status->rawOcspResponse) {
360 status->rawOcspResponseSz = responseBuffer->length;
361 XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
362 responseBuffer->length);
363 }
364 }
365
366 wc_UnLockMutex(&ocsp->ocspLock);
367
368end:
369 if (ret == 0 && validated == 1) {
370 WOLFSSL_MSG("New OcspResponse validated");
371 } else if (ret != OCSP_CERT_REVOKED) {
372 ret = OCSP_LOOKUP_FAIL;
373 }
374
375#ifdef WOLFSSL_SMALL_STACK
376 XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
377 XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
378#endif
379 return ret;
380}
381
382/* 0 on success */
383int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
384 buffer* responseBuffer)
385{
386 OcspEntry* entry = NULL;
387 CertStatus* status = NULL;
388 byte* request = NULL;
389 int requestSz = 2048;
390 int responseSz = 0;
391 byte* response = NULL;
392 const char* url = NULL;
393 int urlSz = 0;
394 int ret = -1;
395 WOLFSSL* ssl;
396 void* ioCtx;
397
398 WOLFSSL_ENTER("CheckOcspRequest");
399
400 if (ocsp == NULL || ocspRequest == NULL)
401 return BAD_FUNC_ARG;
402
403 if (responseBuffer) {
404 responseBuffer->buffer = NULL;
405 responseBuffer->length = 0;
406 }
407
408 ret = GetOcspEntry(ocsp, ocspRequest, &entry);
409 if (ret != 0)
410 return ret;
411
412 ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
413 if (ret != OCSP_INVALID_STATUS)
414 return ret;
415
416 /* get SSL and IOCtx */
417 ssl = (WOLFSSL*)ocspRequest->ssl;
418 ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
419 ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
420
421#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
422 if (ocsp->statusCb != NULL && ssl != NULL) {
423 ret = ocsp->statusCb(ssl, ioCtx);
424 if (ret == 0) {
425 ret = wolfSSL_get_ocsp_response(ssl, &response);
426 ret = CheckResponse(ocsp, response, ret, responseBuffer, status,
427 entry, NULL);
428 if (response != NULL)
429 XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
430 return ret;
431 }
432 return OCSP_LOOKUP_FAIL;
433 }
434#endif
435
436 if (ocsp->cm->ocspUseOverrideURL) {
437 url = ocsp->cm->ocspOverrideURL;
438 if (url != NULL && url[0] != '\0')
439 urlSz = (int)XSTRLEN(url);
440 else
441 return OCSP_NEED_URL;
442 }
443 else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
444 url = (const char *)ocspRequest->url;
445 urlSz = ocspRequest->urlSz;
446 }
447 else {
448 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
449 return 0;
450 }
451
452 request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
453 if (request == NULL) {
454 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
455 return MEMORY_ERROR;
456 }
457
458 requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
459 if (requestSz > 0 && ocsp->cm->ocspIOCb) {
460 responseSz = ocsp->cm->ocspIOCb(ioCtx, url, urlSz,
461 request, requestSz, &response);
462 }
463 if (responseSz == WOLFSSL_CBIO_ERR_WANT_READ) {
464 ret = OCSP_WANT_READ;
465 }
466
467 XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
468
469 if (responseSz >= 0 && response) {
470 ret = CheckResponse(ocsp, response, responseSz, responseBuffer, status,
471 entry, ocspRequest);
472 }
473
474 if (response != NULL && ocsp->cm->ocspRespFreeCb)
475 ocsp->cm->ocspRespFreeCb(ioCtx, response);
476
477 WOLFSSL_LEAVE("CheckOcspRequest", ret);
478 return ret;
479}
480
481#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
482
483int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
484 WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
485 WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
486 WOLFSSL_ASN1_TIME** nextupd)
487{
488 if (bs == NULL || id == NULL)
489 return WOLFSSL_FAILURE;
490
491 /* Only supporting one certificate status in asn.c. */
492 if (CompareOcspReqResp(id, bs) != 0)
493 return WOLFSSL_FAILURE;
494
495 if (status != NULL)
496 *status = bs->status->status;
497 if (thisupd != NULL)
498 *thisupd = (WOLFSSL_ASN1_TIME*)bs->status->thisDateAsn;
499 if (nextupd != NULL)
500 *nextupd = (WOLFSSL_ASN1_TIME*)bs->status->nextDateAsn;
501
502 /* TODO: Not needed for Nginx. */
503 if (reason != NULL)
504 *reason = 0;
505 if (revtime != NULL)
506 *revtime = NULL;
507
508 return WOLFSSL_SUCCESS;
509}
510
511const char *wolfSSL_OCSP_cert_status_str(long s)
512{
513 switch (s) {
514 case CERT_GOOD:
515 return "good";
516 case CERT_REVOKED:
517 return "revoked";
518 case CERT_UNKNOWN:
519 return "unknown";
520 default:
521 return "(UNKNOWN)";
522 }
523}
524
525int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
526 WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
527{
528 (void)thisupd;
529 (void)nextupd;
530 (void)sec;
531 (void)maxsec;
532 /* Dates validated in DecodeSingleResponse. */
533 return WOLFSSL_SUCCESS;
534}
535
536void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
537{
538 FreeOcspRequest(certId);
539 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
540}
541
542WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
543 const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
544 const WOLFSSL_X509 *issuer)
545{
546 WOLFSSL_OCSP_CERTID* certId;
547 DecodedCert cert;
548 WOLFSSL_CERT_MANAGER* cm;
549 int ret;
550 DerBuffer* derCert = NULL;
551
552 (void)dgst;
553
554 cm = wolfSSL_CertManagerNew();
555 if (cm == NULL)
556 return NULL;
557
558 ret = AllocDer(&derCert, issuer->derCert->length,
559 issuer->derCert->type, NULL);
560 if (ret == 0) {
561 /* AddCA() frees the buffer. */
562 XMEMCPY(derCert->buffer, issuer->derCert->buffer,
563 issuer->derCert->length);
564 AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
565 }
566
567 certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
568 DYNAMIC_TYPE_OPENSSL);
569 if (certId != NULL) {
570 InitDecodedCert(&cert, subject->derCert->buffer,
571 subject->derCert->length, NULL);
572 if (ParseCertRelative(&cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
573 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
574 certId = NULL;
575 }
576 else {
577 ret = InitOcspRequest(certId, &cert, 0, NULL);
578 if (ret != 0) {
579 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
580 certId = NULL;
581 }
582 }
583 FreeDecodedCert(&cert);
584 }
585
586 wolfSSL_CertManagerFree(cm);
587
588 return certId;
589}
590
591void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
592{
593 wolfSSL_OCSP_RESPONSE_free(basicResponse);
594}
595
596/* Signature verified in DecodeBasicOcspResponse.
597 * But no store available to verify certificate. */
598int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
599 WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
600{
601 DecodedCert cert;
602 int ret = WOLFSSL_SUCCESS;
603
604 (void)certs;
605
606 if (flags & OCSP_NOVERIFY)
607 return WOLFSSL_SUCCESS;
608
609#ifdef OPENSSL_EXTRA
610 if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
611 return WOLFSSL_FAILURE;
612#endif
613
614 InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
615 if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
616 ret = WOLFSSL_FAILURE;
617 FreeDecodedCert(&cert);
618
619 return ret;
620}
621
622void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
623{
624 if (response->status != NULL)
625 XFREE(response->status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
626 if (response->source != NULL)
627 XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
628 XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
629}
630
631OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
632 OcspResponse** response)
633{
634 byte* data;
635 byte* p;
636 int len;
637 int dataAlloced = 0;
638 OcspResponse* ret = NULL;
639
640 if (bio == NULL)
641 return NULL;
642
643 if (bio->type == WOLFSSL_BIO_MEMORY) {
644 len = wolfSSL_BIO_get_mem_data(bio, &data);
645 if (len <= 0 || data == NULL) {
646 return NULL;
647 }
648 }
649#ifndef NO_FILESYSTEM
650 else if (bio->type == WOLFSSL_BIO_FILE) {
651 long i;
652 long l;
653
654 i = XFTELL(bio->file);
655 if (i < 0)
656 return NULL;
657 if(XFSEEK(bio->file, 0, SEEK_END) != 0)
658 return NULL;
659 l = XFTELL(bio->file);
660 if (l < 0)
661 return NULL;
662 if (XFSEEK(bio->file, i, SEEK_SET) != 0)
663 return NULL;
664
665 /* check calculated length */
666 if (l - i <= 0)
667 return NULL;
668
669 data = (byte*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER);
670 if (data == NULL)
671 return NULL;
672 dataAlloced = 1;
673
674 len = wolfSSL_BIO_read(bio, (char *)data, (int)l);
675 }
676#endif
677 else
678 return NULL;
679
680 if (len > 0) {
681 p = data;
682 ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p, len);
683 }
684
685 if (dataAlloced)
686 XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
687
688 return ret;
689}
690
691OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
692 const unsigned char** data, int len)
693{
694 OcspResponse *resp = NULL;
695 word32 idx = 0;
696 int length = 0;
697
698 if (data == NULL)
699 return NULL;
700
701 if (response != NULL)
702 resp = *response;
703 if (resp == NULL) {
704 resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
705 DYNAMIC_TYPE_OPENSSL);
706 if (resp == NULL)
707 return NULL;
708 XMEMSET(resp, 0, sizeof(OcspResponse));
709 }
710
711 resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
712 if (resp->source == NULL) {
713 XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
714 return NULL;
715 }
716 resp->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
717 DYNAMIC_TYPE_TMP_BUFFER);
718 if (resp->status == NULL) {
719 XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
720 XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
721 return NULL;
722 }
723
724 XMEMCPY(resp->source, *data, len);
725 resp->maxIdx = len;
726
727 if (OcspResponseDecode(resp, NULL, NULL, 1) != 0) {
728 wolfSSL_OCSP_RESPONSE_free(resp);
729 return NULL;
730 }
731
732 if (GetSequence(*data, &idx, &length, len) >= 0)
733 (*data) += idx + length;
734
735 return resp;
736}
737
738int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
739 unsigned char** data)
740{
741 if (data == NULL)
742 return response->maxIdx;
743
744 XMEMCPY(*data, response->source, response->maxIdx);
745 return response->maxIdx;
746}
747
748int wolfSSL_OCSP_response_status(OcspResponse *response)
749{
750 return response->responseStatus;
751}
752
753const char *wolfSSL_OCSP_response_status_str(long s)
754{
755 switch (s) {
756 case OCSP_SUCCESSFUL:
757 return "successful";
758 case OCSP_MALFORMED_REQUEST:
759 return "malformedrequest";
760 case OCSP_INTERNAL_ERROR:
761 return "internalerror";
762 case OCSP_TRY_LATER:
763 return "trylater";
764 case OCSP_SIG_REQUIRED:
765 return "sigrequired";
766 case OCSP_UNAUTHROIZED:
767 return "unauthorized";
768 default:
769 return "(UNKNOWN)";
770 }
771}
772
773WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
774{
775 WOLFSSL_OCSP_BASICRESP* bs;
776
777 bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL,
778 DYNAMIC_TYPE_OPENSSL);
779 if (bs == NULL)
780 return NULL;
781
782 XMEMCPY(bs, response, sizeof(OcspResponse));
783 bs->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
784 DYNAMIC_TYPE_TMP_BUFFER);
785 bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
786 if (bs->status == NULL || bs->source == NULL) {
787 if (bs->status) XFREE(bs->status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
788 if (bs->source) XFREE(bs->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
789 wolfSSL_OCSP_RESPONSE_free(bs);
790 bs = NULL;
791 }
792 else {
793 XMEMCPY(bs->status, response->status, sizeof(CertStatus));
794 XMEMCPY(bs->source, response->source, response->maxIdx);
795 }
796 return bs;
797}
798
799OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
800{
801 OcspRequest* request;
802
803 request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
804 DYNAMIC_TYPE_OPENSSL);
805 if (request != NULL)
806 XMEMSET(request, 0, sizeof(OcspRequest));
807
808 return request;
809}
810
811void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
812{
813 FreeOcspRequest(request);
814 XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL);
815}
816
817int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
818{
819 word32 size;
820
821 size = EncodeOcspRequest(request, NULL, 0);
822 if (size <= 0 || data == NULL)
823 return size;
824
825 return EncodeOcspRequest(request, *data, size);
826}
827
828WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
829 WOLFSSL_OCSP_CERTID *cid)
830{
831 if (req == NULL || cid == NULL)
832 return NULL;
833
834 FreeOcspRequest(req);
835 XMEMCPY(req, cid, sizeof(OcspRequest));
836
837 if (cid->serial != NULL) {
838 req->serial = (byte*)XMALLOC(cid->serialSz, NULL,
839 DYNAMIC_TYPE_OCSP_REQUEST);
840 req->url = (byte*)XMALLOC(cid->urlSz, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
841 if (req->serial == NULL || req->url == NULL) {
842 FreeOcspRequest(req);
843 return NULL;
844 }
845
846 XMEMCPY(req->serial, cid->serial, cid->serialSz);
847 XMEMCPY(req->url, cid->url, cid->urlSz);
848 }
849
850 wolfSSL_OCSP_REQUEST_free(cid);
851
852 return req;
853}
854
855#endif
856
857#else /* HAVE_OCSP */
858
859
860#ifdef _MSC_VER
861 /* 4206 warning for blank file */
862 #pragma warning(disable: 4206)
863#endif
864
865
866#endif /* HAVE_OCSP */
867#endif /* WOLFCRYPT_ONLY */
868
Note: See TracBrowser for help on using the repository browser.