crl.c 39 KB

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