crl.c 42 KB

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