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.
ocsp.c
00001 /* ocsp.c 00002 * 00003 * Copyright (C) 2006-2013 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 OcspRequest ocspRequest; 00111 OcspResponse ocspResponse; 00112 int result = -1; 00113 OCSP_Entry* ocspe; 00114 CertStatus* certStatus = NULL; 00115 CertStatus newStatus; 00116 const char *url; 00117 int urlSz; 00118 00119 CYASSL_ENTER("CheckCertOCSP"); 00120 00121 if (LockMutex(&ocsp->ocspLock) != 0) { 00122 CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); 00123 return BAD_MUTEX_E; 00124 } 00125 00126 ocspe = ocsp->ocspList; 00127 while (ocspe) { 00128 if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0 00129 && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash, 00130 SHA_DIGEST_SIZE) == 0) 00131 break; 00132 else 00133 ocspe = ocspe->next; 00134 } 00135 00136 if (ocspe == NULL) { 00137 ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry), 00138 NULL, DYNAMIC_TYPE_OCSP_ENTRY); 00139 if (ocspe != NULL) { 00140 InitOCSP_Entry(ocspe, cert); 00141 ocspe->next = ocsp->ocspList; 00142 ocsp->ocspList = ocspe; 00143 } 00144 else { 00145 UnLockMutex(&ocsp->ocspLock); 00146 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00147 return MEMORY_ERROR; 00148 } 00149 } 00150 else { 00151 certStatus = ocspe->status; 00152 while (certStatus) { 00153 if (certStatus->serialSz == cert->serialSz && 00154 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0) 00155 break; 00156 else 00157 certStatus = certStatus->next; 00158 } 00159 } 00160 00161 if (certStatus != NULL) { 00162 if (!ValidateDate(certStatus->thisDate, 00163 certStatus->thisDateFormat, BEFORE) || 00164 (certStatus->nextDate[0] == 0) || 00165 !ValidateDate(certStatus->nextDate, 00166 certStatus->nextDateFormat, AFTER)) { 00167 CYASSL_MSG("\tinvalid status date, looking up cert"); 00168 } 00169 else { 00170 result = xstat2err(certStatus->status); 00171 UnLockMutex(&ocsp->ocspLock); 00172 CYASSL_LEAVE("CheckCertOCSP", result); 00173 return result; 00174 } 00175 } 00176 00177 UnLockMutex(&ocsp->ocspLock); 00178 00179 if (ocsp->cm->ocspUseOverrideURL) { 00180 url = ocsp->cm->ocspOverrideURL; 00181 if (url != NULL && url[0] != '\0') 00182 urlSz = (int)XSTRLEN(url); 00183 else 00184 return OCSP_NEED_URL; 00185 } 00186 else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) { 00187 url = (const char *)cert->extAuthInfo; 00188 urlSz = cert->extAuthInfoSz; 00189 } 00190 else { 00191 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ 00192 return 0; 00193 } 00194 00195 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); 00196 if (ocspReqBuf == NULL) { 00197 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); 00198 return MEMORY_ERROR; 00199 } 00200 InitOcspRequest(&ocspRequest, cert, ocsp->cm->ocspSendNonce, 00201 ocspReqBuf, ocspReqSz); 00202 ocspReqSz = EncodeOcspRequest(&ocspRequest); 00203 00204 if (ocsp->cm->ocspIOCb) 00205 result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, 00206 ocspReqBuf, ocspReqSz, &ocspRespBuf); 00207 00208 if (result >= 0 && ocspRespBuf) { 00209 XMEMSET(&newStatus, 0, sizeof(CertStatus)); 00210 00211 InitOcspResponse(&ocspResponse, &newStatus, ocspRespBuf, result); 00212 OcspResponseDecode(&ocspResponse); 00213 00214 if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) 00215 result = OCSP_LOOKUP_FAIL; 00216 else { 00217 if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) { 00218 result = xstat2err(ocspResponse.status->status); 00219 00220 if (LockMutex(&ocsp->ocspLock) != 0) 00221 result = BAD_MUTEX_E; 00222 else { 00223 if (certStatus != NULL) 00224 /* Replace existing certificate entry with updated */ 00225 XMEMCPY(certStatus, &newStatus, sizeof(CertStatus)); 00226 else { 00227 /* Save new certificate entry */ 00228 certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), 00229 NULL, DYNAMIC_TYPE_OCSP_STATUS); 00230 if (certStatus != NULL) { 00231 XMEMCPY(certStatus, &newStatus, sizeof(CertStatus)); 00232 certStatus->next = ocspe->status; 00233 ocspe->status = certStatus; 00234 ocspe->totalStatus++; 00235 } 00236 } 00237 00238 UnLockMutex(&ocsp->ocspLock); 00239 } 00240 } 00241 else 00242 result = OCSP_LOOKUP_FAIL; 00243 } 00244 } 00245 else 00246 result = OCSP_LOOKUP_FAIL; 00247 00248 if (ocspReqBuf != NULL) 00249 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); 00250 00251 if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb) 00252 ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf); 00253 00254 CYASSL_LEAVE("CheckCertOCSP", result); 00255 return result; 00256 } 00257 00258 00259 #else /* HAVE_OCSP */ 00260 00261 00262 #ifdef _MSC_VER 00263 /* 4206 warning for blank file */ 00264 #pragma warning(disable: 4206) 00265 #endif 00266 00267 00268 #endif /* HAVE_OCSP */ 00269
Generated on Tue Jul 12 2022 20:12:51 by
