ssl_certman.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427
  1. /* ssl_certman.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. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #include <wolfssl/internal.h>
  26. #if !defined(WOLFSSL_SSL_CERTMAN_INCLUDED)
  27. #ifndef WOLFSSL_IGNORE_FILE_WARN
  28. #warning ssl_certman.c does not need to be compiled separately from ssl.c
  29. #endif
  30. #else
  31. #ifndef NO_CERTS
  32. /* Pick an available TLS method.
  33. *
  34. * Used when creating temporary WOLFSSL_CTX.
  35. *
  36. * @return A TLS method on success.
  37. * @return NULL when no TLS method built into wolfSSL.
  38. */
  39. static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void* heap)
  40. {
  41. #ifndef NO_WOLFSSL_CLIENT
  42. #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
  43. return wolfSSLv3_client_method_ex(heap);
  44. #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
  45. return wolfTLSv1_client_method_ex(heap);
  46. #elif !defined(NO_OLD_TLS)
  47. return wolfTLSv1_1_client_method_ex(heap);
  48. #elif !defined(WOLFSSL_NO_TLS12)
  49. return wolfTLSv1_2_client_method_ex(heap);
  50. #elif defined(WOLFSSL_TLS13)
  51. return wolfTLSv1_3_client_method_ex(heap);
  52. #else
  53. return NULL;
  54. #endif
  55. #elif !defined(NO_WOLFSSL_SERVER)
  56. #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
  57. return wolfSSLv3_server_method_ex(heap);
  58. #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
  59. return wolfTLSv1_server_method_ex(heap);
  60. #elif !defined(NO_OLD_TLS)
  61. return wolfTLSv1_1_server_method_ex(heap);
  62. #elif !defined(WOLFSSL_NO_TLS12)
  63. return wolfTLSv1_2_server_method_ex(heap);
  64. #elif defined(WOLFSSL_TLS13)
  65. return wolfTLSv1_3_server_method_ex(heap);
  66. #else
  67. return NULL;
  68. #endif
  69. #else
  70. return NULL;
  71. #endif
  72. }
  73. /* Create a new certificate manager with a heap hint.
  74. *
  75. * @param [in] heap Heap hint.
  76. * @return Certificate manager object on success.
  77. * @return NULL on failure.
  78. */
  79. WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
  80. {
  81. int err = 0;
  82. WOLFSSL_CERT_MANAGER* cm;
  83. WOLFSSL_ENTER("wolfSSL_CertManagerNew");
  84. if (heap == NULL) {
  85. WOLFSSL_MSG("heap param is null");
  86. }
  87. else {
  88. /* Some systems may have heap in unexpected segments. (IRAM vs DRAM) */
  89. WOLFSSL_MSG_EX("heap param = %p", heap);
  90. }
  91. WOLFSSL_MSG_EX("DYNAMIC_TYPE_CERT_MANAGER Allocating = %d bytes",
  92. (word32)sizeof(WOLFSSL_CERT_MANAGER));
  93. /* Allocate memory for certificate manager. */
  94. cm = (WOLFSSL_CERT_MANAGER*)XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
  95. DYNAMIC_TYPE_CERT_MANAGER);
  96. if (cm == NULL) {
  97. WOLFSSL_MSG_EX("XMALLOC failed to allocate WOLFSSL_CERT_MANAGER %d "
  98. "bytes.", (int)sizeof(WOLFSSL_CERT_MANAGER));
  99. err = 1;
  100. }
  101. if (!err) {
  102. /* Reset all fields. */
  103. XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
  104. /* Create a mutex for use when modify table of stored CAs. */
  105. if (wc_InitMutex(&cm->caLock) != 0) {
  106. WOLFSSL_MSG("Bad mutex init");
  107. err = 1;
  108. }
  109. }
  110. if (!err) {
  111. /* Initialize reference count. */
  112. wolfSSL_RefInit(&cm->ref, &err);
  113. #ifdef WOLFSSL_REFCNT_ERROR_RETURN
  114. if (err != 0) {
  115. WOLFSSL_MSG("Bad reference count init");
  116. }
  117. #endif
  118. }
  119. #ifdef WOLFSSL_TRUST_PEER_CERT
  120. /* Create a mutex for use when modify table of trusted peers. */
  121. if ((!err) && (wc_InitMutex(&cm->tpLock) != 0)) {
  122. WOLFSSL_MSG("Bad mutex init");
  123. err = 1;
  124. }
  125. #endif
  126. if (!err) {
  127. /* Set default minimum key sizes allowed. */
  128. #ifndef NO_RSA
  129. cm->minRsaKeySz = MIN_RSAKEY_SZ;
  130. #endif
  131. #ifdef HAVE_ECC
  132. cm->minEccKeySz = MIN_ECCKEY_SZ;
  133. #endif
  134. #ifdef HAVE_PQC
  135. #ifdef HAVE_FALCON
  136. cm->minFalconKeySz = MIN_FALCONKEY_SZ;
  137. #endif /* HAVE_FALCON */
  138. #ifdef HAVE_DILITHIUM
  139. cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ;
  140. #endif /* HAVE_DILITHIUM */
  141. #endif /* HAVE_PQC */
  142. /* Set heap hint to use in certificate manager operations. */
  143. cm->heap = heap;
  144. }
  145. /* Dispose of certificate manager on error. */
  146. if (err && (cm != NULL)) {
  147. wolfSSL_CertManagerFree(cm);
  148. cm = NULL;
  149. }
  150. return cm;
  151. }
  152. /* Create a new certificate manager.
  153. *
  154. * @return Certificate manager object on success.
  155. * @return NULL on failure.
  156. */
  157. WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
  158. {
  159. /* No heap hint. */
  160. return wolfSSL_CertManagerNew_ex(NULL);
  161. }
  162. /* Dispose of certificate manager.
  163. *
  164. * @param [in, out] cm Certificate manager.
  165. */
  166. void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
  167. {
  168. WOLFSSL_ENTER("wolfSSL_CertManagerFree");
  169. /* Validate parameter. */
  170. if (cm != NULL) {
  171. int doFree = 0;
  172. int ret;
  173. /* Decrement reference count and check if value is 0. */
  174. wolfSSL_RefDec(&cm->ref, &doFree, &ret);
  175. #ifdef WOLFSSL_REFCNT_ERROR_RETURN
  176. if (ret != 0) {
  177. WOLFSSL_MSG("Couldn't lock cm mutex");
  178. }
  179. #else
  180. (void)ret;
  181. #endif
  182. if (doFree) {
  183. #ifdef HAVE_CRL
  184. /* Dispose of CRL handler. */
  185. if (cm->crl != NULL) {
  186. /* Dispose of CRL object - indicating dynamically allocated. */
  187. FreeCRL(cm->crl, 1);
  188. }
  189. #endif
  190. #ifdef HAVE_OCSP
  191. /* Dispose of OCSP handler. */
  192. if (cm->ocsp != NULL) {
  193. FreeOCSP(cm->ocsp, 1);
  194. }
  195. /* Dispose of URL. */
  196. XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
  197. #if !defined(NO_WOLFSSL_SERVER) && \
  198. (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
  199. defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
  200. /* Dispose of OCSP stapling handler. */
  201. if (cm->ocsp_stapling) {
  202. FreeOCSP(cm->ocsp_stapling, 1);
  203. }
  204. #endif
  205. #endif /* HAVE_OCSP */
  206. /* Dispose of CA table and mutex. */
  207. FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
  208. wc_FreeMutex(&cm->caLock);
  209. #ifdef WOLFSSL_TRUST_PEER_CERT
  210. /* Dispose of trusted peer table and mutex. */
  211. FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
  212. wc_FreeMutex(&cm->tpLock);
  213. #endif
  214. /* Dispose of reference count. */
  215. wolfSSL_RefFree(&cm->ref);
  216. /* Dispose of certificate manager memory. */
  217. XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
  218. }
  219. }
  220. }
  221. /* Increase reference count on certificate manager.
  222. *
  223. * @param [in, out] cm Certificate manager.
  224. * @return WOLFSSL_SUCCESS on success.
  225. * @return 0 when cm is NULL or locking mutex fails.
  226. */
  227. int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm)
  228. {
  229. int ret = WOLFSSL_SUCCESS;
  230. /* Validate parameter. */
  231. if (cm == NULL) {
  232. ret = 0;
  233. }
  234. if (ret == WOLFSSL_SUCCESS) {
  235. int err;
  236. /* Increment reference. */
  237. wolfSSL_RefInc(&cm->ref, &err);
  238. #ifdef WOLFSSL_REFCNT_ERROR_RETURN
  239. if (err) {
  240. WOLFSSL_MSG("Failed to lock cm mutex");
  241. ret = 0;
  242. }
  243. #else
  244. (void)err;
  245. #endif
  246. }
  247. return ret;
  248. }
  249. #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
  250. #if defined(WOLFSSL_SIGNER_DER_CERT)
  251. static WC_INLINE int wolfssl_cm_get_certs_der(WOLFSSL_CERT_MANAGER* cm,
  252. DerBuffer*** buffers, int* cnt)
  253. {
  254. int err = 0;
  255. Signer* signers = NULL;
  256. DerBuffer** certBuffers = NULL;
  257. int i = 0;
  258. word32 row = 0;
  259. int numCerts = 0;
  260. /* Iterate once to get the number of certs, for memory allocation
  261. * purposes. */
  262. for (row = 0; row < CA_TABLE_SIZE; row++) {
  263. /* Get signer information of CAs in a row. */
  264. signers = cm->caTable[row];
  265. /* Count each signer in row that has a DER certificate buffer. */
  266. while ((signers != NULL) && (signers->derCert != NULL) &&
  267. (signers->derCert->buffer != NULL)) {
  268. ++numCerts;
  269. signers = signers->next;
  270. }
  271. }
  272. /* Check we found certificates. */
  273. if (numCerts == 0) {
  274. err = 1;
  275. }
  276. if (!err) {
  277. /* Allocate memory for pointers to each DER buffer. */
  278. certBuffers = (DerBuffer**)XMALLOC(
  279. sizeof(DerBuffer*) * (size_t)numCerts, cm->heap,
  280. DYNAMIC_TYPE_TMP_BUFFER);
  281. if (certBuffers == NULL) {
  282. err = 1;
  283. }
  284. }
  285. if (!err) {
  286. /* Reset pointers. */
  287. XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * (size_t)numCerts);
  288. }
  289. /* Copy the certs locally so that we can release the caLock. If the lock
  290. * is held when wolfSSL_d2i_X509 is called, GetCA will also try to get
  291. * the lock, leading to deadlock. */
  292. for (row = 0; (!err) && (row < CA_TABLE_SIZE); row++) {
  293. /* Get signer information of CAs in a row. */
  294. signers = cm->caTable[row];
  295. /* Copy each DER certificate buffer of signers in a row. */
  296. while ((signers != NULL) && (signers->derCert != NULL) &&
  297. (signers->derCert->buffer != NULL)) {
  298. /* Allocate memory to hold DER certificate buffer. */
  299. int ret = AllocDer(&certBuffers[i], signers->derCert->length,
  300. CA_TYPE, cm->heap);
  301. if (ret < 0) {
  302. err = 1;
  303. break;
  304. }
  305. /* Copy buffer into array element. */
  306. XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer,
  307. signers->derCert->length);
  308. certBuffers[i]->length = signers->derCert->length;
  309. /* Store in next index. */
  310. ++i;
  311. /* Move on to next signer in row. */
  312. signers = signers->next;
  313. }
  314. }
  315. *buffers = certBuffers;
  316. *cnt = numCerts;
  317. return err;
  318. }
  319. /* Retrieve stack of X509 certificates in a certificate manager (CM).
  320. *
  321. * @param [in] cm Certificate manager.
  322. *
  323. * @return Stack of X509 certs on success
  324. * @return NULL on failure.
  325. */
  326. WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
  327. {
  328. WOLFSSL_STACK* sk = NULL;
  329. int numCerts = 0;
  330. DerBuffer** certBuffers = NULL;
  331. int i = 0;
  332. int err = 0;
  333. WOLFSSL_ENTER("wolfSSL_CertManagerGetCerts");
  334. /* Validate parameter. */
  335. if (cm == NULL) {
  336. err = 1;
  337. }
  338. if (!err) {
  339. /* Create an empty certificate stack to return. */
  340. sk = wolfSSL_sk_X509_new_null();
  341. if (sk == NULL) {
  342. err = 1;
  343. }
  344. }
  345. /* Lock CA table. */
  346. if ((!err) && (wc_LockMutex(&cm->caLock) != 0)) {
  347. err = 1;
  348. }
  349. if (!err) {
  350. err = wolfssl_cm_get_certs_der(cm, &certBuffers, &numCerts);
  351. /* Release CA lock. */
  352. wc_UnLockMutex(&cm->caLock);
  353. }
  354. /* Put each DER certificate buffer into a stack of WOLFSSL_X509 */
  355. for (i = 0; (!err) && (i < numCerts); ++i) {
  356. const byte* derBuffer = NULL;
  357. WOLFSSL_X509* x509 = NULL;
  358. /* Get pointer to DER encoding of certificate. */
  359. derBuffer = certBuffers[i]->buffer;
  360. /* Decode certificate. */
  361. wolfSSL_d2i_X509(&x509, &derBuffer, (int)certBuffers[i]->length);
  362. if (x509 == NULL) {
  363. err = 1;
  364. }
  365. /* Decode certificate. */
  366. if ((!err) && (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)) {
  367. wolfSSL_X509_free(x509);
  368. err = 1;
  369. }
  370. }
  371. if (certBuffers != NULL) {
  372. /* Dispose of temporary cert storage (for access outside of lock). */
  373. for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
  374. FreeDer(&certBuffers[i]);
  375. }
  376. XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
  377. }
  378. /* Dispose of stack of certificates on error. */
  379. if (err && (sk != NULL)) {
  380. wolfSSL_sk_X509_pop_free(sk, NULL);
  381. sk = NULL;
  382. }
  383. return sk;
  384. }
  385. #endif /* WOLFSSL_SIGNER_DER_CERT */
  386. #endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
  387. /* Unload the CA signer table.
  388. *
  389. * @param [in] cm Certificate manager.
  390. * @return WOLFSSL_SUCCESS on success.
  391. * @return BAD_FUNC_ARG when cm is NULL.
  392. * @return BAD_MUTEX_E when locking fails.
  393. */
  394. int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
  395. {
  396. int ret = WOLFSSL_SUCCESS;
  397. WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
  398. /* Validate parameter. */
  399. if (cm == NULL) {
  400. ret = BAD_FUNC_ARG;
  401. }
  402. /* Lock CA table. */
  403. if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
  404. ret = BAD_MUTEX_E;
  405. }
  406. if (ret == WOLFSSL_SUCCESS) {
  407. /* Dispose of CA table. */
  408. FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
  409. /* Unlock CA table. */
  410. wc_UnLockMutex(&cm->caLock);
  411. }
  412. return ret;
  413. }
  414. int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
  415. {
  416. int ret = WOLFSSL_SUCCESS;
  417. WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts");
  418. /* Validate parameter. */
  419. if (cm == NULL) {
  420. ret = BAD_FUNC_ARG;
  421. }
  422. /* Lock CA table. */
  423. if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
  424. ret = BAD_MUTEX_E;
  425. }
  426. if (ret == WOLFSSL_SUCCESS) {
  427. /* Dispose of CA table. */
  428. FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, WOLFSSL_CHAIN_CA,
  429. cm->heap);
  430. /* Unlock CA table. */
  431. wc_UnLockMutex(&cm->caLock);
  432. }
  433. return ret;
  434. }
  435. #ifdef WOLFSSL_TRUST_PEER_CERT
  436. /* Unload the trusted peers table.
  437. *
  438. * @param [in] cm Certificate manager.
  439. * @return WOLFSSL_SUCCESS on success.
  440. * @return BAD_FUNC_ARG when cm is NULL.
  441. * @return BAD_MUTEX_E when locking fails.
  442. */
  443. int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
  444. {
  445. int ret = WOLFSSL_SUCCESS;
  446. WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
  447. /* Validate parameter. */
  448. if (cm == NULL) {
  449. ret = BAD_FUNC_ARG;
  450. }
  451. /* Lock trusted peers table. */
  452. if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->tpLock) != 0)) {
  453. ret = BAD_MUTEX_E;
  454. }
  455. if (ret == WOLFSSL_SUCCESS) {
  456. /* Dispose of trusted peers table. */
  457. FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
  458. /* Unlock trusted peers table. */
  459. wc_UnLockMutex(&cm->tpLock);
  460. }
  461. return ret;
  462. }
  463. #endif /* WOLFSSL_TRUST_PEER_CERT */
  464. /* Load certificate/s from buffer with flags.
  465. *
  466. * @param [in] cm Certificate manager.
  467. * @param [in] buff Buffer holding encoding of certificate.
  468. * @param [in] sz Length in bytes of data in buffer.
  469. * @param [in] format Format of encoding. Valid values:
  470. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  471. * @param [in] userChain Indicates buffer holds chain of certificates.
  472. * @param [in] flags Flags to modify behaviour of loading. Valid flags:
  473. * WOLFSSL_LOAD_FLAG_IGNORE_ERR,
  474. * WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY,
  475. * WOLFSSL_LOAD_FLAG_PEM_CA_ONLY,
  476. * WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR, and
  477. * WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE.
  478. * @return WOLFSSL_SUCCESS on success.
  479. * @return WOLFSSL_FATAL_ERROR when cm is NULL or failed create WOLFSSL_CTX.
  480. * @return Other values on loading failure.
  481. */
  482. int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm,
  483. const unsigned char* buff, long sz, int format, int userChain, word32 flags)
  484. {
  485. int ret = WOLFSSL_SUCCESS;
  486. WOLFSSL_CTX* tmp = NULL;
  487. WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer_ex");
  488. /* Validate parameters. */
  489. if (cm == NULL) {
  490. WOLFSSL_MSG("No CertManager error");
  491. ret = WOLFSSL_FATAL_ERROR;
  492. }
  493. /* Allocate a temporary WOLFSSL_CTX to load with. */
  494. if ((ret == WOLFSSL_SUCCESS) && ((tmp =
  495. wolfSSL_CTX_new_ex(cm_pick_method(cm->heap), cm->heap)) == NULL)) {
  496. WOLFSSL_MSG("CTX new failed");
  497. ret = WOLFSSL_FATAL_ERROR;
  498. }
  499. if (ret == WOLFSSL_SUCCESS) {
  500. /* Some configurations like OPENSSL_COMPATIBLE_DEFAULTS may turn off
  501. * verification by default. Let's restore our desired defaults. */
  502. wolfSSL_CTX_set_verify(tmp, WOLFSSL_VERIFY_DEFAULT, NULL);
  503. /* Replace certificate manager with one to load certificate/s into. */
  504. wolfSSL_CertManagerFree(tmp->cm);
  505. tmp->cm = cm;
  506. /* Load certificate buffer. */
  507. ret = wolfSSL_CTX_load_verify_buffer_ex(tmp, buff, sz, format,
  508. userChain, flags);
  509. /* Clear certificate manager in WOLFSSL_CTX so it won't be freed. */
  510. tmp->cm = NULL;
  511. }
  512. /* Dispose of temporary WOLFSSL_CTX. */
  513. wolfSSL_CTX_free(tmp);
  514. return ret;
  515. }
  516. /* Load certificate/s from buffer into table.
  517. *
  518. * Uses default load verification flags and is not a user chain.
  519. *
  520. * @param [in] cm Certificate manager.
  521. * @param [in] buff Buffer holding encoding of certificate.
  522. * @param [in] sz Length in bytes of data in buffer.
  523. * @param [in] format Format of encoding. Valid values:
  524. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  525. * @return WOLFSSL_SUCCESS on success.
  526. * @return WOLFSSL_FATAL_ERROR when cm is NULL or failed create WOLFSSL_CTX.
  527. * @return Other values on loading failure.
  528. */
  529. int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
  530. const unsigned char* buff, long sz, int format)
  531. {
  532. return wolfSSL_CertManagerLoadCABuffer_ex(cm, buff, sz, format, 0,
  533. WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
  534. }
  535. #ifndef NO_WOLFSSL_CM_VERIFY
  536. /* Set the verification callback into certificate manager.
  537. *
  538. * @param [in] cm Certificate manager.
  539. * @param [in] vc Verification callback.
  540. */
  541. void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
  542. {
  543. WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
  544. if (cm != NULL) {
  545. cm->verifyCallback = vc;
  546. }
  547. }
  548. #endif /* NO_WOLFSSL_CM_VERIFY */
  549. #if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
  550. && defined(HAVE_OID_DECODING)
  551. void wolfSSL_CertManagerSetUnknownExtCallback(WOLFSSL_CERT_MANAGER* cm,
  552. wc_UnknownExtCallback cb)
  553. {
  554. WOLFSSL_ENTER("wolfSSL_CertManagerSetUnknownExtCallback");
  555. if (cm != NULL) {
  556. cm->unknownExtCallback = cb;
  557. }
  558. }
  559. #endif /* WOLFSSL_CUSTOM_OID && WOLFSSL_ASN_TEMPLATE && HAVE_OID_DECODING */
  560. #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
  561. /* Verify the certificate.
  562. *
  563. * Uses the verification callback if available.
  564. *
  565. * @param [in] cm Certificate manager.
  566. * @param [in] buff Buffer holding encoded certificate.
  567. * @param [in] sz Size in bytes of data in buffer.
  568. * @param [in] format Format of encoding. Valid values:
  569. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  570. * @param [in] prev_err Previous error. Passed to callback.
  571. * @return WOLFSSL_SUCCESS on success.
  572. * @return MEMORY_E when dynamic memory allocation fails.
  573. * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of
  574. * the wolfSSL build.
  575. */
  576. int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const unsigned char* buff,
  577. long sz, int format, int prev_err)
  578. {
  579. int ret = 0;
  580. int fatal = 0;
  581. DerBuffer* der = NULL;
  582. #ifdef WOLFSSL_SMALL_STACK
  583. DecodedCert* cert = NULL;
  584. #else
  585. DecodedCert cert[1];
  586. #endif
  587. WOLFSSL_ENTER("CM_VerifyBuffer_ex");
  588. (void)prev_err;
  589. #ifdef WOLFSSL_SMALL_STACK
  590. /* Allocate memory for decoded certificate. */
  591. cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
  592. DYNAMIC_TYPE_DCERT);
  593. if (cert == NULL) {
  594. ret = MEMORY_E;
  595. fatal = 1;
  596. }
  597. if (ret == 0)
  598. #endif
  599. {
  600. /* Reset fields of decoded certificate. */
  601. XMEMSET(cert, 0, sizeof(DecodedCert));
  602. if (format == WOLFSSL_FILETYPE_PEM) {
  603. #ifndef WOLFSSL_PEM_TO_DER
  604. ret = NOT_COMPILED_IN;
  605. fatal = 1;
  606. #else
  607. /* Convert to DER from PEM. */
  608. ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
  609. if (ret != 0) {
  610. fatal = 1;
  611. }
  612. else {
  613. /* Replace buffer pointer and size with DER buffer. */
  614. buff = der->buffer;
  615. sz = (long)der->length;
  616. }
  617. #endif
  618. }
  619. }
  620. if (ret == 0) {
  621. /* Create a decoded certificate with DER buffer. */
  622. InitDecodedCert(cert, buff, (word32)sz, cm->heap);
  623. #if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
  624. && defined(HAVE_OID_DECODING)
  625. if (cm->unknownExtCallback != NULL)
  626. wc_SetUnknownExtCallback(cert, cm->unknownExtCallback);
  627. #endif
  628. /* Parse DER into decoded certificate fields and verify signature
  629. * against a known CA. */
  630. ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, cm);
  631. }
  632. #ifdef HAVE_CRL
  633. if ((ret == 0) && cm->crlEnabled) {
  634. /* Check for a CRL for the CA and check validity of certificate. */
  635. ret = CheckCertCRL(cm->crl, cert);
  636. }
  637. #endif
  638. (void)fatal;
  639. #ifndef NO_WOLFSSL_CM_VERIFY
  640. /* Use callback to perform verification too if available. */
  641. if ((!fatal) && cm->verifyCallback) {
  642. #ifdef WOLFSSL_SMALL_STACK
  643. ProcPeerCertArgs* args;
  644. #else
  645. ProcPeerCertArgs args[1];
  646. #endif
  647. buffer certBuf;
  648. #ifdef WOLFSSL_SMALL_STACK
  649. /* Allocate memory for object to hold arguments for callback. */
  650. args = (ProcPeerCertArgs*)XMALLOC(sizeof(ProcPeerCertArgs), cm->heap,
  651. DYNAMIC_TYPE_TMP_BUFFER);
  652. if (args == NULL) {
  653. ret = MEMORY_E;
  654. fatal = 1;
  655. }
  656. if (!fatal)
  657. #endif
  658. {
  659. XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
  660. /* DER encoding. */
  661. certBuf.buffer = (byte*)buff;
  662. certBuf.length = (unsigned int)sz;
  663. /* One certificate available. */
  664. args->totalCerts = 1;
  665. args->certs = &certBuf;
  666. args->dCert = cert;
  667. args->dCertInit = 1;
  668. /* Replace value in ret with an error value passed in. */
  669. if (prev_err != 0) {
  670. ret = prev_err;
  671. }
  672. /* Use callback to verify certificate. */
  673. ret = DoVerifyCallback(cm, NULL, ret, args);
  674. }
  675. #ifdef WOLFSSL_SMALL_STACK
  676. /* Dispose of allocated callback args. */
  677. XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
  678. #endif
  679. }
  680. #endif
  681. /* Dispose of allocated memory. */
  682. FreeDecodedCert(cert);
  683. FreeDer(&der);
  684. #ifdef WOLFSSL_SMALL_STACK
  685. XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
  686. #endif
  687. /* Convert the ret value to a return value. */
  688. return (ret == 0) ? WOLFSSL_SUCCESS : ret;
  689. }
  690. /* Verify the certificate.
  691. *
  692. * Uses the verification callback if available.
  693. *
  694. * @param [in] cm Certificate manager.
  695. * @param [in] buff Buffer holding encoded certificate.
  696. * @param [in] sz Size in bytes of data in buffer.
  697. * @param [in] format Format of encoding. Valid values:
  698. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  699. * @param [in] prev_err Previous error. Passed to callback.
  700. * @return WOLFSSL_SUCCESS on success.
  701. * @return BAD_FUNC_ARG when cm or buff is NULL or sz is negative or zero.
  702. * @return WOLFSSL_BAD_FILETYPE when format is invalid.
  703. * @return MEMORY_E when dynamic memory allocation fails.
  704. * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of
  705. * the wolfSSL build.
  706. */
  707. int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm,
  708. const unsigned char* buff, long sz, int format)
  709. {
  710. int ret;
  711. WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
  712. /* Validate parameters. */
  713. if ((cm == NULL) || (buff == NULL) || (sz <= 0)) {
  714. ret = BAD_FUNC_ARG;
  715. }
  716. else if ((format != WOLFSSL_FILETYPE_ASN1) &&
  717. (format != WOLFSSL_FILETYPE_PEM)) {
  718. ret = WOLFSSL_BAD_FILETYPE;
  719. }
  720. else {
  721. /* No previous error. */
  722. ret = CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
  723. }
  724. return ret;
  725. }
  726. #endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */
  727. #ifndef NO_FILESYSTEM
  728. #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
  729. /* Verify the certificate loaded from a file.
  730. *
  731. * Uses the verification callback if available.
  732. *
  733. * @param [in] cm Certificate manager.
  734. * @param [in] format Format of encoding. Valid values:
  735. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  736. * @param [in] prev_err Previous error. Passed to callback.
  737. * @return WOLFSSL_SUCCESS on success.
  738. * @return BAD_FUNC_ARG when cm or buff is NULL or sz is negative.
  739. * @return WOLFSSL_BAD_FILETYPE when format is invalid.
  740. * @return WOLFSSL_BAD_FILE when reading the certificate file fails.
  741. * @return MEMORY_E when dynamic memory allocation fails.
  742. * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of
  743. * the wolfSSL build.
  744. */
  745. int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
  746. int format)
  747. {
  748. int ret = WOLFSSL_SUCCESS;
  749. #ifndef WOLFSSL_SMALL_STACK
  750. byte staticBuffer[FILE_BUFFER_SIZE];
  751. #endif
  752. byte* buff = NULL;
  753. long sz = 0;
  754. XFILE file = XBADFILE;
  755. WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
  756. #ifndef WOLFSSL_SMALL_STACK
  757. buff = staticBuffer;
  758. #endif
  759. /* Validate parameters. cm and format validated in:
  760. * wolfSSL_CertManagerVerifyBuffer */
  761. if ((cm == NULL) || (fname == NULL)) {
  762. ret = BAD_FUNC_ARG;
  763. }
  764. /* Open the file containing a certificate. */
  765. if ((ret == WOLFSSL_SUCCESS) &&
  766. ((file = XFOPEN(fname, "rb")) == XBADFILE)) {
  767. ret = WOLFSSL_BAD_FILE;
  768. }
  769. /* Get the length of the file. */
  770. if (ret == WOLFSSL_SUCCESS) {
  771. ret = wolfssl_file_len(file, &sz);
  772. if (ret == 0) {
  773. ret = WOLFSSL_SUCCESS;
  774. }
  775. }
  776. /* Allocate dynamic memory for file contents if no static buffer or too
  777. * small. */
  778. #ifndef WOLFSSL_SMALL_STACK
  779. if ((ret == WOLFSSL_SUCCESS) && (sz > (long)sizeof(staticBuffer)))
  780. #else
  781. if (ret == WOLFSSL_SUCCESS)
  782. #endif
  783. {
  784. WOLFSSL_MSG("Getting dynamic buffer");
  785. buff = (byte*)XMALLOC((size_t)sz, cm->heap, DYNAMIC_TYPE_FILE);
  786. if (buff == NULL) {
  787. ret = WOLFSSL_BAD_FILE;
  788. }
  789. }
  790. /* Read all the file into buffer. */
  791. if ((ret == WOLFSSL_SUCCESS) && (XFREAD(buff, 1, (size_t)sz, file) !=
  792. (size_t)sz)) {
  793. ret = WOLFSSL_BAD_FILE;
  794. }
  795. /* Close file if opened. */
  796. if (file != XBADFILE) {
  797. XFCLOSE(file);
  798. }
  799. if (ret == WOLFSSL_SUCCESS) {
  800. /* Verify the certificate read. */
  801. ret = wolfSSL_CertManagerVerifyBuffer(cm, buff, sz, format);
  802. }
  803. /* Dispose of buffer if it was allocated. */
  804. #ifndef WOLFSSL_SMALL_STACK
  805. if (buff != staticBuffer)
  806. #endif
  807. {
  808. if (cm != NULL) {
  809. XFREE(buff, cm->heap, DYNAMIC_TYPE_FILE);
  810. }
  811. }
  812. return ret;
  813. }
  814. #endif
  815. /* Load the CA file and/or certificate files in a path.
  816. *
  817. * @param [in] cm Certificate manager.
  818. * @param [in] file Name of CA file.
  819. * @param [in] path Path to a directory containing certificates.
  820. * @return WOLFSSL_SUCCESS on success.
  821. * @return WOLFSSL_FATAL_ERROR when cm is NULL or unable to create WOLFSSL_CTX.
  822. * @return Otherwise failure.
  823. */
  824. int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
  825. const char* path)
  826. {
  827. int ret = WOLFSSL_SUCCESS;
  828. WOLFSSL_CTX* tmp = NULL;
  829. WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
  830. /* Validate parameters. file and path validated in:
  831. * wolfSSL_CTX_load_verify_locations*/
  832. if (cm == NULL) {
  833. WOLFSSL_MSG("No CertManager error");
  834. ret = WOLFSSL_FATAL_ERROR;
  835. }
  836. /* Create temporary WOLFSSL_CTX. */
  837. if ((ret == WOLFSSL_SUCCESS) && ((tmp =
  838. wolfSSL_CTX_new_ex(cm_pick_method(cm->heap), cm->heap)) == NULL)) {
  839. WOLFSSL_MSG("CTX new failed");
  840. ret = WOLFSSL_FATAL_ERROR;
  841. }
  842. if (ret == WOLFSSL_SUCCESS) {
  843. /* Some configurations like OPENSSL_COMPATIBLE_DEFAULTS may turn off
  844. * verification by default. Let's restore our desired defaults. */
  845. wolfSSL_CTX_set_verify(tmp, WOLFSSL_VERIFY_DEFAULT, NULL);
  846. /* Replace certificate manager with one to load certificate/s into. */
  847. wolfSSL_CertManagerFree(tmp->cm);
  848. tmp->cm = cm;
  849. /* Load certificate from file and path. */
  850. ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
  851. /* Clear certificate manager in WOLFSSL_CTX so it won't be freed. */
  852. tmp->cm = NULL;
  853. }
  854. /* Dispose of temporary WOLFSSL_CTX. */
  855. wolfSSL_CTX_free(tmp);
  856. return ret;
  857. }
  858. #endif /* NO_FILESYSTEM */
  859. #if defined(PERSIST_CERT_CACHE)
  860. /* Version of layout of cache of CA certificates. */
  861. #define WOLFSSL_CACHE_CERT_VERSION 1
  862. /* CA certificates cache information. */
  863. typedef struct {
  864. /* Cache certificate layout version id. */
  865. int version;
  866. /* Number of hash table rows. Maximum of CA_TABLE_SIZE. */
  867. int rows;
  868. /* Number of columns per row. */
  869. int columns[CA_TABLE_SIZE];
  870. /* Size of Signer object. */
  871. int signerSz;
  872. } CertCacheHeader;
  873. /* current cert persistence layout is:
  874. 1) CertCacheHeader
  875. 2) caTable
  876. update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
  877. PERSIST_CERT_CACHE functions
  878. */
  879. /* Return number of bytes of memory needed to persist this signer.
  880. *
  881. * Assumes we have locked CA table.
  882. *
  883. * @param [in] Signer Signer entry in CA table.
  884. * @return Number of bytes.
  885. */
  886. static WC_INLINE int cm_get_signer_memory(Signer* signer)
  887. {
  888. int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
  889. + sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
  890. #if !defined(NO_SKID)
  891. sz += (int)sizeof(signer->subjectKeyIdHash);
  892. #endif
  893. /* Add dynamic bytes needed. */
  894. sz += (int)signer->pubKeySize;
  895. sz += signer->nameLen;
  896. return sz;
  897. }
  898. /* Return number of bytes of memory needed to persist this row.
  899. *
  900. * Assumes we have locked CA table.
  901. *
  902. * @param [in] row A row of signers from the CA table.
  903. * @return Number of bytes.
  904. */
  905. static WC_INLINE int cm_get_cert_cache_row_memory(Signer* row)
  906. {
  907. int sz = 0;
  908. /* Each signer in row. */
  909. while (row != NULL) {
  910. /* Add in size of this signer. */
  911. sz += cm_get_signer_memory(row);
  912. row = row->next;
  913. }
  914. return sz;
  915. }
  916. /* Return the number of bytes of memory to persist cert cache.
  917. *
  918. * Assumes we have locked CA table.
  919. *
  920. * @param [in] cm Certificate manager.
  921. * @return Number of bytes.
  922. */
  923. static WC_INLINE int cm_get_cert_cache_mem_size(WOLFSSL_CERT_MANAGER* cm)
  924. {
  925. int sz;
  926. int i;
  927. sz = sizeof(CertCacheHeader);
  928. /* Each row in table. */
  929. for (i = 0; i < CA_TABLE_SIZE; i++) {
  930. /* Add in size of this row. */
  931. sz += cm_get_cert_cache_row_memory(cm->caTable[i]);
  932. }
  933. return sz;
  934. }
  935. /* Get count of columns for each row.
  936. *
  937. * Assumes we have locked CA table.
  938. *
  939. * @param [in] cm Certificate manager.
  940. * @param [in] columns Array of row counts.
  941. */
  942. static WC_INLINE void cm_set_cert_header_Columns(WOLFSSL_CERT_MANAGER* cm,
  943. int* columns)
  944. {
  945. int i;
  946. Signer* row;
  947. /* Each row in table. */
  948. for (i = 0; i < CA_TABLE_SIZE; i++) {
  949. int count = 0;
  950. /* Get row from table. */
  951. row = cm->caTable[i];
  952. /* Each entry in row. */
  953. while (row != NULL) {
  954. /* Update count. */
  955. ++count;
  956. row = row->next;
  957. }
  958. /* Store row count. */
  959. columns[i] = count;
  960. }
  961. }
  962. /* Restore whole cert row from memory,
  963. *
  964. * Assumes we have locked CA table.
  965. *
  966. * @param [in] cm Certificate manager.
  967. * @param [in] current Buffer containing rows.
  968. * @param [in] row Row number being restored.
  969. * @param [in] listSz Number of entries in row.
  970. * @param [in] end End of data in buffer.
  971. * @return Number of bytes consumed on success.
  972. * @return PARSE_ERROR when listSz is less than zero.
  973. * @return BUFFER_E when buffer is too small.
  974. * @return MEMORY_E when dynamic memory allocation fails.
  975. * @return Negative value on error.
  976. */
  977. static WC_INLINE int cm_restore_cert_row(WOLFSSL_CERT_MANAGER* cm,
  978. byte* current, int row, int listSz, const byte* end)
  979. {
  980. int ret = 0;
  981. int idx = 0;
  982. /* Validate parameters. */
  983. if (listSz < 0) {
  984. WOLFSSL_MSG("Row header corrupted, negative value");
  985. ret = PARSE_ERROR;
  986. }
  987. /* Process all entries. */
  988. while ((ret == 0) && (listSz > 0)) {
  989. Signer* signer = NULL;
  990. byte* publicKey;
  991. byte* start = current + idx; /* for end checks on this signer */
  992. int minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
  993. sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
  994. #ifndef NO_SKID
  995. minSz += (int)sizeof(signer->subjectKeyIdHash);
  996. #endif
  997. /* Check minimal size of bytes available. */
  998. if (start + minSz > end) {
  999. WOLFSSL_MSG("Would overread restore buffer");
  1000. ret = BUFFER_E;
  1001. }
  1002. /* Make a new signer. */
  1003. if ((ret == 0) && ((signer = MakeSigner(cm->heap)) == NULL)) {
  1004. ret = MEMORY_E;
  1005. }
  1006. if (ret == 0) {
  1007. /* Copy in public key size. */
  1008. XMEMCPY(&signer->pubKeySize, current + idx,
  1009. sizeof(signer->pubKeySize));
  1010. idx += (int)sizeof(signer->pubKeySize);
  1011. /* Copy in public key OID. */
  1012. XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
  1013. idx += (int)sizeof(signer->keyOID);
  1014. /* Check bytes available for public key. */
  1015. if (start + minSz + signer->pubKeySize > end) {
  1016. WOLFSSL_MSG("Would overread restore buffer");
  1017. ret = BUFFER_E;
  1018. }
  1019. }
  1020. if (ret == 0) {
  1021. /* Allocate memory for public key to be stored in. */
  1022. publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
  1023. DYNAMIC_TYPE_KEY);
  1024. if (publicKey == NULL) {
  1025. ret = MEMORY_E;
  1026. }
  1027. }
  1028. if (ret == 0) {
  1029. /* Copy in public key. */
  1030. XMEMCPY(publicKey, current + idx, signer->pubKeySize);
  1031. signer->publicKey = publicKey;
  1032. idx += (int)signer->pubKeySize;
  1033. /* Copy in certificate name length. */
  1034. XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
  1035. idx += (int)sizeof(signer->nameLen);
  1036. /* Check bytes available for certificate name. */
  1037. if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
  1038. WOLFSSL_MSG("Would overread restore buffer");
  1039. ret = BUFFER_E;
  1040. }
  1041. }
  1042. if (ret == 0) {
  1043. /* Allocate memory for public key to be stored in. */
  1044. signer->name = (char*)XMALLOC((size_t)signer->nameLen, cm->heap,
  1045. DYNAMIC_TYPE_SUBJECT_CN);
  1046. if (signer->name == NULL) {
  1047. ret = MEMORY_E;
  1048. }
  1049. }
  1050. if (ret == 0) {
  1051. /* Copy in certificate name. */
  1052. XMEMCPY(signer->name, current + idx, (size_t)signer->nameLen);
  1053. idx += signer->nameLen;
  1054. /* Copy in hash of subject name. */
  1055. XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
  1056. idx += SIGNER_DIGEST_SIZE;
  1057. #ifndef NO_SKID
  1058. /* Copy in hash of subject key. */
  1059. XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
  1060. idx += SIGNER_DIGEST_SIZE;
  1061. #endif
  1062. /* Make next Signer the head of the row. */
  1063. signer->next = cm->caTable[row];
  1064. /* Add Signer to start of row. */
  1065. cm->caTable[row] = signer;
  1066. /* Done one more Signer. */
  1067. --listSz;
  1068. }
  1069. if ((ret != 0) && (signer != NULL)) {
  1070. /* Dispose of allocated signer. */
  1071. FreeSigner(signer, cm->heap);
  1072. }
  1073. }
  1074. if (ret == 0) {
  1075. /* Return the number of bytes used on success. */
  1076. ret = idx;
  1077. }
  1078. return ret;
  1079. }
  1080. /* Store whole CA certificate row into memory.
  1081. *
  1082. * Assumes we have locked CA table.
  1083. *
  1084. * @param [in] cm Certificate manager.
  1085. * @param [in] current Buffer to write to.
  1086. * @param [in] row Row number being stored.
  1087. * @return Number of bytes added.
  1088. */
  1089. static WC_INLINE int cm_store_cert_row(WOLFSSL_CERT_MANAGER* cm, byte* current,
  1090. int row)
  1091. {
  1092. int added = 0;
  1093. Signer* list;
  1094. /* Get the row - a linked list. */
  1095. list = cm->caTable[row];
  1096. /* Each certificate in row. */
  1097. while (list != NULL) {
  1098. /* Public key size. */
  1099. XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
  1100. added += (int)sizeof(list->pubKeySize);
  1101. /* Public key OID. */
  1102. XMEMCPY(current + added, &list->keyOID, sizeof(list->keyOID));
  1103. added += (int)sizeof(list->keyOID);
  1104. /* Public key. */
  1105. XMEMCPY(current + added, list->publicKey, (size_t)list->pubKeySize);
  1106. added += (int)list->pubKeySize;
  1107. /* Certificate name length. */
  1108. XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
  1109. added += (int)sizeof(list->nameLen);
  1110. /* Certificate name. */
  1111. XMEMCPY(current + added, list->name, (size_t)list->nameLen);
  1112. added += list->nameLen;
  1113. /* Hash of subject name. */
  1114. XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
  1115. added += SIGNER_DIGEST_SIZE;
  1116. #ifndef NO_SKID
  1117. /* Hash of public key. */
  1118. XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
  1119. added += SIGNER_DIGEST_SIZE;
  1120. #endif
  1121. /* Next certificate in row. */
  1122. list = list->next;
  1123. }
  1124. return added;
  1125. }
  1126. /* Persist CA certificate cache to memory.
  1127. *
  1128. * Assumes we have locked CA table.
  1129. *
  1130. * @param [in] cm Certificate manager.
  1131. * @param [in] mem Memory to persist into.
  1132. * @param [in] sz Size in bytes of memory.
  1133. * @return WOLFSSL_SUCCESS on success.
  1134. * @return BUFFER_E when memory is too small.
  1135. */
  1136. static WC_INLINE int cm_do_mem_save_cert_cache(WOLFSSL_CERT_MANAGER* cm,
  1137. void* mem, int sz)
  1138. {
  1139. int ret = WOLFSSL_SUCCESS;
  1140. int realSz;
  1141. int i;
  1142. WOLFSSL_ENTER("cm_do_mem_save_cert_cache");
  1143. /* Calculate amount of memory required to store CA certificate table. */
  1144. realSz = cm_get_cert_cache_mem_size(cm);
  1145. if (realSz > sz) {
  1146. WOLFSSL_MSG("Mem output buffer too small");
  1147. ret = BUFFER_E;
  1148. }
  1149. if (ret == WOLFSSL_SUCCESS) {
  1150. byte* current;
  1151. CertCacheHeader hdr;
  1152. /* Create header for storage. */
  1153. hdr.version = WOLFSSL_CACHE_CERT_VERSION;
  1154. hdr.rows = CA_TABLE_SIZE;
  1155. cm_set_cert_header_Columns(cm, hdr.columns);
  1156. hdr.signerSz = (int)sizeof(Signer);
  1157. /* Copy header into memory. */
  1158. XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
  1159. current = (byte*)mem + sizeof(CertCacheHeader);
  1160. /* Each row of table. */
  1161. for (i = 0; i < CA_TABLE_SIZE; ++i) {
  1162. /* Append row to memory. */
  1163. current += cm_store_cert_row(cm, current, i);
  1164. }
  1165. }
  1166. return ret;
  1167. }
  1168. #if !defined(NO_FILESYSTEM)
  1169. /* Persist CA certificate cache to file.
  1170. *
  1171. * Locks CA table.
  1172. *
  1173. * @param [in] cm Certificate manager.
  1174. * @param [in] fname File name to write to.
  1175. * @return WOLFSSL_SUCCESS on success.
  1176. * @return WOLFSSL_BAD_FILE when opening file fails.
  1177. * @return BAD_MUTEX_E when locking fails.
  1178. * @return MEMORY_E when dynamic memory allocation fails.
  1179. * @return FWRITE_ERROR when writing to file fails.
  1180. */
  1181. int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
  1182. {
  1183. XFILE file;
  1184. int ret = WOLFSSL_SUCCESS;
  1185. WOLFSSL_ENTER("CM_SaveCertCache");
  1186. /* Open file for writing. */
  1187. file = XFOPEN(fname, "w+b");
  1188. if (file == XBADFILE) {
  1189. WOLFSSL_MSG("Couldn't open cert cache save file");
  1190. ret = WOLFSSL_BAD_FILE;
  1191. }
  1192. /* Lock CA table. */
  1193. if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
  1194. WOLFSSL_MSG("wc_LockMutex on caLock failed");
  1195. ret = BAD_MUTEX_E;
  1196. }
  1197. if (ret == WOLFSSL_SUCCESS) {
  1198. byte* mem;
  1199. /* Calculate size of memory required to store CA table. */
  1200. size_t memSz = (size_t)cm_get_cert_cache_mem_size(cm);
  1201. /* Allocate memory to hold CA table. */
  1202. mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1203. if (mem == NULL) {
  1204. WOLFSSL_MSG("Alloc for tmp buffer failed");
  1205. ret = MEMORY_E;
  1206. }
  1207. if (ret == WOLFSSL_SUCCESS) {
  1208. /* Store CA table in memory. */
  1209. ret = cm_do_mem_save_cert_cache(cm, mem, (int)memSz);
  1210. }
  1211. if (ret == WOLFSSL_SUCCESS) {
  1212. /* Write memory to file. */
  1213. int sz = (int)XFWRITE(mem, memSz, 1, file);
  1214. if (sz != 1) {
  1215. WOLFSSL_MSG("Cert cache file write failed");
  1216. ret = FWRITE_ERROR;
  1217. }
  1218. }
  1219. if (mem != NULL) {
  1220. XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1221. }
  1222. /* Unlock CA table. */
  1223. wc_UnLockMutex(&cm->caLock);
  1224. }
  1225. /* Close file. */
  1226. if (file != XBADFILE) {
  1227. XFCLOSE(file);
  1228. }
  1229. return ret;
  1230. }
  1231. /* Restore CA certificate cache from file.
  1232. *
  1233. * @param [in] cm Certificate manager.
  1234. * @param [in] fname File name to write to.
  1235. * @return WOLFSSL_SUCCESS on success.
  1236. * @return WOLFSSL_BAD_FILE when opening or using file fails.
  1237. * @return MEMORY_E when dynamic memory allocation fails.
  1238. * @return FREAD_ERROR when reading from file fails.
  1239. */
  1240. int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
  1241. {
  1242. XFILE file;
  1243. int ret = WOLFSSL_SUCCESS;
  1244. int memSz = 0;
  1245. byte* mem = NULL;
  1246. WOLFSSL_ENTER("CM_RestoreCertCache");
  1247. /* Open file for reading. */
  1248. file = XFOPEN(fname, "rb");
  1249. if (file == XBADFILE) {
  1250. WOLFSSL_MSG("Couldn't open cert cache save file");
  1251. ret = WOLFSSL_BAD_FILE;
  1252. }
  1253. if (ret == WOLFSSL_SUCCESS) {
  1254. /* Read file into allocated memory. */
  1255. ret = wolfssl_read_file(file, (char**)&mem, &memSz);
  1256. if (ret == 0) {
  1257. ret = WOLFSSL_SUCCESS;
  1258. }
  1259. }
  1260. if (ret == WOLFSSL_SUCCESS) {
  1261. /* Create the CA certificate table from memory. */
  1262. ret = CM_MemRestoreCertCache(cm, mem, memSz);
  1263. if (ret != WOLFSSL_SUCCESS) {
  1264. WOLFSSL_MSG("Mem restore cert cache failed");
  1265. }
  1266. }
  1267. /* Dispose of dynamic memory read into. */
  1268. XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1269. /* Close file. */
  1270. if (file != XBADFILE) {
  1271. XFCLOSE(file);
  1272. }
  1273. return ret;
  1274. }
  1275. #endif /* NO_FILESYSTEM */
  1276. /* Persist CA certificate cache to memory.
  1277. *
  1278. * Locks CA table.
  1279. *
  1280. * @param [in] cm Certificate manager.
  1281. * @param [in] mem Memory to persist into.
  1282. * @param [in] sz Size in bytes of memory.
  1283. * @param [out] used Number of bytes used when persisting cache.
  1284. * @return WOLFSSL_SUCCESS on success.
  1285. * @return BAD_MUTEX_E when locking fails.
  1286. * @return BUFFER_E when memory is too small.
  1287. */
  1288. int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
  1289. {
  1290. int ret = WOLFSSL_SUCCESS;
  1291. WOLFSSL_ENTER("CM_MemSaveCertCache");
  1292. /* Lock CA table. */
  1293. if (wc_LockMutex(&cm->caLock) != 0) {
  1294. WOLFSSL_MSG("wc_LockMutex on caLock failed");
  1295. ret = BAD_MUTEX_E;
  1296. }
  1297. if (ret == WOLFSSL_SUCCESS) {
  1298. /* Save CA table into memory. */
  1299. ret = cm_do_mem_save_cert_cache(cm, mem, sz);
  1300. if (ret == WOLFSSL_SUCCESS) {
  1301. /* Get the number of bytes used. */
  1302. *used = cm_get_cert_cache_mem_size(cm);
  1303. }
  1304. /* Unlock CA table. */
  1305. wc_UnLockMutex(&cm->caLock);
  1306. }
  1307. return ret;
  1308. }
  1309. /* Restore CA certificate table from memory,
  1310. *
  1311. * Locks CA table.
  1312. *
  1313. * @param [in] cm Certificate manager.
  1314. * @param [in] mem Buffer containing rows.
  1315. * @param [in] sz Size in bytes of data in buffer.
  1316. * @return WOLFSSL_SUCCESS on success.
  1317. * @return BUFFER_E when buffer is too small.
  1318. * @return BAD_MUTEX_E when locking fails.
  1319. * @return MEMORY_E when dynamic memory allocation fails.
  1320. */
  1321. int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
  1322. {
  1323. int ret = WOLFSSL_SUCCESS;
  1324. int i;
  1325. CertCacheHeader* hdr = (CertCacheHeader*)mem;
  1326. byte* current = (byte*)mem + sizeof(CertCacheHeader);
  1327. byte* end = (byte*)mem + sz; /* don't go over */
  1328. WOLFSSL_ENTER("CM_MemRestoreCertCache");
  1329. /* Check memory available is bigger than cache header. */
  1330. if (current > end) {
  1331. WOLFSSL_MSG("Cert Cache Memory buffer too small");
  1332. ret = BUFFER_E;
  1333. }
  1334. /* Validate the cache header. */
  1335. if ((ret == WOLFSSL_SUCCESS) &&
  1336. ((hdr->version != WOLFSSL_CACHE_CERT_VERSION) ||
  1337. (hdr->rows != CA_TABLE_SIZE) ||
  1338. (hdr->signerSz != (int)sizeof(Signer)))) {
  1339. WOLFSSL_MSG("Cert Cache Memory header mismatch");
  1340. ret = CACHE_MATCH_ERROR;
  1341. }
  1342. /* Lock CA table. */
  1343. if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
  1344. WOLFSSL_MSG("wc_LockMutex on caLock failed");
  1345. ret = BAD_MUTEX_E;
  1346. }
  1347. if (ret == WOLFSSL_SUCCESS) {
  1348. /* Dispose of current CA certificate table. */
  1349. FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
  1350. /* Each row. */
  1351. for (i = 0; i < CA_TABLE_SIZE; ++i) {
  1352. /* Restore a row from memory. */
  1353. int added = cm_restore_cert_row(cm, current, i, hdr->columns[i],
  1354. end);
  1355. /* Bail on error. */
  1356. if (added < 0) {
  1357. WOLFSSL_MSG("cm_restore_cert_row error");
  1358. ret = added;
  1359. break;
  1360. }
  1361. /* Update pointer to data of next row. */
  1362. current += added;
  1363. }
  1364. /* Unlock CA table. */
  1365. wc_UnLockMutex(&cm->caLock);
  1366. }
  1367. return ret;
  1368. }
  1369. /* Calculate size of CA certificate cache when persisted to memory.
  1370. *
  1371. * Locks CA table.
  1372. *
  1373. * @param [in] cm Certificate manager.
  1374. * @return Number of bytes on success.
  1375. * @return BAD_MUTEX_E when locking fails.
  1376. */
  1377. int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
  1378. {
  1379. int ret;
  1380. WOLFSSL_ENTER("CM_GetCertCacheMemSize");
  1381. /* Lock CA table. */
  1382. if (wc_LockMutex(&cm->caLock) != 0) {
  1383. WOLFSSL_MSG("wc_LockMutex on caLock failed");
  1384. ret = BAD_MUTEX_E;
  1385. }
  1386. else {
  1387. /* Calculate memory size. */
  1388. ret = cm_get_cert_cache_mem_size(cm);
  1389. /* Unlock CA table. */
  1390. wc_UnLockMutex(&cm->caLock);
  1391. }
  1392. return ret;
  1393. }
  1394. #endif /* PERSIST_CERT_CACHE */
  1395. /*******************************************************************************
  1396. * CRL handling
  1397. ******************************************************************************/
  1398. /* Enables/disables the use of CRLs when validating certificates.
  1399. *
  1400. * @param [in] cm Certificate manager.
  1401. * @param [in] options Options for using CRLs. Valid flags:
  1402. * WOLFSSL_CRL_CHECKALL, WOLFSSL_CRL_CHECK.
  1403. * @return WOLFSSL_SUCCESS on success.
  1404. * @return WOLFSSL_FAILURE when initializing the CRL object fails.
  1405. * @return BAD_FUNC_ARG when cm is NULL.
  1406. * @return MEMORY_E when dynamic memory allocation fails.
  1407. * @return NOT_COMPILED_IN when the CRL feature is disabled.
  1408. */
  1409. int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
  1410. {
  1411. int ret = WOLFSSL_SUCCESS;
  1412. WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
  1413. (void)options;
  1414. /* Validate parameters. */
  1415. if (cm == NULL) {
  1416. ret = BAD_FUNC_ARG;
  1417. }
  1418. #if defined(OPENSSL_COMPATIBLE_DEFAULTS)
  1419. /* If disabling then don't worry about whether CRL feature is enabled. */
  1420. if ((ret == WOLFSSL_SUCCESS) && (options == 0)) {
  1421. /* Disable leaf CRL check. */
  1422. cm->crlEnabled = 0;
  1423. /* Disable all CRL checks. */
  1424. cm->crlCheckAll = 0;
  1425. }
  1426. else
  1427. #endif
  1428. if (ret == WOLFSSL_SUCCESS) {
  1429. #ifndef HAVE_CRL
  1430. /* CRL feature not enabled. */
  1431. ret = NOT_COMPILED_IN;
  1432. #else
  1433. /* Create CRL object if not present. */
  1434. if (cm->crl == NULL) {
  1435. /* Allocate memory for CRL object. */
  1436. cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
  1437. DYNAMIC_TYPE_CRL);
  1438. if (cm->crl == NULL) {
  1439. ret = MEMORY_E;
  1440. }
  1441. if (ret == WOLFSSL_SUCCESS) {
  1442. /* Reset fields of CRL object. */
  1443. XMEMSET(cm->crl, 0, sizeof(WOLFSSL_CRL));
  1444. /* Initialize CRL object. */
  1445. if (InitCRL(cm->crl, cm) != 0) {
  1446. WOLFSSL_MSG("Init CRL failed");
  1447. /* Dispose of CRL object - indicating dynamically allocated.
  1448. */
  1449. FreeCRL(cm->crl, 1);
  1450. cm->crl = NULL;
  1451. ret = WOLFSSL_FAILURE;
  1452. }
  1453. }
  1454. }
  1455. if (ret == WOLFSSL_SUCCESS) {
  1456. #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO)
  1457. /* Use built-in callback to lookup CRL from URL. */
  1458. cm->crl->crlIOCb = EmbedCrlLookup;
  1459. #endif
  1460. #if defined(OPENSSL_COMPATIBLE_DEFAULTS)
  1461. if ((options & WOLFSSL_CRL_CHECKALL) ||
  1462. (options & WOLFSSL_CRL_CHECK))
  1463. #endif
  1464. {
  1465. /* Enable leaf CRL check. */
  1466. cm->crlEnabled = 1;
  1467. if (options & WOLFSSL_CRL_CHECKALL) {
  1468. /* Enable all CRL check. */
  1469. cm->crlCheckAll = 1;
  1470. }
  1471. }
  1472. }
  1473. #endif
  1474. }
  1475. return ret;
  1476. }
  1477. /* Disables the CRL checks.
  1478. *
  1479. * @param [in] cm Certificate manager.
  1480. * @return WOLFSSL_SUCCESS on success.
  1481. * @return BAD_FUNC_ARG when cm is NULL.
  1482. */
  1483. int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
  1484. {
  1485. int ret = WOLFSSL_SUCCESS;
  1486. WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
  1487. /* Validate parameter. */
  1488. if (cm == NULL) {
  1489. ret = BAD_FUNC_ARG;
  1490. }
  1491. if (ret == WOLFSSL_SUCCESS) {
  1492. /* Disable CRL checking. */
  1493. cm->crlEnabled = 0;
  1494. cm->crlCheckAll = 0;
  1495. }
  1496. return ret;
  1497. }
  1498. #ifdef HAVE_CRL
  1499. /* Load CRL for use.
  1500. *
  1501. * @param [in] cm Certificate manager.
  1502. * @param [in] buff Buffer holding CRL.
  1503. * @param [in] sz Size in bytes of CRL in buffer.
  1504. * @param [in] type Format of encoding. Valid values:
  1505. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  1506. * @return WOLFSSL_SUCCESS on success.
  1507. * @return BAD_FUNC_ARG when cm or buff is NULL or sz is negative or zero.
  1508. * @return WOLFSSL_FATAL_ERROR when creating CRL object fails.
  1509. */
  1510. int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
  1511. const unsigned char* buff, long sz, int type)
  1512. {
  1513. int ret = WOLFSSL_SUCCESS;
  1514. WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
  1515. /* Validate parameters. */
  1516. if ((cm == NULL) || (buff == NULL) || (sz <= 0)) {
  1517. ret = BAD_FUNC_ARG;
  1518. }
  1519. /* Create a CRL object if not available and enable CRL checking. */
  1520. if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) &&
  1521. (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) !=
  1522. WOLFSSL_SUCCESS)) {
  1523. WOLFSSL_MSG("Enable CRL failed");
  1524. ret = WOLFSSL_FATAL_ERROR;
  1525. }
  1526. if (ret == WOLFSSL_SUCCESS) {
  1527. /* Load CRL into CRL object of the certificate manager. */
  1528. ret = BufferLoadCRL(cm->crl, buff, sz, type, VERIFY);
  1529. }
  1530. return ret;
  1531. }
  1532. /* Free the CRL object of the certificate manager.
  1533. *
  1534. * @param [in] cm Certificate manager.
  1535. * @return WOLFSSL_SUCCESS on success.
  1536. * @return BAD_FUNC_ARG when cm is NULL.
  1537. */
  1538. int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm)
  1539. {
  1540. int ret = WOLFSSL_SUCCESS;
  1541. WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL");
  1542. /* Validate parameter. */
  1543. if (cm == NULL) {
  1544. ret = BAD_FUNC_ARG;
  1545. }
  1546. /* Check whether CRL object exists. */
  1547. if ((ret == WOLFSSL_SUCCESS) && (cm->crl != NULL)) {
  1548. /* Dispose of CRL object - indicating dynamically allocated. */
  1549. FreeCRL(cm->crl, 1);
  1550. cm->crl = NULL;
  1551. }
  1552. return ret;
  1553. }
  1554. /* Check DER encoded certificate against CRLs if checking enabled.
  1555. *
  1556. * @param [in] cm Certificate manager.
  1557. * @param [in] der DER encode certificate.
  1558. * @param [in] sz Size in bytes of DER encode certificate.
  1559. * @return WOLFSSL_SUCCESS on success.
  1560. * @return BAD_FUNC_ARG when cm or der is NULL or sz is negative or zero.
  1561. * @return MEMORY_E when dynamic memory allocation fails.
  1562. */
  1563. int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm,
  1564. const unsigned char* der, int sz)
  1565. {
  1566. int ret = 0;
  1567. #ifdef WOLFSSL_SMALL_STACK
  1568. DecodedCert* cert = NULL;
  1569. #else
  1570. DecodedCert cert[1];
  1571. #endif
  1572. WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
  1573. /* Validate parameters. */
  1574. if ((cm == NULL) || (der == NULL) || (sz <= 0)) {
  1575. ret = BAD_FUNC_ARG;
  1576. }
  1577. /* Check if CRL checking enabled. */
  1578. if ((ret == 0) && cm->crlEnabled) {
  1579. #ifdef WOLFSSL_SMALL_STACK
  1580. /* Allocate memory for decoded certificate. */
  1581. cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
  1582. DYNAMIC_TYPE_DCERT);
  1583. if (cert == NULL)
  1584. ret = MEMORY_E;
  1585. if (ret == 0)
  1586. #endif
  1587. {
  1588. /* Initialize decoded certificate with buffer. */
  1589. InitDecodedCert(cert, der, (word32)sz, NULL);
  1590. /* Parse certificate and perform CRL checks. */
  1591. ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm);
  1592. if (ret != 0) {
  1593. WOLFSSL_MSG("ParseCert failed");
  1594. }
  1595. /* Do CRL checks with decoded certificate. */
  1596. else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
  1597. WOLFSSL_MSG("CheckCertCRL failed");
  1598. }
  1599. /* Dispose of dynamically allocated memory. */
  1600. FreeDecodedCert(cert);
  1601. #ifdef WOLFSSL_SMALL_STACK
  1602. XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
  1603. #endif
  1604. }
  1605. }
  1606. return (ret == 0) ? WOLFSSL_SUCCESS : ret;
  1607. }
  1608. /* Set the missing CRL callback.
  1609. *
  1610. * @param [in] cm Certificate manager.
  1611. * @param [in] cb Missing CRL callback.
  1612. * @return WOLFSSL_SUCCESS on success.
  1613. * @return BAD_FUNC_ARG when cm is NULL.
  1614. */
  1615. int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
  1616. {
  1617. int ret = WOLFSSL_SUCCESS;
  1618. WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
  1619. /* Validate parameters. */
  1620. if (cm == NULL) {
  1621. ret = BAD_FUNC_ARG;
  1622. }
  1623. if (ret == WOLFSSL_SUCCESS) {
  1624. /* Store callback. */
  1625. cm->cbMissingCRL = cb;
  1626. }
  1627. return ret;
  1628. }
  1629. #ifdef HAVE_CRL_IO
  1630. /* Set the CRL I/O callback.
  1631. *
  1632. * @param [in] cm Certificate manager.
  1633. * @param [in] cb CRL I/O callback.
  1634. * @return WOLFSSL_SUCCESS on success.
  1635. * @return BAD_FUNC_ARG when cm is NULL.
  1636. */
  1637. int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
  1638. {
  1639. int ret = WOLFSSL_SUCCESS;
  1640. /* Validate parameters. */
  1641. if (cm == NULL) {
  1642. ret = BAD_FUNC_ARG;
  1643. }
  1644. if ((ret == WOLFSSL_SUCCESS) && (cm->crl != NULL)) {
  1645. /* Store callback. */
  1646. cm->crl->crlIOCb = cb;
  1647. }
  1648. return ret;
  1649. }
  1650. #endif
  1651. #ifndef NO_FILESYSTEM
  1652. /* Load CRL/s from path with the option of monitoring for changes.
  1653. *
  1654. * @param [in] cm Certificate manager.
  1655. * @param [in] path Path to a directory containing CRLs.
  1656. * @param [in] type Format of encoding. Valid values:
  1657. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  1658. * @param [in] monitor Whether to monitor path for changes to files.
  1659. * @return WOLFSSL_SUCCESS on success.
  1660. * @return BAD_FUNC_ARG when cm or path is NULL.
  1661. * @return WOLFSSL_FATAL_ERROR when enabling CRLs fails.
  1662. */
  1663. int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
  1664. int type, int monitor)
  1665. {
  1666. int ret = WOLFSSL_SUCCESS;
  1667. WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
  1668. /* Validate parameters. */
  1669. if ((cm == NULL) || (path == NULL)) {
  1670. ret = BAD_FUNC_ARG;
  1671. }
  1672. /* Create a CRL object if not available. */
  1673. if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) &&
  1674. (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) !=
  1675. WOLFSSL_SUCCESS)) {
  1676. WOLFSSL_MSG("Enable CRL failed");
  1677. ret = WOLFSSL_FATAL_ERROR;
  1678. }
  1679. if (ret == WOLFSSL_SUCCESS) {
  1680. /* Load CRLs from path into CRL object of certificate manager. */
  1681. ret = LoadCRL(cm->crl, path, type, monitor);
  1682. }
  1683. return ret;
  1684. }
  1685. /* Load CRL from file.
  1686. *
  1687. * @param [in] cm Certificate manager.
  1688. * @param [in] file Path to a directory containing CRLs.
  1689. * @param [in] type Format of encoding. Valid values:
  1690. * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
  1691. * @return WOLFSSL_SUCCESS on success.
  1692. * @return BAD_FUNC_ARG when cm or file is NULL.
  1693. * @return WOLFSSL_FATAL_ERROR when enabling CRLs fails.
  1694. */
  1695. int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file,
  1696. int type)
  1697. {
  1698. int ret = WOLFSSL_SUCCESS;
  1699. WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLFile");
  1700. /* Validate parameters. */
  1701. if ((cm == NULL) || (file == NULL)) {
  1702. ret = BAD_FUNC_ARG;
  1703. }
  1704. /* Create a CRL object if not available. */
  1705. if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) &&
  1706. (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) !=
  1707. WOLFSSL_SUCCESS)) {
  1708. WOLFSSL_MSG("Enable CRL failed");
  1709. ret = WOLFSSL_FATAL_ERROR;
  1710. }
  1711. if (ret == WOLFSSL_SUCCESS) {
  1712. /* Load CRL file into CRL object of certificate manager. */
  1713. ret = ProcessFile(NULL, file, type, CRL_TYPE, NULL, 0, cm->crl, VERIFY);
  1714. }
  1715. return ret;
  1716. }
  1717. #endif /* !NO_FILESYSTEM */
  1718. #endif /* HAVE_CRL */
  1719. /*******************************************************************************
  1720. * OCSP handling
  1721. ******************************************************************************/
  1722. /* Enables OCSP when validating certificates and sets options.
  1723. *
  1724. * @param [in] cm Certificate manager.
  1725. * @param [in] options Options for using OCSP. Valid flags:
  1726. * WOLFSSL_OCSP_URL_OVERRIDE, WOLFSSL_OCSP_NO_NONCE,
  1727. * WOLFSSL_OCSP_CHECKALL.
  1728. * @return WOLFSSL_SUCCESS on success.
  1729. * @return 0 when initializing the OCSP object fails.
  1730. * @return BAD_FUNC_ARG when cm is NULL.
  1731. * @return MEMORY_E when dynamic memory allocation fails.
  1732. * @return NOT_COMPILED_IN when the OCSP feature is disabled.
  1733. */
  1734. int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
  1735. {
  1736. int ret = WOLFSSL_SUCCESS;
  1737. (void)options;
  1738. WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
  1739. /* Validate parameters. */
  1740. if (cm == NULL) {
  1741. ret = BAD_FUNC_ARG;
  1742. }
  1743. #ifndef HAVE_OCSP
  1744. if (ret == WOLFSSL_SUCCESS) {
  1745. /* OCSP feature not enabled. */
  1746. ret = NOT_COMPILED_IN;
  1747. }
  1748. #else
  1749. if (ret == WOLFSSL_SUCCESS) {
  1750. /* Check whether OCSP object is available. */
  1751. if (cm->ocsp == NULL) {
  1752. /* Allocate memory for OCSP object. */
  1753. cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
  1754. DYNAMIC_TYPE_OCSP);
  1755. if (cm->ocsp == NULL) {
  1756. ret = MEMORY_E;
  1757. }
  1758. if (ret == WOLFSSL_SUCCESS) {
  1759. /* Reset the fields of the OCSP object. */
  1760. XMEMSET(cm->ocsp, 0, sizeof(WOLFSSL_OCSP));
  1761. /* Initialize the OCSP object. */
  1762. if (InitOCSP(cm->ocsp, cm) != 0) {
  1763. WOLFSSL_MSG("Init OCSP failed");
  1764. /* Dispose of OCSP object - indicating dynamically allocated.
  1765. */
  1766. FreeOCSP(cm->ocsp, 1);
  1767. cm->ocsp = NULL;
  1768. ret = 0;
  1769. }
  1770. }
  1771. }
  1772. }
  1773. if (ret == WOLFSSL_SUCCESS) {
  1774. /* Enable OCSP checking. */
  1775. cm->ocspEnabled = 1;
  1776. /* Enable URL override if requested. */
  1777. if (options & WOLFSSL_OCSP_URL_OVERRIDE) {
  1778. cm->ocspUseOverrideURL = 1;
  1779. }
  1780. /* Set nonce option for creating OCSP requests. */
  1781. cm->ocspSendNonce = (options & WOLFSSL_OCSP_NO_NONCE) !=
  1782. WOLFSSL_OCSP_NO_NONCE;
  1783. /* Set all OCSP checks on if requested. */
  1784. if (options & WOLFSSL_OCSP_CHECKALL) {
  1785. cm->ocspCheckAll = 1;
  1786. }
  1787. #ifndef WOLFSSL_USER_IO
  1788. /* Set built-in OCSP lookup. */
  1789. cm->ocspIOCb = EmbedOcspLookup;
  1790. cm->ocspRespFreeCb = EmbedOcspRespFree;
  1791. cm->ocspIOCtx = cm->heap;
  1792. #endif /* WOLFSSL_USER_IO */
  1793. }
  1794. #endif /* HAVE_OCSP */
  1795. return ret;
  1796. }
  1797. /* Disables the OCSP checks.
  1798. *
  1799. * @param [in] cm Certificate manager.
  1800. * @return WOLFSSL_SUCCESS on success.
  1801. * @return BAD_FUNC_ARG when cm is NULL.
  1802. */
  1803. int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
  1804. {
  1805. int ret = WOLFSSL_SUCCESS;
  1806. WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
  1807. /* Validate parameter. */
  1808. if (cm == NULL) {
  1809. ret = BAD_FUNC_ARG;
  1810. }
  1811. if (ret == WOLFSSL_SUCCESS) {
  1812. /* Disable use of OCSP with certificate validation. */
  1813. cm->ocspEnabled = 0;
  1814. }
  1815. return ret;
  1816. }
  1817. /* Enables OCSP stapling with certificates in manager.
  1818. *
  1819. * @param [in] cm Certificate manager.
  1820. * @param [in] options Options for using OCSP. Valid flags:
  1821. * WOLFSSL_OCSP_URL_OVERRIDE, WOLFSSL_OCSP_NO_NONCE,
  1822. * WOLFSSL_OCSP_CHECKALL.
  1823. * @return WOLFSSL_SUCCESS on success.
  1824. * @return 0 when initializing the OCSP stapling object fails.
  1825. * @return BAD_FUNC_ARG when cm is NULL.
  1826. * @return MEMORY_E when dynamic memory allocation fails.
  1827. * @return NOT_COMPILED_IN when the OCSP stapling feature is disabled.
  1828. */
  1829. int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
  1830. {
  1831. int ret = WOLFSSL_SUCCESS;
  1832. WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
  1833. /* Validate parameters. */
  1834. if (cm == NULL) {
  1835. ret = BAD_FUNC_ARG;
  1836. }
  1837. #if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
  1838. !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
  1839. if (ret == WOLFSSL_SUCCESS) {
  1840. /* OCSP stapling feature not enabled. */
  1841. ret = NOT_COMPILED_IN;
  1842. }
  1843. #else
  1844. #ifndef NO_WOLFSSL_SERVER
  1845. if (ret == WOLFSSL_SUCCESS) {
  1846. /* Check whether OCSP object is available. */
  1847. if (cm->ocsp_stapling == NULL) {
  1848. /* Allocate memory for OCSP stapling object. */
  1849. cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
  1850. cm->heap, DYNAMIC_TYPE_OCSP);
  1851. if (cm->ocsp_stapling == NULL) {
  1852. ret = MEMORY_E;
  1853. }
  1854. if (ret == WOLFSSL_SUCCESS) {
  1855. /* Reset the fields of the OCSP object. */
  1856. XMEMSET(cm->ocsp_stapling, 0, sizeof(WOLFSSL_OCSP));
  1857. /* Initialize the OCSP stapling object. */
  1858. if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
  1859. WOLFSSL_MSG("Init OCSP failed");
  1860. /* Dispose of OCSP stapling object - indicating dynamically
  1861. * allocated. */
  1862. FreeOCSP(cm->ocsp_stapling, 1);
  1863. cm->ocsp_stapling = NULL;
  1864. ret = 0;
  1865. }
  1866. }
  1867. }
  1868. }
  1869. #ifndef WOLFSSL_USER_IO
  1870. if (ret == WOLFSSL_SUCCESS) {
  1871. /* Set built-in OCSP lookup. */
  1872. cm->ocspIOCb = EmbedOcspLookup;
  1873. cm->ocspRespFreeCb = EmbedOcspRespFree;
  1874. cm->ocspIOCtx = cm->heap;
  1875. }
  1876. #endif /* WOLFSSL_USER_IO */
  1877. #endif /* NO_WOLFSSL_SERVER */
  1878. if (ret == WOLFSSL_SUCCESS) {
  1879. /* Enable OCSP stapling. */
  1880. cm->ocspStaplingEnabled = 1;
  1881. }
  1882. #endif /* HAVE_CERTIFICATE_STATUS_REQUEST ||
  1883. * HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
  1884. return ret;
  1885. }
  1886. /* Disables OCSP Stapling.
  1887. *
  1888. * @param [in] cm Certificate manager.
  1889. * @return WOLFSSL_SUCCESS on success.
  1890. * @return BAD_FUNC_ARG when cm is NULL.
  1891. */
  1892. int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
  1893. {
  1894. int ret = WOLFSSL_SUCCESS;
  1895. WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
  1896. /* Validate parameter. */
  1897. if (cm == NULL) {
  1898. ret = BAD_FUNC_ARG;
  1899. }
  1900. if (ret == WOLFSSL_SUCCESS) {
  1901. #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
  1902. defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
  1903. /* Disable use of OCSP Stapling. */
  1904. cm->ocspStaplingEnabled = 0;
  1905. #else
  1906. /* OCSP stapling feature not enabled. */
  1907. ret = NOT_COMPILED_IN;
  1908. #endif
  1909. }
  1910. return ret;
  1911. }
  1912. /* Enable the must use OCSP Stapling option.
  1913. *
  1914. * @param [in] cm Certificate manager.
  1915. * @return WOLFSSL_SUCCESS on success.
  1916. * @return BAD_FUNC_ARG when cm is NULL.
  1917. */
  1918. int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
  1919. {
  1920. int ret = WOLFSSL_SUCCESS;
  1921. WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple");
  1922. /* Validate parameter. */
  1923. if (cm == NULL) {
  1924. ret = BAD_FUNC_ARG;
  1925. }
  1926. if (ret == WOLFSSL_SUCCESS) {
  1927. #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
  1928. defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
  1929. #ifndef NO_WOLFSSL_CLIENT
  1930. /* Enable must use OCSP Stapling option. */
  1931. cm->ocspMustStaple = 1;
  1932. #endif
  1933. #else
  1934. /* OCSP stapling feature not enabled. */
  1935. ret = NOT_COMPILED_IN;
  1936. #endif
  1937. }
  1938. return ret;
  1939. }
  1940. /* Disable the must use OCSP Stapling option.
  1941. *
  1942. * @param [in] cm Certificate manager.
  1943. * @return WOLFSSL_SUCCESS on success.
  1944. * @return BAD_FUNC_ARG when cm is NULL.
  1945. */
  1946. int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
  1947. {
  1948. int ret = WOLFSSL_SUCCESS;
  1949. WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple");
  1950. /* Validate parameter. */
  1951. if (cm == NULL) {
  1952. ret = BAD_FUNC_ARG;
  1953. }
  1954. if (ret == WOLFSSL_SUCCESS) {
  1955. #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
  1956. defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
  1957. #ifndef NO_WOLFSSL_CLIENT
  1958. /* Disable must use OCSP Stapling option. */
  1959. cm->ocspMustStaple = 0;
  1960. #endif
  1961. #else
  1962. /* OCSP stapling feature not enabled. */
  1963. ret = NOT_COMPILED_IN;
  1964. #endif
  1965. }
  1966. return ret;
  1967. }
  1968. #ifdef HAVE_OCSP
  1969. /* Check DER encoded certificate against with OCSP if checking enabled.
  1970. *
  1971. * @param [in] cm Certificate manager.
  1972. * @param [in] der DER encode certificate.
  1973. * @param [in] sz Size in bytes of DER encode certificate.
  1974. * @return WOLFSSL_SUCCESS on success.
  1975. * @return BAD_FUNC_ARG when cm or der is NULL or sz is negative or 0.
  1976. * @return MEMORY_E when dynamic memory allocation fails.
  1977. */
  1978. int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm,
  1979. const unsigned char* der, int sz)
  1980. {
  1981. int ret = 0;
  1982. #ifdef WOLFSSL_SMALL_STACK
  1983. DecodedCert* cert = NULL;
  1984. #else
  1985. DecodedCert cert[1];
  1986. #endif
  1987. WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
  1988. /* Validate parameters. */
  1989. if ((cm == NULL) || (der == NULL) || (sz <= 0)) {
  1990. ret = BAD_FUNC_ARG;
  1991. }
  1992. /* Check if OCSP checking enabled. */
  1993. if ((ret == 0) && cm->ocspEnabled) {
  1994. #ifdef WOLFSSL_SMALL_STACK
  1995. /* Allocate memory for decoded certificate. */
  1996. cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
  1997. DYNAMIC_TYPE_DCERT);
  1998. if (cert == NULL) {
  1999. ret = MEMORY_E;
  2000. }
  2001. if (ret == 0)
  2002. #endif
  2003. {
  2004. /* Initialize decoded certificate with buffer. */
  2005. InitDecodedCert(cert, der, (word32)sz, NULL);
  2006. /* Parse certificate and perform CRL checks. */
  2007. ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm);
  2008. if (ret != 0) {
  2009. WOLFSSL_MSG("ParseCert failed");
  2010. }
  2011. /* Do OCSP checks with decoded certificate. */
  2012. else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
  2013. WOLFSSL_MSG("CheckCertOCSP failed");
  2014. }
  2015. /* Dispose of dynamically allocated memory. */
  2016. FreeDecodedCert(cert);
  2017. #ifdef WOLFSSL_SMALL_STACK
  2018. XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
  2019. #endif
  2020. }
  2021. }
  2022. return (ret == 0) ? WOLFSSL_SUCCESS : ret;
  2023. }
  2024. /* Check OCSP response.
  2025. *
  2026. * @param [in] cm Certificate manager.
  2027. * @param [in] response Buffer holding OCSP response.
  2028. * @param [in] responseSz Size in bytes of OCSP response.
  2029. * @param [in] responseBuffer Buffer to copy response into.
  2030. * @param [in] status Place to store certificate status.
  2031. * @param [in] entry Place to store OCSP entry.
  2032. * @param [in] ocspRequest OCSP request to match with response.
  2033. * @return WOLFSSL_SUCCESS on success.
  2034. * @return BAD_FUNC_ARG when cm or response is NULL.
  2035. */
  2036. int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
  2037. byte *response, int responseSz, buffer *responseBuffer,
  2038. CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest)
  2039. {
  2040. int ret = 0;
  2041. WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse");
  2042. /* Validate parameters. */
  2043. if ((cm == NULL) || (response == NULL)) {
  2044. ret = BAD_FUNC_ARG;
  2045. }
  2046. if ((ret == 0) && cm->ocspEnabled) {
  2047. /* Check OCSP response with OCSP object from certificate manager. */
  2048. ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer,
  2049. status, entry, ocspRequest, NULL);
  2050. }
  2051. return (ret == 0) ? WOLFSSL_SUCCESS : ret;
  2052. }
  2053. /* Set the OCSP override URL.
  2054. *
  2055. * @param [in] cm Certificate manager.
  2056. * @param [in] url URL to get an OCSP response from.
  2057. * @return WOLFSSL_SUCCESS on success.
  2058. * @return BAD_FUNC_ARG when cm is NULL.
  2059. * @return MEMORY_E when dynamic memory allocation fails.
  2060. */
  2061. int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
  2062. const char* url)
  2063. {
  2064. int ret = WOLFSSL_SUCCESS;
  2065. WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
  2066. /* Validate parameters. */
  2067. if (cm == NULL) {
  2068. ret = BAD_FUNC_ARG;
  2069. }
  2070. if (ret == WOLFSSL_SUCCESS) {
  2071. /* Dispose of old URL. */
  2072. XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
  2073. if (url != NULL) {
  2074. /* Calculate size of URL string. Include terminator character. */
  2075. int urlSz = (int)XSTRLEN(url) + 1;
  2076. /* Allocate memory for URL to be copied into. */
  2077. cm->ocspOverrideURL = (char*)XMALLOC((size_t)urlSz, cm->heap,
  2078. DYNAMIC_TYPE_URL);
  2079. if (cm->ocspOverrideURL == NULL) {
  2080. ret = MEMORY_E;
  2081. }
  2082. if (ret == WOLFSSL_SUCCESS) {
  2083. /* Copy URL into certificate manager. */
  2084. XMEMCPY(cm->ocspOverrideURL, url, (size_t)urlSz);
  2085. }
  2086. }
  2087. else {
  2088. /* No URL to set so make it NULL. */
  2089. cm->ocspOverrideURL = NULL;
  2090. }
  2091. }
  2092. return ret;
  2093. }
  2094. /* Set the OCSP I/O callback, OCSP response free callback and related data.
  2095. *
  2096. * @param [in] cm Certificate manager.
  2097. * @param [in] ioCb OCSP callback.
  2098. * @param [in] respFreeCb Callback to free OCSP response buffer.
  2099. * @param [in] ioCbCtx Context data to pass to OCSP callbacks.
  2100. * @return WOLFSSL_SUCCESS on success.
  2101. * @return BAD_FUNC_ARG when cm is NULL.
  2102. */
  2103. int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm, CbOCSPIO ioCb,
  2104. CbOCSPRespFree respFreeCb, void* ioCbCtx)
  2105. {
  2106. int ret = WOLFSSL_SUCCESS;
  2107. WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
  2108. /* Validate parameters. */
  2109. if (cm == NULL) {
  2110. ret = BAD_FUNC_ARG;
  2111. }
  2112. if (ret == WOLFSSL_SUCCESS) {
  2113. /* Set callbacks and data into certificate manager. */
  2114. cm->ocspIOCb = ioCb;
  2115. cm->ocspRespFreeCb = respFreeCb;
  2116. cm->ocspIOCtx = ioCbCtx;
  2117. }
  2118. return ret;
  2119. }
  2120. #endif /* HAVE_OCSP */
  2121. #endif /* NO_CERTS */
  2122. #endif /* !WOLFSSL_SSL_CERTMAN_INCLUDED */