pkcs12.c 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763
  1. /* pkcs12.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. /* PKCS#12 allows storage of key and certificates into containers */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <wolfssl/wolfcrypt/settings.h>
  26. #if defined(HAVE_PKCS12) && \
  27. !defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_HMAC) && \
  28. !defined(NO_CERTS)
  29. #include <wolfssl/wolfcrypt/asn.h>
  30. #include <wolfssl/wolfcrypt/asn_public.h>
  31. #include <wolfssl/wolfcrypt/error-crypt.h>
  32. #include <wolfssl/wolfcrypt/hmac.h>
  33. #include <wolfssl/wolfcrypt/logging.h>
  34. #ifdef NO_INLINE
  35. #include <wolfssl/wolfcrypt/misc.h>
  36. #else
  37. #define WOLFSSL_MISC_INCLUDED
  38. #include <wolfcrypt/src/misc.c>
  39. #endif
  40. #include <wolfssl/wolfcrypt/pkcs12.h>
  41. #include <wolfssl/wolfcrypt/pwdbased.h>
  42. #include <wolfssl/wolfcrypt/hash.h>
  43. #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
  44. enum {
  45. WC_PKCS12_KeyBag = 667,
  46. WC_PKCS12_ShroudedKeyBag = 668,
  47. WC_PKCS12_CertBag = 669,
  48. WC_PKCS12_CertBag_Type1 = 675,
  49. WC_PKCS12_CrlBag = 670,
  50. WC_PKCS12_SecretBag = 671,
  51. WC_PKCS12_SafeContentsBag = 672,
  52. WC_PKCS12_DATA = 651,
  53. WC_PKCS12_ENCRYPTED_DATA = 656,
  54. WC_PKCS12_DATA_OBJ_SZ = 11,
  55. WC_PKCS12_MAC_SALT_SZ = 8
  56. };
  57. static const byte WC_PKCS12_ENCRYPTED_OID[] =
  58. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06};
  59. static const byte WC_PKCS12_DATA_OID[] =
  60. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01};
  61. static const byte WC_PKCS12_CertBag_Type1_OID[] =
  62. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01};
  63. static const byte WC_PKCS12_CertBag_OID[] =
  64. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x03};
  65. static const byte WC_PKCS12_KeyBag_OID[] =
  66. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x01};
  67. static const byte WC_PKCS12_ShroudedKeyBag_OID[] =
  68. {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x02};
  69. typedef struct ContentInfo {
  70. byte* data;
  71. struct ContentInfo* next;
  72. word32 encC; /* encryptedContent */
  73. word32 dataSz;
  74. int type; /* DATA / encrypted / enveloped */
  75. } ContentInfo;
  76. typedef struct AuthenticatedSafe {
  77. ContentInfo* CI;
  78. byte* data; /* T contents.... */
  79. word32 oid; /* encrypted or not */
  80. word32 numCI; /* number of Content Info structs */
  81. word32 dataSz;
  82. } AuthenticatedSafe;
  83. typedef struct MacData {
  84. byte* digest;
  85. byte* salt;
  86. word32 oid;
  87. word32 digestSz;
  88. word32 saltSz;
  89. int itt; /* number of iterations when creating HMAC key */
  90. } MacData;
  91. struct WC_PKCS12 {
  92. void* heap;
  93. AuthenticatedSafe* safe;
  94. MacData* signData;
  95. word32 oid; /* DATA / Enveloped DATA ... */
  96. byte indefinite;
  97. #ifdef ASN_BER_TO_DER
  98. byte* safeDer; /* der encoded version of message */
  99. byte* der; /* der encoded version of message */
  100. word32 safeDersz;
  101. word32 derSz;
  102. #endif
  103. };
  104. /* for friendlyName, localKeyId .... */
  105. typedef struct WC_PKCS12_ATTRIBUTE {
  106. byte* data;
  107. word32 oid;
  108. word32 dataSz;
  109. } WC_PKCS12_ATTRIBUTE;
  110. WC_PKCS12* wc_PKCS12_new(void)
  111. {
  112. WC_PKCS12* pkcs12 = (WC_PKCS12*)XMALLOC(sizeof(WC_PKCS12),
  113. NULL, DYNAMIC_TYPE_PKCS);
  114. if (pkcs12 == NULL) {
  115. WOLFSSL_MSG("Memory issue when creating WC_PKCS12 struct");
  116. return NULL;
  117. }
  118. XMEMSET(pkcs12, 0, sizeof(WC_PKCS12));
  119. return pkcs12;
  120. }
  121. static void freeSafe(AuthenticatedSafe* safe, void* heap)
  122. {
  123. int i;
  124. if (safe == NULL) {
  125. return;
  126. }
  127. /* free content info structs */
  128. for (i = (int)safe->numCI; i > 0; i--) {
  129. ContentInfo* ci = safe->CI;
  130. safe->CI = ci->next;
  131. XFREE(ci, heap, DYNAMIC_TYPE_PKCS);
  132. }
  133. if (safe->data != NULL) {
  134. XFREE(safe->data, heap, DYNAMIC_TYPE_PKCS);
  135. }
  136. XFREE(safe, heap, DYNAMIC_TYPE_PKCS);
  137. (void)heap;
  138. }
  139. void wc_PKCS12_free(WC_PKCS12* pkcs12)
  140. {
  141. void* heap;
  142. /* if null pointer is passed in do nothing */
  143. if (pkcs12 == NULL) {
  144. WOLFSSL_MSG("Trying to free null WC_PKCS12 object");
  145. return;
  146. }
  147. heap = pkcs12->heap;
  148. if (pkcs12->safe != NULL) {
  149. freeSafe(pkcs12->safe, heap);
  150. }
  151. /* free mac data */
  152. if (pkcs12->signData != NULL) {
  153. if (pkcs12->signData->digest != NULL) {
  154. XFREE(pkcs12->signData->digest, heap, DYNAMIC_TYPE_DIGEST);
  155. }
  156. if (pkcs12->signData->salt != NULL) {
  157. XFREE(pkcs12->signData->salt, heap, DYNAMIC_TYPE_SALT);
  158. }
  159. XFREE(pkcs12->signData, heap, DYNAMIC_TYPE_PKCS);
  160. }
  161. #ifdef ASN_BER_TO_DER
  162. if (pkcs12->der != NULL) {
  163. XFREE(pkcs12->der, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  164. }
  165. if (pkcs12->safeDer != NULL) {
  166. XFREE(pkcs12->safeDer, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  167. }
  168. #endif
  169. XFREE(pkcs12, NULL, DYNAMIC_TYPE_PKCS);
  170. }
  171. /* return 0 on success */
  172. static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
  173. word32* idx, word32 maxIdx)
  174. {
  175. AuthenticatedSafe* safe;
  176. word32 oid;
  177. word32 localIdx = *idx;
  178. int ret;
  179. int size = 0;
  180. byte tag;
  181. safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,
  182. DYNAMIC_TYPE_PKCS);
  183. if (safe == NULL) {
  184. return MEMORY_E;
  185. }
  186. XMEMSET(safe, 0, sizeof(AuthenticatedSafe));
  187. ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType, maxIdx);
  188. if (ret < 0) {
  189. WOLFSSL_LEAVE("Get object id failed", ret);
  190. freeSafe(safe, pkcs12->heap);
  191. return ASN_PARSE_E;
  192. }
  193. safe->oid = oid;
  194. /* check tag, length */
  195. if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
  196. freeSafe(safe, pkcs12->heap);
  197. return ASN_PARSE_E;
  198. }
  199. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  200. WOLFSSL_MSG("Unexpected tag in PKCS12 DER");
  201. freeSafe(safe, pkcs12->heap);
  202. return ASN_PARSE_E;
  203. }
  204. if (GetLength(input, &localIdx, &size, maxIdx) <= 0) {
  205. freeSafe(safe, pkcs12->heap);
  206. return ASN_PARSE_E;
  207. }
  208. switch (oid) {
  209. case WC_PKCS12_ENCRYPTED_DATA:
  210. WOLFSSL_MSG("Found PKCS12 OBJECT: ENCRYPTED DATA");
  211. break;
  212. case WC_PKCS12_DATA:
  213. WOLFSSL_MSG("Found PKCS12 OBJECT: DATA");
  214. /* get octets holding contents */
  215. if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
  216. freeSafe(safe, pkcs12->heap);
  217. return ASN_PARSE_E;
  218. }
  219. if (tag != ASN_OCTET_STRING) {
  220. WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA");
  221. freeSafe(safe, pkcs12->heap);
  222. return ASN_PARSE_E;
  223. }
  224. if (GetLength(input, &localIdx, &size, maxIdx) <= 0) {
  225. freeSafe(safe, pkcs12->heap);
  226. return ASN_PARSE_E;
  227. }
  228. break;
  229. }
  230. safe->dataSz = (word32)size;
  231. safe->data = (byte*)XMALLOC((size_t)size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  232. if (safe->data == NULL) {
  233. freeSafe(safe, pkcs12->heap);
  234. return MEMORY_E;
  235. }
  236. XMEMCPY(safe->data, input + localIdx, (size_t)size);
  237. *idx = localIdx;
  238. localIdx = 0;
  239. input = safe->data;
  240. size = (int)safe->dataSz;
  241. #ifdef ASN_BER_TO_DER
  242. if (pkcs12->indefinite) {
  243. if (wc_BerToDer(input, safe->dataSz, NULL,
  244. &pkcs12->safeDersz) != LENGTH_ONLY_E) {
  245. WOLFSSL_MSG("Not BER sequence");
  246. return ASN_PARSE_E;
  247. }
  248. pkcs12->safeDer = (byte*)XMALLOC(pkcs12->safeDersz, pkcs12->heap,
  249. DYNAMIC_TYPE_PKCS);
  250. if (pkcs12->safeDer == NULL) {
  251. freeSafe(safe, pkcs12->heap);
  252. return MEMORY_E;
  253. }
  254. ret = wc_BerToDer(input, safe->dataSz, pkcs12->safeDer, &pkcs12->safeDersz);
  255. if (ret < 0) {
  256. freeSafe(safe, pkcs12->heap);
  257. return ret;
  258. }
  259. input = pkcs12->safeDer;
  260. }
  261. #endif /* ASN_BER_TO_DER */
  262. /* an instance of AuthenticatedSafe is created from
  263. * ContentInfo's strung together in a SEQUENCE. Here we iterate
  264. * through the ContentInfo's and add them to our
  265. * AuthenticatedSafe struct */
  266. {
  267. int CISz;
  268. ret = GetSequence(input, &localIdx, &CISz, (word32)size);
  269. if (ret < 0) {
  270. freeSafe(safe, pkcs12->heap);
  271. return ASN_PARSE_E;
  272. }
  273. CISz += (int)localIdx;
  274. while (localIdx < (word32)CISz) {
  275. int curSz = 0;
  276. word32 curIdx;
  277. ContentInfo* ci = NULL;
  278. #ifdef WOLFSSL_DEBUG_PKCS12
  279. printf("\t\tlooking for Content Info.... ");
  280. #endif
  281. if ((ret = GetSequence(input, &localIdx, &curSz, (word32)size)) < 0) {
  282. freeSafe(safe, pkcs12->heap);
  283. return ret;
  284. }
  285. if (curSz > CISz) {
  286. /* subset should not be larger than universe */
  287. freeSafe(safe, pkcs12->heap);
  288. return ASN_PARSE_E;
  289. }
  290. curIdx = localIdx;
  291. if ((ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType,
  292. (word32)size)) < 0) {
  293. WOLFSSL_LEAVE("Get object id failed", ret);
  294. freeSafe(safe, pkcs12->heap);
  295. return ret;
  296. }
  297. /* create new content info struct ... possible OID sanity check? */
  298. ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), pkcs12->heap,
  299. DYNAMIC_TYPE_PKCS);
  300. if (ci == NULL) {
  301. freeSafe(safe, pkcs12->heap);
  302. return MEMORY_E;
  303. }
  304. ci->type = (int)oid;
  305. ci->dataSz = (word32)curSz - (localIdx-curIdx);
  306. ci->data = (byte*)input + localIdx;
  307. localIdx += ci->dataSz;
  308. #ifdef WOLFSSL_DEBUG_PKCS12
  309. switch (oid) {
  310. case WC_PKCS12_ENCRYPTED_DATA:
  311. printf("CONTENT INFO: ENCRYPTED DATA, size = %d\n", ci->dataSz);
  312. break;
  313. case WC_PKCS12_DATA:
  314. printf("CONTENT INFO: DATA, size = %d\n", ci->dataSz);
  315. break;
  316. default:
  317. printf("CONTENT INFO: UNKNOWN, size = %d\n", ci->dataSz);
  318. }
  319. #endif
  320. /* insert to head of list */
  321. ci->next = safe->CI;
  322. safe->CI = ci;
  323. safe->numCI += 1;
  324. }
  325. }
  326. pkcs12->safe = safe;
  327. *idx += localIdx;
  328. return ret;
  329. }
  330. /* parse optional mac data
  331. * return 0 on success */
  332. static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
  333. word32 totalSz)
  334. {
  335. MacData* mac;
  336. word32 curIdx = *idx;
  337. word32 oid = 0;
  338. int size, ret;
  339. byte tag;
  340. /* Digest Info : Sequence
  341. * DigestAlgorithmIdentifier
  342. * Digest
  343. */
  344. if (GetSequence(mem, &curIdx, &size, totalSz) <= 0) {
  345. WOLFSSL_MSG("Failed to get PKCS12 sequence");
  346. return ASN_PARSE_E;
  347. }
  348. #ifdef WOLFSSL_DEBUG_PKCS12
  349. printf("\t\tSEQUENCE: DigestInfo size = %d\n", size);
  350. #endif
  351. mac = (MacData*)XMALLOC(sizeof(MacData), pkcs12->heap, DYNAMIC_TYPE_PKCS);
  352. if (mac == NULL) {
  353. return MEMORY_E;
  354. }
  355. XMEMSET(mac, 0, sizeof(MacData));
  356. /* DigestAlgorithmIdentifier */
  357. if ((ret = GetAlgoId(mem, &curIdx, &oid, oidIgnoreType, totalSz)) < 0) {
  358. WOLFSSL_MSG("Failed to get PKCS12 sequence");
  359. XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  360. return ret;
  361. }
  362. mac->oid = oid;
  363. #ifdef WOLFSSL_DEBUG_PKCS12
  364. printf("\t\tALGO ID = %d\n", oid);
  365. #endif
  366. /* Digest: should be octet type holding digest */
  367. if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
  368. XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  369. return ASN_PARSE_E;
  370. }
  371. if (tag != ASN_OCTET_STRING) {
  372. WOLFSSL_MSG("Failed to get digest");
  373. XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  374. return ASN_PARSE_E;
  375. }
  376. if (GetLength(mem, &curIdx, &size, totalSz) <= 0) {
  377. XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  378. return ASN_PARSE_E;
  379. }
  380. mac->digestSz = (word32)size;
  381. mac->digest = (byte*)XMALLOC(mac->digestSz, pkcs12->heap,
  382. DYNAMIC_TYPE_DIGEST);
  383. if (mac->digest == NULL || mac->digestSz + curIdx > totalSz) {
  384. ERROR_OUT(MEMORY_E, exit_gsd);
  385. }
  386. XMEMCPY(mac->digest, mem + curIdx, mac->digestSz);
  387. #ifdef WOLFSSL_DEBUG_PKCS12
  388. {
  389. byte* p;
  390. for (printf("\t\tDigest = "), p = (byte*)mem+curIdx;
  391. p < (byte*)mem + curIdx + mac->digestSz;
  392. printf("%02X", *p), p++);
  393. printf(" : size = %d\n", mac->digestSz);
  394. }
  395. #endif
  396. curIdx += mac->digestSz;
  397. /* get salt, should be octet string */
  398. if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
  399. ERROR_OUT(ASN_PARSE_E, exit_gsd);
  400. }
  401. if (tag != ASN_OCTET_STRING) {
  402. WOLFSSL_MSG("Failed to get salt");
  403. ERROR_OUT(ASN_PARSE_E, exit_gsd);
  404. }
  405. if ((ret = GetLength(mem, &curIdx, &size, totalSz)) < 0) {
  406. goto exit_gsd;
  407. }
  408. mac->saltSz = (word32)size;
  409. mac->salt = (byte*)XMALLOC(mac->saltSz, pkcs12->heap, DYNAMIC_TYPE_SALT);
  410. if (mac->salt == NULL || mac->saltSz + curIdx > totalSz) {
  411. ERROR_OUT(MEMORY_E, exit_gsd);
  412. }
  413. XMEMCPY(mac->salt, mem + curIdx, mac->saltSz);
  414. #ifdef WOLFSSL_DEBUG_PKCS12
  415. {
  416. byte* p;
  417. for (printf("\t\tSalt = "), p = (byte*)mem + curIdx;
  418. p < (byte*)mem + curIdx + mac->saltSz;
  419. printf("%02X", *p), p++);
  420. printf(" : size = %d\n", mac->saltSz);
  421. }
  422. #endif
  423. curIdx += mac->saltSz;
  424. /* check for MAC iterations, default to 1 */
  425. mac->itt = WC_PKCS12_MAC_DEFAULT;
  426. if (curIdx < totalSz) {
  427. int number = 0;
  428. if (GetShortInt(mem, &curIdx, &number, totalSz) >= 0) {
  429. /* found a iteration value */
  430. mac->itt = number;
  431. }
  432. }
  433. #ifdef WOLFSSL_DEBUG_PKCS12
  434. printf("\t\tITERATIONS : %d\n", mac->itt);
  435. #endif
  436. *idx = curIdx;
  437. pkcs12->signData = mac;
  438. ret = 0; /* success */
  439. exit_gsd:
  440. /* failure cleanup */
  441. if (ret != 0) {
  442. if (mac) {
  443. if (mac->digest)
  444. XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_DIGEST);
  445. XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  446. }
  447. }
  448. return ret;
  449. }
  450. /* expects PKCS12 signData to be set up with OID
  451. *
  452. * returns the size of mac created on success. A negative value will be returned
  453. * in the case that an error happened.
  454. */
  455. static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
  456. const byte* psw, word32 pswSz, byte* out, word32 outSz)
  457. {
  458. Hmac hmac;
  459. MacData* mac;
  460. int ret, kLen;
  461. enum wc_HashType hashT;
  462. int idx = 0;
  463. int id = 3; /* value from RFC 7292 indicating key is used for MAC */
  464. word32 i;
  465. byte unicodePasswd[MAX_UNICODE_SZ];
  466. byte key[PKCS_MAX_KEY_SIZE];
  467. if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL ||
  468. out == NULL) {
  469. return BAD_FUNC_ARG;
  470. }
  471. mac = pkcs12->signData;
  472. /* unicode set up from asn.c */
  473. if ((pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
  474. WOLFSSL_MSG("PKCS12 max unicode size too small");
  475. return UNICODE_SIZE_E;
  476. }
  477. for (i = 0; i < pswSz; i++) {
  478. unicodePasswd[idx++] = 0x00;
  479. unicodePasswd[idx++] = (byte)psw[i];
  480. }
  481. /* add trailing NULL */
  482. unicodePasswd[idx++] = 0x00;
  483. unicodePasswd[idx++] = 0x00;
  484. /* get hash type used and resulting size of HMAC key */
  485. hashT = wc_OidGetHash((int)mac->oid);
  486. if (hashT == WC_HASH_TYPE_NONE) {
  487. ForceZero(unicodePasswd, MAX_UNICODE_SZ);
  488. WOLFSSL_MSG("Unsupported hash used");
  489. return BAD_FUNC_ARG;
  490. }
  491. kLen = wc_HashGetDigestSize(hashT);
  492. /* check out buffer is large enough */
  493. if (kLen < 0 || outSz < (word32)kLen) {
  494. ForceZero(unicodePasswd, MAX_UNICODE_SZ);
  495. return BAD_FUNC_ARG;
  496. }
  497. /* idx contains size of unicodePasswd */
  498. ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt, (int)mac->saltSz,
  499. mac->itt, kLen, (int)hashT, id, pkcs12->heap);
  500. ForceZero(unicodePasswd, MAX_UNICODE_SZ);
  501. if (ret < 0) {
  502. return ret;
  503. }
  504. /* now that key has been created use it to get HMAC hash on data */
  505. if ((ret = wc_HmacInit(&hmac, pkcs12->heap, INVALID_DEVID)) != 0) {
  506. return ret;
  507. }
  508. ret = wc_HmacSetKey(&hmac, (int)hashT, key, (word32)kLen);
  509. if (ret == 0)
  510. ret = wc_HmacUpdate(&hmac, data, dataSz);
  511. if (ret == 0)
  512. ret = wc_HmacFinal(&hmac, out);
  513. wc_HmacFree(&hmac);
  514. if (ret != 0)
  515. return ret;
  516. return kLen; /* same as digest size */
  517. }
  518. /* check mac on pkcs12, pkcs12->mac has been sanity checked before entering *
  519. * returns the result of comparison, success is 0 */
  520. static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
  521. const byte* psw, word32 pswSz)
  522. {
  523. MacData* mac;
  524. int ret;
  525. byte digest[WC_MAX_DIGEST_SIZE];
  526. if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL) {
  527. return BAD_FUNC_ARG;
  528. }
  529. mac = pkcs12->signData;
  530. #ifdef WOLFSSL_DEBUG_PKCS12
  531. printf("Verifying MAC with OID = %d\n", mac->oid);
  532. #endif
  533. /* check if this builds digest size is too small */
  534. if (mac->digestSz > WC_MAX_DIGEST_SIZE) {
  535. WOLFSSL_MSG("PKCS12 max digest size too small");
  536. return BAD_FUNC_ARG;
  537. }
  538. if ((ret = wc_PKCS12_create_mac(pkcs12, data, dataSz, psw, pswSz,
  539. digest, WC_MAX_DIGEST_SIZE)) < 0) {
  540. return ret;
  541. }
  542. #ifdef WOLFSSL_DEBUG_PKCS12
  543. {
  544. byte* p;
  545. for (printf("\t\tHash = "), p = (byte*)digest;
  546. p < (byte*)digest + mac->digestSz;
  547. printf("%02X", *p), p++);
  548. printf(" : size = %d\n", mac->digestSz);
  549. }
  550. #endif
  551. return XMEMCMP(digest, mac->digest, mac->digestSz);
  552. }
  553. int wc_PKCS12_verify_ex(WC_PKCS12* pkcs12, const byte* psw, word32 pswSz)
  554. {
  555. if (pkcs12 == NULL || pkcs12->safe == NULL) {
  556. return BAD_FUNC_ARG;
  557. }
  558. return wc_PKCS12_verify(pkcs12, pkcs12->safe->data, pkcs12->safe->dataSz,
  559. psw, pswSz);
  560. }
  561. /* Convert DER format stored in der buffer to WC_PKCS12 struct
  562. * Puts the raw contents of Content Info into structure without completely
  563. * parsing or decoding.
  564. * der : pointer to der buffer holding PKCS12
  565. * derSz : size of der buffer
  566. * pkcs12 : non-null pkcs12 pointer
  567. * return 0 on success and negative on failure.
  568. */
  569. int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12)
  570. {
  571. word32 idx = 0;
  572. word32 totalSz = 0;
  573. int ret;
  574. int size = 0;
  575. int version = 0;
  576. WOLFSSL_ENTER("wolfSSL_d2i_PKCS12");
  577. if (der == NULL || pkcs12 == NULL) {
  578. return BAD_FUNC_ARG;
  579. }
  580. totalSz = derSz;
  581. if (GetSequence(der, &idx, &size, totalSz) < 0) {
  582. WOLFSSL_MSG("Failed to get PKCS12 sequence");
  583. return ASN_PARSE_E;
  584. }
  585. /* get version */
  586. if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {
  587. return ret;
  588. }
  589. #ifdef ASN_BER_TO_DER
  590. if (size == 0) {
  591. if (wc_BerToDer(der, totalSz, NULL,
  592. (word32*)&size) != LENGTH_ONLY_E) {
  593. WOLFSSL_MSG("Not BER sequence");
  594. return ASN_PARSE_E;
  595. }
  596. pkcs12->der = (byte*)XMALLOC((size_t)size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  597. if (pkcs12->der == NULL)
  598. return MEMORY_E;
  599. ret = wc_BerToDer(der, derSz, pkcs12->der, (word32*)&size);
  600. if (ret < 0) {
  601. return ret;
  602. }
  603. der = pkcs12->der;
  604. pkcs12->derSz = (word32)size;
  605. totalSz = (word32)size;
  606. idx = 0;
  607. if (GetSequence(der, &idx, &size, totalSz) < 0) {
  608. WOLFSSL_MSG("Failed to get PKCS12 sequence");
  609. return ASN_PARSE_E;
  610. }
  611. /* get version */
  612. if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {
  613. return ret;
  614. }
  615. pkcs12->indefinite = 1;
  616. }
  617. else
  618. #endif /* ASN_BER_TO_DER */
  619. {
  620. pkcs12->indefinite = 0;
  621. }
  622. #ifdef WOLFSSL_DEBUG_PKCS12
  623. printf("\nBEGIN: PKCS12 size = %d\n", totalSz);
  624. printf("version = %d\n", version);
  625. #endif
  626. if (version != WC_PKCS12_VERSION_DEFAULT) {
  627. WOLFSSL_MSG("PKCS12 unsupported version!");
  628. WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
  629. return ASN_VERSION_E;
  630. }
  631. if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
  632. return ret;
  633. }
  634. #ifdef WOLFSSL_DEBUG_PKCS12
  635. printf("\tSEQUENCE: AuthenticatedSafe size = %d\n", size);
  636. #endif
  637. if ((ret = GetSafeContent(pkcs12, der, &idx, (word32)size + idx)) < 0) {
  638. WOLFSSL_MSG("GetSafeContent error");
  639. return ret;
  640. }
  641. #ifdef ASN_BER_TO_DER
  642. /* If indef, skip EOF */
  643. if (pkcs12->indefinite) {
  644. while((idx < totalSz) && (der[idx] == ASN_EOC)) {
  645. idx+=1;
  646. }
  647. }
  648. #endif
  649. /* if more buffer left check for MAC data */
  650. if (idx < totalSz) {
  651. if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
  652. WOLFSSL_MSG("Ignoring unknown data at end of PKCS12 DER buffer");
  653. }
  654. else {
  655. #ifdef WOLFSSL_DEBUG_PKCS12
  656. printf("\tSEQUENCE: Signature size = %d\n", size);
  657. #endif
  658. if ((ret = GetSignData(pkcs12, der, &idx, totalSz)) < 0) {
  659. return ASN_PARSE_E;
  660. }
  661. }
  662. }
  663. #ifdef WOLFSSL_DEBUG_PKCS12
  664. printf("END: PKCS12\n");
  665. #endif
  666. return ret;
  667. }
  668. #ifndef NO_FILESYSTEM
  669. /* Parse the DER-encoded PKCS #12 object in the provided file. Populate the
  670. * WC_PKCS12 object pointed to by the passed in pointer, allocating the object
  671. * if necessary.
  672. *
  673. * file : path to PKCS #12 file.
  674. * pkcs12: pointer to a pointer to a WC_PKCS12 object to populate. If *pkcs12 is
  675. * NULL, this function will allocate a new WC_PKCS12.
  676. * return 0 on success and negative on failure.
  677. */
  678. int wc_d2i_PKCS12_fp(const char* file, WC_PKCS12** pkcs12)
  679. {
  680. int ret = 0;
  681. byte* buf = NULL;
  682. size_t bufSz = 0;
  683. WC_PKCS12* tmpPkcs12 = NULL;
  684. int callerAlloc = 1;
  685. WOLFSSL_ENTER("wc_d2i_PKCS12_fp");
  686. if (pkcs12 == NULL) {
  687. WOLFSSL_MSG("pkcs12 parameter NULL.");
  688. ret = BAD_FUNC_ARG;
  689. }
  690. if (ret == 0)
  691. ret = wc_FileLoad(file, &buf, &bufSz, NULL);
  692. if (ret == 0) {
  693. if (*pkcs12 == NULL) {
  694. tmpPkcs12 = wc_PKCS12_new();
  695. if (tmpPkcs12 == NULL) {
  696. WOLFSSL_MSG("Failed to allocate PKCS12 object.");
  697. ret = MEMORY_E;
  698. }
  699. else {
  700. *pkcs12 = tmpPkcs12;
  701. callerAlloc = 0;
  702. }
  703. }
  704. }
  705. if (ret == 0) {
  706. ret = wc_d2i_PKCS12(buf, (word32)bufSz, *pkcs12);
  707. if (ret != 0) {
  708. WOLFSSL_MSG("wc_d2i_PKCS12 failed.");
  709. }
  710. }
  711. if (ret != 0 && callerAlloc == 0 && *pkcs12 != NULL) {
  712. wc_PKCS12_free(*pkcs12);
  713. *pkcs12 = NULL;
  714. }
  715. if (buf != NULL) {
  716. XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  717. }
  718. WOLFSSL_LEAVE("wc_d2i_PKCS12_fp", ret);
  719. return ret;
  720. }
  721. #endif /* NO_FILESYSTEM */
  722. /* Convert WC_PKCS12 struct to allocated DER buffer.
  723. * pkcs12 : non-null pkcs12 pointer
  724. * der : pointer-pointer to der buffer. If NULL space will be
  725. * allocated for der, which must be freed by application.
  726. * derSz : size of buffer passed in when der is not NULL. NULL arg disables
  727. * sanity checks on buffer read/writes. Max size gets set to derSz when
  728. * the "der" buffer passed in is NULL and LENGTH_ONLY_E is returned.
  729. * return size of DER on success and negative on failure.
  730. */
  731. int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz)
  732. {
  733. int ret = 0;
  734. word32 seqSz = 0, verSz = 0, totalSz = 0, idx = 0, sdBufSz = 0;
  735. byte *buf = NULL;
  736. byte ver[MAX_VERSION_SZ];
  737. byte seq[MAX_SEQ_SZ];
  738. byte *sdBuf = NULL;
  739. if ((pkcs12 == NULL) || (pkcs12->safe == NULL) ||
  740. (der == NULL && derSz == NULL)) {
  741. return BAD_FUNC_ARG;
  742. }
  743. /* Create the MAC portion */
  744. if (pkcs12->signData != NULL) {
  745. MacData *mac = (MacData*)pkcs12->signData;
  746. word32 innerSz = 0;
  747. word32 outerSz = 0;
  748. /* get exact size */
  749. {
  750. byte ASNLENGTH[MAX_LENGTH_SZ];
  751. byte ASNSHORT[MAX_SHORT_SZ];
  752. byte ASNALGO[MAX_ALGO_SZ];
  753. word32 tmpIdx = 0;
  754. /* algo id */
  755. innerSz += SetAlgoID((int)mac->oid, ASNALGO, oidHashType, 0);
  756. /* Octet string holding digest */
  757. innerSz += ASN_TAG_SZ;
  758. innerSz += SetLength(mac->digestSz, ASNLENGTH);
  759. innerSz += mac->digestSz;
  760. /* salt */
  761. outerSz += ASN_TAG_SZ;
  762. outerSz += SetLength(mac->saltSz, ASNLENGTH);
  763. outerSz += mac->saltSz;
  764. /* MAC iterations */
  765. ret = SetShortInt(ASNSHORT, &tmpIdx, (word32)mac->itt, MAX_SHORT_SZ);
  766. if (ret >= 0) {
  767. outerSz += (word32)ret;
  768. ret = 0;
  769. }
  770. else {
  771. return ret;
  772. }
  773. /* sequence of inner data */
  774. outerSz += SetSequence(innerSz, seq);
  775. outerSz += innerSz;
  776. }
  777. sdBufSz = outerSz + SetSequence(outerSz, seq);
  778. sdBuf = (byte*)XMALLOC(sdBufSz, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  779. if (sdBuf == NULL) {
  780. ret = MEMORY_E;
  781. }
  782. if (ret == 0) {
  783. idx += SetSequence(outerSz, sdBuf);
  784. idx += SetSequence(innerSz, &sdBuf[idx]);
  785. /* Set Algorithm Identifier */
  786. {
  787. word32 algoIdSz;
  788. algoIdSz = SetAlgoID((int)mac->oid, &sdBuf[idx], oidHashType, 0);
  789. if (algoIdSz == 0) {
  790. ret = ALGO_ID_E;
  791. }
  792. else {
  793. idx += algoIdSz;
  794. }
  795. }
  796. }
  797. if (ret == 0) {
  798. /* Octet string holding digest */
  799. idx += SetOctetString(mac->digestSz, &sdBuf[idx]);
  800. XMEMCPY(&sdBuf[idx], mac->digest, mac->digestSz);
  801. idx += mac->digestSz;
  802. /* Set salt */
  803. idx += SetOctetString(mac->saltSz, &sdBuf[idx]);
  804. XMEMCPY(&sdBuf[idx], mac->salt, mac->saltSz);
  805. idx += mac->saltSz;
  806. /* MAC iterations */
  807. {
  808. int tmpSz;
  809. word32 tmpIdx = 0;
  810. byte ar[MAX_SHORT_SZ];
  811. tmpSz = SetShortInt(ar, &tmpIdx, (word32)mac->itt, MAX_SHORT_SZ);
  812. if (tmpSz < 0) {
  813. ret = tmpSz;
  814. }
  815. else {
  816. XMEMCPY(&sdBuf[idx], ar, (size_t)tmpSz);
  817. }
  818. }
  819. totalSz += sdBufSz;
  820. }
  821. }
  822. /* Calculate size of der */
  823. if (ret == 0) {
  824. totalSz += pkcs12->safe->dataSz;
  825. totalSz += 4; /* Octet string */
  826. totalSz += 4; /* Element */
  827. totalSz += 2 + sizeof(WC_PKCS12_DATA_OID);
  828. totalSz += 4; /* Seq */
  829. ret = SetMyVersion(WC_PKCS12_VERSION_DEFAULT, ver, FALSE);
  830. if (ret > 0) {
  831. verSz = (word32)ret;
  832. ret = 0; /* value larger than 0 is success */
  833. totalSz += verSz;
  834. seqSz = SetSequence(totalSz, seq);
  835. totalSz += seqSz;
  836. /* check if getting length only */
  837. if (der == NULL && derSz != NULL) {
  838. *derSz = (int)totalSz;
  839. XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  840. return LENGTH_ONLY_E;
  841. }
  842. if (*der == NULL) {
  843. /* Allocate if requested */
  844. buf = (byte*)XMALLOC(totalSz, NULL, DYNAMIC_TYPE_PKCS);
  845. }
  846. else {
  847. buf = *der;
  848. /* sanity check on buffer size if passed in */
  849. if (derSz != NULL) {
  850. if (*derSz < (int)totalSz) {
  851. WOLFSSL_MSG("Buffer passed in is too small");
  852. ret = BUFFER_E;
  853. }
  854. }
  855. }
  856. }
  857. }
  858. if (buf == NULL) {
  859. ret = MEMORY_E;
  860. }
  861. if (ret == 0) {
  862. idx = 0;
  863. /* Copy parts to buf */
  864. XMEMCPY(&buf[idx], seq, seqSz);
  865. idx += seqSz;
  866. XMEMCPY(&buf[idx], ver, verSz);
  867. idx += verSz;
  868. seqSz = SetSequence(totalSz - sdBufSz - idx - 4, seq);
  869. XMEMCPY(&buf[idx], seq, seqSz);
  870. idx += seqSz;
  871. /* OID */
  872. idx += (word32)SetObjectId(sizeof(WC_PKCS12_DATA_OID), &buf[idx]);
  873. XMEMCPY(&buf[idx], WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
  874. idx += sizeof(WC_PKCS12_DATA_OID);
  875. /* Element */
  876. buf[idx++] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC;
  877. idx += SetLength(totalSz - sdBufSz - idx - 3, &buf[idx]);
  878. /* Octet string */
  879. idx += SetOctetString(totalSz - sdBufSz - idx - 4, &buf[idx]);
  880. XMEMCPY(&buf[idx], pkcs12->safe->data, pkcs12->safe->dataSz);
  881. idx += pkcs12->safe->dataSz;
  882. if (pkcs12->signData != NULL) {
  883. XMEMCPY(&buf[idx], sdBuf, sdBufSz);
  884. }
  885. if (*der == NULL) {
  886. /* Point to start of data allocated for DER */
  887. *der = buf;
  888. }
  889. else {
  890. /* Increment pointer to byte past DER */
  891. *der = &buf[totalSz];
  892. }
  893. /* Return size of der */
  894. ret = (int)totalSz;
  895. }
  896. XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  897. /* Allocation of buf was the last time ret could be a failure,
  898. * so no need to free here */
  899. return ret;
  900. }
  901. /* helper function to free WC_DerCertList */
  902. void wc_FreeCertList(WC_DerCertList* list, void* heap)
  903. {
  904. WC_DerCertList* current = list;
  905. WC_DerCertList* next;
  906. if (list == NULL) {
  907. return;
  908. }
  909. while (current != NULL) {
  910. next = current->next;
  911. if (current->buffer != NULL) {
  912. XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
  913. }
  914. XFREE(current, heap, DYNAMIC_TYPE_PKCS);
  915. current = next;
  916. }
  917. (void)heap;
  918. }
  919. static WARN_UNUSED_RESULT int freeDecCertList(WC_DerCertList** list,
  920. byte** pkey, word32* pkeySz, byte** cert, word32* certSz, void* heap)
  921. {
  922. WC_DerCertList* current = *list;
  923. WC_DerCertList* previous = NULL;
  924. #ifdef WOLFSSL_SMALL_STACK
  925. DecodedCert *DeCert = (DecodedCert *)XMALLOC(
  926. sizeof(*DeCert), heap, DYNAMIC_TYPE_PKCS);
  927. if (DeCert == NULL)
  928. return MEMORY_E;
  929. #else
  930. DecodedCert DeCert[1];
  931. #endif
  932. while (current != NULL) {
  933. InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
  934. if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
  935. if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert) == 1) {
  936. WOLFSSL_MSG("Key Pair found");
  937. *cert = current->buffer;
  938. *certSz = current->bufferSz;
  939. if (previous == NULL) {
  940. *list = current->next;
  941. }
  942. else {
  943. previous->next = current->next;
  944. }
  945. FreeDecodedCert(DeCert);
  946. XFREE(current, heap, DYNAMIC_TYPE_PKCS);
  947. break;
  948. }
  949. }
  950. FreeDecodedCert(DeCert);
  951. previous = current;
  952. current = current->next;
  953. }
  954. #ifdef WOLFSSL_SMALL_STACK
  955. XFREE(DeCert, heap, DYNAMIC_TYPE_PKCS);
  956. #endif
  957. return 0;
  958. }
  959. #ifdef ASN_BER_TO_DER
  960. /* append data to encrypted content cache in PKCS12 structure
  961. * return buffer on success, NULL on error */
  962. static byte* PKCS12_ConcatonateContent(WC_PKCS12* pkcs12,byte* mergedData,
  963. word32* mergedSz, byte* in, word32 inSz)
  964. {
  965. byte* oldContent;
  966. word32 oldContentSz;
  967. (void)pkcs12;
  968. if (mergedData == NULL || in == NULL)
  969. return NULL;
  970. /* save pointer to old cache */
  971. oldContent = mergedData;
  972. oldContentSz = *mergedSz;
  973. /* re-allocate new buffer to fit appended data */
  974. mergedData = (byte*)XMALLOC(oldContentSz + inSz, pkcs12->heap,
  975. DYNAMIC_TYPE_PKCS);
  976. if (mergedData != NULL) {
  977. if (oldContent != NULL) {
  978. XMEMCPY(mergedData, oldContent, oldContentSz);
  979. }
  980. XMEMCPY(mergedData + oldContentSz, in, inSz);
  981. *mergedSz += inSz;
  982. }
  983. XFREE(oldContent, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  984. return mergedData;
  985. }
  986. /* Check if constructed [0] is seen after wc_BerToDer() or not.
  987. * returns 1 if seen, 0 if not, ASN_PARSE_E on error */
  988. static int PKCS12_CheckConstructedZero(byte* data, word32 dataSz, word32* idx)
  989. {
  990. word32 oid;
  991. int ret = 0;
  992. int number, size;
  993. byte tag = 0;
  994. if (GetSequence(data, idx, &size, dataSz) < 0) {
  995. ret = ASN_PARSE_E;
  996. }
  997. if (ret == 0 && GetObjectId(data, idx, &oid, oidIgnoreType, dataSz)) {
  998. ret = ASN_PARSE_E;
  999. }
  1000. if (ret == 0 && GetSequence(data, idx, &size, dataSz) < 0) {
  1001. ret = ASN_PARSE_E;
  1002. }
  1003. if (ret == 0 && GetOctetString(data, idx, &size, dataSz) < 0) {
  1004. ret = ASN_PARSE_E;
  1005. }
  1006. *idx += (word32)size;
  1007. if (ret == 0 && GetShortInt(data, idx, &number, dataSz) < 0) {
  1008. ret = ASN_PARSE_E;
  1009. }
  1010. /* Check if wc_BerToDer() handled constructed [0] and octet
  1011. * strings properly, manually fix it if not. */
  1012. if (ret == 0 && GetASNTag(data, idx, &tag, dataSz) < 0) {
  1013. ret = ASN_PARSE_E;
  1014. }
  1015. else if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1016. ret = 1;
  1017. }
  1018. return ret;
  1019. }
  1020. /* Manually coalesce definite length octet strings into one unconstructed
  1021. * definite length octet string.
  1022. * returns 0 on success, negative on failure */
  1023. static int PKCS12_CoalesceOctetStrings(WC_PKCS12* pkcs12, byte* data,
  1024. word32 dataSz, word32* idx, int* curIdx)
  1025. {
  1026. byte* mergedData = NULL; /* buffer for concatenated strings */
  1027. word32 mergedSz = 0; /* total size of merged strings */
  1028. int encryptedContentSz = 0;
  1029. int originalEncSz = 0;
  1030. int ret = 0;
  1031. word32 saveIdx;
  1032. byte tag;
  1033. saveIdx = *idx;
  1034. if (GetLength(data, idx, &originalEncSz, dataSz) < 0) {
  1035. ret = ASN_PARSE_E;
  1036. }
  1037. /* Loop through octet strings and concatenate them without
  1038. * the tags and length */
  1039. while ((int)*idx < originalEncSz + *curIdx) {
  1040. if (GetASNTag(data, idx, &tag, dataSz) < 0) {
  1041. ret = ASN_PARSE_E;
  1042. }
  1043. if (ret == 0 && (tag != ASN_OCTET_STRING)) {
  1044. ret = ASN_PARSE_E;
  1045. }
  1046. if (ret == 0 && GetLength(data, idx,
  1047. &encryptedContentSz, dataSz) <= 0) {
  1048. ret = ASN_PARSE_E;
  1049. }
  1050. if (ret == 0) {
  1051. if (mergedData == NULL) {
  1052. mergedData = (byte*)XMALLOC((size_t)encryptedContentSz,
  1053. pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1054. if (mergedData == NULL) {
  1055. ret = MEMORY_E;
  1056. }
  1057. }
  1058. mergedData = PKCS12_ConcatonateContent(pkcs12, mergedData,
  1059. &mergedSz, &data[*idx], (word32)encryptedContentSz);
  1060. if (mergedData == NULL) {
  1061. ret = MEMORY_E;
  1062. }
  1063. }
  1064. if (ret != 0) {
  1065. break;
  1066. }
  1067. *idx += (word32)encryptedContentSz;
  1068. }
  1069. *idx = saveIdx;
  1070. *idx += SetLength(mergedSz, &data[*idx]);
  1071. if (mergedSz > 0) {
  1072. /* Copy over concatenated octet strings into data buffer */
  1073. XMEMCPY(&data[*idx], mergedData, mergedSz);
  1074. XFREE(mergedData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1075. }
  1076. return ret;
  1077. }
  1078. #endif
  1079. /* return 0 on success and negative on failure.
  1080. * By side effect returns private key, cert, and optionally ca.
  1081. * Parses and decodes the parts of PKCS12
  1082. *
  1083. * NOTE: can parse with USER RSA enabled but may return cert that is not the
  1084. * pair for the key when using RSA key pairs.
  1085. *
  1086. * pkcs12 : non-null WC_PKCS12 struct
  1087. * psw : password to use for PKCS12 decode
  1088. * pkey : Private key returned
  1089. * cert : x509 cert returned
  1090. * ca : optional ca returned
  1091. */
  1092. int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
  1093. byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
  1094. WC_DerCertList** ca)
  1095. {
  1096. ContentInfo* ci = NULL;
  1097. WC_DerCertList* certList = NULL;
  1098. WC_DerCertList* tailList = NULL;
  1099. byte* buf = NULL;
  1100. word32 i, oid;
  1101. word32 algId;
  1102. int ret, pswSz;
  1103. #ifdef ASN_BER_TO_DER
  1104. int curIdx;
  1105. #endif
  1106. WOLFSSL_ENTER("wc_PKCS12_parse");
  1107. if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||
  1108. pkey == NULL || pkeySz == NULL) {
  1109. return BAD_FUNC_ARG;
  1110. }
  1111. pswSz = (int)XSTRLEN(psw);
  1112. *cert = NULL;
  1113. *pkey = NULL;
  1114. if (ca != NULL)
  1115. *ca = NULL;
  1116. /* if there is sign data then verify the MAC */
  1117. if (pkcs12->signData != NULL ) {
  1118. if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,
  1119. pkcs12->safe->dataSz, (byte*)psw, (word32)pswSz)) != 0) {
  1120. WOLFSSL_MSG("PKCS12 Bad MAC on verify");
  1121. WOLFSSL_LEAVE("wc_PKCS12_parse verify ", ret);
  1122. (void)ret;
  1123. return MAC_CMP_FAILED_E;
  1124. }
  1125. }
  1126. if (pkcs12->safe == NULL) {
  1127. WOLFSSL_MSG("No PKCS12 safes to parse");
  1128. return BAD_FUNC_ARG;
  1129. }
  1130. /* Decode content infos */
  1131. ci = pkcs12->safe->CI;
  1132. for (i = 0; i < pkcs12->safe->numCI; i++) {
  1133. byte* data;
  1134. word32 idx = 0;
  1135. int size, totalSz;
  1136. byte tag;
  1137. data = ci->data;
  1138. if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
  1139. int number;
  1140. WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
  1141. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1142. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1143. }
  1144. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1145. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1146. }
  1147. if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
  1148. goto exit_pk12par;
  1149. }
  1150. if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
  1151. goto exit_pk12par;
  1152. }
  1153. if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {
  1154. goto exit_pk12par;
  1155. }
  1156. if (number != 0) {
  1157. WOLFSSL_MSG("Expecting 0 for Integer with Encrypted PKCS12");
  1158. }
  1159. if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
  1160. goto exit_pk12par;
  1161. }
  1162. ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);
  1163. if (ret < 0 || oid != WC_PKCS12_DATA) {
  1164. WOLFSSL_MSG("Not PKCS12 DATA object or get object parse error");
  1165. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1166. }
  1167. #ifdef ASN_BER_TO_DER
  1168. curIdx = (int)idx;
  1169. /* If indefinite length format, ensure it is in the ASN format
  1170. * the DecryptContent() expects */
  1171. if (pkcs12->indefinite && PKCS12_CheckConstructedZero(data,
  1172. ci->dataSz, &idx) == 1) {
  1173. data[idx-1] = ASN_LONG_LENGTH;
  1174. ret = PKCS12_CoalesceOctetStrings(pkcs12, data, ci->dataSz,
  1175. &idx, &curIdx);
  1176. if (ret < 0) {
  1177. goto exit_pk12par;
  1178. }
  1179. }
  1180. idx = (word32)curIdx;
  1181. #endif
  1182. /* decrypted content overwrites input buffer */
  1183. size = (int)(ci->dataSz - idx);
  1184. buf = (byte*)XMALLOC((size_t)size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1185. if (buf == NULL) {
  1186. ERROR_OUT(MEMORY_E, exit_pk12par);
  1187. }
  1188. XMEMCPY(buf, data + idx, (size_t)size);
  1189. if ((ret = DecryptContent(buf, (word32)size, psw, pswSz)) < 0) {
  1190. WOLFSSL_MSG("Decryption failed, algorithm not compiled in?");
  1191. goto exit_pk12par;
  1192. }
  1193. data = buf;
  1194. idx = 0;
  1195. #ifdef WOLFSSL_DEBUG_PKCS12
  1196. {
  1197. byte* p;
  1198. for (printf("\tData = "), p = (byte*)buf;
  1199. p < (byte*)buf + size;
  1200. printf("%02X", *p), p++);
  1201. printf("\n");
  1202. }
  1203. #endif
  1204. }
  1205. else { /* type DATA */
  1206. WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
  1207. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1208. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1209. }
  1210. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1211. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1212. }
  1213. if (GetLength(data, &idx, &size, ci->dataSz) <= 0) {
  1214. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1215. }
  1216. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1217. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1218. }
  1219. if (tag != ASN_OCTET_STRING) {
  1220. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1221. }
  1222. if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
  1223. goto exit_pk12par;
  1224. }
  1225. }
  1226. /* parse through bags in ContentInfo */
  1227. if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {
  1228. goto exit_pk12par;
  1229. }
  1230. totalSz += (int)idx;
  1231. while ((int)idx < totalSz) {
  1232. int bagSz;
  1233. if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {
  1234. goto exit_pk12par;
  1235. }
  1236. bagSz += (int)idx;
  1237. if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
  1238. ci->dataSz)) < 0) {
  1239. goto exit_pk12par;
  1240. }
  1241. switch (oid) {
  1242. case WC_PKCS12_KeyBag: /* 667 */
  1243. WOLFSSL_MSG("PKCS12 Key Bag found");
  1244. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1245. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1246. }
  1247. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1248. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1249. }
  1250. if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
  1251. if (ret == 0)
  1252. ret = ASN_PARSE_E;
  1253. goto exit_pk12par;
  1254. }
  1255. if (*pkey == NULL) {
  1256. *pkey = (byte*)XMALLOC((size_t)size, pkcs12->heap,
  1257. DYNAMIC_TYPE_PUBLIC_KEY);
  1258. if (*pkey == NULL) {
  1259. ERROR_OUT(MEMORY_E, exit_pk12par);
  1260. }
  1261. XMEMCPY(*pkey, data + idx, (size_t)size);
  1262. *pkeySz = (word32)ToTraditional_ex(*pkey, (word32)size, &algId);
  1263. }
  1264. #ifdef WOLFSSL_DEBUG_PKCS12
  1265. {
  1266. byte* p;
  1267. for (printf("\tKey = "), p = (byte*)*pkey;
  1268. p < (byte*)*pkey + size;
  1269. printf("%02X", *p), p++);
  1270. printf("\n");
  1271. }
  1272. #endif
  1273. idx += (word32)size;
  1274. break;
  1275. case WC_PKCS12_ShroudedKeyBag: /* 668 */
  1276. {
  1277. byte* k;
  1278. WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
  1279. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1280. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1281. }
  1282. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1283. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1284. }
  1285. if ((ret = GetLength(data, &idx, &size,
  1286. ci->dataSz)) < 0) {
  1287. goto exit_pk12par;
  1288. }
  1289. k = (byte*)XMALLOC((size_t)size, pkcs12->heap,
  1290. DYNAMIC_TYPE_PUBLIC_KEY);
  1291. if (k == NULL) {
  1292. ERROR_OUT(MEMORY_E, exit_pk12par);
  1293. }
  1294. XMEMCPY(k, data + idx, (size_t)size);
  1295. /* overwrites input, be warned */
  1296. if ((ret = ToTraditionalEnc(k, (word32)size, psw, pswSz,
  1297. &algId)) < 0) {
  1298. XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1299. goto exit_pk12par;
  1300. }
  1301. if (ret < size) {
  1302. /* shrink key buffer */
  1303. byte* tmp = (byte*)XMALLOC((size_t)ret, pkcs12->heap,
  1304. DYNAMIC_TYPE_PUBLIC_KEY);
  1305. if (tmp == NULL) {
  1306. XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1307. ERROR_OUT(MEMORY_E, exit_pk12par);
  1308. }
  1309. XMEMCPY(tmp, k, (size_t)ret);
  1310. XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1311. k = tmp;
  1312. }
  1313. size = ret;
  1314. if (*pkey == NULL) {
  1315. *pkey = k;
  1316. *pkeySz = (word32)size;
  1317. }
  1318. else { /* only expecting one key */
  1319. XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1320. }
  1321. idx += (word32)size;
  1322. #ifdef WOLFSSL_DEBUG_PKCS12
  1323. {
  1324. byte* p;
  1325. for (printf("\tKey = "), p = (byte*)k;
  1326. p < (byte*)k + ret;
  1327. printf("%02X", *p), p++);
  1328. printf("\n");
  1329. }
  1330. #endif
  1331. }
  1332. break;
  1333. case WC_PKCS12_CertBag: /* 669 */
  1334. {
  1335. WC_DerCertList* node;
  1336. WOLFSSL_MSG("PKCS12 Cert Bag found");
  1337. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1338. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1339. }
  1340. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
  1341. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1342. }
  1343. if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
  1344. goto exit_pk12par;
  1345. }
  1346. /* get cert bag type */
  1347. if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {
  1348. goto exit_pk12par;
  1349. }
  1350. if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
  1351. ci->dataSz)) < 0) {
  1352. goto exit_pk12par;
  1353. }
  1354. switch (oid) {
  1355. case WC_PKCS12_CertBag_Type1: /* 675 */
  1356. /* type 1 */
  1357. WOLFSSL_MSG("PKCS12 cert bag type 1");
  1358. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1359. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1360. }
  1361. if (tag != (ASN_CONSTRUCTED |
  1362. ASN_CONTEXT_SPECIFIC)) {
  1363. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1364. }
  1365. if ((ret = GetLength(data, &idx, &size, ci->dataSz))
  1366. <= 0) {
  1367. if (ret == 0)
  1368. ret = ASN_PARSE_E;
  1369. goto exit_pk12par;
  1370. }
  1371. if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
  1372. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1373. }
  1374. if (tag != ASN_OCTET_STRING) {
  1375. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1376. }
  1377. if ((ret = GetLength(data, &idx, &size, ci->dataSz))
  1378. < 0) {
  1379. goto exit_pk12par;
  1380. }
  1381. break;
  1382. default:
  1383. WOLFSSL_MSG("Unknown PKCS12 cert bag type");
  1384. }
  1385. if (size + (int)idx > bagSz) {
  1386. ERROR_OUT(ASN_PARSE_E, exit_pk12par);
  1387. }
  1388. /* list to hold all certs found */
  1389. node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
  1390. pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1391. if (node == NULL) {
  1392. ERROR_OUT(MEMORY_E, exit_pk12par);
  1393. }
  1394. XMEMSET(node, 0, sizeof(WC_DerCertList));
  1395. node->buffer = (byte*)XMALLOC((size_t)size, pkcs12->heap,
  1396. DYNAMIC_TYPE_PKCS);
  1397. if (node->buffer == NULL) {
  1398. XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1399. ERROR_OUT(MEMORY_E, exit_pk12par);
  1400. }
  1401. XMEMCPY(node->buffer, data + idx, (size_t)size);
  1402. node->bufferSz = (word32)size;
  1403. /* put the new node into the list */
  1404. if (certList != NULL) {
  1405. WOLFSSL_MSG("Pushing new cert onto queue");
  1406. tailList->next = node;
  1407. tailList = node;
  1408. }
  1409. else {
  1410. certList = node;
  1411. tailList = node;
  1412. }
  1413. /* on to next */
  1414. idx += (word32)size;
  1415. }
  1416. break;
  1417. case WC_PKCS12_CrlBag: /* 670 */
  1418. WOLFSSL_MSG("PKCS12 CRL BAG not yet supported");
  1419. break;
  1420. case WC_PKCS12_SecretBag: /* 671 */
  1421. WOLFSSL_MSG("PKCS12 Secret BAG not yet supported");
  1422. break;
  1423. case WC_PKCS12_SafeContentsBag: /* 672 */
  1424. WOLFSSL_MSG("PKCS12 Safe Contents BAG not yet supported");
  1425. break;
  1426. default:
  1427. WOLFSSL_MSG("Unknown PKCS12 BAG type found");
  1428. }
  1429. /* Attribute, unknown bag or unsupported */
  1430. if ((int)idx < bagSz) {
  1431. idx = (word32)bagSz; /* skip for now */
  1432. }
  1433. }
  1434. /* free temporary buffer */
  1435. if (buf != NULL) {
  1436. XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1437. buf = NULL;
  1438. }
  1439. ci = ci->next;
  1440. WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container");
  1441. }
  1442. /* check if key pair, remove from list */
  1443. if (*pkey != NULL) {
  1444. ret = freeDecCertList(&certList, pkey, pkeySz, cert, certSz,
  1445. pkcs12->heap);
  1446. if (ret < 0)
  1447. goto exit_pk12par;
  1448. }
  1449. /* if ca arg provided return certList, otherwise free it */
  1450. if (ca != NULL) {
  1451. *ca = certList;
  1452. }
  1453. else {
  1454. /* free list, not wanted */
  1455. wc_FreeCertList(certList, pkcs12->heap);
  1456. }
  1457. (void)tailList; /* not used */
  1458. ret = 0; /* success */
  1459. exit_pk12par:
  1460. if (ret != 0) {
  1461. /* failure cleanup */
  1462. if (*pkey) {
  1463. XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
  1464. *pkey = NULL;
  1465. }
  1466. if (buf) {
  1467. XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  1468. buf = NULL;
  1469. }
  1470. wc_FreeCertList(certList, pkcs12->heap);
  1471. }
  1472. return ret;
  1473. }
  1474. /* Helper function to shroud keys.
  1475. *
  1476. * pkcs12 structure to use with shrouding key
  1477. * rng random number generator used
  1478. * out buffer to hold results
  1479. * outSz size of out buffer
  1480. * key key that is going to be shrouded
  1481. * keySz size of key buffer
  1482. * vAlgo algorithm version
  1483. * pass password to use
  1484. * passSz size of pass buffer
  1485. * itt number of iterations
  1486. *
  1487. * returns the size of the shrouded key on success
  1488. */
  1489. static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng,
  1490. byte* out, word32* outSz, byte* key, word32 keySz, int vAlgo,
  1491. const char* pass, int passSz, int itt)
  1492. {
  1493. void* heap;
  1494. word32 tmpIdx = 0;
  1495. int vPKCS = 1; /* PKCS#12 default set to 1 */
  1496. word32 sz;
  1497. word32 totalSz = 0;
  1498. int ret;
  1499. byte* pkcs8Key = NULL;
  1500. if (outSz == NULL || pkcs12 == NULL || rng == NULL || key == NULL ||
  1501. pass == NULL) {
  1502. return BAD_FUNC_ARG;
  1503. }
  1504. heap = wc_PKCS12_GetHeap(pkcs12);
  1505. /* check if trying to get size */
  1506. if (out != NULL) {
  1507. tmpIdx += MAX_LENGTH_SZ + 1; /* save room for length and tag (+1) */
  1508. sz = *outSz - tmpIdx;
  1509. pkcs8Key = out + tmpIdx;
  1510. }
  1511. /* case of no encryption */
  1512. if (vAlgo < 0) {
  1513. const byte* curveOID = NULL;
  1514. word32 oidSz = 0;
  1515. int algoID;
  1516. WOLFSSL_MSG("creating PKCS12 Key Bag");
  1517. /* check key type and get OID if ECC */
  1518. if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))
  1519. < 0) {
  1520. return ret;
  1521. }
  1522. /* PKCS#8 wrapping around key */
  1523. ret = wc_CreatePKCS8Key(pkcs8Key, &sz, key, keySz, algoID, curveOID,
  1524. oidSz);
  1525. }
  1526. else {
  1527. WOLFSSL_MSG("creating PKCS12 Shrouded Key Bag");
  1528. if (vAlgo == PBE_SHA1_DES) {
  1529. vPKCS = PKCS5;
  1530. vAlgo = 10;
  1531. }
  1532. ret = UnTraditionalEnc(key, keySz, pkcs8Key, &sz, pass, passSz,
  1533. vPKCS, vAlgo, NULL, 0, itt, rng, heap);
  1534. }
  1535. if (ret == LENGTH_ONLY_E) {
  1536. *outSz = sz + MAX_LENGTH_SZ + 1;
  1537. return LENGTH_ONLY_E;
  1538. }
  1539. if (ret < 0) {
  1540. return ret;
  1541. }
  1542. totalSz += (word32)ret;
  1543. /* out should not be null at this point but check before writing */
  1544. if (out == NULL) {
  1545. return BAD_FUNC_ARG;
  1546. }
  1547. /* rewind index and set tag and length */
  1548. tmpIdx -= MAX_LENGTH_SZ + 1;
  1549. sz = (word32)SetExplicit(0, (word32)ret, out + tmpIdx);
  1550. tmpIdx += sz; totalSz += sz;
  1551. XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, (size_t)ret);
  1552. return (int)totalSz;
  1553. }
  1554. /* Helper function to create key bag.
  1555. *
  1556. * pkcs12 structure to use with key bag
  1557. * rng random number generator used
  1558. * out buffer to hold results
  1559. * outSz size of out buffer
  1560. * key key that is going into key bag
  1561. * keySz size of key buffer
  1562. * algo algorithm version
  1563. * iter number of iterations
  1564. * pass password to use
  1565. * passSz size of pass buffer
  1566. *
  1567. * returns the size of the key bag on success
  1568. */
  1569. static int wc_PKCS12_create_key_bag(WC_PKCS12* pkcs12, WC_RNG* rng,
  1570. byte* out, word32* outSz, byte* key, word32 keySz, int algo, int iter,
  1571. char* pass, int passSz)
  1572. {
  1573. void* heap;
  1574. byte* tmp;
  1575. word32 length = 0;
  1576. word32 idx = 0;
  1577. word32 totalSz = 0;
  1578. word32 sz;
  1579. word32 i;
  1580. word32 tmpSz;
  1581. int ret;
  1582. /* get max size for shrouded key */
  1583. ret = wc_PKCS12_shroud_key(pkcs12, rng, NULL, &length, key, keySz,
  1584. algo, pass, passSz, iter);
  1585. if (ret != LENGTH_ONLY_E && ret < 0) {
  1586. return ret;
  1587. }
  1588. if (out == NULL) {
  1589. *outSz = MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + 1 + MAX_LENGTH_SZ +
  1590. length;
  1591. return LENGTH_ONLY_E;
  1592. }
  1593. heap = wc_PKCS12_GetHeap(pkcs12);
  1594. /* leave room for sequence */
  1595. idx += MAX_SEQ_SZ;
  1596. if (algo < 0) { /* not encrypted */
  1597. out[idx++] = ASN_OBJECT_ID; totalSz++;
  1598. sz = SetLength(sizeof(WC_PKCS12_KeyBag_OID), out + idx);
  1599. idx += sz; totalSz += sz;
  1600. for (i = 0; i < sizeof(WC_PKCS12_KeyBag_OID); i++) {
  1601. out[idx++] = WC_PKCS12_KeyBag_OID[i]; totalSz++;
  1602. }
  1603. }
  1604. else { /* encrypted */
  1605. out[idx++] = ASN_OBJECT_ID; totalSz++;
  1606. sz = SetLength(sizeof(WC_PKCS12_ShroudedKeyBag_OID), out + idx);
  1607. idx += sz; totalSz += sz;
  1608. for (i = 0; i < sizeof(WC_PKCS12_ShroudedKeyBag_OID); i++) {
  1609. out[idx++] = WC_PKCS12_ShroudedKeyBag_OID[i]; totalSz++;
  1610. }
  1611. }
  1612. /* shroud key */
  1613. tmp = (byte*)XMALLOC(length, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1614. if (tmp == NULL) {
  1615. return MEMORY_E;
  1616. }
  1617. ret = wc_PKCS12_shroud_key(pkcs12, rng, tmp, &length, key, keySz,
  1618. algo, pass, passSz, iter);
  1619. if (ret < 0) {
  1620. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1621. return ret;
  1622. }
  1623. length = (word32)ret;
  1624. XMEMCPY(out + idx, tmp, (size_t)length);
  1625. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1626. totalSz += length;
  1627. /* set beginning sequence */
  1628. tmpSz = SetSequence(totalSz, out);
  1629. XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
  1630. (void)heap;
  1631. return (int)(totalSz + tmpSz);
  1632. }
  1633. /* Helper function to create cert bag.
  1634. *
  1635. * pkcs12 structure to use with cert bag
  1636. * out buffer to hold results
  1637. * outSz size of out buffer
  1638. * cert cert that is going into cert bag
  1639. * certSz size of cert buffer
  1640. *
  1641. * returns the size of the cert bag on success
  1642. */
  1643. static int wc_PKCS12_create_cert_bag(WC_PKCS12* pkcs12,
  1644. byte* out, word32* outSz, byte* cert, word32 certSz)
  1645. {
  1646. word32 length = 0;
  1647. word32 idx = 0;
  1648. word32 totalSz = 0;
  1649. word32 sz;
  1650. int WC_CERTBAG_OBJECT_ID = 13;
  1651. int WC_CERTBAG1_OBJECT_ID = 12;
  1652. word32 i;
  1653. word32 tmpSz;
  1654. if (out == NULL) {
  1655. *outSz = (word32)(MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
  1656. MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
  1657. MAX_LENGTH_SZ + (int)certSz);
  1658. return LENGTH_ONLY_E;
  1659. }
  1660. /* check buffer size able to handle max size */
  1661. if (*outSz < (word32)(MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
  1662. MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
  1663. MAX_LENGTH_SZ + (int)certSz)) {
  1664. return BUFFER_E;
  1665. }
  1666. /* save room for sequence */
  1667. idx += MAX_SEQ_SZ;
  1668. /* objectId WC_PKCS12_CertBag */
  1669. out[idx++] = ASN_OBJECT_ID; totalSz++;
  1670. sz = SetLength(sizeof(WC_PKCS12_CertBag_OID), out + idx);
  1671. idx += sz; totalSz += sz;
  1672. for (i = 0; i < sizeof(WC_PKCS12_CertBag_OID); i++) {
  1673. out[idx++] = WC_PKCS12_CertBag_OID[i]; totalSz++;
  1674. }
  1675. /**** Cert Bag type 1 ****/
  1676. out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;
  1677. /* save room for length and sequence */
  1678. idx += MAX_LENGTH_SZ;
  1679. idx += MAX_SEQ_SZ;
  1680. /* object id WC_PKCS12_CertBag_Type1 */
  1681. out[idx++] = ASN_OBJECT_ID; length++;
  1682. sz = SetLength(sizeof(WC_PKCS12_CertBag_Type1_OID), out + idx);
  1683. idx += sz; length += sz;
  1684. for (i = 0; i < sizeof(WC_PKCS12_CertBag_Type1_OID); i++) {
  1685. out[idx++] = WC_PKCS12_CertBag_Type1_OID[i]; length++;
  1686. }
  1687. out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); length++;
  1688. sz = 0;
  1689. idx += MAX_LENGTH_SZ; /* save room for length */
  1690. /* place the cert in the buffer */
  1691. out[idx++] = ASN_OCTET_STRING; sz++;
  1692. tmpSz = SetLength(certSz, out + idx);
  1693. idx += tmpSz; sz += tmpSz;
  1694. XMEMCPY(out + idx, cert, certSz);
  1695. idx += certSz; sz += certSz;
  1696. /* rewind idx and place length */
  1697. idx -= (sz + MAX_LENGTH_SZ);
  1698. tmpSz = SetLength(sz, out + idx);
  1699. XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, sz);
  1700. idx += tmpSz + sz; length += tmpSz + sz;
  1701. /* rewind idx and set sequence */
  1702. idx -= (length + MAX_SEQ_SZ);
  1703. tmpSz = SetSequence(length, out + idx);
  1704. XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);
  1705. length += tmpSz;
  1706. /* place final length */
  1707. idx -= MAX_LENGTH_SZ;
  1708. tmpSz = SetLength(length, out + idx);
  1709. XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);
  1710. length += tmpSz;
  1711. /* place final sequence */
  1712. totalSz += length;
  1713. tmpSz = SetSequence(totalSz, out);
  1714. XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
  1715. (void)pkcs12;
  1716. return (int)(totalSz + tmpSz);
  1717. }
  1718. /* Helper function to encrypt content.
  1719. *
  1720. * pkcs12 structure to use with key bag
  1721. * rng random number generator used
  1722. * out buffer to hold results
  1723. * outSz size of out buffer
  1724. * content content to encrypt
  1725. * contentSz size of content buffer
  1726. * vAlgo algorithm version
  1727. * pass password to use
  1728. * passSz size of pass buffer
  1729. * iter number of iterations
  1730. * type content type i.e WC_PKCS12_ENCRYPTED_DATA or WC_PKCS12_DATA
  1731. *
  1732. * returns the size of result on success
  1733. */
  1734. static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng,
  1735. byte* out, word32* outSz, byte* content, word32 contentSz, int vAlgo,
  1736. const char* pass, int passSz, int iter, int type)
  1737. {
  1738. void* heap;
  1739. int vPKCS = 1; /* PKCS#12 is always set to 1 */
  1740. int ret;
  1741. byte* tmp;
  1742. word32 idx = 0;
  1743. word32 totalSz = 0;
  1744. word32 length = 0;
  1745. word32 tmpSz;
  1746. word32 encSz;
  1747. byte seq[MAX_SEQ_SZ];
  1748. WOLFSSL_MSG("encrypting PKCS12 content");
  1749. heap = wc_PKCS12_GetHeap(pkcs12);
  1750. /* ENCRYPTED DATA
  1751. * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
  1752. * length
  1753. * sequence
  1754. * short int
  1755. * sequence
  1756. * get object id */
  1757. if (type == WC_PKCS12_ENCRYPTED_DATA) {
  1758. word32 outerSz = 0;
  1759. encSz = contentSz;
  1760. if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz,
  1761. pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
  1762. if (ret != LENGTH_ONLY_E) {
  1763. return ret;
  1764. }
  1765. }
  1766. /* calculate size */
  1767. totalSz = (word32)SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), seq);
  1768. totalSz += sizeof(WC_PKCS12_ENCRYPTED_OID);
  1769. totalSz += ASN_TAG_SZ;
  1770. length = (word32)SetMyVersion(0, seq, 0);
  1771. tmpSz = (word32)SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq);
  1772. tmpSz += sizeof(WC_PKCS12_DATA_OID);
  1773. tmpSz += encSz;
  1774. length += SetSequence(tmpSz, seq) + tmpSz;
  1775. outerSz = SetSequence(length, seq) + length;
  1776. totalSz += SetLength(outerSz, seq) + outerSz;
  1777. if (out == NULL) {
  1778. *outSz = totalSz + SetSequence(totalSz, seq);
  1779. return LENGTH_ONLY_E;
  1780. }
  1781. if (*outSz < totalSz + SetSequence(totalSz, seq)) {
  1782. return BUFFER_E;
  1783. }
  1784. idx = 0;
  1785. idx += SetSequence(totalSz, out + idx);
  1786. idx += (word32)SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), out + idx);
  1787. if (idx + sizeof(WC_PKCS12_ENCRYPTED_OID) > *outSz){
  1788. return BUFFER_E;
  1789. }
  1790. XMEMCPY(out + idx, WC_PKCS12_ENCRYPTED_OID,
  1791. sizeof(WC_PKCS12_ENCRYPTED_OID));
  1792. idx += sizeof(WC_PKCS12_ENCRYPTED_OID);
  1793. if (idx + 1 > *outSz){
  1794. return BUFFER_E;
  1795. }
  1796. out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);
  1797. idx += SetLength(outerSz, out + idx);
  1798. idx += SetSequence(length, out + idx);
  1799. idx += (word32)SetMyVersion(0, out + idx, 0);
  1800. tmp = (byte*)XMALLOC(encSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1801. if (tmp == NULL) {
  1802. return MEMORY_E;
  1803. }
  1804. if ((ret = EncryptContent(content, contentSz, tmp, &encSz,
  1805. pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
  1806. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1807. return ret;
  1808. }
  1809. encSz = (word32)ret;
  1810. #ifdef WOLFSSL_DEBUG_PKCS12
  1811. {
  1812. byte* p;
  1813. for (printf("(size %u) Encrypted Content = ", encSz),
  1814. p = (byte*)tmp;
  1815. p < (byte*)tmp + encSz;
  1816. printf("%02X", *p), p++);
  1817. printf("\n");
  1818. }
  1819. #endif
  1820. idx += SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx);
  1821. idx += (word32)SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx);
  1822. if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){
  1823. WOLFSSL_MSG("Buffer not large enough for DATA OID");
  1824. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1825. return BUFFER_E;
  1826. }
  1827. XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
  1828. idx += sizeof(WC_PKCS12_DATA_OID);
  1829. /* copy over encrypted data */
  1830. if (idx + encSz > *outSz){
  1831. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1832. return BUFFER_E;
  1833. }
  1834. XMEMCPY(out + idx, tmp, encSz);
  1835. XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1836. idx += encSz;
  1837. return (int)idx;
  1838. }
  1839. /* DATA
  1840. * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
  1841. * length
  1842. * ASN_OCTET_STRING
  1843. * length
  1844. * sequence containing all bags */
  1845. if (type == WC_PKCS12_DATA) {
  1846. /* calculate size */
  1847. totalSz = (word32)SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq);
  1848. totalSz += sizeof(WC_PKCS12_DATA_OID);
  1849. totalSz += ASN_TAG_SZ;
  1850. length = SetOctetString(contentSz, seq);
  1851. length += contentSz;
  1852. totalSz += SetLength(length, seq);
  1853. totalSz += length;
  1854. if (out == NULL) {
  1855. *outSz = totalSz + SetSequence(totalSz, seq);
  1856. return LENGTH_ONLY_E;
  1857. }
  1858. if (*outSz < (totalSz + SetSequence(totalSz, seq))) {
  1859. return BUFFER_E;
  1860. }
  1861. /* place data in output buffer */
  1862. idx = 0;
  1863. idx += SetSequence(totalSz, out);
  1864. idx += (word32)SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx);
  1865. if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){
  1866. WOLFSSL_MSG("Buffer not large enough for DATA OID");
  1867. return BUFFER_E;
  1868. }
  1869. XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
  1870. idx += sizeof(WC_PKCS12_DATA_OID);
  1871. if (idx + 1 > *outSz){
  1872. return BUFFER_E;
  1873. }
  1874. out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);
  1875. idx += SetLength(length, out + idx);
  1876. idx += SetOctetString(contentSz, out + idx);
  1877. if (idx + contentSz > *outSz){
  1878. return BUFFER_E;
  1879. }
  1880. XMEMCPY(out + idx, content, contentSz);
  1881. idx += contentSz;
  1882. return (int)idx;
  1883. }
  1884. WOLFSSL_MSG("Unknown/Unsupported content type");
  1885. return BAD_FUNC_ARG;
  1886. }
  1887. /* helper function to create the PKCS12 key content
  1888. * keyCiSz is output buffer size
  1889. * returns a pointer to be free'd by caller on success and NULL on failure */
  1890. static byte* PKCS12_create_key_content(WC_PKCS12* pkcs12, int nidKey,
  1891. word32* keyCiSz, WC_RNG* rng, char* pass, word32 passSz,
  1892. byte* key, word32 keySz, int iter)
  1893. {
  1894. byte* keyBuf;
  1895. word32 keyBufSz = 0;
  1896. byte* keyCi = NULL;
  1897. word32 tmpSz;
  1898. int ret;
  1899. int algo;
  1900. void* heap;
  1901. heap = wc_PKCS12_GetHeap(pkcs12);
  1902. *keyCiSz = 0;
  1903. switch (nidKey) {
  1904. case PBE_SHA1_RC4_128:
  1905. algo = 1;
  1906. break;
  1907. case PBE_SHA1_DES:
  1908. algo = 2;
  1909. break;
  1910. case PBE_SHA1_DES3:
  1911. algo = 3;
  1912. break;
  1913. /* no encryption */
  1914. case -1:
  1915. algo = -1;
  1916. break;
  1917. default:
  1918. WOLFSSL_MSG("Unknown/Unsupported key encryption");
  1919. return NULL;
  1920. }
  1921. /* get max size for key bag */
  1922. ret = wc_PKCS12_create_key_bag(pkcs12, rng, NULL, &keyBufSz, key, keySz,
  1923. algo, iter, pass, (int)passSz);
  1924. if (ret != LENGTH_ONLY_E && ret < 0) {
  1925. WOLFSSL_MSG("Error getting key bag size");
  1926. return NULL;
  1927. }
  1928. /* account for sequence around bag */
  1929. keyBufSz += MAX_SEQ_SZ;
  1930. keyBuf = (byte*)XMALLOC(keyBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1931. if (keyBuf == NULL) {
  1932. WOLFSSL_MSG("Memory error creating keyBuf buffer");
  1933. return NULL;
  1934. }
  1935. ret = wc_PKCS12_create_key_bag(pkcs12, rng, keyBuf + MAX_SEQ_SZ, &keyBufSz,
  1936. key, keySz, algo, iter, pass, (int)passSz);
  1937. if (ret < 0) {
  1938. XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1939. WOLFSSL_MSG("Error creating key bag");
  1940. return NULL;
  1941. }
  1942. keyBufSz = (word32)ret;
  1943. tmpSz = SetSequence(keyBufSz, keyBuf);
  1944. XMEMMOVE(keyBuf + tmpSz, keyBuf + MAX_SEQ_SZ, keyBufSz);
  1945. keyBufSz += tmpSz;
  1946. #ifdef WOLFSSL_DEBUG_PKCS12
  1947. {
  1948. word32 i;
  1949. printf("(size %u) Key Bag = ", keyBufSz);
  1950. for (i = 0; i < keyBufSz; i++)
  1951. printf("%02X", keyBuf[i]);
  1952. printf("\n");
  1953. }
  1954. #endif
  1955. ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, keyCiSz,
  1956. NULL, keyBufSz, algo, pass, (int)passSz, iter, WC_PKCS12_DATA);
  1957. if (ret != LENGTH_ONLY_E) {
  1958. XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1959. WOLFSSL_MSG("Error getting key encrypt content size");
  1960. return NULL;
  1961. }
  1962. keyCi = (byte*)XMALLOC(*keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1963. if (keyCi == NULL) {
  1964. XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1965. return NULL;
  1966. }
  1967. ret = wc_PKCS12_encrypt_content(pkcs12, rng, keyCi, keyCiSz,
  1968. keyBuf, keyBufSz, algo, pass, (int)passSz, iter, WC_PKCS12_DATA);
  1969. XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1970. if (ret < 0 ) {
  1971. XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
  1972. WOLFSSL_MSG("Error creating key encrypt content");
  1973. return NULL;
  1974. }
  1975. *keyCiSz = (word32)ret;
  1976. #ifdef WOLFSSL_DEBUG_PKCS12
  1977. {
  1978. word32 i;
  1979. printf("(size %u) Key Content Info = ", *keyCiSz);
  1980. for (i = 0; i < *keyCiSz; i++)
  1981. printf("%02X", keyCi[i]);
  1982. printf("\n");
  1983. }
  1984. #endif
  1985. (void)heap;
  1986. return keyCi;
  1987. }
  1988. /* helper function to create the PKCS12 certificate content
  1989. * certCiSz is output buffer size
  1990. * returns a pointer to be free'd by caller on success and NULL on failure */
  1991. static byte* PKCS12_create_cert_content(WC_PKCS12* pkcs12, int nidCert,
  1992. WC_DerCertList* ca, byte* cert, word32 certSz, word32* certCiSz,
  1993. WC_RNG* rng, char* pass, word32 passSz, int iter)
  1994. {
  1995. int algo;
  1996. int ret;
  1997. int type;
  1998. byte* certBuf = NULL;
  1999. word32 certBufSz;
  2000. word32 idx;
  2001. word32 sz;
  2002. word32 tmpSz;
  2003. byte* certCi;
  2004. void* heap;
  2005. heap = wc_PKCS12_GetHeap(pkcs12);
  2006. switch (nidCert) {
  2007. case PBE_SHA1_RC4_128:
  2008. type = WC_PKCS12_ENCRYPTED_DATA;
  2009. algo = 1;
  2010. break;
  2011. case PBE_SHA1_DES:
  2012. type = WC_PKCS12_ENCRYPTED_DATA;
  2013. algo = 2;
  2014. break;
  2015. case PBE_SHA1_DES3:
  2016. type = WC_PKCS12_ENCRYPTED_DATA;
  2017. algo = 3;
  2018. break;
  2019. case -1:
  2020. type = WC_PKCS12_DATA;
  2021. algo = -1;
  2022. break;
  2023. default:
  2024. WOLFSSL_MSG("Unknown/Unsupported certificate encryption");
  2025. return NULL;
  2026. }
  2027. /* get max size of buffer needed */
  2028. ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &certBufSz, cert, certSz);
  2029. if (ret != LENGTH_ONLY_E) {
  2030. return NULL;
  2031. }
  2032. if (ca != NULL) {
  2033. WC_DerCertList* current = ca;
  2034. word32 curBufSz = 0;
  2035. /* get max buffer size */
  2036. while (current != NULL) {
  2037. ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &curBufSz,
  2038. current->buffer, current->bufferSz);
  2039. if (ret != LENGTH_ONLY_E) {
  2040. return NULL;
  2041. }
  2042. certBufSz += curBufSz;
  2043. current = current->next;
  2044. }
  2045. }
  2046. /* account for Sequence that holds all certificate bags */
  2047. certBufSz += MAX_SEQ_SZ;
  2048. /* completed getting max size, now create buffer and start adding bags */
  2049. certBuf = (byte*)XMALLOC(certBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2050. if (certBuf == NULL) {
  2051. WOLFSSL_MSG("Memory error creating certificate bags");
  2052. return NULL;
  2053. }
  2054. idx = 0;
  2055. idx += MAX_SEQ_SZ;
  2056. sz = certBufSz - idx;
  2057. if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
  2058. cert, certSz)) < 0) {
  2059. XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2060. return NULL;
  2061. }
  2062. idx += (word32)ret;
  2063. if (ca != NULL) {
  2064. WC_DerCertList* current = ca;
  2065. while (current != NULL) {
  2066. sz = certBufSz - idx;
  2067. if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
  2068. current->buffer, current->bufferSz)) < 0) {
  2069. XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2070. return NULL;
  2071. }
  2072. idx += (word32)ret;
  2073. current = current->next;
  2074. }
  2075. }
  2076. /* set sequence and create encrypted content with all certificate bags */
  2077. tmpSz = SetSequence(idx - MAX_SEQ_SZ, certBuf);
  2078. XMEMMOVE(certBuf + tmpSz, certBuf + MAX_SEQ_SZ, idx - MAX_SEQ_SZ);
  2079. certBufSz = tmpSz + (idx - MAX_SEQ_SZ);
  2080. /* get buffer size needed for content info */
  2081. ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, certCiSz,
  2082. NULL, certBufSz, algo, pass, (int)passSz, iter, type);
  2083. if (ret != LENGTH_ONLY_E) {
  2084. XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2085. WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
  2086. return NULL;
  2087. }
  2088. certCi = (byte*)XMALLOC(*certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2089. if (certCi == NULL) {
  2090. XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2091. return NULL;
  2092. }
  2093. ret = wc_PKCS12_encrypt_content(pkcs12, rng, certCi, certCiSz,
  2094. certBuf, certBufSz, algo, pass, (int)passSz, iter, type);
  2095. XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2096. if (ret < 0) {
  2097. WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
  2098. XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2099. return NULL;
  2100. }
  2101. *certCiSz = (word32)ret;
  2102. #ifdef WOLFSSL_DEBUG_PKCS12
  2103. {
  2104. word32 i;
  2105. printf("(size %u) Encrypted Certificate Content Info = ", *certCiSz);
  2106. for (i = 0; i < *certCiSz; i++)
  2107. printf("%02X", certCi[i]);
  2108. printf("\n");
  2109. }
  2110. #endif
  2111. (void)heap;
  2112. return certCi;
  2113. }
  2114. /* helper function to create the PKCS12 safe
  2115. * returns 0 on success */
  2116. static int PKCS12_create_safe(WC_PKCS12* pkcs12, byte* certCi, word32 certCiSz,
  2117. byte* keyCi, word32 keyCiSz, WC_RNG* rng, char* pass, word32 passSz,
  2118. int iter)
  2119. {
  2120. int length;
  2121. int ret;
  2122. byte seq[MAX_SEQ_SZ];
  2123. word32 safeDataSz;
  2124. word32 innerDataSz;
  2125. byte *innerData = NULL;
  2126. byte *safeData = NULL;
  2127. word32 idx;
  2128. innerDataSz = certCiSz + keyCiSz+SetSequence(certCiSz + keyCiSz, seq);
  2129. /* add Content Info structs to safe, key first then cert */
  2130. ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, &safeDataSz,
  2131. NULL, innerDataSz, 0, NULL, 0, 0, WC_PKCS12_DATA);
  2132. if (ret != LENGTH_ONLY_E) {
  2133. return ret;
  2134. }
  2135. safeData = (byte*)XMALLOC(safeDataSz, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2136. if (safeData == NULL) {
  2137. WOLFSSL_MSG("Error malloc'ing safe data buffer");
  2138. return MEMORY_E;
  2139. }
  2140. /* create sequence of inner data */
  2141. innerData = (byte*)XMALLOC(innerDataSz, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  2142. if (innerData == NULL) {
  2143. WOLFSSL_MSG("Error malloc'ing inner data buffer");
  2144. XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2145. return MEMORY_E;
  2146. }
  2147. idx = 0;
  2148. idx += SetSequence(certCiSz + keyCiSz, innerData);
  2149. XMEMCPY(innerData + idx, certCi, certCiSz);
  2150. XMEMCPY(innerData + idx + certCiSz, keyCi, keyCiSz);
  2151. ret = wc_PKCS12_encrypt_content(pkcs12, rng, safeData, &safeDataSz,
  2152. innerData, innerDataSz, 0, pass, (int)passSz, iter, WC_PKCS12_DATA);
  2153. XFREE(innerData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
  2154. if (ret < 0 ) {
  2155. WOLFSSL_MSG("Error setting data type for safe contents");
  2156. XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2157. return ret;
  2158. }
  2159. idx = 0;
  2160. ret = GetSequence(safeData, &idx, &length, safeDataSz);
  2161. if (ret < 0) {
  2162. WOLFSSL_MSG("Error getting first sequence of safe");
  2163. XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2164. return ret;
  2165. }
  2166. ret = GetSafeContent(pkcs12, safeData, &idx, safeDataSz);
  2167. XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2168. if (ret < 0) {
  2169. WOLFSSL_MSG("Unable to create safe contents");
  2170. return ret;
  2171. }
  2172. return 0;
  2173. }
  2174. /*
  2175. * pass : password to use with encryption
  2176. * passSz : size of the password buffer
  2177. * name : friendlyName to use
  2178. * key : DER format of key
  2179. * keySz : size of key buffer
  2180. * cert : DER format of certificate
  2181. * certSz : size of the certificate buffer
  2182. * ca : a list of extra certificates
  2183. * nidKey : type of encryption to use on the key (-1 means no encryption)
  2184. * nidCert : type of encryption to use on the certificate
  2185. * (-1 means no encryption)
  2186. * iter : number of iterations with encryption
  2187. * macIter : number of iterations when creating MAC
  2188. * keyType : flag for signature and/or encryption key
  2189. * heap : pointer to allocate from memory
  2190. *
  2191. * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed
  2192. */
  2193. WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name,
  2194. byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca,
  2195. int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap)
  2196. {
  2197. WC_PKCS12* pkcs12;
  2198. WC_RNG rng;
  2199. int ret;
  2200. byte* certCi = NULL;
  2201. byte* keyCi = NULL;
  2202. word32 certCiSz;
  2203. word32 keyCiSz;
  2204. WOLFSSL_ENTER("wc_PKCS12_create");
  2205. if (wc_InitRng_ex(&rng, heap, INVALID_DEVID) != 0) {
  2206. return NULL;
  2207. }
  2208. if ((pkcs12 = wc_PKCS12_new()) == NULL) {
  2209. wc_FreeRng(&rng);
  2210. WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E);
  2211. return NULL;
  2212. }
  2213. if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) {
  2214. wc_PKCS12_free(pkcs12);
  2215. wc_FreeRng(&rng);
  2216. WOLFSSL_LEAVE("wc_PKCS12_create", ret);
  2217. (void)ret;
  2218. return NULL;
  2219. }
  2220. if (iter <= 0) {
  2221. iter = WC_PKCS12_ITT_DEFAULT;
  2222. }
  2223. /**** add private key bag ****/
  2224. keyCi = PKCS12_create_key_content(pkcs12, nidKey, &keyCiSz, &rng,
  2225. pass, passSz, key, keySz, iter);
  2226. if (keyCi == NULL) {
  2227. wc_PKCS12_free(pkcs12);
  2228. wc_FreeRng(&rng);
  2229. return NULL;
  2230. }
  2231. /**** add main certificate bag and extras ****/
  2232. certCi = PKCS12_create_cert_content(pkcs12, nidCert, ca, cert, certSz,
  2233. &certCiSz, &rng, pass, passSz, iter);
  2234. if (certCi == NULL) {
  2235. XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2236. wc_PKCS12_free(pkcs12);
  2237. wc_FreeRng(&rng);
  2238. return NULL;
  2239. }
  2240. /**** create safe and Content Info ****/
  2241. ret = PKCS12_create_safe(pkcs12, certCi, certCiSz, keyCi, keyCiSz, &rng,
  2242. pass, passSz, iter);
  2243. XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2244. XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
  2245. if (ret != 0) {
  2246. WOLFSSL_MSG("Unable to create PKCS12 safe");
  2247. wc_PKCS12_free(pkcs12);
  2248. wc_FreeRng(&rng);
  2249. return NULL;
  2250. }
  2251. /* create MAC */
  2252. if (macIter > 0) {
  2253. MacData* mac;
  2254. byte digest[WC_MAX_DIGEST_SIZE]; /* for MAC */
  2255. mac = (MacData*)XMALLOC(sizeof(MacData), heap, DYNAMIC_TYPE_PKCS);
  2256. if (mac == NULL) {
  2257. wc_PKCS12_free(pkcs12);
  2258. wc_FreeRng(&rng);
  2259. WOLFSSL_MSG("Error malloc'ing mac data buffer");
  2260. return NULL;
  2261. }
  2262. XMEMSET(mac, 0, sizeof(MacData));
  2263. pkcs12->signData = mac; /* now wc_PKCS12_free will free all mac too */
  2264. #ifndef NO_SHA256
  2265. mac->oid = SHA256h;
  2266. #elif !defined(NO_SHA)
  2267. mac->oid = SHA;
  2268. #elif defined(WOLFSSL_SHA384)
  2269. mac->oid = SHA384;
  2270. #elif defined(WOLFSSL_SHA512)
  2271. mac->oid = SHA512;
  2272. #else
  2273. WOLFSSL_MSG("No supported hash algorithm compiled in!");
  2274. wc_PKCS12_free(pkcs12);
  2275. wc_FreeRng(&rng);
  2276. return NULL;
  2277. #endif
  2278. /* store number of iterations */
  2279. mac->itt = macIter;
  2280. /* set mac salt */
  2281. mac->saltSz = WC_PKCS12_MAC_SALT_SZ;
  2282. mac->salt = (byte*)XMALLOC(WC_PKCS12_MAC_SALT_SZ, heap,
  2283. DYNAMIC_TYPE_PKCS);
  2284. if (mac->salt == NULL) {
  2285. wc_PKCS12_free(pkcs12);
  2286. wc_FreeRng(&rng);
  2287. WOLFSSL_MSG("Error malloc'ing salt data buffer");
  2288. return NULL;
  2289. }
  2290. if (wc_RNG_GenerateBlock(&rng, mac->salt, mac->saltSz) != 0) {
  2291. WOLFSSL_MSG("Error generating random salt");
  2292. wc_PKCS12_free(pkcs12);
  2293. wc_FreeRng(&rng);
  2294. return NULL;
  2295. }
  2296. ret = wc_PKCS12_create_mac(pkcs12, pkcs12->safe->data,
  2297. pkcs12->safe->dataSz, (const byte*)pass, passSz, digest,
  2298. WC_MAX_DIGEST_SIZE);
  2299. if (ret < 0) {
  2300. wc_PKCS12_free(pkcs12);
  2301. wc_FreeRng(&rng);
  2302. WOLFSSL_MSG("Error creating mac");
  2303. WOLFSSL_LEAVE("wc_PKCS12_create", ret);
  2304. return NULL;
  2305. }
  2306. mac->digestSz = (word32)ret;
  2307. mac->digest = (byte*)XMALLOC((size_t)ret, heap, DYNAMIC_TYPE_PKCS);
  2308. if (mac->digest == NULL) {
  2309. WOLFSSL_MSG("Error malloc'ing mac digest buffer");
  2310. wc_PKCS12_free(pkcs12);
  2311. wc_FreeRng(&rng);
  2312. return NULL;
  2313. }
  2314. XMEMCPY(mac->digest, digest, mac->digestSz);
  2315. }
  2316. else {
  2317. pkcs12->signData = NULL;
  2318. }
  2319. wc_FreeRng(&rng);
  2320. (void)name;
  2321. (void)keyType;
  2322. return pkcs12;
  2323. }
  2324. /* if using a specific memory heap */
  2325. int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap)
  2326. {
  2327. if (pkcs12 == NULL) {
  2328. return BAD_FUNC_ARG;
  2329. }
  2330. pkcs12->heap = heap;
  2331. return 0;
  2332. }
  2333. /* getter for heap */
  2334. void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12)
  2335. {
  2336. if (pkcs12 == NULL) {
  2337. return NULL;
  2338. }
  2339. return pkcs12->heap;
  2340. }
  2341. #undef ERROR_OUT
  2342. #endif /* HAVE_PKCS12 && !NO_ASN && !NO_PWDBASED && !NO_HMAC */