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