SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

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