pkcs12.c 82 KB

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