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.
Fork of wolfSSL by
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 #include <string.h> 00038 00039 #ifdef HAVE_CRL_MONITOR 00040 #if (defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__)) 00041 static int StopMonitor(int mfd); 00042 #else 00043 #error "CRL monitor only currently supported on linux or mach" 00044 #endif 00045 #endif /* HAVE_CRL_MONITOR */ 00046 00047 00048 /* Initialize CRL members */ 00049 int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm) 00050 { 00051 WOLFSSL_ENTER("InitCRL"); 00052 00053 crl->heap = cm->heap; 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 (wc_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, void* heap) 00099 { 00100 RevokedCert* tmp = crle->certs; 00101 00102 WOLFSSL_ENTER("FreeCRL_Entry"); 00103 00104 while(tmp) { 00105 RevokedCert* next = tmp->next; 00106 XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED); 00107 tmp = next; 00108 } 00109 00110 (void)heap; 00111 } 00112 00113 00114 00115 /* Free all CRL resources */ 00116 void FreeCRL(WOLFSSL_CRL* crl, int dynamic) 00117 { 00118 CRL_Entry* tmp = crl->crlList; 00119 00120 WOLFSSL_ENTER("FreeCRL"); 00121 00122 if (crl->monitors[0].path) 00123 XFREE(crl->monitors[0].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR); 00124 00125 if (crl->monitors[1].path) 00126 XFREE(crl->monitors[1].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR); 00127 00128 while(tmp) { 00129 CRL_Entry* next = tmp->next; 00130 FreeCRL_Entry(tmp, crl->heap); 00131 XFREE(tmp, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); 00132 tmp = next; 00133 } 00134 00135 #ifdef HAVE_CRL_MONITOR 00136 if (crl->tid != 0) { 00137 WOLFSSL_MSG("stopping monitor thread"); 00138 if (StopMonitor(crl->mfd) == 0) 00139 pthread_join(crl->tid, NULL); 00140 else { 00141 WOLFSSL_MSG("stop monitor failed"); 00142 } 00143 } 00144 pthread_cond_destroy(&crl->cond); 00145 #endif 00146 wc_FreeMutex(&crl->crlLock); 00147 if (dynamic) /* free self */ 00148 XFREE(crl, crl->heap, DYNAMIC_TYPE_CRL); 00149 } 00150 00151 00152 static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntry) 00153 { 00154 CRL_Entry* crle; 00155 int foundEntry = 0; 00156 int ret = 0; 00157 00158 if (wc_LockMutex(&crl->crlLock) != 0) { 00159 WOLFSSL_MSG("wc_LockMutex failed"); 00160 return BAD_MUTEX_E; 00161 } 00162 00163 crle = crl->crlList; 00164 00165 while (crle) { 00166 if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) { 00167 int doNextDate = 1; 00168 00169 WOLFSSL_MSG("Found CRL Entry on list"); 00170 WOLFSSL_MSG("Checking next date validity"); 00171 00172 #ifdef WOLFSSL_NO_CRL_NEXT_DATE 00173 if (crle->nextDateFormat == ASN_OTHER_TYPE) 00174 doNextDate = 0; /* skip */ 00175 #endif 00176 00177 if (doNextDate) { 00178 #ifndef NO_ASN_TIME 00179 if (!ValidateDate(crle->nextDate,crle->nextDateFormat, AFTER)) { 00180 WOLFSSL_MSG("CRL next date is no longer valid"); 00181 ret = ASN_AFTER_DATE_E; 00182 } 00183 #endif 00184 } 00185 if (ret == 0) { 00186 foundEntry = 1; 00187 } 00188 break; 00189 } 00190 crle = crle->next; 00191 } 00192 00193 if (foundEntry) { 00194 RevokedCert* rc = crle->certs; 00195 00196 while (rc) { 00197 if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) { 00198 WOLFSSL_MSG("Cert revoked"); 00199 ret = CRL_CERT_REVOKED; 00200 break; 00201 } 00202 rc = rc->next; 00203 } 00204 } 00205 00206 wc_UnLockMutex(&crl->crlLock); 00207 00208 *pFoundEntry = foundEntry; 00209 00210 return ret; 00211 } 00212 00213 /* Is the cert ok with CRL, return 0 on success */ 00214 int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) 00215 { 00216 int foundEntry = 0; 00217 int ret = 0; 00218 00219 WOLFSSL_ENTER("CheckCertCRL"); 00220 00221 ret = CheckCertCRLList(crl, cert, &foundEntry); 00222 00223 #ifdef HAVE_CRL_IO 00224 if (foundEntry == 0) { 00225 /* perform embedded lookup */ 00226 if (crl->crlIOCb) { 00227 ret = crl->crlIOCb(crl, (const char*)cert->extCrlInfo, 00228 cert->extCrlInfoSz); 00229 if (ret >= 0) { 00230 /* try again */ 00231 ret = CheckCertCRLList(crl, cert, &foundEntry); 00232 } 00233 } 00234 } 00235 #endif 00236 00237 if (foundEntry == 0) { 00238 WOLFSSL_MSG("Couldn't find CRL for status check"); 00239 ret = CRL_MISSING; 00240 00241 if (crl->cm->cbMissingCRL) { 00242 char url[256]; 00243 00244 WOLFSSL_MSG("Issuing missing CRL callback"); 00245 url[0] = '\0'; 00246 if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) { 00247 XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz); 00248 url[cert->extCrlInfoSz] = '\0'; 00249 } 00250 else { 00251 WOLFSSL_MSG("CRL url too long"); 00252 } 00253 00254 crl->cm->cbMissingCRL(url); 00255 } 00256 } 00257 00258 return ret; 00259 } 00260 00261 00262 /* Add Decoded CRL, 0 on success */ 00263 static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl) 00264 { 00265 CRL_Entry* crle; 00266 00267 WOLFSSL_ENTER("AddCRL"); 00268 00269 crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap, DYNAMIC_TYPE_CRL_ENTRY); 00270 if (crle == NULL) { 00271 WOLFSSL_MSG("alloc CRL Entry failed"); 00272 return -1; 00273 } 00274 00275 if (InitCRL_Entry(crle, dcrl) < 0) { 00276 WOLFSSL_MSG("Init CRL Entry failed"); 00277 XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); 00278 return -1; 00279 } 00280 00281 if (wc_LockMutex(&crl->crlLock) != 0) { 00282 WOLFSSL_MSG("wc_LockMutex failed"); 00283 FreeCRL_Entry(crle, crl->heap); 00284 XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); 00285 return BAD_MUTEX_E; 00286 } 00287 crle->next = crl->crlList; 00288 crl->crlList = crle; 00289 wc_UnLockMutex(&crl->crlLock); 00290 00291 return 0; 00292 } 00293 00294 00295 /* Load CRL File of type, SSL_SUCCESS on ok */ 00296 int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type) 00297 { 00298 int ret = SSL_SUCCESS; 00299 const byte* myBuffer = buff; /* if DER ok, otherwise switch */ 00300 DerBuffer* der = NULL; 00301 #ifdef WOLFSSL_SMALL_STACK 00302 DecodedCRL* dcrl; 00303 #else 00304 DecodedCRL dcrl[1]; 00305 #endif 00306 00307 WOLFSSL_ENTER("BufferLoadCRL"); 00308 00309 if (crl == NULL || buff == NULL || sz == 0) 00310 return BAD_FUNC_ARG; 00311 00312 if (type == SSL_FILETYPE_PEM) { 00313 int eccKey = 0; /* not used */ 00314 EncryptedInfo info; 00315 info.ctx = NULL; 00316 00317 ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey); 00318 if (ret == 0) { 00319 myBuffer = der->buffer; 00320 sz = der->length; 00321 } 00322 else { 00323 WOLFSSL_MSG("Pem to Der failed"); 00324 FreeDer(&der); 00325 return -1; 00326 } 00327 } 00328 00329 #ifdef WOLFSSL_SMALL_STACK 00330 dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00331 if (dcrl == NULL) { 00332 FreeDer(&der); 00333 return MEMORY_E; 00334 } 00335 #endif 00336 00337 InitDecodedCRL(dcrl, crl->heap); 00338 ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm); 00339 if (ret != 0) { 00340 WOLFSSL_MSG("ParseCRL error"); 00341 } 00342 else { 00343 ret = AddCRL(crl, dcrl); 00344 if (ret != 0) { 00345 WOLFSSL_MSG("AddCRL error"); 00346 } 00347 } 00348 00349 FreeDecodedCRL(dcrl); 00350 00351 #ifdef WOLFSSL_SMALL_STACK 00352 XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00353 #endif 00354 00355 FreeDer(&der); 00356 00357 return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */ 00358 } 00359 00360 00361 #ifdef HAVE_CRL_MONITOR 00362 00363 00364 /* Signal Monitor thread is setup, save status to setup flag, 0 on success */ 00365 static int SignalSetup(WOLFSSL_CRL* crl, int status) 00366 { 00367 int ret; 00368 00369 /* signal to calling thread we're setup */ 00370 if (wc_LockMutex(&crl->crlLock) != 0) { 00371 WOLFSSL_MSG("wc_LockMutex crlLock failed"); 00372 return BAD_MUTEX_E; 00373 } 00374 00375 crl->setup = status; 00376 ret = pthread_cond_signal(&crl->cond); 00377 00378 wc_UnLockMutex(&crl->crlLock); 00379 00380 if (ret != 0) 00381 return BAD_COND_E; 00382 00383 return 0; 00384 } 00385 00386 00387 /* read in new CRL entries and save new list */ 00388 static int SwapLists(WOLFSSL_CRL* crl) 00389 { 00390 int ret; 00391 CRL_Entry* newList; 00392 #ifdef WOLFSSL_SMALL_STACK 00393 WOLFSSL_CRL* tmp; 00394 #else 00395 WOLFSSL_CRL tmp[1]; 00396 #endif 00397 00398 #ifdef WOLFSSL_SMALL_STACK 00399 tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00400 if (tmp == NULL) 00401 return MEMORY_E; 00402 #endif 00403 00404 if (InitCRL(tmp, crl->cm) < 0) { 00405 WOLFSSL_MSG("Init tmp CRL failed"); 00406 #ifdef WOLFSSL_SMALL_STACK 00407 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00408 #endif 00409 return -1; 00410 } 00411 00412 if (crl->monitors[0].path) { 00413 ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0); 00414 if (ret != SSL_SUCCESS) { 00415 WOLFSSL_MSG("PEM LoadCRL on dir change failed"); 00416 FreeCRL(tmp, 0); 00417 #ifdef WOLFSSL_SMALL_STACK 00418 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00419 #endif 00420 return -1; 00421 } 00422 } 00423 00424 if (crl->monitors[1].path) { 00425 ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0); 00426 if (ret != SSL_SUCCESS) { 00427 WOLFSSL_MSG("DER LoadCRL on dir change failed"); 00428 FreeCRL(tmp, 0); 00429 #ifdef WOLFSSL_SMALL_STACK 00430 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00431 #endif 00432 return -1; 00433 } 00434 } 00435 00436 if (wc_LockMutex(&crl->crlLock) != 0) { 00437 WOLFSSL_MSG("wc_LockMutex failed"); 00438 FreeCRL(tmp, 0); 00439 #ifdef WOLFSSL_SMALL_STACK 00440 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00441 #endif 00442 return -1; 00443 } 00444 00445 newList = tmp->crlList; 00446 00447 /* swap lists */ 00448 tmp->crlList = crl->crlList; 00449 crl->crlList = newList; 00450 00451 wc_UnLockMutex(&crl->crlLock); 00452 00453 FreeCRL(tmp, 0); 00454 00455 #ifdef WOLFSSL_SMALL_STACK 00456 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00457 #endif 00458 00459 return 0; 00460 } 00461 00462 00463 #if (defined(__MACH__) || defined(__FreeBSD__)) 00464 00465 #include <sys/types.h> 00466 #include <sys/event.h> 00467 #include <sys/time.h> 00468 #include <fcntl.h> 00469 #include <unistd.h> 00470 00471 #ifdef __MACH__ 00472 #define XEVENT_MODE O_EVTONLY 00473 #elif defined(__FreeBSD__) 00474 #define XEVENT_MODE EVFILT_VNODE 00475 #endif 00476 00477 00478 /* we need a unique kqueue user filter fd for crl in case user is doing custom 00479 * events too */ 00480 #ifndef CRL_CUSTOM_FD 00481 #define CRL_CUSTOM_FD 123456 00482 #endif 00483 00484 00485 /* shutdown monitor thread, 0 on success */ 00486 static int StopMonitor(int mfd) 00487 { 00488 struct kevent change; 00489 00490 /* trigger custom shutdown */ 00491 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 00492 if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) { 00493 WOLFSSL_MSG("kevent trigger customer event failed"); 00494 return -1; 00495 } 00496 00497 return 0; 00498 } 00499 00500 00501 /* OS X monitoring */ 00502 static void* DoMonitor(void* arg) 00503 { 00504 int fPEM, fDER; 00505 struct kevent change; 00506 00507 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; 00508 00509 WOLFSSL_ENTER("DoMonitor"); 00510 00511 crl->mfd = kqueue(); 00512 if (crl->mfd == -1) { 00513 WOLFSSL_MSG("kqueue failed"); 00514 SignalSetup(crl, MONITOR_SETUP_E); 00515 return NULL; 00516 } 00517 00518 /* listen for custom shutdown event */ 00519 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL); 00520 if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) { 00521 WOLFSSL_MSG("kevent monitor customer event failed"); 00522 SignalSetup(crl, MONITOR_SETUP_E); 00523 close(crl->mfd); 00524 return NULL; 00525 } 00526 00527 fPEM = -1; 00528 fDER = -1; 00529 00530 if (crl->monitors[0].path) { 00531 fPEM = open(crl->monitors[0].path, XEVENT_MODE); 00532 if (fPEM == -1) { 00533 WOLFSSL_MSG("PEM event dir open failed"); 00534 SignalSetup(crl, MONITOR_SETUP_E); 00535 close(crl->mfd); 00536 return NULL; 00537 } 00538 } 00539 00540 if (crl->monitors[1].path) { 00541 fDER = open(crl->monitors[1].path, XEVENT_MODE); 00542 if (fDER == -1) { 00543 WOLFSSL_MSG("DER event dir open failed"); 00544 if (fPEM != -1) 00545 close(fPEM); 00546 close(crl->mfd); 00547 SignalSetup(crl, MONITOR_SETUP_E); 00548 return NULL; 00549 } 00550 } 00551 00552 if (fPEM != -1) 00553 EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, 00554 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0); 00555 00556 if (fDER != -1) 00557 EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT, 00558 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0); 00559 00560 /* signal to calling thread we're setup */ 00561 if (SignalSetup(crl, 1) != 0) { 00562 if (fPEM != -1) 00563 close(fPEM); 00564 if (fDER != -1) 00565 close(fDER); 00566 close(crl->mfd); 00567 return NULL; 00568 } 00569 00570 for (;;) { 00571 struct kevent event; 00572 int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL); 00573 00574 WOLFSSL_MSG("Got kevent"); 00575 00576 if (numEvents == -1) { 00577 WOLFSSL_MSG("kevent problem, continue"); 00578 continue; 00579 } 00580 00581 if (event.filter == EVFILT_USER) { 00582 WOLFSSL_MSG("Got user shutdown event, breaking out"); 00583 break; 00584 } 00585 00586 if (SwapLists(crl) < 0) { 00587 WOLFSSL_MSG("SwapLists problem, continue"); 00588 } 00589 } 00590 00591 if (fPEM != -1) 00592 close(fPEM); 00593 if (fDER != -1) 00594 close(fDER); 00595 00596 close(crl->mfd); 00597 00598 return NULL; 00599 } 00600 00601 00602 #elif defined(__linux__) 00603 00604 #include <sys/types.h> 00605 #include <sys/inotify.h> 00606 #include <sys/eventfd.h> 00607 #include <unistd.h> 00608 00609 00610 #ifndef max 00611 static INLINE int max(int a, int b) 00612 { 00613 return a > b ? a : b; 00614 } 00615 #endif /* max */ 00616 00617 00618 /* shutdown monitor thread, 0 on success */ 00619 static int StopMonitor(int mfd) 00620 { 00621 word64 w64 = 1; 00622 00623 /* write to our custom event */ 00624 if (write(mfd, &w64, sizeof(w64)) < 0) { 00625 WOLFSSL_MSG("StopMonitor write failed"); 00626 return -1; 00627 } 00628 00629 return 0; 00630 } 00631 00632 00633 /* linux monitoring */ 00634 static void* DoMonitor(void* arg) 00635 { 00636 int notifyFd; 00637 int wd = -1; 00638 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; 00639 #ifdef WOLFSSL_SMALL_STACK 00640 char* buff; 00641 #else 00642 char buff[8192]; 00643 #endif 00644 00645 WOLFSSL_ENTER("DoMonitor"); 00646 00647 crl->mfd = eventfd(0, 0); /* our custom shutdown event */ 00648 if (crl->mfd < 0) { 00649 WOLFSSL_MSG("eventfd failed"); 00650 SignalSetup(crl, MONITOR_SETUP_E); 00651 return NULL; 00652 } 00653 00654 notifyFd = inotify_init(); 00655 if (notifyFd < 0) { 00656 WOLFSSL_MSG("inotify failed"); 00657 close(crl->mfd); 00658 SignalSetup(crl, MONITOR_SETUP_E); 00659 return NULL; 00660 } 00661 00662 if (crl->monitors[0].path) { 00663 wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE | 00664 IN_DELETE); 00665 if (wd < 0) { 00666 WOLFSSL_MSG("PEM notify add watch failed"); 00667 close(crl->mfd); 00668 close(notifyFd); 00669 SignalSetup(crl, MONITOR_SETUP_E); 00670 return NULL; 00671 } 00672 } 00673 00674 if (crl->monitors[1].path) { 00675 wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE | 00676 IN_DELETE); 00677 if (wd < 0) { 00678 WOLFSSL_MSG("DER notify add watch failed"); 00679 close(crl->mfd); 00680 close(notifyFd); 00681 SignalSetup(crl, MONITOR_SETUP_E); 00682 return NULL; 00683 } 00684 } 00685 00686 #ifdef WOLFSSL_SMALL_STACK 00687 buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00688 if (buff == NULL) 00689 return NULL; 00690 #endif 00691 00692 /* signal to calling thread we're setup */ 00693 if (SignalSetup(crl, 1) != 0) { 00694 #ifdef WOLFSSL_SMALL_STACK 00695 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00696 #endif 00697 00698 if (wd > 0) 00699 inotify_rm_watch(notifyFd, wd); 00700 close(crl->mfd); 00701 close(notifyFd); 00702 return NULL; 00703 } 00704 00705 for (;;) { 00706 fd_set readfds; 00707 int result; 00708 int length; 00709 00710 FD_ZERO(&readfds); 00711 FD_SET(notifyFd, &readfds); 00712 FD_SET(crl->mfd, &readfds); 00713 00714 result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL); 00715 00716 WOLFSSL_MSG("Got notify event"); 00717 00718 if (result < 0) { 00719 WOLFSSL_MSG("select problem, continue"); 00720 continue; 00721 } 00722 00723 if (FD_ISSET(crl->mfd, &readfds)) { 00724 WOLFSSL_MSG("got custom shutdown event, breaking out"); 00725 break; 00726 } 00727 00728 length = (int) read(notifyFd, buff, 8192); 00729 if (length < 0) { 00730 WOLFSSL_MSG("notify read problem, continue"); 00731 continue; 00732 } 00733 00734 if (SwapLists(crl) < 0) { 00735 WOLFSSL_MSG("SwapLists problem, continue"); 00736 } 00737 } 00738 00739 #ifdef WOLFSSL_SMALL_STACK 00740 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00741 #endif 00742 00743 if (wd > 0) 00744 inotify_rm_watch(notifyFd, wd); 00745 close(crl->mfd); 00746 close(notifyFd); 00747 00748 return NULL; 00749 } 00750 00751 #endif /* MACH or linux */ 00752 00753 00754 /* Start Monitoring the CRL path(s) in a thread */ 00755 static int StartMonitorCRL(WOLFSSL_CRL* crl) 00756 { 00757 int ret = SSL_SUCCESS; 00758 00759 WOLFSSL_ENTER("StartMonitorCRL"); 00760 00761 if (crl == NULL) 00762 return BAD_FUNC_ARG; 00763 00764 if (crl->tid != 0) { 00765 WOLFSSL_MSG("Monitor thread already running"); 00766 return ret; /* that's ok, someone already started */ 00767 } 00768 00769 if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) { 00770 WOLFSSL_MSG("Thread creation error"); 00771 return THREAD_CREATE_E; 00772 } 00773 00774 /* wait for setup to complete */ 00775 if (wc_LockMutex(&crl->crlLock) != 0) { 00776 WOLFSSL_MSG("wc_LockMutex crlLock error"); 00777 return BAD_MUTEX_E; 00778 } 00779 00780 while (crl->setup == 0) { 00781 if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) { 00782 ret = BAD_COND_E; 00783 break; 00784 } 00785 } 00786 00787 if (crl->setup < 0) 00788 ret = crl->setup; /* store setup error */ 00789 00790 wc_UnLockMutex(&crl->crlLock); 00791 00792 if (ret < 0) { 00793 WOLFSSL_MSG("DoMonitor setup failure"); 00794 crl->tid = 0; /* thread already done */ 00795 } 00796 00797 return ret; 00798 } 00799 00800 00801 #else /* HAVE_CRL_MONITOR */ 00802 00803 #ifndef NO_FILESYSTEM 00804 00805 static int StartMonitorCRL(WOLFSSL_CRL* crl) 00806 { 00807 (void)crl; 00808 00809 WOLFSSL_ENTER("StartMonitorCRL"); 00810 WOLFSSL_MSG("Not compiled in"); 00811 00812 return NOT_COMPILED_IN; 00813 } 00814 00815 #endif /* NO_FILESYSTEM */ 00816 00817 #endif /* HAVE_CRL_MONITOR */ 00818 00819 #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) 00820 00821 /* Load CRL path files of type, SSL_SUCCESS on ok */ 00822 int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) 00823 { 00824 int ret = SSL_SUCCESS; 00825 char* name = NULL; 00826 #ifdef WOLFSSL_SMALL_STACK 00827 ReadDirCtx* readCtx = NULL; 00828 #else 00829 ReadDirCtx readCtx[1]; 00830 #endif 00831 00832 WOLFSSL_ENTER("LoadCRL"); 00833 if (crl == NULL) 00834 return BAD_FUNC_ARG; 00835 00836 #ifdef WOLFSSL_SMALL_STACK 00837 readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), crl->heap, 00838 DYNAMIC_TYPE_TMP_BUFFER); 00839 if (readCtx == NULL) 00840 return MEMORY_E; 00841 #endif 00842 00843 /* try to load each regular file in path */ 00844 ret = wc_ReadDirFirst(readCtx, path, &name); 00845 while (ret == 0 && name) { 00846 int skip = 0; 00847 if (type == SSL_FILETYPE_PEM) { 00848 if (XSTRSTR(name, ".pem") == NULL) { 00849 WOLFSSL_MSG("not .pem file, skipping"); 00850 skip = 1; 00851 } 00852 } 00853 else { 00854 if (XSTRSTR(name, ".der") == NULL && 00855 XSTRSTR(name, ".crl") == NULL) 00856 { 00857 WOLFSSL_MSG("not .der or .crl file, skipping"); 00858 skip = 1; 00859 } 00860 } 00861 00862 if (!skip && ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl) 00863 != SSL_SUCCESS) { 00864 WOLFSSL_MSG("CRL file load failed, continuing"); 00865 } 00866 00867 ret = wc_ReadDirNext(readCtx, path, &name); 00868 } 00869 wc_ReadDirClose(readCtx); 00870 ret = SSL_SUCCESS; /* load failures not reported, for backwards compat */ 00871 00872 #ifdef WOLFSSL_SMALL_STACK 00873 XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); 00874 #endif 00875 00876 if (monitor & WOLFSSL_CRL_MONITOR) { 00877 word32 pathLen; 00878 char* pathBuf; 00879 00880 WOLFSSL_MSG("monitor path requested"); 00881 00882 pathLen = (word32)XSTRLEN(path); 00883 pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR); 00884 if (pathBuf) { 00885 XSTRNCPY(pathBuf, path, pathLen); 00886 pathBuf[pathLen] = '\0'; /* Null Terminate */ 00887 00888 if (type == SSL_FILETYPE_PEM) { 00889 /* free old path before setting a new one */ 00890 if (crl->monitors[0].path) { 00891 XFREE(crl->monitors[0].path, crl->heap, 00892 DYNAMIC_TYPE_CRL_MONITOR); 00893 } 00894 crl->monitors[0].path = pathBuf; 00895 crl->monitors[0].type = SSL_FILETYPE_PEM; 00896 } else { 00897 /* free old path before setting a new one */ 00898 if (crl->monitors[1].path) { 00899 XFREE(crl->monitors[1].path, crl->heap, 00900 DYNAMIC_TYPE_CRL_MONITOR); 00901 } 00902 crl->monitors[1].path = pathBuf; 00903 crl->monitors[1].type = SSL_FILETYPE_ASN1; 00904 } 00905 00906 if (monitor & WOLFSSL_CRL_START_MON) { 00907 WOLFSSL_MSG("start monitoring requested"); 00908 00909 ret = StartMonitorCRL(crl); 00910 } 00911 } 00912 else { 00913 ret = MEMORY_E; 00914 } 00915 } 00916 00917 return ret; 00918 } 00919 00920 #else 00921 int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) 00922 { 00923 (void)crl; 00924 (void)path; 00925 (void)type; 00926 (void)monitor; 00927 00928 /* stub for scenario where file system is not supported */ 00929 return NOT_COMPILED_IN; 00930 } 00931 #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */ 00932 00933 #endif /* HAVE_CRL */ 00934 #endif /* !WOLFCRYPT_ONLY */ 00935
Generated on Tue Jul 12 2022 23:30:55 by
1.7.2
