cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

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