1 /* crl.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23 /* Name change compatibility layer no longer needs included here */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <wolfssl/wolfcrypt/settings.h>
30
31 #ifndef WOLFCRYPT_ONLY
32 #ifdef HAVE_CRL
33
34 #include <wolfssl/internal.h>
35 #include <wolfssl/error-ssl.h>
36
37 #ifndef WOLFSSL_LINUXKM
38 #include <string.h>
39 #endif
40
41 #ifdef HAVE_CRL_MONITOR
42 #if (defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__))
43 static int StopMonitor(int mfd);
44 #else
45 #error "CRL monitor only currently supported on linux or mach"
46 #endif
47 #endif /* HAVE_CRL_MONITOR */
48
49
50 /* Initialize CRL members */
InitCRL(WOLFSSL_CRL * crl,WOLFSSL_CERT_MANAGER * cm)51 int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
52 {
53 WOLFSSL_ENTER("InitCRL");
54 if(cm != NULL)
55 crl->heap = cm->heap;
56 else
57 crl->heap = NULL;
58 crl->cm = cm;
59 crl->crlList = NULL;
60 crl->monitors[0].path = NULL;
61 crl->monitors[1].path = NULL;
62 #ifdef HAVE_CRL_MONITOR
63 crl->tid = 0;
64 crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */
65 crl->setup = 0; /* thread setup done predicate */
66 if (pthread_cond_init(&crl->cond, 0) != 0) {
67 WOLFSSL_MSG("Pthread condition init failed");
68 return BAD_COND_E;
69 }
70 #endif
71 if (wc_InitMutex(&crl->crlLock) != 0) {
72 WOLFSSL_MSG("Init Mutex failed");
73 return BAD_MUTEX_E;
74 }
75
76 return 0;
77 }
78
79
80 /* Initialize CRL Entry */
InitCRL_Entry(CRL_Entry * crle,DecodedCRL * dcrl,const byte * buff,int verified,void * heap)81 static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
82 int verified, void* heap)
83 {
84 WOLFSSL_ENTER("InitCRL_Entry");
85
86 XMEMCPY(crle->issuerHash, dcrl->issuerHash, CRL_DIGEST_SIZE);
87 /* XMEMCPY(crle->crlHash, dcrl->crlHash, CRL_DIGEST_SIZE);
88 * copy the hash here if needed for optimized comparisons */
89 XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
90 XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
91 crle->lastDateFormat = dcrl->lastDateFormat;
92 crle->nextDateFormat = dcrl->nextDateFormat;
93
94 crle->certs = dcrl->certs; /* take ownsership */
95 dcrl->certs = NULL;
96 crle->totalCerts = dcrl->totalCerts;
97 crle->verified = verified;
98 if (!verified) {
99 crle->tbsSz = dcrl->sigIndex - dcrl->certBegin;
100 crle->signatureSz = dcrl->sigLength;
101 crle->signatureOID = dcrl->signatureOID;
102 crle->toBeSigned = (byte*)XMALLOC(crle->tbsSz, heap,
103 DYNAMIC_TYPE_CRL_ENTRY);
104 if (crle->toBeSigned == NULL)
105 return -1;
106 crle->signature = (byte*)XMALLOC(crle->signatureSz, heap,
107 DYNAMIC_TYPE_CRL_ENTRY);
108 if (crle->signature == NULL) {
109 XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_CRL_ENTRY);
110 return -1;
111 }
112 XMEMCPY(crle->toBeSigned, buff + dcrl->certBegin, crle->tbsSz);
113 XMEMCPY(crle->signature, dcrl->signature, crle->signatureSz);
114 #ifndef NO_SKID
115 crle->extAuthKeyIdSet = dcrl->extAuthKeyIdSet;
116 if (crle->extAuthKeyIdSet)
117 XMEMCPY(crle->extAuthKeyId, dcrl->extAuthKeyId, KEYID_SIZE);
118 #endif
119 }
120 else {
121 crle->toBeSigned = NULL;
122 crle->signature = NULL;
123 }
124
125 (void)verified;
126 (void)heap;
127
128 return 0;
129 }
130
131
132 /* Free all CRL Entry resources */
FreeCRL_Entry(CRL_Entry * crle,void * heap)133 static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
134 {
135 RevokedCert* tmp = crle->certs;
136 RevokedCert* next;
137
138 WOLFSSL_ENTER("FreeCRL_Entry");
139
140 while (tmp) {
141 next = tmp->next;
142 XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED);
143 tmp = next;
144 }
145 if (crle->signature != NULL)
146 XFREE(crle->signature, heap, DYNAMIC_TYPE_REVOKED);
147 if (crle->toBeSigned != NULL)
148 XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_REVOKED);
149
150 (void)heap;
151 }
152
153
154
155 /* Free all CRL resources */
FreeCRL(WOLFSSL_CRL * crl,int dynamic)156 void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
157 {
158 CRL_Entry* tmp = crl->crlList;
159
160 WOLFSSL_ENTER("FreeCRL");
161 if (crl->monitors[0].path)
162 XFREE(crl->monitors[0].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
163
164 if (crl->monitors[1].path)
165 XFREE(crl->monitors[1].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
166
167 while(tmp) {
168 CRL_Entry* next = tmp->next;
169 FreeCRL_Entry(tmp, crl->heap);
170 XFREE(tmp, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
171 tmp = next;
172 }
173
174 #ifdef HAVE_CRL_MONITOR
175 if (crl->tid != 0) {
176 WOLFSSL_MSG("stopping monitor thread");
177 if (StopMonitor(crl->mfd) == 0)
178 pthread_join(crl->tid, NULL);
179 else {
180 WOLFSSL_MSG("stop monitor failed");
181 }
182 }
183 pthread_cond_destroy(&crl->cond);
184 #endif
185 wc_FreeMutex(&crl->crlLock);
186 if (dynamic) /* free self */
187 XFREE(crl, crl->heap, DYNAMIC_TYPE_CRL);
188 }
189
190
CheckCertCRLList(WOLFSSL_CRL * crl,DecodedCert * cert,int * pFoundEntry)191 static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntry)
192 {
193 CRL_Entry* crle;
194 int foundEntry = 0;
195 int ret = 0;
196
197 if (wc_LockMutex(&crl->crlLock) != 0) {
198 WOLFSSL_MSG("wc_LockMutex failed");
199 return BAD_MUTEX_E;
200 }
201
202 crle = crl->crlList;
203
204 while (crle) {
205 if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) {
206 WOLFSSL_MSG("Found CRL Entry on list");
207
208 if (crle->verified == 0) {
209 Signer* ca = NULL;
210 #ifndef NO_SKID
211 byte extAuthKeyId[KEYID_SIZE];
212 #endif
213 byte issuerHash[CRL_DIGEST_SIZE];
214 byte* tbs;
215 word32 tbsSz = crle->tbsSz;
216 byte* sig = NULL;
217 word32 sigSz = crle->signatureSz;
218 word32 sigOID = crle->signatureOID;
219 SignatureCtx sigCtx;
220
221 tbs = (byte*)XMALLOC(tbsSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
222 if (tbs == NULL) {
223 wc_UnLockMutex(&crl->crlLock);
224 return MEMORY_E;
225 }
226 sig = (byte*)XMALLOC(sigSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
227 if (sig == NULL) {
228 XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
229 wc_UnLockMutex(&crl->crlLock);
230 return MEMORY_E;
231 }
232
233 XMEMCPY(tbs, crle->toBeSigned, tbsSz);
234 XMEMCPY(sig, crle->signature, sigSz);
235 #ifndef NO_SKID
236 XMEMCPY(extAuthKeyId, crle->extAuthKeyId,
237 sizeof(extAuthKeyId));
238 #endif
239 XMEMCPY(issuerHash, crle->issuerHash, sizeof(issuerHash));
240
241 wc_UnLockMutex(&crl->crlLock);
242
243 #ifndef NO_SKID
244 if (crle->extAuthKeyIdSet)
245 ca = GetCA(crl->cm, extAuthKeyId);
246 if (ca == NULL)
247 ca = GetCAByName(crl->cm, issuerHash);
248 #else /* NO_SKID */
249 ca = GetCA(crl->cm, issuerHash);
250 #endif /* NO_SKID */
251 if (ca == NULL) {
252 XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
253 XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
254 WOLFSSL_MSG("Did NOT find CRL issuer CA");
255 return ASN_CRL_NO_SIGNER_E;
256 }
257
258 ret = VerifyCRL_Signature(&sigCtx, tbs, tbsSz, sig, sigSz,
259 sigOID, ca, crl->heap);
260
261 XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
262 XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
263
264 if (wc_LockMutex(&crl->crlLock) != 0) {
265 WOLFSSL_MSG("wc_LockMutex failed");
266 return BAD_MUTEX_E;
267 }
268
269 crle = crl->crlList;
270 while (crle) {
271 if (XMEMCMP(crle->issuerHash, cert->issuerHash,
272 CRL_DIGEST_SIZE) == 0) {
273
274 if (ret == 0)
275 crle->verified = 1;
276 else
277 crle->verified = ret;
278
279 XFREE(crle->toBeSigned, crl->heap,
280 DYNAMIC_TYPE_CRL_ENTRY);
281 crle->toBeSigned = NULL;
282 XFREE(crle->signature, crl->heap,
283 DYNAMIC_TYPE_CRL_ENTRY);
284 crle->signature = NULL;
285 break;
286 }
287 crle = crle->next;
288 }
289 if (crle == NULL || crle->verified < 0)
290 break;
291 }
292 else if (crle->verified < 0) {
293 WOLFSSL_MSG("Cannot use CRL as it didn't verify");
294 ret = crle->verified;
295 break;
296 }
297
298 WOLFSSL_MSG("Checking next date validity");
299
300 #ifdef WOLFSSL_NO_CRL_NEXT_DATE
301 if (crle->nextDateFormat != ASN_OTHER_TYPE)
302 #endif
303 {
304 #ifndef NO_ASN_TIME
305 if (!XVALIDATE_DATE(crle->nextDate,crle->nextDateFormat, AFTER)) {
306 WOLFSSL_MSG("CRL next date is no longer valid");
307 ret = ASN_AFTER_DATE_E;
308 }
309 #endif
310 }
311 if (ret == 0) {
312 foundEntry = 1;
313 }
314 break;
315 }
316 crle = crle->next;
317 }
318
319 if (foundEntry) {
320 RevokedCert* rc = crle->certs;
321
322 while (rc) {
323 if (rc->serialSz == cert->serialSz &&
324 XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
325 WOLFSSL_MSG("Cert revoked");
326 ret = CRL_CERT_REVOKED;
327 break;
328 }
329 rc = rc->next;
330 }
331 }
332
333 wc_UnLockMutex(&crl->crlLock);
334
335 *pFoundEntry = foundEntry;
336
337 return ret;
338 }
339
340 /* Is the cert ok with CRL, return 0 on success */
CheckCertCRL(WOLFSSL_CRL * crl,DecodedCert * cert)341 int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
342 {
343 int foundEntry = 0;
344 int ret = 0;
345
346 WOLFSSL_ENTER("CheckCertCRL");
347
348 #ifdef WOLFSSL_CRL_ALLOW_MISSING_CDP
349 /* Skip CRL verification in case no CDP in peer cert */
350 if (!cert->extCrlInfo) {
351 return ret;
352 }
353 #endif
354
355 ret = CheckCertCRLList(crl, cert, &foundEntry);
356
357 #ifdef HAVE_CRL_IO
358 if (foundEntry == 0) {
359 /* perform embedded lookup */
360 if (crl->crlIOCb) {
361 ret = crl->crlIOCb(crl, (const char*)cert->extCrlInfo,
362 cert->extCrlInfoSz);
363 if (ret == WOLFSSL_CBIO_ERR_WANT_READ) {
364 ret = OCSP_WANT_READ;
365 }
366 else if (ret >= 0) {
367 /* try again */
368 ret = CheckCertCRLList(crl, cert, &foundEntry);
369 }
370 }
371 }
372 #endif
373
374 #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
375 (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
376 !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
377 /* if not find entry in the CRL list, it looks at the folder that sets */
378 /* by LOOKUP_ctrl because user would want to use hash_dir. */
379 /* Loading <issuer-hash>.rN form CRL file if find at the folder, */
380 /* and try again checking Cert in the CRL list. */
381 /* When not set the folder or not use hash_dir, do nothing. */
382 if ((foundEntry == 0) && (ret != OCSP_WANT_READ)) {
383 if (crl->cm->x509_store_p != NULL) {
384 ret = LoadCertByIssuer(crl->cm->x509_store_p,
385 (WOLFSSL_X509_NAME*)cert->issuerName, X509_LU_CRL);
386 if (ret == WOLFSSL_SUCCESS) {
387 /* try again */
388 ret = CheckCertCRLList(crl, cert, &foundEntry);
389 }
390 }
391 }
392 #endif
393 if (foundEntry == 0) {
394 WOLFSSL_MSG("Couldn't find CRL for status check");
395 if (ret != CRL_CERT_DATE_ERR) {
396 ret = CRL_MISSING;
397 }
398
399 if (crl->cm->cbMissingCRL) {
400 char url[256];
401
402 WOLFSSL_MSG("Issuing missing CRL callback");
403 url[0] = '\0';
404 if (cert->extCrlInfo) {
405 if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
406 XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
407 url[cert->extCrlInfoSz] = '\0';
408 }
409 else {
410 WOLFSSL_MSG("CRL url too long");
411 }
412 }
413
414 crl->cm->cbMissingCRL(url);
415 }
416 }
417
418 return ret;
419 }
420
421
422 /* Add Decoded CRL, 0 on success */
AddCRL(WOLFSSL_CRL * crl,DecodedCRL * dcrl,const byte * buff,int verified)423 static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
424 int verified)
425 {
426 CRL_Entry* crle;
427
428 WOLFSSL_ENTER("AddCRL");
429
430 crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
431 if (crle == NULL) {
432 WOLFSSL_MSG("alloc CRL Entry failed");
433 return -1;
434 }
435
436 if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
437 WOLFSSL_MSG("Init CRL Entry failed");
438 XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
439 return -1;
440 }
441
442 if (wc_LockMutex(&crl->crlLock) != 0) {
443 WOLFSSL_MSG("wc_LockMutex failed");
444 FreeCRL_Entry(crle, crl->heap);
445 XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
446 return BAD_MUTEX_E;
447 }
448 crle->next = crl->crlList;
449 crl->crlList = crle;
450 wc_UnLockMutex(&crl->crlLock);
451
452 return 0;
453 }
454
455
456 /* Load CRL File of type, WOLFSSL_SUCCESS on ok */
BufferLoadCRL(WOLFSSL_CRL * crl,const byte * buff,long sz,int type,int verify)457 int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
458 int verify)
459 {
460 int ret = WOLFSSL_SUCCESS;
461 const byte* myBuffer = buff; /* if DER ok, otherwise switch */
462 DerBuffer* der = NULL;
463 #ifdef WOLFSSL_SMALL_STACK
464 DecodedCRL* dcrl;
465 #else
466 DecodedCRL dcrl[1];
467 #endif
468
469 WOLFSSL_ENTER("BufferLoadCRL");
470
471 if (crl == NULL || buff == NULL || sz == 0)
472 return BAD_FUNC_ARG;
473
474 if (type == WOLFSSL_FILETYPE_PEM) {
475 #ifdef WOLFSSL_PEM_TO_DER
476 ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, NULL, NULL);
477 if (ret == 0) {
478 myBuffer = der->buffer;
479 sz = der->length;
480 }
481 else {
482 WOLFSSL_MSG("Pem to Der failed");
483 FreeDer(&der);
484 return -1;
485 }
486 #else
487 ret = NOT_COMPILED_IN;
488 #endif
489 }
490
491 #ifdef WOLFSSL_SMALL_STACK
492 dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
493 if (dcrl == NULL) {
494 FreeDer(&der);
495 return MEMORY_E;
496 }
497 #endif
498
499 InitDecodedCRL(dcrl, crl->heap);
500 ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
501 if (ret != 0 && !(ret == ASN_CRL_NO_SIGNER_E && verify == NO_VERIFY)) {
502 WOLFSSL_MSG("ParseCRL error");
503 }
504 else {
505 ret = AddCRL(crl, dcrl, myBuffer, ret != ASN_CRL_NO_SIGNER_E);
506 if (ret != 0) {
507 WOLFSSL_MSG("AddCRL error");
508 }
509 }
510
511 FreeDecodedCRL(dcrl);
512
513 #ifdef WOLFSSL_SMALL_STACK
514 XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
515 #endif
516
517 FreeDer(&der);
518
519 return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
520 }
521
522 #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
523 /* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER * cm)524 static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
525 {
526 WOLFSSL_X509_CRL* ret;
527
528 ret = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), cm->heap,
529 DYNAMIC_TYPE_CRL);
530 if (ret != NULL) {
531 if (InitCRL(ret, cm) < 0) {
532 WOLFSSL_MSG("Unable to initialize new CRL structure");
533 XFREE(ret, cm->heap, DYNAMIC_TYPE_CRL);
534 ret = NULL;
535 }
536 }
537 return ret;
538 }
539
540
541 /* returns head of copied list that was alloc'd */
DupRevokedCertList(RevokedCert * in,void * heap)542 static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap)
543 {
544 RevokedCert* head = NULL;
545 RevokedCert* current = in;
546 RevokedCert* prev = NULL;
547 while (current) {
548 RevokedCert* tmp = (RevokedCert*)XMALLOC(sizeof(RevokedCert), heap,
549 DYNAMIC_TYPE_REVOKED);
550 if (tmp != NULL) {
551 XMEMCPY(tmp->serialNumber, current->serialNumber,
552 EXTERNAL_SERIAL_SIZE);
553 tmp->serialSz = current->serialSz;
554 tmp->next = NULL;
555 if (prev != NULL)
556 prev->next = tmp;
557 if (head == NULL)
558 head = tmp;
559 prev = tmp;
560 }
561 else {
562 WOLFSSL_MSG("Failed to allocate new RevokedCert structure");
563 /* free up any existing list */
564 while (head != NULL) {
565 current = head;
566 head = head->next;
567 XFREE(current, heap, DYNAMIC_TYPE_REVOKED);
568 }
569 return NULL;
570 }
571 current = current->next;
572 }
573
574 (void)heap;
575 return head;
576 }
577
578
579 /* returns a deep copy of ent on success and null on fail */
DupCRL_Entry(const CRL_Entry * ent,void * heap)580 static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap)
581 {
582 CRL_Entry *dupl;
583
584 dupl = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), heap, DYNAMIC_TYPE_CRL_ENTRY);
585 if (dupl == NULL) {
586 WOLFSSL_MSG("alloc CRL Entry failed");
587 return NULL;
588 }
589 XMEMSET(dupl, 0, sizeof(CRL_Entry));
590
591 XMEMCPY(dupl->issuerHash, ent->issuerHash, CRL_DIGEST_SIZE);
592 XMEMCPY(dupl->lastDate, ent->lastDate, MAX_DATE_SIZE);
593 XMEMCPY(dupl->nextDate, ent->nextDate, MAX_DATE_SIZE);
594 dupl->lastDateFormat = ent->lastDateFormat;
595 dupl->nextDateFormat = ent->nextDateFormat;
596 dupl->certs = DupRevokedCertList(ent->certs, heap);
597
598 dupl->totalCerts = ent->totalCerts;
599 dupl->verified = ent->verified;
600
601 if (!ent->verified) {
602 dupl->tbsSz = ent->tbsSz;
603 dupl->signatureSz = ent->signatureSz;
604 dupl->signatureOID = ent->signatureOID;
605 dupl->toBeSigned = (byte*)XMALLOC(dupl->tbsSz, heap,
606 DYNAMIC_TYPE_CRL_ENTRY);
607 if (dupl->toBeSigned == NULL) {
608 FreeCRL_Entry(dupl, heap);
609 XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
610 return NULL;
611 }
612
613 dupl->signature = (byte*)XMALLOC(dupl->signatureSz, heap,
614 DYNAMIC_TYPE_CRL_ENTRY);
615 if (dupl->signature == NULL) {
616 FreeCRL_Entry(dupl, heap);
617 XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
618 return NULL;
619 }
620 XMEMCPY(dupl->toBeSigned, ent->toBeSigned, dupl->tbsSz);
621 XMEMCPY(dupl->signature, ent->signature, dupl->signatureSz);
622 #ifndef NO_SKID
623 dupl->extAuthKeyIdSet = ent->extAuthKeyIdSet;
624 if (dupl->extAuthKeyIdSet)
625 XMEMCPY(dupl->extAuthKeyId, ent->extAuthKeyId, KEYID_SIZE);
626 #endif
627 }
628 else {
629 dupl->toBeSigned = NULL;
630 dupl->tbsSz = 0;
631 dupl->signature = NULL;
632 dupl->signatureSz = 0;
633 }
634
635 return dupl;
636 }
637
638
639 /* returns the head of a deep copy of the list on success and null on fail */
DupCRL_list(CRL_Entry * crl,void * heap)640 static CRL_Entry* DupCRL_list(CRL_Entry* crl, void* heap)
641 {
642 CRL_Entry* current;
643 CRL_Entry* head = NULL;
644 CRL_Entry* prev = NULL;
645
646 current = crl;
647 while (current != NULL) {
648 CRL_Entry* tmp = DupCRL_Entry(current, heap);
649 if (tmp != NULL) {
650 tmp->next = NULL;
651 if (head == NULL)
652 head = tmp;
653 if (prev != NULL)
654 prev->next = tmp;
655 prev = tmp;
656 }
657 else {
658 WOLFSSL_MSG("Failed to allocate new CRL_Entry structure");
659 /* free up any existing list */
660 while (head != NULL) {
661 current = head;
662 head = head->next;
663 FreeCRL_Entry(current, heap);
664 XFREE(current, heap, DYNAMIC_TYPE_CRL_ENTRY);
665 }
666
667 return NULL;
668 }
669 current = current->next;
670 }
671 return head;
672 }
673
674
675 /* Duplicates everything except the parent cm pointed to.
676 * Expects that Init has already been done to 'dupl'
677 * return 0 on success */
DupX509_CRL(WOLFSSL_X509_CRL * dupl,const WOLFSSL_X509_CRL * crl)678 static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl)
679 {
680 if (dupl == NULL || crl == NULL) {
681 return BAD_FUNC_ARG;
682 }
683
684 if (crl->monitors[0].path) {
685 int pathSz = (int)XSTRLEN(crl->monitors[0].path) + 1;
686 dupl->monitors[0].path = (char*)XMALLOC(pathSz, dupl->heap,
687 DYNAMIC_TYPE_CRL_MONITOR);
688 if (dupl->monitors[0].path != NULL) {
689 XSTRNCPY(dupl->monitors[0].path, crl->monitors[0].path, pathSz);
690 }
691 else {
692 return MEMORY_E;
693 }
694 }
695
696 if (crl->monitors[1].path) {
697 int pathSz = (int)XSTRLEN(crl->monitors[1].path) + 1;
698 dupl->monitors[1].path = (char*)XMALLOC(pathSz, dupl->heap,
699 DYNAMIC_TYPE_CRL_MONITOR);
700 if (dupl->monitors[1].path != NULL) {
701 XSTRNCPY(dupl->monitors[1].path, crl->monitors[1].path, pathSz);
702 }
703 else {
704 if (dupl->monitors[0].path != NULL) {
705 XFREE(dupl->monitors[0].path, dupl->heap,
706 DYNAMIC_TYPE_CRL_MONITOR);
707 }
708 return MEMORY_E;
709 }
710 }
711
712 dupl->crlList = DupCRL_list(crl->crlList, dupl->heap);
713 #ifdef HAVE_CRL_IO
714 dupl->crlIOCb = crl->crlIOCb;
715 #endif
716
717 return 0;
718 }
719
720 /* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */
wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE * store,WOLFSSL_X509_CRL * newcrl)721 int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
722 {
723 CRL_Entry *crle;
724 WOLFSSL_X509_CRL *crl;
725
726 WOLFSSL_ENTER("wolfSSL_X509_STORE_add_crl");
727 if (store == NULL || newcrl == NULL || store->cm == NULL)
728 return BAD_FUNC_ARG;
729
730 if (store->cm->crl == NULL) {
731 crl = wolfSSL_X509_crl_new(store->cm);
732 if (DupX509_CRL(crl, newcrl) != 0) {
733 if (crl != NULL)
734 FreeCRL(crl, 1);
735 return WOLFSSL_FAILURE;
736 }
737 store->crl = store->cm->crl = crl;
738 if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
739 != WOLFSSL_SUCCESS) {
740 WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error");
741 return WOLFSSL_FAILURE;
742 }
743 return WOLFSSL_SUCCESS;
744 }
745
746 /* find tail of current list and add new list */
747 crl = store->cm->crl;
748 crle = crl->crlList;
749 if (newcrl->crlList != NULL) {
750 CRL_Entry *tail = crle;
751 CRL_Entry *toAdd;
752
753 if (wc_LockMutex(&crl->crlLock) != 0)
754 {
755 WOLFSSL_MSG("wc_LockMutex failed");
756 return BAD_MUTEX_E;
757 }
758
759 toAdd = DupCRL_list(newcrl->crlList, crl->heap);
760 if (tail == NULL) {
761 crl->crlList = toAdd;
762 }
763 else {
764 while (tail->next != NULL) tail = tail->next;
765 tail->next = toAdd;
766 }
767 wc_UnLockMutex(&crl->crlLock);
768 }
769
770 if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
771 != WOLFSSL_SUCCESS) {
772 WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error");
773 return WOLFSSL_FAILURE;
774 }
775
776 WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_crl", WOLFSSL_SUCCESS);
777
778 return WOLFSSL_SUCCESS;
779 }
780 #endif
781
782 #ifdef HAVE_CRL_MONITOR
783
784
785 /* Signal Monitor thread is setup, save status to setup flag, 0 on success */
SignalSetup(WOLFSSL_CRL * crl,int status)786 static int SignalSetup(WOLFSSL_CRL* crl, int status)
787 {
788 int ret;
789
790 /* signal to calling thread we're setup */
791 if (wc_LockMutex(&crl->crlLock) != 0) {
792 WOLFSSL_MSG("wc_LockMutex crlLock failed");
793 return BAD_MUTEX_E;
794 }
795
796 crl->setup = status;
797 ret = pthread_cond_signal(&crl->cond);
798
799 wc_UnLockMutex(&crl->crlLock);
800
801 if (ret != 0)
802 return BAD_COND_E;
803
804 return 0;
805 }
806
807
808 /* read in new CRL entries and save new list */
SwapLists(WOLFSSL_CRL * crl)809 static int SwapLists(WOLFSSL_CRL* crl)
810 {
811 int ret;
812 CRL_Entry* newList;
813 #ifdef WOLFSSL_SMALL_STACK
814 WOLFSSL_CRL* tmp;
815 #else
816 WOLFSSL_CRL tmp[1];
817 #endif
818
819 #ifdef WOLFSSL_SMALL_STACK
820 tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
821 if (tmp == NULL)
822 return MEMORY_E;
823 #endif
824
825 if (InitCRL(tmp, crl->cm) < 0) {
826 WOLFSSL_MSG("Init tmp CRL failed");
827 #ifdef WOLFSSL_SMALL_STACK
828 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
829 #endif
830 return -1;
831 }
832
833 if (crl->monitors[0].path) {
834 ret = LoadCRL(tmp, crl->monitors[0].path, WOLFSSL_FILETYPE_PEM, 0);
835 if (ret != WOLFSSL_SUCCESS) {
836 WOLFSSL_MSG("PEM LoadCRL on dir change failed");
837 FreeCRL(tmp, 0);
838 #ifdef WOLFSSL_SMALL_STACK
839 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
840 #endif
841 return -1;
842 }
843 }
844
845 if (crl->monitors[1].path) {
846 ret = LoadCRL(tmp, crl->monitors[1].path, WOLFSSL_FILETYPE_ASN1, 0);
847 if (ret != WOLFSSL_SUCCESS) {
848 WOLFSSL_MSG("DER LoadCRL on dir change failed");
849 FreeCRL(tmp, 0);
850 #ifdef WOLFSSL_SMALL_STACK
851 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
852 #endif
853 return -1;
854 }
855 }
856
857 if (wc_LockMutex(&crl->crlLock) != 0) {
858 WOLFSSL_MSG("wc_LockMutex failed");
859 FreeCRL(tmp, 0);
860 #ifdef WOLFSSL_SMALL_STACK
861 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
862 #endif
863 return -1;
864 }
865
866 newList = tmp->crlList;
867
868 /* swap lists */
869 tmp->crlList = crl->crlList;
870 crl->crlList = newList;
871
872 wc_UnLockMutex(&crl->crlLock);
873
874 FreeCRL(tmp, 0);
875
876 #ifdef WOLFSSL_SMALL_STACK
877 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
878 #endif
879
880 return 0;
881 }
882
883
884 #if (defined(__MACH__) || defined(__FreeBSD__))
885
886 #include <sys/types.h>
887 #include <sys/event.h>
888 #include <sys/time.h>
889 #include <fcntl.h>
890 #include <unistd.h>
891
892 #ifdef __MACH__
893 #define XEVENT_MODE O_EVTONLY
894 #elif defined(__FreeBSD__)
895 #define XEVENT_MODE EVFILT_VNODE
896 #endif
897
898
899 /* we need a unique kqueue user filter fd for crl in case user is doing custom
900 * events too */
901 #ifndef CRL_CUSTOM_FD
902 #define CRL_CUSTOM_FD 123456
903 #endif
904
905
906 /* shutdown monitor thread, 0 on success */
StopMonitor(int mfd)907 static int StopMonitor(int mfd)
908 {
909 struct kevent change;
910
911 /* trigger custom shutdown */
912 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
913 if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
914 WOLFSSL_MSG("kevent trigger customer event failed");
915 return -1;
916 }
917
918 return 0;
919 }
920
921
922 /* OS X monitoring */
DoMonitor(void * arg)923 static void* DoMonitor(void* arg)
924 {
925 int fPEM, fDER;
926 struct kevent change;
927
928 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
929
930 WOLFSSL_ENTER("DoMonitor");
931
932 crl->mfd = kqueue();
933 if (crl->mfd == -1) {
934 WOLFSSL_MSG("kqueue failed");
935 SignalSetup(crl, MONITOR_SETUP_E);
936 return NULL;
937 }
938
939 /* listen for custom shutdown event */
940 EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
941 if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
942 WOLFSSL_MSG("kevent monitor customer event failed");
943 SignalSetup(crl, MONITOR_SETUP_E);
944 (void)close(crl->mfd);
945 return NULL;
946 }
947
948 fPEM = -1;
949 fDER = -1;
950
951 if (crl->monitors[0].path) {
952 fPEM = open(crl->monitors[0].path, XEVENT_MODE);
953 if (fPEM == -1) {
954 WOLFSSL_MSG("PEM event dir open failed");
955 SignalSetup(crl, MONITOR_SETUP_E);
956 (void)close(crl->mfd);
957 return NULL;
958 }
959 }
960
961 if (crl->monitors[1].path) {
962 fDER = open(crl->monitors[1].path, XEVENT_MODE);
963 if (fDER == -1) {
964 WOLFSSL_MSG("DER event dir open failed");
965 if (fPEM != -1)
966 (void)close(fPEM);
967 (void)close(crl->mfd);
968 SignalSetup(crl, MONITOR_SETUP_E);
969 return NULL;
970 }
971 }
972
973 if (fPEM != -1)
974 EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
975 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
976
977 if (fDER != -1)
978 EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
979 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
980
981 /* signal to calling thread we're setup */
982 if (SignalSetup(crl, 1) != 0) {
983 if (fPEM != -1)
984 (void)close(fPEM);
985 if (fDER != -1)
986 (void)close(fDER);
987 (void)close(crl->mfd);
988 return NULL;
989 }
990
991 for (;;) {
992 struct kevent event;
993 int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
994
995 WOLFSSL_MSG("Got kevent");
996
997 if (numEvents == -1) {
998 WOLFSSL_MSG("kevent problem, continue");
999 continue;
1000 }
1001
1002 if (event.filter == EVFILT_USER) {
1003 WOLFSSL_MSG("Got user shutdown event, breaking out");
1004 break;
1005 }
1006
1007 if (SwapLists(crl) < 0) {
1008 WOLFSSL_MSG("SwapLists problem, continue");
1009 }
1010 }
1011
1012 if (fPEM != -1)
1013 (void)close(fPEM);
1014 if (fDER != -1)
1015 (void)close(fDER);
1016
1017 (void)close(crl->mfd);
1018
1019 return NULL;
1020 }
1021
1022
1023 #elif defined(__linux__)
1024
1025 #include <sys/types.h>
1026 #include <sys/inotify.h>
1027 #include <sys/eventfd.h>
1028 #include <unistd.h>
1029
1030
1031 #ifndef max
max(int a,int b)1032 static WC_INLINE int max(int a, int b)
1033 {
1034 return a > b ? a : b;
1035 }
1036 #endif /* max */
1037
1038
1039 /* shutdown monitor thread, 0 on success */
StopMonitor(int mfd)1040 static int StopMonitor(int mfd)
1041 {
1042 word64 w64 = 1;
1043
1044 /* write to our custom event */
1045 if (write(mfd, &w64, sizeof(w64)) < 0) {
1046 WOLFSSL_MSG("StopMonitor write failed");
1047 return -1;
1048 }
1049
1050 return 0;
1051 }
1052
1053
1054 /* linux monitoring */
DoMonitor(void * arg)1055 static void* DoMonitor(void* arg)
1056 {
1057 int notifyFd;
1058 int wd = -1;
1059 WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
1060 #ifdef WOLFSSL_SMALL_STACK
1061 char* buff;
1062 #else
1063 char buff[8192];
1064 #endif
1065
1066 WOLFSSL_ENTER("DoMonitor");
1067
1068 crl->mfd = eventfd(0, 0); /* our custom shutdown event */
1069 if (crl->mfd < 0) {
1070 WOLFSSL_MSG("eventfd failed");
1071 SignalSetup(crl, MONITOR_SETUP_E);
1072 return NULL;
1073 }
1074
1075 notifyFd = inotify_init();
1076 if (notifyFd < 0) {
1077 WOLFSSL_MSG("inotify failed");
1078 (void)close(crl->mfd);
1079 SignalSetup(crl, MONITOR_SETUP_E);
1080 return NULL;
1081 }
1082
1083 if (crl->monitors[0].path) {
1084 wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
1085 IN_DELETE);
1086 if (wd < 0) {
1087 WOLFSSL_MSG("PEM notify add watch failed");
1088 (void)close(crl->mfd);
1089 (void)close(notifyFd);
1090 SignalSetup(crl, MONITOR_SETUP_E);
1091 return NULL;
1092 }
1093 }
1094
1095 if (crl->monitors[1].path) {
1096 wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
1097 IN_DELETE);
1098 if (wd < 0) {
1099 WOLFSSL_MSG("DER notify add watch failed");
1100 (void)close(crl->mfd);
1101 (void)close(notifyFd);
1102 SignalSetup(crl, MONITOR_SETUP_E);
1103 return NULL;
1104 }
1105 }
1106
1107 #ifdef WOLFSSL_SMALL_STACK
1108 buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1109 if (buff == NULL)
1110 return NULL;
1111 #endif
1112
1113 /* signal to calling thread we're setup */
1114 if (SignalSetup(crl, 1) != 0) {
1115 #ifdef WOLFSSL_SMALL_STACK
1116 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1117 #endif
1118
1119 if (wd > 0)
1120 inotify_rm_watch(notifyFd, wd);
1121 (void)close(crl->mfd);
1122 (void)close(notifyFd);
1123 return NULL;
1124 }
1125
1126 for (;;) {
1127 fd_set readfds;
1128 int result;
1129 int length;
1130
1131 FD_ZERO(&readfds);
1132 FD_SET(notifyFd, &readfds);
1133 FD_SET(crl->mfd, &readfds);
1134
1135 result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
1136
1137 WOLFSSL_MSG("Got notify event");
1138
1139 if (result < 0) {
1140 WOLFSSL_MSG("select problem, continue");
1141 continue;
1142 }
1143
1144 if (FD_ISSET(crl->mfd, &readfds)) {
1145 word64 r64;
1146 int rlen;
1147
1148 WOLFSSL_MSG("got custom shutdown event, breaking out");
1149
1150 /* read out the bytes written to the event to clean up */
1151 rlen = (int) read(crl->mfd, &r64, sizeof(r64));
1152 if (rlen < 0) {
1153 WOLFSSL_MSG("read custom event failure");
1154 }
1155
1156 break;
1157 }
1158
1159 length = (int) read(notifyFd, buff, 8192);
1160 if (length < 0) {
1161 WOLFSSL_MSG("notify read problem, continue");
1162 continue;
1163 }
1164
1165 if (SwapLists(crl) < 0) {
1166 WOLFSSL_MSG("SwapLists problem, continue");
1167 }
1168 }
1169
1170 #ifdef WOLFSSL_SMALL_STACK
1171 XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1172 #endif
1173
1174 if (wd > 0)
1175 inotify_rm_watch(notifyFd, wd);
1176 (void)close(crl->mfd);
1177 (void)close(notifyFd);
1178
1179 return NULL;
1180 }
1181
1182 #endif /* MACH or linux */
1183
1184
1185 /* Start Monitoring the CRL path(s) in a thread */
StartMonitorCRL(WOLFSSL_CRL * crl)1186 static int StartMonitorCRL(WOLFSSL_CRL* crl)
1187 {
1188 int ret = WOLFSSL_SUCCESS;
1189
1190 WOLFSSL_ENTER("StartMonitorCRL");
1191
1192 if (crl == NULL)
1193 return BAD_FUNC_ARG;
1194
1195 if (crl->tid != 0) {
1196 WOLFSSL_MSG("Monitor thread already running");
1197 return ret; /* that's ok, someone already started */
1198 }
1199
1200 if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) {
1201 WOLFSSL_MSG("Thread creation error");
1202 return THREAD_CREATE_E;
1203 }
1204
1205 /* wait for setup to complete */
1206 if (wc_LockMutex(&crl->crlLock) != 0) {
1207 WOLFSSL_MSG("wc_LockMutex crlLock error");
1208 return BAD_MUTEX_E;
1209 }
1210
1211 while (crl->setup == 0) {
1212 if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) {
1213 ret = BAD_COND_E;
1214 break;
1215 }
1216 }
1217
1218 if (crl->setup < 0)
1219 ret = crl->setup; /* store setup error */
1220
1221 wc_UnLockMutex(&crl->crlLock);
1222
1223 if (ret < 0) {
1224 WOLFSSL_MSG("DoMonitor setup failure");
1225 crl->tid = 0; /* thread already done */
1226 }
1227
1228 return ret;
1229 }
1230
1231
1232 #else /* HAVE_CRL_MONITOR */
1233
1234 #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1235
StartMonitorCRL(WOLFSSL_CRL * crl)1236 static int StartMonitorCRL(WOLFSSL_CRL* crl)
1237 {
1238 (void)crl;
1239
1240 WOLFSSL_ENTER("StartMonitorCRL");
1241 WOLFSSL_MSG("Not compiled in");
1242
1243 return NOT_COMPILED_IN;
1244 }
1245
1246 #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
1247
1248 #endif /* HAVE_CRL_MONITOR */
1249
1250 #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1251
1252 /* Load CRL path files of type, WOLFSSL_SUCCESS on ok */
LoadCRL(WOLFSSL_CRL * crl,const char * path,int type,int monitor)1253 int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
1254 {
1255 int ret = WOLFSSL_SUCCESS;
1256 char* name = NULL;
1257 #ifdef WOLFSSL_SMALL_STACK
1258 ReadDirCtx* readCtx = NULL;
1259 #else
1260 ReadDirCtx readCtx[1];
1261 #endif
1262
1263 WOLFSSL_ENTER("LoadCRL");
1264 if (crl == NULL)
1265 return BAD_FUNC_ARG;
1266
1267 #ifdef WOLFSSL_SMALL_STACK
1268 readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), crl->heap,
1269 DYNAMIC_TYPE_TMP_BUFFER);
1270 if (readCtx == NULL)
1271 return MEMORY_E;
1272 #endif
1273
1274 /* try to load each regular file in path */
1275 ret = wc_ReadDirFirst(readCtx, path, &name);
1276 while (ret == 0 && name) {
1277 int skip = 0;
1278 if (type == WOLFSSL_FILETYPE_PEM) {
1279 if (XSTRSTR(name, ".pem") == NULL) {
1280 WOLFSSL_MSG("not .pem file, skipping");
1281 skip = 1;
1282 }
1283 }
1284 else {
1285 if (XSTRSTR(name, ".der") == NULL &&
1286 XSTRSTR(name, ".crl") == NULL)
1287 {
1288 WOLFSSL_MSG("not .der or .crl file, skipping");
1289 skip = 1;
1290 }
1291 }
1292
1293 if (!skip && ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl,
1294 VERIFY) != WOLFSSL_SUCCESS) {
1295 WOLFSSL_MSG("CRL file load failed, continuing");
1296 }
1297
1298 ret = wc_ReadDirNext(readCtx, path, &name);
1299 }
1300 wc_ReadDirClose(readCtx);
1301 ret = WOLFSSL_SUCCESS; /* load failures not reported, for backwards compat */
1302
1303 #ifdef WOLFSSL_SMALL_STACK
1304 XFREE(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1305 #endif
1306
1307 if (monitor & WOLFSSL_CRL_MONITOR) {
1308 word32 pathLen;
1309 char* pathBuf;
1310
1311 WOLFSSL_MSG("monitor path requested");
1312
1313 pathLen = (word32)XSTRLEN(path);
1314 pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR);
1315 if (pathBuf) {
1316 XSTRNCPY(pathBuf, path, pathLen+1);
1317
1318 if (type == WOLFSSL_FILETYPE_PEM) {
1319 /* free old path before setting a new one */
1320 if (crl->monitors[0].path) {
1321 XFREE(crl->monitors[0].path, crl->heap,
1322 DYNAMIC_TYPE_CRL_MONITOR);
1323 }
1324 crl->monitors[0].path = pathBuf;
1325 crl->monitors[0].type = WOLFSSL_FILETYPE_PEM;
1326 } else {
1327 /* free old path before setting a new one */
1328 if (crl->monitors[1].path) {
1329 XFREE(crl->monitors[1].path, crl->heap,
1330 DYNAMIC_TYPE_CRL_MONITOR);
1331 }
1332 crl->monitors[1].path = pathBuf;
1333 crl->monitors[1].type = WOLFSSL_FILETYPE_ASN1;
1334 }
1335
1336 if (monitor & WOLFSSL_CRL_START_MON) {
1337 WOLFSSL_MSG("start monitoring requested");
1338
1339 ret = StartMonitorCRL(crl);
1340 }
1341 }
1342 else {
1343 ret = MEMORY_E;
1344 }
1345 }
1346
1347 return ret;
1348 }
1349
1350 #else
LoadCRL(WOLFSSL_CRL * crl,const char * path,int type,int monitor)1351 int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
1352 {
1353 (void)crl;
1354 (void)path;
1355 (void)type;
1356 (void)monitor;
1357
1358 /* stub for scenario where file system is not supported */
1359 return NOT_COMPILED_IN;
1360 }
1361 #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
1362
1363 #endif /* HAVE_CRL */
1364 #endif /* !WOLFCRYPT_ONLY */
1365