Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
crl.c
00001 /* crl.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 /* Name change compatibility layer no longer needs included here */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 #include <wolfssl/wolfcrypt/settings.h> 00030 00031 #ifndef WOLFCRYPT_ONLY 00032 #ifdef HAVE_CRL 00033 00034 #include <wolfssl/internal.h> 00035 #include <wolfssl/error-ssl.h> 00036 00037 #ifndef NO_FILESYSTEM 00038 #include <dirent.h> 00039 #include <sys/stat.h> 00040 #endif 00041 00042 #include <string.h> 00043 00044 #ifdef HAVE_CRL_MONITOR 00045 static int StopMonitor(int mfd); 00046 #endif 00047 00048 00049 /* Initialize CRL members */ 00050 int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm) 00051 { 00052 WOLFSSL_ENTER("InitCRL"); 00053 00054 crl->cm = cm; 00055 crl->crlList = NULL; 00056 crl->monitors[0].path = NULL; 00057 crl->monitors[1].path = NULL; 00058 #ifdef HAVE_CRL_MONITOR 00059 crl->tid = 0; 00060 crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */ 00061 crl->setup = 0; /* thread setup done predicate */ 00062 if (pthread_cond_init(&crl->cond, 0) != 0) { 00063 WOLFSSL_MSG("Pthread condition init failed"); 00064 return BAD_COND_E; 00065 } 00066 #endif 00067 if (InitMutex(&crl->crlLock) != 0) { 00068 WOLFSSL_MSG("Init Mutex failed"); 00069 return BAD_MUTEX_E; 00070 } 00071 00072 return 0; 00073 } 00074 00075 00076 /* Initialize CRL Entry */ 00077 static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl) 00078 { 00079 WOLFSSL_ENTER("InitCRL_Entry"); 00080 00081 XMEMCPY(crle->issuerHash, dcrl->issuerHash, CRL_DIGEST_SIZE); 00082 /* XMEMCPY(crle->crlHash, dcrl->crlHash, CRL_DIGEST_SIZE); 00083 * copy the hash here if needed for optimized comparisons */ 00084 XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE); 00085 XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE); 00086 crle->lastDateFormat = dcrl->lastDateFormat; 00087 crle->nextDateFormat = dcrl->nextDateFormat; 00088 00089 crle->certs = dcrl->certs; /* take ownsership */ 00090 dcrl->certs = NULL; 00091 crle->totalCerts = dcrl->totalCerts; 00092 00093 return 0; 00094 } 00095 00096 00097 /* Free all CRL Entry resources */ 00098 static void FreeCRL_Entry(CRL_Entry* crle) 00099 { 00100 RevokedCert* tmp = crle->certs; 00101 00102 WOLFSSL_ENTER("FreeCRL_Entry"); 00103 00104 while(tmp) { 00105 RevokedCert* next = tmp->next; 00106 XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); 00107 tmp = next; 00108 } 00109 } 00110 00111 00112 00113 /* Free all CRL resources */ 00114 void FreeCRL(WOLFSSL_CRL* crl, int dynamic) 00115 { 00116 CRL_Entry* tmp = crl->crlList; 00117 00118 WOLFSSL_ENTER("FreeCRL"); 00119 00120 if (crl->monitors[0].path) 00121 XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR); 00122 00123 if (crl->monitors[1].path) 00124 XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR); 00125 00126 while(tmp) { 00127 CRL_Entry* next = tmp->next; 00128 FreeCRL_Entry(tmp); 00129 XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY); 00130 tmp = next; 00131 } 00132 00133 #ifdef HAVE_CRL_MONITOR 00134 if (crl->tid != 0) { 00135 WOLFSSL_MSG("stopping monitor thread"); 00136 if (StopMonitor(crl->mfd) == 0) 00137 pthread_join(crl->tid, NULL); 00138 else { 00139 WOLFSSL_MSG("stop monitor failed"); 00140 } 00141 } 00142 pthread_cond_destroy(&crl->cond); 00143 #endif 00144 FreeMutex(&crl->crlLock); 00145 if (dynamic) /* free self */ 00146 XFREE(crl, NULL, DYNAMIC_TYPE_CRL); 00147 } 00148 00149 00150 /* Is the cert ok with CRL, return 0 on success */ 00151 int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) 00152 { 00153 CRL_Entry* crle; 00154 int foundEntry = 0; 00155 int ret = 0; 00156 00157 WOLFSSL_ENTER("CheckCertCRL"); 00158 00159 if (LockMutex(&crl->crlLock) != 0) { 00160 WOLFSSL_MSG("LockMutex failed"); 00161 return BAD_MUTEX_E; 00162 } 00163 00164 crle = crl->crlList; 00165 00166 while (crle) { 00167 if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) { 00168 int doNextDate = 1; 00169 00170 WOLFSSL_MSG("Found CRL Entry on list"); 00171 WOLFSSL_MSG("Checking next date validity"); 00172 00173 #ifdef WOLFSSL_NO_CRL_NEXT_DATE 00174 if (crle->nextDateFormat == ASN_OTHER_TYPE) 00175 doNextDate = 0; /* skip */ 00176 #endif 00177 00178 if (doNextDate && !ValidateDate(crle->nextDate, 00179 crle->nextDateFormat, AFTER)) { 00180 WOLFSSL_MSG("CRL next date is no longer valid"); 00181 ret = ASN_AFTER_DATE_E; 00182 } 00183 else 00184 foundEntry = 1; 00185 break; 00186 } 00187 crle = crle->next; 00188 } 00189 00190 if (foundEntry) { 00191 RevokedCert* rc = crle->certs; 00192 00193 while (rc) { 00194 if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) { 00195 WOLFSSL_MSG("Cert revoked"); 00196 ret = CRL_CERT_REVOKED; 00197 break; 00198 } 00199 rc = rc->next; 00200 } 00201 } 00202 00203 UnLockMutex(&crl->crlLock); 00204 00205 if (foundEntry == 0) { 00206 WOLFSSL_MSG("Couldn't find CRL for status check"); 00207 ret = CRL_MISSING; 00208 if (crl->cm->cbMissingCRL) { 00209 char url[256]; 00210 00211 WOLFSSL_MSG("Issuing missing CRL callback"); 00212 url[0] = '\0'; 00213 if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) { 00214 XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz); 00215 url[cert->extCrlInfoSz] = '\0'; 00216 } 00217 else { 00218 WOLFSSL_MSG("CRL url too long"); 00219 } 00220 crl->cm->cbMissingCRL(url); 00221 } 00222 } 00223 00224 00225 return ret; 00226 } 00227 00228 00229 /* Add Decoded CRL, 0 on success */ 00230 static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl) 00231 { 00232 CRL_Entry* crle; 00233 00234 WOLFSSL_ENTER("AddCRL"); 00235 00236 crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY); 00237 if (crle == NULL) { 00238 WOLFSSL_MSG("alloc CRL Entry failed"); 00239 return -1; 00240 } 00241 00242 if (InitCRL_Entry(crle, dcrl) < 0) { 00243 WOLFSSL_MSG("Init CRL Entry failed"); 00244 XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY); 00245 return -1; 00246 } 00247 00248 if (LockMutex(&crl->crlLock) != 0) { 00249 WOLFSSL_MSG("LockMutex failed"); 00250 FreeCRL_Entry(crle); 00251 XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY); 00252 return BAD_MUTEX_E; 00253 } 00254 crle->next = crl->crlList; 00255 crl->crlList = crle; 00256 UnLockMutex(&crl->crlLock); 00257 00258 return 0; 00259 } 00260 00261 00262 /* Load CRL File of type, SSL_SUCCESS on ok */ 00263 int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type) 00264 { 00265 int ret = SSL_SUCCESS; 00266 const byte* myBuffer = buff; /* if DER ok, otherwise switch */ 00267 DerBuffer* der = NULL; 00268 #ifdef WOLFSSL_SMALL_STACK 00269 DecodedCRL* dcrl; 00270 #else 00271 DecodedCRL dcrl[1]; 00272 #endif 00273 00274 WOLFSSL_ENTER("BufferLoadCRL"); 00275 00276 if (crl == NULL || buff == NULL || sz == 0) 00277 return BAD_FUNC_ARG; 00278 00279 if (type == SSL_FILETYPE_PEM) { 00280 int eccKey = 0; /* not used */ 00281 EncryptedInfo info; 00282 info.ctx = NULL; 00283 00284 ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey); 00285 if (ret == 0) { 00286 myBuffer = der->buffer; 00287 sz = der->length; 00288 } 00289 else { 00290 WOLFSSL_MSG("Pem to Der failed"); 00291 FreeDer(&der); 00292 return -1; 00293 } 00294 } 00295 00296 #ifdef WOLFSSL_SMALL_STACK 00297 dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00298 if (dcrl == NULL) { 00299 FreeDer(&der); 00300 return MEMORY_E; 00301 } 00302 #endif 00303 00304 InitDecodedCRL(dcrl); 00305 ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm); 00306 if (ret != 0) { 00307 WOLFSSL_MSG("ParseCRL error"); 00308 } 00309 else { 00310 ret = AddCRL(crl, dcrl); 00311 if (ret != 0) { 00312 WOLFSSL_MSG("AddCRL error"); 00313 } 00314 } 00315 00316 FreeDecodedCRL(dcrl); 00317 00318 #ifdef WOLFSSL_SMALL_STACK 00319 XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00320 #endif 00321 00322 FreeDer(&der); 00323 00324 return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */ 00325 } 00326 00327 00328 #ifdef HAVE_CRL_MONITOR 00329 00330 00331 /* Signal Monitor thread is setup, save status to setup flag, 0 on success */ 00332 static int SignalSetup(WOLFSSL_CRL* crl, int status) 00333 { 00334 int ret; 00335 00336 /* signal to calling thread we're setup */ 00337 if (LockMutex(&crl->crlLock) != 0) { 00338 WOLFSSL_MSG("LockMutex crlLock failed"); 00339 return BAD_MUTEX_E; 00340 } 00341 00342 crl->setup = status; 00343 ret = pthread_cond_signal(&crl->cond); 00344 00345 UnLockMutex(&crl->crlLock); 00346 00347 if (ret != 0) 00348 return BAD_COND_E; 00349 00350 return 0; 00351 } 00352 00353 00354 /* read in new CRL entries and save new list */ 00355 static int SwapLists(WOLFSSL_CRL* crl) 00356 { 00357 int ret; 00358 CRL_Entry* newList; 00359 #ifdef WOLFSSL_SMALL_STACK 00360 WOLFSSL_CRL* tmp; 00361 #else 00362 WOLFSSL_CRL tmp[1]; 00363 #endif 00364 00365 #ifdef WOLFSSL_SMALL_STACK 00366 tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00367 if (tmp == NULL) 00368 return MEMORY_E; 00369 #endif 00370 00371 if (InitCRL(tmp, crl->cm) < 0) { 00372 WOLFSSL_MSG("Init tmp CRL failed"); 00373 #ifdef WOLFSSL_SMALL_STACK 00374 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00375 #endif 00376 return -1; 00377 } 00378 00379 if (crl->monitors[0].path) { 00380 ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0); 00381 if (ret != SSL_SUCCESS) { 00382 WOLFSSL_MSG("PEM LoadCRL on dir change failed"); 00383 FreeCRL(tmp, 0); 00384 #ifdef WOLFSSL_SMALL_STACK 00385 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00386 #endif 00387 return -1; 00388 } 00389 } 00390 00391 if (crl->monitors[1].path) { 00392 ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0); 00393 if (ret != SSL_SUCCESS) { 00394 WOLFSSL_MSG("DER LoadCRL on dir change failed"); 00395 FreeCRL(tmp, 0); 00396 #ifdef WOLFSSL_SMALL_STACK 00397 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00398 #endif 00399 return -1; 00400 } 00401 } 00402 00403 if (LockMutex(&crl->crlLock) != 0) { 00404 WOLFSSL_MSG("LockMutex failed"); 00405 FreeCRL(tmp, 0); 00406 #ifdef WOLFSSL_SMALL_STACK 00407 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00408 #endif 00409 return -1; 00410 } 00411 00412 newList = tmp->crlList; 00413 00414 /* swap lists */ 00415 tmp->crlList = crl->crlList; 00416 crl->crlList = newList; 00417 00418 UnLockMutex(&crl->crlLock); 00419 00420 FreeCRL(tmp, 0); 00421 00422 #ifdef WOLFSSL_SMALL_STACK 00423 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00424 #endif 00425 00426 return 0; 00427 } 00428 00429 00430 #if (defined(__MACH__) || defined(__FreeBSD__)) 00431 00432 #include <sys/types.h> 00433 #include <sys/event.h> 00434 #include <sys/time.h> 00435 #include <fcntl.h> 00436 #include <unistd.h> 00437 00438 #ifdef __MACH__ 00439 #define XEVENT_MODE O_EVTONLY 00440 #elif defined(__FreeBSD__) 00441 #define XEVENT_MODE EVFILT_VNODE 00442 #endif 00443 00444 00445 /* we need a unique kqueue user filter fd for crl in case user is doing custom 00446 * events too */ 00447 #ifndef CRL_CUSTOM_FD 00448 #define CRL_CUSTOM_FD 123456 00449 #endif 00450 00451 00452 /* shutdown monitor thread, 0 on success */ 00453 static int StopMonitor(int mfd) 00454 { 00455 struct kevent change; 00456 00457 /* trigger custom shutdown */ 00458 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 00459 if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) { 00460 WOLFSSL_MSG("kevent trigger customer event failed"); 00461 return -1; 00462 } 00463 00464 return 0; 00465 } 00466 00467 00468 /* OS X monitoring */ 00469 static void* DoMonitor(void* arg) 00470 { 00471 int fPEM, fDER; 00472 struct kevent change; 00473 00474 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; 00475 00476 WOLFSSL_ENTER("DoMonitor"); 00477 00478 crl->mfd = kqueue(); 00479 if (crl->mfd == -1) { 00480 WOLFSSL_MSG("kqueue failed"); 00481 SignalSetup(crl, MONITOR_SETUP_E); 00482 return NULL; 00483 } 00484 00485 /* listen for custom shutdown event */ 00486 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL); 00487 if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) { 00488 WOLFSSL_MSG("kevent monitor customer event failed"); 00489 SignalSetup(crl, MONITOR_SETUP_E); 00490 close(crl->mfd); 00491 return NULL; 00492 } 00493 00494 fPEM = -1; 00495 fDER = -1; 00496 00497 if (crl->monitors[0].path) { 00498 fPEM = open(crl->monitors[0].path, XEVENT_MODE); 00499 if (fPEM == -1) { 00500 WOLFSSL_MSG("PEM event dir open failed"); 00501 SignalSetup(crl, MONITOR_SETUP_E); 00502 close(crl->mfd); 00503 return NULL; 00504 } 00505 } 00506 00507 if (crl->monitors[1].path) { 00508 fDER = open(crl->monitors[1].path, XEVENT_MODE); 00509 if (fDER == -1) { 00510 WOLFSSL_MSG("DER event dir open failed"); 00511 if (fPEM != -1) 00512 close(fPEM); 00513 close(crl->mfd); 00514 SignalSetup(crl, MONITOR_SETUP_E); 00515 return NULL; 00516 } 00517 } 00518 00519 if (fPEM != -1) 00520 EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, 00521 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0); 00522 00523 if (fDER != -1) 00524 EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, 00525 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0); 00526 00527 /* signal to calling thread we're setup */ 00528 if (SignalSetup(crl, 1) != 0) { 00529 if (fPEM != -1) 00530 close(fPEM); 00531 if (fDER != -1) 00532 close(fDER); 00533 close(crl->mfd); 00534 return NULL; 00535 } 00536 00537 for (;;) { 00538 struct kevent event; 00539 int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL); 00540 00541 WOLFSSL_MSG("Got kevent"); 00542 00543 if (numEvents == -1) { 00544 WOLFSSL_MSG("kevent problem, continue"); 00545 continue; 00546 } 00547 00548 if (event.filter == EVFILT_USER) { 00549 WOLFSSL_MSG("Got user shutdown event, breaking out"); 00550 break; 00551 } 00552 00553 if (SwapLists(crl) < 0) { 00554 WOLFSSL_MSG("SwapLists problem, continue"); 00555 } 00556 } 00557 00558 if (fPEM != -1) 00559 close(fPEM); 00560 if (fDER != -1) 00561 close(fDER); 00562 00563 close(crl->mfd); 00564 00565 return NULL; 00566 } 00567 00568 00569 #elif defined(__linux__) 00570 00571 #include <sys/types.h> 00572 #include <sys/inotify.h> 00573 #include <sys/eventfd.h> 00574 #include <unistd.h> 00575 00576 00577 #ifndef max 00578 static INLINE int max(int a, int b) 00579 { 00580 return a > b ? a : b; 00581 } 00582 #endif /* max */ 00583 00584 00585 /* shutdown monitor thread, 0 on success */ 00586 static int StopMonitor(int mfd) 00587 { 00588 word64 w64 = 1; 00589 00590 /* write to our custom event */ 00591 if (write(mfd, &w64, sizeof(w64)) < 0) { 00592 WOLFSSL_MSG("StopMonitor write failed"); 00593 return -1; 00594 } 00595 00596 return 0; 00597 } 00598 00599 00600 /* linux monitoring */ 00601 static void* DoMonitor(void* arg) 00602 { 00603 int notifyFd; 00604 int wd = -1; 00605 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; 00606 #ifdef WOLFSSL_SMALL_STACK 00607 char* buff; 00608 #else 00609 char buff[8192]; 00610 #endif 00611 00612 WOLFSSL_ENTER("DoMonitor"); 00613 00614 crl->mfd = eventfd(0, 0); /* our custom shutdown event */ 00615 if (crl->mfd < 0) { 00616 WOLFSSL_MSG("eventfd failed"); 00617 SignalSetup(crl, MONITOR_SETUP_E); 00618 return NULL; 00619 } 00620 00621 notifyFd = inotify_init(); 00622 if (notifyFd < 0) { 00623 WOLFSSL_MSG("inotify failed"); 00624 close(crl->mfd); 00625 SignalSetup(crl, MONITOR_SETUP_E); 00626 return NULL; 00627 } 00628 00629 if (crl->monitors[0].path) { 00630 wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE | 00631 IN_DELETE); 00632 if (wd < 0) { 00633 WOLFSSL_MSG("PEM notify add watch failed"); 00634 close(crl->mfd); 00635 close(notifyFd); 00636 SignalSetup(crl, MONITOR_SETUP_E); 00637 return NULL; 00638 } 00639 } 00640 00641 if (crl->monitors[1].path) { 00642 wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE | 00643 IN_DELETE); 00644 if (wd < 0) { 00645 WOLFSSL_MSG("DER notify add watch failed"); 00646 close(crl->mfd); 00647 close(notifyFd); 00648 SignalSetup(crl, MONITOR_SETUP_E); 00649 return NULL; 00650 } 00651 } 00652 00653 #ifdef WOLFSSL_SMALL_STACK 00654 buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00655 if (buff == NULL) 00656 return NULL; 00657 #endif 00658 00659 /* signal to calling thread we're setup */ 00660 if (SignalSetup(crl, 1) != 0) { 00661 #ifdef WOLFSSL_SMALL_STACK 00662 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00663 #endif 00664 00665 if (wd > 0) 00666 inotify_rm_watch(notifyFd, wd); 00667 close(crl->mfd); 00668 close(notifyFd); 00669 return NULL; 00670 } 00671 00672 for (;;) { 00673 fd_set readfds; 00674 int result; 00675 int length; 00676 00677 FD_ZERO(&readfds); 00678 FD_SET(notifyFd, &readfds); 00679 FD_SET(crl->mfd, &readfds); 00680 00681 result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL); 00682 00683 WOLFSSL_MSG("Got notify event"); 00684 00685 if (result < 0) { 00686 WOLFSSL_MSG("select problem, continue"); 00687 continue; 00688 } 00689 00690 if (FD_ISSET(crl->mfd, &readfds)) { 00691 WOLFSSL_MSG("got custom shutdown event, breaking out"); 00692 break; 00693 } 00694 00695 length = (int) read(notifyFd, buff, 8192); 00696 if (length < 0) { 00697 WOLFSSL_MSG("notify read problem, continue"); 00698 continue; 00699 } 00700 00701 if (SwapLists(crl) < 0) { 00702 WOLFSSL_MSG("SwapLists problem, continue"); 00703 } 00704 } 00705 00706 #ifdef WOLFSSL_SMALL_STACK 00707 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00708 #endif 00709 00710 if (wd > 0) 00711 inotify_rm_watch(notifyFd, wd); 00712 close(crl->mfd); 00713 close(notifyFd); 00714 00715 return NULL; 00716 } 00717 00718 00719 #else 00720 00721 #error "CRL monitor only currently supported on linux or mach" 00722 00723 #endif /* MACH or linux */ 00724 00725 00726 /* Start Monitoring the CRL path(s) in a thread */ 00727 static int StartMonitorCRL(WOLFSSL_CRL* crl) 00728 { 00729 int ret = SSL_SUCCESS; 00730 00731 WOLFSSL_ENTER("StartMonitorCRL"); 00732 00733 if (crl == NULL) 00734 return BAD_FUNC_ARG; 00735 00736 if (crl->tid != 0) { 00737 WOLFSSL_MSG("Monitor thread already running"); 00738 return ret; /* that's ok, someone already started */ 00739 } 00740 00741 if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) { 00742 WOLFSSL_MSG("Thread creation error"); 00743 return THREAD_CREATE_E; 00744 } 00745 00746 /* wait for setup to complete */ 00747 if (LockMutex(&crl->crlLock) != 0) { 00748 WOLFSSL_MSG("LockMutex crlLock error"); 00749 return BAD_MUTEX_E; 00750 } 00751 00752 while (crl->setup == 0) { 00753 if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) { 00754 ret = BAD_COND_E; 00755 break; 00756 } 00757 } 00758 00759 if (crl->setup < 0) 00760 ret = crl->setup; /* store setup error */ 00761 00762 UnLockMutex(&crl->crlLock); 00763 00764 if (ret < 0) { 00765 WOLFSSL_MSG("DoMonitor setup failure"); 00766 crl->tid = 0; /* thread already done */ 00767 } 00768 00769 return ret; 00770 } 00771 00772 00773 #else /* HAVE_CRL_MONITOR */ 00774 00775 #ifndef NO_FILESYSTEM 00776 00777 static int StartMonitorCRL(WOLFSSL_CRL* crl) 00778 { 00779 (void)crl; 00780 00781 WOLFSSL_ENTER("StartMonitorCRL"); 00782 WOLFSSL_MSG("Not compiled in"); 00783 00784 return NOT_COMPILED_IN; 00785 } 00786 00787 #endif /* NO_FILESYSTEM */ 00788 00789 #endif /* HAVE_CRL_MONITOR */ 00790 00791 #ifndef NO_FILESYSTEM 00792 00793 /* Load CRL path files of type, SSL_SUCCESS on ok */ 00794 int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) 00795 { 00796 struct dirent* entry; 00797 DIR* dir; 00798 int ret = SSL_SUCCESS; 00799 #ifdef WOLFSSL_SMALL_STACK 00800 char* name; 00801 #else 00802 char name[MAX_FILENAME_SZ]; 00803 #endif 00804 00805 WOLFSSL_ENTER("LoadCRL"); 00806 if (crl == NULL) 00807 return BAD_FUNC_ARG; 00808 00809 dir = opendir(path); 00810 if (dir == NULL) { 00811 WOLFSSL_MSG("opendir path crl load failed"); 00812 return BAD_PATH_ERROR; 00813 } 00814 00815 #ifdef WOLFSSL_SMALL_STACK 00816 name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00817 if (name == NULL) 00818 return MEMORY_E; 00819 #endif 00820 00821 while ( (entry = readdir(dir)) != NULL) { 00822 struct stat s; 00823 00824 XMEMSET(name, 0, MAX_FILENAME_SZ); 00825 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2); 00826 XSTRNCAT(name, "/", 1); 00827 XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2); 00828 00829 if (stat(name, &s) != 0) { 00830 WOLFSSL_MSG("stat on name failed"); 00831 continue; 00832 } 00833 if (s.st_mode & S_IFREG) { 00834 00835 if (type == SSL_FILETYPE_PEM) { 00836 if (XSTRSTR(entry->d_name, ".pem") == NULL) { 00837 WOLFSSL_MSG("not .pem file, skipping"); 00838 continue; 00839 } 00840 } 00841 else { 00842 if (XSTRSTR(entry->d_name, ".der") == NULL && 00843 XSTRSTR(entry->d_name, ".crl") == NULL) { 00844 00845 WOLFSSL_MSG("not .der or .crl file, skipping"); 00846 continue; 00847 } 00848 } 00849 00850 if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl) 00851 != SSL_SUCCESS) { 00852 WOLFSSL_MSG("CRL file load failed, continuing"); 00853 } 00854 } 00855 } 00856 00857 #ifdef WOLFSSL_SMALL_STACK 00858 XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00859 #endif 00860 00861 if (monitor & WOLFSSL_CRL_MONITOR) { 00862 word32 pathLen; 00863 char* pathBuf; 00864 00865 WOLFSSL_MSG("monitor path requested"); 00866 00867 pathLen = (word32)XSTRLEN(path); 00868 pathBuf = (char*)XMALLOC(pathLen+1, NULL, DYNAMIC_TYPE_CRL_MONITOR); 00869 if (pathBuf) { 00870 XSTRNCPY(pathBuf, path, pathLen); 00871 pathBuf[pathLen] = '\0'; /* Null Terminate */ 00872 00873 if (type == SSL_FILETYPE_PEM) { 00874 crl->monitors[0].path = pathBuf; 00875 crl->monitors[0].type = SSL_FILETYPE_PEM; 00876 } else { 00877 crl->monitors[1].path = pathBuf; 00878 crl->monitors[1].type = SSL_FILETYPE_ASN1; 00879 } 00880 00881 if (monitor & WOLFSSL_CRL_START_MON) { 00882 WOLFSSL_MSG("start monitoring requested"); 00883 00884 ret = StartMonitorCRL(crl); 00885 } 00886 } 00887 else { 00888 ret = MEMORY_E; 00889 } 00890 } 00891 00892 closedir(dir); 00893 00894 return ret; 00895 } 00896 00897 #endif /* NO_FILESYSTEM */ 00898 00899 #endif /* HAVE_CRL */ 00900 #endif /* !WOLFCRYPT_ONLY */ 00901
Generated on Tue Jul 12 2022 15:55:18 by
1.7.2