ssl_certman.c 70 KB

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