crl.c 48 KB

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