fork of cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Committer:
feb11
Date:
Mon Sep 16 09:53:35 2013 +0000
Revision:
4:f377303c41be
Parent:
0:714293de3836
changed settings

Who changed what in which revision?

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