CyaSSL 3.0.0
Dependents: HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more
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 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 00270
Generated on Wed Jul 13 2022 02:18:39 by 1.7.2