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 /* crl.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_CRL
wolfSSL 0:9d17e4342598 29
wolfSSL 0:9d17e4342598 30 #include <cyassl/internal.h>
wolfSSL 0:9d17e4342598 31 #include <cyassl/error-ssl.h>
wolfSSL 0:9d17e4342598 32
wolfSSL 0:9d17e4342598 33 #include <dirent.h>
wolfSSL 0:9d17e4342598 34 #include <sys/stat.h>
wolfSSL 0:9d17e4342598 35 #include <string.h>
wolfSSL 0:9d17e4342598 36
wolfSSL 0:9d17e4342598 37
wolfSSL 0:9d17e4342598 38 /* Initialze CRL members */
wolfSSL 0:9d17e4342598 39 int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm)
wolfSSL 0:9d17e4342598 40 {
wolfSSL 0:9d17e4342598 41 CYASSL_ENTER("InitCRL");
wolfSSL 0:9d17e4342598 42
wolfSSL 0:9d17e4342598 43 crl->cm = cm;
wolfSSL 0:9d17e4342598 44 crl->crlList = NULL;
wolfSSL 0:9d17e4342598 45 crl->monitors[0].path = NULL;
wolfSSL 0:9d17e4342598 46 crl->monitors[1].path = NULL;
wolfSSL 0:9d17e4342598 47 #ifdef HAVE_CRL_MONITOR
wolfSSL 0:9d17e4342598 48 crl->tid = 0;
wolfSSL 0:9d17e4342598 49 #endif
wolfSSL 0:9d17e4342598 50 if (InitMutex(&crl->crlLock) != 0)
wolfSSL 0:9d17e4342598 51 return BAD_MUTEX_E;
wolfSSL 0:9d17e4342598 52
wolfSSL 0:9d17e4342598 53 return 0;
wolfSSL 0:9d17e4342598 54 }
wolfSSL 0:9d17e4342598 55
wolfSSL 0:9d17e4342598 56
wolfSSL 0:9d17e4342598 57 /* Initialze CRL Entry */
wolfSSL 0:9d17e4342598 58 static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
wolfSSL 0:9d17e4342598 59 {
wolfSSL 0:9d17e4342598 60 CYASSL_ENTER("InitCRL_Entry");
wolfSSL 0:9d17e4342598 61
wolfSSL 0:9d17e4342598 62 XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE);
wolfSSL 0:9d17e4342598 63 /* XMEMCPY(crle->crlHash, dcrl->crlHash, SHA_DIGEST_SIZE);
wolfSSL 0:9d17e4342598 64 * copy the hash here if needed for optimized comparisons */
wolfSSL 0:9d17e4342598 65 XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
wolfSSL 0:9d17e4342598 66 XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
wolfSSL 0:9d17e4342598 67 crle->lastDateFormat = dcrl->lastDateFormat;
wolfSSL 0:9d17e4342598 68 crle->nextDateFormat = dcrl->nextDateFormat;
wolfSSL 0:9d17e4342598 69
wolfSSL 0:9d17e4342598 70 crle->certs = dcrl->certs; /* take ownsership */
wolfSSL 0:9d17e4342598 71 dcrl->certs = NULL;
wolfSSL 0:9d17e4342598 72 crle->totalCerts = dcrl->totalCerts;
wolfSSL 0:9d17e4342598 73
wolfSSL 0:9d17e4342598 74 return 0;
wolfSSL 0:9d17e4342598 75 }
wolfSSL 0:9d17e4342598 76
wolfSSL 0:9d17e4342598 77
wolfSSL 0:9d17e4342598 78 /* Free all CRL Entry resources */
wolfSSL 0:9d17e4342598 79 static void FreeCRL_Entry(CRL_Entry* crle)
wolfSSL 0:9d17e4342598 80 {
wolfSSL 0:9d17e4342598 81 RevokedCert* tmp = crle->certs;
wolfSSL 0:9d17e4342598 82
wolfSSL 0:9d17e4342598 83 CYASSL_ENTER("FreeCRL_Entry");
wolfSSL 0:9d17e4342598 84
wolfSSL 0:9d17e4342598 85 while(tmp) {
wolfSSL 0:9d17e4342598 86 RevokedCert* next = tmp->next;
wolfSSL 0:9d17e4342598 87 XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
wolfSSL 0:9d17e4342598 88 tmp = next;
wolfSSL 0:9d17e4342598 89 }
wolfSSL 0:9d17e4342598 90 }
wolfSSL 0:9d17e4342598 91
wolfSSL 0:9d17e4342598 92
wolfSSL 0:9d17e4342598 93
wolfSSL 0:9d17e4342598 94 /* Free all CRL resources */
wolfSSL 0:9d17e4342598 95 void FreeCRL(CYASSL_CRL* crl, int dynamic)
wolfSSL 0:9d17e4342598 96 {
wolfSSL 0:9d17e4342598 97 CRL_Entry* tmp = crl->crlList;
wolfSSL 0:9d17e4342598 98
wolfSSL 0:9d17e4342598 99 CYASSL_ENTER("FreeCRL");
wolfSSL 0:9d17e4342598 100
wolfSSL 0:9d17e4342598 101 if (crl->monitors[0].path)
wolfSSL 0:9d17e4342598 102 XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
wolfSSL 0:9d17e4342598 103
wolfSSL 0:9d17e4342598 104 if (crl->monitors[1].path)
wolfSSL 0:9d17e4342598 105 XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
wolfSSL 0:9d17e4342598 106
wolfSSL 0:9d17e4342598 107 while(tmp) {
wolfSSL 0:9d17e4342598 108 CRL_Entry* next = tmp->next;
wolfSSL 0:9d17e4342598 109 FreeCRL_Entry(tmp);
wolfSSL 0:9d17e4342598 110 XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY);
wolfSSL 0:9d17e4342598 111 tmp = next;
wolfSSL 0:9d17e4342598 112 }
wolfSSL 0:9d17e4342598 113
wolfSSL 0:9d17e4342598 114 #ifdef HAVE_CRL_MONITOR
wolfSSL 0:9d17e4342598 115 if (crl->tid != 0) {
wolfSSL 0:9d17e4342598 116 CYASSL_MSG("Canceling monitor thread");
wolfSSL 0:9d17e4342598 117 pthread_cancel(crl->tid);
wolfSSL 0:9d17e4342598 118 }
wolfSSL 0:9d17e4342598 119 #endif
wolfSSL 0:9d17e4342598 120 FreeMutex(&crl->crlLock);
wolfSSL 0:9d17e4342598 121 if (dynamic) /* free self */
wolfSSL 0:9d17e4342598 122 XFREE(crl, NULL, DYNAMIC_TYPE_CRL);
wolfSSL 0:9d17e4342598 123 }
wolfSSL 0:9d17e4342598 124
wolfSSL 0:9d17e4342598 125
wolfSSL 0:9d17e4342598 126 /* Is the cert ok with CRL, return 0 on success */
wolfSSL 0:9d17e4342598 127 int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
wolfSSL 0:9d17e4342598 128 {
wolfSSL 0:9d17e4342598 129 CRL_Entry* crle;
wolfSSL 0:9d17e4342598 130 int foundEntry = 0;
wolfSSL 0:9d17e4342598 131 int ret = 0;
wolfSSL 0:9d17e4342598 132
wolfSSL 0:9d17e4342598 133 CYASSL_ENTER("CheckCertCRL");
wolfSSL 0:9d17e4342598 134
wolfSSL 0:9d17e4342598 135 if (LockMutex(&crl->crlLock) != 0) {
wolfSSL 0:9d17e4342598 136 CYASSL_MSG("LockMutex failed");
wolfSSL 0:9d17e4342598 137 return BAD_MUTEX_E;
wolfSSL 0:9d17e4342598 138 }
wolfSSL 0:9d17e4342598 139
wolfSSL 0:9d17e4342598 140 crle = crl->crlList;
wolfSSL 0:9d17e4342598 141
wolfSSL 0:9d17e4342598 142 while (crle) {
wolfSSL 0:9d17e4342598 143 if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) {
wolfSSL 0:9d17e4342598 144 CYASSL_MSG("Found CRL Entry on list");
wolfSSL 0:9d17e4342598 145 CYASSL_MSG("Checking next date validity");
wolfSSL 0:9d17e4342598 146
wolfSSL 0:9d17e4342598 147 if (!ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) {
wolfSSL 0:9d17e4342598 148 CYASSL_MSG("CRL next date is no longer valid");
wolfSSL 0:9d17e4342598 149 ret = ASN_AFTER_DATE_E;
wolfSSL 0:9d17e4342598 150 }
wolfSSL 0:9d17e4342598 151 else
wolfSSL 0:9d17e4342598 152 foundEntry = 1;
wolfSSL 0:9d17e4342598 153 break;
wolfSSL 0:9d17e4342598 154 }
wolfSSL 0:9d17e4342598 155 crle = crle->next;
wolfSSL 0:9d17e4342598 156 }
wolfSSL 0:9d17e4342598 157
wolfSSL 0:9d17e4342598 158 if (foundEntry) {
wolfSSL 0:9d17e4342598 159 RevokedCert* rc = crle->certs;
wolfSSL 0:9d17e4342598 160
wolfSSL 0:9d17e4342598 161 while (rc) {
wolfSSL 0:9d17e4342598 162 if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
wolfSSL 0:9d17e4342598 163 CYASSL_MSG("Cert revoked");
wolfSSL 0:9d17e4342598 164 ret = CRL_CERT_REVOKED;
wolfSSL 0:9d17e4342598 165 break;
wolfSSL 0:9d17e4342598 166 }
wolfSSL 0:9d17e4342598 167 rc = rc->next;
wolfSSL 0:9d17e4342598 168 }
wolfSSL 0:9d17e4342598 169 }
wolfSSL 0:9d17e4342598 170
wolfSSL 0:9d17e4342598 171 UnLockMutex(&crl->crlLock);
wolfSSL 0:9d17e4342598 172
wolfSSL 0:9d17e4342598 173 if (foundEntry == 0) {
wolfSSL 0:9d17e4342598 174 CYASSL_MSG("Couldn't find CRL for status check");
wolfSSL 0:9d17e4342598 175 ret = CRL_MISSING;
wolfSSL 0:9d17e4342598 176 if (crl->cm->cbMissingCRL) {
wolfSSL 0:9d17e4342598 177 char url[256];
wolfSSL 0:9d17e4342598 178
wolfSSL 0:9d17e4342598 179 CYASSL_MSG("Issuing missing CRL callback");
wolfSSL 0:9d17e4342598 180 url[0] = '\0';
wolfSSL 0:9d17e4342598 181 if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
wolfSSL 0:9d17e4342598 182 XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
wolfSSL 0:9d17e4342598 183 url[cert->extCrlInfoSz] = '\0';
wolfSSL 0:9d17e4342598 184 }
wolfSSL 0:9d17e4342598 185 else {
wolfSSL 0:9d17e4342598 186 CYASSL_MSG("CRL url too long");
wolfSSL 0:9d17e4342598 187 }
wolfSSL 0:9d17e4342598 188 crl->cm->cbMissingCRL(url);
wolfSSL 0:9d17e4342598 189 }
wolfSSL 0:9d17e4342598 190 }
wolfSSL 0:9d17e4342598 191
wolfSSL 0:9d17e4342598 192
wolfSSL 0:9d17e4342598 193 return ret;
wolfSSL 0:9d17e4342598 194 }
wolfSSL 0:9d17e4342598 195
wolfSSL 0:9d17e4342598 196
wolfSSL 0:9d17e4342598 197 /* Add Decoded CRL, 0 on success */
wolfSSL 0:9d17e4342598 198 static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl)
wolfSSL 0:9d17e4342598 199 {
wolfSSL 0:9d17e4342598 200 CRL_Entry* crle;
wolfSSL 0:9d17e4342598 201
wolfSSL 0:9d17e4342598 202 CYASSL_ENTER("AddCRL");
wolfSSL 0:9d17e4342598 203
wolfSSL 0:9d17e4342598 204 crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
wolfSSL 0:9d17e4342598 205 if (crle == NULL) {
wolfSSL 0:9d17e4342598 206 CYASSL_MSG("alloc CRL Entry failed");
wolfSSL 0:9d17e4342598 207 return -1;
wolfSSL 0:9d17e4342598 208 }
wolfSSL 0:9d17e4342598 209
wolfSSL 0:9d17e4342598 210 if (InitCRL_Entry(crle, dcrl) < 0) {
wolfSSL 0:9d17e4342598 211 CYASSL_MSG("Init CRL Entry failed");
wolfSSL 0:9d17e4342598 212 XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
wolfSSL 0:9d17e4342598 213 return -1;
wolfSSL 0:9d17e4342598 214 }
wolfSSL 0:9d17e4342598 215
wolfSSL 0:9d17e4342598 216 if (LockMutex(&crl->crlLock) != 0) {
wolfSSL 0:9d17e4342598 217 CYASSL_MSG("LockMutex failed");
wolfSSL 0:9d17e4342598 218 FreeCRL_Entry(crle);
wolfSSL 0:9d17e4342598 219 XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
wolfSSL 0:9d17e4342598 220 return BAD_MUTEX_E;
wolfSSL 0:9d17e4342598 221 }
wolfSSL 0:9d17e4342598 222 crle->next = crl->crlList;
wolfSSL 0:9d17e4342598 223 crl->crlList = crle;
wolfSSL 0:9d17e4342598 224 UnLockMutex(&crl->crlLock);
wolfSSL 0:9d17e4342598 225
wolfSSL 0:9d17e4342598 226 return 0;
wolfSSL 0:9d17e4342598 227 }
wolfSSL 0:9d17e4342598 228
wolfSSL 0:9d17e4342598 229
wolfSSL 0:9d17e4342598 230 /* Load CRL File of type, SSL_SUCCESS on ok */
wolfSSL 0:9d17e4342598 231 int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type)
wolfSSL 0:9d17e4342598 232 {
wolfSSL 0:9d17e4342598 233 int ret = SSL_SUCCESS;
wolfSSL 0:9d17e4342598 234 const byte* myBuffer = buff; /* if DER ok, otherwise switch */
wolfSSL 0:9d17e4342598 235 buffer der;
wolfSSL 0:9d17e4342598 236 DecodedCRL dcrl;
wolfSSL 0:9d17e4342598 237
wolfSSL 0:9d17e4342598 238 der.buffer = NULL;
wolfSSL 0:9d17e4342598 239
wolfSSL 0:9d17e4342598 240 CYASSL_ENTER("BufferLoadCRL");
wolfSSL 0:9d17e4342598 241
wolfSSL 0:9d17e4342598 242 if (crl == NULL || buff == NULL || sz == 0)
wolfSSL 0:9d17e4342598 243 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 244
wolfSSL 0:9d17e4342598 245 if (type == SSL_FILETYPE_PEM) {
wolfSSL 0:9d17e4342598 246 int eccKey = 0; /* not used */
wolfSSL 0:9d17e4342598 247 EncryptedInfo info;
wolfSSL 0:9d17e4342598 248 info.ctx = NULL;
wolfSSL 0:9d17e4342598 249
wolfSSL 0:9d17e4342598 250 ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
wolfSSL 0:9d17e4342598 251 if (ret == 0) {
wolfSSL 0:9d17e4342598 252 myBuffer = der.buffer;
wolfSSL 0:9d17e4342598 253 sz = der.length;
wolfSSL 0:9d17e4342598 254 }
wolfSSL 0:9d17e4342598 255 else {
wolfSSL 0:9d17e4342598 256 CYASSL_MSG("Pem to Der failed");
wolfSSL 0:9d17e4342598 257 return -1;
wolfSSL 0:9d17e4342598 258 }
wolfSSL 0:9d17e4342598 259 }
wolfSSL 0:9d17e4342598 260
wolfSSL 0:9d17e4342598 261 InitDecodedCRL(&dcrl);
wolfSSL 0:9d17e4342598 262 ret = ParseCRL(&dcrl, myBuffer, (word32)sz, crl->cm);
wolfSSL 0:9d17e4342598 263 if (ret != 0) {
wolfSSL 0:9d17e4342598 264 CYASSL_MSG("ParseCRL error");
wolfSSL 0:9d17e4342598 265 }
wolfSSL 0:9d17e4342598 266 else {
wolfSSL 0:9d17e4342598 267 ret = AddCRL(crl, &dcrl);
wolfSSL 0:9d17e4342598 268 if (ret != 0) {
wolfSSL 0:9d17e4342598 269 CYASSL_MSG("AddCRL error");
wolfSSL 0:9d17e4342598 270 }
wolfSSL 0:9d17e4342598 271 }
wolfSSL 0:9d17e4342598 272 FreeDecodedCRL(&dcrl);
wolfSSL 0:9d17e4342598 273
wolfSSL 0:9d17e4342598 274 if (der.buffer)
wolfSSL 0:9d17e4342598 275 XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
wolfSSL 0:9d17e4342598 276
wolfSSL 0:9d17e4342598 277 if (ret == 0)
wolfSSL 0:9d17e4342598 278 return SSL_SUCCESS; /* convert */
wolfSSL 0:9d17e4342598 279 return ret;
wolfSSL 0:9d17e4342598 280 }
wolfSSL 0:9d17e4342598 281
wolfSSL 0:9d17e4342598 282
wolfSSL 0:9d17e4342598 283 #ifdef HAVE_CRL_MONITOR
wolfSSL 0:9d17e4342598 284
wolfSSL 0:9d17e4342598 285
wolfSSL 0:9d17e4342598 286 /* read in new CRL entries and save new list */
wolfSSL 0:9d17e4342598 287 static int SwapLists(CYASSL_CRL* crl)
wolfSSL 0:9d17e4342598 288 {
wolfSSL 0:9d17e4342598 289 int ret;
wolfSSL 0:9d17e4342598 290 CYASSL_CRL tmp;
wolfSSL 0:9d17e4342598 291 CRL_Entry* newList;
wolfSSL 0:9d17e4342598 292
wolfSSL 0:9d17e4342598 293 if (InitCRL(&tmp, crl->cm) < 0) {
wolfSSL 0:9d17e4342598 294 CYASSL_MSG("Init tmp CRL failed");
wolfSSL 0:9d17e4342598 295 return -1;
wolfSSL 0:9d17e4342598 296 }
wolfSSL 0:9d17e4342598 297
wolfSSL 0:9d17e4342598 298 if (crl->monitors[0].path) {
wolfSSL 0:9d17e4342598 299 ret = LoadCRL(&tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
wolfSSL 0:9d17e4342598 300 if (ret != SSL_SUCCESS) {
wolfSSL 0:9d17e4342598 301 CYASSL_MSG("PEM LoadCRL on dir change failed");
wolfSSL 0:9d17e4342598 302 FreeCRL(&tmp, 0);
wolfSSL 0:9d17e4342598 303 return -1;
wolfSSL 0:9d17e4342598 304 }
wolfSSL 0:9d17e4342598 305 }
wolfSSL 0:9d17e4342598 306
wolfSSL 0:9d17e4342598 307 if (crl->monitors[1].path) {
wolfSSL 0:9d17e4342598 308 ret = LoadCRL(&tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
wolfSSL 0:9d17e4342598 309 if (ret != SSL_SUCCESS) {
wolfSSL 0:9d17e4342598 310 CYASSL_MSG("DER LoadCRL on dir change failed");
wolfSSL 0:9d17e4342598 311 FreeCRL(&tmp, 0);
wolfSSL 0:9d17e4342598 312 return -1;
wolfSSL 0:9d17e4342598 313 }
wolfSSL 0:9d17e4342598 314 }
wolfSSL 0:9d17e4342598 315
wolfSSL 0:9d17e4342598 316 if (LockMutex(&crl->crlLock) != 0) {
wolfSSL 0:9d17e4342598 317 CYASSL_MSG("LockMutex failed");
wolfSSL 0:9d17e4342598 318 FreeCRL(&tmp, 0);
wolfSSL 0:9d17e4342598 319 return -1;
wolfSSL 0:9d17e4342598 320 }
wolfSSL 0:9d17e4342598 321
wolfSSL 0:9d17e4342598 322 newList = tmp.crlList;
wolfSSL 0:9d17e4342598 323
wolfSSL 0:9d17e4342598 324 /* swap lists */
wolfSSL 0:9d17e4342598 325 tmp.crlList = crl->crlList;
wolfSSL 0:9d17e4342598 326 crl->crlList = newList;
wolfSSL 0:9d17e4342598 327
wolfSSL 0:9d17e4342598 328 UnLockMutex(&crl->crlLock);
wolfSSL 0:9d17e4342598 329
wolfSSL 0:9d17e4342598 330 FreeCRL(&tmp, 0);
wolfSSL 0:9d17e4342598 331
wolfSSL 0:9d17e4342598 332 return 0;
wolfSSL 0:9d17e4342598 333 }
wolfSSL 0:9d17e4342598 334
wolfSSL 0:9d17e4342598 335
wolfSSL 0:9d17e4342598 336 #if (defined(__MACH__) || defined(__FreeBSD__))
wolfSSL 0:9d17e4342598 337
wolfSSL 0:9d17e4342598 338 #include <sys/types.h>
wolfSSL 0:9d17e4342598 339 #include <sys/event.h>
wolfSSL 0:9d17e4342598 340 #include <sys/time.h>
wolfSSL 0:9d17e4342598 341 #include <fcntl.h>
wolfSSL 0:9d17e4342598 342
wolfSSL 0:9d17e4342598 343 #ifdef __MACH__
wolfSSL 0:9d17e4342598 344 #define XEVENT_MODE O_EVTONLY
wolfSSL 0:9d17e4342598 345 #elif defined(__FreeBSD__)
wolfSSL 0:9d17e4342598 346 #define XEVENT_MODE EVFILT_VNODE
wolfSSL 0:9d17e4342598 347 #endif
wolfSSL 0:9d17e4342598 348
wolfSSL 0:9d17e4342598 349
wolfSSL 0:9d17e4342598 350 /* OS X monitoring */
wolfSSL 0:9d17e4342598 351 static void* DoMonitor(void* arg)
wolfSSL 0:9d17e4342598 352 {
wolfSSL 0:9d17e4342598 353 int fPEM, fDER, kq;
wolfSSL 0:9d17e4342598 354 struct kevent change;
wolfSSL 0:9d17e4342598 355
wolfSSL 0:9d17e4342598 356 CYASSL_CRL* crl = (CYASSL_CRL*)arg;
wolfSSL 0:9d17e4342598 357
wolfSSL 0:9d17e4342598 358 CYASSL_ENTER("DoMonitor");
wolfSSL 0:9d17e4342598 359
wolfSSL 0:9d17e4342598 360 kq = kqueue();
wolfSSL 0:9d17e4342598 361 if (kq == -1) {
wolfSSL 0:9d17e4342598 362 CYASSL_MSG("kqueue failed");
wolfSSL 0:9d17e4342598 363 return NULL;
wolfSSL 0:9d17e4342598 364 }
wolfSSL 0:9d17e4342598 365
wolfSSL 0:9d17e4342598 366 fPEM = -1;
wolfSSL 0:9d17e4342598 367 fDER = -1;
wolfSSL 0:9d17e4342598 368
wolfSSL 0:9d17e4342598 369 if (crl->monitors[0].path) {
wolfSSL 0:9d17e4342598 370 fPEM = open(crl->monitors[0].path, XEVENT_MODE);
wolfSSL 0:9d17e4342598 371 if (fPEM == -1) {
wolfSSL 0:9d17e4342598 372 CYASSL_MSG("PEM event dir open failed");
wolfSSL 0:9d17e4342598 373 return NULL;
wolfSSL 0:9d17e4342598 374 }
wolfSSL 0:9d17e4342598 375 }
wolfSSL 0:9d17e4342598 376
wolfSSL 0:9d17e4342598 377 if (crl->monitors[1].path) {
wolfSSL 0:9d17e4342598 378 fDER = open(crl->monitors[1].path, XEVENT_MODE);
wolfSSL 0:9d17e4342598 379 if (fDER == -1) {
wolfSSL 0:9d17e4342598 380 CYASSL_MSG("DER event dir open failed");
wolfSSL 0:9d17e4342598 381 return NULL;
wolfSSL 0:9d17e4342598 382 }
wolfSSL 0:9d17e4342598 383 }
wolfSSL 0:9d17e4342598 384
wolfSSL 0:9d17e4342598 385 if (fPEM != -1)
wolfSSL 0:9d17e4342598 386 EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
wolfSSL 0:9d17e4342598 387 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
wolfSSL 0:9d17e4342598 388
wolfSSL 0:9d17e4342598 389 if (fDER != -1)
wolfSSL 0:9d17e4342598 390 EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
wolfSSL 0:9d17e4342598 391 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
wolfSSL 0:9d17e4342598 392
wolfSSL 0:9d17e4342598 393 for (;;) {
wolfSSL 0:9d17e4342598 394 struct kevent event;
wolfSSL 0:9d17e4342598 395 int numEvents = kevent(kq, &change, 1, &event, 1, NULL);
wolfSSL 0:9d17e4342598 396
wolfSSL 0:9d17e4342598 397 CYASSL_MSG("Got kevent");
wolfSSL 0:9d17e4342598 398
wolfSSL 0:9d17e4342598 399 if (numEvents == -1) {
wolfSSL 0:9d17e4342598 400 CYASSL_MSG("kevent problem, continue");
wolfSSL 0:9d17e4342598 401 continue;
wolfSSL 0:9d17e4342598 402 }
wolfSSL 0:9d17e4342598 403
wolfSSL 0:9d17e4342598 404 if (SwapLists(crl) < 0) {
wolfSSL 0:9d17e4342598 405 CYASSL_MSG("SwapLists problem, continue");
wolfSSL 0:9d17e4342598 406 }
wolfSSL 0:9d17e4342598 407 }
wolfSSL 0:9d17e4342598 408
wolfSSL 0:9d17e4342598 409 return NULL;
wolfSSL 0:9d17e4342598 410 }
wolfSSL 0:9d17e4342598 411
wolfSSL 0:9d17e4342598 412
wolfSSL 0:9d17e4342598 413 #elif defined(__linux__)
wolfSSL 0:9d17e4342598 414
wolfSSL 0:9d17e4342598 415 #include <sys/types.h>
wolfSSL 0:9d17e4342598 416 #include <sys/inotify.h>
wolfSSL 0:9d17e4342598 417 #include <unistd.h>
wolfSSL 0:9d17e4342598 418
wolfSSL 0:9d17e4342598 419 /* linux monitoring */
wolfSSL 0:9d17e4342598 420 static void* DoMonitor(void* arg)
wolfSSL 0:9d17e4342598 421 {
wolfSSL 0:9d17e4342598 422 int notifyFd;
wolfSSL 0:9d17e4342598 423 int wd;
wolfSSL 0:9d17e4342598 424 CYASSL_CRL* crl = (CYASSL_CRL*)arg;
wolfSSL 0:9d17e4342598 425
wolfSSL 0:9d17e4342598 426 CYASSL_ENTER("DoMonitor");
wolfSSL 0:9d17e4342598 427
wolfSSL 0:9d17e4342598 428 notifyFd = inotify_init();
wolfSSL 0:9d17e4342598 429 if (notifyFd < 0) {
wolfSSL 0:9d17e4342598 430 CYASSL_MSG("inotify failed");
wolfSSL 0:9d17e4342598 431 return NULL;
wolfSSL 0:9d17e4342598 432 }
wolfSSL 0:9d17e4342598 433
wolfSSL 0:9d17e4342598 434 if (crl->monitors[0].path) {
wolfSSL 0:9d17e4342598 435 wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
wolfSSL 0:9d17e4342598 436 IN_DELETE);
wolfSSL 0:9d17e4342598 437 if (wd < 0) {
wolfSSL 0:9d17e4342598 438 CYASSL_MSG("PEM notify add watch failed");
wolfSSL 0:9d17e4342598 439 return NULL;
wolfSSL 0:9d17e4342598 440 }
wolfSSL 0:9d17e4342598 441 }
wolfSSL 0:9d17e4342598 442
wolfSSL 0:9d17e4342598 443 if (crl->monitors[1].path) {
wolfSSL 0:9d17e4342598 444 wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
wolfSSL 0:9d17e4342598 445 IN_DELETE);
wolfSSL 0:9d17e4342598 446 if (wd < 0) {
wolfSSL 0:9d17e4342598 447 CYASSL_MSG("DER notify add watch failed");
wolfSSL 0:9d17e4342598 448 return NULL;
wolfSSL 0:9d17e4342598 449 }
wolfSSL 0:9d17e4342598 450 }
wolfSSL 0:9d17e4342598 451
wolfSSL 0:9d17e4342598 452 for (;;) {
wolfSSL 0:9d17e4342598 453 char buff[8192];
wolfSSL 0:9d17e4342598 454 int length = read(notifyFd, buff, sizeof(buff));
wolfSSL 0:9d17e4342598 455
wolfSSL 0:9d17e4342598 456 CYASSL_MSG("Got notify event");
wolfSSL 0:9d17e4342598 457
wolfSSL 0:9d17e4342598 458 if (length < 0) {
wolfSSL 0:9d17e4342598 459 CYASSL_MSG("notify read problem, continue");
wolfSSL 0:9d17e4342598 460 continue;
wolfSSL 0:9d17e4342598 461 }
wolfSSL 0:9d17e4342598 462
wolfSSL 0:9d17e4342598 463 if (SwapLists(crl) < 0) {
wolfSSL 0:9d17e4342598 464 CYASSL_MSG("SwapLists problem, continue");
wolfSSL 0:9d17e4342598 465 }
wolfSSL 0:9d17e4342598 466 }
wolfSSL 0:9d17e4342598 467
wolfSSL 0:9d17e4342598 468 return NULL;
wolfSSL 0:9d17e4342598 469 }
wolfSSL 0:9d17e4342598 470
wolfSSL 0:9d17e4342598 471
wolfSSL 0:9d17e4342598 472 #else
wolfSSL 0:9d17e4342598 473
wolfSSL 0:9d17e4342598 474 #error "CRL monitor only currently supported on linux or mach"
wolfSSL 0:9d17e4342598 475
wolfSSL 0:9d17e4342598 476 #endif /* MACH or linux */
wolfSSL 0:9d17e4342598 477
wolfSSL 0:9d17e4342598 478
wolfSSL 0:9d17e4342598 479 /* Start Monitoring the CRL path(s) in a thread */
wolfSSL 0:9d17e4342598 480 static int StartMonitorCRL(CYASSL_CRL* crl)
wolfSSL 0:9d17e4342598 481 {
wolfSSL 0:9d17e4342598 482 pthread_attr_t attr;
wolfSSL 0:9d17e4342598 483
wolfSSL 0:9d17e4342598 484 CYASSL_ENTER("StartMonitorCRL");
wolfSSL 0:9d17e4342598 485
wolfSSL 0:9d17e4342598 486 if (crl == NULL)
wolfSSL 0:9d17e4342598 487 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 488
wolfSSL 0:9d17e4342598 489 if (crl->tid != 0) {
wolfSSL 0:9d17e4342598 490 CYASSL_MSG("Monitor thread already running");
wolfSSL 0:9d17e4342598 491 return MONITOR_RUNNING_E;
wolfSSL 0:9d17e4342598 492 }
wolfSSL 0:9d17e4342598 493
wolfSSL 0:9d17e4342598 494 pthread_attr_init(&attr);
wolfSSL 0:9d17e4342598 495
wolfSSL 0:9d17e4342598 496 if (pthread_create(&crl->tid, &attr, DoMonitor, crl) != 0) {
wolfSSL 0:9d17e4342598 497 CYASSL_MSG("Thread creation error");
wolfSSL 0:9d17e4342598 498 return THREAD_CREATE_E;
wolfSSL 0:9d17e4342598 499 }
wolfSSL 0:9d17e4342598 500
wolfSSL 0:9d17e4342598 501 return SSL_SUCCESS;
wolfSSL 0:9d17e4342598 502 }
wolfSSL 0:9d17e4342598 503
wolfSSL 0:9d17e4342598 504
wolfSSL 0:9d17e4342598 505 #else /* HAVE_CRL_MONITOR */
wolfSSL 0:9d17e4342598 506
wolfSSL 0:9d17e4342598 507 static int StartMonitorCRL(CYASSL_CRL* crl)
wolfSSL 0:9d17e4342598 508 {
wolfSSL 0:9d17e4342598 509 (void)crl;
wolfSSL 0:9d17e4342598 510
wolfSSL 0:9d17e4342598 511 CYASSL_ENTER("StartMonitorCRL");
wolfSSL 0:9d17e4342598 512 CYASSL_MSG("Not compiled in");
wolfSSL 0:9d17e4342598 513
wolfSSL 0:9d17e4342598 514 return NOT_COMPILED_IN;
wolfSSL 0:9d17e4342598 515 }
wolfSSL 0:9d17e4342598 516
wolfSSL 0:9d17e4342598 517 #endif /* HAVE_CRL_MONITOR */
wolfSSL 0:9d17e4342598 518
wolfSSL 0:9d17e4342598 519
wolfSSL 0:9d17e4342598 520 /* Load CRL path files of type, SSL_SUCCESS on ok */
wolfSSL 0:9d17e4342598 521 int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
wolfSSL 0:9d17e4342598 522 {
wolfSSL 0:9d17e4342598 523 struct dirent* entry;
wolfSSL 0:9d17e4342598 524 DIR* dir;
wolfSSL 0:9d17e4342598 525 int ret = SSL_SUCCESS;
wolfSSL 0:9d17e4342598 526
wolfSSL 0:9d17e4342598 527 CYASSL_ENTER("LoadCRL");
wolfSSL 0:9d17e4342598 528 if (crl == NULL)
wolfSSL 0:9d17e4342598 529 return BAD_FUNC_ARG;
wolfSSL 0:9d17e4342598 530
wolfSSL 0:9d17e4342598 531 dir = opendir(path);
wolfSSL 0:9d17e4342598 532 if (dir == NULL) {
wolfSSL 0:9d17e4342598 533 CYASSL_MSG("opendir path crl load failed");
wolfSSL 0:9d17e4342598 534 return BAD_PATH_ERROR;
wolfSSL 0:9d17e4342598 535 }
wolfSSL 0:9d17e4342598 536 while ( (entry = readdir(dir)) != NULL) {
wolfSSL 0:9d17e4342598 537 char name[MAX_FILENAME_SZ];
wolfSSL 0:9d17e4342598 538 struct stat s;
wolfSSL 0:9d17e4342598 539
wolfSSL 0:9d17e4342598 540 XMEMSET(name, 0, sizeof(name));
wolfSSL 0:9d17e4342598 541 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
wolfSSL 0:9d17e4342598 542 XSTRNCAT(name, "/", 1);
wolfSSL 0:9d17e4342598 543 XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
wolfSSL 0:9d17e4342598 544
wolfSSL 0:9d17e4342598 545 if (stat(name, &s) != 0) {
wolfSSL 0:9d17e4342598 546 CYASSL_MSG("stat on name failed");
wolfSSL 0:9d17e4342598 547 continue;
wolfSSL 0:9d17e4342598 548 }
wolfSSL 0:9d17e4342598 549 if (s.st_mode & S_IFREG) {
wolfSSL 0:9d17e4342598 550
wolfSSL 0:9d17e4342598 551 if (type == SSL_FILETYPE_PEM) {
wolfSSL 0:9d17e4342598 552 if (strstr(entry->d_name, ".pem") == NULL) {
wolfSSL 0:9d17e4342598 553 CYASSL_MSG("not .pem file, skipping");
wolfSSL 0:9d17e4342598 554 continue;
wolfSSL 0:9d17e4342598 555 }
wolfSSL 0:9d17e4342598 556 }
wolfSSL 0:9d17e4342598 557 else {
wolfSSL 0:9d17e4342598 558 if (strstr(entry->d_name, ".der") == NULL &&
wolfSSL 0:9d17e4342598 559 strstr(entry->d_name, ".crl") == NULL) {
wolfSSL 0:9d17e4342598 560
wolfSSL 0:9d17e4342598 561 CYASSL_MSG("not .der or .crl file, skipping");
wolfSSL 0:9d17e4342598 562 continue;
wolfSSL 0:9d17e4342598 563 }
wolfSSL 0:9d17e4342598 564 }
wolfSSL 0:9d17e4342598 565
wolfSSL 0:9d17e4342598 566 if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
wolfSSL 0:9d17e4342598 567 != SSL_SUCCESS) {
wolfSSL 0:9d17e4342598 568 CYASSL_MSG("CRL file load failed, continuing");
wolfSSL 0:9d17e4342598 569 }
wolfSSL 0:9d17e4342598 570 }
wolfSSL 0:9d17e4342598 571 }
wolfSSL 0:9d17e4342598 572
wolfSSL 0:9d17e4342598 573 if (monitor & CYASSL_CRL_MONITOR) {
wolfSSL 0:9d17e4342598 574 CYASSL_MSG("monitor path requested");
wolfSSL 0:9d17e4342598 575
wolfSSL 0:9d17e4342598 576 if (type == SSL_FILETYPE_PEM) {
wolfSSL 0:9d17e4342598 577 crl->monitors[0].path = strdup(path);
wolfSSL 0:9d17e4342598 578 crl->monitors[0].type = SSL_FILETYPE_PEM;
wolfSSL 0:9d17e4342598 579 if (crl->monitors[0].path == NULL)
wolfSSL 0:9d17e4342598 580 ret = MEMORY_E;
wolfSSL 0:9d17e4342598 581 } else {
wolfSSL 0:9d17e4342598 582 crl->monitors[1].path = strdup(path);
wolfSSL 0:9d17e4342598 583 crl->monitors[1].type = SSL_FILETYPE_ASN1;
wolfSSL 0:9d17e4342598 584 if (crl->monitors[1].path == NULL)
wolfSSL 0:9d17e4342598 585 ret = MEMORY_E;
wolfSSL 0:9d17e4342598 586 }
wolfSSL 0:9d17e4342598 587
wolfSSL 0:9d17e4342598 588 if (monitor & CYASSL_CRL_START_MON) {
wolfSSL 0:9d17e4342598 589 CYASSL_MSG("start monitoring requested");
wolfSSL 0:9d17e4342598 590
wolfSSL 0:9d17e4342598 591 ret = StartMonitorCRL(crl);
wolfSSL 0:9d17e4342598 592 }
wolfSSL 0:9d17e4342598 593 }
wolfSSL 0:9d17e4342598 594
wolfSSL 0:9d17e4342598 595 closedir(dir);
wolfSSL 0:9d17e4342598 596
wolfSSL 0:9d17e4342598 597 return ret;
wolfSSL 0:9d17e4342598 598 }
wolfSSL 0:9d17e4342598 599
wolfSSL 0:9d17e4342598 600 #endif /* HAVE_CRL */