wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ocsp.c Source File

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