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.
Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
ocsp.c
00001 /* ocsp.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL 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 * CyaSSL 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-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifdef HAVE_OCSP 00029 00030 #include <cyassl/error-ssl.h> 00031 #include <cyassl/ocsp.h> 00032 #include <cyassl/internal.h> 00033 00034 00035 int InitOCSP(CYASSL_OCSP* ocsp, CYASSL_CERT_MANAGER* cm) 00036 { 00037 CYASSL_ENTER("InitOCSP"); 00038 XMEMSET(ocsp, 0, sizeof(*ocsp)); 00039 ocsp->cm = cm; 00040 if (InitMutex(&ocsp->ocspLock) != 0) 00041 return BAD_MUTEX_E; 00042 00043 return 0; 00044 } 00045 00046 00047 static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert) 00048 { 00049 CYASSL_ENTER("InitOCSP_Entry"); 00050 00051 XMEMSET(ocspe, 0, sizeof(*ocspe)); 00052 XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE); 00053 XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE); 00054 00055 return 0; 00056 } 00057 00058 00059 static void FreeOCSP_Entry(OCSP_Entry* ocspe) 00060 { 00061 CertStatus* tmp = ocspe->status; 00062 00063 CYASSL_ENTER("FreeOCSP_Entry"); 00064 00065 while (tmp) { 00066 CertStatus* next = tmp->next; 00067 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS); 00068 tmp = next; 00069 } 00070 } 00071 00072 00073 void FreeOCSP(CYASSL_OCSP* ocsp, int dynamic) 00074 { 00075 OCSP_Entry* tmp = ocsp->ocspList; 00076 00077 CYASSL_ENTER("FreeOCSP"); 00078 00079 while (tmp) { 00080 OCSP_Entry* next = tmp->next; 00081 FreeOCSP_Entry(tmp); 00082 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY); 00083 tmp = next; 00084 } 00085 00086 FreeMutex(&ocsp->ocspLock); 00087 if (dynamic) 00088 XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP); 00089 } 00090 00091 00092 static int xstat2err(int stat) 00093 { 00094 switch (stat) { 00095 case CERT_GOOD: 00096 return 0; 00097 case CERT_REVOKED: 00098 return OCSP_CERT_REVOKED; 00099 default: 00100 return OCSP_CERT_UNKNOWN; 00101 } 00102 } 00103 00104 00105 int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert) 00106 { 00107 byte* ocspReqBuf = NULL; 00108 int ocspReqSz = 2048; 00109 byte* ocspRespBuf = NULL; 00110 int result = -1; 00111 OCSP_Entry* ocspe; 00112 CertStatus* certStatus = NULL; 00113 const char *url; 00114 int urlSz; 00115 #ifdef CYASSL_SMALL_STACK 00116 CertStatus* newStatus; 00117 OcspRequest* ocspRequest; 00118 OcspResponse* ocspResponse; 00119 #else 00120 CertStatus newStatus[1]; 00121 OcspRequest ocspRequest[1]; 00122 OcspResponse ocspResponse[1]; 00123 #endif 00124 00125 CYASSL_ENTER("CheckCertOCSP"); 00126 00127 if (LockMutex(&ocsp->ocspLock) != 0) { 00128 CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); 00129 return BAD_MUTEX_E; 00130 } 00131 00132 ocspe = ocsp->ocspList; 00133 while (ocspe) { 00134 if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0 00135 && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash, 00136 SHA_DIGEST_SIZE) == 0) 00137 break; 00138 else 00139 ocspe = ocspe->next; 00140 } 00141 00142 if (ocspe == NULL) { 00143 ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry), 00144 NULL, DYNAMIC_TYPE_OCSP_ENTRY); 00145 if (ocspe != NULL) { 00146 InitOCSP_Entry(ocspe, cert); 00147 ocspe->next = ocsp->ocspList; 00148 ocsp->ocspList = ocspe; 00149 } 00150 else { 00151 UnLockMutex(&ocsp->ocspLock); 00152 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00153 return MEMORY_ERROR; 00154 } 00155 } 00156 else { 00157 certStatus = ocspe->status; 00158 while (certStatus) { 00159 if (certStatus->serialSz == cert->serialSz && 00160 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0) 00161 break; 00162 else 00163 certStatus = certStatus->next; 00164 } 00165 } 00166 00167 if (certStatus != NULL) { 00168 if (!ValidateDate(certStatus->thisDate, 00169 certStatus->thisDateFormat, BEFORE) || 00170 (certStatus->nextDate[0] == 0) || 00171 !ValidateDate(certStatus->nextDate, 00172 certStatus->nextDateFormat, AFTER)) { 00173 CYASSL_MSG("\tinvalid status date, looking up cert"); 00174 } 00175 else { 00176 result = xstat2err(certStatus->status); 00177 UnLockMutex(&ocsp->ocspLock); 00178 CYASSL_LEAVE("CheckCertOCSP", result); 00179 return result; 00180 } 00181 } 00182 00183 UnLockMutex(&ocsp->ocspLock); 00184 00185 if (ocsp->cm->ocspUseOverrideURL) { 00186 url = ocsp->cm->ocspOverrideURL; 00187 if (url != NULL && url[0] != '\0') 00188 urlSz = (int)XSTRLEN(url); 00189 else 00190 return OCSP_NEED_URL; 00191 } 00192 else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) { 00193 url = (const char *)cert->extAuthInfo; 00194 urlSz = cert->extAuthInfoSz; 00195 } 00196 else { 00197 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ 00198 return 0; 00199 } 00200 00201 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); 00202 if (ocspReqBuf == NULL) { 00203 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00204 return MEMORY_ERROR; 00205 } 00206 00207 #ifdef CYASSL_SMALL_STACK 00208 newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, 00209 DYNAMIC_TYPE_TMP_BUFFER); 00210 ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, 00211 DYNAMIC_TYPE_TMP_BUFFER); 00212 ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, 00213 DYNAMIC_TYPE_TMP_BUFFER); 00214 00215 if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) { 00216 if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00217 if (ocspRequest) XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00218 if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00219 00220 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00221 00222 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00223 return MEMORY_E; 00224 } 00225 #endif 00226 00227 InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce, 00228 ocspReqBuf, ocspReqSz); 00229 ocspReqSz = EncodeOcspRequest(ocspRequest); 00230 00231 if (ocsp->cm->ocspIOCb) 00232 result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, 00233 ocspReqBuf, ocspReqSz, &ocspRespBuf); 00234 00235 if (result >= 0 && ocspRespBuf) { 00236 XMEMSET(newStatus, 0, sizeof(CertStatus)); 00237 00238 InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result); 00239 OcspResponseDecode(ocspResponse); 00240 00241 if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) 00242 result = OCSP_LOOKUP_FAIL; 00243 else { 00244 if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) { 00245 result = xstat2err(ocspResponse->status->status); 00246 00247 if (LockMutex(&ocsp->ocspLock) != 0) 00248 result = BAD_MUTEX_E; 00249 else { 00250 if (certStatus != NULL) 00251 /* Replace existing certificate entry with updated */ 00252 XMEMCPY(certStatus, newStatus, sizeof(CertStatus)); 00253 else { 00254 /* Save new certificate entry */ 00255 certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), 00256 NULL, DYNAMIC_TYPE_OCSP_STATUS); 00257 if (certStatus != NULL) { 00258 XMEMCPY(certStatus, newStatus, sizeof(CertStatus)); 00259 certStatus->next = ocspe->status; 00260 ocspe->status = certStatus; 00261 ocspe->totalStatus++; 00262 } 00263 } 00264 00265 UnLockMutex(&ocsp->ocspLock); 00266 } 00267 } 00268 else 00269 result = OCSP_LOOKUP_FAIL; 00270 } 00271 } 00272 else 00273 result = OCSP_LOOKUP_FAIL; 00274 00275 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); 00276 00277 #ifdef CYASSL_SMALL_STACK 00278 XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00279 XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00280 XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00281 #endif 00282 00283 if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb) 00284 ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf); 00285 00286 CYASSL_LEAVE("CheckCertOCSP", result); 00287 return result; 00288 } 00289 00290 00291 #else /* HAVE_OCSP */ 00292 00293 00294 #ifdef _MSC_VER 00295 /* 4206 warning for blank file */ 00296 #pragma warning(disable: 4206) 00297 #endif 00298 00299 00300 #endif /* HAVE_OCSP */ 00301
Generated on Wed Jul 13 2022 02:33:57 by
1.7.2