A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* ocsp.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 23 #include <config.h>
Vanger 0:b86d15c6ba29 24 #endif
Vanger 0:b86d15c6ba29 25
Vanger 0:b86d15c6ba29 26 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 #ifdef HAVE_OCSP
Vanger 0:b86d15c6ba29 29
Vanger 0:b86d15c6ba29 30 #include <cyassl/error-ssl.h>
Vanger 0:b86d15c6ba29 31 #include <cyassl/ocsp.h>
Vanger 0:b86d15c6ba29 32 #include <cyassl/internal.h>
Vanger 0:b86d15c6ba29 33
Vanger 0:b86d15c6ba29 34
Vanger 0:b86d15c6ba29 35 int InitOCSP(CYASSL_OCSP* ocsp, CYASSL_CERT_MANAGER* cm)
Vanger 0:b86d15c6ba29 36 {
Vanger 0:b86d15c6ba29 37 CYASSL_ENTER("InitOCSP");
Vanger 0:b86d15c6ba29 38 XMEMSET(ocsp, 0, sizeof(*ocsp));
Vanger 0:b86d15c6ba29 39 ocsp->cm = cm;
Vanger 0:b86d15c6ba29 40 if (InitMutex(&ocsp->ocspLock) != 0)
Vanger 0:b86d15c6ba29 41 return BAD_MUTEX_E;
Vanger 0:b86d15c6ba29 42
Vanger 0:b86d15c6ba29 43 return 0;
Vanger 0:b86d15c6ba29 44 }
Vanger 0:b86d15c6ba29 45
Vanger 0:b86d15c6ba29 46
Vanger 0:b86d15c6ba29 47 static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
Vanger 0:b86d15c6ba29 48 {
Vanger 0:b86d15c6ba29 49 CYASSL_ENTER("InitOCSP_Entry");
Vanger 0:b86d15c6ba29 50
Vanger 0:b86d15c6ba29 51 XMEMSET(ocspe, 0, sizeof(*ocspe));
Vanger 0:b86d15c6ba29 52 XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 53 XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 54
Vanger 0:b86d15c6ba29 55 return 0;
Vanger 0:b86d15c6ba29 56 }
Vanger 0:b86d15c6ba29 57
Vanger 0:b86d15c6ba29 58
Vanger 0:b86d15c6ba29 59 static void FreeOCSP_Entry(OCSP_Entry* ocspe)
Vanger 0:b86d15c6ba29 60 {
Vanger 0:b86d15c6ba29 61 CertStatus* tmp = ocspe->status;
Vanger 0:b86d15c6ba29 62
Vanger 0:b86d15c6ba29 63 CYASSL_ENTER("FreeOCSP_Entry");
Vanger 0:b86d15c6ba29 64
Vanger 0:b86d15c6ba29 65 while (tmp) {
Vanger 0:b86d15c6ba29 66 CertStatus* next = tmp->next;
Vanger 0:b86d15c6ba29 67 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
Vanger 0:b86d15c6ba29 68 tmp = next;
Vanger 0:b86d15c6ba29 69 }
Vanger 0:b86d15c6ba29 70 }
Vanger 0:b86d15c6ba29 71
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73 void FreeOCSP(CYASSL_OCSP* ocsp, int dynamic)
Vanger 0:b86d15c6ba29 74 {
Vanger 0:b86d15c6ba29 75 OCSP_Entry* tmp = ocsp->ocspList;
Vanger 0:b86d15c6ba29 76
Vanger 0:b86d15c6ba29 77 CYASSL_ENTER("FreeOCSP");
Vanger 0:b86d15c6ba29 78
Vanger 0:b86d15c6ba29 79 while (tmp) {
Vanger 0:b86d15c6ba29 80 OCSP_Entry* next = tmp->next;
Vanger 0:b86d15c6ba29 81 FreeOCSP_Entry(tmp);
Vanger 0:b86d15c6ba29 82 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
Vanger 0:b86d15c6ba29 83 tmp = next;
Vanger 0:b86d15c6ba29 84 }
Vanger 0:b86d15c6ba29 85
Vanger 0:b86d15c6ba29 86 FreeMutex(&ocsp->ocspLock);
Vanger 0:b86d15c6ba29 87 if (dynamic)
Vanger 0:b86d15c6ba29 88 XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
Vanger 0:b86d15c6ba29 89 }
Vanger 0:b86d15c6ba29 90
Vanger 0:b86d15c6ba29 91
Vanger 0:b86d15c6ba29 92 static int xstat2err(int stat)
Vanger 0:b86d15c6ba29 93 {
Vanger 0:b86d15c6ba29 94 switch (stat) {
Vanger 0:b86d15c6ba29 95 case CERT_GOOD:
Vanger 0:b86d15c6ba29 96 return 0;
Vanger 0:b86d15c6ba29 97 case CERT_REVOKED:
Vanger 0:b86d15c6ba29 98 return OCSP_CERT_REVOKED;
Vanger 0:b86d15c6ba29 99 default:
Vanger 0:b86d15c6ba29 100 return OCSP_CERT_UNKNOWN;
Vanger 0:b86d15c6ba29 101 }
Vanger 0:b86d15c6ba29 102 }
Vanger 0:b86d15c6ba29 103
Vanger 0:b86d15c6ba29 104
Vanger 0:b86d15c6ba29 105 int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert)
Vanger 0:b86d15c6ba29 106 {
Vanger 0:b86d15c6ba29 107 byte* ocspReqBuf = NULL;
Vanger 0:b86d15c6ba29 108 int ocspReqSz = 2048;
Vanger 0:b86d15c6ba29 109 byte* ocspRespBuf = NULL;
Vanger 0:b86d15c6ba29 110 int result = -1;
Vanger 0:b86d15c6ba29 111 OCSP_Entry* ocspe;
Vanger 0:b86d15c6ba29 112 CertStatus* certStatus = NULL;
Vanger 0:b86d15c6ba29 113 const char *url;
Vanger 0:b86d15c6ba29 114 int urlSz;
Vanger 0:b86d15c6ba29 115 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 116 CertStatus* newStatus;
Vanger 0:b86d15c6ba29 117 OcspRequest* ocspRequest;
Vanger 0:b86d15c6ba29 118 OcspResponse* ocspResponse;
Vanger 0:b86d15c6ba29 119 #else
Vanger 0:b86d15c6ba29 120 CertStatus newStatus[1];
Vanger 0:b86d15c6ba29 121 OcspRequest ocspRequest[1];
Vanger 0:b86d15c6ba29 122 OcspResponse ocspResponse[1];
Vanger 0:b86d15c6ba29 123 #endif
Vanger 0:b86d15c6ba29 124
Vanger 0:b86d15c6ba29 125 CYASSL_ENTER("CheckCertOCSP");
Vanger 0:b86d15c6ba29 126
Vanger 0:b86d15c6ba29 127 if (LockMutex(&ocsp->ocspLock) != 0) {
Vanger 0:b86d15c6ba29 128 CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
Vanger 0:b86d15c6ba29 129 return BAD_MUTEX_E;
Vanger 0:b86d15c6ba29 130 }
Vanger 0:b86d15c6ba29 131
Vanger 0:b86d15c6ba29 132 ocspe = ocsp->ocspList;
Vanger 0:b86d15c6ba29 133 while (ocspe) {
Vanger 0:b86d15c6ba29 134 if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
Vanger 0:b86d15c6ba29 135 && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
Vanger 0:b86d15c6ba29 136 SHA_DIGEST_SIZE) == 0)
Vanger 0:b86d15c6ba29 137 break;
Vanger 0:b86d15c6ba29 138 else
Vanger 0:b86d15c6ba29 139 ocspe = ocspe->next;
Vanger 0:b86d15c6ba29 140 }
Vanger 0:b86d15c6ba29 141
Vanger 0:b86d15c6ba29 142 if (ocspe == NULL) {
Vanger 0:b86d15c6ba29 143 ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
Vanger 0:b86d15c6ba29 144 NULL, DYNAMIC_TYPE_OCSP_ENTRY);
Vanger 0:b86d15c6ba29 145 if (ocspe != NULL) {
Vanger 0:b86d15c6ba29 146 InitOCSP_Entry(ocspe, cert);
Vanger 0:b86d15c6ba29 147 ocspe->next = ocsp->ocspList;
Vanger 0:b86d15c6ba29 148 ocsp->ocspList = ocspe;
Vanger 0:b86d15c6ba29 149 }
Vanger 0:b86d15c6ba29 150 else {
Vanger 0:b86d15c6ba29 151 UnLockMutex(&ocsp->ocspLock);
Vanger 0:b86d15c6ba29 152 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
Vanger 0:b86d15c6ba29 153 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 154 }
Vanger 0:b86d15c6ba29 155 }
Vanger 0:b86d15c6ba29 156 else {
Vanger 0:b86d15c6ba29 157 certStatus = ocspe->status;
Vanger 0:b86d15c6ba29 158 while (certStatus) {
Vanger 0:b86d15c6ba29 159 if (certStatus->serialSz == cert->serialSz &&
Vanger 0:b86d15c6ba29 160 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
Vanger 0:b86d15c6ba29 161 break;
Vanger 0:b86d15c6ba29 162 else
Vanger 0:b86d15c6ba29 163 certStatus = certStatus->next;
Vanger 0:b86d15c6ba29 164 }
Vanger 0:b86d15c6ba29 165 }
Vanger 0:b86d15c6ba29 166
Vanger 0:b86d15c6ba29 167 if (certStatus != NULL) {
Vanger 0:b86d15c6ba29 168 if (!ValidateDate(certStatus->thisDate,
Vanger 0:b86d15c6ba29 169 certStatus->thisDateFormat, BEFORE) ||
Vanger 0:b86d15c6ba29 170 (certStatus->nextDate[0] == 0) ||
Vanger 0:b86d15c6ba29 171 !ValidateDate(certStatus->nextDate,
Vanger 0:b86d15c6ba29 172 certStatus->nextDateFormat, AFTER)) {
Vanger 0:b86d15c6ba29 173 CYASSL_MSG("\tinvalid status date, looking up cert");
Vanger 0:b86d15c6ba29 174 }
Vanger 0:b86d15c6ba29 175 else {
Vanger 0:b86d15c6ba29 176 result = xstat2err(certStatus->status);
Vanger 0:b86d15c6ba29 177 UnLockMutex(&ocsp->ocspLock);
Vanger 0:b86d15c6ba29 178 CYASSL_LEAVE("CheckCertOCSP", result);
Vanger 0:b86d15c6ba29 179 return result;
Vanger 0:b86d15c6ba29 180 }
Vanger 0:b86d15c6ba29 181 }
Vanger 0:b86d15c6ba29 182
Vanger 0:b86d15c6ba29 183 UnLockMutex(&ocsp->ocspLock);
Vanger 0:b86d15c6ba29 184
Vanger 0:b86d15c6ba29 185 if (ocsp->cm->ocspUseOverrideURL) {
Vanger 0:b86d15c6ba29 186 url = ocsp->cm->ocspOverrideURL;
Vanger 0:b86d15c6ba29 187 if (url != NULL && url[0] != '\0')
Vanger 0:b86d15c6ba29 188 urlSz = (int)XSTRLEN(url);
Vanger 0:b86d15c6ba29 189 else
Vanger 0:b86d15c6ba29 190 return OCSP_NEED_URL;
Vanger 0:b86d15c6ba29 191 }
Vanger 0:b86d15c6ba29 192 else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
Vanger 0:b86d15c6ba29 193 url = (const char *)cert->extAuthInfo;
Vanger 0:b86d15c6ba29 194 urlSz = cert->extAuthInfoSz;
Vanger 0:b86d15c6ba29 195 }
Vanger 0:b86d15c6ba29 196 else {
Vanger 0:b86d15c6ba29 197 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
Vanger 0:b86d15c6ba29 198 return 0;
Vanger 0:b86d15c6ba29 199 }
Vanger 0:b86d15c6ba29 200
Vanger 0:b86d15c6ba29 201 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
Vanger 0:b86d15c6ba29 202 if (ocspReqBuf == NULL) {
Vanger 0:b86d15c6ba29 203 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
Vanger 0:b86d15c6ba29 204 return MEMORY_ERROR;
Vanger 0:b86d15c6ba29 205 }
Vanger 0:b86d15c6ba29 206
Vanger 0:b86d15c6ba29 207 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 208 newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
Vanger 0:b86d15c6ba29 209 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 210 ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
Vanger 0:b86d15c6ba29 211 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 212 ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
Vanger 0:b86d15c6ba29 213 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 214
Vanger 0:b86d15c6ba29 215 if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) {
Vanger 0:b86d15c6ba29 216 if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 217 if (ocspRequest) XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 218 if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 219
Vanger 0:b86d15c6ba29 220 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 221
Vanger 0:b86d15c6ba29 222 CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
Vanger 0:b86d15c6ba29 223 return MEMORY_E;
Vanger 0:b86d15c6ba29 224 }
Vanger 0:b86d15c6ba29 225 #endif
Vanger 0:b86d15c6ba29 226
Vanger 0:b86d15c6ba29 227 InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
Vanger 0:b86d15c6ba29 228 ocspReqBuf, ocspReqSz);
Vanger 0:b86d15c6ba29 229 ocspReqSz = EncodeOcspRequest(ocspRequest);
Vanger 0:b86d15c6ba29 230
Vanger 0:b86d15c6ba29 231 if (ocsp->cm->ocspIOCb)
Vanger 0:b86d15c6ba29 232 result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
Vanger 0:b86d15c6ba29 233 ocspReqBuf, ocspReqSz, &ocspRespBuf);
Vanger 0:b86d15c6ba29 234
Vanger 0:b86d15c6ba29 235 if (result >= 0 && ocspRespBuf) {
Vanger 0:b86d15c6ba29 236 XMEMSET(newStatus, 0, sizeof(CertStatus));
Vanger 0:b86d15c6ba29 237
Vanger 0:b86d15c6ba29 238 InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result);
Vanger 0:b86d15c6ba29 239 OcspResponseDecode(ocspResponse);
Vanger 0:b86d15c6ba29 240
Vanger 0:b86d15c6ba29 241 if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
Vanger 0:b86d15c6ba29 242 result = OCSP_LOOKUP_FAIL;
Vanger 0:b86d15c6ba29 243 else {
Vanger 0:b86d15c6ba29 244 if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
Vanger 0:b86d15c6ba29 245 result = xstat2err(ocspResponse->status->status);
Vanger 0:b86d15c6ba29 246
Vanger 0:b86d15c6ba29 247 if (LockMutex(&ocsp->ocspLock) != 0)
Vanger 0:b86d15c6ba29 248 result = BAD_MUTEX_E;
Vanger 0:b86d15c6ba29 249 else {
Vanger 0:b86d15c6ba29 250 if (certStatus != NULL)
Vanger 0:b86d15c6ba29 251 /* Replace existing certificate entry with updated */
Vanger 0:b86d15c6ba29 252 XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
Vanger 0:b86d15c6ba29 253 else {
Vanger 0:b86d15c6ba29 254 /* Save new certificate entry */
Vanger 0:b86d15c6ba29 255 certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
Vanger 0:b86d15c6ba29 256 NULL, DYNAMIC_TYPE_OCSP_STATUS);
Vanger 0:b86d15c6ba29 257 if (certStatus != NULL) {
Vanger 0:b86d15c6ba29 258 XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
Vanger 0:b86d15c6ba29 259 certStatus->next = ocspe->status;
Vanger 0:b86d15c6ba29 260 ocspe->status = certStatus;
Vanger 0:b86d15c6ba29 261 ocspe->totalStatus++;
Vanger 0:b86d15c6ba29 262 }
Vanger 0:b86d15c6ba29 263 }
Vanger 0:b86d15c6ba29 264
Vanger 0:b86d15c6ba29 265 UnLockMutex(&ocsp->ocspLock);
Vanger 0:b86d15c6ba29 266 }
Vanger 0:b86d15c6ba29 267 }
Vanger 0:b86d15c6ba29 268 else
Vanger 0:b86d15c6ba29 269 result = OCSP_LOOKUP_FAIL;
Vanger 0:b86d15c6ba29 270 }
Vanger 0:b86d15c6ba29 271 }
Vanger 0:b86d15c6ba29 272 else
Vanger 0:b86d15c6ba29 273 result = OCSP_LOOKUP_FAIL;
Vanger 0:b86d15c6ba29 274
Vanger 0:b86d15c6ba29 275 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
Vanger 0:b86d15c6ba29 276
Vanger 0:b86d15c6ba29 277 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 278 XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 279 XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 280 XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 281 #endif
Vanger 0:b86d15c6ba29 282
Vanger 0:b86d15c6ba29 283 if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
Vanger 0:b86d15c6ba29 284 ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);
Vanger 0:b86d15c6ba29 285
Vanger 0:b86d15c6ba29 286 CYASSL_LEAVE("CheckCertOCSP", result);
Vanger 0:b86d15c6ba29 287 return result;
Vanger 0:b86d15c6ba29 288 }
Vanger 0:b86d15c6ba29 289
Vanger 0:b86d15c6ba29 290
Vanger 0:b86d15c6ba29 291 #else /* HAVE_OCSP */
Vanger 0:b86d15c6ba29 292
Vanger 0:b86d15c6ba29 293
Vanger 0:b86d15c6ba29 294 #ifdef _MSC_VER
Vanger 0:b86d15c6ba29 295 /* 4206 warning for blank file */
Vanger 0:b86d15c6ba29 296 #pragma warning(disable: 4206)
Vanger 0:b86d15c6ba29 297 #endif
Vanger 0:b86d15c6ba29 298
Vanger 0:b86d15c6ba29 299
Vanger 0:b86d15c6ba29 300 #endif /* HAVE_OCSP */
Vanger 0:b86d15c6ba29 301