CyaSSL 3.0.0

Dependents:   HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more

Committer:
wolfSSL
Date:
Wed Dec 03 05:24:18 2014 +0000
Revision:
3:64d4f7cb83d5
Parent:
0:1239e9b70ca2
added IGNORE_KEY_EXTENSIONS

Who changed what in which revision?

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