crl.c 47 KB

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