crl.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309
  1. /* crl.c
  2. *
  3. * Copyright (C) 2006-2020 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. /* Name change compatibility layer no longer needs included here */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <wolfssl/wolfcrypt/settings.h>
  26. #ifndef WOLFCRYPT_ONLY
  27. #ifdef HAVE_CRL
  28. #include <wolfssl/internal.h>
  29. #include <wolfssl/error-ssl.h>
  30. #include <string.h>
  31. #ifdef HAVE_CRL_MONITOR
  32. #if (defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__))
  33. static int StopMonitor(int mfd);
  34. #else
  35. #error "CRL monitor only currently supported on linux or mach"
  36. #endif
  37. #endif /* HAVE_CRL_MONITOR */
  38. /* Initialize CRL members */
  39. int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
  40. {
  41. WOLFSSL_ENTER("InitCRL");
  42. if(cm != NULL)
  43. crl->heap = cm->heap;
  44. else
  45. crl->heap = NULL;
  46. crl->cm = cm;
  47. crl->crlList = NULL;
  48. crl->monitors[0].path = NULL;
  49. crl->monitors[1].path = NULL;
  50. #ifdef HAVE_CRL_MONITOR
  51. crl->tid = 0;
  52. crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */
  53. crl->setup = 0; /* thread setup done predicate */
  54. if (pthread_cond_init(&crl->cond, 0) != 0) {
  55. WOLFSSL_MSG("Pthread condition init failed");
  56. return BAD_COND_E;
  57. }
  58. #endif
  59. if (wc_InitMutex(&crl->crlLock) != 0) {
  60. WOLFSSL_MSG("Init Mutex failed");
  61. return BAD_MUTEX_E;
  62. }
  63. return 0;
  64. }
  65. /* Initialize CRL Entry */
  66. static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
  67. int verified, void* heap)
  68. {
  69. WOLFSSL_ENTER("InitCRL_Entry");
  70. XMEMCPY(crle->issuerHash, dcrl->issuerHash, CRL_DIGEST_SIZE);
  71. /* XMEMCPY(crle->crlHash, dcrl->crlHash, CRL_DIGEST_SIZE);
  72. * copy the hash here if needed for optimized comparisons */
  73. XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
  74. XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
  75. crle->lastDateFormat = dcrl->lastDateFormat;
  76. crle->nextDateFormat = dcrl->nextDateFormat;
  77. crle->certs = dcrl->certs; /* take ownsership */
  78. dcrl->certs = NULL;
  79. crle->totalCerts = dcrl->totalCerts;
  80. crle->verified = verified;
  81. if (!verified) {
  82. crle->tbsSz = dcrl->sigIndex - dcrl->certBegin;
  83. crle->signatureSz = dcrl->sigLength;
  84. crle->signatureOID = dcrl->signatureOID;
  85. crle->toBeSigned = (byte*)XMALLOC(crle->tbsSz, heap,
  86. DYNAMIC_TYPE_CRL_ENTRY);
  87. if (crle->toBeSigned == NULL)
  88. return -1;
  89. crle->signature = (byte*)XMALLOC(crle->signatureSz, heap,
  90. DYNAMIC_TYPE_CRL_ENTRY);
  91. if (crle->signature == NULL) {
  92. XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_CRL_ENTRY);
  93. return -1;
  94. }
  95. XMEMCPY(crle->toBeSigned, buff + dcrl->certBegin, crle->tbsSz);
  96. XMEMCPY(crle->signature, dcrl->signature, crle->signatureSz);
  97. #ifndef NO_SKID
  98. crle->extAuthKeyIdSet = dcrl->extAuthKeyIdSet;
  99. if (crle->extAuthKeyIdSet)
  100. XMEMCPY(crle->extAuthKeyId, dcrl->extAuthKeyId, KEYID_SIZE);
  101. #endif
  102. }
  103. else {
  104. crle->toBeSigned = NULL;
  105. crle->signature = NULL;
  106. }
  107. (void)verified;
  108. (void)heap;
  109. return 0;
  110. }
  111. /* Free all CRL Entry resources */
  112. static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
  113. {
  114. RevokedCert* tmp = crle->certs;
  115. RevokedCert* next;
  116. WOLFSSL_ENTER("FreeCRL_Entry");
  117. while (tmp) {
  118. next = tmp->next;
  119. XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED);
  120. tmp = next;
  121. }
  122. if (crle->signature != NULL)
  123. XFREE(crle->signature, heap, DYNAMIC_TYPE_REVOKED);
  124. if (crle->toBeSigned != NULL)
  125. XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_REVOKED);
  126. (void)heap;
  127. }
  128. /* Free all CRL resources */
  129. void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
  130. {
  131. CRL_Entry* tmp = crl->crlList;
  132. WOLFSSL_ENTER("FreeCRL");
  133. if (crl->monitors[0].path)
  134. XFREE(crl->monitors[0].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
  135. if (crl->monitors[1].path)
  136. XFREE(crl->monitors[1].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR);
  137. while(tmp) {
  138. CRL_Entry* next = tmp->next;
  139. FreeCRL_Entry(tmp, crl->heap);
  140. XFREE(tmp, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  141. tmp = next;
  142. }
  143. #ifdef HAVE_CRL_MONITOR
  144. if (crl->tid != 0) {
  145. WOLFSSL_MSG("stopping monitor thread");
  146. if (StopMonitor(crl->mfd) == 0)
  147. pthread_join(crl->tid, NULL);
  148. else {
  149. WOLFSSL_MSG("stop monitor failed");
  150. }
  151. }
  152. pthread_cond_destroy(&crl->cond);
  153. #endif
  154. wc_FreeMutex(&crl->crlLock);
  155. if (dynamic) /* free self */
  156. XFREE(crl, crl->heap, DYNAMIC_TYPE_CRL);
  157. }
  158. static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntry)
  159. {
  160. CRL_Entry* crle;
  161. int foundEntry = 0;
  162. int ret = 0;
  163. if (wc_LockMutex(&crl->crlLock) != 0) {
  164. WOLFSSL_MSG("wc_LockMutex failed");
  165. return BAD_MUTEX_E;
  166. }
  167. crle = crl->crlList;
  168. while (crle) {
  169. if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) {
  170. WOLFSSL_MSG("Found CRL Entry on list");
  171. if (crle->verified == 0) {
  172. Signer* ca = NULL;
  173. #ifndef NO_SKID
  174. byte extAuthKeyId[KEYID_SIZE];
  175. #endif
  176. byte issuerHash[CRL_DIGEST_SIZE];
  177. byte* tbs;
  178. word32 tbsSz = crle->tbsSz;
  179. byte* sig = NULL;
  180. word32 sigSz = crle->signatureSz;
  181. word32 sigOID = crle->signatureOID;
  182. SignatureCtx sigCtx;
  183. tbs = (byte*)XMALLOC(tbsSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  184. if (tbs == NULL) {
  185. wc_UnLockMutex(&crl->crlLock);
  186. return MEMORY_E;
  187. }
  188. sig = (byte*)XMALLOC(sigSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  189. if (sig == NULL) {
  190. XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  191. wc_UnLockMutex(&crl->crlLock);
  192. return MEMORY_E;
  193. }
  194. XMEMCPY(tbs, crle->toBeSigned, tbsSz);
  195. XMEMCPY(sig, crle->signature, sigSz);
  196. #ifndef NO_SKID
  197. XMEMCPY(extAuthKeyId, crle->extAuthKeyId,
  198. sizeof(extAuthKeyId));
  199. #endif
  200. XMEMCPY(issuerHash, crle->issuerHash, sizeof(issuerHash));
  201. wc_UnLockMutex(&crl->crlLock);
  202. #ifndef NO_SKID
  203. if (crle->extAuthKeyIdSet)
  204. ca = GetCA(crl->cm, extAuthKeyId);
  205. if (ca == NULL)
  206. ca = GetCAByName(crl->cm, issuerHash);
  207. #else /* NO_SKID */
  208. ca = GetCA(crl->cm, issuerHash);
  209. #endif /* NO_SKID */
  210. if (ca == NULL) {
  211. XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  212. XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  213. WOLFSSL_MSG("Did NOT find CRL issuer CA");
  214. return ASN_CRL_NO_SIGNER_E;
  215. }
  216. ret = VerifyCRL_Signature(&sigCtx, tbs, tbsSz, sig, sigSz,
  217. sigOID, ca, crl->heap);
  218. XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  219. XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  220. if (wc_LockMutex(&crl->crlLock) != 0) {
  221. WOLFSSL_MSG("wc_LockMutex failed");
  222. return BAD_MUTEX_E;
  223. }
  224. crle = crl->crlList;
  225. while (crle) {
  226. if (XMEMCMP(crle->issuerHash, cert->issuerHash,
  227. CRL_DIGEST_SIZE) == 0) {
  228. if (ret == 0)
  229. crle->verified = 1;
  230. else
  231. crle->verified = ret;
  232. XFREE(crle->toBeSigned, crl->heap,
  233. DYNAMIC_TYPE_CRL_ENTRY);
  234. crle->toBeSigned = NULL;
  235. XFREE(crle->signature, crl->heap,
  236. DYNAMIC_TYPE_CRL_ENTRY);
  237. crle->signature = NULL;
  238. break;
  239. }
  240. crle = crle->next;
  241. }
  242. if (crle == NULL || crle->verified < 0)
  243. break;
  244. }
  245. else if (crle->verified < 0) {
  246. WOLFSSL_MSG("Cannot use CRL as it didn't verify");
  247. ret = crle->verified;
  248. break;
  249. }
  250. WOLFSSL_MSG("Checking next date validity");
  251. #ifdef WOLFSSL_NO_CRL_NEXT_DATE
  252. if (crle->nextDateFormat != ASN_OTHER_TYPE)
  253. #endif
  254. {
  255. #ifndef NO_ASN_TIME
  256. if (!XVALIDATE_DATE(crle->nextDate,crle->nextDateFormat, AFTER)) {
  257. WOLFSSL_MSG("CRL next date is no longer valid");
  258. ret = ASN_AFTER_DATE_E;
  259. }
  260. #endif
  261. }
  262. if (ret == 0) {
  263. foundEntry = 1;
  264. }
  265. break;
  266. }
  267. crle = crle->next;
  268. }
  269. if (foundEntry) {
  270. RevokedCert* rc = crle->certs;
  271. while (rc) {
  272. if (rc->serialSz == cert->serialSz &&
  273. XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
  274. WOLFSSL_MSG("Cert revoked");
  275. ret = CRL_CERT_REVOKED;
  276. break;
  277. }
  278. rc = rc->next;
  279. }
  280. }
  281. wc_UnLockMutex(&crl->crlLock);
  282. *pFoundEntry = foundEntry;
  283. return ret;
  284. }
  285. /* Is the cert ok with CRL, return 0 on success */
  286. int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
  287. {
  288. int foundEntry = 0;
  289. int ret = 0;
  290. WOLFSSL_ENTER("CheckCertCRL");
  291. ret = CheckCertCRLList(crl, cert, &foundEntry);
  292. #ifdef HAVE_CRL_IO
  293. if (foundEntry == 0) {
  294. /* perform embedded lookup */
  295. if (crl->crlIOCb) {
  296. ret = crl->crlIOCb(crl, (const char*)cert->extCrlInfo,
  297. cert->extCrlInfoSz);
  298. if (ret == WOLFSSL_CBIO_ERR_WANT_READ) {
  299. ret = WANT_READ;
  300. }
  301. else if (ret >= 0) {
  302. /* try again */
  303. ret = CheckCertCRLList(crl, cert, &foundEntry);
  304. }
  305. }
  306. }
  307. #endif
  308. if (foundEntry == 0) {
  309. WOLFSSL_MSG("Couldn't find CRL for status check");
  310. ret = CRL_MISSING;
  311. if (crl->cm->cbMissingCRL) {
  312. char url[256];
  313. WOLFSSL_MSG("Issuing missing CRL callback");
  314. url[0] = '\0';
  315. if (cert->extCrlInfo) {
  316. if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
  317. XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
  318. url[cert->extCrlInfoSz] = '\0';
  319. }
  320. else {
  321. WOLFSSL_MSG("CRL url too long");
  322. }
  323. }
  324. crl->cm->cbMissingCRL(url);
  325. }
  326. }
  327. return ret;
  328. }
  329. /* Add Decoded CRL, 0 on success */
  330. static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
  331. int verified)
  332. {
  333. CRL_Entry* crle;
  334. WOLFSSL_ENTER("AddCRL");
  335. crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  336. if (crle == NULL) {
  337. WOLFSSL_MSG("alloc CRL Entry failed");
  338. return -1;
  339. }
  340. if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
  341. WOLFSSL_MSG("Init CRL Entry failed");
  342. XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  343. return -1;
  344. }
  345. if (wc_LockMutex(&crl->crlLock) != 0) {
  346. WOLFSSL_MSG("wc_LockMutex failed");
  347. FreeCRL_Entry(crle, crl->heap);
  348. XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
  349. return BAD_MUTEX_E;
  350. }
  351. crle->next = crl->crlList;
  352. crl->crlList = crle;
  353. wc_UnLockMutex(&crl->crlLock);
  354. return 0;
  355. }
  356. /* Load CRL File of type, WOLFSSL_SUCCESS on ok */
  357. int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
  358. int verify)
  359. {
  360. int ret = WOLFSSL_SUCCESS;
  361. const byte* myBuffer = buff; /* if DER ok, otherwise switch */
  362. DerBuffer* der = NULL;
  363. #ifdef WOLFSSL_SMALL_STACK
  364. DecodedCRL* dcrl;
  365. #else
  366. DecodedCRL dcrl[1];
  367. #endif
  368. WOLFSSL_ENTER("BufferLoadCRL");
  369. if (crl == NULL || buff == NULL || sz == 0)
  370. return BAD_FUNC_ARG;
  371. if (type == WOLFSSL_FILETYPE_PEM) {
  372. #ifdef WOLFSSL_PEM_TO_DER
  373. ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, NULL, NULL);
  374. if (ret == 0) {
  375. myBuffer = der->buffer;
  376. sz = der->length;
  377. }
  378. else {
  379. WOLFSSL_MSG("Pem to Der failed");
  380. FreeDer(&der);
  381. return -1;
  382. }
  383. #else
  384. ret = NOT_COMPILED_IN;
  385. #endif
  386. }
  387. #ifdef WOLFSSL_SMALL_STACK
  388. dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
  389. if (dcrl == NULL) {
  390. FreeDer(&der);
  391. return MEMORY_E;
  392. }
  393. #endif
  394. InitDecodedCRL(dcrl, crl->heap);
  395. ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
  396. if (ret != 0 && !(ret == ASN_CRL_NO_SIGNER_E && verify == NO_VERIFY)) {
  397. WOLFSSL_MSG("ParseCRL error");
  398. }
  399. else {
  400. ret = AddCRL(crl, dcrl, myBuffer, ret != ASN_CRL_NO_SIGNER_E);
  401. if (ret != 0) {
  402. WOLFSSL_MSG("AddCRL error");
  403. }
  404. }
  405. FreeDecodedCRL(dcrl);
  406. #ifdef WOLFSSL_SMALL_STACK
  407. XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  408. #endif
  409. FreeDer(&der);
  410. return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
  411. }
  412. #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
  413. /* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
  414. static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
  415. {
  416. WOLFSSL_X509_CRL* ret;
  417. ret = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), cm->heap,
  418. DYNAMIC_TYPE_CRL);
  419. if (ret != NULL) {
  420. if (InitCRL(ret, cm) < 0) {
  421. WOLFSSL_MSG("Unable to initialize new CRL structure");
  422. XFREE(ret, cm->heap, DYNAMIC_TYPE_CRL);
  423. ret = NULL;
  424. }
  425. }
  426. return ret;
  427. }
  428. /* returns head of copied list that was alloc'd */
  429. static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap)
  430. {
  431. RevokedCert* head = NULL;
  432. RevokedCert* current = in;
  433. RevokedCert* prev = NULL;
  434. while (current) {
  435. RevokedCert* tmp = (RevokedCert*)XMALLOC(sizeof(RevokedCert), heap,
  436. DYNAMIC_TYPE_REVOKED);
  437. if (tmp != NULL) {
  438. XMEMCPY(tmp->serialNumber, current->serialNumber,
  439. EXTERNAL_SERIAL_SIZE);
  440. tmp->serialSz = current->serialSz;
  441. tmp->next = NULL;
  442. if (prev != NULL)
  443. prev->next = tmp;
  444. if (head == NULL)
  445. head = tmp;
  446. prev = tmp;
  447. }
  448. else {
  449. WOLFSSL_MSG("Failed to allocate new RevokedCert structure");
  450. /* free up any existing list */
  451. while (head != NULL) {
  452. current = head;
  453. head = head->next;
  454. XFREE(current, heap, DYNAMIC_TYPE_REVOKED);
  455. }
  456. return NULL;
  457. }
  458. current = current->next;
  459. }
  460. return head;
  461. }
  462. /* returns a deep copy of ent on success and null on fail */
  463. static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap)
  464. {
  465. CRL_Entry *dup;
  466. dup = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), heap, DYNAMIC_TYPE_CRL_ENTRY);
  467. if (dup == NULL) {
  468. WOLFSSL_MSG("alloc CRL Entry failed");
  469. return NULL;
  470. }
  471. XMEMSET(dup, 0, sizeof(CRL_Entry));
  472. XMEMCPY(dup->issuerHash, ent->issuerHash, CRL_DIGEST_SIZE);
  473. XMEMCPY(dup->lastDate, ent->lastDate, MAX_DATE_SIZE);
  474. XMEMCPY(dup->nextDate, ent->nextDate, MAX_DATE_SIZE);
  475. dup->lastDateFormat = ent->lastDateFormat;
  476. dup->nextDateFormat = ent->nextDateFormat;
  477. dup->certs = DupRevokedCertList(ent->certs, heap);
  478. dup->totalCerts = ent->totalCerts;
  479. dup->verified = ent->verified;
  480. if (!ent->verified) {
  481. dup->tbsSz = ent->tbsSz;
  482. dup->signatureSz = ent->signatureSz;
  483. dup->signatureOID = ent->signatureOID;
  484. dup->toBeSigned = (byte*)XMALLOC(dup->tbsSz, heap,
  485. DYNAMIC_TYPE_CRL_ENTRY);
  486. if (dup->toBeSigned == NULL) {
  487. FreeCRL_Entry(dup, heap);
  488. XFREE(dup, heap, DYNAMIC_TYPE_CRL_ENTRY);
  489. return NULL;
  490. }
  491. dup->signature = (byte*)XMALLOC(dup->signatureSz, heap,
  492. DYNAMIC_TYPE_CRL_ENTRY);
  493. if (dup->signature == NULL) {
  494. FreeCRL_Entry(dup, heap);
  495. XFREE(dup, heap, DYNAMIC_TYPE_CRL_ENTRY);
  496. return NULL;
  497. }
  498. XMEMCPY(dup->toBeSigned, ent->toBeSigned, dup->tbsSz);
  499. XMEMCPY(dup->signature, ent->signature, dup->signatureSz);
  500. #ifndef NO_SKID
  501. dup->extAuthKeyIdSet = ent->extAuthKeyIdSet;
  502. if (dup->extAuthKeyIdSet)
  503. XMEMCPY(dup->extAuthKeyId, ent->extAuthKeyId, KEYID_SIZE);
  504. #endif
  505. }
  506. else {
  507. dup->toBeSigned = NULL;
  508. dup->tbsSz = 0;
  509. dup->signature = NULL;
  510. dup->signatureSz = 0;
  511. }
  512. return dup;
  513. }
  514. /* returns the head of a deep copy of the list on success and null on fail */
  515. static CRL_Entry* DupCRL_list(CRL_Entry* crl, void* heap)
  516. {
  517. CRL_Entry* current;
  518. CRL_Entry* head = NULL;
  519. CRL_Entry* prev = NULL;
  520. current = crl;
  521. while (current != NULL) {
  522. CRL_Entry* tmp = DupCRL_Entry(current, heap);
  523. if (tmp != NULL) {
  524. tmp->next = NULL;
  525. if (head == NULL)
  526. head = tmp;
  527. if (prev != NULL)
  528. prev->next = tmp;
  529. prev = tmp;
  530. }
  531. else {
  532. WOLFSSL_MSG("Failed to allocate new CRL_Entry structure");
  533. /* free up any existing list */
  534. while (head != NULL) {
  535. current = head;
  536. head = head->next;
  537. FreeCRL_Entry(current, heap);
  538. }
  539. return NULL;
  540. }
  541. current = current->next;
  542. }
  543. return head;
  544. }
  545. /* Duplicates everything except the parent cm pointed to.
  546. * Expects that Init has already been done to 'dup'
  547. * return 0 on success */
  548. static int DupX509_CRL(WOLFSSL_X509_CRL *dup, const WOLFSSL_X509_CRL* crl)
  549. {
  550. if (dup == NULL || crl == NULL) {
  551. return BAD_FUNC_ARG;
  552. }
  553. if (crl->monitors[0].path) {
  554. int pathSz = (int)XSTRLEN(crl->monitors[0].path) + 1;
  555. dup->monitors[0].path = (char*)XMALLOC(pathSz, dup->heap,
  556. DYNAMIC_TYPE_CRL_MONITOR);
  557. if (dup->monitors[0].path != NULL) {
  558. XSTRNCPY(dup->monitors[0].path, crl->monitors[0].path, pathSz);
  559. }
  560. else {
  561. return MEMORY_E;
  562. }
  563. }
  564. if (crl->monitors[1].path) {
  565. int pathSz = (int)XSTRLEN(crl->monitors[1].path) + 1;
  566. dup->monitors[1].path = (char*)XMALLOC(pathSz, dup->heap,
  567. DYNAMIC_TYPE_CRL_MONITOR);
  568. if (dup->monitors[1].path != NULL) {
  569. XSTRNCPY(dup->monitors[1].path, crl->monitors[1].path, pathSz);
  570. }
  571. else {
  572. if (dup->monitors[0].path != NULL) {
  573. XFREE(dup->monitors[0].path, dup->heap,
  574. DYNAMIC_TYPE_CRL_MONITOR);
  575. }
  576. return MEMORY_E;
  577. }
  578. }
  579. dup->crlList = DupCRL_list(crl->crlList, dup->heap);
  580. #ifdef HAVE_CRL_IO
  581. dup->crlIOCb = crl->crlIOCb;
  582. #endif
  583. return 0;
  584. }
  585. /* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */
  586. int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
  587. {
  588. CRL_Entry *crle;
  589. WOLFSSL_X509_CRL *crl;
  590. WOLFSSL_ENTER("wolfSSL_X509_STORE_add_crl");
  591. if (store == NULL || newcrl == NULL || store->cm == NULL)
  592. return BAD_FUNC_ARG;
  593. if (store->cm->crl == NULL) {
  594. crl = wolfSSL_X509_crl_new(store->cm);
  595. if (DupX509_CRL(crl, newcrl) != 0) {
  596. FreeCRL(crl, 1);
  597. return WOLFSSL_FAILURE;
  598. }
  599. store->crl = store->cm->crl = crl;
  600. return WOLFSSL_SUCCESS;
  601. }
  602. /* find tail of current list and add new list */
  603. crl = store->cm->crl;
  604. crle = crl->crlList;
  605. if (newcrl->crlList != NULL) {
  606. CRL_Entry *tail = crle;
  607. CRL_Entry *toAdd;
  608. if (wc_LockMutex(&crl->crlLock) != 0)
  609. {
  610. WOLFSSL_MSG("wc_LockMutex failed");
  611. return BAD_MUTEX_E;
  612. }
  613. toAdd = DupCRL_list(newcrl->crlList, crl->heap);
  614. if (tail == NULL) {
  615. crl->crlList = toAdd;
  616. }
  617. else {
  618. while (tail->next != NULL) tail = tail->next;
  619. tail->next = toAdd;
  620. }
  621. wc_UnLockMutex(&crl->crlLock);
  622. }
  623. WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_crl", WOLFSSL_SUCCESS);
  624. return WOLFSSL_SUCCESS;
  625. }
  626. #endif
  627. #ifdef HAVE_CRL_MONITOR
  628. /* Signal Monitor thread is setup, save status to setup flag, 0 on success */
  629. static int SignalSetup(WOLFSSL_CRL* crl, int status)
  630. {
  631. int ret;
  632. /* signal to calling thread we're setup */
  633. if (wc_LockMutex(&crl->crlLock) != 0) {
  634. WOLFSSL_MSG("wc_LockMutex crlLock failed");
  635. return BAD_MUTEX_E;
  636. }
  637. crl->setup = status;
  638. ret = pthread_cond_signal(&crl->cond);
  639. wc_UnLockMutex(&crl->crlLock);
  640. if (ret != 0)
  641. return BAD_COND_E;
  642. return 0;
  643. }
  644. /* read in new CRL entries and save new list */
  645. static int SwapLists(WOLFSSL_CRL* crl)
  646. {
  647. int ret;
  648. CRL_Entry* newList;
  649. #ifdef WOLFSSL_SMALL_STACK
  650. WOLFSSL_CRL* tmp;
  651. #else
  652. WOLFSSL_CRL tmp[1];
  653. #endif
  654. #ifdef WOLFSSL_SMALL_STACK
  655. tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
  656. if (tmp == NULL)
  657. return MEMORY_E;
  658. #endif
  659. if (InitCRL(tmp, crl->cm) < 0) {
  660. WOLFSSL_MSG("Init tmp CRL failed");
  661. #ifdef WOLFSSL_SMALL_STACK
  662. XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  663. #endif
  664. return -1;
  665. }
  666. if (crl->monitors[0].path) {
  667. ret = LoadCRL(tmp, crl->monitors[0].path, WOLFSSL_FILETYPE_PEM, 0);
  668. if (ret != WOLFSSL_SUCCESS) {
  669. WOLFSSL_MSG("PEM LoadCRL on dir change failed");
  670. FreeCRL(tmp, 0);
  671. #ifdef WOLFSSL_SMALL_STACK
  672. XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  673. #endif
  674. return -1;
  675. }
  676. }
  677. if (crl->monitors[1].path) {
  678. ret = LoadCRL(tmp, crl->monitors[1].path, WOLFSSL_FILETYPE_ASN1, 0);
  679. if (ret != WOLFSSL_SUCCESS) {
  680. WOLFSSL_MSG("DER LoadCRL on dir change failed");
  681. FreeCRL(tmp, 0);
  682. #ifdef WOLFSSL_SMALL_STACK
  683. XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  684. #endif
  685. return -1;
  686. }
  687. }
  688. if (wc_LockMutex(&crl->crlLock) != 0) {
  689. WOLFSSL_MSG("wc_LockMutex failed");
  690. FreeCRL(tmp, 0);
  691. #ifdef WOLFSSL_SMALL_STACK
  692. XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  693. #endif
  694. return -1;
  695. }
  696. newList = tmp->crlList;
  697. /* swap lists */
  698. tmp->crlList = crl->crlList;
  699. crl->crlList = newList;
  700. wc_UnLockMutex(&crl->crlLock);
  701. FreeCRL(tmp, 0);
  702. #ifdef WOLFSSL_SMALL_STACK
  703. XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  704. #endif
  705. return 0;
  706. }
  707. #if (defined(__MACH__) || defined(__FreeBSD__))
  708. #include <sys/types.h>
  709. #include <sys/event.h>
  710. #include <sys/time.h>
  711. #include <fcntl.h>
  712. #include <unistd.h>
  713. #ifdef __MACH__
  714. #define XEVENT_MODE O_EVTONLY
  715. #elif defined(__FreeBSD__)
  716. #define XEVENT_MODE EVFILT_VNODE
  717. #endif
  718. /* we need a unique kqueue user filter fd for crl in case user is doing custom
  719. * events too */
  720. #ifndef CRL_CUSTOM_FD
  721. #define CRL_CUSTOM_FD 123456
  722. #endif
  723. /* shutdown monitor thread, 0 on success */
  724. static int StopMonitor(int mfd)
  725. {
  726. struct kevent change;
  727. /* trigger custom shutdown */
  728. EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
  729. if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
  730. WOLFSSL_MSG("kevent trigger customer event failed");
  731. return -1;
  732. }
  733. return 0;
  734. }
  735. /* OS X monitoring */
  736. static void* DoMonitor(void* arg)
  737. {
  738. int fPEM, fDER;
  739. struct kevent change;
  740. WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
  741. WOLFSSL_ENTER("DoMonitor");
  742. crl->mfd = kqueue();
  743. if (crl->mfd == -1) {
  744. WOLFSSL_MSG("kqueue failed");
  745. SignalSetup(crl, MONITOR_SETUP_E);
  746. return NULL;
  747. }
  748. /* listen for custom shutdown event */
  749. EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
  750. if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
  751. WOLFSSL_MSG("kevent monitor customer event failed");
  752. SignalSetup(crl, MONITOR_SETUP_E);
  753. close(crl->mfd);
  754. return NULL;
  755. }
  756. fPEM = -1;
  757. fDER = -1;
  758. if (crl->monitors[0].path) {
  759. fPEM = open(crl->monitors[0].path, XEVENT_MODE);
  760. if (fPEM == -1) {
  761. WOLFSSL_MSG("PEM event dir open failed");
  762. SignalSetup(crl, MONITOR_SETUP_E);
  763. close(crl->mfd);
  764. return NULL;
  765. }
  766. }
  767. if (crl->monitors[1].path) {
  768. fDER = open(crl->monitors[1].path, XEVENT_MODE);
  769. if (fDER == -1) {
  770. WOLFSSL_MSG("DER event dir open failed");
  771. if (fPEM != -1)
  772. close(fPEM);
  773. close(crl->mfd);
  774. SignalSetup(crl, MONITOR_SETUP_E);
  775. return NULL;
  776. }
  777. }
  778. if (fPEM != -1)
  779. EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
  780. NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
  781. if (fDER != -1)
  782. EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
  783. NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
  784. /* signal to calling thread we're setup */
  785. if (SignalSetup(crl, 1) != 0) {
  786. if (fPEM != -1)
  787. close(fPEM);
  788. if (fDER != -1)
  789. close(fDER);
  790. close(crl->mfd);
  791. return NULL;
  792. }
  793. for (;;) {
  794. struct kevent event;
  795. int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
  796. WOLFSSL_MSG("Got kevent");
  797. if (numEvents == -1) {
  798. WOLFSSL_MSG("kevent problem, continue");
  799. continue;
  800. }
  801. if (event.filter == EVFILT_USER) {
  802. WOLFSSL_MSG("Got user shutdown event, breaking out");
  803. break;
  804. }
  805. if (SwapLists(crl) < 0) {
  806. WOLFSSL_MSG("SwapLists problem, continue");
  807. }
  808. }
  809. if (fPEM != -1)
  810. close(fPEM);
  811. if (fDER != -1)
  812. close(fDER);
  813. close(crl->mfd);
  814. return NULL;
  815. }
  816. #elif defined(__linux__)
  817. #include <sys/types.h>
  818. #include <sys/inotify.h>
  819. #include <sys/eventfd.h>
  820. #include <unistd.h>
  821. #ifndef max
  822. static WC_INLINE int max(int a, int b)
  823. {
  824. return a > b ? a : b;
  825. }
  826. #endif /* max */
  827. /* shutdown monitor thread, 0 on success */
  828. static int StopMonitor(int mfd)
  829. {
  830. word64 w64 = 1;
  831. /* write to our custom event */
  832. if (write(mfd, &w64, sizeof(w64)) < 0) {
  833. WOLFSSL_MSG("StopMonitor write failed");
  834. return -1;
  835. }
  836. return 0;
  837. }
  838. /* linux monitoring */
  839. static void* DoMonitor(void* arg)
  840. {
  841. int notifyFd;
  842. int wd = -1;
  843. WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
  844. #ifdef WOLFSSL_SMALL_STACK
  845. char* buff;
  846. #else
  847. char buff[8192];
  848. #endif
  849. WOLFSSL_ENTER("DoMonitor");
  850. crl->mfd = eventfd(0, 0); /* our custom shutdown event */
  851. if (crl->mfd < 0) {
  852. WOLFSSL_MSG("eventfd failed");
  853. SignalSetup(crl, MONITOR_SETUP_E);
  854. return NULL;
  855. }
  856. notifyFd = inotify_init();
  857. if (notifyFd < 0) {
  858. WOLFSSL_MSG("inotify failed");
  859. close(crl->mfd);
  860. SignalSetup(crl, MONITOR_SETUP_E);
  861. return NULL;
  862. }
  863. if (crl->monitors[0].path) {
  864. wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
  865. IN_DELETE);
  866. if (wd < 0) {
  867. WOLFSSL_MSG("PEM notify add watch failed");
  868. close(crl->mfd);
  869. close(notifyFd);
  870. SignalSetup(crl, MONITOR_SETUP_E);
  871. return NULL;
  872. }
  873. }
  874. if (crl->monitors[1].path) {
  875. wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
  876. IN_DELETE);
  877. if (wd < 0) {
  878. WOLFSSL_MSG("DER notify add watch failed");
  879. close(crl->mfd);
  880. close(notifyFd);
  881. SignalSetup(crl, MONITOR_SETUP_E);
  882. return NULL;
  883. }
  884. }
  885. #ifdef WOLFSSL_SMALL_STACK
  886. buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  887. if (buff == NULL)
  888. return NULL;
  889. #endif
  890. /* signal to calling thread we're setup */
  891. if (SignalSetup(crl, 1) != 0) {
  892. #ifdef WOLFSSL_SMALL_STACK
  893. XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  894. #endif
  895. if (wd > 0)
  896. inotify_rm_watch(notifyFd, wd);
  897. close(crl->mfd);
  898. close(notifyFd);
  899. return NULL;
  900. }
  901. for (;;) {
  902. fd_set readfds;
  903. int result;
  904. int length;
  905. FD_ZERO(&readfds);
  906. FD_SET(notifyFd, &readfds);
  907. FD_SET(crl->mfd, &readfds);
  908. result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
  909. WOLFSSL_MSG("Got notify event");
  910. if (result < 0) {
  911. WOLFSSL_MSG("select problem, continue");
  912. continue;
  913. }
  914. if (FD_ISSET(crl->mfd, &readfds)) {
  915. WOLFSSL_MSG("got custom shutdown event, breaking out");
  916. break;
  917. }
  918. length = (int) read(notifyFd, buff, 8192);
  919. if (length < 0) {
  920. WOLFSSL_MSG("notify read problem, continue");
  921. continue;
  922. }
  923. if (SwapLists(crl) < 0) {
  924. WOLFSSL_MSG("SwapLists problem, continue");
  925. }
  926. }
  927. #ifdef WOLFSSL_SMALL_STACK
  928. XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  929. #endif
  930. if (wd > 0)
  931. inotify_rm_watch(notifyFd, wd);
  932. close(crl->mfd);
  933. close(notifyFd);
  934. return NULL;
  935. }
  936. #endif /* MACH or linux */
  937. /* Start Monitoring the CRL path(s) in a thread */
  938. static int StartMonitorCRL(WOLFSSL_CRL* crl)
  939. {
  940. int ret = WOLFSSL_SUCCESS;
  941. WOLFSSL_ENTER("StartMonitorCRL");
  942. if (crl == NULL)
  943. return BAD_FUNC_ARG;
  944. if (crl->tid != 0) {
  945. WOLFSSL_MSG("Monitor thread already running");
  946. return ret; /* that's ok, someone already started */
  947. }
  948. if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) {
  949. WOLFSSL_MSG("Thread creation error");
  950. return THREAD_CREATE_E;
  951. }
  952. /* wait for setup to complete */
  953. if (wc_LockMutex(&crl->crlLock) != 0) {
  954. WOLFSSL_MSG("wc_LockMutex crlLock error");
  955. return BAD_MUTEX_E;
  956. }
  957. while (crl->setup == 0) {
  958. if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) {
  959. ret = BAD_COND_E;
  960. break;
  961. }
  962. }
  963. if (crl->setup < 0)
  964. ret = crl->setup; /* store setup error */
  965. wc_UnLockMutex(&crl->crlLock);
  966. if (ret < 0) {
  967. WOLFSSL_MSG("DoMonitor setup failure");
  968. crl->tid = 0; /* thread already done */
  969. }
  970. return ret;
  971. }
  972. #else /* HAVE_CRL_MONITOR */
  973. #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
  974. static int StartMonitorCRL(WOLFSSL_CRL* crl)
  975. {
  976. (void)crl;
  977. WOLFSSL_ENTER("StartMonitorCRL");
  978. WOLFSSL_MSG("Not compiled in");
  979. return NOT_COMPILED_IN;
  980. }
  981. #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
  982. #endif /* HAVE_CRL_MONITOR */
  983. #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
  984. /* Load CRL path files of type, WOLFSSL_SUCCESS on ok */
  985. int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
  986. {
  987. int ret = WOLFSSL_SUCCESS;
  988. char* name = NULL;
  989. #ifdef WOLFSSL_SMALL_STACK
  990. ReadDirCtx* readCtx = NULL;
  991. #else
  992. ReadDirCtx readCtx[1];
  993. #endif
  994. WOLFSSL_ENTER("LoadCRL");
  995. if (crl == NULL)
  996. return BAD_FUNC_ARG;
  997. #ifdef WOLFSSL_SMALL_STACK
  998. readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), crl->heap,
  999. DYNAMIC_TYPE_TMP_BUFFER);
  1000. if (readCtx == NULL)
  1001. return MEMORY_E;
  1002. #endif
  1003. /* try to load each regular file in path */
  1004. ret = wc_ReadDirFirst(readCtx, path, &name);
  1005. while (ret == 0 && name) {
  1006. int skip = 0;
  1007. if (type == WOLFSSL_FILETYPE_PEM) {
  1008. if (XSTRSTR(name, ".pem") == NULL) {
  1009. WOLFSSL_MSG("not .pem file, skipping");
  1010. skip = 1;
  1011. }
  1012. }
  1013. else {
  1014. if (XSTRSTR(name, ".der") == NULL &&
  1015. XSTRSTR(name, ".crl") == NULL)
  1016. {
  1017. WOLFSSL_MSG("not .der or .crl file, skipping");
  1018. skip = 1;
  1019. }
  1020. }
  1021. if (!skip && ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl,
  1022. VERIFY) != WOLFSSL_SUCCESS) {
  1023. WOLFSSL_MSG("CRL file load failed, continuing");
  1024. }
  1025. ret = wc_ReadDirNext(readCtx, path, &name);
  1026. }
  1027. wc_ReadDirClose(readCtx);
  1028. ret = WOLFSSL_SUCCESS; /* load failures not reported, for backwards compat */
  1029. #ifdef WOLFSSL_SMALL_STACK
  1030. XFREE(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1031. #endif
  1032. if (monitor & WOLFSSL_CRL_MONITOR) {
  1033. word32 pathLen;
  1034. char* pathBuf;
  1035. WOLFSSL_MSG("monitor path requested");
  1036. pathLen = (word32)XSTRLEN(path);
  1037. pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR);
  1038. if (pathBuf) {
  1039. XSTRNCPY(pathBuf, path, pathLen+1);
  1040. if (type == WOLFSSL_FILETYPE_PEM) {
  1041. /* free old path before setting a new one */
  1042. if (crl->monitors[0].path) {
  1043. XFREE(crl->monitors[0].path, crl->heap,
  1044. DYNAMIC_TYPE_CRL_MONITOR);
  1045. }
  1046. crl->monitors[0].path = pathBuf;
  1047. crl->monitors[0].type = WOLFSSL_FILETYPE_PEM;
  1048. } else {
  1049. /* free old path before setting a new one */
  1050. if (crl->monitors[1].path) {
  1051. XFREE(crl->monitors[1].path, crl->heap,
  1052. DYNAMIC_TYPE_CRL_MONITOR);
  1053. }
  1054. crl->monitors[1].path = pathBuf;
  1055. crl->monitors[1].type = WOLFSSL_FILETYPE_ASN1;
  1056. }
  1057. if (monitor & WOLFSSL_CRL_START_MON) {
  1058. WOLFSSL_MSG("start monitoring requested");
  1059. ret = StartMonitorCRL(crl);
  1060. }
  1061. }
  1062. else {
  1063. ret = MEMORY_E;
  1064. }
  1065. }
  1066. return ret;
  1067. }
  1068. #else
  1069. int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
  1070. {
  1071. (void)crl;
  1072. (void)path;
  1073. (void)type;
  1074. (void)monitor;
  1075. /* stub for scenario where file system is not supported */
  1076. return NOT_COMPILED_IN;
  1077. }
  1078. #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
  1079. #endif /* HAVE_CRL */
  1080. #endif /* !WOLFCRYPT_ONLY */