Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
ocsp.c
00001 /* ocsp.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 /* Name change compatibility layer no longer needs to be included here */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 #include <wolfssl/wolfcrypt/settings.h> 00030 00031 #ifndef WOLFCRYPT_ONLY 00032 #ifdef HAVE_OCSP 00033 00034 #include <wolfssl/error-ssl.h> 00035 #include <wolfssl/ocsp.h> 00036 #include <wolfssl/internal.h> 00037 00038 #ifdef NO_INLINE 00039 #include <wolfssl/wolfcrypt/misc.h> 00040 #else 00041 #define WOLFSSL_MISC_INCLUDED 00042 #include <wolfcrypt/src/misc.c> 00043 #endif 00044 00045 00046 int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm) 00047 { 00048 WOLFSSL_ENTER("InitOCSP"); 00049 00050 ForceZero(ocsp, sizeof(WOLFSSL_OCSP)); 00051 00052 if (wc_InitMutex(&ocsp->ocspLock) != 0) 00053 return BAD_MUTEX_E; 00054 00055 ocsp->cm = cm; 00056 00057 return 0; 00058 } 00059 00060 00061 static int InitOcspEntry(OcspEntry* entry, OcspRequest* request) 00062 { 00063 WOLFSSL_ENTER("InitOcspEntry"); 00064 00065 ForceZero(entry, sizeof(OcspEntry)); 00066 00067 XMEMCPY(entry->issuerHash, request->issuerHash, OCSP_DIGEST_SIZE); 00068 XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE); 00069 00070 return 0; 00071 } 00072 00073 00074 static void FreeOcspEntry(OcspEntry* entry, void* heap) 00075 { 00076 CertStatus *status, *next; 00077 00078 WOLFSSL_ENTER("FreeOcspEntry"); 00079 00080 for (status = entry->status; status; status = next) { 00081 next = status->next; 00082 00083 if (status->rawOcspResponse) 00084 XFREE(status->rawOcspResponse, heap, DYNAMIC_TYPE_OCSP_STATUS); 00085 00086 XFREE(status, heap, DYNAMIC_TYPE_OCSP_STATUS); 00087 } 00088 00089 (void)heap; 00090 } 00091 00092 00093 void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic) 00094 { 00095 OcspEntry *entry, *next; 00096 00097 WOLFSSL_ENTER("FreeOCSP"); 00098 00099 for (entry = ocsp->ocspList; entry; entry = next) { 00100 next = entry->next; 00101 FreeOcspEntry(entry, ocsp->cm->heap); 00102 XFREE(entry, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY); 00103 } 00104 00105 wc_FreeMutex(&ocsp->ocspLock); 00106 00107 if (dynamic) 00108 XFREE(ocsp, ocsp->cm->heap, DYNAMIC_TYPE_OCSP); 00109 00110 } 00111 00112 00113 static int xstat2err(int st) 00114 { 00115 switch (st) { 00116 case CERT_GOOD: 00117 return 0; 00118 case CERT_REVOKED: 00119 return OCSP_CERT_REVOKED; 00120 default: 00121 return OCSP_CERT_UNKNOWN; 00122 } 00123 } 00124 00125 00126 int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer) 00127 { 00128 int ret = OCSP_LOOKUP_FAIL; 00129 00130 #ifdef WOLFSSL_SMALL_STACK 00131 OcspRequest* ocspRequest; 00132 #else 00133 OcspRequest ocspRequest[1]; 00134 #endif 00135 00136 WOLFSSL_ENTER("CheckCertOCSP"); 00137 00138 00139 #ifdef WOLFSSL_SMALL_STACK 00140 ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, 00141 DYNAMIC_TYPE_TMP_BUFFER); 00142 if (ocspRequest == NULL) { 00143 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00144 return MEMORY_E; 00145 } 00146 #endif 00147 00148 if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce, 00149 ocsp->cm->heap) == 0) { 00150 ret = CheckOcspRequest(ocsp, ocspRequest, responseBuffer); 00151 00152 FreeOcspRequest(ocspRequest); 00153 } 00154 00155 #ifdef WOLFSSL_SMALL_STACK 00156 XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00157 #endif 00158 00159 WOLFSSL_LEAVE("CheckCertOCSP", ret); 00160 return ret; 00161 } 00162 00163 static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request, 00164 OcspEntry** entry) 00165 { 00166 WOLFSSL_ENTER("GetOcspEntry"); 00167 00168 *entry = NULL; 00169 00170 if (wc_LockMutex(&ocsp->ocspLock) != 0) { 00171 WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); 00172 return BAD_MUTEX_E; 00173 } 00174 00175 for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next) 00176 if (XMEMCMP((*entry)->issuerHash, request->issuerHash, 00177 OCSP_DIGEST_SIZE) == 0 00178 && XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash, 00179 OCSP_DIGEST_SIZE) == 0) 00180 break; 00181 00182 if (*entry == NULL) { 00183 *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), 00184 ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY); 00185 if (*entry) { 00186 InitOcspEntry(*entry, request); 00187 (*entry)->next = ocsp->ocspList; 00188 ocsp->ocspList = *entry; 00189 } 00190 } 00191 00192 wc_UnLockMutex(&ocsp->ocspLock); 00193 00194 return *entry ? 0 : MEMORY_ERROR; 00195 } 00196 00197 00198 static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, 00199 OcspEntry* entry, CertStatus** status, buffer* responseBuffer) 00200 { 00201 int ret = OCSP_INVALID_STATUS; 00202 00203 WOLFSSL_ENTER("GetOcspStatus"); 00204 00205 *status = NULL; 00206 00207 if (wc_LockMutex(&ocsp->ocspLock) != 0) { 00208 WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); 00209 return BAD_MUTEX_E; 00210 } 00211 00212 for (*status = entry->status; *status; *status = (*status)->next) 00213 if ((*status)->serialSz == request->serialSz 00214 && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz)) 00215 break; 00216 00217 if (responseBuffer && *status && !(*status)->rawOcspResponse) { 00218 /* force fetching again */ 00219 ret = OCSP_INVALID_STATUS; 00220 } 00221 else if (*status) { 00222 #ifndef NO_ASN_TIME 00223 if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE) 00224 && ((*status)->nextDate[0] != 0) 00225 && ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER)) 00226 #endif 00227 { 00228 ret = xstat2err((*status)->status); 00229 00230 if (responseBuffer) { 00231 responseBuffer->buffer = (byte*)XMALLOC( 00232 (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00233 00234 if (responseBuffer->buffer) { 00235 responseBuffer->length = (*status)->rawOcspResponseSz; 00236 XMEMCPY(responseBuffer->buffer, 00237 (*status)->rawOcspResponse, 00238 (*status)->rawOcspResponseSz); 00239 } 00240 } 00241 } 00242 } 00243 00244 wc_UnLockMutex(&ocsp->ocspLock); 00245 00246 return ret; 00247 } 00248 00249 /* Check that the response for validity. Store result in status. 00250 * 00251 * ocsp Context object for OCSP status. 00252 * response OCSP response message data. 00253 * responseSz Length of OCSP response message data. 00254 * reponseBuffer Buffer object to return the response with. 00255 * status The certificate status object. 00256 * entry The OCSP entry for this certificate. 00257 * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise. 00258 */ 00259 static int CheckResponse(WOLFSSL_OCSP* ocsp, byte* response, int responseSz, 00260 buffer* responseBuffer, CertStatus* status, 00261 OcspEntry* entry, OcspRequest* ocspRequest) 00262 { 00263 #ifdef WOLFSSL_SMALL_STACK 00264 CertStatus* newStatus; 00265 OcspResponse* ocspResponse; 00266 #else 00267 CertStatus newStatus[1]; 00268 OcspResponse ocspResponse[1]; 00269 #endif 00270 int ret; 00271 int validated = 0; /* ocsp validation flag */ 00272 00273 #ifdef WOLFSSL_SMALL_STACK 00274 newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, 00275 DYNAMIC_TYPE_TMP_BUFFER); 00276 ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, 00277 DYNAMIC_TYPE_TMP_BUFFER); 00278 00279 if (newStatus == NULL || ocspResponse == NULL) { 00280 if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00281 if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00282 00283 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00284 return MEMORY_E; 00285 } 00286 #endif 00287 XMEMSET(newStatus, 0, sizeof(CertStatus)); 00288 00289 InitOcspResponse(ocspResponse, newStatus, response, responseSz); 00290 ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0); 00291 if (ret != 0) { 00292 WOLFSSL_MSG("OcspResponseDecode failed"); 00293 goto end; 00294 } 00295 00296 if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) { 00297 WOLFSSL_MSG("OcspResponse status bad"); 00298 goto end; 00299 } 00300 if (ocspRequest != NULL) { 00301 ret = CompareOcspReqResp(ocspRequest, ocspResponse); 00302 if (ret != 0) { 00303 goto end; 00304 } 00305 } 00306 00307 if (responseBuffer) { 00308 responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap, 00309 DYNAMIC_TYPE_TMP_BUFFER); 00310 00311 if (responseBuffer->buffer) { 00312 responseBuffer->length = responseSz; 00313 XMEMCPY(responseBuffer->buffer, response, responseSz); 00314 } 00315 } 00316 00317 ret = xstat2err(ocspResponse->status->status); 00318 if (ret == 0) { 00319 validated = 1; 00320 } 00321 00322 if (wc_LockMutex(&ocsp->ocspLock) != 0) { 00323 ret = BAD_MUTEX_E; 00324 goto end; 00325 } 00326 00327 if (status != NULL) { 00328 if (status->rawOcspResponse) { 00329 XFREE(status->rawOcspResponse, ocsp->cm->heap, 00330 DYNAMIC_TYPE_OCSP_STATUS); 00331 } 00332 00333 /* Replace existing certificate entry with updated */ 00334 XMEMCPY(status, newStatus, sizeof(CertStatus)); 00335 } 00336 else { 00337 /* Save new certificate entry */ 00338 status = (CertStatus*)XMALLOC(sizeof(CertStatus), 00339 ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS); 00340 if (status != NULL) { 00341 XMEMCPY(status, newStatus, sizeof(CertStatus)); 00342 status->next = entry->status; 00343 entry->status = status; 00344 entry->totalStatus++; 00345 } 00346 } 00347 00348 if (status && responseBuffer && responseBuffer->buffer) { 00349 status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length, 00350 ocsp->cm->heap, 00351 DYNAMIC_TYPE_OCSP_STATUS); 00352 00353 if (status->rawOcspResponse) { 00354 status->rawOcspResponseSz = responseBuffer->length; 00355 XMEMCPY(status->rawOcspResponse, responseBuffer->buffer, 00356 responseBuffer->length); 00357 } 00358 } 00359 00360 wc_UnLockMutex(&ocsp->ocspLock); 00361 00362 end: 00363 if (ret == 0 && validated == 1) { 00364 WOLFSSL_MSG("New OcspResponse validated"); 00365 } else if (ret != OCSP_CERT_REVOKED) { 00366 ret = OCSP_LOOKUP_FAIL; 00367 } 00368 00369 #ifdef WOLFSSL_SMALL_STACK 00370 XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00371 XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00372 #endif 00373 return ret; 00374 } 00375 00376 /* 0 on success */ 00377 int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, 00378 buffer* responseBuffer) 00379 { 00380 OcspEntry* entry = NULL; 00381 CertStatus* status = NULL; 00382 byte* request = NULL; 00383 int requestSz = 2048; 00384 int responseSz = 0; 00385 byte* response = NULL; 00386 const char* url = NULL; 00387 int urlSz = 0; 00388 int ret = -1; 00389 00390 WOLFSSL_ENTER("CheckOcspRequest"); 00391 00392 if (responseBuffer) { 00393 responseBuffer->buffer = NULL; 00394 responseBuffer->length = 0; 00395 } 00396 00397 ret = GetOcspEntry(ocsp, ocspRequest, &entry); 00398 if (ret != 0) 00399 return ret; 00400 00401 ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer); 00402 if (ret != OCSP_INVALID_STATUS) 00403 return ret; 00404 00405 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) 00406 if (ocsp->statusCb != NULL && ocspRequest->ssl != NULL) { 00407 ret = ocsp->statusCb((WOLFSSL*)ocspRequest->ssl, ocsp->cm->ocspIOCtx); 00408 if (ret == 0) { 00409 ret = wolfSSL_get_ocsp_response((WOLFSSL*)ocspRequest->ssl, 00410 &response); 00411 ret = CheckResponse(ocsp, response, ret, responseBuffer, status, 00412 entry, NULL); 00413 if (response != NULL) 00414 XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL); 00415 return ret; 00416 } 00417 return OCSP_LOOKUP_FAIL; 00418 } 00419 #endif 00420 00421 if (ocsp->cm->ocspUseOverrideURL) { 00422 url = ocsp->cm->ocspOverrideURL; 00423 if (url != NULL && url[0] != '\0') 00424 urlSz = (int)XSTRLEN(url); 00425 else 00426 return OCSP_NEED_URL; 00427 } 00428 else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) { 00429 url = (const char *)ocspRequest->url; 00430 urlSz = ocspRequest->urlSz; 00431 } 00432 else { 00433 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ 00434 return 0; 00435 } 00436 00437 request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP); 00438 if (request == NULL) { 00439 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00440 return MEMORY_ERROR; 00441 } 00442 00443 requestSz = EncodeOcspRequest(ocspRequest, request, requestSz); 00444 if (requestSz > 0 && ocsp->cm->ocspIOCb) { 00445 responseSz = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, 00446 request, requestSz, &response); 00447 } 00448 00449 XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP); 00450 00451 if (responseSz >= 0 && response) { 00452 ret = CheckResponse(ocsp, response, responseSz, responseBuffer, status, 00453 entry, ocspRequest); 00454 } 00455 00456 if (response != NULL && ocsp->cm->ocspRespFreeCb) 00457 ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response); 00458 00459 WOLFSSL_LEAVE("CheckOcspRequest", ret); 00460 return ret; 00461 } 00462 00463 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) 00464 00465 int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, 00466 WOLFSSL_OCSP_CERTID* id, int* status, int* reason, 00467 WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd, 00468 WOLFSSL_ASN1_TIME** nextupd) 00469 { 00470 if (bs == NULL || id == NULL) 00471 return SSL_FAILURE; 00472 00473 /* Only supporting one certificate status in asn.c. */ 00474 if (CompareOcspReqResp(id, bs) != 0) 00475 return SSL_FAILURE; 00476 00477 if (status != NULL) 00478 *status = bs->status->status; 00479 if (thisupd != NULL) 00480 *thisupd = (WOLFSSL_ASN1_TIME*)bs->status->thisDateAsn; 00481 if (nextupd != NULL) 00482 *nextupd = (WOLFSSL_ASN1_TIME*)bs->status->nextDateAsn; 00483 00484 /* TODO: Not needed for Nginx. */ 00485 if (reason != NULL) 00486 *reason = 0; 00487 if (revtime != NULL) 00488 *revtime = NULL; 00489 00490 return SSL_SUCCESS; 00491 } 00492 00493 const char *wolfSSL_OCSP_cert_status_str(long s) 00494 { 00495 switch (s) { 00496 case CERT_GOOD: 00497 return "good"; 00498 case CERT_REVOKED: 00499 return "revoked"; 00500 case CERT_UNKNOWN: 00501 return "unknown"; 00502 default: 00503 return "(UNKNOWN)"; 00504 } 00505 } 00506 00507 int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd, 00508 WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec) 00509 { 00510 (void)thisupd; 00511 (void)nextupd; 00512 (void)sec; 00513 (void)maxsec; 00514 /* Dates validated in DecodeSingleResponse. */ 00515 return SSL_SUCCESS; 00516 } 00517 00518 void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId) 00519 { 00520 FreeOcspRequest(certId); 00521 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL); 00522 } 00523 00524 WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id( 00525 const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject, 00526 const WOLFSSL_X509 *issuer) 00527 { 00528 WOLFSSL_OCSP_CERTID* certId; 00529 DecodedCert cert; 00530 WOLFSSL_CERT_MANAGER* cm; 00531 int ret; 00532 DerBuffer* derCert = NULL; 00533 00534 (void)dgst; 00535 00536 cm = wolfSSL_CertManagerNew(); 00537 if (cm == NULL) 00538 return NULL; 00539 00540 ret = AllocDer(&derCert, issuer->derCert->length, 00541 issuer->derCert->type, NULL); 00542 if (ret == 0) { 00543 /* AddCA() frees the buffer. */ 00544 XMEMCPY(derCert->buffer, issuer->derCert->buffer, 00545 issuer->derCert->length); 00546 AddCA(cm, &derCert, WOLFSSL_USER_CA, 1); 00547 } 00548 00549 certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL, 00550 DYNAMIC_TYPE_OPENSSL); 00551 if (certId != NULL) { 00552 InitDecodedCert(&cert, subject->derCert->buffer, 00553 subject->derCert->length, NULL); 00554 if (ParseCertRelative(&cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) { 00555 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL); 00556 certId = NULL; 00557 } 00558 else { 00559 ret = InitOcspRequest(certId, &cert, 0, NULL); 00560 if (ret != 0) { 00561 XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL); 00562 certId = NULL; 00563 } 00564 } 00565 FreeDecodedCert(&cert); 00566 } 00567 00568 wolfSSL_CertManagerFree(cm); 00569 00570 return certId; 00571 } 00572 00573 void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse) 00574 { 00575 wolfSSL_OCSP_RESPONSE_free(basicResponse); 00576 } 00577 00578 /* Signature verified in DecodeBasicOcspResponse. 00579 * But no store available to verify certificate. */ 00580 int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs, 00581 STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags) 00582 { 00583 DecodedCert cert; 00584 int ret = SSL_SUCCESS; 00585 00586 (void)certs; 00587 00588 if (flags & OCSP_NOVERIFY) 00589 return SSL_SUCCESS; 00590 00591 InitDecodedCert(&cert, bs->cert, bs->certSz, NULL); 00592 if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0) 00593 ret = SSL_FAILURE; 00594 FreeDecodedCert(&cert); 00595 00596 return ret; 00597 } 00598 00599 void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response) 00600 { 00601 if (response->status != NULL) 00602 XFREE(response->status, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00603 if (response->source != NULL) 00604 XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00605 XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL); 00606 } 00607 00608 OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio, 00609 OcspResponse** response) 00610 { 00611 byte* data; 00612 byte* p; 00613 int len; 00614 int dataAlloced = 0; 00615 OcspResponse* ret = NULL; 00616 00617 if (bio == NULL) 00618 return NULL; 00619 00620 if (bio->type == BIO_MEMORY) { 00621 len = wolfSSL_BIO_get_mem_data(bio, &data); 00622 if (len <= 0 || data == NULL) { 00623 return NULL; 00624 } 00625 } 00626 else if (bio->type == BIO_FILE) { 00627 long i; 00628 long l; 00629 00630 i = XFTELL(bio->file); 00631 if (i < 0) 00632 return NULL; 00633 XFSEEK(bio->file, 0, SEEK_END); 00634 l = XFTELL(bio->file); 00635 if (l < 0) 00636 return NULL; 00637 XFSEEK(bio->file, i, SEEK_SET); 00638 00639 /* check calulated length */ 00640 if (l - i <= 0) 00641 return NULL; 00642 00643 data = (byte*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER); 00644 if (data == NULL) 00645 return NULL; 00646 dataAlloced = 1; 00647 00648 len = wolfSSL_BIO_read(bio, (char *)data, (int)l); 00649 } 00650 else 00651 return NULL; 00652 00653 if (len > 0) { 00654 p = data; 00655 ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p, len); 00656 } 00657 00658 if (dataAlloced) 00659 XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER); 00660 00661 return ret; 00662 } 00663 00664 OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response, 00665 const unsigned char** data, int len) 00666 { 00667 OcspResponse *resp = NULL; 00668 word32 idx = 0; 00669 int length = 0; 00670 00671 if (data == NULL) 00672 return NULL; 00673 00674 if (response != NULL) 00675 resp = *response; 00676 if (resp == NULL) { 00677 resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, 00678 DYNAMIC_TYPE_OPENSSL); 00679 if (resp == NULL) 00680 return NULL; 00681 XMEMSET(resp, 0, sizeof(OcspResponse)); 00682 } 00683 00684 resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00685 if (resp->source == NULL) { 00686 XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL); 00687 return NULL; 00688 } 00689 resp->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, 00690 DYNAMIC_TYPE_TMP_BUFFER); 00691 if (resp->status == NULL) { 00692 XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00693 XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL); 00694 return NULL; 00695 } 00696 00697 XMEMCPY(resp->source, *data, len); 00698 resp->maxIdx = len; 00699 00700 if (OcspResponseDecode(resp, NULL, NULL, 1) != 0) { 00701 wolfSSL_OCSP_RESPONSE_free(resp); 00702 return NULL; 00703 } 00704 00705 if (GetSequence(*data, &idx, &length, len) >= 0) 00706 (*data) += idx + length; 00707 00708 return resp; 00709 } 00710 00711 int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response, 00712 unsigned char** data) 00713 { 00714 if (data == NULL) 00715 return response->maxIdx; 00716 00717 XMEMCPY(*data, response->source, response->maxIdx); 00718 return response->maxIdx; 00719 } 00720 00721 int wolfSSL_OCSP_response_status(OcspResponse *response) 00722 { 00723 return response->responseStatus; 00724 } 00725 00726 const char *wolfSSL_OCSP_response_status_str(long s) 00727 { 00728 switch (s) { 00729 case OCSP_SUCCESSFUL: 00730 return "successful"; 00731 case OCSP_MALFORMED_REQUEST: 00732 return "malformedrequest"; 00733 case OCSP_INTERNAL_ERROR: 00734 return "internalerror"; 00735 case OCSP_TRY_LATER: 00736 return "trylater"; 00737 case OCSP_SIG_REQUIRED: 00738 return "sigrequired"; 00739 case OCSP_UNAUTHROIZED: 00740 return "unauthorized"; 00741 default: 00742 return "(UNKNOWN)"; 00743 } 00744 } 00745 00746 WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response) 00747 { 00748 WOLFSSL_OCSP_BASICRESP* bs; 00749 00750 bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL, 00751 DYNAMIC_TYPE_OPENSSL); 00752 if (bs == NULL) 00753 return NULL; 00754 00755 XMEMCPY(bs, response, sizeof(OcspResponse)); 00756 bs->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, 00757 DYNAMIC_TYPE_TMP_BUFFER); 00758 bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00759 if (bs->status == NULL || bs->source == NULL) { 00760 if (bs->status) XFREE(bs->status, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00761 if (bs->source) XFREE(bs->source, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00762 wolfSSL_OCSP_RESPONSE_free(bs); 00763 bs = NULL; 00764 } 00765 else { 00766 XMEMCPY(bs->status, response->status, sizeof(CertStatus)); 00767 XMEMCPY(bs->source, response->source, response->maxIdx); 00768 } 00769 return bs; 00770 } 00771 00772 OcspRequest* wolfSSL_OCSP_REQUEST_new(void) 00773 { 00774 OcspRequest* request; 00775 00776 request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, 00777 DYNAMIC_TYPE_OPENSSL); 00778 if (request != NULL) 00779 XMEMSET(request, 0, sizeof(OcspRequest)); 00780 00781 return request; 00782 } 00783 00784 void wolfSSL_OCSP_REQUEST_free(OcspRequest* request) 00785 { 00786 FreeOcspRequest(request); 00787 XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL); 00788 } 00789 00790 int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data) 00791 { 00792 word32 size; 00793 00794 size = EncodeOcspRequest(request, NULL, 0); 00795 if (size <= 0 || data == NULL) 00796 return size; 00797 00798 return EncodeOcspRequest(request, *data, size); 00799 } 00800 00801 WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req, 00802 WOLFSSL_OCSP_CERTID *cid) 00803 { 00804 if (req == NULL || cid == NULL) 00805 return NULL; 00806 00807 FreeOcspRequest(req); 00808 XMEMCPY(req, cid, sizeof(OcspRequest)); 00809 00810 if (cid->serial != NULL) { 00811 req->serial = (byte*)XMALLOC(cid->serialSz, NULL, 00812 DYNAMIC_TYPE_OCSP_REQUEST); 00813 req->url = (byte*)XMALLOC(cid->urlSz, NULL, DYNAMIC_TYPE_OCSP_REQUEST); 00814 if (req->serial == NULL || req->url == NULL) { 00815 FreeOcspRequest(req); 00816 return NULL; 00817 } 00818 00819 XMEMCPY(req->serial, cid->serial, cid->serialSz); 00820 XMEMCPY(req->url, cid->url, cid->urlSz); 00821 } 00822 00823 wolfSSL_OCSP_REQUEST_free(cid); 00824 00825 return req; 00826 } 00827 00828 #endif 00829 00830 #else /* HAVE_OCSP */ 00831 00832 00833 #ifdef _MSC_VER 00834 /* 4206 warning for blank file */ 00835 #pragma warning(disable: 4206) 00836 #endif 00837 00838 00839 #endif /* HAVE_OCSP */ 00840 #endif /* WOLFCRYPT_ONLY */ 00841 00842
Generated on Tue Jul 12 2022 23:30:58 by
1.7.2
