MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers crl.c Source File

crl.c

00001 /* crl.c
00002  *
00003  * Copyright (C) 2006-2014 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL 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  * CyaSSL 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-1301, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifdef HAVE_CRL
00029 
00030 #include <cyassl/internal.h>
00031 #include <cyassl/error-ssl.h>
00032 
00033 #include <dirent.h>
00034 #include <sys/stat.h>
00035 #include <string.h>
00036 
00037 #ifdef HAVE_CRL_MONITOR
00038     static int StopMonitor(int mfd);
00039 #endif
00040 
00041 
00042 /* Initialze CRL members */
00043 int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm)
00044 {
00045     CYASSL_ENTER("InitCRL");
00046 
00047     crl->cm = cm;
00048     crl->crlList = NULL;
00049     crl->monitors[0].path = NULL;
00050     crl->monitors[1].path = NULL;
00051 #ifdef HAVE_CRL_MONITOR
00052     crl->tid =  0;
00053     crl->mfd = -1;   /* mfd for bsd is kqueue fd, eventfd for linux */
00054 #endif
00055     if (InitMutex(&crl->crlLock) != 0)
00056         return BAD_MUTEX_E; 
00057 
00058     return 0;
00059 }
00060 
00061 
00062 /* Initialze CRL Entry */
00063 static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
00064 {
00065     CYASSL_ENTER("InitCRL_Entry");
00066 
00067     XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE);
00068     /* XMEMCPY(crle->crlHash, dcrl->crlHash, SHA_DIGEST_SIZE);
00069      *   copy the hash here if needed for optimized comparisons */
00070     XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
00071     XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
00072     crle->lastDateFormat = dcrl->lastDateFormat;
00073     crle->nextDateFormat = dcrl->nextDateFormat;
00074 
00075     crle->certs = dcrl->certs;   /* take ownsership */
00076     dcrl->certs = NULL;
00077     crle->totalCerts = dcrl->totalCerts;
00078 
00079     return 0;
00080 }
00081 
00082 
00083 /* Free all CRL Entry resources */
00084 static void FreeCRL_Entry(CRL_Entry* crle)
00085 {
00086     RevokedCert* tmp = crle->certs; 
00087 
00088     CYASSL_ENTER("FreeCRL_Entry");
00089 
00090     while(tmp) {
00091         RevokedCert* next = tmp->next;
00092         XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
00093         tmp = next;
00094     }
00095 }
00096 
00097 
00098 
00099 /* Free all CRL resources */
00100 void FreeCRL(CYASSL_CRL* crl, int dynamic)
00101 {
00102     CRL_Entry* tmp = crl->crlList;
00103 
00104     CYASSL_ENTER("FreeCRL");
00105 
00106     if (crl->monitors[0].path)
00107         XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
00108 
00109     if (crl->monitors[1].path)
00110         XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
00111 
00112     while(tmp) {
00113         CRL_Entry* next = tmp->next;
00114         FreeCRL_Entry(tmp);
00115         XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY);
00116         tmp = next;
00117     }   
00118 
00119 #ifdef HAVE_CRL_MONITOR
00120     if (crl->tid != 0) {
00121         CYASSL_MSG("stopping monitor thread");
00122         if (StopMonitor(crl->mfd) == 0)
00123             pthread_join(crl->tid, NULL);
00124         else {
00125             CYASSL_MSG("stop monitor failed, cancel instead");
00126             pthread_cancel(crl->tid);
00127         }
00128     }
00129 #endif
00130     FreeMutex(&crl->crlLock);
00131     if (dynamic)   /* free self */
00132         XFREE(crl, NULL, DYNAMIC_TYPE_CRL);
00133 }
00134 
00135 
00136 /* Is the cert ok with CRL, return 0 on success */
00137 int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
00138 {
00139     CRL_Entry* crle;
00140     int        foundEntry = 0;
00141     int        ret = 0;
00142 
00143     CYASSL_ENTER("CheckCertCRL");
00144 
00145     if (LockMutex(&crl->crlLock) != 0) {
00146         CYASSL_MSG("LockMutex failed");
00147         return BAD_MUTEX_E;
00148     }
00149 
00150     crle = crl->crlList;
00151 
00152     while (crle) {
00153         if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) {
00154             CYASSL_MSG("Found CRL Entry on list");
00155             CYASSL_MSG("Checking next date validity");
00156 
00157             if (!ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) {
00158                 CYASSL_MSG("CRL next date is no longer valid");
00159                 ret = ASN_AFTER_DATE_E;
00160             }
00161             else
00162                 foundEntry = 1;
00163             break;
00164         }
00165         crle = crle->next;
00166     }
00167 
00168     if (foundEntry) {
00169         RevokedCert* rc = crle->certs;
00170 
00171         while (rc) {
00172             if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
00173                 CYASSL_MSG("Cert revoked");
00174                 ret = CRL_CERT_REVOKED;
00175                 break;
00176             }
00177             rc = rc->next;  
00178         }
00179     }
00180 
00181     UnLockMutex(&crl->crlLock);
00182 
00183     if (foundEntry == 0) {
00184         CYASSL_MSG("Couldn't find CRL for status check");
00185         ret = CRL_MISSING;
00186         if (crl->cm->cbMissingCRL) {
00187             char url[256];
00188 
00189             CYASSL_MSG("Issuing missing CRL callback");
00190             url[0] = '\0';
00191             if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
00192                 XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
00193                 url[cert->extCrlInfoSz] = '\0';
00194             }
00195             else  {
00196                 CYASSL_MSG("CRL url too long");
00197             }
00198             crl->cm->cbMissingCRL(url);
00199         }
00200     }
00201 
00202 
00203     return ret; 
00204 }
00205 
00206 
00207 /* Add Decoded CRL, 0 on success */
00208 static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl)
00209 {
00210     CRL_Entry* crle;
00211 
00212     CYASSL_ENTER("AddCRL");
00213 
00214     crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
00215     if (crle == NULL) {
00216         CYASSL_MSG("alloc CRL Entry failed");
00217         return -1;
00218     }
00219 
00220     if (InitCRL_Entry(crle, dcrl) < 0) {
00221         CYASSL_MSG("Init CRL Entry failed");
00222         XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
00223         return -1;
00224     }
00225 
00226     if (LockMutex(&crl->crlLock) != 0) {
00227         CYASSL_MSG("LockMutex failed");
00228         FreeCRL_Entry(crle);
00229         XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
00230         return BAD_MUTEX_E;
00231     }
00232     crle->next = crl->crlList;
00233     crl->crlList = crle;
00234     UnLockMutex(&crl->crlLock);
00235 
00236     return 0;
00237 }
00238 
00239 
00240 /* Load CRL File of type, SSL_SUCCESS on ok */
00241 int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type)
00242 {
00243     int          ret = SSL_SUCCESS;
00244     const byte*  myBuffer = buff;    /* if DER ok, otherwise switch */
00245     buffer       der;
00246 #ifdef CYASSL_SMALL_STACK
00247     DecodedCRL*  dcrl;
00248 #else
00249     DecodedCRL   dcrl[1];
00250 #endif
00251 
00252     der.buffer = NULL;
00253 
00254     CYASSL_ENTER("BufferLoadCRL");
00255 
00256     if (crl == NULL || buff == NULL || sz == 0)
00257         return BAD_FUNC_ARG;
00258 
00259     if (type == SSL_FILETYPE_PEM) {
00260         int eccKey = 0;   /* not used */
00261         EncryptedInfo info;
00262         info.ctx = NULL;
00263 
00264         ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
00265         if (ret == 0) {
00266             myBuffer = der.buffer;
00267             sz = der.length;
00268         }
00269         else {
00270             CYASSL_MSG("Pem to Der failed");
00271             return -1;
00272         }
00273     }
00274 
00275 #ifdef CYASSL_SMALL_STACK
00276     dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
00277     if (dcrl == NULL) {
00278         if (der.buffer)
00279             XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
00280 
00281         return MEMORY_E;
00282     }
00283 #endif
00284 
00285     InitDecodedCRL(dcrl);
00286     ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
00287     if (ret != 0) {
00288         CYASSL_MSG("ParseCRL error");
00289     }
00290     else {
00291         ret = AddCRL(crl, dcrl);
00292         if (ret != 0) {
00293             CYASSL_MSG("AddCRL error");
00294         }
00295     }
00296 
00297     FreeDecodedCRL(dcrl);
00298 
00299 #ifdef CYASSL_SMALL_STACK
00300     XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00301 #endif
00302 
00303     if (der.buffer)
00304         XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
00305 
00306     return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */
00307 }
00308 
00309 
00310 #ifdef HAVE_CRL_MONITOR
00311 
00312 
00313 /* read in new CRL entries and save new list */
00314 static int SwapLists(CYASSL_CRL* crl)
00315 {
00316     int        ret;
00317     CRL_Entry* newList;
00318 #ifdef CYASSL_SMALL_STACK
00319     CYASSL_CRL* tmp;    
00320 #else
00321     CYASSL_CRL tmp[1];
00322 #endif
00323     
00324 #ifdef CYASSL_SMALL_STACK
00325     tmp = (CYASSL_CRL*)XMALLOC(sizeof(CYASSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
00326     if (tmp == NULL)
00327         return MEMORY_E;
00328 #endif   
00329 
00330     if (InitCRL(tmp, crl->cm) < 0) {
00331         CYASSL_MSG("Init tmp CRL failed");
00332 #ifdef CYASSL_SMALL_STACK
00333         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00334 #endif
00335         return -1;
00336     }
00337 
00338     if (crl->monitors[0].path) {
00339         ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
00340         if (ret != SSL_SUCCESS) {
00341             CYASSL_MSG("PEM LoadCRL on dir change failed");
00342             FreeCRL(tmp, 0);
00343 #ifdef CYASSL_SMALL_STACK
00344             XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00345 #endif
00346             return -1;
00347         }
00348     }
00349 
00350     if (crl->monitors[1].path) {
00351         ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
00352         if (ret != SSL_SUCCESS) {
00353             CYASSL_MSG("DER LoadCRL on dir change failed");
00354             FreeCRL(tmp, 0);
00355 #ifdef CYASSL_SMALL_STACK
00356             XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00357 #endif
00358             return -1;
00359         }
00360     }
00361 
00362     if (LockMutex(&crl->crlLock) != 0) {
00363         CYASSL_MSG("LockMutex failed");
00364         FreeCRL(tmp, 0);
00365 #ifdef CYASSL_SMALL_STACK
00366         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00367 #endif
00368         return -1;
00369     }
00370 
00371     newList = tmp->crlList;
00372 
00373     /* swap lists */
00374     tmp->crlList  = crl->crlList;
00375     crl->crlList = newList;
00376 
00377     UnLockMutex(&crl->crlLock);
00378 
00379     FreeCRL(tmp, 0);
00380 
00381 #ifdef CYASSL_SMALL_STACK
00382     XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00383 #endif
00384 
00385     return 0;
00386 }
00387 
00388 
00389 #if (defined(__MACH__) || defined(__FreeBSD__))
00390 
00391 #include <sys/types.h>
00392 #include <sys/event.h>
00393 #include <sys/time.h>
00394 #include <fcntl.h>
00395 #include <unistd.h>
00396 
00397 #ifdef __MACH__
00398     #define XEVENT_MODE O_EVTONLY
00399 #elif defined(__FreeBSD__)
00400     #define XEVENT_MODE EVFILT_VNODE
00401 #endif
00402 
00403 
00404 /* we need a unique kqueue user filter fd for crl in case user is doing custom
00405  * events too */
00406 #ifndef CRL_CUSTOM_FD
00407     #define CRL_CUSTOM_FD 123456
00408 #endif
00409 
00410 
00411 /* shutdown monitor thread, 0 on success */
00412 static int StopMonitor(int mfd)
00413 {
00414     struct kevent change;
00415 
00416     /* trigger custom shutdown */
00417     EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
00418     if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
00419         CYASSL_MSG("kevent trigger customer event failed");
00420         return -1;
00421     }
00422 
00423     return 0;
00424 }
00425 
00426 
00427 /* OS X  monitoring */
00428 static void* DoMonitor(void* arg)
00429 {
00430     int fPEM, fDER;
00431     struct kevent change;
00432 
00433     CYASSL_CRL* crl = (CYASSL_CRL*)arg;
00434 
00435     CYASSL_ENTER("DoMonitor");
00436 
00437     crl->mfd = kqueue();
00438     if (crl->mfd == -1) {
00439         CYASSL_MSG("kqueue failed");
00440         return NULL;
00441     }
00442 
00443     /* listen for custom shutdown event */
00444     EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
00445     if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
00446         CYASSL_MSG("kevent monitor customer event failed");
00447         close(crl->mfd);
00448         return NULL;
00449     }
00450 
00451     fPEM = -1;
00452     fDER = -1;
00453 
00454     if (crl->monitors[0].path) {
00455         fPEM = open(crl->monitors[0].path, XEVENT_MODE);
00456         if (fPEM == -1) {
00457             CYASSL_MSG("PEM event dir open failed");
00458             close(crl->mfd);
00459             return NULL;
00460         }
00461     }
00462 
00463     if (crl->monitors[1].path) {
00464         fDER = open(crl->monitors[1].path, XEVENT_MODE);
00465         if (fDER == -1) {
00466             CYASSL_MSG("DER event dir open failed");
00467             close(crl->mfd);
00468             return NULL;
00469         }
00470     }
00471 
00472     if (fPEM != -1)
00473         EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
00474                 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
00475 
00476     if (fDER != -1)
00477         EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
00478                 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
00479 
00480     for (;;) {
00481         struct kevent event;
00482         int           numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
00483        
00484         CYASSL_MSG("Got kevent");
00485 
00486         if (numEvents == -1) {
00487             CYASSL_MSG("kevent problem, continue");
00488             continue;
00489         }
00490 
00491         if (event.filter == EVFILT_USER) {
00492             CYASSL_MSG("Got user shutdown event, breaking out");
00493             break;
00494         }
00495 
00496         if (SwapLists(crl) < 0) {
00497             CYASSL_MSG("SwapLists problem, continue");
00498         }
00499     }
00500 
00501     if (fPEM != -1)
00502         close(fPEM);
00503     if (fDER != -1)
00504         close(fDER);
00505 
00506     close(crl->mfd);
00507 
00508     return NULL;
00509 }
00510 
00511 
00512 #elif defined(__linux__)
00513 
00514 #include <sys/types.h>
00515 #include <sys/inotify.h>
00516 #include <sys/eventfd.h>
00517 #include <unistd.h>
00518 
00519 
00520 #ifndef max
00521     static INLINE int max(int a, int b)
00522     {
00523         return a > b ? a : b;
00524     }
00525 #endif /* max */
00526 
00527 
00528 /* shutdown monitor thread, 0 on success */
00529 static int StopMonitor(int mfd)
00530 {
00531     word64 w64 = 1;
00532 
00533     /* write to our custom event */
00534     if (write(mfd, &w64, sizeof(w64)) < 0) {
00535         CYASSL_MSG("StopMonitor write failed");
00536         return -1;
00537     }
00538 
00539     return 0;
00540 }
00541 
00542 
00543 /* linux monitoring */
00544 static void* DoMonitor(void* arg)
00545 {
00546     int         notifyFd;
00547     int         wd  = -1;
00548     CYASSL_CRL* crl = (CYASSL_CRL*)arg;
00549 #ifdef CYASSL_SMALL_STACK
00550     char*       buff;
00551 #else
00552     char        buff[8192];
00553 #endif
00554 
00555     CYASSL_ENTER("DoMonitor");
00556 
00557     crl->mfd = eventfd(0, 0);  /* our custom shutdown event */
00558     if (crl->mfd < 0) {
00559         CYASSL_MSG("eventfd failed");
00560         return NULL;
00561     }
00562 
00563     notifyFd = inotify_init();
00564     if (notifyFd < 0) {
00565         CYASSL_MSG("inotify failed");
00566         close(crl->mfd);
00567         return NULL;
00568     }
00569 
00570     if (crl->monitors[0].path) {
00571         wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
00572                                                                 IN_DELETE);
00573         if (wd < 0) {
00574             CYASSL_MSG("PEM notify add watch failed");
00575             close(crl->mfd);
00576             close(notifyFd);
00577             return NULL;
00578         }
00579     }
00580 
00581     if (crl->monitors[1].path) {
00582         wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
00583                                                                 IN_DELETE);
00584         if (wd < 0) {
00585             CYASSL_MSG("DER notify add watch failed");
00586             close(crl->mfd);
00587             close(notifyFd);
00588             return NULL;
00589         }
00590     }
00591 
00592 #ifdef CYASSL_SMALL_STACK
00593     buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00594     if (buff == NULL)
00595         return NULL;
00596 #endif
00597 
00598     for (;;) {
00599         fd_set readfds;
00600         int    result;
00601         int    length;
00602 
00603         FD_ZERO(&readfds);
00604         FD_SET(notifyFd, &readfds);
00605         FD_SET(crl->mfd, &readfds);
00606 
00607         result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
00608        
00609         CYASSL_MSG("Got notify event");
00610 
00611         if (result < 0) {
00612             CYASSL_MSG("select problem, continue");
00613             continue;
00614         }
00615 
00616         if (FD_ISSET(crl->mfd, &readfds)) {
00617             CYASSL_MSG("got custom shutdown event, breaking out");
00618             break;
00619         }
00620 
00621         length = read(notifyFd, buff, 8192);
00622         if (length < 0) {
00623             CYASSL_MSG("notify read problem, continue");
00624             continue;
00625         } 
00626 
00627         if (SwapLists(crl) < 0) {
00628             CYASSL_MSG("SwapLists problem, continue");
00629         }
00630     }
00631 
00632 #ifdef CYASSL_SMALL_STACK
00633     XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00634 #endif
00635 
00636     if (wd > 0)
00637         inotify_rm_watch(notifyFd, wd);
00638     close(crl->mfd);
00639     close(notifyFd);
00640 
00641     return NULL;
00642 }
00643 
00644 
00645 #else
00646 
00647 #error "CRL monitor only currently supported on linux or mach"
00648 
00649 #endif /* MACH or linux */
00650 
00651 
00652 /* Start Monitoring the CRL path(s) in a thread */
00653 static int StartMonitorCRL(CYASSL_CRL* crl)
00654 {
00655     pthread_attr_t attr;
00656 
00657     CYASSL_ENTER("StartMonitorCRL");
00658 
00659     if (crl == NULL) 
00660         return BAD_FUNC_ARG;
00661 
00662     if (crl->tid != 0) {
00663         CYASSL_MSG("Monitor thread already running");
00664         return MONITOR_RUNNING_E;
00665     }
00666 
00667     pthread_attr_init(&attr);
00668 
00669     if (pthread_create(&crl->tid, &attr, DoMonitor, crl) != 0) {
00670         CYASSL_MSG("Thread creation error");
00671         return THREAD_CREATE_E;
00672     }
00673 
00674     return SSL_SUCCESS;
00675 }
00676 
00677 
00678 #else /* HAVE_CRL_MONITOR */
00679 
00680 static int StartMonitorCRL(CYASSL_CRL* crl)
00681 {
00682     (void)crl;
00683 
00684     CYASSL_ENTER("StartMonitorCRL");
00685     CYASSL_MSG("Not compiled in");
00686 
00687     return NOT_COMPILED_IN;
00688 }
00689 
00690 #endif  /* HAVE_CRL_MONITOR */
00691 
00692 
00693 /* Load CRL path files of type, SSL_SUCCESS on ok */ 
00694 int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
00695 {
00696     struct dirent* entry;
00697     DIR*           dir;
00698     int            ret = SSL_SUCCESS;
00699 #ifdef CYASSL_SMALL_STACK
00700     char*          name;
00701 #else
00702     char           name[MAX_FILENAME_SZ];
00703 #endif
00704 
00705     CYASSL_ENTER("LoadCRL");
00706     if (crl == NULL)
00707         return BAD_FUNC_ARG;
00708 
00709     dir = opendir(path);
00710     if (dir == NULL) {
00711         CYASSL_MSG("opendir path crl load failed");
00712         return BAD_PATH_ERROR;
00713     }
00714 
00715 #ifdef CYASSL_SMALL_STACK
00716     name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00717     if (name == NULL)
00718         return MEMORY_E;
00719 #endif
00720 
00721     while ( (entry = readdir(dir)) != NULL) {
00722         struct stat s;
00723 
00724         XMEMSET(name, 0, MAX_FILENAME_SZ);
00725         XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
00726         XSTRNCAT(name, "/", 1);
00727         XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
00728 
00729         if (stat(name, &s) != 0) {
00730             CYASSL_MSG("stat on name failed");
00731             continue;
00732         }
00733         if (s.st_mode & S_IFREG) {
00734 
00735             if (type == SSL_FILETYPE_PEM) {
00736                 if (strstr(entry->d_name, ".pem") == NULL) {
00737                     CYASSL_MSG("not .pem file, skipping");
00738                     continue;
00739                 }
00740             }
00741             else {
00742                 if (strstr(entry->d_name, ".der") == NULL &&
00743                     strstr(entry->d_name, ".crl") == NULL) {
00744 
00745                     CYASSL_MSG("not .der or .crl file, skipping");
00746                     continue;
00747                 }
00748             }
00749 
00750             if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
00751                                                                != SSL_SUCCESS) {
00752                 CYASSL_MSG("CRL file load failed, continuing");
00753             }
00754         }
00755     }
00756 
00757 #ifdef CYASSL_SMALL_STACK
00758     XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00759 #endif
00760 
00761     if (monitor & CYASSL_CRL_MONITOR) {
00762         CYASSL_MSG("monitor path requested");
00763 
00764         if (type == SSL_FILETYPE_PEM) {
00765             crl->monitors[0].path = strdup(path);
00766             crl->monitors[0].type = SSL_FILETYPE_PEM;
00767             if (crl->monitors[0].path == NULL)
00768                 ret = MEMORY_E;
00769         } else {
00770             crl->monitors[1].path = strdup(path);
00771             crl->monitors[1].type = SSL_FILETYPE_ASN1;
00772             if (crl->monitors[1].path == NULL)
00773                 ret = MEMORY_E;
00774         }
00775       
00776         if (monitor & CYASSL_CRL_START_MON) {
00777             CYASSL_MSG("start monitoring requested");
00778     
00779             ret = StartMonitorCRL(crl);
00780        } 
00781     }
00782     
00783     closedir(dir);
00784 
00785     return ret;
00786 }
00787 
00788 #endif /* HAVE_CRL */