ssl_p7p12.c 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122
  1. /* ssl_p7p12.c
  2. *
  3. * Copyright (C) 2006-2024 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. #if defined(OPENSSL_EXTRA) && (defined(HAVE_FIPS) || defined(HAVE_SELFTEST))
  26. #include <wolfssl/wolfcrypt/pkcs7.h>
  27. #endif
  28. #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
  29. #include <wolfssl/openssl/pkcs7.h>
  30. #endif
  31. #if !defined(WOLFSSL_SSL_P7P12_INCLUDED)
  32. #ifndef WOLFSSL_IGNORE_FILE_WARN
  33. #warning ssl_p7p12.c does not need to be compiled separately from ssl.c
  34. #endif
  35. #else
  36. #if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS)
  37. /*******************************************************************************
  38. * START OF PKCS7 APIs
  39. ******************************************************************************/
  40. #ifdef HAVE_PKCS7
  41. #ifdef OPENSSL_ALL
  42. PKCS7* wolfSSL_PKCS7_new(void)
  43. {
  44. WOLFSSL_PKCS7* pkcs7;
  45. int ret = 0;
  46. pkcs7 = (WOLFSSL_PKCS7*)XMALLOC(sizeof(WOLFSSL_PKCS7), NULL,
  47. DYNAMIC_TYPE_PKCS7);
  48. if (pkcs7 != NULL) {
  49. XMEMSET(pkcs7, 0, sizeof(WOLFSSL_PKCS7));
  50. ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID);
  51. }
  52. if (ret != 0 && pkcs7 != NULL) {
  53. XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7);
  54. pkcs7 = NULL;
  55. }
  56. return (PKCS7*)pkcs7;
  57. }
  58. /******************************************************************************
  59. * wolfSSL_PKCS7_SIGNED_new - allocates PKCS7 and initialize it for a signed data
  60. *
  61. * RETURNS:
  62. * returns pointer to the PKCS7 structure on success, otherwise returns NULL
  63. */
  64. PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void)
  65. {
  66. byte signedData[]= { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
  67. PKCS7* pkcs7 = NULL;
  68. if ((pkcs7 = wolfSSL_PKCS7_new()) == NULL)
  69. return NULL;
  70. pkcs7->contentOID = SIGNED_DATA;
  71. if ((wc_PKCS7_SetContentType(pkcs7, signedData, sizeof(signedData))) < 0) {
  72. if (pkcs7) {
  73. wolfSSL_PKCS7_free(pkcs7);
  74. return NULL;
  75. }
  76. }
  77. return pkcs7;
  78. }
  79. void wolfSSL_PKCS7_free(PKCS7* pkcs7)
  80. {
  81. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  82. if (p7 != NULL) {
  83. if (p7->data != NULL)
  84. XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
  85. wc_PKCS7_Free(&p7->pkcs7);
  86. if (p7->certs)
  87. wolfSSL_sk_pop_free(p7->certs, NULL);
  88. XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7);
  89. }
  90. }
  91. void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7)
  92. {
  93. wolfSSL_PKCS7_free(p7);
  94. return;
  95. }
  96. /**
  97. * Convert DER/ASN.1 encoded signedData structure to internal PKCS7
  98. * structure. Note, does not support detached content.
  99. *
  100. * p7 - pointer to set to address of newly created PKCS7 structure on return
  101. * in - pointer to pointer of DER/ASN.1 data
  102. * len - length of input data, bytes
  103. *
  104. * Returns newly allocated and populated PKCS7 structure or NULL on error.
  105. */
  106. PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
  107. {
  108. return wolfSSL_d2i_PKCS7_ex(p7, in, len, NULL, 0);
  109. }
  110. /* This internal function is only decoding and setting up the PKCS7 struct. It
  111. * does not verify the PKCS7 signature.
  112. *
  113. * RETURNS:
  114. * returns pointer to a PKCS7 structure on success, otherwise returns NULL
  115. */
  116. static PKCS7* wolfSSL_d2i_PKCS7_only(PKCS7** p7, const unsigned char** in,
  117. int len, byte* content, word32 contentSz)
  118. {
  119. WOLFSSL_PKCS7* pkcs7 = NULL;
  120. WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
  121. if (in == NULL || *in == NULL || len < 0)
  122. return NULL;
  123. if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
  124. return NULL;
  125. pkcs7->len = len;
  126. pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
  127. if (pkcs7->data == NULL) {
  128. wolfSSL_PKCS7_free((PKCS7*)pkcs7);
  129. return NULL;
  130. }
  131. XMEMCPY(pkcs7->data, *in, pkcs7->len);
  132. if (content != NULL) {
  133. pkcs7->pkcs7.content = content;
  134. pkcs7->pkcs7.contentSz = contentSz;
  135. }
  136. if (p7 != NULL)
  137. *p7 = (PKCS7*)pkcs7;
  138. *in += pkcs7->len;
  139. return (PKCS7*)pkcs7;
  140. }
  141. /*****************************************************************************
  142. * wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
  143. * into a PKCS7 object. Optionally, accepts a byte buffer of content which
  144. * is stored as the PKCS7 object's content, to support detached signatures.
  145. * @param content The content which is signed, in case the signature is
  146. * detached. Ignored if NULL.
  147. * @param contentSz The size of the passed in content.
  148. *
  149. * RETURNS:
  150. * returns pointer to a PKCS7 structure on success, otherwise returns NULL
  151. */
  152. PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
  153. byte* content, word32 contentSz)
  154. {
  155. WOLFSSL_PKCS7* pkcs7 = NULL;
  156. WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
  157. if (in == NULL || *in == NULL || len < 0)
  158. return NULL;
  159. pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_d2i_PKCS7_only(p7, in, len, content,
  160. contentSz);
  161. if (pkcs7 != NULL) {
  162. if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
  163. != 0) {
  164. WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
  165. wolfSSL_PKCS7_free((PKCS7*)pkcs7);
  166. if (p7 != NULL) {
  167. *p7 = NULL;
  168. }
  169. return NULL;
  170. }
  171. }
  172. return (PKCS7*)pkcs7;
  173. }
  174. /**
  175. * This API was added as a helper function for libest. It
  176. * extracts a stack of certificates from the pkcs7 object.
  177. * @param pkcs7 PKCS7 parameter object
  178. * @return WOLFSSL_STACK_OF(WOLFSSL_X509)*
  179. */
  180. WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7)
  181. {
  182. int i;
  183. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  184. WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
  185. WOLFSSL_ENTER("wolfSSL_PKCS7_to_stack");
  186. if (!p7) {
  187. WOLFSSL_MSG("Bad parameter");
  188. return NULL;
  189. }
  190. if (p7->certs)
  191. return p7->certs;
  192. for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) {
  193. WOLFSSL_X509* x509 = wolfSSL_X509_d2i_ex(NULL, p7->pkcs7.cert[i],
  194. p7->pkcs7.certSz[i], pkcs7->heap);
  195. if (!ret)
  196. ret = wolfSSL_sk_X509_new_null();
  197. if (x509) {
  198. if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) {
  199. wolfSSL_X509_free(x509);
  200. WOLFSSL_MSG("wolfSSL_sk_X509_push error");
  201. goto error;
  202. }
  203. }
  204. else {
  205. WOLFSSL_MSG("wolfSSL_X509_d2i error");
  206. goto error;
  207. }
  208. }
  209. /* Save stack to free later */
  210. if (p7->certs)
  211. wolfSSL_sk_pop_free(p7->certs, NULL);
  212. p7->certs = ret;
  213. return ret;
  214. error:
  215. if (ret) {
  216. wolfSSL_sk_pop_free(ret, NULL);
  217. }
  218. return NULL;
  219. }
  220. /**
  221. * Return stack of signers contained in PKCS7 cert.
  222. * Notes:
  223. * - Currently only PKCS#7 messages with a single signer cert is supported.
  224. * - Returned WOLFSSL_STACK must be freed by caller.
  225. *
  226. * pkcs7 - PKCS7 struct to retrieve signer certs from.
  227. * certs - currently unused
  228. * flags - flags to control function behavior.
  229. *
  230. * Return WOLFSSL_STACK of signers on success, NULL on error.
  231. */
  232. WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs,
  233. int flags)
  234. {
  235. WOLFSSL_X509* x509 = NULL;
  236. WOLFSSL_STACK* signers = NULL;
  237. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  238. if (p7 == NULL)
  239. return NULL;
  240. /* Only PKCS#7 messages with a single cert that is the verifying certificate
  241. * is supported.
  242. */
  243. if (flags & PKCS7_NOINTERN) {
  244. WOLFSSL_MSG("PKCS7_NOINTERN flag not supported");
  245. return NULL;
  246. }
  247. signers = wolfSSL_sk_X509_new_null();
  248. if (signers == NULL)
  249. return NULL;
  250. if (wolfSSL_d2i_X509(&x509, (const byte**)&p7->pkcs7.singleCert,
  251. p7->pkcs7.singleCertSz) == NULL) {
  252. wolfSSL_sk_X509_pop_free(signers, NULL);
  253. return NULL;
  254. }
  255. if (wolfSSL_sk_X509_push(signers, x509) != WOLFSSL_SUCCESS) {
  256. wolfSSL_sk_X509_pop_free(signers, NULL);
  257. return NULL;
  258. }
  259. (void)certs;
  260. return signers;
  261. }
  262. #ifndef NO_BIO
  263. PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
  264. {
  265. WOLFSSL_PKCS7* pkcs7;
  266. int ret;
  267. WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio");
  268. if (bio == NULL)
  269. return NULL;
  270. if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
  271. return NULL;
  272. pkcs7->len = wolfSSL_BIO_get_len(bio);
  273. pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
  274. if (pkcs7->data == NULL) {
  275. wolfSSL_PKCS7_free((PKCS7*)pkcs7);
  276. return NULL;
  277. }
  278. if ((ret = wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len)) <= 0) {
  279. wolfSSL_PKCS7_free((PKCS7*)pkcs7);
  280. return NULL;
  281. }
  282. /* pkcs7->len may change if using b64 for example */
  283. pkcs7->len = ret;
  284. if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
  285. != 0) {
  286. WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
  287. wolfSSL_PKCS7_free((PKCS7*)pkcs7);
  288. return NULL;
  289. }
  290. if (p7 != NULL)
  291. *p7 = (PKCS7*)pkcs7;
  292. return (PKCS7*)pkcs7;
  293. }
  294. int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out)
  295. {
  296. byte* output = NULL;
  297. int localBuf = 0;
  298. int len;
  299. WC_RNG rng;
  300. int ret = WOLFSSL_FAILURE;
  301. WOLFSSL_ENTER("wolfSSL_i2d_PKCS7");
  302. if (!out || !p7) {
  303. WOLFSSL_MSG("Bad parameter");
  304. return WOLFSSL_FAILURE;
  305. }
  306. if (!p7->rng) {
  307. if (wc_InitRng(&rng) != 0) {
  308. WOLFSSL_MSG("wc_InitRng error");
  309. return WOLFSSL_FAILURE;
  310. }
  311. p7->rng = &rng; /* cppcheck-suppress autoVariables
  312. */
  313. }
  314. if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) {
  315. WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
  316. goto cleanup;
  317. }
  318. if (*out == NULL) {
  319. output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  320. if (!output) {
  321. WOLFSSL_MSG("malloc error");
  322. goto cleanup;
  323. }
  324. localBuf = 1;
  325. }
  326. else {
  327. output = *out;
  328. }
  329. if ((len = wc_PKCS7_EncodeSignedData(p7, output, (word32)len)) < 0) {
  330. WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
  331. goto cleanup;
  332. }
  333. ret = len;
  334. cleanup:
  335. if (p7->rng == &rng) {
  336. wc_FreeRng(&rng);
  337. p7->rng = NULL;
  338. }
  339. if (ret == WOLFSSL_FAILURE && localBuf && output)
  340. XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  341. if (ret != WOLFSSL_FAILURE)
  342. *out = output;
  343. return ret;
  344. }
  345. int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7)
  346. {
  347. byte* output = NULL;
  348. int len;
  349. int ret = WOLFSSL_FAILURE;
  350. WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio");
  351. if (!bio || !p7) {
  352. WOLFSSL_MSG("Bad parameter");
  353. return WOLFSSL_FAILURE;
  354. }
  355. if ((len = wolfSSL_i2d_PKCS7(p7, &output)) == WOLFSSL_FAILURE) {
  356. WOLFSSL_MSG("wolfSSL_i2d_PKCS7 error");
  357. goto cleanup;
  358. }
  359. if (wolfSSL_BIO_write(bio, output, len) <= 0) {
  360. WOLFSSL_MSG("wolfSSL_BIO_write error");
  361. goto cleanup;
  362. }
  363. ret = WOLFSSL_SUCCESS;
  364. cleanup:
  365. if (output)
  366. XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  367. return ret;
  368. }
  369. /**
  370. * Creates and returns a PKCS7 signedData structure.
  371. *
  372. * Inner content type is set to DATA to match OpenSSL behavior.
  373. *
  374. * signer - certificate to sign bundle with
  375. * pkey - private key matching signer
  376. * certs - optional additional set of certificates to include
  377. * in - input data to be signed
  378. * flags - optional set of flags to control sign behavior
  379. *
  380. * PKCS7_BINARY - Do not translate input data to MIME canonical
  381. * format (\r\n line endings), thus preventing corruption of
  382. * binary content.
  383. * PKCS7_TEXT - Prepend MIME headers for text/plain to content.
  384. * PKCS7_DETACHED - Set signature detached, omit content from output bundle.
  385. * PKCS7_STREAM - initialize PKCS7 struct for signing, do not read data.
  386. *
  387. * Flags not currently supported:
  388. * PKCS7_NOCERTS - Do not include the signer cert in the output bundle.
  389. * PKCS7_PARTIAL - Allow for PKCS7_sign() to be only partially set up,
  390. * then signers etc to be added separately before
  391. * calling PKCS7_final().
  392. *
  393. * Returns valid PKCS7 structure pointer, or NULL if an error occurred.
  394. */
  395. PKCS7* wolfSSL_PKCS7_sign(WOLFSSL_X509* signer, WOLFSSL_EVP_PKEY* pkey,
  396. WOLFSSL_STACK* certs, WOLFSSL_BIO* in, int flags)
  397. {
  398. int err = 0;
  399. WOLFSSL_PKCS7* p7 = NULL;
  400. WOLFSSL_STACK* cert = certs;
  401. WOLFSSL_ENTER("wolfSSL_PKCS7_sign");
  402. if (flags & PKCS7_NOCERTS) {
  403. WOLFSSL_MSG("PKCS7_NOCERTS flag not yet supported");
  404. err = 1;
  405. }
  406. if (flags & PKCS7_PARTIAL) {
  407. WOLFSSL_MSG("PKCS7_PARTIAL flag not yet supported");
  408. err = 1;
  409. }
  410. if ((err == 0) && (signer == NULL || signer->derCert == NULL ||
  411. signer->derCert->length == 0)) {
  412. WOLFSSL_MSG("Bad function arg, signer is NULL or incomplete");
  413. err = 1;
  414. }
  415. if ((err == 0) && (pkey == NULL || pkey->pkey.ptr == NULL ||
  416. pkey->pkey_sz <= 0)) {
  417. WOLFSSL_MSG("Bad function arg, pkey is NULL or incomplete");
  418. err = 1;
  419. }
  420. if ((err == 0) && (in == NULL) && !(flags & PKCS7_STREAM)) {
  421. WOLFSSL_MSG("input data required unless PKCS7_STREAM used");
  422. err = 1;
  423. }
  424. if ((err == 0) && ((p7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)) {
  425. WOLFSSL_MSG("Error allocating new WOLFSSL_PKCS7");
  426. err = 1;
  427. }
  428. /* load signer certificate */
  429. if (err == 0) {
  430. if (wc_PKCS7_InitWithCert(&p7->pkcs7, signer->derCert->buffer,
  431. signer->derCert->length) != 0) {
  432. WOLFSSL_MSG("Failed to load signer certificate");
  433. err = 1;
  434. }
  435. }
  436. /* set signer private key, data types, defaults */
  437. if (err == 0) {
  438. p7->pkcs7.privateKey = (byte*)pkey->pkey.ptr;
  439. p7->pkcs7.privateKeySz = (word32)pkey->pkey_sz;
  440. p7->pkcs7.contentOID = DATA; /* inner content default is DATA */
  441. p7->pkcs7.hashOID = SHA256h; /* default to SHA-256 hash type */
  442. p7->type = SIGNED_DATA; /* PKCS7_final switches on type */
  443. }
  444. /* add additional chain certs if provided */
  445. while (cert && (err == 0)) {
  446. if (cert->data.x509 != NULL && cert->data.x509->derCert != NULL) {
  447. if (wc_PKCS7_AddCertificate(&p7->pkcs7,
  448. cert->data.x509->derCert->buffer,
  449. cert->data.x509->derCert->length) != 0) {
  450. WOLFSSL_MSG("Error in wc_PKCS7_AddCertificate");
  451. err = 1;
  452. }
  453. }
  454. cert = cert->next;
  455. }
  456. if ((err == 0) && (flags & PKCS7_DETACHED)) {
  457. if (wc_PKCS7_SetDetached(&p7->pkcs7, 1) != 0) {
  458. WOLFSSL_MSG("Failed to set signature detached");
  459. err = 1;
  460. }
  461. }
  462. if ((err == 0) && (flags & PKCS7_STREAM)) {
  463. /* if streaming, return before finalizing */
  464. return (PKCS7*)p7;
  465. }
  466. if ((err == 0) && (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1)) {
  467. WOLFSSL_MSG("Error calling wolfSSL_PKCS7_final");
  468. err = 1;
  469. }
  470. if ((err != 0) && (p7 != NULL)) {
  471. wolfSSL_PKCS7_free((PKCS7*)p7);
  472. p7 = NULL;
  473. }
  474. return (PKCS7*)p7;
  475. }
  476. #ifdef HAVE_SMIME
  477. #ifndef MAX_MIME_LINE_LEN
  478. #define MAX_MIME_LINE_LEN 1024
  479. #endif
  480. /**
  481. * Copy input BIO to output BIO, but convert all line endings to CRLF (\r\n),
  482. * used by PKCS7_final().
  483. *
  484. * in - input WOLFSSL_BIO to be converted
  485. * out - output WOLFSSL_BIO to hold copy of in, with line endings adjusted
  486. *
  487. * Return 0 on success, negative on error
  488. */
  489. static int wolfSSL_BIO_to_MIME_crlf(WOLFSSL_BIO* in, WOLFSSL_BIO* out)
  490. {
  491. int ret = 0;
  492. int lineLen = 0;
  493. word32 canonLineLen = 0;
  494. char* canonLine = NULL;
  495. #ifdef WOLFSSL_SMALL_STACK
  496. char* line = NULL;
  497. #else
  498. char line[MAX_MIME_LINE_LEN];
  499. #endif
  500. if (in == NULL || out == NULL) {
  501. return BAD_FUNC_ARG;
  502. }
  503. #ifdef WOLFSSL_SMALL_STACK
  504. line = (char*)XMALLOC(MAX_MIME_LINE_LEN, in->heap,
  505. DYNAMIC_TYPE_TMP_BUFFER);
  506. if (line == NULL) {
  507. return MEMORY_E;
  508. }
  509. #endif
  510. XMEMSET(line, 0, MAX_MIME_LINE_LEN);
  511. while ((lineLen = wolfSSL_BIO_gets(in, line, MAX_MIME_LINE_LEN)) > 0) {
  512. if (line[lineLen - 1] == '\r' || line[lineLen - 1] == '\n') {
  513. canonLineLen = (word32)lineLen;
  514. if ((canonLine = wc_MIME_single_canonicalize(
  515. line, &canonLineLen)) == NULL) {
  516. ret = -1;
  517. break;
  518. }
  519. /* remove trailing null */
  520. if (canonLineLen >= 1 && canonLine[canonLineLen-1] == '\0') {
  521. canonLineLen--;
  522. }
  523. if (wolfSSL_BIO_write(out, canonLine, (int)canonLineLen) < 0) {
  524. ret = -1;
  525. break;
  526. }
  527. XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
  528. canonLine = NULL;
  529. }
  530. else {
  531. /* no line ending in current line, write direct to out */
  532. if (wolfSSL_BIO_write(out, line, lineLen) < 0) {
  533. ret = -1;
  534. break;
  535. }
  536. }
  537. }
  538. if (canonLine != NULL) {
  539. XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
  540. }
  541. #ifdef WOLFSSL_SMALL_STACK
  542. XFREE(line, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
  543. #endif
  544. return ret;
  545. }
  546. #endif /* HAVE_SMIME */
  547. /* Used by both PKCS7_final() and PKCS7_verify() */
  548. static const char contTypeText[] = "Content-Type: text/plain\r\n\r\n";
  549. /**
  550. * Finalize PKCS7 structure, currently supports signedData only.
  551. *
  552. * Does not generate final bundle (ie: signedData), but finalizes
  553. * the PKCS7 structure in preparation for a output function to be called next.
  554. *
  555. * pkcs7 - initialized PKCS7 structure, populated with signer, etc
  556. * in - input data
  557. * flags - flags to control PKCS7 behavior. Other flags except those noted
  558. * below are ignored:
  559. *
  560. * PKCS7_BINARY - Do not translate input data to MIME canonical
  561. * format (\r\n line endings), thus preventing corruption of
  562. * binary content.
  563. * PKCS7_TEXT - Prepend MIME headers for text/plain to content.
  564. *
  565. * Returns 1 on success, 0 on error
  566. */
  567. int wolfSSL_PKCS7_final(PKCS7* pkcs7, WOLFSSL_BIO* in, int flags)
  568. {
  569. int ret = 1;
  570. int memSz = 0;
  571. unsigned char* mem = NULL;
  572. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  573. WOLFSSL_BIO* data = NULL;
  574. WOLFSSL_ENTER("wolfSSL_PKCS7_final");
  575. if (p7 == NULL || in == NULL) {
  576. WOLFSSL_MSG("Bad input args to PKCS7_final");
  577. ret = 0;
  578. }
  579. if (ret == 1) {
  580. if ((data = wolfSSL_BIO_new(wolfSSL_BIO_s_mem())) == NULL) {
  581. WOLFSSL_MSG("Error in wolfSSL_BIO_new");
  582. ret = 0;
  583. }
  584. }
  585. /* prepend Content-Type header if PKCS7_TEXT */
  586. if ((ret == 1) && (flags & PKCS7_TEXT)) {
  587. if (wolfSSL_BIO_write(data, contTypeText,
  588. (int)XSTR_SIZEOF(contTypeText)) < 0) {
  589. WOLFSSL_MSG("Error prepending Content-Type header");
  590. ret = 0;
  591. }
  592. }
  593. /* convert line endings to CRLF if !PKCS7_BINARY */
  594. if (ret == 1) {
  595. if (flags & PKCS7_BINARY) {
  596. /* no CRLF conversion, direct copy content */
  597. if ((memSz = wolfSSL_BIO_get_len(in)) <= 0) {
  598. ret = 0;
  599. }
  600. if (ret == 1) {
  601. mem = (unsigned char*)XMALLOC(memSz, in->heap,
  602. DYNAMIC_TYPE_TMP_BUFFER);
  603. if (mem == NULL) {
  604. WOLFSSL_MSG("Failed to allocate memory for input data");
  605. ret = 0;
  606. }
  607. }
  608. if (ret == 1) {
  609. if (wolfSSL_BIO_read(in, mem, memSz) != memSz) {
  610. WOLFSSL_MSG("Error reading from input BIO");
  611. ret = 0;
  612. }
  613. else if (wolfSSL_BIO_write(data, mem, memSz) < 0) {
  614. ret = 0;
  615. }
  616. }
  617. if (mem != NULL) {
  618. XFREE(mem, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
  619. }
  620. }
  621. else {
  622. #ifdef HAVE_SMIME
  623. /* convert content line endings to CRLF */
  624. if (wolfSSL_BIO_to_MIME_crlf(in, data) != 0) {
  625. WOLFSSL_MSG("Error converting line endings to CRLF");
  626. ret = 0;
  627. }
  628. else {
  629. p7->pkcs7.contentCRLF = 1;
  630. }
  631. #else
  632. WOLFSSL_MSG("Without PKCS7_BINARY requires wolfSSL to be built "
  633. "with HAVE_SMIME");
  634. ret = 0;
  635. #endif
  636. }
  637. }
  638. if ((ret == 1) && ((memSz = wolfSSL_BIO_get_mem_data(data, &mem)) < 0)) {
  639. WOLFSSL_MSG("Error in wolfSSL_BIO_get_mem_data");
  640. ret = 0;
  641. }
  642. if (ret == 1) {
  643. if (p7->data != NULL) {
  644. XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
  645. }
  646. p7->data = (byte*)XMALLOC(memSz, NULL, DYNAMIC_TYPE_PKCS7);
  647. if (p7->data == NULL) {
  648. ret = 0;
  649. }
  650. else {
  651. XMEMCPY(p7->data, mem, memSz);
  652. p7->len = memSz;
  653. }
  654. }
  655. if (ret == 1) {
  656. p7->pkcs7.content = p7->data;
  657. p7->pkcs7.contentSz = (word32)p7->len;
  658. }
  659. if (data != NULL) {
  660. wolfSSL_BIO_free(data);
  661. }
  662. return ret;
  663. }
  664. int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs,
  665. WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags)
  666. {
  667. int i, ret = 0;
  668. unsigned char* mem = NULL;
  669. int memSz = 0;
  670. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  671. int contTypeLen;
  672. WOLFSSL_X509* signer = NULL;
  673. WOLFSSL_STACK* signers = NULL;
  674. WOLFSSL_ENTER("wolfSSL_PKCS7_verify");
  675. if (pkcs7 == NULL)
  676. return WOLFSSL_FAILURE;
  677. if (in != NULL) {
  678. if ((memSz = wolfSSL_BIO_get_mem_data(in, &mem)) < 0)
  679. return WOLFSSL_FAILURE;
  680. p7->pkcs7.content = mem;
  681. p7->pkcs7.contentSz = (word32)memSz;
  682. }
  683. /* certs is the list of certificates to find the cert with issuer/serial. */
  684. (void)certs;
  685. /* store is the certificate store to use to verify signer certificate
  686. * associated with the signers.
  687. */
  688. (void)store;
  689. ret = wc_PKCS7_VerifySignedData(&p7->pkcs7, p7->data, p7->len);
  690. if (ret != 0)
  691. return WOLFSSL_FAILURE;
  692. if ((flags & PKCS7_NOVERIFY) != PKCS7_NOVERIFY) {
  693. /* Verify signer certificates */
  694. if (store == NULL || store->cm == NULL) {
  695. WOLFSSL_MSG("No store or store certs, but PKCS7_NOVERIFY not set");
  696. return WOLFSSL_FAILURE;
  697. }
  698. signers = wolfSSL_PKCS7_get0_signers(pkcs7, certs, flags);
  699. if (signers == NULL) {
  700. WOLFSSL_MSG("No signers found to verify");
  701. return WOLFSSL_FAILURE;
  702. }
  703. for (i = 0; i < wolfSSL_sk_X509_num(signers); i++) {
  704. signer = wolfSSL_sk_X509_value(signers, i);
  705. if (wolfSSL_CertManagerVerifyBuffer(store->cm,
  706. signer->derCert->buffer,
  707. signer->derCert->length,
  708. WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  709. WOLFSSL_MSG("Failed to verify signer certificate");
  710. wolfSSL_sk_X509_pop_free(signers, NULL);
  711. return WOLFSSL_FAILURE;
  712. }
  713. }
  714. wolfSSL_sk_X509_pop_free(signers, NULL);
  715. }
  716. if (flags & PKCS7_TEXT) {
  717. /* strip MIME header for text/plain, otherwise error */
  718. contTypeLen = XSTR_SIZEOF(contTypeText);
  719. if ((p7->pkcs7.contentSz < (word32)contTypeLen) ||
  720. (XMEMCMP(p7->pkcs7.content, contTypeText, contTypeLen) != 0)) {
  721. WOLFSSL_MSG("Error PKCS7 Content-Type not found with PKCS7_TEXT");
  722. return WOLFSSL_FAILURE;
  723. }
  724. p7->pkcs7.content += contTypeLen;
  725. p7->pkcs7.contentSz -= contTypeLen;
  726. }
  727. if (out != NULL) {
  728. wolfSSL_BIO_write(out, p7->pkcs7.content, p7->pkcs7.contentSz);
  729. }
  730. WOLFSSL_LEAVE("wolfSSL_PKCS7_verify", WOLFSSL_SUCCESS);
  731. return WOLFSSL_SUCCESS;
  732. }
  733. /**
  734. * This API was added as a helper function for libest. It
  735. * encodes a stack of certificates to pkcs7 format.
  736. * @param pkcs7 PKCS7 parameter object
  737. * @param certs WOLFSSL_STACK_OF(WOLFSSL_X509)*
  738. * @param out Output bio
  739. * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
  740. */
  741. int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs,
  742. WOLFSSL_BIO* out)
  743. {
  744. int ret;
  745. WOLFSSL_PKCS7* p7;
  746. WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs");
  747. if (!pkcs7 || !certs || !out) {
  748. WOLFSSL_MSG("Bad parameter");
  749. return WOLFSSL_FAILURE;
  750. }
  751. p7 = (WOLFSSL_PKCS7*)pkcs7;
  752. /* take ownership of certs */
  753. p7->certs = certs;
  754. /* TODO: takes ownership even on failure below but not on above failure. */
  755. if (pkcs7->certList) {
  756. WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same "
  757. "struct");
  758. return WOLFSSL_FAILURE;
  759. }
  760. if (certs) {
  761. /* Save some of the values */
  762. int hashOID = pkcs7->hashOID;
  763. byte version = pkcs7->version;
  764. if (!certs->data.x509 || !certs->data.x509->derCert) {
  765. WOLFSSL_MSG("Missing cert");
  766. return WOLFSSL_FAILURE;
  767. }
  768. if (wc_PKCS7_InitWithCert(pkcs7, certs->data.x509->derCert->buffer,
  769. certs->data.x509->derCert->length) != 0) {
  770. WOLFSSL_MSG("wc_PKCS7_InitWithCert error");
  771. return WOLFSSL_FAILURE;
  772. }
  773. certs = certs->next;
  774. pkcs7->hashOID = hashOID;
  775. pkcs7->version = version;
  776. }
  777. /* Add the certs to the PKCS7 struct */
  778. while (certs) {
  779. if (!certs->data.x509 || !certs->data.x509->derCert) {
  780. WOLFSSL_MSG("Missing cert");
  781. return WOLFSSL_FAILURE;
  782. }
  783. if (wc_PKCS7_AddCertificate(pkcs7, certs->data.x509->derCert->buffer,
  784. certs->data.x509->derCert->length) != 0) {
  785. WOLFSSL_MSG("wc_PKCS7_AddCertificate error");
  786. return WOLFSSL_FAILURE;
  787. }
  788. certs = certs->next;
  789. }
  790. if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) {
  791. WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error");
  792. return WOLFSSL_FAILURE;
  793. }
  794. ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7);
  795. return ret;
  796. }
  797. /******************************************************************************
  798. * wolfSSL_PEM_write_bio_PKCS7 - writes the PKCS7 data to BIO
  799. *
  800. * RETURNS:
  801. * returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
  802. */
  803. int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
  804. {
  805. #ifdef WOLFSSL_SMALL_STACK
  806. byte* outputHead;
  807. byte* outputFoot;
  808. #else
  809. byte outputHead[2048];
  810. byte outputFoot[2048];
  811. #endif
  812. word32 outputHeadSz = 2048;
  813. word32 outputFootSz = 2048;
  814. word32 outputSz = 0;
  815. byte* output = NULL;
  816. byte* pem = NULL;
  817. int pemSz = -1;
  818. enum wc_HashType hashType;
  819. byte hashBuf[WC_MAX_DIGEST_SIZE];
  820. word32 hashSz = -1;
  821. WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PKCS7");
  822. if (bio == NULL || p7 == NULL)
  823. return WOLFSSL_FAILURE;
  824. #ifdef WOLFSSL_SMALL_STACK
  825. outputHead = (byte*)XMALLOC(outputHeadSz, bio->heap,
  826. DYNAMIC_TYPE_TMP_BUFFER);
  827. if (outputHead == NULL)
  828. return MEMORY_E;
  829. outputFoot = (byte*)XMALLOC(outputFootSz, bio->heap,
  830. DYNAMIC_TYPE_TMP_BUFFER);
  831. if (outputFoot == NULL)
  832. goto error;
  833. #endif
  834. XMEMSET(hashBuf, 0, WC_MAX_DIGEST_SIZE);
  835. XMEMSET(outputHead, 0, outputHeadSz);
  836. XMEMSET(outputFoot, 0, outputFootSz);
  837. hashType = wc_OidGetHash(p7->hashOID);
  838. hashSz = (word32)wc_HashGetDigestSize(hashType);
  839. if (hashSz > WC_MAX_DIGEST_SIZE)
  840. goto error;
  841. /* only SIGNED_DATA is supported */
  842. switch (p7->contentOID) {
  843. case SIGNED_DATA:
  844. break;
  845. default:
  846. WOLFSSL_MSG("Unknown PKCS#7 Type");
  847. goto error;
  848. };
  849. if ((wc_PKCS7_EncodeSignedData_ex(p7, hashBuf, hashSz,
  850. outputHead, &outputHeadSz, outputFoot, &outputFootSz)) != 0)
  851. goto error;
  852. outputSz = outputHeadSz + p7->contentSz + outputFootSz;
  853. output = (byte*)XMALLOC(outputSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  854. if (!output)
  855. goto error;
  856. XMEMSET(output, 0, outputSz);
  857. outputSz = 0;
  858. XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
  859. outputSz += outputHeadSz;
  860. XMEMCPY(&output[outputSz], p7->content, p7->contentSz);
  861. outputSz += p7->contentSz;
  862. XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
  863. outputSz += outputFootSz;
  864. /* get PEM size */
  865. pemSz = wc_DerToPemEx(output, outputSz, NULL, 0, NULL, CERT_TYPE);
  866. if (pemSz < 0)
  867. goto error;
  868. pemSz++; /* for '\0'*/
  869. /* create PEM buffer and convert from DER to PEM*/
  870. if ((pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER))
  871. == NULL)
  872. goto error;
  873. XMEMSET(pem, 0, pemSz);
  874. if (wc_DerToPemEx(output, outputSz, pem, (word32)pemSz, NULL, CERT_TYPE) < 0) {
  875. goto error;
  876. }
  877. if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
  878. XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  879. XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  880. #ifdef WOLFSSL_SMALL_STACK
  881. XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  882. XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  883. #endif
  884. return WOLFSSL_SUCCESS;
  885. }
  886. error:
  887. #ifdef WOLFSSL_SMALL_STACK
  888. if (outputHead) {
  889. XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  890. }
  891. if (outputFoot) {
  892. XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  893. }
  894. #endif
  895. if (output) {
  896. XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  897. }
  898. if (pem) {
  899. XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  900. }
  901. return WOLFSSL_FAILURE;
  902. }
  903. #ifdef HAVE_SMIME
  904. /*****************************************************************************
  905. * wolfSSL_SMIME_read_PKCS7 - Reads the given S/MIME message and parses it into
  906. * a PKCS7 object. In case of a multipart message, stores the signed data in
  907. * bcont.
  908. *
  909. * RETURNS:
  910. * returns pointer to a PKCS7 structure on success, otherwise returns NULL
  911. */
  912. PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
  913. WOLFSSL_BIO** bcont)
  914. {
  915. MimeHdr* allHdrs = NULL;
  916. MimeHdr* curHdr = NULL;
  917. MimeParam* curParam = NULL;
  918. int inLen = 0;
  919. byte* bcontMem = NULL;
  920. int bcontMemSz = 0;
  921. int sectionLen = 0;
  922. int ret = -1;
  923. char* section = NULL;
  924. char* canonLine = NULL;
  925. char* canonSection = NULL;
  926. PKCS7* pkcs7 = NULL;
  927. word32 outLen = 0;
  928. word32 canonLineLen = 0;
  929. byte* out = NULL;
  930. byte* outHead = NULL;
  931. int canonPos = 0;
  932. int lineLen = 0;
  933. int remainLen = 0;
  934. byte isEnd = 0;
  935. size_t canonSize = 0;
  936. size_t boundLen = 0;
  937. char* boundary = NULL;
  938. static const char kContType[] = "Content-Type";
  939. static const char kCTE[] = "Content-Transfer-Encoding";
  940. static const char kMultSigned[] = "multipart/signed";
  941. static const char kAppPkcsSign[] = "application/pkcs7-signature";
  942. static const char kAppXPkcsSign[] = "application/x-pkcs7-signature";
  943. static const char kAppPkcs7Mime[] = "application/pkcs7-mime";
  944. static const char kAppXPkcs7Mime[] = "application/x-pkcs7-mime";
  945. WOLFSSL_ENTER("wolfSSL_SMIME_read_PKCS7");
  946. if (in == NULL || bcont == NULL) {
  947. goto error;
  948. }
  949. inLen = wolfSSL_BIO_get_len(in);
  950. if (inLen <= 0) {
  951. goto error;
  952. }
  953. remainLen = wolfSSL_BIO_get_len(in);
  954. if (remainLen <= 0) {
  955. goto error;
  956. }
  957. section = (char*)XMALLOC(remainLen+1, NULL, DYNAMIC_TYPE_PKCS7);
  958. if (section == NULL) {
  959. goto error;
  960. }
  961. lineLen = wolfSSL_BIO_gets(in, section, remainLen);
  962. if (lineLen <= 0) {
  963. goto error;
  964. }
  965. while (isEnd == 0 && remainLen > 0) {
  966. sectionLen += lineLen;
  967. remainLen -= lineLen;
  968. lineLen = wolfSSL_BIO_gets(in, &section[sectionLen], remainLen);
  969. if (lineLen <= 0) {
  970. goto error;
  971. }
  972. /* Line with just newline signals end of headers. */
  973. if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
  974. "\r\n", 2)) ||
  975. (lineLen==1 && (section[sectionLen] == '\r' ||
  976. section[sectionLen] == '\n'))) {
  977. isEnd = 1;
  978. }
  979. }
  980. section[sectionLen] = '\0';
  981. ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
  982. if (ret < 0) {
  983. WOLFSSL_MSG("Parsing MIME headers failed.");
  984. goto error;
  985. }
  986. isEnd = 0;
  987. section[0] = '\0';
  988. sectionLen = 0;
  989. curHdr = wc_MIME_find_header_name(kContType, allHdrs);
  990. if (curHdr && !XSTRNCMP(curHdr->body, kMultSigned,
  991. XSTR_SIZEOF(kMultSigned))) {
  992. curParam = wc_MIME_find_param_attr("protocol", curHdr->params);
  993. if (curParam && (!XSTRNCMP(curParam->value, kAppPkcsSign,
  994. XSTR_SIZEOF(kAppPkcsSign)) ||
  995. !XSTRNCMP(curParam->value, kAppXPkcsSign,
  996. XSTR_SIZEOF(kAppXPkcsSign)))) {
  997. curParam = wc_MIME_find_param_attr("boundary", curHdr->params);
  998. if (curParam == NULL) {
  999. goto error;
  1000. }
  1001. boundLen = XSTRLEN(curParam->value) + 2;
  1002. boundary = (char*)XMALLOC(boundLen+1, NULL, DYNAMIC_TYPE_PKCS7);
  1003. if (boundary == NULL) {
  1004. goto error;
  1005. }
  1006. XMEMSET(boundary, 0, (word32)(boundLen+1));
  1007. boundary[0] = boundary[1] = '-';
  1008. XSTRNCPY(&boundary[2], curParam->value, boundLen-2);
  1009. /* Parse up to first boundary, ignore everything here. */
  1010. lineLen = wolfSSL_BIO_gets(in, section, remainLen);
  1011. if (lineLen <= 0) {
  1012. goto error;
  1013. }
  1014. while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
  1015. remainLen > 0) {
  1016. sectionLen += lineLen;
  1017. remainLen -= lineLen;
  1018. lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
  1019. remainLen);
  1020. if (lineLen <= 0) {
  1021. goto error;
  1022. }
  1023. }
  1024. section[0] = '\0';
  1025. sectionLen = 0;
  1026. canonSize = (size_t)remainLen + 1;
  1027. canonSection = (char*)XMALLOC(canonSize, NULL,
  1028. DYNAMIC_TYPE_PKCS7);
  1029. if (canonSection == NULL) {
  1030. goto error;
  1031. }
  1032. lineLen = wolfSSL_BIO_gets(in, section, remainLen);
  1033. if (lineLen < 0) {
  1034. goto error;
  1035. }
  1036. while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
  1037. remainLen > 0) {
  1038. canonLineLen = (word32)lineLen;
  1039. canonLine = wc_MIME_single_canonicalize(&section[sectionLen],
  1040. &canonLineLen);
  1041. if (canonLine == NULL) {
  1042. goto error;
  1043. }
  1044. /* If line endings were added, the initial length may be
  1045. * exceeded. */
  1046. if ((canonPos + canonLineLen) >= canonSize) {
  1047. canonSize = canonPos + canonLineLen;
  1048. canonSection = (char*)XREALLOC(canonSection, canonSize,
  1049. NULL, DYNAMIC_TYPE_PKCS7);
  1050. if (canonSection == NULL) {
  1051. goto error;
  1052. }
  1053. }
  1054. XMEMCPY(&canonSection[canonPos], canonLine,
  1055. (int)canonLineLen - 1);
  1056. canonPos += canonLineLen - 1;
  1057. XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
  1058. canonLine = NULL;
  1059. sectionLen += lineLen;
  1060. remainLen -= lineLen;
  1061. lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
  1062. remainLen);
  1063. if (lineLen <= 0) {
  1064. goto error;
  1065. }
  1066. }
  1067. if (canonPos > 0) {
  1068. canonPos--;
  1069. }
  1070. /* Strip the final trailing newline. Support \r, \n or \r\n. */
  1071. if (canonSection[canonPos] == '\n') {
  1072. if (canonPos > 0) {
  1073. canonPos--;
  1074. }
  1075. }
  1076. if (canonSection[canonPos] == '\r') {
  1077. if (canonPos > 0) {
  1078. canonPos--;
  1079. }
  1080. }
  1081. canonSection[canonPos+1] = '\0';
  1082. *bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
  1083. ret = wolfSSL_BIO_write(*bcont, canonSection,
  1084. canonPos + 1);
  1085. if (ret != (canonPos+1)) {
  1086. goto error;
  1087. }
  1088. if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem))
  1089. < 0) {
  1090. goto error;
  1091. }
  1092. XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
  1093. canonSection = NULL;
  1094. wc_MIME_free_hdrs(allHdrs);
  1095. allHdrs = NULL;
  1096. section[0] = '\0';
  1097. sectionLen = 0;
  1098. lineLen = wolfSSL_BIO_gets(in, section, remainLen);
  1099. if (lineLen <= 0) {
  1100. goto error;
  1101. }
  1102. while (isEnd == 0 && remainLen > 0) {
  1103. sectionLen += lineLen;
  1104. remainLen -= lineLen;
  1105. lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
  1106. remainLen);
  1107. if (lineLen <= 0) {
  1108. goto error;
  1109. }
  1110. /* Line with just newline signals end of headers. */
  1111. if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
  1112. "\r\n", 2)) ||
  1113. (lineLen==1 && (section[sectionLen] == '\r' ||
  1114. section[sectionLen] == '\n'))) {
  1115. isEnd = 1;
  1116. }
  1117. }
  1118. section[sectionLen] = '\0';
  1119. ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
  1120. if (ret < 0) {
  1121. WOLFSSL_MSG("Parsing MIME headers failed.");
  1122. goto error;
  1123. }
  1124. curHdr = wc_MIME_find_header_name(kContType, allHdrs);
  1125. if (curHdr == NULL || (XSTRNCMP(curHdr->body, kAppPkcsSign,
  1126. XSTR_SIZEOF(kAppPkcsSign)) &&
  1127. XSTRNCMP(curHdr->body, kAppXPkcsSign,
  1128. XSTR_SIZEOF(kAppXPkcsSign)))) {
  1129. WOLFSSL_MSG("S/MIME headers not found inside "
  1130. "multipart message.\n");
  1131. goto error;
  1132. }
  1133. section[0] = '\0';
  1134. sectionLen = 0;
  1135. lineLen = wolfSSL_BIO_gets(in, section, remainLen);
  1136. while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
  1137. remainLen > 0) {
  1138. sectionLen += lineLen;
  1139. remainLen -= lineLen;
  1140. lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
  1141. remainLen);
  1142. if (lineLen <= 0) {
  1143. goto error;
  1144. }
  1145. }
  1146. XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
  1147. boundary = NULL;
  1148. }
  1149. }
  1150. else if (curHdr && (!XSTRNCMP(curHdr->body, kAppPkcs7Mime,
  1151. XSTR_SIZEOF(kAppPkcs7Mime)) ||
  1152. !XSTRNCMP(curHdr->body, kAppXPkcs7Mime,
  1153. XSTR_SIZEOF(kAppXPkcs7Mime)))) {
  1154. sectionLen = wolfSSL_BIO_get_len(in);
  1155. if (sectionLen <= 0) {
  1156. goto error;
  1157. }
  1158. ret = wolfSSL_BIO_read(in, section, sectionLen);
  1159. if (ret < 0 || ret != sectionLen) {
  1160. WOLFSSL_MSG("Error reading input BIO.");
  1161. goto error;
  1162. }
  1163. }
  1164. else {
  1165. WOLFSSL_MSG("S/MIME headers not found.");
  1166. goto error;
  1167. }
  1168. curHdr = wc_MIME_find_header_name(kCTE, allHdrs);
  1169. if (curHdr == NULL) {
  1170. WOLFSSL_MSG("Content-Transfer-Encoding header not found, "
  1171. "assuming base64 encoding.");
  1172. }
  1173. else if (XSTRNCMP(curHdr->body, "base64", XSTRLEN("base64"))) {
  1174. WOLFSSL_MSG("S/MIME encodings other than base64 are not "
  1175. "currently supported.\n");
  1176. goto error;
  1177. }
  1178. if (section == NULL || sectionLen <= 0) {
  1179. goto error;
  1180. }
  1181. outLen = (word32)((sectionLen*3+3)/4)+1;
  1182. out = (byte*)XMALLOC(outLen*sizeof(byte), NULL, DYNAMIC_TYPE_PKCS7);
  1183. outHead = out;
  1184. if (outHead == NULL) {
  1185. goto error;
  1186. }
  1187. /* Strip trailing newlines. */
  1188. while ((sectionLen > 0) &&
  1189. (section[sectionLen-1] == '\r' || section[sectionLen-1] == '\n')) {
  1190. sectionLen--;
  1191. }
  1192. section[sectionLen] = '\0';
  1193. ret = Base64_Decode((const byte*)section, (word32)sectionLen, out, &outLen);
  1194. if (ret < 0) {
  1195. WOLFSSL_MSG("Error base64 decoding S/MIME message.");
  1196. goto error;
  1197. }
  1198. pkcs7 = wolfSSL_d2i_PKCS7_only(NULL, (const unsigned char**)&out, (int)outLen,
  1199. bcontMem, (word32)bcontMemSz);
  1200. wc_MIME_free_hdrs(allHdrs);
  1201. XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
  1202. XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
  1203. return pkcs7;
  1204. error:
  1205. wc_MIME_free_hdrs(allHdrs);
  1206. XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
  1207. XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
  1208. XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
  1209. if (canonSection != NULL)
  1210. XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
  1211. if (canonLine != NULL)
  1212. XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
  1213. if (bcont) {
  1214. wolfSSL_BIO_free(*bcont);
  1215. *bcont = NULL; /* reset 'bcount' pointer to NULL on failure */
  1216. }
  1217. return NULL;
  1218. }
  1219. /* Convert hash algo OID (from Hash_Sum in asn.h) to SMIME string equivalent.
  1220. * Returns hash algorithm string or "unknown" if not found */
  1221. static const char* wolfSSL_SMIME_HashOIDToString(int hashOID)
  1222. {
  1223. switch (hashOID) {
  1224. case MD5h:
  1225. return "md5";
  1226. case SHAh:
  1227. return "sha1";
  1228. case SHA224h:
  1229. return "sha-224";
  1230. case SHA256h:
  1231. return "sha-256";
  1232. case SHA384h:
  1233. return "sha-384";
  1234. case SHA512h:
  1235. return "sha-512";
  1236. case SHA3_224h:
  1237. return "sha3-224";
  1238. case SHA3_384h:
  1239. return "sha3-384";
  1240. case SHA3_512h:
  1241. return "sha3-512";
  1242. default:
  1243. break;
  1244. }
  1245. return "unknown";
  1246. }
  1247. /* Convert PKCS#7 type (from PKCS7_TYPES in pkcs7.h) to SMIME string.
  1248. * RFC2633 only defines signed-data, enveloped-data, certs-only.
  1249. * Returns string on success, NULL on unknown type. */
  1250. static const char* wolfSSL_SMIME_PKCS7TypeToString(int type)
  1251. {
  1252. switch (type) {
  1253. case SIGNED_DATA:
  1254. return "signed-data";
  1255. case ENVELOPED_DATA:
  1256. return "enveloped-data";
  1257. default:
  1258. break;
  1259. }
  1260. return NULL;
  1261. }
  1262. /**
  1263. * Convert PKCS7 structure to SMIME format, adding necessary headers.
  1264. *
  1265. * Handles generation of PKCS7 bundle (ie: signedData). PKCS7 structure
  1266. * should be set up beforehand with PKCS7_sign/final/etc. Output is always
  1267. * Base64 encoded.
  1268. *
  1269. * out - output BIO for SMIME formatted data to be placed
  1270. * pkcs7 - input PKCS7 structure, initialized and set up
  1271. * in - input content to be encoded into PKCS7
  1272. * flags - flags to control behavior of PKCS7 generation
  1273. *
  1274. * Returns 1 on success, 0 or negative on failure
  1275. */
  1276. int wolfSSL_SMIME_write_PKCS7(WOLFSSL_BIO* out, PKCS7* pkcs7, WOLFSSL_BIO* in,
  1277. int flags)
  1278. {
  1279. int i;
  1280. int ret = 1;
  1281. WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
  1282. byte* p7out = NULL;
  1283. int len = 0;
  1284. char boundary[33]; /* 32 chars + \0 */
  1285. byte* sigBase64 = NULL;
  1286. word32 sigBase64Len = 0;
  1287. const char* p7TypeString = NULL;
  1288. static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  1289. if (out == NULL || p7 == NULL) {
  1290. WOLFSSL_MSG("Bad function arguments");
  1291. return 0;
  1292. }
  1293. if (in != NULL && (p7->pkcs7.content == NULL || p7->pkcs7.contentSz == 0 ||
  1294. p7->pkcs7.contentCRLF == 0)) {
  1295. /* store and adjust content line endings for CRLF if needed */
  1296. if (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1) {
  1297. ret = 0;
  1298. }
  1299. }
  1300. if (ret > 0) {
  1301. /* Generate signedData bundle, DER in output (dynamic) */
  1302. if ((len = wolfSSL_i2d_PKCS7((PKCS7*)p7, &p7out)) == WOLFSSL_FAILURE) {
  1303. WOLFSSL_MSG("Error in wolfSSL_i2d_PKCS7");
  1304. ret = 0;
  1305. }
  1306. }
  1307. /* Base64 encode signedData bundle */
  1308. if (ret > 0) {
  1309. if (Base64_Encode(p7out, (word32)len, NULL, &sigBase64Len) != LENGTH_ONLY_E) {
  1310. ret = 0;
  1311. }
  1312. else {
  1313. sigBase64 = (byte*)XMALLOC(sigBase64Len, NULL,
  1314. DYNAMIC_TYPE_TMP_BUFFER);
  1315. if (sigBase64 == NULL) {
  1316. ret = 0;
  1317. }
  1318. }
  1319. }
  1320. if (ret > 0) {
  1321. XMEMSET(sigBase64, 0, sigBase64Len);
  1322. if (Base64_Encode(p7out, (word32)len, sigBase64, &sigBase64Len) < 0) {
  1323. WOLFSSL_MSG("Error in Base64_Encode of signature");
  1324. ret = 0;
  1325. }
  1326. }
  1327. /* build up SMIME message */
  1328. if (ret > 0) {
  1329. if (flags & PKCS7_DETACHED) {
  1330. /* generate random boundary */
  1331. if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
  1332. WOLFSSL_MSG("No RNG to use");
  1333. ret = 0;
  1334. }
  1335. /* no need to generate random byte for null terminator (size-1) */
  1336. if ((ret > 0) && (wc_RNG_GenerateBlock(&globalRNG, (byte*)boundary,
  1337. sizeof(boundary) - 1 ) != 0)) {
  1338. WOLFSSL_MSG("Error in wc_RNG_GenerateBlock");
  1339. ret = 0;
  1340. }
  1341. if (ret > 0) {
  1342. for (i = 0; i < (int)sizeof(boundary) - 1; i++) {
  1343. boundary[i] =
  1344. alphanum[boundary[i] % XSTR_SIZEOF(alphanum)];
  1345. }
  1346. boundary[sizeof(boundary)-1] = 0;
  1347. }
  1348. if (ret > 0) {
  1349. /* S/MIME header beginning */
  1350. ret = wolfSSL_BIO_printf(out,
  1351. "MIME-Version: 1.0\n"
  1352. "Content-Type: multipart/signed; "
  1353. "protocol=\"application/x-pkcs7-signature\"; "
  1354. "micalg=\"%s\"; "
  1355. "boundary=\"----%s\"\n\n"
  1356. "This is an S/MIME signed message\n\n"
  1357. "------%s\n",
  1358. wolfSSL_SMIME_HashOIDToString(p7->pkcs7.hashOID),
  1359. boundary, boundary);
  1360. }
  1361. if (ret > 0) {
  1362. /* S/MIME content */
  1363. ret = wolfSSL_BIO_write(out,
  1364. p7->pkcs7.content, p7->pkcs7.contentSz);
  1365. }
  1366. if (ret > 0) {
  1367. /* S/SMIME header end boundary */
  1368. ret = wolfSSL_BIO_printf(out,
  1369. "\n------%s\n", boundary);
  1370. }
  1371. if (ret > 0) {
  1372. /* Signature and header */
  1373. ret = wolfSSL_BIO_printf(out,
  1374. "Content-Type: application/x-pkcs7-signature; "
  1375. "name=\"smime.p7s\"\n"
  1376. "Content-Transfer-Encoding: base64\n"
  1377. "Content-Disposition: attachment; "
  1378. "filename=\"smime.p7s\"\n\n"
  1379. "%.*s\n" /* Base64 encoded signature */
  1380. "------%s--\n\n",
  1381. sigBase64Len, sigBase64,
  1382. boundary);
  1383. }
  1384. }
  1385. else {
  1386. p7TypeString = wolfSSL_SMIME_PKCS7TypeToString(p7->type);
  1387. if (p7TypeString == NULL) {
  1388. WOLFSSL_MSG("Unsupported PKCS7 SMIME type");
  1389. ret = 0;
  1390. }
  1391. if (ret > 0) {
  1392. /* not detached */
  1393. ret = wolfSSL_BIO_printf(out,
  1394. "MIME-Version: 1.0\n"
  1395. "Content-Disposition: attachment; "
  1396. "filename=\"smime.p7m\"\n"
  1397. "Content-Type: application/x-pkcs7-mime; "
  1398. "smime-type=%s; name=\"smime.p7m\"\n"
  1399. "Content-Transfer-Encoding: base64\n\n"
  1400. "%.*s\n" /* signature */,
  1401. p7TypeString, sigBase64Len, sigBase64);
  1402. }
  1403. }
  1404. }
  1405. if (p7out != NULL) {
  1406. XFREE(p7out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1407. }
  1408. if (sigBase64 != NULL) {
  1409. XFREE(sigBase64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1410. }
  1411. if (ret > 0) {
  1412. return WOLFSSL_SUCCESS;
  1413. }
  1414. return WOLFSSL_FAILURE;
  1415. }
  1416. #endif /* HAVE_SMIME */
  1417. #endif /* !NO_BIO */
  1418. #endif /* OPENSSL_ALL */
  1419. #endif /* HAVE_PKCS7 */
  1420. /*******************************************************************************
  1421. * END OF PKCS7 APIs
  1422. ******************************************************************************/
  1423. /*******************************************************************************
  1424. * START OF PKCS12 APIs
  1425. ******************************************************************************/
  1426. #ifdef OPENSSL_EXTRA
  1427. /* no-op function. Was initially used for adding encryption algorithms available
  1428. * for PKCS12 */
  1429. void wolfSSL_PKCS12_PBE_add(void)
  1430. {
  1431. WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
  1432. }
  1433. #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
  1434. WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp,
  1435. WOLFSSL_X509_PKCS12 **pkcs12)
  1436. {
  1437. WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
  1438. return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12,
  1439. PKCS12_TYPE);
  1440. }
  1441. #endif /* !NO_FILESYSTEM */
  1442. #endif /* OPENSSL_EXTRA */
  1443. #if defined(HAVE_PKCS12)
  1444. #ifdef OPENSSL_EXTRA
  1445. #if !defined(NO_ASN) && !defined(NO_PWDBASED)
  1446. #ifndef NO_BIO
  1447. WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
  1448. {
  1449. WC_PKCS12* localPkcs12 = NULL;
  1450. unsigned char* mem = NULL;
  1451. long memSz;
  1452. int ret = -1;
  1453. WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
  1454. if (bio == NULL) {
  1455. WOLFSSL_MSG("Bad Function Argument bio is NULL");
  1456. return NULL;
  1457. }
  1458. memSz = wolfSSL_BIO_get_len(bio);
  1459. if (memSz <= 0) {
  1460. return NULL;
  1461. }
  1462. mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1463. if (mem == NULL) {
  1464. return NULL;
  1465. }
  1466. if (mem != NULL) {
  1467. localPkcs12 = wc_PKCS12_new_ex(bio->heap);
  1468. if (localPkcs12 == NULL) {
  1469. WOLFSSL_MSG("Memory error");
  1470. }
  1471. }
  1472. if (mem != NULL && localPkcs12 != NULL) {
  1473. if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
  1474. ret = wc_d2i_PKCS12(mem, (word32)memSz, localPkcs12);
  1475. if (ret < 0) {
  1476. WOLFSSL_MSG("Failed to get PKCS12 sequence");
  1477. }
  1478. }
  1479. else {
  1480. WOLFSSL_MSG("Failed to get data from bio struct");
  1481. }
  1482. }
  1483. /* cleanup */
  1484. if (mem != NULL)
  1485. XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1486. if (ret < 0 && localPkcs12 != NULL) {
  1487. wc_PKCS12_free(localPkcs12);
  1488. localPkcs12 = NULL;
  1489. }
  1490. if (pkcs12 != NULL)
  1491. *pkcs12 = localPkcs12;
  1492. return localPkcs12;
  1493. }
  1494. /* Converts the PKCS12 to DER format and outputs it into bio.
  1495. *
  1496. * bio is the structure to hold output DER
  1497. * pkcs12 structure to create DER from
  1498. *
  1499. * return 1 for success or 0 if an error occurs
  1500. */
  1501. int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12)
  1502. {
  1503. int ret = WOLFSSL_FAILURE;
  1504. WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio");
  1505. if ((bio != NULL) && (pkcs12 != NULL)) {
  1506. word32 certSz = 0;
  1507. byte *certDer = NULL;
  1508. certSz = (word32)wc_i2d_PKCS12(pkcs12, &certDer, NULL);
  1509. if ((certSz > 0) && (certDer != NULL)) {
  1510. if (wolfSSL_BIO_write(bio, certDer, (int)certSz) == (int)certSz) {
  1511. ret = WOLFSSL_SUCCESS;
  1512. }
  1513. }
  1514. if (certDer != NULL) {
  1515. XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS);
  1516. }
  1517. }
  1518. return ret;
  1519. }
  1520. #endif /* !NO_BIO */
  1521. /* Creates a new WC_PKCS12 structure
  1522. *
  1523. * pass password to use
  1524. * name friendlyName to use
  1525. * pkey private key to go into PKCS12 bundle
  1526. * cert certificate to go into PKCS12 bundle
  1527. * ca extra certificates that can be added to bundle. Can be NULL
  1528. * keyNID type of encryption to use on the key (-1 means no encryption)
  1529. * certNID type of encryption to use on the certificate
  1530. * itt number of iterations with encryption
  1531. * macItt number of iterations with mac creation
  1532. * keyType flag for signature and/or encryption key
  1533. *
  1534. * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
  1535. */
  1536. WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WOLFSSL_EVP_PKEY* pkey,
  1537. WOLFSSL_X509* cert, WOLF_STACK_OF(WOLFSSL_X509)* ca, int keyNID,
  1538. int certNID, int itt, int macItt, int keyType)
  1539. {
  1540. WC_PKCS12* pkcs12;
  1541. WC_DerCertList* list = NULL;
  1542. word32 passSz;
  1543. byte* keyDer = NULL;
  1544. word32 keyDerSz;
  1545. byte* certDer;
  1546. int certDerSz;
  1547. WOLFSSL_ENTER("wolfSSL_PKCS12_create");
  1548. if (pass == NULL || pkey == NULL || cert == NULL) {
  1549. WOLFSSL_LEAVE("wolfSSL_PKCS12_create", BAD_FUNC_ARG);
  1550. return NULL;
  1551. }
  1552. passSz = (word32)XSTRLEN(pass);
  1553. keyDer = (byte*)pkey->pkey.ptr;
  1554. keyDerSz = (word32)pkey->pkey_sz;
  1555. certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
  1556. if (certDer == NULL) {
  1557. return NULL;
  1558. }
  1559. if (ca != NULL) {
  1560. unsigned long numCerts = ca->num;
  1561. WOLFSSL_STACK* sk = ca;
  1562. while (numCerts > 0 && sk != NULL) {
  1563. byte* curDer;
  1564. WC_DerCertList* cur;
  1565. int curDerSz = 0;
  1566. cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
  1567. DYNAMIC_TYPE_PKCS);
  1568. if (cur == NULL) {
  1569. wc_FreeCertList(list, NULL);
  1570. return NULL;
  1571. }
  1572. curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
  1573. if (curDer == NULL || curDerSz < 0) {
  1574. XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
  1575. wc_FreeCertList(list, NULL);
  1576. return NULL;
  1577. }
  1578. cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
  1579. if (cur->buffer == NULL) {
  1580. XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
  1581. wc_FreeCertList(list, NULL);
  1582. return NULL;
  1583. }
  1584. XMEMCPY(cur->buffer, curDer, curDerSz);
  1585. cur->bufferSz = (word32)curDerSz;
  1586. cur->next = list;
  1587. list = cur;
  1588. sk = sk->next;
  1589. numCerts--;
  1590. }
  1591. }
  1592. pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
  1593. certDer, (word32)certDerSz, list, keyNID, certNID, itt, macItt,
  1594. keyType, NULL);
  1595. if (ca != NULL) {
  1596. wc_FreeCertList(list, NULL);
  1597. }
  1598. return pkcs12;
  1599. }
  1600. /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
  1601. int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
  1602. WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert,
  1603. WOLF_STACK_OF(WOLFSSL_X509)** ca)
  1604. {
  1605. void* heap = NULL;
  1606. int ret;
  1607. byte* certData = NULL;
  1608. word32 certDataSz;
  1609. byte* pk = NULL;
  1610. word32 pkSz;
  1611. WC_DerCertList* certList = NULL;
  1612. #ifdef WOLFSSL_SMALL_STACK
  1613. DecodedCert *DeCert;
  1614. #else
  1615. DecodedCert DeCert[1];
  1616. #endif
  1617. WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
  1618. /* make sure we init return args */
  1619. if (pkey) *pkey = NULL;
  1620. if (cert) *cert = NULL;
  1621. if (ca) *ca = NULL;
  1622. if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
  1623. WOLFSSL_MSG("Bad argument value");
  1624. return WOLFSSL_FAILURE;
  1625. }
  1626. heap = wc_PKCS12_GetHeap(pkcs12);
  1627. if (ca == NULL) {
  1628. ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
  1629. NULL);
  1630. }
  1631. else {
  1632. ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
  1633. &certList);
  1634. }
  1635. if (ret < 0) {
  1636. WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
  1637. return WOLFSSL_FAILURE;
  1638. }
  1639. #ifdef WOLFSSL_SMALL_STACK
  1640. DeCert = (DecodedCert *)XMALLOC(sizeof(*DeCert), heap,
  1641. DYNAMIC_TYPE_DCERT);
  1642. if (DeCert == NULL) {
  1643. WOLFSSL_MSG("out of memory");
  1644. return WOLFSSL_FAILURE;
  1645. }
  1646. #endif
  1647. /* Decode cert and place in X509 stack struct */
  1648. if (certList != NULL) {
  1649. WC_DerCertList* current = certList;
  1650. *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(
  1651. sizeof(WOLF_STACK_OF(WOLFSSL_X509)), heap, DYNAMIC_TYPE_X509);
  1652. if (*ca == NULL) {
  1653. if (pk != NULL) {
  1654. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1655. }
  1656. if (certData != NULL) {
  1657. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1658. }
  1659. /* Free up WC_DerCertList and move on */
  1660. while (current != NULL) {
  1661. WC_DerCertList* next = current->next;
  1662. XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
  1663. XFREE(current, heap, DYNAMIC_TYPE_PKCS);
  1664. current = next;
  1665. }
  1666. ret = WOLFSSL_FAILURE;
  1667. goto out;
  1668. }
  1669. XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
  1670. /* add list of DER certs as X509's to stack */
  1671. while (current != NULL) {
  1672. WC_DerCertList* toFree = current;
  1673. WOLFSSL_X509* x509;
  1674. x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
  1675. DYNAMIC_TYPE_X509);
  1676. InitX509(x509, 1, heap);
  1677. InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
  1678. if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
  1679. WOLFSSL_MSG("Issue with parsing certificate");
  1680. FreeDecodedCert(DeCert);
  1681. wolfSSL_X509_free(x509);
  1682. }
  1683. else {
  1684. if (CopyDecodedToX509(x509, DeCert) != 0) {
  1685. WOLFSSL_MSG("Failed to copy decoded cert");
  1686. FreeDecodedCert(DeCert);
  1687. wolfSSL_X509_free(x509);
  1688. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1689. if (pk != NULL) {
  1690. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1691. }
  1692. if (certData != NULL) {
  1693. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1694. }
  1695. /* Free up WC_DerCertList */
  1696. while (current != NULL) {
  1697. WC_DerCertList* next = current->next;
  1698. XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
  1699. XFREE(current, heap, DYNAMIC_TYPE_PKCS);
  1700. current = next;
  1701. }
  1702. ret = WOLFSSL_FAILURE;
  1703. goto out;
  1704. }
  1705. FreeDecodedCert(DeCert);
  1706. if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
  1707. WOLFSSL_MSG("Failed to push x509 onto stack");
  1708. wolfSSL_X509_free(x509);
  1709. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1710. if (pk != NULL) {
  1711. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1712. }
  1713. if (certData != NULL) {
  1714. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1715. }
  1716. /* Free up WC_DerCertList */
  1717. while (current != NULL) {
  1718. WC_DerCertList* next = current->next;
  1719. XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
  1720. XFREE(current, heap, DYNAMIC_TYPE_PKCS);
  1721. current = next;
  1722. }
  1723. ret = WOLFSSL_FAILURE;
  1724. goto out;
  1725. }
  1726. }
  1727. current = current->next;
  1728. XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
  1729. XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
  1730. }
  1731. }
  1732. /* Decode cert and place in X509 struct */
  1733. if (certData != NULL) {
  1734. *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
  1735. DYNAMIC_TYPE_X509);
  1736. if (*cert == NULL) {
  1737. if (pk != NULL) {
  1738. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1739. }
  1740. if (ca != NULL) {
  1741. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1742. }
  1743. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1744. ret = WOLFSSL_FAILURE;
  1745. goto out;
  1746. }
  1747. InitX509(*cert, 1, heap);
  1748. InitDecodedCert(DeCert, certData, certDataSz, heap);
  1749. if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
  1750. WOLFSSL_MSG("Issue with parsing certificate");
  1751. }
  1752. if (CopyDecodedToX509(*cert, DeCert) != 0) {
  1753. WOLFSSL_MSG("Failed to copy decoded cert");
  1754. FreeDecodedCert(DeCert);
  1755. if (pk != NULL) {
  1756. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1757. }
  1758. if (ca != NULL) {
  1759. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1760. }
  1761. wolfSSL_X509_free(*cert); *cert = NULL;
  1762. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1763. ret = WOLFSSL_FAILURE;
  1764. goto out;
  1765. }
  1766. FreeDecodedCert(DeCert);
  1767. XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
  1768. }
  1769. /* get key type */
  1770. ret = BAD_STATE_E;
  1771. if (pk != NULL) { /* decode key if present */
  1772. *pkey = wolfSSL_EVP_PKEY_new_ex(heap);
  1773. if (*pkey == NULL) {
  1774. wolfSSL_X509_free(*cert); *cert = NULL;
  1775. if (ca != NULL) {
  1776. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1777. }
  1778. XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1779. ret = WOLFSSL_FAILURE;
  1780. goto out;
  1781. }
  1782. #ifndef NO_RSA
  1783. {
  1784. const unsigned char* pt = pk;
  1785. if (wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, pkey, &pt, pkSz) !=
  1786. NULL) {
  1787. ret = 0;
  1788. }
  1789. }
  1790. #endif /* NO_RSA */
  1791. #ifdef HAVE_ECC
  1792. if (ret != 0) { /* if is in fail state check if ECC key */
  1793. const unsigned char* pt = pk;
  1794. if (wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, pkey, &pt, pkSz) !=
  1795. NULL) {
  1796. ret = 0;
  1797. }
  1798. }
  1799. #endif /* HAVE_ECC */
  1800. if (pk != NULL)
  1801. XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
  1802. if (ret != 0) { /* if is in fail state and no PKEY then fail */
  1803. wolfSSL_X509_free(*cert); *cert = NULL;
  1804. if (ca != NULL) {
  1805. wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
  1806. }
  1807. wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
  1808. WOLFSSL_MSG("Bad PKCS12 key format");
  1809. ret = WOLFSSL_FAILURE;
  1810. goto out;
  1811. }
  1812. if (pkey != NULL && *pkey != NULL) {
  1813. (*pkey)->save_type = 0;
  1814. }
  1815. }
  1816. (void)ret;
  1817. (void)ca;
  1818. ret = WOLFSSL_SUCCESS;
  1819. out:
  1820. #ifdef WOLFSSL_SMALL_STACK
  1821. XFREE(DeCert, heap, DYNAMIC_TYPE_DCERT);
  1822. #endif
  1823. return ret;
  1824. }
  1825. int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,
  1826. int pswLen)
  1827. {
  1828. WOLFSSL_ENTER("wolfSSL_PKCS12_verify_mac");
  1829. if (!pkcs12) {
  1830. return WOLFSSL_FAILURE;
  1831. }
  1832. return wc_PKCS12_verify_ex(pkcs12, (const byte*)psw, (word32)pswLen) == 0 ?
  1833. WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
  1834. }
  1835. #endif /* !NO_ASN && !NO_PWDBASED */
  1836. #endif /* OPENSSL_EXTRA */
  1837. #endif /* HAVE_PKCS12 */
  1838. /*******************************************************************************
  1839. * END OF PKCS12 APIs
  1840. ******************************************************************************/
  1841. #endif /* !WOLFCRYPT_ONLY && !NO_CERTS */
  1842. #endif /* !WOLFSSL_SSL_P7P12_INCLUDED */