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: TLS_cyassl TLS_cyassl
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 #ifdef EBSNET 00031 #include "rtip.h" 00032 #include "socket.h" 00033 #endif 00034 00035 #include <cyassl/ctaoerror.h> 00036 #include <cyassl/ocsp.h> 00037 #include <cyassl/internal.h> 00038 #include <ctype.h> 00039 00040 #include <string.h> 00041 00042 #ifndef EBSNET 00043 #include <unistd.h> 00044 #include <netdb.h> 00045 #include <netinet/in.h> 00046 #include <netinet/tcp.h> 00047 #include <arpa/inet.h> 00048 #include <sys/ioctl.h> 00049 #include <sys/time.h> 00050 #include <sys/types.h> 00051 #include <sys/socket.h> 00052 #endif 00053 00054 00055 CYASSL_API int ocsp_test(unsigned char* buf, int sz); 00056 #define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */ 00057 #define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL 00058 * in certificate */ 00059 #define CYASSL_OCSP_NO_NONCE 0x0004 /* Disables the request nonce */ 00060 00061 typedef struct sockaddr_in SOCKADDR_IN_T; 00062 #define AF_INET_V AF_INET 00063 #define SOCKET_T unsigned int 00064 00065 00066 int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp) 00067 { 00068 if (ocsp != NULL) { 00069 XMEMSET(ocsp, 0, sizeof(*ocsp)); 00070 ocsp->useNonce = 1; 00071 #ifndef CYASSL_USER_IO 00072 ocsp->CBIOOcsp = EmbedOcspLookup; 00073 ocsp->CBIOOcspRespFree = EmbedOcspRespFree; 00074 #endif 00075 return 0; 00076 } 00077 00078 return -1; 00079 } 00080 00081 00082 static void FreeOCSP_Entry(OCSP_Entry* ocspe) 00083 { 00084 CertStatus* tmp = ocspe->status; 00085 00086 CYASSL_ENTER("FreeOCSP_Entry"); 00087 00088 while (tmp) { 00089 CertStatus* next = tmp->next; 00090 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS); 00091 tmp = next; 00092 } 00093 } 00094 00095 00096 void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp) 00097 { 00098 OCSP_Entry* tmp = ocsp->ocspList; 00099 00100 ocsp->enabled = 0; 00101 while (tmp) { 00102 OCSP_Entry* next = tmp->next; 00103 FreeOCSP_Entry(tmp); 00104 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY); 00105 tmp = next; 00106 } 00107 } 00108 00109 00110 int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url) 00111 { 00112 if (ocsp != NULL) { 00113 int urlSz = (int)XSTRLEN(url); 00114 if (urlSz < (int)sizeof(ocsp->overrideUrl)) { 00115 XSTRNCPY(ocsp->overrideUrl, url, urlSz); 00116 return 1; 00117 } 00118 } 00119 00120 return 0; 00121 } 00122 00123 00124 static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert) 00125 { 00126 CYASSL_ENTER("InitOCSP_Entry"); 00127 00128 ocspe->next = NULL; 00129 XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE); 00130 XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE); 00131 ocspe->status = NULL; 00132 ocspe->totalStatus = 0; 00133 00134 return 0; 00135 } 00136 00137 00138 static OCSP_Entry* find_ocsp_entry(CYASSL_OCSP* ocsp, DecodedCert* cert) 00139 { 00140 OCSP_Entry* entry = ocsp->ocspList; 00141 00142 while (entry) 00143 { 00144 if (XMEMCMP(entry->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0 00145 && XMEMCMP(entry->issuerKeyHash, cert->issuerKeyHash, 00146 SHA_DIGEST_SIZE) == 0) 00147 { 00148 CYASSL_MSG("Found OCSP responder"); 00149 break; 00150 } 00151 else 00152 { 00153 entry = entry->next; 00154 } 00155 } 00156 00157 if (entry == NULL) 00158 { 00159 CYASSL_MSG("Add a new OCSP entry"); 00160 entry = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry), 00161 NULL, DYNAMIC_TYPE_OCSP_ENTRY); 00162 if (entry != NULL) 00163 { 00164 InitOCSP_Entry(entry, cert); 00165 entry->next = ocsp->ocspList; 00166 ocsp->ocspList = entry; 00167 } 00168 } 00169 00170 return entry; 00171 } 00172 00173 00174 static CertStatus* find_cert_status(OCSP_Entry* ocspe, DecodedCert* cert) 00175 { 00176 CertStatus* stat = ocspe->status; 00177 00178 while (stat) 00179 { 00180 if(stat->serialSz == cert->serialSz && 00181 (XMEMCMP(stat->serial, cert->serial, cert->serialSz) == 0)) 00182 { 00183 break; 00184 } 00185 else 00186 { 00187 stat = stat->next; 00188 } 00189 } 00190 if (stat == NULL) 00191 { 00192 stat = (CertStatus*)XMALLOC(sizeof(CertStatus), 00193 NULL, DYNAMIC_TYPE_OCSP_STATUS); 00194 if (stat != NULL) 00195 { 00196 XMEMCPY(stat->serial, cert->serial, cert->serialSz); 00197 stat->serialSz = cert->serialSz; 00198 stat->status = -1; 00199 stat->nextDate[0] = 0; 00200 ocspe->totalStatus++; 00201 00202 stat->next = ocspe->status; 00203 ocspe->status = stat; 00204 } 00205 } 00206 00207 return stat; 00208 } 00209 00210 00211 static int xstat2err(int stat) 00212 { 00213 switch (stat) { 00214 case CERT_GOOD: 00215 return 0; 00216 break; 00217 case CERT_REVOKED: 00218 return OCSP_CERT_REVOKED; 00219 break; 00220 default: 00221 return OCSP_CERT_UNKNOWN; 00222 break; 00223 } 00224 } 00225 00226 00227 int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) 00228 { 00229 byte* ocspReqBuf = NULL; 00230 int ocspReqSz = 2048; 00231 byte* ocspRespBuf = NULL; 00232 OcspRequest ocspRequest; 00233 OcspResponse ocspResponse; 00234 int result = 0; 00235 OCSP_Entry* ocspe; 00236 CertStatus* certStatus; 00237 const char *url; 00238 int urlSz; 00239 00240 /* If OCSP lookups are disabled, return success. */ 00241 if (!ocsp->enabled) { 00242 CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD"); 00243 return 0; 00244 } 00245 00246 ocspe = find_ocsp_entry(ocsp, cert); 00247 if (ocspe == NULL) { 00248 CYASSL_MSG("alloc OCSP entry failed"); 00249 return MEMORY_ERROR; 00250 } 00251 00252 certStatus = find_cert_status(ocspe, cert); 00253 if (certStatus == NULL) 00254 { 00255 CYASSL_MSG("alloc OCSP cert status failed"); 00256 return MEMORY_ERROR; 00257 } 00258 00259 if (certStatus->status != -1) 00260 { 00261 if (!ValidateDate(certStatus->thisDate, 00262 certStatus->thisDateFormat, BEFORE) || 00263 (certStatus->nextDate[0] == 0) || 00264 !ValidateDate(certStatus->nextDate, 00265 certStatus->nextDateFormat, AFTER)) 00266 { 00267 CYASSL_MSG("\tinvalid status date, looking up cert"); 00268 certStatus->status = -1; 00269 } 00270 else 00271 { 00272 CYASSL_MSG("\tusing cached status"); 00273 result = xstat2err(certStatus->status); 00274 return result; 00275 } 00276 } 00277 00278 if (ocsp->useOverrideUrl) { 00279 if (ocsp->overrideUrl[0] != '\0') { 00280 url = ocsp->overrideUrl; 00281 urlSz = (int)XSTRLEN(url); 00282 } 00283 else 00284 return OCSP_NEED_URL; 00285 } 00286 else if (cert->extAuthInfoSz == 0 || cert->extAuthInfo == NULL) { 00287 url = (const char *)cert->extAuthInfo; 00288 urlSz = cert->extAuthInfoSz; 00289 } 00290 else { 00291 CYASSL_MSG("\tcert doesn't have extAuthInfo, assuming CERT_GOOD"); 00292 return 0; 00293 } 00294 00295 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); 00296 if (ocspReqBuf == NULL) { 00297 CYASSL_MSG("\talloc OCSP request buffer failed"); 00298 return MEMORY_ERROR; 00299 } 00300 InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz); 00301 ocspReqSz = EncodeOcspRequest(&ocspRequest); 00302 00303 if (ocsp->CBIOOcsp) { 00304 result = ocsp->CBIOOcsp(ocsp->IOCB_OcspCtx, url, urlSz, 00305 ocspReqBuf, ocspReqSz, &ocspRespBuf); 00306 } 00307 00308 if (result >= 0 && ocspRespBuf) { 00309 InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result); 00310 OcspResponseDecode(&ocspResponse); 00311 00312 if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) { 00313 CYASSL_MSG("OCSP Responder failure"); 00314 result = OCSP_LOOKUP_FAIL; 00315 } else { 00316 if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) 00317 { 00318 result = xstat2err(ocspResponse.status->status); 00319 } 00320 else 00321 { 00322 CYASSL_MSG("OCSP Response incorrect for Request"); 00323 result = OCSP_LOOKUP_FAIL; 00324 } 00325 } 00326 } 00327 else { 00328 result = OCSP_LOOKUP_FAIL; 00329 } 00330 00331 if (ocspReqBuf != NULL) { 00332 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); 00333 } 00334 if (ocspRespBuf != NULL && ocsp->CBIOOcspRespFree) { 00335 ocsp->CBIOOcspRespFree(ocsp->IOCB_OcspCtx, ocspRespBuf); 00336 } 00337 00338 return result; 00339 } 00340 00341 00342 #endif /* HAVE_OCSP */ 00343
Generated on Thu Jul 14 2022 20:26:03 by
1.7.2