source: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/src/ocsp.c@ 352

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

arm向けASP3版ECNLを追加

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