12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577 |
- /* ocsp.c
- *
- * Copyright (C) 2006-2023 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- /* Name change compatibility layer no longer needs to be included here */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <wolfssl/wolfcrypt/settings.h>
- /*
- * WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK:
- * Disable looking for an authorized responder in the verification path of
- * the issuer. This will make the authorized responder only look at the
- * OCSP response signer and direct issuer.
- */
- #ifndef WOLFCRYPT_ONLY
- #ifdef HAVE_OCSP
- #include <wolfssl/error-ssl.h>
- #include <wolfssl/ocsp.h>
- #include <wolfssl/internal.h>
- #ifdef NO_INLINE
- #include <wolfssl/wolfcrypt/misc.h>
- #else
- #define WOLFSSL_MISC_INCLUDED
- #include <wolfcrypt/src/misc.c>
- #endif
- int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
- {
- WOLFSSL_ENTER("InitOCSP");
- ForceZero(ocsp, sizeof(WOLFSSL_OCSP));
- if (wc_InitMutex(&ocsp->ocspLock) != 0)
- return BAD_MUTEX_E;
- ocsp->cm = cm;
- return 0;
- }
- static int InitOcspEntry(OcspEntry* entry, OcspRequest* request)
- {
- WOLFSSL_ENTER("InitOcspEntry");
- ForceZero(entry, sizeof(OcspEntry));
- XMEMCPY(entry->issuerHash, request->issuerHash, OCSP_DIGEST_SIZE);
- XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE);
- return 0;
- }
- static void FreeOcspEntry(OcspEntry* entry, void* heap)
- {
- CertStatus *status, *next;
- if (entry == NULL || !entry->ownStatus)
- return;
- WOLFSSL_ENTER("FreeOcspEntry");
- for (status = entry->status; status; status = next) {
- next = status->next;
- if (status->rawOcspResponse)
- XFREE(status->rawOcspResponse, heap, DYNAMIC_TYPE_OCSP_STATUS);
- #ifdef OPENSSL_EXTRA
- if (status->serialInt) {
- if (status->serialInt->isDynamic) {
- XFREE(status->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- XFREE(status->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- status->serialInt = NULL;
- #endif
- XFREE(status, heap, DYNAMIC_TYPE_OCSP_STATUS);
- }
- (void)heap;
- }
- void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
- {
- OcspEntry *entry, *next;
- WOLFSSL_ENTER("FreeOCSP");
- for (entry = ocsp->ocspList; entry; entry = next) {
- next = entry->next;
- FreeOcspEntry(entry, ocsp->cm->heap);
- XFREE(entry, ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
- }
- wc_FreeMutex(&ocsp->ocspLock);
- if (dynamic)
- XFREE(ocsp, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
- }
- static int xstat2err(int st)
- {
- switch (st) {
- case CERT_GOOD:
- return 0;
- case CERT_REVOKED:
- return OCSP_CERT_REVOKED;
- default:
- return OCSP_CERT_UNKNOWN;
- }
- }
- int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, WOLFSSL* ssl)
- {
- int ret = OCSP_LOOKUP_FAIL;
- #ifdef WOLFSSL_SMALL_STACK
- OcspRequest* ocspRequest;
- #else
- OcspRequest ocspRequest[1];
- #endif
- WOLFSSL_ENTER("CheckCertOCSP");
- #ifdef WOLFSSL_SMALL_STACK
- ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
- DYNAMIC_TYPE_TMP_BUFFER);
- if (ocspRequest == NULL) {
- WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
- return MEMORY_E;
- }
- #endif
- if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
- ocsp->cm->heap) == 0) {
- ocspRequest->ssl = ssl;
- ret = CheckOcspRequest(ocsp, ocspRequest, NULL, NULL);
- FreeOcspRequest(ocspRequest);
- }
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- #endif
- WOLFSSL_LEAVE("CheckCertOCSP", ret);
- return ret;
- }
- int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
- {
- return CheckCertOCSP_ex(ocsp, cert, NULL);
- }
- static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
- OcspEntry** entry)
- {
- WOLFSSL_ENTER("GetOcspEntry");
- *entry = NULL;
- if (wc_LockMutex(&ocsp->ocspLock) != 0) {
- WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
- return BAD_MUTEX_E;
- }
- for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next)
- if (XMEMCMP((*entry)->issuerHash, request->issuerHash,
- OCSP_DIGEST_SIZE) == 0
- && XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash,
- OCSP_DIGEST_SIZE) == 0)
- break;
- if (*entry == NULL) {
- *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry),
- ocsp->cm->heap, DYNAMIC_TYPE_OCSP_ENTRY);
- if (*entry) {
- InitOcspEntry(*entry, request);
- (*entry)->next = ocsp->ocspList;
- ocsp->ocspList = *entry;
- }
- }
- wc_UnLockMutex(&ocsp->ocspLock);
- return *entry ? 0 : MEMORY_ERROR;
- }
- /* Mallocs responseBuffer->buffer and is up to caller to free on success
- *
- * Returns OCSP status
- */
- static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
- OcspEntry* entry, CertStatus** status, buffer* responseBuffer,
- void* heap)
- {
- int ret = OCSP_INVALID_STATUS;
- WOLFSSL_ENTER("GetOcspStatus");
- (void)heap;
- *status = NULL;
- if (wc_LockMutex(&ocsp->ocspLock) != 0) {
- WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
- return BAD_MUTEX_E;
- }
- for (*status = entry->status; *status; *status = (*status)->next)
- if ((*status)->serialSz == request->serialSz
- && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
- break;
- if (responseBuffer && *status && !(*status)->rawOcspResponse) {
- /* force fetching again */
- ret = OCSP_INVALID_STATUS;
- }
- else if (*status) {
- #ifndef NO_ASN_TIME
- if (XVALIDATE_DATE((*status)->thisDate,
- (*status)->thisDateFormat, BEFORE)
- && ((*status)->nextDate[0] != 0)
- && XVALIDATE_DATE((*status)->nextDate,
- (*status)->nextDateFormat, AFTER))
- #endif
- {
- ret = xstat2err((*status)->status);
- if (responseBuffer) {
- responseBuffer->buffer = (byte*)XMALLOC(
- (*status)->rawOcspResponseSz, heap,
- DYNAMIC_TYPE_TMP_BUFFER);
- if (responseBuffer->buffer) {
- responseBuffer->length = (*status)->rawOcspResponseSz;
- XMEMCPY(responseBuffer->buffer,
- (*status)->rawOcspResponse,
- (*status)->rawOcspResponseSz);
- }
- }
- }
- }
- wc_UnLockMutex(&ocsp->ocspLock);
- return ret;
- }
- /* Check that the response for validity. Store result in status.
- *
- * ocsp Context object for OCSP status.
- * response OCSP response message data.
- * responseSz Length of OCSP response message data.
- * reponseBuffer Buffer object to return the response with.
- * status The certificate status object.
- * entry The OCSP entry for this certificate.
- * ocspRequest Request corresponding to response.
- * heap Heap hint used for responseBuffer
- * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
- */
- int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
- WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
- OcspEntry *entry, OcspRequest *ocspRequest, void* heap)
- {
- #ifdef WOLFSSL_SMALL_STACK
- CertStatus* newStatus;
- OcspEntry* newSingle;
- OcspResponse* ocspResponse;
- #else
- CertStatus newStatus[1];
- OcspEntry newSingle[1];
- OcspResponse ocspResponse[1];
- #endif
- int ret;
- int validated = 0; /* ocsp validation flag */
- (void)heap;
- #ifdef WOLFSSL_SMALL_STACK
- newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
- DYNAMIC_TYPE_OCSP_STATUS);
- newSingle = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
- DYNAMIC_TYPE_OCSP_ENTRY);
- ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
- DYNAMIC_TYPE_OCSP_REQUEST);
- if (newStatus == NULL || newSingle == NULL || ocspResponse == NULL) {
- if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_OCSP_STATUS);
- if (newSingle) XFREE(newSingle, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
- if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
- return MEMORY_E;
- }
- #endif
- InitOcspResponse(ocspResponse, newSingle, newStatus, response, responseSz,
- ocsp->cm->heap);
- ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
- if (ret != 0) {
- ocsp->error = ret;
- WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
- goto end;
- }
- if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
- WOLFSSL_MSG("OcspResponse status bad");
- goto end;
- }
- if (ocspRequest != NULL) {
- /* Has the chance to bubble up response changing ocspResponse->single to
- no longer be pointing at newSingle */
- ret = CompareOcspReqResp(ocspRequest, ocspResponse);
- if (ret != 0) {
- goto end;
- }
- }
- if (responseBuffer) {
- responseBuffer->buffer = (byte*)XMALLOC(responseSz, heap,
- DYNAMIC_TYPE_TMP_BUFFER);
- if (responseBuffer->buffer) {
- responseBuffer->length = responseSz;
- XMEMCPY(responseBuffer->buffer, response, responseSz);
- }
- }
- ret = xstat2err(ocspResponse->single->status->status);
- if (ret == 0) {
- validated = 1;
- }
- if (wc_LockMutex(&ocsp->ocspLock) != 0) {
- ret = BAD_MUTEX_E;
- goto end;
- }
- if (status != NULL) {
- if (status->rawOcspResponse) {
- XFREE(status->rawOcspResponse, ocsp->cm->heap,
- DYNAMIC_TYPE_OCSP_STATUS);
- }
- /* Replace existing certificate entry with updated */
- ocspResponse->single->status->next = status->next;
- XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus));
- }
- else {
- /* Save new certificate entry */
- status = (CertStatus*)XMALLOC(sizeof(CertStatus),
- ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
- if (status != NULL) {
- XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus));
- status->next = entry->status;
- entry->status = status;
- entry->ownStatus = 1;
- entry->totalStatus++;
- }
- }
- if (status && responseBuffer && responseBuffer->buffer) {
- status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
- ocsp->cm->heap,
- DYNAMIC_TYPE_OCSP_STATUS);
- if (status->rawOcspResponse) {
- status->rawOcspResponseSz = responseBuffer->length;
- XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
- responseBuffer->length);
- }
- }
- wc_UnLockMutex(&ocsp->ocspLock);
- end:
- if (ret == 0 && validated == 1) {
- WOLFSSL_MSG("New OcspResponse validated");
- } else if ((ret == ocsp->error) && (ocspResponse->single->status->status == CERT_UNKNOWN)) {
- WOLFSSL_MSG("OCSP unknown");
- ret = OCSP_CERT_UNKNOWN;
- } else if (ret != OCSP_CERT_REVOKED) {
- WOLFSSL_MSG("OCSP lookup failure");
- ret = OCSP_LOOKUP_FAIL;
- }
- FreeOcspResponse(ocspResponse);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(newStatus, NULL, DYNAMIC_TYPE_OCSP_STATUS);
- XFREE(newSingle, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
- XFREE(ocspResponse, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- #endif
- return ret;
- }
- /* 0 on success */
- /* allow user to override the maximum request size at build-time */
- #ifndef OCSP_MAX_REQUEST_SZ
- #define OCSP_MAX_REQUEST_SZ 2048
- #endif
- int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
- buffer* responseBuffer, void* heap)
- {
- OcspEntry* entry = NULL;
- CertStatus* status = NULL;
- byte* request = NULL;
- int requestSz = OCSP_MAX_REQUEST_SZ;
- int responseSz = 0;
- byte* response = NULL;
- const char* url = NULL;
- int urlSz = 0;
- int ret = -1;
- WOLFSSL* ssl;
- void* ioCtx;
- WOLFSSL_ENTER("CheckOcspRequest");
- if (ocsp == NULL || ocspRequest == NULL)
- return BAD_FUNC_ARG;
- if (responseBuffer) {
- responseBuffer->buffer = NULL;
- responseBuffer->length = 0;
- }
- ret = GetOcspEntry(ocsp, ocspRequest, &entry);
- if (ret != 0)
- return ret;
- ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer,
- heap);
- if (ret != OCSP_INVALID_STATUS)
- return ret;
- if (responseBuffer) {
- XFREE(responseBuffer->buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
- responseBuffer->buffer = NULL;
- }
- /* get SSL and IOCtx */
- ssl = (WOLFSSL*)ocspRequest->ssl;
- ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
- ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
- if (ocsp->statusCb != NULL && ssl != NULL) {
- WOLFSSL_MSG("Calling ocsp->statusCb");
- ret = ocsp->statusCb(ssl, ioCtx);
- switch (ret) {
- case SSL_TLSEXT_ERR_OK:
- ret = wolfSSL_get_ocsp_response(ssl, &response);
- ret = CheckOcspResponse(ocsp, response, ret, responseBuffer,
- status, entry, NULL, heap);
- if (response != NULL)
- XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
- break;
- case SSL_TLSEXT_ERR_NOACK:
- ret = OCSP_LOOKUP_FAIL;
- break;
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- default:
- WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error);
- ret = WOLFSSL_FATAL_ERROR;
- break;
- }
- WOLFSSL_LEAVE("CheckOcspRequest", ret);
- return ret;
- }
- #endif
- if (ocsp->cm->ocspUseOverrideURL) {
- url = ocsp->cm->ocspOverrideURL;
- if (url != NULL && url[0] != '\0')
- urlSz = (int)XSTRLEN(url);
- else
- return OCSP_NEED_URL;
- }
- else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
- url = (const char *)ocspRequest->url;
- urlSz = ocspRequest->urlSz;
- }
- else {
- /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
- WOLFSSL_MSG("Cert has no OCSP URL, assuming CERT_GOOD");
- return 0;
- }
- request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
- if (request == NULL) {
- WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
- return MEMORY_ERROR;
- }
- requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
- if (requestSz > 0 && ocsp->cm->ocspIOCb) {
- responseSz = ocsp->cm->ocspIOCb(ioCtx, url, urlSz,
- request, requestSz, &response);
- }
- if (responseSz == WOLFSSL_CBIO_ERR_WANT_READ) {
- ret = OCSP_WANT_READ;
- }
- XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
- if (responseSz >= 0 && response) {
- ret = CheckOcspResponse(ocsp, response, responseSz, responseBuffer, status,
- entry, ocspRequest, heap);
- }
- if (response != NULL && ocsp->cm->ocspRespFreeCb)
- ocsp->cm->ocspRespFreeCb(ioCtx, response);
- /* Keep responseBuffer in the case of getting to response check. Caller
- * should free responseBuffer after checking OCSP return value in "ret" */
- WOLFSSL_LEAVE("CheckOcspRequest", ret);
- return ret;
- }
- #ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
- static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
- void* vp) {
- /* Attempt to build a chain up to cert's issuer */
- WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
- Signer* ca = NULL;
- Signer* prev = NULL;
- int passed = 0;
- /*
- * Relation between certs:
- * CA
- * / \
- * intermediate(s) cert in OCSP response
- * | with OCSP key usage ext
- * issuer of cert
- * in OCSP request
- */
- /* End loop if no more issuers found or if we have found a self
- * signed cert (ca == prev) */
- for (ca = GetCAByName(cm, single->issuerHash); ca != NULL && ca != prev;
- prev = ca, ca = GetCAByName(cm, ca->issuerNameHash)) {
- if (XMEMCMP(cert->issuerHash, ca->issuerNameHash,
- OCSP_DIGEST_SIZE) == 0) {
- WOLFSSL_MSG("\tOCSP Response signed by authorized "
- "responder delegated by issuer "
- "(found in chain)");
- passed = 1;
- break;
- }
- }
- return passed;
- }
- #endif
- /**
- * Enforce https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2
- * @param bs The basic response to verify
- * @param cert The decoded bs->cert
- * @return
- */
- int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp)
- {
- int ret = 0;
- OcspEntry* single;
- /* Both evaluate to enum values so can't use a pre-processor check */
- WOLFSSL_ASSERT_EQ(OCSP_DIGEST_SIZE, SIGNER_DIGEST_SIZE);
- (void)vp;
- WOLFSSL_ENTER("CheckOcspResponder");
- /* In the future if this API is used more then it could be beneficial to
- * implement calling InitDecodedCert and ParseCertRelative here
- * automatically when cert == NULL. */
- if (bs == NULL || cert == NULL)
- return BAD_FUNC_ARG;
- /* Traverse the list and check that the cert has the authority to provide
- * an OCSP response for each entry. */
- for (single = bs->single; single != NULL; single = single->next) {
- int passed = 0;
- if (XMEMCMP(cert->subjectHash, single->issuerHash, OCSP_DIGEST_SIZE)
- == 0) {
- WOLFSSL_MSG("\tOCSP Response signed by issuer");
- passed = 1;
- }
- else if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) != 0) {
- if (XMEMCMP(cert->issuerHash, single->issuerHash,
- OCSP_DIGEST_SIZE) == 0) {
- WOLFSSL_MSG("\tOCSP Response signed by authorized responder "
- "delegated by issuer");
- passed = 1;
- }
- #ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
- else if (vp != NULL) {
- passed = CheckOcspResponderChain(single, cert, vp);
- }
- #endif
- }
- if (!passed) {
- WOLFSSL_MSG("\tOCSP Responder not authorized");
- #ifdef OPENSSL_EXTRA
- bs->verifyError = OCSP_BAD_ISSUER;
- #endif
- ret = BAD_OCSP_RESPONDER;
- break;
- }
- }
- return ret;
- }
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
- defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIGHTY)
- int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
- WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
- WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
- WOLFSSL_ASN1_TIME** nextupd)
- {
- WOLFSSL_OCSP_SINGLERESP* single;
- if (bs == NULL || id == NULL)
- return WOLFSSL_FAILURE;
- single = bs->single;
- while (single != NULL) {
- if ((XMEMCMP(single->status->serial, id->status->serial, single->status->serialSz) == 0)
- && (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0)
- && (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) {
- break;
- }
- single = single->next;
- }
- if (single == NULL)
- return WOLFSSL_FAILURE;
- if (status != NULL)
- *status = single->status->status;
- if (thisupd != NULL)
- *thisupd = &single->status->thisDateParsed;
- if (nextupd != NULL)
- *nextupd = &single->status->nextDateParsed;
- /* TODO: Not needed for Nginx or httpd */
- if (reason != NULL)
- *reason = 0;
- if (revtime != NULL)
- *revtime = NULL;
- return WOLFSSL_SUCCESS;
- }
- const char *wolfSSL_OCSP_cert_status_str(long s)
- {
- switch (s) {
- case CERT_GOOD:
- return "good";
- case CERT_REVOKED:
- return "revoked";
- case CERT_UNKNOWN:
- return "unknown";
- default:
- return "(UNKNOWN)";
- }
- }
- int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
- WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
- {
- (void)thisupd;
- (void)nextupd;
- (void)sec;
- (void)maxsec;
- /* Dates validated in DecodeSingleResponse. */
- return WOLFSSL_SUCCESS;
- }
- void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
- {
- FreeOcspEntry(certId, NULL);
- XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
- const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
- const WOLFSSL_X509 *issuer)
- {
- WOLFSSL_OCSP_CERTID* certId = NULL;
- CertStatus* certStatus = NULL;
- WOLFSSL_CERT_MANAGER* cm = NULL;
- int ret = -1;
- DerBuffer* derCert = NULL;
- #ifdef WOLFSSL_SMALL_STACK
- DecodedCert *cert = NULL;
- #else
- DecodedCert cert[1];
- #endif
- (void)dgst;
- cm = wolfSSL_CertManagerNew();
- if (cm == NULL
- || subject == NULL || subject->derCert == NULL
- || issuer == NULL || issuer->derCert == NULL)
- goto out;
- #ifdef WOLFSSL_SMALL_STACK
- cert = (DecodedCert *)XMALLOC(sizeof(*cert), cm->heap, DYNAMIC_TYPE_DCERT);
- if (cert == NULL)
- goto out;
- #endif
- ret = AllocDer(&derCert, issuer->derCert->length,
- issuer->derCert->type, NULL);
- if (ret == 0) {
- /* AddCA() frees the buffer. */
- XMEMCPY(derCert->buffer, issuer->derCert->buffer,
- issuer->derCert->length);
- ret = AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
- if (ret != WOLFSSL_SUCCESS) {
- goto out;
- }
- derCert = NULL;
- }
- ret = -1;
- certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
- cm->heap, DYNAMIC_TYPE_OPENSSL);
- if (certId == NULL)
- goto out;
- certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), cm->heap,
- DYNAMIC_TYPE_OPENSSL);
- if (certStatus == NULL)
- goto out;
- XMEMSET(certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
- XMEMSET(certStatus, 0, sizeof(CertStatus));
- certId->status = certStatus;
- certId->ownStatus = 1;
- InitDecodedCert(cert, subject->derCert->buffer,
- subject->derCert->length, NULL);
- if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
- FreeDecodedCert(cert);
- goto out;
- }
- else {
- XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
- XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
- XMEMCPY(certId->status->serial, cert->serial, cert->serialSz);
- certId->status->serialSz = cert->serialSz;
- FreeDecodedCert(cert);
- }
- ret = 0;
- out:
- if (ret != 0) {
- if (derCert != NULL)
- FreeDer(&derCert);
- if (certId != NULL) {
- XFREE(certId, cm->heap, DYNAMIC_TYPE_OPENSSL);
- certId = NULL;
- }
- if (certStatus)
- XFREE(certStatus, cm->heap, DYNAMIC_TYPE_OPENSSL);
- }
- #ifdef WOLFSSL_SMALL_STACK
- if (cert != NULL)
- XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
- #endif
- if (cm != NULL)
- wolfSSL_CertManagerFree(cm);
- return certId;
- }
- void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
- {
- wolfSSL_OCSP_RESPONSE_free(basicResponse);
- }
- /* Signature verified in DecodeBasicOcspResponse.
- * But no store available to verify certificate. */
- int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
- WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
- {
- int ret = WOLFSSL_FAILURE;
- #ifdef WOLFSSL_SMALL_STACK
- DecodedCert *cert;
- #else
- DecodedCert cert[1];
- #endif
- byte certInit = 0;
- int idx;
- (void)certs;
- if (flags & OCSP_NOVERIFY)
- return WOLFSSL_SUCCESS;
- #ifdef WOLFSSL_SMALL_STACK
- cert = (DecodedCert *)
- XMALLOC(sizeof(*cert), (st && st->cm) ? st->cm->heap : NULL,
- DYNAMIC_TYPE_DCERT);
- if (cert == NULL)
- return WOLFSSL_FAILURE;
- #endif
- #ifdef OPENSSL_EXTRA
- if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
- goto out;
- #endif
- if (flags & OCSP_TRUSTOTHER) {
- for (idx = 0; idx < wolfSSL_sk_X509_num(certs); idx++) {
- WOLFSSL_X509* x = wolfSSL_sk_X509_value(certs, idx);
- int derSz = 0;
- const byte* der = wolfSSL_X509_get_der(x, &derSz);
- if (derSz == (int)bs->certSz && XMEMCMP(bs->cert, der, derSz) == 0) {
- ret = WOLFSSL_SUCCESS;
- goto out;
- }
- }
- }
- InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
- certInit = 1;
- if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0)
- goto out;
- if (!(flags & OCSP_NOCHECKS)) {
- if (CheckOcspResponder(bs, cert, st->cm) != 0)
- goto out;
- }
- ret = WOLFSSL_SUCCESS;
- out:
- if (certInit)
- FreeDecodedCert(cert);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(cert, (st && st->cm) ? st->cm->heap : NULL, DYNAMIC_TYPE_DCERT);
- #endif
- return ret;
- }
- void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
- {
- if (response == NULL)
- return;
- if (response->single != NULL) {
- FreeOcspEntry(response->single, NULL);
- XFREE(response->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
- }
- if (response->source != NULL)
- XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- }
- #ifndef NO_BIO
- OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
- OcspResponse** response)
- {
- byte* data;
- byte* p;
- int len;
- int dataAlloced = 0;
- OcspResponse* ret = NULL;
- if (bio == NULL)
- return NULL;
- if (bio->type == WOLFSSL_BIO_MEMORY) {
- len = wolfSSL_BIO_get_mem_data(bio, &data);
- if (len <= 0 || data == NULL) {
- return NULL;
- }
- }
- #ifndef NO_FILESYSTEM
- else if (bio->type == WOLFSSL_BIO_FILE) {
- long fcur;
- long flen;
- if (bio->ptr == NULL)
- return NULL;
- fcur = XFTELL((XFILE)bio->ptr);
- if (fcur < 0)
- return NULL;
- if(XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
- return NULL;
- flen = XFTELL((XFILE)bio->ptr);
- if (flen < 0)
- return NULL;
- if (XFSEEK((XFILE)bio->ptr, fcur, SEEK_SET) != 0)
- return NULL;
- /* check calculated length */
- fcur = flen - fcur;
- if (fcur > MAX_WOLFSSL_FILE_SIZE || fcur <= 0)
- return NULL;
- data = (byte*)XMALLOC(fcur, 0, DYNAMIC_TYPE_TMP_BUFFER);
- if (data == NULL)
- return NULL;
- dataAlloced = 1;
- len = wolfSSL_BIO_read(bio, (char *)data, (int)flen);
- }
- #endif
- else
- return NULL;
- if (len > 0) {
- p = data;
- ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p,
- len);
- }
- if (dataAlloced)
- XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
- return ret;
- }
- #endif /* !NO_BIO */
- OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
- const unsigned char** data, int len)
- {
- OcspResponse *resp = NULL;
- word32 idx = 0;
- int length = 0;
- int ret;
- if (data == NULL)
- return NULL;
- if (response != NULL)
- resp = *response;
- if (resp == NULL) {
- resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
- DYNAMIC_TYPE_OCSP_REQUEST);
- if (resp == NULL)
- return NULL;
- XMEMSET(resp, 0, sizeof(OcspResponse));
- }
- resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (resp->source == NULL) {
- XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- return NULL;
- }
- resp->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
- DYNAMIC_TYPE_OCSP_ENTRY);
- if (resp->single == NULL) {
- XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- return NULL;
- }
- XMEMSET(resp->single, 0, sizeof(OcspEntry));
- resp->single->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
- DYNAMIC_TYPE_OCSP_STATUS);
- resp->single->ownStatus = 1;
- if (resp->single->status == NULL) {
- XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(resp->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
- XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
- return NULL;
- }
- XMEMSET(resp->single->status, 0, sizeof(CertStatus));
- XMEMCPY(resp->source, *data, len);
- resp->maxIdx = len;
- ret = OcspResponseDecode(resp, NULL, NULL, 1);
- if (ret != 0 && ret != ASN_OCSP_CONFIRM_E) {
- /* for just converting from a DER to an internal structure the CA may
- * not yet be known to this function for signature verification */
- wolfSSL_OCSP_RESPONSE_free(resp);
- return NULL;
- }
- if (GetSequence(*data, &idx, &length, len) >= 0)
- (*data) += idx + length;
- return resp;
- }
- int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
- unsigned char** data)
- {
- if (data == NULL)
- return response->maxIdx;
- XMEMCPY(*data, response->source, response->maxIdx);
- return response->maxIdx;
- }
- int wolfSSL_OCSP_response_status(OcspResponse *response)
- {
- return response->responseStatus;
- }
- const char *wolfSSL_OCSP_response_status_str(long s)
- {
- switch (s) {
- case OCSP_SUCCESSFUL:
- return "successful";
- case OCSP_MALFORMED_REQUEST:
- return "malformedrequest";
- case OCSP_INTERNAL_ERROR:
- return "internalerror";
- case OCSP_TRY_LATER:
- return "trylater";
- case OCSP_SIG_REQUIRED:
- return "sigrequired";
- case OCSP_UNAUTHORIZED:
- return "unauthorized";
- default:
- return "(UNKNOWN)";
- }
- }
- WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
- {
- WOLFSSL_OCSP_BASICRESP* bs;
- bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL,
- DYNAMIC_TYPE_OCSP_REQUEST);
- if (bs == NULL)
- return NULL;
- XMEMCPY(bs, response, sizeof(OcspResponse));
- bs->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
- DYNAMIC_TYPE_OCSP_ENTRY);
- bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (bs->single == NULL || bs->source == NULL) {
- if (bs->single) {
- XFREE(bs->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
- bs->single = NULL;
- }
- wolfSSL_OCSP_RESPONSE_free(bs);
- bs = NULL;
- }
- else {
- XMEMCPY(bs->single, response->single, sizeof(OcspEntry));
- XMEMCPY(bs->source, response->source, response->maxIdx);
- bs->single->ownStatus = 0;
- }
- return bs;
- }
- OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
- {
- OcspRequest* request;
- request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
- DYNAMIC_TYPE_OPENSSL);
- if (request != NULL)
- XMEMSET(request, 0, sizeof(OcspRequest));
- return request;
- }
- void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
- {
- FreeOcspRequest(request);
- XFREE(request, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
- {
- int size;
- size = EncodeOcspRequest(request, NULL, 0);
- if (size <= 0 || data == NULL)
- return size;
- return EncodeOcspRequest(request, *data, size);
- }
- WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
- WOLFSSL_OCSP_CERTID *cid)
- {
- if (req == NULL || cid == NULL || cid->status == NULL)
- return NULL;
- if (req->cid != NULL)
- wolfSSL_OCSP_CERTID_free((WOLFSSL_OCSP_CERTID*)req->cid);
- /* Keep to free */
- req->cid = (void*)cid;
- XMEMCPY(req->issuerHash, cid->issuerHash, KEYID_SIZE);
- XMEMCPY(req->issuerKeyHash, cid->issuerKeyHash, KEYID_SIZE);
- if (cid->status->serialSz > req->serialSz) {
- if (req->serial != NULL)
- XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
- req->serial = (byte*)XMALLOC(cid->status->serialSz,
- req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
- if (req->serial == NULL)
- return NULL;
- }
- XMEMCPY(req->serial, cid->status->serial, cid->status->serialSz);
- req->serialSz = cid->status->serialSz;
- return req;
- }
- WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID* id)
- {
- WOLFSSL_OCSP_CERTID* certId;
- if (id == NULL)
- return NULL;
- certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID),
- NULL, DYNAMIC_TYPE_OPENSSL);
- if (certId) {
- XMEMCPY(certId, id, sizeof(WOLFSSL_OCSP_CERTID));
- }
- return certId;
- }
- #endif
- #if defined(OPENSSL_ALL) || defined(APACHE_HTTPD) || defined(WOLFSSL_HAPROXY)
- #ifndef NO_BIO
- int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
- WOLFSSL_OCSP_REQUEST *req)
- {
- int size = -1;
- unsigned char* data = NULL;
- WOLFSSL_ENTER("wolfSSL_i2d_OCSP_REQUEST_bio");
- if (out == NULL || req == NULL)
- return WOLFSSL_FAILURE;
- size = wolfSSL_i2d_OCSP_REQUEST(req, NULL);
- if (size > 0) {
- data = (unsigned char*) XMALLOC(size, out->heap,
- DYNAMIC_TYPE_TMP_BUFFER);
- }
- if (data != NULL) {
- size = wolfSSL_i2d_OCSP_REQUEST(req, &data);
- }
- if (size <= 0) {
- XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_FAILURE;
- }
- if (wolfSSL_BIO_write(out, data, size) == (int)size) {
- XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_SUCCESS;
- }
- XFREE(data, out->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_FAILURE;
- }
- #endif /* !NO_BIO */
- int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data)
- {
- if (id == NULL || data == NULL)
- return WOLFSSL_FAILURE;
- if (*data != NULL) {
- XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
- *data = *data + id->rawCertIdSize;
- }
- else {
- *data = (unsigned char*)XMALLOC(id->rawCertIdSize, NULL, DYNAMIC_TYPE_OPENSSL);
- if (*data == NULL) {
- return WOLFSSL_FAILURE;
- }
- XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
- }
- return id->rawCertIdSize;
- }
- WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut,
- const unsigned char** derIn,
- int length)
- {
- WOLFSSL_OCSP_CERTID *cid = NULL;
- if ((cidOut != NULL) && (derIn != NULL) && (*derIn != NULL) &&
- (length > 0)) {
- cid = *cidOut;
- /* If a NULL is passed we allocate the memory for the caller. */
- if (cid == NULL) {
- cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*cid), NULL,
- DYNAMIC_TYPE_OPENSSL);
- }
- else if (cid->rawCertId != NULL) {
- XFREE(cid->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
- cid->rawCertId = NULL;
- cid->rawCertIdSize = 0;
- }
- if (cid != NULL) {
- cid->rawCertId = (byte*)XMALLOC(length + 1, NULL, DYNAMIC_TYPE_OPENSSL);
- if (cid->rawCertId != NULL) {
- XMEMCPY(cid->rawCertId, *derIn, length);
- cid->rawCertIdSize = length;
- /* Per spec. advance past the data that is being returned
- * to the caller. */
- *cidOut = cid;
- *derIn = *derIn + length;
- return cid;
- }
- }
- }
- if ((cid != NULL) && ((cidOut == NULL) || (cid != *cidOut))) {
- XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- return NULL;
- }
- const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(const WOLFSSL_OCSP_SINGLERESP *single)
- {
- return single;
- }
- /**
- * Compare two WOLFSSL_OCSP_CERTID objects
- * @param a
- * @param b
- * @return 0 on success and when objects have the same id otherwise either
- * the id's don't match or an error occurred
- */
- int wolfSSL_OCSP_id_cmp(WOLFSSL_OCSP_CERTID *a, WOLFSSL_OCSP_CERTID *b)
- {
- int ret = 0;
- if (a == NULL || b == NULL)
- return WOLFSSL_FATAL_ERROR;
- ret = a->hashAlgoOID != b->hashAlgoOID;
- if (ret == 0)
- ret = XMEMCMP(a->issuerHash, b->issuerHash, OCSP_DIGEST_SIZE);
- if (ret == 0)
- ret = XMEMCMP(a->issuerKeyHash, b->issuerKeyHash, OCSP_DIGEST_SIZE);
- if (ret == 0) {
- if (a->status != NULL && b->status != NULL) {
- if (a->status->serialSz == b->status->serialSz)
- ret = XMEMCMP(a->status->serial, b->status->serial,
- a->status->serialSz);
- else
- ret = -1;
- }
- else if (a->status != b->status) {
- /* If either is not null then return non-zero */
- ret = -1;
- }
- }
- return ret;
- }
- int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single,
- int *reason,
- WOLFSSL_ASN1_TIME **revtime,
- WOLFSSL_ASN1_TIME **thisupd,
- WOLFSSL_ASN1_TIME **nextupd)
- {
- if (single == NULL)
- return WOLFSSL_FAILURE;
- if (thisupd != NULL)
- *thisupd = &single->status->thisDateParsed;
- if (nextupd != NULL)
- *nextupd = &single->status->nextDateParsed;
- if (reason != NULL)
- *reason = 0;
- if (revtime != NULL)
- *revtime = NULL;
- return single->status->status;
- }
- int wolfSSL_OCSP_resp_count(WOLFSSL_OCSP_BASICRESP *bs)
- {
- WOLFSSL_OCSP_SINGLERESP* single;
- int count = 0;
- if (bs == NULL)
- return WOLFSSL_FAILURE;
- single = bs->single;
- while(single != NULL)
- {
- ++count;
- single = single->next;
- }
- return count;
- }
- WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0(WOLFSSL_OCSP_BASICRESP *bs, int idx)
- {
- WOLFSSL_OCSP_SINGLERESP* single;
- int currIdx = 0;
- if (bs == NULL)
- return NULL;
- single = bs->single;
- while(single != NULL && currIdx != idx)
- {
- single = single->next;
- ++currIdx;
- }
- return single;
- }
- #endif /* OPENSSL_ALL || APACHE_HTTPD || WOLFSSL_HAPROXY */
- #ifdef OPENSSL_EXTRA
- #ifndef NO_WOLFSSL_STUB
- int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext,
- int idx)
- {
- WOLFSSL_STUB("wolfSSL_OCSP_REQUEST_add_ext");
- (void)req;
- (void)ext;
- (void)idx;
- return WOLFSSL_FATAL_ERROR;
- }
- #endif
- #ifndef NO_WOLFSSL_STUB
- OcspResponse* wolfSSL_OCSP_response_create(int status,
- WOLFSSL_OCSP_BASICRESP* bs)
- {
- WOLFSSL_STUB("wolfSSL_OCSP_response_create");
- (void)status;
- (void)bs;
- return NULL;
- }
- #endif
- #ifndef NO_WOLFSSL_STUB
- const char* wolfSSL_OCSP_crl_reason_str(long s)
- {
- WOLFSSL_STUB("wolfSSL_OCSP_crl_reason_str");
- (void)s;
- return NULL;
- }
- #endif
- /* Returns elements of an OCSP_CERTID struct. Currently only supports
- * returning the serial number, and returns an error if user requests
- * any of name, pmd, and/or keyHash.
- * Return 1 on success, 0 on failure */
- int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name,
- WOLFSSL_ASN1_OBJECT **pmd, WOLFSSL_ASN1_STRING **keyHash,
- WOLFSSL_ASN1_INTEGER **serial, WOLFSSL_OCSP_CERTID *cid)
- {
- WOLFSSL_ENTER("wolfSSL_OCSP_id_get0_info");
- if (cid == NULL)
- return 0;
- /* build up ASN1_INTEGER for serial */
- if (serial != NULL) {
- int i = 0;
- WOLFSSL_ASN1_INTEGER* ser;
- ser = wolfSSL_ASN1_INTEGER_new();
- if (ser == NULL)
- return 0;
- if (cid->status->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
- /* allocate data buffer, +2 for type and length */
- ser->data = (unsigned char*)XMALLOC(cid->status->serialSz + 2, NULL,
- DYNAMIC_TYPE_OPENSSL);
- if (ser->data == NULL) {
- wolfSSL_ASN1_INTEGER_free(ser);
- return 0;
- }
- ser->dataMax = cid->status->serialSz + 2;
- ser->isDynamic = 1;
- } else {
- /* Use array instead of dynamic memory */
- ser->data = ser->intData;
- ser->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
- }
- #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
- /* Serial number starts at 0 index of ser->data */
- XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz);
- ser->length = cid->status->serialSz;
- #else
- ser->data[i++] = ASN_INTEGER;
- i += SetLength(cid->status->serialSz, ser->data + i);
- XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz);
- ser->length = i + cid->status->serialSz;
- #endif
- cid->status->serialInt = ser;
- *serial = ser;
- }
- /* Not needed for Apache, return error if user is requesting */
- if (name != NULL || pmd != NULL || keyHash != NULL) {
- if (name != NULL)
- *name = NULL;
- if (pmd != NULL)
- *pmd = NULL;
- if (keyHash != NULL)
- *keyHash = NULL;
- return 0;
- }
- return 1;
- }
- int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val,
- int sz)
- {
- WC_RNG rng;
- WOLFSSL_ENTER("wolfSSL_OCSP_request_add1_nonce");
- if (req == NULL || sz > MAX_OCSP_NONCE_SZ) {
- WOLFSSL_MSG("Bad parameter");
- return WOLFSSL_FAILURE;
- }
- if (sz <= 0)
- sz = MAX_OCSP_NONCE_SZ;
- if (val != NULL) {
- XMEMCPY(req->nonce, val, sz);
- }
- else {
- if (
- #ifndef HAVE_FIPS
- wc_InitRng_ex(&rng, req->heap, INVALID_DEVID)
- #else
- wc_InitRng(&rng)
- #endif
- != 0) {
- WOLFSSL_MSG("RNG init failed");
- return WOLFSSL_FAILURE;
- }
- if (wc_RNG_GenerateBlock(&rng, req->nonce, sz) != 0) {
- WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
- wc_FreeRng(&rng);
- return WOLFSSL_FAILURE;
- }
- wc_FreeRng(&rng);
- }
- req->nonceSz = sz;
- return WOLFSSL_SUCCESS;
- }
- /* Returns result of OCSP nonce comparison. Return values:
- * 1 - nonces are both present and equal
- * 2 - both nonces are absent
- * 3 - nonce only present in response
- * -1 - nonce only present in request
- * 0 - both nonces present and equal
- */
- int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs)
- {
- byte* reqNonce = NULL;
- byte* rspNonce = NULL;
- int reqNonceSz = 0;
- int rspNonceSz = 0;
- WOLFSSL_ENTER("wolfSSL_OCSP_check_nonce");
- if (req != NULL) {
- reqNonce = req->nonce;
- reqNonceSz = req->nonceSz;
- }
- if (bs != NULL) {
- rspNonce = bs->nonce;
- rspNonceSz = bs->nonceSz;
- }
- /* nonce absent in both req and rsp */
- if (reqNonce == NULL && rspNonce == NULL)
- return 2;
- /* nonce present in rsp only */
- if (reqNonce == NULL && rspNonce != NULL)
- return 3;
- /* nonce present in req only */
- if (reqNonce != NULL && rspNonce == NULL)
- return -1;
- /* nonces are present and equal, return 1. Extra NULL check for fixing
- scan-build warning. */
- if (reqNonceSz == rspNonceSz && reqNonce && rspNonce) {
- if (XMEMCMP(reqNonce, rspNonce, reqNonceSz) == 0)
- return 1;
- }
- /* nonces are present but not equal */
- return 0;
- }
- #endif /* OPENSSL_EXTRA */
- #else /* HAVE_OCSP */
- #ifdef _MSC_VER
- /* 4206 warning for blank file */
- #pragma warning(disable: 4206)
- #endif
- #endif /* HAVE_OCSP */
- #endif /* WOLFCRYPT_ONLY */
|