pkcs7.c 433 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407
  1. /* pkcs7.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #ifdef HAVE_PKCS7
  26. #include <wolfssl/wolfcrypt/pkcs7.h>
  27. #include <wolfssl/wolfcrypt/error-crypt.h>
  28. #include <wolfssl/wolfcrypt/logging.h>
  29. #include <wolfssl/wolfcrypt/hash.h>
  30. #ifndef NO_RSA
  31. #include <wolfssl/wolfcrypt/rsa.h>
  32. #endif
  33. #ifdef HAVE_ECC
  34. #include <wolfssl/wolfcrypt/ecc.h>
  35. #endif
  36. #ifdef HAVE_LIBZ
  37. #include <wolfssl/wolfcrypt/compress.h>
  38. #endif
  39. #ifndef NO_PWDBASED
  40. #include <wolfssl/wolfcrypt/pwdbased.h>
  41. #endif
  42. #ifdef NO_INLINE
  43. #include <wolfssl/wolfcrypt/misc.h>
  44. #else
  45. #define WOLFSSL_MISC_INCLUDED
  46. #include <wolfcrypt/src/misc.c>
  47. #endif
  48. /* direction for processing, encoding or decoding */
  49. typedef enum {
  50. WC_PKCS7_ENCODE,
  51. WC_PKCS7_DECODE
  52. } pkcs7Direction;
  53. #define NO_USER_CHECK 0
  54. /* holds information about the signers */
  55. struct PKCS7SignerInfo {
  56. int version;
  57. byte *sid;
  58. word32 sidSz;
  59. };
  60. #ifndef WOLFSSL_PKCS7_MAX_DECOMPRESSION
  61. /* 1031 comes from "Maximum Compression Factor" in the zlib tech document,
  62. * typical compression is from 2:1 to 5:1 but there is rare cases where
  63. * 1030.3:1 could happen (like a file with all 0's)
  64. */
  65. #define WOLFSSL_PKCS7_MAX_DECOMPRESSION 1031
  66. #endif
  67. #ifndef NO_PKCS7_STREAM
  68. #define MAX_PKCS7_STREAM_BUFFER 256
  69. struct PKCS7State {
  70. byte* tmpCert;
  71. byte* bufferPt;
  72. byte* key;
  73. byte* nonce; /* stored nonce */
  74. byte* aad; /* additional data for AEAD algos */
  75. byte* tag; /* tag data for AEAD algos */
  76. byte* content;
  77. byte* buffer; /* main internal read buffer */
  78. /* stack variables to store for when returning */
  79. word32 varOne;
  80. int varTwo;
  81. int varThree;
  82. word32 vers;
  83. word32 idx; /* index read into current input buffer */
  84. word32 maxLen; /* sanity cap on maximum amount of data to allow
  85. * needed for GetSequence and other calls */
  86. word32 length; /* amount of data stored */
  87. word32 bufferSz; /* size of internal buffer */
  88. word32 expected; /* next amount of data expected, if needed */
  89. word32 totalRd; /* total amount of bytes read */
  90. word32 nonceSz; /* size of nonce stored */
  91. word32 aadSz; /* size of additional AEAD data */
  92. word32 tagSz; /* size of tag for AEAD */
  93. word32 contentSz;
  94. byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
  95. #ifdef WC_PKCS7_STREAM_DEBUG
  96. word32 peakUsed; /* most bytes used for struct at any one time */
  97. word32 peakRead; /* most bytes used by read buffer */
  98. #endif
  99. byte multi:1; /* flag for if content is in multiple parts */
  100. byte flagOne:1;
  101. byte detached:1; /* flag to indicate detached signature is present */
  102. };
  103. /* creates a PKCS7State structure and returns 0 on success */
  104. static int wc_PKCS7_CreateStream(PKCS7* pkcs7)
  105. {
  106. WOLFSSL_MSG("creating PKCS7 stream structure");
  107. pkcs7->stream = (PKCS7State*)XMALLOC(sizeof(PKCS7State), pkcs7->heap,
  108. DYNAMIC_TYPE_PKCS7);
  109. if (pkcs7->stream == NULL) {
  110. return MEMORY_E;
  111. }
  112. XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State));
  113. #ifdef WC_PKCS7_STREAM_DEBUG
  114. printf("\nCreating new PKCS#7 stream %p\n", pkcs7->stream);
  115. #endif
  116. return 0;
  117. }
  118. static void wc_PKCS7_ResetStream(PKCS7* pkcs7)
  119. {
  120. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  121. #ifdef WC_PKCS7_STREAM_DEBUG
  122. /* collect final data point in case more was read right before reset */
  123. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  124. pkcs7->stream->peakRead = pkcs7->stream->length;
  125. }
  126. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz +
  127. pkcs7->stream->nonceSz + pkcs7->stream->tagSz >
  128. pkcs7->stream->peakUsed) {
  129. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  130. pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  131. pkcs7->stream->tagSz;
  132. }
  133. /* print out debugging statistics */
  134. if (pkcs7->stream->peakUsed > 0 || pkcs7->stream->peakRead > 0) {
  135. printf("PKCS#7 STREAM:\n\tPeak heap used by struct = %d"
  136. "\n\tPeak read buffer bytes = %d"
  137. "\n\tTotal bytes read = %d"
  138. "\n",
  139. pkcs7->stream->peakUsed, pkcs7->stream->peakRead,
  140. pkcs7->stream->totalRd);
  141. }
  142. printf("PKCS#7 stream reset : Address [%p]\n", pkcs7->stream);
  143. #endif
  144. /* free any buffers that may be allocated */
  145. XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  146. XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  147. XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  148. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  149. XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  150. pkcs7->stream->aad = NULL;
  151. pkcs7->stream->tag = NULL;
  152. pkcs7->stream->nonce = NULL;
  153. pkcs7->stream->buffer = NULL;
  154. pkcs7->stream->key = NULL;
  155. /* reset values, note that content and tmpCert are saved */
  156. pkcs7->stream->maxLen = 0;
  157. pkcs7->stream->length = 0;
  158. pkcs7->stream->idx = 0;
  159. pkcs7->stream->expected = 0;
  160. pkcs7->stream->totalRd = 0;
  161. pkcs7->stream->bufferSz = 0;
  162. pkcs7->stream->multi = 0;
  163. pkcs7->stream->flagOne = 0;
  164. pkcs7->stream->detached = 0;
  165. pkcs7->stream->varOne = 0;
  166. pkcs7->stream->varTwo = 0;
  167. pkcs7->stream->varThree = 0;
  168. }
  169. }
  170. static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
  171. {
  172. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  173. wc_PKCS7_ResetStream(pkcs7);
  174. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  175. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  176. pkcs7->stream->content = NULL;
  177. pkcs7->stream->tmpCert = NULL;
  178. XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  179. pkcs7->stream = NULL;
  180. }
  181. }
  182. /* used to increase the max size for internal buffer
  183. * returns 0 on success */
  184. static int wc_PKCS7_GrowStream(PKCS7* pkcs7, word32 newSz)
  185. {
  186. byte* pt;
  187. pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  188. if (pt == NULL) {
  189. return MEMORY_E;
  190. }
  191. if (pkcs7->stream->buffer != NULL && pkcs7->stream->bufferSz > 0) {
  192. XMEMCPY(pt, pkcs7->stream->buffer, pkcs7->stream->bufferSz);
  193. }
  194. #ifdef WC_PKCS7_STREAM_DEBUG
  195. printf("PKCS7 increasing internal stream buffer %d -> %d\n",
  196. pkcs7->stream->bufferSz, newSz);
  197. #endif
  198. pkcs7->stream->bufferSz = newSz;
  199. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  200. pkcs7->stream->buffer = pt;
  201. return 0;
  202. }
  203. /* pt gets set to the buffer that is holding data in the case that stream struct
  204. * is used.
  205. *
  206. * Sets idx to be the current offset into "pt" buffer
  207. * returns 0 on success
  208. */
  209. static int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz,
  210. word32 expected, byte** pt, word32* idx)
  211. {
  212. word32 rdSz = pkcs7->stream->idx;
  213. /* If the input size minus current index into input buffer is greater than
  214. * the expected size then use the input buffer. If data is already stored
  215. * in stream buffer or if there is not enough input data available then use
  216. * the stream buffer. */
  217. if (inSz - rdSz >= expected && pkcs7->stream->length == 0) {
  218. /* storing input buffer is not needed */
  219. *pt = in; /* reset in case previously used internal buffer */
  220. *idx = rdSz;
  221. return 0;
  222. }
  223. /* is there enough stored in buffer already? */
  224. if (pkcs7->stream->length >= expected) {
  225. *idx = 0; /* start reading from beginning of stream buffer */
  226. *pt = pkcs7->stream->buffer;
  227. return 0;
  228. }
  229. /* check if all data has been read from input */
  230. if (rdSz >= inSz) {
  231. /* no more input to read, reset input index and request more data */
  232. pkcs7->stream->idx = 0;
  233. return WC_PKCS7_WANT_READ_E;
  234. }
  235. /* try to store input data into stream buffer */
  236. if (inSz - rdSz > 0 && pkcs7->stream->length < expected) {
  237. int len = min(inSz - rdSz, expected - pkcs7->stream->length);
  238. /* sanity check that the input buffer is not internal buffer */
  239. if (in == pkcs7->stream->buffer) {
  240. return WC_PKCS7_WANT_READ_E;
  241. }
  242. /* check if internal buffer size needs to be increased */
  243. if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) {
  244. int ret = wc_PKCS7_GrowStream(pkcs7, expected);
  245. if (ret < 0) {
  246. return ret;
  247. }
  248. }
  249. XMEMCPY(pkcs7->stream->buffer + pkcs7->stream->length, in + rdSz, len);
  250. pkcs7->stream->length += len;
  251. pkcs7->stream->idx += len;
  252. pkcs7->stream->totalRd += len;
  253. }
  254. #ifdef WC_PKCS7_STREAM_DEBUG
  255. /* collects memory usage for debugging */
  256. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  257. pkcs7->stream->peakRead = pkcs7->stream->length;
  258. }
  259. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  260. pkcs7->stream->tagSz > pkcs7->stream->peakUsed) {
  261. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  262. pkcs7->stream->aadSz + pkcs7->stream->nonceSz + pkcs7->stream->tagSz;
  263. }
  264. #endif
  265. /* if not enough data was read in then request more */
  266. if (pkcs7->stream->length < expected) {
  267. pkcs7->stream->idx = 0;
  268. return WC_PKCS7_WANT_READ_E;
  269. }
  270. /* adjust pointer to read from stored buffer */
  271. *idx = 0;
  272. *pt = pkcs7->stream->buffer;
  273. return 0;
  274. }
  275. /* setter function for stored variables */
  276. static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2,
  277. int var3)
  278. {
  279. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  280. pkcs7->stream->varOne = var1;
  281. pkcs7->stream->varTwo = var2;
  282. pkcs7->stream->varThree = var3;
  283. }
  284. }
  285. /* Tries to peek at the SEQ and get the length
  286. * returns 0 on success
  287. */
  288. static int wc_PKCS7_SetMaxStream(PKCS7* pkcs7, byte* in, word32 defSz)
  289. {
  290. /* check there is a buffer to read from */
  291. if (pkcs7) {
  292. int length = 0, ret;
  293. word32 idx = 0, maxIdx;
  294. byte* pt;
  295. if (pkcs7->stream->length > 0) {
  296. length = pkcs7->stream->length;
  297. pt = pkcs7->stream->buffer;
  298. }
  299. else {
  300. length = defSz;
  301. pt = in;
  302. }
  303. maxIdx = (word32)length;
  304. if (length < MAX_SEQ_SZ) {
  305. WOLFSSL_MSG("PKCS7 Error not enough data for SEQ peek");
  306. return 0;
  307. }
  308. if ((ret = GetSequence_ex(pt, &idx, &length, maxIdx, NO_USER_CHECK))
  309. < 0) {
  310. return ret;
  311. }
  312. #ifdef ASN_BER_TO_DER
  313. if (length == 0 && ret == 0) {
  314. idx = 0;
  315. if ((ret = wc_BerToDer(pt, maxIdx, NULL,
  316. (word32*)&length)) != LENGTH_ONLY_E) {
  317. return ret;
  318. }
  319. }
  320. #endif /* ASN_BER_TO_DER */
  321. pkcs7->stream->maxLen = length + idx;
  322. if (pkcs7->stream->maxLen == 0) {
  323. pkcs7->stream->maxLen = defSz;
  324. }
  325. }
  326. return 0;
  327. }
  328. /* getter function for stored variables */
  329. static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2,
  330. int* var3)
  331. {
  332. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  333. if (var1 != NULL) *var1 = pkcs7->stream->varOne;
  334. if (var2 != NULL) *var2 = pkcs7->stream->varTwo;
  335. if (var3 != NULL) *var3 = pkcs7->stream->varThree;
  336. }
  337. }
  338. /* common update of index and total read after section complete
  339. * returns 0 on success */
  340. static int wc_PKCS7_StreamEndCase(PKCS7* pkcs7, word32* tmpIdx, word32* idx)
  341. {
  342. int ret = 0;
  343. if (pkcs7->stream->length > 0) {
  344. if (pkcs7->stream->length < *idx) {
  345. WOLFSSL_MSG("PKCS7 read too much data from internal buffer");
  346. ret = BUFFER_E;
  347. }
  348. else {
  349. XMEMMOVE(pkcs7->stream->buffer, pkcs7->stream->buffer + *idx,
  350. pkcs7->stream->length - *idx);
  351. pkcs7->stream->length -= *idx;
  352. }
  353. }
  354. else {
  355. pkcs7->stream->totalRd += *idx - *tmpIdx;
  356. pkcs7->stream->idx = *idx; /* adjust index into input buffer */
  357. *tmpIdx = *idx;
  358. }
  359. return ret;
  360. }
  361. #endif /* NO_PKCS7_STREAM */
  362. #ifdef WC_PKCS7_STREAM_DEBUG
  363. /* used to print out human readable state for debugging */
  364. static const char* wc_PKCS7_GetStateName(int in)
  365. {
  366. switch (in) {
  367. case WC_PKCS7_START: return "WC_PKCS7_START";
  368. case WC_PKCS7_STAGE2: return "WC_PKCS7_STAGE2";
  369. case WC_PKCS7_STAGE3: return "WC_PKCS7_STAGE3";
  370. case WC_PKCS7_STAGE4: return "WC_PKCS7_STAGE4";
  371. case WC_PKCS7_STAGE5: return "WC_PKCS7_STAGE5";
  372. case WC_PKCS7_STAGE6: return "WC_PKCS7_STAGE6";
  373. /* parse info set */
  374. case WC_PKCS7_INFOSET_START: return "WC_PKCS7_INFOSET_START";
  375. case WC_PKCS7_INFOSET_BER: return "WC_PKCS7_INFOSET_BER";
  376. case WC_PKCS7_INFOSET_STAGE1: return "WC_PKCS7_INFOSET_STAGE1";
  377. case WC_PKCS7_INFOSET_STAGE2: return "WC_PKCS7_INFOSET_STAGE2";
  378. case WC_PKCS7_INFOSET_END: return "WC_PKCS7_INFOSET_END";
  379. /* decode enveloped data */
  380. case WC_PKCS7_ENV_2: return "WC_PKCS7_ENV_2";
  381. case WC_PKCS7_ENV_3: return "WC_PKCS7_ENV_3";
  382. case WC_PKCS7_ENV_4: return "WC_PKCS7_ENV_4";
  383. case WC_PKCS7_ENV_5: return "WC_PKCS7_ENV_5";
  384. /* decode auth enveloped */
  385. case WC_PKCS7_AUTHENV_2: return "WC_PKCS7_AUTHENV_2";
  386. case WC_PKCS7_AUTHENV_3: return "WC_PKCS7_AUTHENV_3";
  387. case WC_PKCS7_AUTHENV_4: return "WC_PKCS7_AUTHENV_4";
  388. case WC_PKCS7_AUTHENV_5: return "WC_PKCS7_AUTHENV_5";
  389. case WC_PKCS7_AUTHENV_6: return "WC_PKCS7_AUTHENV_6";
  390. case WC_PKCS7_AUTHENV_ATRB: return "WC_PKCS7_AUTHENV_ATRB";
  391. case WC_PKCS7_AUTHENV_ATRBEND: return "WC_PKCS7_AUTHENV_ATRBEND";
  392. case WC_PKCS7_AUTHENV_7: return "WC_PKCS7_AUTHENV_7";
  393. /* decryption state types */
  394. case WC_PKCS7_DECRYPT_KTRI: return "WC_PKCS7_DECRYPT_KTRI";
  395. case WC_PKCS7_DECRYPT_KTRI_2: return "WC_PKCS7_DECRYPT_KTRI_2";
  396. case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
  397. case WC_PKCS7_DECRYPT_KARI: return "WC_PKCS7_DECRYPT_KARI";
  398. case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
  399. case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
  400. case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
  401. case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
  402. case WC_PKCS7_VERIFY_STAGE2: return "WC_PKCS7_VERIFY_STAGE2";
  403. case WC_PKCS7_VERIFY_STAGE3: return "WC_PKCS7_VERIFY_STAGE3";
  404. case WC_PKCS7_VERIFY_STAGE4: return "WC_PKCS7_VERIFY_STAGE4";
  405. case WC_PKCS7_VERIFY_STAGE5: return "WC_PKCS7_VERIFY_STAGE5";
  406. case WC_PKCS7_VERIFY_STAGE6: return "WC_PKCS7_VERIFY_STAGE6";
  407. default:
  408. return "Unknown state";
  409. }
  410. }
  411. #endif
  412. /* Used to change the PKCS7 state. Having state change as a function allows
  413. * for easier debugging */
  414. static void wc_PKCS7_ChangeState(PKCS7* pkcs7, int newState)
  415. {
  416. #ifdef WC_PKCS7_STREAM_DEBUG
  417. printf("\tChanging from state [%02d] %s to [%02d] %s\n",
  418. pkcs7->state, wc_PKCS7_GetStateName(pkcs7->state),
  419. newState, wc_PKCS7_GetStateName(newState));
  420. #endif
  421. pkcs7->state = newState;
  422. }
  423. #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \
  424. MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)
  425. /* placed ASN.1 contentType OID into *output, return idx on success,
  426. * 0 upon failure */
  427. static int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz)
  428. {
  429. /* PKCS#7 content types, RFC 2315, section 14 */
  430. static const byte pkcs7[] =
  431. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07 };
  432. static const byte data[] =
  433. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
  434. static const byte signedData[] =
  435. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
  436. static const byte envelopedData[] =
  437. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03 };
  438. static const byte authEnvelopedData[] =
  439. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x17};
  440. static const byte signedAndEnveloped[] =
  441. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04 };
  442. static const byte digestedData[] =
  443. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05 };
  444. #ifndef NO_PKCS7_ENCRYPTED_DATA
  445. static const byte encryptedData[] =
  446. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
  447. #endif
  448. /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), RFC 4108 */
  449. static const byte firmwarePkgData[] =
  450. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x10 };
  451. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  452. /* id-ct-compressedData (1.2.840.113549.1.9.16.1.9), RFC 3274 */
  453. static const byte compressedData[] =
  454. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x09 };
  455. #endif
  456. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  457. static const byte pwriKek[] =
  458. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x03, 0x09 };
  459. static const byte pbkdf2[] =
  460. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C };
  461. #endif
  462. int idSz, idx = 0;
  463. word32 typeSz = 0;
  464. const byte* typeName = 0;
  465. byte ID_Length[MAX_LENGTH_SZ];
  466. switch (pkcs7TypeOID) {
  467. case PKCS7_MSG:
  468. typeSz = sizeof(pkcs7);
  469. typeName = pkcs7;
  470. break;
  471. case DATA:
  472. typeSz = sizeof(data);
  473. typeName = data;
  474. break;
  475. case SIGNED_DATA:
  476. typeSz = sizeof(signedData);
  477. typeName = signedData;
  478. break;
  479. case ENVELOPED_DATA:
  480. typeSz = sizeof(envelopedData);
  481. typeName = envelopedData;
  482. break;
  483. case AUTH_ENVELOPED_DATA:
  484. typeSz = sizeof(authEnvelopedData);
  485. typeName = authEnvelopedData;
  486. break;
  487. case SIGNED_AND_ENVELOPED_DATA:
  488. typeSz = sizeof(signedAndEnveloped);
  489. typeName = signedAndEnveloped;
  490. break;
  491. case DIGESTED_DATA:
  492. typeSz = sizeof(digestedData);
  493. typeName = digestedData;
  494. break;
  495. #ifndef NO_PKCS7_ENCRYPTED_DATA
  496. case ENCRYPTED_DATA:
  497. typeSz = sizeof(encryptedData);
  498. typeName = encryptedData;
  499. break;
  500. #endif
  501. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  502. case COMPRESSED_DATA:
  503. typeSz = sizeof(compressedData);
  504. typeName = compressedData;
  505. break;
  506. #endif
  507. case FIRMWARE_PKG_DATA:
  508. typeSz = sizeof(firmwarePkgData);
  509. typeName = firmwarePkgData;
  510. break;
  511. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  512. case PWRI_KEK_WRAP:
  513. typeSz = sizeof(pwriKek);
  514. typeName = pwriKek;
  515. break;
  516. case PBKDF2_OID:
  517. typeSz = sizeof(pbkdf2);
  518. typeName = pbkdf2;
  519. break;
  520. #endif
  521. default:
  522. WOLFSSL_MSG("Unknown PKCS#7 Type");
  523. return 0;
  524. };
  525. if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) {
  526. WOLFSSL_MSG("CMS content type buffer too small");
  527. return BAD_FUNC_ARG;
  528. }
  529. idSz = SetLength(typeSz, ID_Length);
  530. output[idx++] = ASN_OBJECT_ID;
  531. XMEMCPY(output + idx, ID_Length, idSz);
  532. idx += idSz;
  533. XMEMCPY(output + idx, typeName, typeSz);
  534. idx += typeSz;
  535. return idx;
  536. }
  537. /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
  538. static int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
  539. word32 maxIdx)
  540. {
  541. WOLFSSL_ENTER("wc_GetContentType");
  542. if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0) {
  543. WOLFSSL_LEAVE("wc_GetContentType", ASN_PARSE_E);
  544. return ASN_PARSE_E;
  545. }
  546. return 0;
  547. }
  548. /* return block size for algorithm represented by oid, or <0 on error */
  549. static int wc_PKCS7_GetOIDBlockSize(int oid)
  550. {
  551. int blockSz;
  552. switch (oid) {
  553. #ifndef NO_AES
  554. #ifdef WOLFSSL_AES_128
  555. #ifdef HAVE_AES_CBC
  556. case AES128CBCb:
  557. #endif
  558. #ifdef HAVE_AESGCM
  559. case AES128GCMb:
  560. #endif
  561. #ifdef HAVE_AESCCM
  562. case AES128CCMb:
  563. #endif
  564. #endif
  565. #ifdef WOLFSSL_AES_192
  566. #ifdef HAVE_AES_CBC
  567. case AES192CBCb:
  568. #endif
  569. #ifdef HAVE_AESGCM
  570. case AES192GCMb:
  571. #endif
  572. #ifdef HAVE_AESCCM
  573. case AES192CCMb:
  574. #endif
  575. #endif
  576. #ifdef WOLFSSL_AES_256
  577. #ifdef HAVE_AES_CBC
  578. case AES256CBCb:
  579. #endif
  580. #ifdef HAVE_AESGCM
  581. case AES256GCMb:
  582. #endif
  583. #ifdef HAVE_AESCCM
  584. case AES256CCMb:
  585. #endif
  586. #endif
  587. blockSz = AES_BLOCK_SIZE;
  588. break;
  589. #endif /* !NO_AES */
  590. #ifndef NO_DES3
  591. case DESb:
  592. case DES3b:
  593. blockSz = DES_BLOCK_SIZE;
  594. break;
  595. #endif
  596. default:
  597. WOLFSSL_MSG("Unsupported content cipher type");
  598. return ALGO_ID_E;
  599. };
  600. return blockSz;
  601. }
  602. /* get key size for algorithm represented by oid, or <0 on error */
  603. static int wc_PKCS7_GetOIDKeySize(int oid)
  604. {
  605. int blockKeySz;
  606. switch (oid) {
  607. #ifndef NO_AES
  608. #ifdef WOLFSSL_AES_128
  609. #ifdef HAVE_AES_CBC
  610. case AES128CBCb:
  611. #endif
  612. #ifdef HAVE_AESGCM
  613. case AES128GCMb:
  614. #endif
  615. #ifdef HAVE_AESCCM
  616. case AES128CCMb:
  617. #endif
  618. case AES128_WRAP:
  619. blockKeySz = 16;
  620. break;
  621. #endif
  622. #ifdef WOLFSSL_AES_192
  623. #ifdef HAVE_AES_CBC
  624. case AES192CBCb:
  625. #endif
  626. #ifdef HAVE_AESGCM
  627. case AES192GCMb:
  628. #endif
  629. #ifdef HAVE_AESCCM
  630. case AES192CCMb:
  631. #endif
  632. case AES192_WRAP:
  633. blockKeySz = 24;
  634. break;
  635. #endif
  636. #ifdef WOLFSSL_AES_256
  637. #ifdef HAVE_AES_CBC
  638. case AES256CBCb:
  639. #endif
  640. #ifdef HAVE_AESGCM
  641. case AES256GCMb:
  642. #endif
  643. #ifdef HAVE_AESCCM
  644. case AES256CCMb:
  645. #endif
  646. case AES256_WRAP:
  647. blockKeySz = 32;
  648. break;
  649. #endif
  650. #endif /* !NO_AES */
  651. #ifndef NO_DES3
  652. case DESb:
  653. blockKeySz = DES_KEYLEN;
  654. break;
  655. case DES3b:
  656. blockKeySz = DES3_KEYLEN;
  657. break;
  658. #endif
  659. default:
  660. WOLFSSL_MSG("Unsupported content cipher type");
  661. return ALGO_ID_E;
  662. };
  663. return blockKeySz;
  664. }
  665. PKCS7* wc_PKCS7_New(void* heap, int devId)
  666. {
  667. PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);
  668. if (pkcs7) {
  669. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  670. if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {
  671. pkcs7->isDynamic = 1;
  672. }
  673. else {
  674. XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);
  675. pkcs7 = NULL;
  676. }
  677. }
  678. return pkcs7;
  679. }
  680. /* This is to initialize a PKCS7 structure. It sets all values to 0 and can be
  681. * used to set the heap hint.
  682. *
  683. * pkcs7 PKCS7 structure to initialize
  684. * heap memory heap hint for PKCS7 structure to use
  685. * devId currently not used but a place holder for async operations
  686. *
  687. * returns 0 on success or a negative value for failure
  688. */
  689. int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)
  690. {
  691. word16 isDynamic;
  692. WOLFSSL_ENTER("wc_PKCS7_Init");
  693. if (pkcs7 == NULL) {
  694. return BAD_FUNC_ARG;
  695. }
  696. isDynamic = pkcs7->isDynamic;
  697. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  698. pkcs7->isDynamic = isDynamic;
  699. #ifdef WOLFSSL_HEAP_TEST
  700. pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;
  701. #else
  702. pkcs7->heap = heap;
  703. #endif
  704. pkcs7->devId = devId;
  705. return 0;
  706. }
  707. /* Certificate structure holding der pointer, size, and pointer to next
  708. * Pkcs7Cert struct. Used when creating SignedData types with multiple
  709. * certificates. */
  710. struct Pkcs7Cert {
  711. byte* der;
  712. word32 derSz;
  713. Pkcs7Cert* next;
  714. };
  715. /* Linked list of ASN.1 encoded RecipientInfos */
  716. struct Pkcs7EncodedRecip {
  717. byte recip[MAX_RECIP_SZ];
  718. word32 recipSz;
  719. int recipType;
  720. int recipVersion;
  721. Pkcs7EncodedRecip* next;
  722. };
  723. /* free all members of Pkcs7Cert linked list */
  724. static void wc_PKCS7_FreeCertSet(PKCS7* pkcs7)
  725. {
  726. Pkcs7Cert* curr = NULL;
  727. Pkcs7Cert* next = NULL;
  728. if (pkcs7 == NULL)
  729. return;
  730. curr = pkcs7->certList;
  731. pkcs7->certList = NULL;
  732. while (curr != NULL) {
  733. next = curr->next;
  734. curr->next = NULL;
  735. XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  736. curr = next;
  737. }
  738. return;
  739. }
  740. /* Get total size of all recipients in recipient list.
  741. *
  742. * Returns total size of recipients, or negative upon error */
  743. static int wc_PKCS7_GetRecipientListSize(PKCS7* pkcs7)
  744. {
  745. int totalSz = 0;
  746. Pkcs7EncodedRecip* tmp = NULL;
  747. if (pkcs7 == NULL)
  748. return BAD_FUNC_ARG;
  749. tmp = pkcs7->recipList;
  750. while (tmp != NULL) {
  751. totalSz += tmp->recipSz;
  752. tmp = tmp->next;
  753. }
  754. return totalSz;
  755. }
  756. /* free all members of Pkcs7EncodedRecip linked list */
  757. static void wc_PKCS7_FreeEncodedRecipientSet(PKCS7* pkcs7)
  758. {
  759. Pkcs7EncodedRecip* curr = NULL;
  760. Pkcs7EncodedRecip* next = NULL;
  761. if (pkcs7 == NULL)
  762. return;
  763. curr = pkcs7->recipList;
  764. pkcs7->recipList = NULL;
  765. while (curr != NULL) {
  766. next = curr->next;
  767. curr->next = NULL;
  768. XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  769. curr = next;
  770. }
  771. return;
  772. }
  773. /* search through RecipientInfo list for specific type.
  774. * return 1 if ANY recipient of type specified is present, otherwise
  775. * return 0 */
  776. static int wc_PKCS7_RecipientListIncludesType(PKCS7* pkcs7, int type)
  777. {
  778. Pkcs7EncodedRecip* tmp = NULL;
  779. if (pkcs7 == NULL)
  780. return BAD_FUNC_ARG;
  781. tmp = pkcs7->recipList;
  782. while (tmp != NULL) {
  783. if (tmp->recipType == type)
  784. return 1;
  785. tmp = tmp->next;
  786. }
  787. return 0;
  788. }
  789. /* searches through RecipientInfo list, returns 1 if all structure
  790. * versions are set to 0, otherwise returns 0 */
  791. static int wc_PKCS7_RecipientListVersionsAllZero(PKCS7* pkcs7)
  792. {
  793. Pkcs7EncodedRecip* tmp = NULL;
  794. if (pkcs7 == NULL)
  795. return BAD_FUNC_ARG;
  796. tmp = pkcs7->recipList;
  797. while (tmp != NULL) {
  798. if (tmp->recipVersion != 0)
  799. return 0;
  800. tmp = tmp->next;
  801. }
  802. return 1;
  803. }
  804. /* Verify RSA/ECC key is correctly formatted, used as sanity check after
  805. * import of key/cert.
  806. *
  807. * keyOID - key OID (ex: RSAk, ECDSAk)
  808. * key - key in DER
  809. * keySz - size of key, octets
  810. *
  811. * Returns 0 on success, negative on error */
  812. static int wc_PKCS7_CheckPublicKeyDer(PKCS7* pkcs7, int keyOID,
  813. const byte* key, word32 keySz)
  814. {
  815. int ret = 0;
  816. word32 scratch = 0;
  817. #ifdef WOLFSSL_SMALL_STACK
  818. #ifndef NO_RSA
  819. RsaKey* rsa;
  820. #endif
  821. #ifdef HAVE_ECC
  822. ecc_key* ecc;
  823. #endif
  824. #else
  825. #ifndef NO_RSA
  826. RsaKey rsa[1];
  827. #endif
  828. #ifdef HAVE_ECC
  829. ecc_key ecc[1];
  830. #endif
  831. #endif
  832. if (pkcs7 == NULL || key == NULL || keySz == 0) {
  833. return BAD_FUNC_ARG;
  834. }
  835. #ifdef WOLFSSL_SMALL_STACK
  836. #ifndef NO_RSA
  837. rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  838. DYNAMIC_TYPE_TMP_BUFFER);
  839. if (rsa == NULL) {
  840. return MEMORY_E;
  841. }
  842. #endif
  843. #ifdef HAVE_ECC
  844. ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  845. DYNAMIC_TYPE_TMP_BUFFER);
  846. if (ecc == NULL) {
  847. #ifndef NO_RSA
  848. XFREE(rsa, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  849. #endif
  850. return MEMORY_E;
  851. }
  852. #endif
  853. #endif
  854. switch (keyOID) {
  855. #ifndef NO_RSA
  856. case RSAk:
  857. ret = wc_InitRsaKey_ex(rsa, pkcs7->heap, pkcs7->devId);
  858. if (ret != 0) {
  859. break;
  860. }
  861. /* Try to decode public key as sanity check. wc_CheckRsaKey()
  862. only checks private key not public. */
  863. ret = wc_RsaPublicKeyDecode(key, &scratch, rsa, keySz);
  864. wc_FreeRsaKey(rsa);
  865. break;
  866. #endif
  867. #ifdef HAVE_ECC
  868. case ECDSAk:
  869. ret = wc_ecc_init_ex(ecc, pkcs7->heap, pkcs7->devId);
  870. if (ret != 0) {
  871. break;
  872. }
  873. /* Try to decode public key and check with wc_ecc_check_key() */
  874. ret = wc_EccPublicKeyDecode(key, &scratch, ecc, keySz);
  875. if (ret == 0) {
  876. ret = wc_ecc_check_key(ecc);
  877. }
  878. wc_ecc_free(ecc);
  879. break;
  880. #endif
  881. }
  882. #ifdef WOLFSSL_SMALL_STACK
  883. #ifndef NO_RSA
  884. XFREE(rsa, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  885. #endif
  886. #ifdef HAVE_ECC
  887. XFREE(ecc, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  888. #endif
  889. #endif
  890. return ret;
  891. }
  892. /* Init PKCS7 struct with recipient cert, decode into DecodedCert
  893. * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */
  894. int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  895. {
  896. int ret = 0;
  897. void* heap;
  898. int devId;
  899. Pkcs7Cert* cert;
  900. Pkcs7Cert* lastCert;
  901. if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) {
  902. return BAD_FUNC_ARG;
  903. }
  904. heap = pkcs7->heap;
  905. devId = pkcs7->devId;
  906. cert = pkcs7->certList;
  907. ret = wc_PKCS7_Init(pkcs7, heap, devId);
  908. if (ret != 0)
  909. return ret;
  910. pkcs7->certList = cert;
  911. if (derCert != NULL && derCertSz > 0) {
  912. #ifdef WOLFSSL_SMALL_STACK
  913. DecodedCert* dCert;
  914. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  915. DYNAMIC_TYPE_DCERT);
  916. if (dCert == NULL)
  917. return MEMORY_E;
  918. #else
  919. DecodedCert dCert[1];
  920. #endif
  921. pkcs7->singleCert = derCert;
  922. pkcs7->singleCertSz = derCertSz;
  923. pkcs7->cert[0] = derCert;
  924. pkcs7->certSz[0] = derCertSz;
  925. /* create new Pkcs7Cert for recipient, freed during cleanup */
  926. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  927. DYNAMIC_TYPE_PKCS7);
  928. if (cert == NULL) {
  929. #ifdef WOLFSSL_SMALL_STACK
  930. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  931. #endif
  932. return MEMORY_E;
  933. }
  934. XMEMSET(cert, 0, sizeof(Pkcs7Cert));
  935. cert->der = derCert;
  936. cert->derSz = derCertSz;
  937. cert->next = NULL;
  938. /* free existing cert list if existing */
  939. wc_PKCS7_FreeCertSet(pkcs7);
  940. /* add cert to list */
  941. if (pkcs7->certList == NULL) {
  942. pkcs7->certList = cert;
  943. } else {
  944. lastCert = pkcs7->certList;
  945. while (lastCert->next != NULL) {
  946. lastCert = lastCert->next;
  947. }
  948. lastCert->next = cert;
  949. }
  950. InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap);
  951. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  952. if (ret < 0) {
  953. FreeDecodedCert(dCert);
  954. #ifdef WOLFSSL_SMALL_STACK
  955. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  956. #endif
  957. return ret;
  958. }
  959. /* verify extracted public key is valid before storing */
  960. ret = wc_PKCS7_CheckPublicKeyDer(pkcs7, dCert->keyOID,
  961. dCert->publicKey, dCert->pubKeySize);
  962. if (ret != 0) {
  963. WOLFSSL_MSG("Invalid public key, check pkcs7->cert");
  964. FreeDecodedCert(dCert);
  965. #ifdef WOLFSSL_SMALL_STACK
  966. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  967. #endif
  968. return ret;
  969. }
  970. if (dCert->pubKeySize > (MAX_RSA_INT_SZ + MAX_RSA_E_SZ) ||
  971. dCert->serialSz > MAX_SN_SZ) {
  972. WOLFSSL_MSG("Invalid size in certificate");
  973. FreeDecodedCert(dCert);
  974. #ifdef WOLFSSL_SMALL_STACK
  975. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  976. #endif
  977. return ASN_PARSE_E;
  978. }
  979. XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
  980. pkcs7->publicKeySz = dCert->pubKeySize;
  981. pkcs7->publicKeyOID = dCert->keyOID;
  982. XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
  983. pkcs7->issuer = dCert->issuerRaw;
  984. pkcs7->issuerSz = dCert->issuerRawLen;
  985. XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
  986. pkcs7->issuerSnSz = dCert->serialSz;
  987. XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE);
  988. /* default to IssuerAndSerialNumber for SignerIdentifier */
  989. pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  990. /* free existing recipient list if existing */
  991. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  992. FreeDecodedCert(dCert);
  993. #ifdef WOLFSSL_SMALL_STACK
  994. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  995. #endif
  996. }
  997. return ret;
  998. }
  999. /* Adds one DER-formatted certificate to the internal PKCS7/CMS certificate
  1000. * list, to be added as part of the certificates CertificateSet. Currently
  1001. * used in SignedData content type.
  1002. *
  1003. * Must be called after wc_PKCS7_Init() or wc_PKCS7_InitWithCert().
  1004. *
  1005. * Does not represent the recipient/signer certificate, only certificates that
  1006. * are part of the certificate chain used to build and verify signer
  1007. * certificates.
  1008. *
  1009. * This API does not currently validate certificates.
  1010. *
  1011. * Returns 0 on success, negative upon error */
  1012. int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  1013. {
  1014. Pkcs7Cert* cert;
  1015. if (pkcs7 == NULL || derCert == NULL || derCertSz == 0)
  1016. return BAD_FUNC_ARG;
  1017. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  1018. DYNAMIC_TYPE_PKCS7);
  1019. if (cert == NULL)
  1020. return MEMORY_E;
  1021. XMEMSET(cert, 0, sizeof(Pkcs7Cert));
  1022. cert->der = derCert;
  1023. cert->derSz = derCertSz;
  1024. if (pkcs7->certList == NULL) {
  1025. pkcs7->certList = cert;
  1026. } else {
  1027. cert->next = pkcs7->certList;
  1028. pkcs7->certList = cert;
  1029. }
  1030. return 0;
  1031. }
  1032. /* free linked list of PKCS7DecodedAttrib structs */
  1033. static void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)
  1034. {
  1035. PKCS7DecodedAttrib* current;
  1036. if (attrib == NULL) {
  1037. return;
  1038. }
  1039. current = attrib;
  1040. while (current != NULL) {
  1041. PKCS7DecodedAttrib* next = current->next;
  1042. if (current->oid != NULL) {
  1043. XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);
  1044. }
  1045. if (current->value != NULL) {
  1046. XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);
  1047. }
  1048. XFREE(current, heap, DYNAMIC_TYPE_PKCS7);
  1049. current = next;
  1050. }
  1051. (void)heap;
  1052. }
  1053. /* return 0 on success */
  1054. static int wc_PKCS7_SignerInfoNew(PKCS7* pkcs7)
  1055. {
  1056. if (pkcs7->signerInfo != NULL) {
  1057. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1058. pkcs7->signerInfo = NULL;
  1059. }
  1060. pkcs7->signerInfo = (PKCS7SignerInfo*)XMALLOC(sizeof(PKCS7SignerInfo),
  1061. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1062. if (pkcs7->signerInfo == NULL) {
  1063. WOLFSSL_MSG("Unable to malloc memory for signer info");
  1064. return MEMORY_E;
  1065. }
  1066. XMEMSET(pkcs7->signerInfo, 0, sizeof(PKCS7SignerInfo));
  1067. return 0;
  1068. }
  1069. static void wc_PKCS7_SignerInfoFree(PKCS7* pkcs7)
  1070. {
  1071. if (pkcs7->signerInfo != NULL) {
  1072. if (pkcs7->signerInfo->sid != NULL) {
  1073. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1074. pkcs7->signerInfo->sid = NULL;
  1075. }
  1076. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1077. pkcs7->signerInfo = NULL;
  1078. }
  1079. }
  1080. /* free's any current SID and sets it to "in"
  1081. * returns 0 on success
  1082. */
  1083. static int wc_PKCS7_SignerInfoSetSID(PKCS7* pkcs7, byte* in, int inSz)
  1084. {
  1085. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  1086. return BAD_FUNC_ARG;
  1087. }
  1088. if (pkcs7->signerInfo->sid != NULL) {
  1089. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1090. pkcs7->signerInfo->sid = NULL;
  1091. }
  1092. pkcs7->signerInfo->sid = (byte*)XMALLOC(inSz, pkcs7->heap,
  1093. DYNAMIC_TYPE_PKCS7);
  1094. if (pkcs7->signerInfo->sid == NULL) {
  1095. return MEMORY_E;
  1096. }
  1097. XMEMCPY(pkcs7->signerInfo->sid, in, inSz);
  1098. pkcs7->signerInfo->sidSz = inSz;
  1099. return 0;
  1100. }
  1101. /* releases any memory allocated by a PKCS7 initializer */
  1102. void wc_PKCS7_Free(PKCS7* pkcs7)
  1103. {
  1104. if (pkcs7 == NULL)
  1105. return;
  1106. #ifndef NO_PKCS7_STREAM
  1107. wc_PKCS7_FreeStream(pkcs7);
  1108. #endif
  1109. wc_PKCS7_SignerInfoFree(pkcs7);
  1110. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  1111. pkcs7->decodedAttrib = NULL;
  1112. wc_PKCS7_FreeCertSet(pkcs7);
  1113. #ifdef ASN_BER_TO_DER
  1114. if (pkcs7->der != NULL) {
  1115. XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1116. pkcs7->der = NULL;
  1117. }
  1118. #endif
  1119. if (pkcs7->contentDynamic != NULL) {
  1120. XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1121. pkcs7->contentDynamic = NULL;
  1122. }
  1123. if (pkcs7->cek != NULL) {
  1124. ForceZero(pkcs7->cek, pkcs7->cekSz);
  1125. XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1126. pkcs7->cek = NULL;
  1127. }
  1128. pkcs7->contentTypeSz = 0;
  1129. if (pkcs7->signature) {
  1130. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  1131. pkcs7->signature = NULL;
  1132. pkcs7->signatureSz = 0;
  1133. }
  1134. if (pkcs7->plainDigest) {
  1135. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  1136. pkcs7->plainDigest = NULL;
  1137. pkcs7->plainDigestSz = 0;
  1138. }
  1139. if (pkcs7->pkcs7Digest) {
  1140. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  1141. pkcs7->pkcs7Digest = NULL;
  1142. pkcs7->pkcs7DigestSz = 0;
  1143. }
  1144. if (pkcs7->cachedEncryptedContent != NULL) {
  1145. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1146. pkcs7->cachedEncryptedContent = NULL;
  1147. pkcs7->cachedEncryptedContentSz = 0;
  1148. }
  1149. if (pkcs7->isDynamic) {
  1150. pkcs7->isDynamic = 0;
  1151. XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1152. }
  1153. }
  1154. /* helper function for parsing through attributes and finding a specific one.
  1155. * returns PKCS7DecodedAttrib pointer on success */
  1156. static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)
  1157. {
  1158. PKCS7DecodedAttrib* list;
  1159. if (pkcs7 == NULL || oid == NULL) {
  1160. return NULL;
  1161. }
  1162. /* search attributes for pkiStatus */
  1163. list = pkcs7->decodedAttrib;
  1164. while (list != NULL) {
  1165. word32 sz = oidSz;
  1166. word32 idx = 0;
  1167. int length = 0;
  1168. byte tag;
  1169. if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {
  1170. return NULL;
  1171. }
  1172. if (tag != ASN_OBJECT_ID) {
  1173. WOLFSSL_MSG("Bad attribute ASN1 syntax");
  1174. return NULL;
  1175. }
  1176. if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {
  1177. WOLFSSL_MSG("Bad attribute length");
  1178. return NULL;
  1179. }
  1180. sz = (sz < (word32)length)? sz : (word32)length;
  1181. if (XMEMCMP(oid, list->oid + idx, sz) == 0) {
  1182. return list;
  1183. }
  1184. list = list->next;
  1185. }
  1186. return NULL;
  1187. }
  1188. /* Searches through decoded attributes and returns the value for the first one
  1189. * matching the oid passed in. Note that this value includes the leading ASN1
  1190. * syntax. So for a printable string of "3" this would be something like
  1191. *
  1192. * 0x13, 0x01, 0x33
  1193. * ID SIZE "3"
  1194. *
  1195. * pkcs7 structure to get value from
  1196. * oid OID value to search for with attributes
  1197. * oidSz size of oid buffer
  1198. * out buffer to hold result
  1199. * outSz size of out buffer (if out is NULL this is set to needed size and
  1200. LENGTH_ONLY_E is returned)
  1201. *
  1202. * returns size of value on success
  1203. */
  1204. int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,
  1205. byte* out, word32* outSz)
  1206. {
  1207. PKCS7DecodedAttrib* attrib;
  1208. if (pkcs7 == NULL || oid == NULL || outSz == NULL) {
  1209. return BAD_FUNC_ARG;
  1210. }
  1211. attrib = findAttrib(pkcs7, oid, oidSz);
  1212. if (attrib == NULL) {
  1213. return ASN_PARSE_E;
  1214. }
  1215. if (out == NULL) {
  1216. *outSz = attrib->valueSz;
  1217. return LENGTH_ONLY_E;
  1218. }
  1219. if (*outSz < attrib->valueSz) {
  1220. return BUFFER_E;
  1221. }
  1222. XMEMCPY(out, attrib->value, attrib->valueSz);
  1223. return attrib->valueSz;
  1224. }
  1225. /* build PKCS#7 data content type */
  1226. int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
  1227. {
  1228. static const byte oid[] =
  1229. { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
  1230. 0x07, 0x01 };
  1231. byte seq[MAX_SEQ_SZ];
  1232. byte octetStr[MAX_OCTET_STR_SZ];
  1233. word32 seqSz;
  1234. word32 octetStrSz;
  1235. word32 oidSz = (word32)sizeof(oid);
  1236. int idx = 0;
  1237. if (pkcs7 == NULL || output == NULL) {
  1238. return BAD_FUNC_ARG;
  1239. }
  1240. octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
  1241. seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
  1242. if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
  1243. return BUFFER_E;
  1244. XMEMCPY(output, seq, seqSz);
  1245. idx += seqSz;
  1246. XMEMCPY(output + idx, oid, oidSz);
  1247. idx += oidSz;
  1248. XMEMCPY(output + idx, octetStr, octetStrSz);
  1249. idx += octetStrSz;
  1250. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  1251. idx += pkcs7->contentSz;
  1252. return idx;
  1253. }
  1254. typedef struct EncodedAttrib {
  1255. byte valueSeq[MAX_SEQ_SZ];
  1256. const byte* oid;
  1257. byte valueSet[MAX_SET_SZ];
  1258. const byte* value;
  1259. word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
  1260. } EncodedAttrib;
  1261. typedef struct ESD {
  1262. wc_HashAlg hash;
  1263. enum wc_HashType hashType;
  1264. byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
  1265. byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];
  1266. byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];
  1267. byte outerSeq[MAX_SEQ_SZ];
  1268. byte outerContent[MAX_EXP_SZ];
  1269. byte innerSeq[MAX_SEQ_SZ];
  1270. byte version[MAX_VERSION_SZ];
  1271. byte digAlgoIdSet[MAX_SET_SZ];
  1272. byte singleDigAlgoId[MAX_ALGO_SZ];
  1273. byte contentInfoSeq[MAX_SEQ_SZ];
  1274. byte innerContSeq[MAX_EXP_SZ];
  1275. byte innerOctets[MAX_OCTET_STR_SZ];
  1276. byte certsSet[MAX_SET_SZ];
  1277. byte signerInfoSet[MAX_SET_SZ];
  1278. byte signerInfoSeq[MAX_SEQ_SZ];
  1279. byte signerVersion[MAX_VERSION_SZ];
  1280. /* issuerAndSerialNumber ...*/
  1281. byte issuerSnSeq[MAX_SEQ_SZ];
  1282. byte issuerName[MAX_SEQ_SZ];
  1283. byte issuerSn[MAX_SN_SZ];
  1284. /* OR subjectKeyIdentifier */
  1285. byte issuerSKIDSeq[MAX_SEQ_SZ];
  1286. byte issuerSKID[MAX_OCTET_STR_SZ];
  1287. byte signerDigAlgoId[MAX_ALGO_SZ];
  1288. byte digEncAlgoId[MAX_ALGO_SZ];
  1289. byte signedAttribSet[MAX_SET_SZ];
  1290. EncodedAttrib signedAttribs[7];
  1291. byte signerDigest[MAX_OCTET_STR_SZ];
  1292. word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
  1293. word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
  1294. singleDigAlgoIdSz, certsSetSz;
  1295. word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
  1296. issuerSnSeqSz, issuerNameSz, issuerSnSz, issuerSKIDSz,
  1297. issuerSKIDSeqSz, signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
  1298. word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
  1299. signedAttribSetSz;
  1300. } ESD;
  1301. static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
  1302. PKCS7Attrib* attribs, int attribsSz)
  1303. {
  1304. int i;
  1305. int maxSz = min(eaSz, attribsSz);
  1306. int allAttribsSz = 0;
  1307. for (i = 0; i < maxSz; i++)
  1308. {
  1309. int attribSz = 0;
  1310. ea[i].value = attribs[i].value;
  1311. ea[i].valueSz = attribs[i].valueSz;
  1312. attribSz += ea[i].valueSz;
  1313. ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
  1314. attribSz += ea[i].valueSetSz;
  1315. ea[i].oid = attribs[i].oid;
  1316. ea[i].oidSz = attribs[i].oidSz;
  1317. attribSz += ea[i].oidSz;
  1318. ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
  1319. attribSz += ea[i].valueSeqSz;
  1320. ea[i].totalSz = attribSz;
  1321. allAttribsSz += attribSz;
  1322. }
  1323. return allAttribsSz;
  1324. }
  1325. typedef struct FlatAttrib {
  1326. byte* data;
  1327. word32 dataSz;
  1328. } FlatAttrib;
  1329. /* Returns a pointer to FlatAttrib whose members are initialized to 0.
  1330. * Caller is expected to free.
  1331. */
  1332. static FlatAttrib* NewAttrib(void* heap)
  1333. {
  1334. FlatAttrib* fb = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), heap,
  1335. DYNAMIC_TYPE_TMP_BUFFER);
  1336. if (fb != NULL) {
  1337. ForceZero(fb, sizeof(FlatAttrib));
  1338. }
  1339. (void)heap;
  1340. return fb;
  1341. }
  1342. /* Free FlatAttrib array and memory allocated to internal struct members */
  1343. static void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)
  1344. {
  1345. int i;
  1346. if (arr) {
  1347. for (i = 0; i < rows; i++) {
  1348. if (arr[i]) {
  1349. if (arr[i]->data) {
  1350. ForceZero(arr[i]->data, arr[i]->dataSz);
  1351. XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1352. }
  1353. ForceZero(arr[i], sizeof(FlatAttrib));
  1354. XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1355. }
  1356. }
  1357. ForceZero(arr, rows);
  1358. XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1359. }
  1360. (void)pkcs7;
  1361. }
  1362. /* Sort FlatAttrib array in ascending order */
  1363. static int SortAttribArray(FlatAttrib** arr, int rows)
  1364. {
  1365. int i, j;
  1366. word32 minSz, minIdx;
  1367. FlatAttrib* a = NULL;
  1368. FlatAttrib* b = NULL;
  1369. FlatAttrib* tmp = NULL;
  1370. if (arr == NULL) {
  1371. return BAD_FUNC_ARG;
  1372. }
  1373. for (i = 0; i < rows; i++) {
  1374. a = arr[i];
  1375. minSz = a->dataSz;
  1376. minIdx = i;
  1377. for (j = i+1; j < rows; j++) {
  1378. b = arr[j];
  1379. if (b->dataSz < minSz) {
  1380. minSz = b->dataSz;
  1381. minIdx = j;
  1382. }
  1383. }
  1384. if (minSz < a->dataSz) {
  1385. /* swap array positions */
  1386. tmp = arr[i];
  1387. arr[i] = arr[minIdx];
  1388. arr[minIdx] = tmp;
  1389. }
  1390. }
  1391. return 0;
  1392. }
  1393. /* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib
  1394. * holds flattened DER encoding of each attribute */
  1395. static int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,
  1396. EncodedAttrib* ea, int eaSz)
  1397. {
  1398. int i, idx, sz;
  1399. byte* output = NULL;
  1400. FlatAttrib* fa = NULL;
  1401. if (pkcs7 == NULL || derArr == NULL || ea == NULL) {
  1402. WOLFSSL_MSG("Invalid arguments to FlattenEncodedAttribs");
  1403. return BAD_FUNC_ARG;
  1404. }
  1405. if (rows != eaSz) {
  1406. WOLFSSL_MSG("DER array not large enough to hold attribute count");
  1407. return BAD_FUNC_ARG;
  1408. }
  1409. for (i = 0; i < eaSz; i++) {
  1410. sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;
  1411. output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1412. if (output == NULL) {
  1413. return MEMORY_E;
  1414. }
  1415. idx = 0;
  1416. XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
  1417. idx += ea[i].valueSeqSz;
  1418. XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
  1419. idx += ea[i].oidSz;
  1420. XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
  1421. idx += ea[i].valueSetSz;
  1422. XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
  1423. fa = derArr[i];
  1424. fa->data = output;
  1425. fa->dataSz = sz;
  1426. }
  1427. return 0;
  1428. }
  1429. /* Sort and Flatten EncodedAttrib attributes into output buffer */
  1430. static int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,
  1431. int eaSz)
  1432. {
  1433. int i, idx, ret;
  1434. FlatAttrib** derArr = NULL;
  1435. FlatAttrib* fa = NULL;
  1436. if (pkcs7 == NULL || output == NULL || ea == NULL) {
  1437. return BAD_FUNC_ARG;
  1438. }
  1439. /* create array of FlatAttrib struct pointers to hold DER attribs */
  1440. derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,
  1441. DYNAMIC_TYPE_TMP_BUFFER);
  1442. if (derArr == NULL) {
  1443. return MEMORY_E;
  1444. }
  1445. XMEMSET(derArr, 0, eaSz * sizeof(FlatAttrib*));
  1446. for (i = 0; i < eaSz; i++) {
  1447. derArr[i] = NewAttrib(pkcs7->heap);
  1448. if (derArr[i] == NULL) {
  1449. FreeAttribArray(pkcs7, derArr, eaSz);
  1450. return MEMORY_E;
  1451. }
  1452. ForceZero(derArr[i], sizeof(FlatAttrib));
  1453. }
  1454. /* flatten EncodedAttrib into DER byte arrays */
  1455. ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);
  1456. if (ret != 0) {
  1457. FreeAttribArray(pkcs7, derArr, eaSz);
  1458. return ret;
  1459. }
  1460. /* SET OF DER signed attributes must be sorted in ascending order */
  1461. ret = SortAttribArray(derArr, eaSz);
  1462. if (ret != 0) {
  1463. FreeAttribArray(pkcs7, derArr, eaSz);
  1464. return ret;
  1465. }
  1466. /* copy sorted DER attribute arrays into output buffer */
  1467. idx = 0;
  1468. for (i = 0; i < eaSz; i++) {
  1469. fa = derArr[i];
  1470. XMEMCPY(output + idx, fa->data, fa->dataSz);
  1471. idx += fa->dataSz;
  1472. }
  1473. FreeAttribArray(pkcs7, derArr, eaSz);
  1474. return 0;
  1475. }
  1476. #ifndef NO_RSA
  1477. /* returns size of signature put into out, negative on error */
  1478. static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1479. {
  1480. int ret;
  1481. word32 idx;
  1482. #ifdef WOLFSSL_SMALL_STACK
  1483. RsaKey* privKey;
  1484. #else
  1485. RsaKey privKey[1];
  1486. #endif
  1487. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1488. return BAD_FUNC_ARG;
  1489. }
  1490. #ifdef WOLFSSL_SMALL_STACK
  1491. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  1492. DYNAMIC_TYPE_TMP_BUFFER);
  1493. if (privKey == NULL)
  1494. return MEMORY_E;
  1495. #endif
  1496. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
  1497. if (ret == 0) {
  1498. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1499. idx = 0;
  1500. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1501. pkcs7->privateKeySz);
  1502. /* If not using old FIPS or CAVP selftest, or not using FAST,
  1503. * or USER RSA, able to check RSA key. */
  1504. if (ret == 0) {
  1505. #ifdef WOLFSSL_RSA_KEY_CHECK
  1506. /* verify imported private key is a valid key before using it */
  1507. ret = wc_CheckRsaKey(privKey);
  1508. if (ret != 0) {
  1509. WOLFSSL_MSG("Invalid RSA private key, check "
  1510. "pkcs7->privateKey");
  1511. }
  1512. #endif
  1513. }
  1514. #ifdef WOLF_CRYPTO_CB
  1515. else if (ret == ASN_PARSE_E && pkcs7->devId != INVALID_DEVID) {
  1516. /* if using crypto callbacks, try public key decode */
  1517. idx = 0;
  1518. ret = wc_RsaPublicKeyDecode(pkcs7->privateKey, &idx, privKey,
  1519. pkcs7->privateKeySz);
  1520. }
  1521. #endif
  1522. }
  1523. else if (pkcs7->devId == INVALID_DEVID) {
  1524. ret = BAD_FUNC_ARG;
  1525. }
  1526. }
  1527. if (ret == 0) {
  1528. #ifdef WOLFSSL_ASYNC_CRYPT
  1529. do {
  1530. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1531. WC_ASYNC_FLAG_CALL_AGAIN);
  1532. if (ret >= 0)
  1533. #endif
  1534. {
  1535. ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
  1536. sizeof(esd->encContentDigest),
  1537. privKey, pkcs7->rng);
  1538. }
  1539. #ifdef WOLFSSL_ASYNC_CRYPT
  1540. } while (ret == WC_PENDING_E);
  1541. #endif
  1542. }
  1543. wc_FreeRsaKey(privKey);
  1544. #ifdef WOLFSSL_SMALL_STACK
  1545. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1546. #endif
  1547. return ret;
  1548. }
  1549. #endif /* NO_RSA */
  1550. #ifdef HAVE_ECC
  1551. /* returns size of signature put into out, negative on error */
  1552. static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1553. {
  1554. int ret;
  1555. word32 outSz, idx;
  1556. #ifdef WOLFSSL_SMALL_STACK
  1557. ecc_key* privKey;
  1558. #else
  1559. ecc_key privKey[1];
  1560. #endif
  1561. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1562. return BAD_FUNC_ARG;
  1563. }
  1564. #ifdef WOLFSSL_SMALL_STACK
  1565. privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  1566. DYNAMIC_TYPE_TMP_BUFFER);
  1567. if (privKey == NULL)
  1568. return MEMORY_E;
  1569. #endif
  1570. ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);
  1571. if (ret == 0) {
  1572. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1573. idx = 0;
  1574. ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1575. pkcs7->privateKeySz);
  1576. /* verify imported private key is a valid key before using it */
  1577. if (ret == 0) {
  1578. ret = wc_ecc_check_key(privKey);
  1579. if (ret != 0) {
  1580. WOLFSSL_MSG("Invalid ECC private key, check "
  1581. "pkcs7->privateKey");
  1582. }
  1583. }
  1584. #ifdef WOLF_CRYPTO_CB
  1585. else if (ret == ASN_PARSE_E && pkcs7->devId != INVALID_DEVID) {
  1586. /* if using crypto callbacks, try public key decode */
  1587. idx = 0;
  1588. ret = wc_EccPublicKeyDecode(pkcs7->privateKey, &idx, privKey,
  1589. pkcs7->privateKeySz);
  1590. }
  1591. #endif
  1592. }
  1593. else if (pkcs7->devId == INVALID_DEVID) {
  1594. ret = BAD_FUNC_ARG;
  1595. }
  1596. }
  1597. if (ret == 0) {
  1598. outSz = sizeof(esd->encContentDigest);
  1599. #ifdef WOLFSSL_ASYNC_CRYPT
  1600. do {
  1601. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1602. WC_ASYNC_FLAG_CALL_AGAIN);
  1603. if (ret >= 0)
  1604. #endif
  1605. {
  1606. ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
  1607. &outSz, pkcs7->rng, privKey);
  1608. }
  1609. #ifdef WOLFSSL_ASYNC_CRYPT
  1610. } while (ret == WC_PENDING_E);
  1611. #endif
  1612. if (ret == 0)
  1613. ret = (int)outSz;
  1614. }
  1615. wc_ecc_free(privKey);
  1616. #ifdef WOLFSSL_SMALL_STACK
  1617. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1618. #endif
  1619. return ret;
  1620. }
  1621. #endif /* HAVE_ECC */
  1622. /* builds up SignedData signed attributes, including default ones.
  1623. *
  1624. * pkcs7 - pointer to initialized PKCS7 structure
  1625. * esd - pointer to initialized ESD structure, used for output
  1626. *
  1627. * return 0 on success, negative on error */
  1628. static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
  1629. const byte* contentType, word32 contentTypeSz,
  1630. const byte* contentTypeOid, word32 contentTypeOidSz,
  1631. const byte* messageDigestOid, word32 messageDigestOidSz,
  1632. const byte* signingTimeOid, word32 signingTimeOidSz,
  1633. byte* signingTime, word32 signingTimeSz)
  1634. {
  1635. int hashSz;
  1636. #ifdef NO_ASN_TIME
  1637. PKCS7Attrib cannedAttribs[2];
  1638. #else
  1639. time_t tm;
  1640. int timeSz;
  1641. PKCS7Attrib cannedAttribs[3];
  1642. #endif
  1643. word32 idx = 0;
  1644. word32 atrIdx = 0;
  1645. word32 cannedAttribsCount;
  1646. if (pkcs7 == NULL || esd == NULL || contentType == NULL ||
  1647. contentTypeOid == NULL || messageDigestOid == NULL ||
  1648. signingTimeOid == NULL) {
  1649. return BAD_FUNC_ARG;
  1650. }
  1651. if (pkcs7->defaultSignedAttribs != WOLFSSL_NO_ATTRIBUTES) {
  1652. hashSz = wc_HashGetDigestSize(esd->hashType);
  1653. if (hashSz < 0)
  1654. return hashSz;
  1655. #ifndef NO_ASN_TIME
  1656. if (signingTime == NULL || signingTimeSz == 0)
  1657. return BAD_FUNC_ARG;
  1658. tm = wc_Time(0);
  1659. timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz);
  1660. if (timeSz < 0)
  1661. return timeSz;
  1662. #endif
  1663. cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
  1664. if ((pkcs7->defaultSignedAttribs & WOLFSSL_CONTENT_TYPE_ATTRIBUTE) ||
  1665. pkcs7->defaultSignedAttribs == 0) {
  1666. cannedAttribs[idx].oid = contentTypeOid;
  1667. cannedAttribs[idx].oidSz = contentTypeOidSz;
  1668. cannedAttribs[idx].value = contentType;
  1669. cannedAttribs[idx].valueSz = contentTypeSz;
  1670. idx++;
  1671. }
  1672. #ifndef NO_ASN_TIME
  1673. if ((pkcs7->defaultSignedAttribs & WOLFSSL_SIGNING_TIME_ATTRIBUTE) ||
  1674. pkcs7->defaultSignedAttribs == 0) {
  1675. cannedAttribs[idx].oid = signingTimeOid;
  1676. cannedAttribs[idx].oidSz = signingTimeOidSz;
  1677. cannedAttribs[idx].value = signingTime;
  1678. cannedAttribs[idx].valueSz = timeSz;
  1679. idx++;
  1680. }
  1681. #endif
  1682. if ((pkcs7->defaultSignedAttribs & WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE) ||
  1683. pkcs7->defaultSignedAttribs == 0) {
  1684. cannedAttribs[idx].oid = messageDigestOid;
  1685. cannedAttribs[idx].oidSz = messageDigestOidSz;
  1686. cannedAttribs[idx].value = esd->contentDigest;
  1687. cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */
  1688. idx++;
  1689. }
  1690. esd->signedAttribsCount += cannedAttribsCount;
  1691. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx],
  1692. idx, cannedAttribs, cannedAttribsCount);
  1693. atrIdx += idx;
  1694. } else {
  1695. esd->signedAttribsCount = 0;
  1696. esd->signedAttribsSz = 0;
  1697. }
  1698. /* add custom signed attributes if set */
  1699. if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) {
  1700. esd->signedAttribsCount += pkcs7->signedAttribsSz;
  1701. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx],
  1702. esd->signedAttribsCount,
  1703. pkcs7->signedAttribs, pkcs7->signedAttribsSz);
  1704. }
  1705. #ifdef NO_ASN_TIME
  1706. (void)signingTimeOidSz;
  1707. (void)signingTime;
  1708. (void)signingTimeSz;
  1709. #endif
  1710. return 0;
  1711. }
  1712. /* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or
  1713. * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.
  1714. *
  1715. * pkcs7 - pointer to PKCS7 structure
  1716. * digEncAlgoId - [OUT] output int to store correct algo ID in
  1717. * digEncAlgoType - [OUT] output for algo ID type
  1718. *
  1719. * return 0 on success, negative on error */
  1720. static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
  1721. int* digEncAlgoType)
  1722. {
  1723. int algoId = 0;
  1724. int algoType = 0;
  1725. if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
  1726. return BAD_FUNC_ARG;
  1727. if (pkcs7->publicKeyOID == RSAk) {
  1728. algoType = oidSigType;
  1729. switch (pkcs7->hashOID) {
  1730. #ifndef NO_SHA
  1731. case SHAh:
  1732. algoId = CTC_SHAwRSA;
  1733. break;
  1734. #endif
  1735. #ifdef WOLFSSL_SHA224
  1736. case SHA224h:
  1737. algoId = CTC_SHA224wRSA;
  1738. break;
  1739. #endif
  1740. #ifndef NO_SHA256
  1741. case SHA256h:
  1742. algoId = CTC_SHA256wRSA;
  1743. break;
  1744. #endif
  1745. #ifdef WOLFSSL_SHA384
  1746. case SHA384h:
  1747. algoId = CTC_SHA384wRSA;
  1748. break;
  1749. #endif
  1750. #ifdef WOLFSSL_SHA512
  1751. case SHA512h:
  1752. algoId = CTC_SHA512wRSA;
  1753. break;
  1754. #endif
  1755. #ifdef WOLFSSL_SHA3
  1756. #ifndef WOLFSSL_NOSHA3_224
  1757. case SHA3_224h:
  1758. algoId = CTC_SHA3_224wRSA;
  1759. break;
  1760. #endif
  1761. #ifndef WOLFSSL_NOSHA3_256
  1762. case SHA3_256h:
  1763. algoId = CTC_SHA3_256wRSA;
  1764. break;
  1765. #endif
  1766. #ifndef WOLFSSL_NOSHA3_384
  1767. case SHA3_384h:
  1768. algoId = CTC_SHA3_384wRSA;
  1769. break;
  1770. #endif
  1771. #ifndef WOLFSSL_NOSHA3_512
  1772. case SHA3_512h:
  1773. algoId = CTC_SHA3_512wRSA;
  1774. break;
  1775. #endif
  1776. #endif
  1777. }
  1778. }
  1779. #ifdef HAVE_ECC
  1780. else if (pkcs7->publicKeyOID == ECDSAk) {
  1781. algoType = oidSigType;
  1782. switch (pkcs7->hashOID) {
  1783. #ifndef NO_SHA
  1784. case SHAh:
  1785. algoId = CTC_SHAwECDSA;
  1786. break;
  1787. #endif
  1788. #ifdef WOLFSSL_SHA224
  1789. case SHA224h:
  1790. algoId = CTC_SHA224wECDSA;
  1791. break;
  1792. #endif
  1793. #ifndef NO_SHA256
  1794. case SHA256h:
  1795. algoId = CTC_SHA256wECDSA;
  1796. break;
  1797. #endif
  1798. #ifdef WOLFSSL_SHA384
  1799. case SHA384h:
  1800. algoId = CTC_SHA384wECDSA;
  1801. break;
  1802. #endif
  1803. #ifdef WOLFSSL_SHA512
  1804. case SHA512h:
  1805. algoId = CTC_SHA512wECDSA;
  1806. break;
  1807. #endif
  1808. #ifdef WOLFSSL_SHA3
  1809. #ifndef WOLFSSL_NOSHA3_224
  1810. case SHA3_224h:
  1811. algoId = CTC_SHA3_224wECDSA;
  1812. break;
  1813. #endif
  1814. #ifndef WOLFSSL_NOSHA3_256
  1815. case SHA3_256h:
  1816. algoId = CTC_SHA3_256wECDSA;
  1817. break;
  1818. #endif
  1819. #ifndef WOLFSSL_NOSHA3_384
  1820. case SHA3_384h:
  1821. algoId = CTC_SHA3_384wECDSA;
  1822. break;
  1823. #endif
  1824. #ifndef WOLFSSL_NOSHA3_512
  1825. case SHA3_512h:
  1826. algoId = CTC_SHA3_512wECDSA;
  1827. break;
  1828. #endif
  1829. #endif
  1830. }
  1831. }
  1832. #endif /* HAVE_ECC */
  1833. if (algoId == 0) {
  1834. WOLFSSL_MSG("Invalid signature algorithm type");
  1835. return BAD_FUNC_ARG;
  1836. }
  1837. *digEncAlgoId = algoId;
  1838. *digEncAlgoType = algoType;
  1839. return 0;
  1840. }
  1841. /* build SignedData DigestInfo for use with PKCS#7/RSA
  1842. *
  1843. * pkcs7 - pointer to initialized PKCS7 struct
  1844. * flatSignedAttribs - flattened, signed attributes
  1845. * flatSignedAttrbsSz - size of flatSignedAttribs, octets
  1846. * esd - pointer to initialized ESD struct
  1847. * digestInfo - [OUT] output array for DigestInfo
  1848. * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
  1849. *
  1850. * return 0 on success, negative on error */
  1851. static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
  1852. word32 flatSignedAttribsSz, ESD* esd,
  1853. byte* digestInfo, word32* digestInfoSz)
  1854. {
  1855. int ret, hashSz, digIdx = 0;
  1856. byte digestInfoSeq[MAX_SEQ_SZ];
  1857. byte digestStr[MAX_OCTET_STR_SZ];
  1858. byte attribSet[MAX_SET_SZ];
  1859. byte algoId[MAX_ALGO_SZ];
  1860. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  1861. word32 attribSetSz;
  1862. if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||
  1863. digestInfoSz == NULL) {
  1864. return BAD_FUNC_ARG;
  1865. }
  1866. hashSz = wc_HashGetDigestSize(esd->hashType);
  1867. if (hashSz < 0)
  1868. return hashSz;
  1869. if (flatSignedAttribsSz != 0) {
  1870. if (flatSignedAttribs == NULL)
  1871. return BAD_FUNC_ARG;
  1872. attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
  1873. ret = wc_HashInit(&esd->hash, esd->hashType);
  1874. if (ret < 0)
  1875. return ret;
  1876. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1877. attribSet, attribSetSz);
  1878. if (ret == 0)
  1879. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1880. flatSignedAttribs, flatSignedAttribsSz);
  1881. if (ret == 0)
  1882. ret = wc_HashFinal(&esd->hash, esd->hashType,
  1883. esd->contentAttribsDigest);
  1884. wc_HashFree(&esd->hash, esd->hashType);
  1885. if (ret < 0)
  1886. return ret;
  1887. } else {
  1888. /* when no attrs, digest is contentDigest without tag and length */
  1889. XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);
  1890. }
  1891. /* set algoID, with NULL attributes */
  1892. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  1893. digestStrSz = SetOctetString(hashSz, digestStr);
  1894. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  1895. digestInfoSeq);
  1896. if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {
  1897. return BUFFER_E;
  1898. }
  1899. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  1900. digIdx += digestInfoSeqSz;
  1901. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  1902. digIdx += algoIdSz;
  1903. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  1904. digIdx += digestStrSz;
  1905. XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);
  1906. digIdx += hashSz;
  1907. *digestInfoSz = digIdx;
  1908. return 0;
  1909. }
  1910. /* build SignedData signature over DigestInfo or content digest
  1911. *
  1912. * pkcs7 - pointer to initialized PKCS7 struct
  1913. * flatSignedAttribs - flattened, signed attributes
  1914. * flatSignedAttribsSz - size of flatSignedAttribs, octets
  1915. * esd - pointer to initialized ESD struct
  1916. *
  1917. * returns length of signature on success, negative on error */
  1918. static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
  1919. byte* flatSignedAttribs,
  1920. word32 flatSignedAttribsSz,
  1921. ESD* esd)
  1922. {
  1923. int ret = 0;
  1924. #if defined(HAVE_ECC) || \
  1925. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1926. int hashSz = 0;
  1927. #endif
  1928. #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
  1929. int hashOID;
  1930. #endif
  1931. word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
  1932. #ifdef WOLFSSL_SMALL_STACK
  1933. byte* digestInfo;
  1934. #else
  1935. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  1936. #endif
  1937. if (pkcs7 == NULL || esd == NULL)
  1938. return BAD_FUNC_ARG;
  1939. #ifdef WOLFSSL_SMALL_STACK
  1940. digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,
  1941. DYNAMIC_TYPE_TMP_BUFFER);
  1942. if (digestInfo == NULL) {
  1943. return MEMORY_E;
  1944. }
  1945. #endif
  1946. XMEMSET(digestInfo, 0, digestInfoSz);
  1947. ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
  1948. flatSignedAttribsSz, esd, digestInfo,
  1949. &digestInfoSz);
  1950. if (ret < 0) {
  1951. #ifdef WOLFSSL_SMALL_STACK
  1952. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1953. #endif
  1954. return ret;
  1955. }
  1956. #if defined(HAVE_ECC) || \
  1957. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1958. /* get digest size from hash type */
  1959. hashSz = wc_HashGetDigestSize(esd->hashType);
  1960. if (hashSz < 0) {
  1961. #ifdef WOLFSSL_SMALL_STACK
  1962. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1963. #endif
  1964. return hashSz;
  1965. }
  1966. #endif
  1967. /* sign digestInfo */
  1968. switch (pkcs7->publicKeyOID) {
  1969. #ifndef NO_RSA
  1970. case RSAk:
  1971. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  1972. if (pkcs7->rsaSignRawDigestCb != NULL) {
  1973. /* get hash OID */
  1974. hashOID = wc_HashGetOID(esd->hashType);
  1975. /* user signing plain digest, build DigestInfo themselves */
  1976. ret = pkcs7->rsaSignRawDigestCb(pkcs7,
  1977. esd->contentAttribsDigest, hashSz,
  1978. esd->encContentDigest, sizeof(esd->encContentDigest),
  1979. pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
  1980. hashOID);
  1981. break;
  1982. }
  1983. #endif
  1984. ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
  1985. break;
  1986. #endif
  1987. #ifdef HAVE_ECC
  1988. case ECDSAk:
  1989. /* CMS with ECDSA does not sign DigestInfo structure
  1990. * like PKCS#7 with RSA does */
  1991. ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
  1992. hashSz, esd);
  1993. break;
  1994. #endif
  1995. default:
  1996. WOLFSSL_MSG("Unsupported public key type");
  1997. ret = BAD_FUNC_ARG;
  1998. }
  1999. #ifdef WOLFSSL_SMALL_STACK
  2000. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2001. #endif
  2002. if (ret >= 0) {
  2003. esd->encContentDigestSz = (word32)ret;
  2004. }
  2005. return ret;
  2006. }
  2007. /* build PKCS#7 signedData content type */
  2008. /* To get the output size then set output = 0 and *outputSz = 0 */
  2009. static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
  2010. const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,
  2011. byte* output2, word32* output2Sz)
  2012. {
  2013. /* contentType OID (1.2.840.113549.1.9.3) */
  2014. static const byte contentTypeOid[] =
  2015. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  2016. 0x09, 0x03 };
  2017. /* messageDigest OID (1.2.840.113549.1.9.4) */
  2018. static const byte messageDigestOid[] =
  2019. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  2020. 0x09, 0x04 };
  2021. /* signingTime OID () */
  2022. static const byte signingTimeOid[] =
  2023. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  2024. 0x09, 0x05};
  2025. Pkcs7Cert* certPtr = NULL;
  2026. word32 certSetSz = 0;
  2027. word32 signerInfoSz = 0;
  2028. word32 totalSz, total2Sz;
  2029. int idx = 0, ret = 0;
  2030. int digEncAlgoId, digEncAlgoType;
  2031. int keyIdSize;
  2032. byte* flatSignedAttribs = NULL;
  2033. word32 flatSignedAttribsSz = 0;
  2034. #ifdef WOLFSSL_SMALL_STACK
  2035. byte *signedDataOid = NULL;
  2036. #else
  2037. byte signedDataOid[MAX_OID_SZ];
  2038. #endif
  2039. word32 signedDataOidSz;
  2040. byte signingTime[MAX_TIME_STRING_SZ];
  2041. if (pkcs7 == NULL || pkcs7->hashOID == 0 ||
  2042. outputSz == NULL || hashSz == 0 ||
  2043. hashBuf == NULL) {
  2044. return BAD_FUNC_ARG;
  2045. }
  2046. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  2047. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  2048. pkcs7->publicKeyOID)));
  2049. #else
  2050. keyIdSize = KEYID_SIZE;
  2051. #endif
  2052. #ifdef WOLFSSL_SMALL_STACK
  2053. signedDataOid = (byte *)XMALLOC(MAX_OID_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2054. if (signedDataOid == NULL) {
  2055. idx = MEMORY_E;
  2056. goto out;
  2057. }
  2058. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2059. if (esd == NULL) {
  2060. idx = MEMORY_E;
  2061. goto out;
  2062. }
  2063. #endif
  2064. XMEMSET(esd, 0, sizeof(ESD));
  2065. /* set content type based on contentOID, unless user has set custom one
  2066. with wc_PKCS7_SetContentType() */
  2067. if (pkcs7->contentTypeSz == 0) {
  2068. /* default to DATA content type if user has not set */
  2069. if (pkcs7->contentOID == 0) {
  2070. pkcs7->contentOID = DATA;
  2071. }
  2072. ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType,
  2073. sizeof(pkcs7->contentType));
  2074. if (ret < 0) {
  2075. idx = ret;
  2076. goto out;
  2077. }
  2078. pkcs7->contentTypeSz = ret;
  2079. }
  2080. /* set signedData outer content type */
  2081. ret = wc_SetContentType(SIGNED_DATA, signedDataOid, MAX_OID_SZ);
  2082. if (ret < 0) {
  2083. idx = ret;
  2084. goto out;
  2085. }
  2086. signedDataOidSz = ret;
  2087. if (pkcs7->sidType != DEGENERATE_SID) {
  2088. esd->hashType = wc_OidGetHash(pkcs7->hashOID);
  2089. if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
  2090. WOLFSSL_MSG("hashSz did not match hashOID");
  2091. idx = BUFFER_E;
  2092. goto out;
  2093. }
  2094. /* include hash */
  2095. esd->contentDigest[0] = ASN_OCTET_STRING;
  2096. esd->contentDigest[1] = (byte)hashSz;
  2097. XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
  2098. }
  2099. if (pkcs7->detached == 1) {
  2100. /* do not include content if generating detached signature */
  2101. esd->innerOctetsSz = 0;
  2102. esd->innerContSeqSz = 0;
  2103. esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz,
  2104. esd->contentInfoSeq);
  2105. } else {
  2106. esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
  2107. esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz +
  2108. pkcs7->contentSz, esd->innerContSeq);
  2109. esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz +
  2110. esd->innerOctetsSz + pkcs7->contentTypeSz +
  2111. esd->innerContSeqSz, esd->contentInfoSeq);
  2112. }
  2113. /* SignerIdentifier */
  2114. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  2115. /* IssuerAndSerialNumber */
  2116. esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
  2117. esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ);
  2118. signerInfoSz += esd->issuerSnSz;
  2119. esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
  2120. signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
  2121. esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
  2122. signerInfoSz += esd->issuerSnSeqSz;
  2123. if (pkcs7->version == 3) {
  2124. /* RFC 4108 version MUST be 3 for firmware package signer */
  2125. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  2126. }
  2127. else {
  2128. /* version MUST be 1 otherwise*/
  2129. esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
  2130. }
  2131. } else if (pkcs7->sidType == CMS_SKID) {
  2132. /* SubjectKeyIdentifier */
  2133. esd->issuerSKIDSz = SetOctetString(keyIdSize, esd->issuerSKID);
  2134. esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + keyIdSize,
  2135. esd->issuerSKIDSeq);
  2136. signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz + keyIdSize);
  2137. /* version MUST be 3 */
  2138. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  2139. } else if (pkcs7->sidType == DEGENERATE_SID) {
  2140. /* no signer info added */
  2141. } else {
  2142. idx = SKID_E;
  2143. goto out;
  2144. }
  2145. if (pkcs7->sidType != DEGENERATE_SID) {
  2146. signerInfoSz += esd->signerVersionSz;
  2147. esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
  2148. oidHashType, 0);
  2149. signerInfoSz += esd->signerDigAlgoIdSz;
  2150. /* set signatureAlgorithm */
  2151. ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
  2152. &digEncAlgoType);
  2153. if (ret < 0) {
  2154. idx = ret;
  2155. goto out;
  2156. }
  2157. esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
  2158. digEncAlgoType, 0);
  2159. signerInfoSz += esd->digEncAlgoIdSz;
  2160. /* build up signed attributes, include contentType, signingTime, and
  2161. messageDigest by default */
  2162. ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType,
  2163. pkcs7->contentTypeSz,
  2164. contentTypeOid, sizeof(contentTypeOid),
  2165. messageDigestOid, sizeof(messageDigestOid),
  2166. signingTimeOid, sizeof(signingTimeOid),
  2167. signingTime, sizeof(signingTime));
  2168. if (ret < 0) {
  2169. idx = ret;
  2170. goto out;
  2171. }
  2172. if (esd->signedAttribsSz > 0) {
  2173. flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
  2174. DYNAMIC_TYPE_PKCS7);
  2175. if (flatSignedAttribs == NULL) {
  2176. idx = MEMORY_E;
  2177. goto out;
  2178. }
  2179. flatSignedAttribsSz = esd->signedAttribsSz;
  2180. FlattenAttributes(pkcs7, flatSignedAttribs,
  2181. esd->signedAttribs, esd->signedAttribsCount);
  2182. esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
  2183. esd->signedAttribSet);
  2184. } else {
  2185. esd->signedAttribSetSz = 0;
  2186. }
  2187. /* Calculate the final hash and encrypt it. */
  2188. ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
  2189. flatSignedAttribsSz, esd);
  2190. if (ret < 0) {
  2191. idx = ret;
  2192. goto out;
  2193. }
  2194. signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
  2195. esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
  2196. esd->signerDigest);
  2197. signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
  2198. esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
  2199. signerInfoSz += esd->signerInfoSeqSz;
  2200. }
  2201. esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
  2202. signerInfoSz += esd->signerInfoSetSz;
  2203. /* certificates [0] IMPLICIT CertificateSet */
  2204. /* get total certificates size */
  2205. certPtr = pkcs7->certList;
  2206. while (certPtr != NULL) {
  2207. certSetSz += certPtr->derSz;
  2208. certPtr = certPtr->next;
  2209. }
  2210. certPtr = NULL;
  2211. if (certSetSz > 0)
  2212. esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet);
  2213. if (pkcs7->sidType != DEGENERATE_SID) {
  2214. esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
  2215. oidHashType, 0);
  2216. }
  2217. esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
  2218. if (pkcs7->version == 3) {
  2219. /* RFC 4108 version MUST be 3 for firmware package signer */
  2220. esd->versionSz = SetMyVersion(3, esd->version, 0);
  2221. }
  2222. else {
  2223. esd->versionSz = SetMyVersion(1, esd->version, 0);
  2224. }
  2225. totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
  2226. esd->contentInfoSeqSz + pkcs7->contentTypeSz +
  2227. esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz;
  2228. total2Sz = esd->certsSetSz + certSetSz + signerInfoSz;
  2229. if (pkcs7->detached) {
  2230. totalSz -= pkcs7->contentSz;
  2231. }
  2232. esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
  2233. totalSz += esd->innerSeqSz;
  2234. esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
  2235. totalSz += esd->outerContentSz + signedDataOidSz;
  2236. esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
  2237. totalSz += esd->outerSeqSz;
  2238. /* if using header/footer, we are not returning the content */
  2239. if (output2 && output2Sz) {
  2240. if (total2Sz > *output2Sz) {
  2241. if (*outputSz == 0 && *output2Sz == 0) {
  2242. *outputSz = totalSz;
  2243. *output2Sz = total2Sz;
  2244. idx = 0;
  2245. goto out;
  2246. }
  2247. idx = BUFFER_E;
  2248. goto out;
  2249. }
  2250. if (!pkcs7->detached) {
  2251. totalSz -= pkcs7->contentSz;
  2252. }
  2253. }
  2254. else {
  2255. /* if using single output buffer include content and footer */
  2256. totalSz += total2Sz;
  2257. }
  2258. if (totalSz > *outputSz) {
  2259. if (*outputSz == 0) {
  2260. #ifdef HAVE_ECC
  2261. if (pkcs7->publicKeyOID == ECDSAk) {
  2262. totalSz += ECC_MAX_PAD_SZ; /* signatures size can vary */
  2263. }
  2264. #endif
  2265. *outputSz = totalSz;
  2266. idx = totalSz;
  2267. goto out;
  2268. }
  2269. idx = BUFFER_E;
  2270. goto out;
  2271. }
  2272. if (output == NULL) {
  2273. idx = BUFFER_E;
  2274. goto out;
  2275. }
  2276. idx = 0;
  2277. XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
  2278. idx += esd->outerSeqSz;
  2279. XMEMCPY(output + idx, signedDataOid, signedDataOidSz);
  2280. idx += signedDataOidSz;
  2281. XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
  2282. idx += esd->outerContentSz;
  2283. XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
  2284. idx += esd->innerSeqSz;
  2285. XMEMCPY(output + idx, esd->version, esd->versionSz);
  2286. idx += esd->versionSz;
  2287. XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
  2288. idx += esd->digAlgoIdSetSz;
  2289. XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
  2290. idx += esd->singleDigAlgoIdSz;
  2291. XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
  2292. idx += esd->contentInfoSeqSz;
  2293. XMEMCPY(output + idx, pkcs7->contentType, pkcs7->contentTypeSz);
  2294. idx += pkcs7->contentTypeSz;
  2295. XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
  2296. idx += esd->innerContSeqSz;
  2297. XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
  2298. idx += esd->innerOctetsSz;
  2299. /* support returning header and footer without content */
  2300. if (output2 && output2Sz) {
  2301. *outputSz = idx;
  2302. idx = 0;
  2303. }
  2304. else {
  2305. if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) {
  2306. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  2307. idx += pkcs7->contentSz;
  2308. }
  2309. output2 = output;
  2310. }
  2311. /* certificates */
  2312. XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);
  2313. idx += esd->certsSetSz;
  2314. certPtr = pkcs7->certList;
  2315. while (certPtr != NULL) {
  2316. XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz);
  2317. idx += certPtr->derSz;
  2318. certPtr = certPtr->next;
  2319. }
  2320. wc_PKCS7_FreeCertSet(pkcs7);
  2321. XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
  2322. idx += esd->signerInfoSetSz;
  2323. XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
  2324. idx += esd->signerInfoSeqSz;
  2325. XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
  2326. idx += esd->signerVersionSz;
  2327. /* SignerIdentifier */
  2328. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  2329. /* IssuerAndSerialNumber */
  2330. XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
  2331. idx += esd->issuerSnSeqSz;
  2332. XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
  2333. idx += esd->issuerNameSz;
  2334. XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
  2335. idx += pkcs7->issuerSz;
  2336. XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
  2337. idx += esd->issuerSnSz;
  2338. } else if (pkcs7->sidType == CMS_SKID) {
  2339. /* SubjectKeyIdentifier */
  2340. XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz);
  2341. idx += esd->issuerSKIDSeqSz;
  2342. XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz);
  2343. idx += esd->issuerSKIDSz;
  2344. XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, keyIdSize);
  2345. idx += keyIdSize;
  2346. } else if (pkcs7->sidType == DEGENERATE_SID) {
  2347. /* no signer infos in degenerate case */
  2348. } else {
  2349. idx = SKID_E;
  2350. goto out;
  2351. }
  2352. XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
  2353. idx += esd->signerDigAlgoIdSz;
  2354. /* SignerInfo:Attributes */
  2355. if (flatSignedAttribsSz > 0) {
  2356. XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
  2357. idx += esd->signedAttribSetSz;
  2358. XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
  2359. idx += flatSignedAttribsSz;
  2360. }
  2361. XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
  2362. idx += esd->digEncAlgoIdSz;
  2363. XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
  2364. idx += esd->signerDigestSz;
  2365. XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
  2366. idx += esd->encContentDigestSz;
  2367. if (output2Sz) {
  2368. *output2Sz = idx;
  2369. idx = 0; /* success */
  2370. }
  2371. else {
  2372. *outputSz = idx;
  2373. }
  2374. out:
  2375. if (flatSignedAttribs != NULL)
  2376. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2377. #ifdef WOLFSSL_SMALL_STACK
  2378. if (esd)
  2379. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2380. if (signedDataOid)
  2381. XFREE(signedDataOid, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2382. #endif
  2383. return idx;
  2384. }
  2385. /* hashBuf: The computed digest for the pkcs7->content
  2386. * hashSz: The size of computed digest for the pkcs7->content based on hashOID
  2387. * outputHead: The PKCS7 header that goes on top of the raw data signed.
  2388. * outputFoot: The PKCS7 footer that goes at the end of the raw data signed.
  2389. * pkcs7->content: Not used
  2390. * pkcs7->contentSz: Must be provided as actual sign of raw data
  2391. * return codes: 0=success, negative=error
  2392. */
  2393. int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  2394. word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
  2395. word32* outputFootSz)
  2396. {
  2397. int ret;
  2398. #ifdef WOLFSSL_SMALL_STACK
  2399. ESD* esd;
  2400. #else
  2401. ESD esd[1];
  2402. #endif
  2403. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2404. if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {
  2405. return BAD_FUNC_ARG;
  2406. }
  2407. #ifdef WOLFSSL_SMALL_STACK
  2408. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2409. if (esd == NULL)
  2410. return MEMORY_E;
  2411. #endif
  2412. XMEMSET(esd, 0, sizeof(ESD));
  2413. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2414. outputHead, outputHeadSz, outputFoot, outputFootSz);
  2415. #ifdef WOLFSSL_SMALL_STACK
  2416. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2417. #endif
  2418. return ret;
  2419. }
  2420. /* Toggle detached signature mode on/off for PKCS#7/CMS SignedData content type.
  2421. * By default wolfCrypt includes the data to be signed in the SignedData
  2422. * bundle. This data can be omitted in the case when a detached signature is
  2423. * being created. To enable generation of detached signatures, set flag to "1",
  2424. * otherwise set to "0":
  2425. *
  2426. * flag 1 turns on support
  2427. * flag 0 turns off support
  2428. *
  2429. * pkcs7 - pointer to initialized PKCS7 structure
  2430. * flag - turn on/off detached signature generation (1 or 0)
  2431. *
  2432. * Returns 0 on success, negative upon error. */
  2433. int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag)
  2434. {
  2435. if (pkcs7 == NULL || (flag != 0 && flag != 1))
  2436. return BAD_FUNC_ARG;
  2437. pkcs7->detached = flag;
  2438. return 0;
  2439. }
  2440. /* By default, SignedData bundles have the following signed attributes attached:
  2441. * contentType (1.2.840.113549.1.9.3)
  2442. * signingTime (1.2.840.113549.1.9.5)
  2443. * messageDigest (1.2.840.113549.1.9.4)
  2444. *
  2445. * Calling this API before wc_PKCS7_EncodeSignedData() will disable the
  2446. * inclusion of those attributes.
  2447. *
  2448. * pkcs7 - pointer to initialized PKCS7 structure
  2449. *
  2450. * Returns 0 on success, negative upon error. */
  2451. int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7)
  2452. {
  2453. return wc_PKCS7_SetDefaultSignedAttribs(pkcs7, WOLFSSL_NO_ATTRIBUTES);
  2454. }
  2455. /* By default, SignedData bundles have the following signed attributes attached:
  2456. * contentType (1.2.840.113549.1.9.3)
  2457. * signingTime (1.2.840.113549.1.9.5)
  2458. * messageDigest (1.2.840.113549.1.9.4)
  2459. *
  2460. * Calling this API before wc_PKCS7_EncodeSignedData() allows control over which
  2461. * default attributes are added.
  2462. *
  2463. * pkcs7 - pointer to initialized PKCS7 structure
  2464. *
  2465. * Returns 0 on success, negative upon error. */
  2466. int wc_PKCS7_SetDefaultSignedAttribs(PKCS7* pkcs7, word16 flag)
  2467. {
  2468. if (pkcs7 == NULL) {
  2469. return BAD_FUNC_ARG;
  2470. }
  2471. if (flag & WOLFSSL_NO_ATTRIBUTES) {
  2472. if (flag ^ WOLFSSL_NO_ATTRIBUTES) {
  2473. WOLFSSL_MSG("Error, can not have additional flags with no "
  2474. "attributes flag set");
  2475. return BAD_FUNC_ARG;
  2476. }
  2477. pkcs7->defaultSignedAttribs = 0;
  2478. }
  2479. /* check for unknown flags */
  2480. if (flag & ~(WOLFSSL_CONTENT_TYPE_ATTRIBUTE |
  2481. WOLFSSL_SIGNING_TIME_ATTRIBUTE |
  2482. WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE | WOLFSSL_NO_ATTRIBUTES)) {
  2483. WOLFSSL_MSG("Unknown attribute flags found");
  2484. return BAD_FUNC_ARG;
  2485. }
  2486. pkcs7->defaultSignedAttribs |= flag;
  2487. return 0;
  2488. }
  2489. /* return codes: >0: Size of signed PKCS7 output buffer, negative: error */
  2490. int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  2491. {
  2492. int ret;
  2493. int hashSz;
  2494. enum wc_HashType hashType;
  2495. byte hashBuf[WC_MAX_DIGEST_SIZE];
  2496. #ifdef WOLFSSL_SMALL_STACK
  2497. ESD* esd;
  2498. #else
  2499. ESD esd[1];
  2500. #endif
  2501. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2502. if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL)) {
  2503. return BAD_FUNC_ARG;
  2504. }
  2505. /* get hash type and size, validate hashOID */
  2506. hashType = wc_OidGetHash(pkcs7->hashOID);
  2507. hashSz = wc_HashGetDigestSize(hashType);
  2508. if (hashSz < 0)
  2509. return hashSz;
  2510. #ifdef WOLFSSL_SMALL_STACK
  2511. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2512. if (esd == NULL)
  2513. return MEMORY_E;
  2514. #endif
  2515. XMEMSET(esd, 0, sizeof(ESD));
  2516. esd->hashType = hashType;
  2517. /* calculate hash for content */
  2518. ret = wc_HashInit(&esd->hash, esd->hashType);
  2519. if (ret == 0) {
  2520. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  2521. pkcs7->content, pkcs7->contentSz);
  2522. if (ret == 0) {
  2523. ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);
  2524. }
  2525. wc_HashFree(&esd->hash, esd->hashType);
  2526. }
  2527. if (ret == 0) {
  2528. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2529. output, &outputSz, NULL, NULL);
  2530. }
  2531. #ifdef WOLFSSL_SMALL_STACK
  2532. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2533. #endif
  2534. return ret;
  2535. }
  2536. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2537. * content of type FirmwarePkgData. Any recipient certificates should be
  2538. * loaded into the PKCS7 structure prior to calling this function, using
  2539. * wc_PKCS7_InitWithCert() and/or wc_PKCS7_AddCertificate().
  2540. *
  2541. * pkcs7 - pointer to initialized PKCS7 struct
  2542. * privateKey - private RSA/ECC key, used for signing SignedData
  2543. * privateKeySz - size of privateKey, octets
  2544. * signOID - public key algorithm OID, used for sign operation
  2545. * hashOID - hash algorithm OID, used for signature generation
  2546. * content - content to be encapsulated, of type FirmwarePkgData
  2547. * contentSz - size of content, octets
  2548. * signedAttribs - optional signed attributes
  2549. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2550. * output - output buffer for final bundle
  2551. * outputSz - size of output buffer, octets
  2552. *
  2553. * Returns length of generated bundle on success, negative upon error. */
  2554. int wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,
  2555. word32 privateKeySz, int signOID, int hashOID,
  2556. byte* content, word32 contentSz,
  2557. PKCS7Attrib* signedAttribs, word32 signedAttribsSz,
  2558. byte* output, word32 outputSz)
  2559. {
  2560. int ret = 0;
  2561. WC_RNG rng;
  2562. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2563. content == NULL || contentSz == 0 || output == NULL || outputSz == 0)
  2564. return BAD_FUNC_ARG;
  2565. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2566. if (ret != 0)
  2567. return ret;
  2568. pkcs7->rng = &rng;
  2569. pkcs7->content = content;
  2570. pkcs7->contentSz = contentSz;
  2571. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2572. pkcs7->hashOID = hashOID;
  2573. pkcs7->encryptOID = signOID;
  2574. pkcs7->privateKey = privateKey;
  2575. pkcs7->privateKeySz = privateKeySz;
  2576. pkcs7->signedAttribs = signedAttribs;
  2577. pkcs7->signedAttribsSz = signedAttribsSz;
  2578. pkcs7->version = 3;
  2579. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2580. if (ret <= 0) {
  2581. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2582. }
  2583. pkcs7->rng = NULL;
  2584. wc_FreeRng(&rng);
  2585. return ret;
  2586. }
  2587. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2588. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2589. * CMS EncryptedData bundle. Content of inner EncryptedData is set to that
  2590. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2591. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2592. * and/or wc_PKCS7_AddCertificate().
  2593. *
  2594. * pkcs7 - pointer to initialized PKCS7 struct
  2595. * encryptKey - encryption key used for encrypting EncryptedData
  2596. * encryptKeySz - size of encryptKey, octets
  2597. * privateKey - private RSA/ECC key, used for signing SignedData
  2598. * privateKeySz - size of privateKey, octets
  2599. * encryptOID - encryption algorithm OID, to be used as encryption
  2600. * algorithm for EncryptedData
  2601. * signOID - public key algorithm OID, to be used for sign
  2602. * operation in SignedData generation
  2603. * hashOID - hash algorithm OID, to be used for signature in
  2604. * SignedData generation
  2605. * content - content to be encapsulated
  2606. * contentSz - size of content, octets
  2607. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2608. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2609. * signedAttribs - optional signed attributes, for SignedData
  2610. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2611. * output - output buffer for final bundle
  2612. * outputSz - size of output buffer, octets
  2613. *
  2614. * Returns length of generated bundle on success, negative upon error. */
  2615. int wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, byte* encryptKey,
  2616. word32 encryptKeySz, byte* privateKey,
  2617. word32 privateKeySz, int encryptOID,
  2618. int signOID, int hashOID,
  2619. byte* content, word32 contentSz,
  2620. PKCS7Attrib* unprotectedAttribs,
  2621. word32 unprotectedAttribsSz,
  2622. PKCS7Attrib* signedAttribs,
  2623. word32 signedAttribsSz,
  2624. byte* output, word32 outputSz)
  2625. {
  2626. int ret = 0, encryptedSz = 0;
  2627. byte* encrypted = NULL;
  2628. WC_RNG rng;
  2629. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2630. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2631. contentSz == 0 || output == NULL || outputSz == 0) {
  2632. return BAD_FUNC_ARG;
  2633. }
  2634. /* 1: build up EncryptedData using FirmwarePkgData type, use output
  2635. * buffer as tmp for storage and to get size */
  2636. /* set struct elements, inner content type is FirmwarePkgData */
  2637. pkcs7->content = content;
  2638. pkcs7->contentSz = contentSz;
  2639. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2640. pkcs7->encryptOID = encryptOID;
  2641. pkcs7->encryptionKey = encryptKey;
  2642. pkcs7->encryptionKeySz = encryptKeySz;
  2643. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2644. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2645. pkcs7->version = 3;
  2646. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2647. if (encryptedSz < 0) {
  2648. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2649. return encryptedSz;
  2650. }
  2651. /* save encryptedData, reset output buffer and struct */
  2652. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2653. if (encrypted == NULL) {
  2654. ForceZero(output, outputSz);
  2655. return MEMORY_E;
  2656. }
  2657. XMEMCPY(encrypted, output, encryptedSz);
  2658. ForceZero(output, outputSz);
  2659. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2660. if (ret != 0) {
  2661. ForceZero(encrypted, encryptedSz);
  2662. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2663. return ret;
  2664. }
  2665. /* 2: build up SignedData, encapsulating EncryptedData */
  2666. pkcs7->rng = &rng;
  2667. pkcs7->content = encrypted;
  2668. pkcs7->contentSz = encryptedSz;
  2669. pkcs7->contentOID = ENCRYPTED_DATA;
  2670. pkcs7->hashOID = hashOID;
  2671. pkcs7->encryptOID = signOID;
  2672. pkcs7->privateKey = privateKey;
  2673. pkcs7->privateKeySz = privateKeySz;
  2674. pkcs7->signedAttribs = signedAttribs;
  2675. pkcs7->signedAttribsSz = signedAttribsSz;
  2676. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2677. if (ret <= 0) {
  2678. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2679. }
  2680. ForceZero(encrypted, encryptedSz);
  2681. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2682. pkcs7->rng = NULL;
  2683. wc_FreeRng(&rng);
  2684. return ret;
  2685. }
  2686. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  2687. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  2688. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2689. * CMS CompressedData bundle. Content of inner CompressedData is set to that
  2690. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2691. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2692. * and/or wc_PKCS7_AddCertificate().
  2693. *
  2694. * pkcs7 - pointer to initialized PKCS7 struct
  2695. * privateKey - private RSA/ECC key, used for signing SignedData
  2696. * privateKeySz - size of privateKey, octets
  2697. * signOID - public key algorithm OID, to be used for sign
  2698. * operation in SignedData generation
  2699. * hashOID - hash algorithm OID, to be used for signature in
  2700. * SignedData generation
  2701. * content - content to be encapsulated
  2702. * contentSz - size of content, octets
  2703. * signedAttribs - optional signed attributes, for SignedData
  2704. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2705. * output - output buffer for final bundle
  2706. * outputSz - size of output buffer, octets
  2707. *
  2708. * Returns length of generated bundle on success, negative upon error. */
  2709. int wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, byte* privateKey,
  2710. word32 privateKeySz, int signOID,
  2711. int hashOID, byte* content,
  2712. word32 contentSz,
  2713. PKCS7Attrib* signedAttribs,
  2714. word32 signedAttribsSz, byte* output,
  2715. word32 outputSz)
  2716. {
  2717. int ret = 0, compressedSz = 0;
  2718. byte* compressed = NULL;
  2719. WC_RNG rng;
  2720. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2721. content == NULL || contentSz == 0 || output == NULL || outputSz == 0) {
  2722. return BAD_FUNC_ARG;
  2723. }
  2724. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2725. * buffer as tmp for storage and to get size */
  2726. /* set struct elements, inner content type is FirmwarePkgData */
  2727. pkcs7->content = content;
  2728. pkcs7->contentSz = contentSz;
  2729. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2730. pkcs7->version = 3;
  2731. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2732. if (compressedSz < 0) {
  2733. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2734. return compressedSz;
  2735. }
  2736. /* save compressedData, reset output buffer and struct */
  2737. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2738. if (compressed == NULL) {
  2739. ForceZero(output, outputSz);
  2740. return MEMORY_E;
  2741. }
  2742. XMEMCPY(compressed, output, compressedSz);
  2743. ForceZero(output, outputSz);
  2744. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2745. if (ret != 0) {
  2746. ForceZero(compressed, compressedSz);
  2747. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2748. return ret;
  2749. }
  2750. /* 2: build up SignedData, encapsulating EncryptedData */
  2751. pkcs7->rng = &rng;
  2752. pkcs7->content = compressed;
  2753. pkcs7->contentSz = compressedSz;
  2754. pkcs7->contentOID = COMPRESSED_DATA;
  2755. pkcs7->hashOID = hashOID;
  2756. pkcs7->encryptOID = signOID;
  2757. pkcs7->privateKey = privateKey;
  2758. pkcs7->privateKeySz = privateKeySz;
  2759. pkcs7->signedAttribs = signedAttribs;
  2760. pkcs7->signedAttribsSz = signedAttribsSz;
  2761. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2762. if (ret <= 0) {
  2763. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2764. }
  2765. ForceZero(compressed, compressedSz);
  2766. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2767. pkcs7->rng = NULL;
  2768. wc_FreeRng(&rng);
  2769. return ret;
  2770. }
  2771. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2772. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2773. * CMS EncryptedData bundle, which then encapsulates a CMS CompressedData
  2774. * bundle. Content of inner CompressedData is set to that of FirmwarePkgData.
  2775. * Any recipient certificates should be loaded into the PKCS7 structure prior
  2776. * to calling this function, using wc_PKCS7_InitWithCert() and/or
  2777. * wc_PKCS7_AddCertificate().
  2778. *
  2779. * pkcs7 - pointer to initialized PKCS7 struct
  2780. * encryptKey - encryption key used for encrypting EncryptedData
  2781. * encryptKeySz - size of encryptKey, octets
  2782. * privateKey - private RSA/ECC key, used for signing SignedData
  2783. * privateKeySz - size of privateKey, octets
  2784. * encryptOID - encryption algorithm OID, to be used as encryption
  2785. * algorithm for EncryptedData
  2786. * signOID - public key algorithm OID, to be used for sign
  2787. * operation in SignedData generation
  2788. * hashOID - hash algorithm OID, to be used for signature in
  2789. * SignedData generation
  2790. * content - content to be encapsulated
  2791. * contentSz - size of content, octets
  2792. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2793. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2794. * signedAttribs - optional signed attributes, for SignedData
  2795. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2796. * output - output buffer for final bundle
  2797. * outputSz - size of output buffer, octets
  2798. *
  2799. * Returns length of generated bundle on success, negative upon error. */
  2800. int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,
  2801. word32 encryptKeySz, byte* privateKey,
  2802. word32 privateKeySz, int encryptOID,
  2803. int signOID, int hashOID, byte* content,
  2804. word32 contentSz,
  2805. PKCS7Attrib* unprotectedAttribs,
  2806. word32 unprotectedAttribsSz,
  2807. PKCS7Attrib* signedAttribs,
  2808. word32 signedAttribsSz,
  2809. byte* output, word32 outputSz)
  2810. {
  2811. int ret = 0, compressedSz = 0, encryptedSz = 0;
  2812. byte* compressed = NULL;
  2813. byte* encrypted = NULL;
  2814. WC_RNG rng;
  2815. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2816. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2817. contentSz == 0 || output == NULL || outputSz == 0) {
  2818. return BAD_FUNC_ARG;
  2819. }
  2820. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2821. * buffer as tmp for storage and to get size */
  2822. pkcs7->content = content;
  2823. pkcs7->contentSz = contentSz;
  2824. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2825. pkcs7->version = 3;
  2826. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2827. if (compressedSz < 0) {
  2828. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2829. return compressedSz;
  2830. }
  2831. /* save compressedData, reset output buffer and struct */
  2832. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2833. if (compressed == NULL)
  2834. return MEMORY_E;
  2835. XMEMCPY(compressed, output, compressedSz);
  2836. ForceZero(output, outputSz);
  2837. /* 2: build up EncryptedData using CompressedData, use output
  2838. * buffer as tmp for storage and to get size */
  2839. pkcs7->content = compressed;
  2840. pkcs7->contentSz = compressedSz;
  2841. pkcs7->contentOID = COMPRESSED_DATA;
  2842. pkcs7->encryptOID = encryptOID;
  2843. pkcs7->encryptionKey = encryptKey;
  2844. pkcs7->encryptionKeySz = encryptKeySz;
  2845. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2846. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2847. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2848. if (encryptedSz < 0) {
  2849. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2850. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2851. return encryptedSz;
  2852. }
  2853. /* save encryptedData, reset output buffer and struct */
  2854. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2855. if (encrypted == NULL) {
  2856. ForceZero(compressed, compressedSz);
  2857. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2858. return MEMORY_E;
  2859. }
  2860. XMEMCPY(encrypted, output, encryptedSz);
  2861. ForceZero(compressed, compressedSz);
  2862. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2863. ForceZero(output, outputSz);
  2864. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2865. if (ret != 0) {
  2866. ForceZero(encrypted, encryptedSz);
  2867. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2868. return ret;
  2869. }
  2870. /* 3: build up SignedData, encapsulating EncryptedData */
  2871. pkcs7->rng = &rng;
  2872. pkcs7->content = encrypted;
  2873. pkcs7->contentSz = encryptedSz;
  2874. pkcs7->contentOID = ENCRYPTED_DATA;
  2875. pkcs7->hashOID = hashOID;
  2876. pkcs7->encryptOID = signOID;
  2877. pkcs7->privateKey = privateKey;
  2878. pkcs7->privateKeySz = privateKeySz;
  2879. pkcs7->signedAttribs = signedAttribs;
  2880. pkcs7->signedAttribsSz = signedAttribsSz;
  2881. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2882. if (ret <= 0) {
  2883. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2884. }
  2885. ForceZero(encrypted, encryptedSz);
  2886. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2887. pkcs7->rng = NULL;
  2888. wc_FreeRng(&rng);
  2889. return ret;
  2890. }
  2891. #endif /* !NO_PKCS7_ENCRYPTED_DATA */
  2892. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  2893. #ifndef NO_RSA
  2894. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  2895. /* register raw RSA sign digest callback */
  2896. int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
  2897. {
  2898. if (pkcs7 == NULL || cb == NULL) {
  2899. return BAD_FUNC_ARG;
  2900. }
  2901. pkcs7->rsaSignRawDigestCb = cb;
  2902. return 0;
  2903. }
  2904. #endif
  2905. /* returns size of signature put into out, negative on error */
  2906. static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  2907. byte* hash, word32 hashSz)
  2908. {
  2909. int ret = 0, i;
  2910. word32 scratch = 0, verified = 0;
  2911. #ifdef WOLFSSL_SMALL_STACK
  2912. byte* digest;
  2913. RsaKey* key;
  2914. DecodedCert* dCert;
  2915. #else
  2916. byte digest[MAX_PKCS7_DIGEST_SZ];
  2917. RsaKey key[1];
  2918. DecodedCert stack_dCert;
  2919. DecodedCert* dCert = &stack_dCert;
  2920. #endif
  2921. if (pkcs7 == NULL || sig == NULL || hash == NULL) {
  2922. return BAD_FUNC_ARG;
  2923. }
  2924. #ifdef WOLFSSL_SMALL_STACK
  2925. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2926. DYNAMIC_TYPE_TMP_BUFFER);
  2927. if (digest == NULL)
  2928. return MEMORY_E;
  2929. key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2930. if (key == NULL) {
  2931. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2932. return MEMORY_E;
  2933. }
  2934. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  2935. DYNAMIC_TYPE_DCERT);
  2936. if (dCert == NULL) {
  2937. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2938. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2939. return MEMORY_E;
  2940. }
  2941. #endif
  2942. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  2943. /* loop over certs received in certificates set, try to find one
  2944. * that will validate signature */
  2945. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  2946. verified = 0;
  2947. scratch = 0;
  2948. if (pkcs7->certSz[i] == 0)
  2949. continue;
  2950. ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);
  2951. if (ret != 0) {
  2952. #ifdef WOLFSSL_SMALL_STACK
  2953. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2954. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2955. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2956. #endif
  2957. return ret;
  2958. }
  2959. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  2960. /* not verifying, only using this to extract public key */
  2961. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  2962. if (ret < 0) {
  2963. WOLFSSL_MSG("ASN RSA cert parse error");
  2964. FreeDecodedCert(dCert);
  2965. wc_FreeRsaKey(key);
  2966. continue;
  2967. }
  2968. if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key,
  2969. dCert->pubKeySize) < 0) {
  2970. WOLFSSL_MSG("ASN RSA key decode error");
  2971. FreeDecodedCert(dCert);
  2972. wc_FreeRsaKey(key);
  2973. continue;
  2974. }
  2975. #ifdef WOLFSSL_ASYNC_CRYPT
  2976. do {
  2977. ret = wc_AsyncWait(ret, &key->asyncDev,
  2978. WC_ASYNC_FLAG_CALL_AGAIN);
  2979. #endif
  2980. if (ret >= 0) {
  2981. ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,
  2982. key);
  2983. }
  2984. #ifdef WOLFSSL_ASYNC_CRYPT
  2985. } while (ret == WC_PENDING_E);
  2986. #endif
  2987. FreeDecodedCert(dCert);
  2988. wc_FreeRsaKey(key);
  2989. if ((ret > 0) && (hashSz == (word32)ret)) {
  2990. if (XMEMCMP(digest, hash, hashSz) == 0) {
  2991. /* found signer that successfully verified signature */
  2992. verified = 1;
  2993. pkcs7->verifyCert = pkcs7->cert[i];
  2994. pkcs7->verifyCertSz = pkcs7->certSz[i];
  2995. break;
  2996. }
  2997. }
  2998. }
  2999. if (verified == 0) {
  3000. ret = SIG_VERIFY_E;
  3001. }
  3002. #ifdef WOLFSSL_SMALL_STACK
  3003. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3004. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3005. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  3006. #endif
  3007. return ret;
  3008. }
  3009. #endif /* NO_RSA */
  3010. #ifdef HAVE_ECC
  3011. /* returns size of signature put into out, negative on error */
  3012. static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  3013. byte* hash, word32 hashSz)
  3014. {
  3015. int ret = 0, i;
  3016. int res = 0;
  3017. int verified = 0;
  3018. #ifdef WOLFSSL_SMALL_STACK
  3019. byte* digest;
  3020. ecc_key* key;
  3021. DecodedCert* dCert;
  3022. #else
  3023. byte digest[MAX_PKCS7_DIGEST_SZ];
  3024. ecc_key key[1];
  3025. DecodedCert stack_dCert;
  3026. DecodedCert* dCert = &stack_dCert;
  3027. #endif
  3028. word32 idx = 0;
  3029. if (pkcs7 == NULL || sig == NULL)
  3030. return BAD_FUNC_ARG;
  3031. #ifdef WOLFSSL_SMALL_STACK
  3032. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3033. DYNAMIC_TYPE_TMP_BUFFER);
  3034. if (digest == NULL)
  3035. return MEMORY_E;
  3036. key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  3037. DYNAMIC_TYPE_TMP_BUFFER);
  3038. if (key == NULL) {
  3039. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3040. return MEMORY_E;
  3041. }
  3042. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  3043. DYNAMIC_TYPE_DCERT);
  3044. if (dCert == NULL) {
  3045. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3046. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3047. return MEMORY_E;
  3048. }
  3049. #endif
  3050. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  3051. /* loop over certs received in certificates set, try to find one
  3052. * that will validate signature */
  3053. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  3054. verified = 0;
  3055. idx = 0;
  3056. if (pkcs7->certSz[i] == 0)
  3057. continue;
  3058. ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);
  3059. if (ret != 0) {
  3060. #ifdef WOLFSSL_SMALL_STACK
  3061. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3062. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3063. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  3064. #endif
  3065. return ret;
  3066. }
  3067. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  3068. /* not verifying, only using this to extract public key */
  3069. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  3070. if (ret < 0) {
  3071. WOLFSSL_MSG("ASN ECC cert parse error");
  3072. FreeDecodedCert(dCert);
  3073. wc_ecc_free(key);
  3074. continue;
  3075. }
  3076. if (wc_EccPublicKeyDecode(dCert->publicKey, &idx, key,
  3077. dCert->pubKeySize) < 0) {
  3078. WOLFSSL_MSG("ASN ECC key decode error");
  3079. FreeDecodedCert(dCert);
  3080. wc_ecc_free(key);
  3081. continue;
  3082. }
  3083. #ifdef WOLFSSL_ASYNC_CRYPT
  3084. do {
  3085. ret = wc_AsyncWait(ret, &key->asyncDev,
  3086. WC_ASYNC_FLAG_CALL_AGAIN);
  3087. #endif
  3088. if (ret >= 0) {
  3089. ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);
  3090. }
  3091. #ifdef WOLFSSL_ASYNC_CRYPT
  3092. } while (ret == WC_PENDING_E);
  3093. #endif
  3094. FreeDecodedCert(dCert);
  3095. wc_ecc_free(key);
  3096. if (ret == 0 && res == 1) {
  3097. /* found signer that successfully verified signature */
  3098. verified = 1;
  3099. pkcs7->verifyCert = pkcs7->cert[i];
  3100. pkcs7->verifyCertSz = pkcs7->certSz[i];
  3101. break;
  3102. }
  3103. }
  3104. if (verified == 0) {
  3105. ret = SIG_VERIFY_E;
  3106. }
  3107. #ifdef WOLFSSL_SMALL_STACK
  3108. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3109. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3110. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  3111. #endif
  3112. return ret;
  3113. }
  3114. #endif /* HAVE_ECC */
  3115. /* build SignedData digest, both in PKCS#7 DigestInfo format and
  3116. * as plain digest for CMS.
  3117. *
  3118. * pkcs7 - pointer to initialized PKCS7 struct
  3119. * signedAttrib - signed attributes
  3120. * signedAttribSz - size of signedAttrib, octets
  3121. * pkcs7Digest - [OUT] PKCS#7 DigestInfo
  3122. * pkcs7DigestSz - [IN/OUT] size of pkcs7Digest
  3123. * plainDigest - [OUT] pointer to plain digest, offset into pkcs7Digest
  3124. * plainDigestSz - [OUT] size of digest at plainDigest
  3125. *
  3126. * returns 0 on success, negative on error */
  3127. static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
  3128. word32 signedAttribSz, byte* pkcs7Digest,
  3129. word32* pkcs7DigestSz, byte** plainDigest,
  3130. word32* plainDigestSz,
  3131. const byte* hashBuf, word32 hashBufSz)
  3132. {
  3133. int ret = 0, digIdx = 0;
  3134. word32 attribSetSz = 0, hashSz = 0;
  3135. byte attribSet[MAX_SET_SZ];
  3136. byte digest[WC_MAX_DIGEST_SIZE];
  3137. byte digestInfoSeq[MAX_SEQ_SZ];
  3138. byte digestStr[MAX_OCTET_STR_SZ];
  3139. byte algoId[MAX_ALGO_SZ];
  3140. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  3141. #ifdef WOLFSSL_SMALL_STACK
  3142. byte* digestInfo;
  3143. #else
  3144. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  3145. #endif
  3146. wc_HashAlg hash;
  3147. enum wc_HashType hashType;
  3148. /* check arguments */
  3149. if (pkcs7 == NULL || pkcs7Digest == NULL ||
  3150. pkcs7DigestSz == NULL || plainDigest == NULL) {
  3151. return BAD_FUNC_ARG;
  3152. }
  3153. hashType = wc_OidGetHash(pkcs7->hashOID);
  3154. ret = wc_HashGetDigestSize(hashType);
  3155. if (ret < 0)
  3156. return ret;
  3157. hashSz = ret;
  3158. if (signedAttribSz > 0) {
  3159. if (signedAttrib == NULL)
  3160. return BAD_FUNC_ARG;
  3161. }
  3162. else {
  3163. if (hashBuf && hashBufSz > 0) {
  3164. if (hashSz != hashBufSz)
  3165. return BAD_FUNC_ARG;
  3166. }
  3167. else if (pkcs7->content == NULL)
  3168. return BAD_FUNC_ARG;
  3169. }
  3170. #ifdef WOLFSSL_SMALL_STACK
  3171. digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3172. DYNAMIC_TYPE_TMP_BUFFER);
  3173. if (digestInfo == NULL)
  3174. return MEMORY_E;
  3175. #endif
  3176. XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);
  3177. XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE);
  3178. XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ);
  3179. /* calculate digest */
  3180. if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
  3181. XMEMCPY(digest, hashBuf, hashBufSz);
  3182. }
  3183. else {
  3184. ret = wc_HashInit(&hash, hashType);
  3185. if (ret < 0) {
  3186. #ifdef WOLFSSL_SMALL_STACK
  3187. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3188. #endif
  3189. return ret;
  3190. }
  3191. if (signedAttribSz > 0) {
  3192. attribSetSz = SetSet(signedAttribSz, attribSet);
  3193. /* calculate digest */
  3194. ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
  3195. if (ret == 0)
  3196. ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
  3197. if (ret == 0)
  3198. ret = wc_HashFinal(&hash, hashType, digest);
  3199. } else {
  3200. ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
  3201. if (ret == 0)
  3202. ret = wc_HashFinal(&hash, hashType, digest);
  3203. }
  3204. wc_HashFree(&hash, hashType);
  3205. if (ret < 0) {
  3206. #ifdef WOLFSSL_SMALL_STACK
  3207. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3208. #endif
  3209. return ret;
  3210. }
  3211. }
  3212. /* Set algoID, with NULL attributes */
  3213. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  3214. digestStrSz = SetOctetString(hashSz, digestStr);
  3215. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  3216. digestInfoSeq);
  3217. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  3218. digIdx += digestInfoSeqSz;
  3219. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  3220. digIdx += algoIdSz;
  3221. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  3222. digIdx += digestStrSz;
  3223. XMEMCPY(digestInfo + digIdx, digest, hashSz);
  3224. digIdx += hashSz;
  3225. XMEMCPY(pkcs7Digest, digestInfo, digIdx);
  3226. *pkcs7DigestSz = digIdx;
  3227. /* set plain digest pointer */
  3228. *plainDigest = pkcs7Digest + digIdx - hashSz;
  3229. *plainDigestSz = hashSz;
  3230. #ifdef WOLFSSL_SMALL_STACK
  3231. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3232. #endif
  3233. return 0;
  3234. }
  3235. /* Verifies CMS/PKCS7 SignedData content digest matches that which is
  3236. * included in the messageDigest signed attribute. Only called when
  3237. * signed attributes are present, otherwise original signature verification
  3238. * is done over content.
  3239. *
  3240. * pkcs7 - pointer to initialized PKCS7 struct
  3241. * hashBuf - pointer to user-provided hash buffer, used with
  3242. * wc_PKCS7_VerifySignedData_ex()
  3243. * hashBufSz - size of hashBuf, octets
  3244. *
  3245. * return 0 on success, negative on error */
  3246. static int wc_PKCS7_VerifyContentMessageDigest(PKCS7* pkcs7,
  3247. const byte* hashBuf,
  3248. word32 hashSz)
  3249. {
  3250. int ret = 0, digestSz = 0, innerAttribSz = 0;
  3251. int contentLen = 0;
  3252. word32 idx = 0;
  3253. word32 contentIdx = 0;
  3254. byte* content = NULL;
  3255. byte* digestBuf = NULL;
  3256. #ifdef WOLFSSL_SMALL_STACK
  3257. byte* digest = NULL;
  3258. #else
  3259. byte digest[MAX_PKCS7_DIGEST_SZ];
  3260. #endif
  3261. PKCS7DecodedAttrib* attrib;
  3262. enum wc_HashType hashType;
  3263. /* messageDigest OID (1.2.840.113549.1.9.4) */
  3264. const byte mdOid[] =
  3265. { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };
  3266. if (pkcs7 == NULL)
  3267. return BAD_FUNC_ARG;
  3268. if ((pkcs7->content == NULL || pkcs7->contentSz == 0) &&
  3269. (hashBuf == NULL || hashSz == 0)) {
  3270. WOLFSSL_MSG("SignedData bundle has no content or hash to verify");
  3271. return BAD_FUNC_ARG;
  3272. }
  3273. /* lookup messageDigest attribute */
  3274. attrib = findAttrib(pkcs7, mdOid, sizeof(mdOid));
  3275. if (attrib == NULL) {
  3276. WOLFSSL_MSG("messageDigest attribute not in bundle, must be when "
  3277. "signed attribs are present");
  3278. return ASN_PARSE_E;
  3279. }
  3280. /* advance past attrib->value ASN.1 header and length */
  3281. if (attrib->value == NULL || attrib->valueSz == 0)
  3282. return ASN_PARSE_E;
  3283. if (attrib->value[idx++] != ASN_OCTET_STRING)
  3284. return ASN_PARSE_E;
  3285. if (GetLength(attrib->value, &idx, &innerAttribSz, attrib->valueSz) < 0)
  3286. return ASN_PARSE_E;
  3287. /* get hash type and size */
  3288. hashType = wc_OidGetHash(pkcs7->hashOID);
  3289. if (hashType == WC_HASH_TYPE_NONE) {
  3290. WOLFSSL_MSG("Error getting hash type for PKCS7 content verification");
  3291. return BAD_FUNC_ARG;
  3292. }
  3293. /* build content hash if needed, or use existing hash value */
  3294. if (hashBuf == NULL) {
  3295. #ifdef WOLFSSL_SMALL_STACK
  3296. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3297. DYNAMIC_TYPE_TMP_BUFFER);
  3298. if (digest == NULL)
  3299. return MEMORY_E;
  3300. #endif
  3301. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  3302. content = pkcs7->content;
  3303. contentLen = pkcs7->contentSz;
  3304. if (pkcs7->contentIsPkcs7Type == 1) {
  3305. /* Content follows PKCS#7 RFC, which defines type as ANY. CMS
  3306. * mandates OCTET_STRING which has already been stripped off.
  3307. * For PKCS#7 message digest calculation, digest is calculated
  3308. * only on the "value" of the DER encoding. As such, advance past
  3309. * the tag and length */
  3310. if (contentLen > 1) {
  3311. contentIdx++;
  3312. }
  3313. if (GetLength_ex(content, &contentIdx, &contentLen,
  3314. contentLen, 1) < 0) {
  3315. #ifdef WOLFSSL_SMALL_STACK
  3316. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3317. #endif
  3318. return ASN_PARSE_E;
  3319. }
  3320. }
  3321. ret = wc_Hash(hashType, content + contentIdx, contentLen, digest,
  3322. MAX_PKCS7_DIGEST_SZ);
  3323. if (ret < 0) {
  3324. WOLFSSL_MSG("Error hashing PKCS7 content for verification");
  3325. #ifdef WOLFSSL_SMALL_STACK
  3326. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3327. #endif
  3328. return ret;
  3329. }
  3330. digestBuf = digest;
  3331. digestSz = wc_HashGetDigestSize(hashType);
  3332. if (digestSz < 0) {
  3333. WOLFSSL_MSG("Invalid hash type");
  3334. #ifdef WOLFSSL_SMALL_STACK
  3335. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3336. #endif
  3337. return digestSz;
  3338. }
  3339. } else {
  3340. /* user passed in pre-computed hash */
  3341. digestBuf = (byte*)hashBuf;
  3342. digestSz = (int)hashSz;
  3343. }
  3344. /* compare generated to hash in messageDigest attribute */
  3345. if ((innerAttribSz != digestSz) ||
  3346. (XMEMCMP(attrib->value + idx, digestBuf, (size_t)digestSz) != 0)) {
  3347. WOLFSSL_MSG("Content digest does not match messageDigest attrib value");
  3348. #ifdef WOLFSSL_SMALL_STACK
  3349. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3350. #endif
  3351. return SIG_VERIFY_E;
  3352. }
  3353. if (hashBuf == NULL) {
  3354. #ifdef WOLFSSL_SMALL_STACK
  3355. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3356. #endif
  3357. }
  3358. return 0;
  3359. }
  3360. /* verifies SignedData signature, over either PKCS#7 DigestInfo or
  3361. * content digest.
  3362. *
  3363. * pkcs7 - pointer to initialized PKCS7 struct
  3364. * sig - signature to verify
  3365. * sigSz - size of sig
  3366. * signedAttrib - signed attributes, or null if empty
  3367. * signedAttribSz - size of signedAttributes
  3368. *
  3369. * return 0 on success, negative on error */
  3370. static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
  3371. word32 sigSz, byte* signedAttrib,
  3372. word32 signedAttribSz,
  3373. const byte* hashBuf, word32 hashSz)
  3374. {
  3375. int ret = 0;
  3376. word32 plainDigestSz = 0, pkcs7DigestSz;
  3377. byte* plainDigest = NULL; /* offset into pkcs7Digest */
  3378. #ifdef WOLFSSL_SMALL_STACK
  3379. byte* pkcs7Digest;
  3380. #else
  3381. byte pkcs7Digest[MAX_PKCS7_DIGEST_SZ];
  3382. #endif
  3383. if (pkcs7 == NULL)
  3384. return BAD_FUNC_ARG;
  3385. /* allocate space to build hash */
  3386. pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;
  3387. #ifdef WOLFSSL_SMALL_STACK
  3388. pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3389. DYNAMIC_TYPE_TMP_BUFFER);
  3390. if (pkcs7Digest == NULL)
  3391. return MEMORY_E;
  3392. #endif
  3393. XMEMSET(pkcs7Digest, 0, pkcs7DigestSz);
  3394. /* verify signed attrib digest matches that of content */
  3395. if (signedAttrib != NULL) {
  3396. ret = wc_PKCS7_VerifyContentMessageDigest(pkcs7, hashBuf, hashSz);
  3397. if (ret != 0) {
  3398. #ifdef WOLFSSL_SMALL_STACK
  3399. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3400. #endif
  3401. return ret;
  3402. }
  3403. }
  3404. /* build hash to verify against */
  3405. ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
  3406. signedAttribSz, pkcs7Digest,
  3407. &pkcs7DigestSz, &plainDigest,
  3408. &plainDigestSz, hashBuf, hashSz);
  3409. if (ret < 0) {
  3410. #ifdef WOLFSSL_SMALL_STACK
  3411. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3412. #endif
  3413. return ret;
  3414. }
  3415. /* If no certificates are available then store the signature and hash for
  3416. * user to verify. Make sure that different return value than success is
  3417. * returned because the signature was not verified here. */
  3418. if (ret == 0) {
  3419. byte haveCert = 0;
  3420. int i;
  3421. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  3422. if (pkcs7->certSz[i] == 0)
  3423. continue;
  3424. haveCert = 1;
  3425. }
  3426. if (!haveCert) {
  3427. WOLFSSL_MSG("No certificates in bundle to verify signature");
  3428. /* store signature */
  3429. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  3430. pkcs7->signature = NULL;
  3431. pkcs7->signatureSz = 0;
  3432. pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap,
  3433. DYNAMIC_TYPE_SIGNATURE);
  3434. if (pkcs7->signature == NULL) {
  3435. #ifdef WOLFSSL_SMALL_STACK
  3436. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3437. #endif
  3438. return MEMORY_E;
  3439. }
  3440. XMEMCPY(pkcs7->signature, sig, sigSz);
  3441. pkcs7->signatureSz = sigSz;
  3442. /* store plain digest (CMS and ECC) */
  3443. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3444. pkcs7->plainDigest = NULL;
  3445. pkcs7->plainDigestSz = 0;
  3446. pkcs7->plainDigest = (byte*)XMALLOC(plainDigestSz, pkcs7->heap,
  3447. DYNAMIC_TYPE_DIGEST);
  3448. if (pkcs7->plainDigest == NULL) {
  3449. #ifdef WOLFSSL_SMALL_STACK
  3450. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3451. #endif
  3452. return MEMORY_E;
  3453. }
  3454. XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz);
  3455. pkcs7->plainDigestSz = plainDigestSz;
  3456. /* store pkcs7 digest (default RSA) */
  3457. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3458. pkcs7->pkcs7Digest = NULL;
  3459. pkcs7->pkcs7DigestSz = 0;
  3460. pkcs7->pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3461. DYNAMIC_TYPE_DIGEST);
  3462. if (pkcs7->pkcs7Digest == NULL) {
  3463. #ifdef WOLFSSL_SMALL_STACK
  3464. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3465. #endif
  3466. return MEMORY_E;
  3467. }
  3468. XMEMCPY(pkcs7->pkcs7Digest, pkcs7Digest, pkcs7DigestSz);
  3469. pkcs7->pkcs7DigestSz = pkcs7DigestSz;
  3470. #ifdef WOLFSSL_SMALL_STACK
  3471. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3472. #endif
  3473. return PKCS7_SIGNEEDS_CHECK;
  3474. }
  3475. }
  3476. switch (pkcs7->publicKeyOID) {
  3477. #ifndef NO_RSA
  3478. case RSAk:
  3479. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,
  3480. pkcs7DigestSz);
  3481. if (ret < 0) {
  3482. WOLFSSL_MSG("PKCS#7 verification failed, trying CMS");
  3483. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,
  3484. plainDigestSz);
  3485. }
  3486. break;
  3487. #endif
  3488. #ifdef HAVE_ECC
  3489. case ECDSAk:
  3490. ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,
  3491. plainDigestSz);
  3492. break;
  3493. #endif
  3494. default:
  3495. WOLFSSL_MSG("Unsupported public key type");
  3496. ret = BAD_FUNC_ARG;
  3497. }
  3498. #ifdef WOLFSSL_SMALL_STACK
  3499. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3500. #endif
  3501. return ret;
  3502. }
  3503. /* set correct public key OID based on signature OID, stores in
  3504. * pkcs7->publicKeyOID and returns same value */
  3505. static int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)
  3506. {
  3507. if (pkcs7 == NULL)
  3508. return BAD_FUNC_ARG;
  3509. pkcs7->publicKeyOID = 0;
  3510. switch (sigOID) {
  3511. #ifndef NO_RSA
  3512. /* RSA signature types */
  3513. case CTC_MD2wRSA:
  3514. case CTC_MD5wRSA:
  3515. case CTC_SHAwRSA:
  3516. case CTC_SHA224wRSA:
  3517. case CTC_SHA256wRSA:
  3518. case CTC_SHA384wRSA:
  3519. case CTC_SHA512wRSA:
  3520. case CTC_SHA3_224wRSA:
  3521. case CTC_SHA3_256wRSA:
  3522. case CTC_SHA3_384wRSA:
  3523. case CTC_SHA3_512wRSA:
  3524. pkcs7->publicKeyOID = RSAk;
  3525. break;
  3526. /* if sigOID is already RSAk */
  3527. case RSAk:
  3528. pkcs7->publicKeyOID = sigOID;
  3529. break;
  3530. #endif
  3531. #ifndef NO_DSA
  3532. /* DSA signature types */
  3533. case CTC_SHAwDSA:
  3534. pkcs7->publicKeyOID = DSAk;
  3535. break;
  3536. /* if sigOID is already DSAk */
  3537. case DSAk:
  3538. pkcs7->publicKeyOID = sigOID;
  3539. break;
  3540. #endif
  3541. #ifdef HAVE_ECC
  3542. /* ECDSA signature types */
  3543. case CTC_SHAwECDSA:
  3544. case CTC_SHA224wECDSA:
  3545. case CTC_SHA256wECDSA:
  3546. case CTC_SHA384wECDSA:
  3547. case CTC_SHA512wECDSA:
  3548. case CTC_SHA3_224wECDSA:
  3549. case CTC_SHA3_256wECDSA:
  3550. case CTC_SHA3_384wECDSA:
  3551. case CTC_SHA3_512wECDSA:
  3552. pkcs7->publicKeyOID = ECDSAk;
  3553. break;
  3554. /* if sigOID is already ECDSAk */
  3555. case ECDSAk:
  3556. pkcs7->publicKeyOID = sigOID;
  3557. break;
  3558. #endif
  3559. default:
  3560. WOLFSSL_MSG("Unsupported public key algorithm");
  3561. return ASN_SIG_KEY_E;
  3562. }
  3563. return pkcs7->publicKeyOID;
  3564. }
  3565. /* Parses through the attributes and adds them to the PKCS7 structure
  3566. * Creates dynamic attribute structures that are free'd with calling
  3567. * wc_PKCS7_Free()
  3568. *
  3569. * NOTE: An attribute has the ASN1 format of
  3570. ** Sequence
  3571. ****** Object ID
  3572. ****** Set
  3573. ********** {PrintableString, UTCTime, OCTET STRING ...}
  3574. *
  3575. * pkcs7 the PKCS7 structure to put the parsed attributes into
  3576. * in buffer holding all attributes
  3577. * inSz size of in buffer
  3578. *
  3579. * returns the number of attributes parsed on success
  3580. */
  3581. static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
  3582. {
  3583. int found = 0;
  3584. word32 idx = 0;
  3585. word32 oid;
  3586. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  3587. return BAD_FUNC_ARG;
  3588. }
  3589. while (idx < (word32)inSz) {
  3590. int length = 0;
  3591. int oidIdx;
  3592. PKCS7DecodedAttrib* attrib;
  3593. if (GetSequence(in, &idx, &length, inSz) < 0)
  3594. return ASN_PARSE_E;
  3595. attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),
  3596. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3597. if (attrib == NULL) {
  3598. return MEMORY_E;
  3599. }
  3600. XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));
  3601. oidIdx = idx;
  3602. if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)
  3603. < 0) {
  3604. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3605. return ASN_PARSE_E;
  3606. }
  3607. attrib->oidSz = idx - oidIdx;
  3608. attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,
  3609. DYNAMIC_TYPE_PKCS7);
  3610. if (attrib->oid == NULL) {
  3611. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3612. return MEMORY_E;
  3613. }
  3614. XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);
  3615. /* Get Set that contains the printable string value */
  3616. if (GetSet(in, &idx, &length, inSz) < 0) {
  3617. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3618. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3619. return ASN_PARSE_E;
  3620. }
  3621. if ((inSz - idx) < (word32)length) {
  3622. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3623. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3624. return ASN_PARSE_E;
  3625. }
  3626. attrib->valueSz = (word32)length;
  3627. attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,
  3628. DYNAMIC_TYPE_PKCS7);
  3629. if (attrib->value == NULL) {
  3630. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3631. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3632. return MEMORY_E;
  3633. }
  3634. XMEMCPY(attrib->value, in + idx, attrib->valueSz);
  3635. idx += length;
  3636. /* store attribute in linked list */
  3637. if (pkcs7->decodedAttrib != NULL) {
  3638. attrib->next = pkcs7->decodedAttrib;
  3639. pkcs7->decodedAttrib = attrib;
  3640. } else {
  3641. pkcs7->decodedAttrib = attrib;
  3642. }
  3643. found++;
  3644. }
  3645. return found;
  3646. }
  3647. /* option to turn off support for degenerate cases
  3648. * flag 0 turns off support
  3649. * flag 1 turns on support
  3650. *
  3651. * by default support for SignedData degenerate cases is on
  3652. */
  3653. void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
  3654. {
  3655. if (pkcs7) {
  3656. if (flag) { /* flag of 1 turns on support for degenerate */
  3657. pkcs7->noDegenerate = 0;
  3658. }
  3659. else { /* flag of 0 turns off support */
  3660. pkcs7->noDegenerate = 1;
  3661. }
  3662. }
  3663. }
  3664. /* Parses through a signerInfo set. Reads buffer "in" from "idxIn" to "idxIn" +
  3665. * length treating the current "idxIn" plus the length of set as max possible
  3666. * index.
  3667. *
  3668. * In the case that signed attributes are found "signedAttrib" gets set to point
  3669. * at their location in the buffer "in". Also in this case signedAttribSz gets
  3670. * set to the size of the signedAttrib buffer.
  3671. *
  3672. * returns 0 on success
  3673. */
  3674. static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
  3675. word32* idxIn, int degenerate, byte** signedAttrib, int* signedAttribSz)
  3676. {
  3677. int ret = 0;
  3678. int length;
  3679. int version;
  3680. word32 sigOID = 0, hashOID = 0;
  3681. word32 idx = *idxIn, localIdx;
  3682. byte tag;
  3683. WOLFSSL_ENTER("wc_PKCS7_ParseSignerInfo");
  3684. /* require a signer if degenerate case not allowed */
  3685. if (inSz == 0 && pkcs7->noDegenerate == 1) {
  3686. WOLFSSL_MSG("Set to not allow degenerate cases");
  3687. return PKCS7_NO_SIGNER_E;
  3688. }
  3689. if (inSz == 0 && degenerate == 0) {
  3690. WOLFSSL_MSG("PKCS7 signers expected");
  3691. return PKCS7_NO_SIGNER_E;
  3692. }
  3693. /* not a degenerate case and there is elements in the set */
  3694. if (inSz > 0 && degenerate == 0) {
  3695. ret = wc_PKCS7_SignerInfoNew(pkcs7);
  3696. /* Get the sequence of the first signerInfo */
  3697. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3698. ret = ASN_PARSE_E;
  3699. /* Get the version */
  3700. if (ret == 0 && GetMyVersion(in, &idx, &version, inSz) < 0)
  3701. ret = ASN_PARSE_E;
  3702. if (ret == 0) {
  3703. pkcs7->signerInfo->version = version;
  3704. }
  3705. if (ret == 0 && version == 1) {
  3706. /* Get the sequence of IssuerAndSerialNumber */
  3707. if (GetSequence(in, &idx, &length, inSz) < 0)
  3708. ret = ASN_PARSE_E;
  3709. if (ret == 0) {
  3710. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3711. idx += length;
  3712. }
  3713. } else if (ret == 0 && version == 3) {
  3714. /* Get the sequence of SubjectKeyIdentifier */
  3715. if (idx + 1 > inSz)
  3716. ret = BUFFER_E;
  3717. localIdx = idx;
  3718. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3719. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3720. idx++;
  3721. if (GetLength(in, &idx, &length, inSz) <= 0)
  3722. ret = ASN_PARSE_E;
  3723. if (ret == 0 && idx + 1 > inSz)
  3724. ret = BUFFER_E;
  3725. if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)
  3726. ret = ASN_PARSE_E;
  3727. if (ret == 0 && tag != ASN_OCTET_STRING)
  3728. ret = ASN_PARSE_E;
  3729. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3730. ret = ASN_PARSE_E;
  3731. }
  3732. else {
  3733. /* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version
  3734. * 3 try to get issuerAndSerial */
  3735. localIdx = idx;
  3736. if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3737. tag == ASN_CONTEXT_SPECIFIC) {
  3738. idx++;
  3739. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3740. ret = ASN_PARSE_E;
  3741. }
  3742. else {
  3743. if (pkcs7->version != 3) {
  3744. WOLFSSL_MSG("Unexpected signer info found with version");
  3745. ret = ASN_PARSE_E;
  3746. }
  3747. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3748. ret = ASN_PARSE_E;
  3749. }
  3750. }
  3751. if (ret == 0) {
  3752. if (length > (int)inSz - (int)idx)
  3753. ret = BUFFER_E;
  3754. }
  3755. if (ret == 0) {
  3756. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3757. idx += length;
  3758. }
  3759. } else {
  3760. WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3");
  3761. ret = ASN_VERSION_E;
  3762. }
  3763. /* Get the sequence of digestAlgorithm */
  3764. if (ret == 0 && GetAlgoId(in, &idx, &hashOID, oidHashType, inSz) < 0) {
  3765. ret = ASN_PARSE_E;
  3766. }
  3767. pkcs7->hashOID = (int)hashOID;
  3768. /* Get the IMPLICIT[0] SET OF signedAttributes */
  3769. localIdx = idx;
  3770. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3771. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3772. idx++;
  3773. if (GetLength(in, &idx, &length, inSz) < 0)
  3774. ret = ASN_PARSE_E;
  3775. /* save pointer and length */
  3776. *signedAttrib = &in[idx];
  3777. *signedAttribSz = length;
  3778. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, *signedAttrib,
  3779. *signedAttribSz) < 0) {
  3780. WOLFSSL_MSG("Error parsing signed attributes");
  3781. ret = ASN_PARSE_E;
  3782. }
  3783. idx += length;
  3784. }
  3785. /* Get digestEncryptionAlgorithm - key type or signature type */
  3786. if (ret == 0 && GetAlgoId(in, &idx, &sigOID, oidIgnoreType, inSz) < 0) {
  3787. ret = ASN_PARSE_E;
  3788. }
  3789. /* store public key type based on digestEncryptionAlgorithm */
  3790. if (ret == 0) {
  3791. ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
  3792. if (ret < 0) {
  3793. WOLFSSL_MSG("Failed to set public key OID from signature");
  3794. }
  3795. else {
  3796. /* if previous return was positive then was success */
  3797. ret = 0;
  3798. }
  3799. }
  3800. }
  3801. /* update index on success */
  3802. if (ret == 0) {
  3803. *idxIn = idx;
  3804. }
  3805. return ret;
  3806. }
  3807. /* Finds the certificates in the message and saves it. By default allows
  3808. * degenerate cases which can have no signer.
  3809. *
  3810. * By default expects type SIGNED_DATA (SignedData) which can have any number of
  3811. * elements in signerInfos collection, including zero. (RFC2315 section 9.1)
  3812. * When adding support for the case of SignedAndEnvelopedData content types a
  3813. * signer is required. In this case the PKCS7 flag noDegenerate could be set.
  3814. */
  3815. static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
  3816. word32 hashSz, byte* in, word32 inSz,
  3817. byte* in2, word32 in2Sz)
  3818. {
  3819. word32 idx, maxIdx = inSz, outerContentType, contentTypeSz = 0, totalSz = 0;
  3820. int length = 0, version = 0, ret = 0;
  3821. byte* content = NULL;
  3822. byte* contentDynamic = NULL;
  3823. byte* sig = NULL;
  3824. byte* cert = NULL;
  3825. byte* signedAttrib = NULL;
  3826. byte* contentType = NULL;
  3827. int encapContentInfoLen = 0;
  3828. int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
  3829. word32 localIdx, start;
  3830. byte degenerate = 0;
  3831. byte detached = 0;
  3832. byte tag = 0;
  3833. word16 contentIsPkcs7Type = 0;
  3834. #ifdef ASN_BER_TO_DER
  3835. byte* der;
  3836. #endif
  3837. int multiPart = 0, keepContent;
  3838. int contentLen = 0;
  3839. byte* pkiMsg = in;
  3840. word32 pkiMsgSz = inSz;
  3841. #ifndef NO_PKCS7_STREAM
  3842. word32 stateIdx = 0;
  3843. #endif
  3844. byte* pkiMsg2 = in2;
  3845. word32 pkiMsg2Sz = in2Sz;
  3846. if (pkcs7 == NULL)
  3847. return BAD_FUNC_ARG;
  3848. #ifndef NO_PKCS7_STREAM
  3849. /* allow for 0 size inputs with stream mode */
  3850. if (pkiMsg == NULL && pkiMsgSz > 0)
  3851. return BAD_FUNC_ARG;
  3852. #else
  3853. if (pkiMsg == NULL || pkiMsgSz == 0)
  3854. return BAD_FUNC_ARG;
  3855. #endif
  3856. if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
  3857. return BAD_FUNC_ARG;
  3858. }
  3859. idx = 0;
  3860. #ifdef ASN_BER_TO_DER
  3861. if (pkcs7->derSz > 0 && pkcs7->der) {
  3862. pkiMsg = pkcs7->der;
  3863. }
  3864. #endif
  3865. #ifndef NO_PKCS7_STREAM
  3866. if (pkcs7->stream == NULL) {
  3867. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  3868. return ret;
  3869. }
  3870. }
  3871. #endif
  3872. switch (pkcs7->state) {
  3873. case WC_PKCS7_START:
  3874. #ifndef NO_PKCS7_STREAM
  3875. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  3876. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
  3877. ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
  3878. &pkiMsg, &idx)) != 0) {
  3879. break;
  3880. }
  3881. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  3882. break;
  3883. }
  3884. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  3885. inSz;
  3886. #endif
  3887. /* determine total message size */
  3888. totalSz = pkiMsgSz;
  3889. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3890. totalSz += pkiMsg2Sz + pkcs7->contentSz;
  3891. }
  3892. /* Get the contentInfo sequence */
  3893. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3894. NO_USER_CHECK) < 0)
  3895. ret = ASN_PARSE_E;
  3896. if (ret == 0 && length == 0 && pkiMsg[idx-1] == ASN_INDEF_LENGTH) {
  3897. #ifdef ASN_BER_TO_DER
  3898. word32 len = 0;
  3899. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  3900. if (ret != LENGTH_ONLY_E)
  3901. return ret;
  3902. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3903. if (pkcs7->der == NULL)
  3904. return MEMORY_E;
  3905. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  3906. if (ret < 0)
  3907. return ret;
  3908. pkiMsg = in = pkcs7->der;
  3909. inSz = pkcs7->derSz = len;
  3910. idx = 0;
  3911. #ifdef NO_PKCS7_STREAM
  3912. pkiMsgSz = len;
  3913. #else
  3914. wc_PKCS7_ResetStream(pkcs7);
  3915. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  3916. MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_SEQ_SZ +
  3917. MAX_LENGTH_SZ + ASN_TAG_SZ + MAX_OID_SZ +
  3918. MAX_SEQ_SZ, &pkiMsg, &idx)) != 0) {
  3919. break;
  3920. }
  3921. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  3922. inSz;
  3923. totalSz = pkiMsgSz;
  3924. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3925. totalSz += pkiMsg2Sz + pkcs7->contentSz;
  3926. }
  3927. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, len)) != 0) {
  3928. break;
  3929. }
  3930. #endif
  3931. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  3932. NO_USER_CHECK) < 0)
  3933. return ASN_PARSE_E;
  3934. #else
  3935. ret = BER_INDEF_E;
  3936. #endif
  3937. }
  3938. /* Get the contentInfo contentType */
  3939. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,
  3940. pkiMsgSz) < 0)
  3941. ret = ASN_PARSE_E;
  3942. if (ret == 0 && outerContentType != SIGNED_DATA) {
  3943. WOLFSSL_MSG("PKCS#7 input not of type SignedData");
  3944. ret = PKCS7_OID_E;
  3945. }
  3946. /* get the ContentInfo content */
  3947. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)
  3948. ret = ASN_PARSE_E;
  3949. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  3950. ret = ASN_PARSE_E;
  3951. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,
  3952. NO_USER_CHECK) < 0)
  3953. ret = ASN_PARSE_E;
  3954. /* Get the signedData sequence */
  3955. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3956. NO_USER_CHECK) < 0)
  3957. ret = ASN_PARSE_E;
  3958. /* Get the version */
  3959. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  3960. ret = ASN_PARSE_E;
  3961. /* version 1 follows RFC 2315 */
  3962. /* version 3 follows RFC 4108 */
  3963. if (ret == 0 && (version != 1 && version != 3)) {
  3964. WOLFSSL_MSG("PKCS#7 signedData needs to be version 1 or 3");
  3965. ret = ASN_VERSION_E;
  3966. }
  3967. pkcs7->version = (byte)version;
  3968. /* Get the set of DigestAlgorithmIdentifiers */
  3969. if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  3970. ret = ASN_PARSE_E;
  3971. /* Skip the set. */
  3972. idx += length;
  3973. degenerate = (length == 0) ? 1 : 0;
  3974. if (pkcs7->noDegenerate == 1 && degenerate == 1) {
  3975. ret = PKCS7_NO_SIGNER_E;
  3976. }
  3977. if (ret != 0)
  3978. break;
  3979. #ifndef NO_PKCS7_STREAM
  3980. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  3981. break;
  3982. }
  3983. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3984. pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz;
  3985. }
  3986. wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);
  3987. #endif
  3988. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);
  3989. FALL_THROUGH;
  3990. case WC_PKCS7_VERIFY_STAGE2:
  3991. #ifndef NO_PKCS7_STREAM
  3992. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  3993. MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ
  3994. + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  3995. break;
  3996. }
  3997. wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
  3998. if (pkcs7->stream->length > 0)
  3999. pkiMsgSz = pkcs7->stream->length;
  4000. #ifdef ASN_BER_TO_DER
  4001. else if (pkcs7->der)
  4002. pkiMsgSz = pkcs7->derSz;
  4003. #endif
  4004. else
  4005. pkiMsgSz = inSz;
  4006. #endif
  4007. /* Get the inner ContentInfo sequence */
  4008. if (GetSequence_ex(pkiMsg, &idx, &encapContentInfoLen, pkiMsgSz,
  4009. NO_USER_CHECK) < 0)
  4010. ret = ASN_PARSE_E;
  4011. /* Get the inner ContentInfo contentType */
  4012. if (ret == 0) {
  4013. int isIndef = 0;
  4014. word32 tmpIdx = idx;
  4015. if (encapContentInfoLen == 0 &&
  4016. pkiMsg[idx-1] == ASN_INDEF_LENGTH) {
  4017. isIndef = 1;
  4018. }
  4019. if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) == 0) {
  4020. contentType = pkiMsg + tmpIdx;
  4021. contentTypeSz = length + (idx - tmpIdx);
  4022. idx += length;
  4023. }
  4024. else {
  4025. ret = ASN_PARSE_E;
  4026. }
  4027. /* if indef, skip EOF */
  4028. if (isIndef) {
  4029. if (idx + 1 >= pkiMsgSz) {
  4030. ret = ASN_PARSE_E;
  4031. }
  4032. else if (pkiMsg[idx] == ASN_EOC && pkiMsg[idx+1] == 0) {
  4033. idx += 2; /* skip EOF + zero byte */
  4034. }
  4035. }
  4036. }
  4037. if (ret != 0)
  4038. break;
  4039. /* Check for content, it could be omitted when degenerate */
  4040. localIdx = idx;
  4041. ret = 0;
  4042. if (localIdx + 1 > pkiMsgSz) {
  4043. ret = BUFFER_E;
  4044. break;
  4045. }
  4046. /* Set error state if no more data left in ContentInfo, meaning
  4047. * no content - may be detached. Will recover from error below */
  4048. if ((encapContentInfoLen != 0) &&
  4049. (encapContentInfoLen - contentTypeSz == 0)) {
  4050. ret = ASN_PARSE_E;
  4051. }
  4052. /* PKCS#7 spec:
  4053. * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
  4054. * CMS spec:
  4055. * eContent [0] EXPLICIT OCTET STRING OPTIONAL
  4056. */
  4057. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)
  4058. ret = ASN_PARSE_E;
  4059. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  4060. ret = ASN_PARSE_E;
  4061. /* Get length of inner eContent payload. For CMS, spec defines
  4062. * OCTET_STRING will be next. If so, we use the length retrieved
  4063. * there. PKCS#7 spec defines ANY as eContent type. In this case
  4064. * we fall back and save this content length for use later */
  4065. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
  4066. NO_USER_CHECK) <= 0) {
  4067. ret = ASN_PARSE_E;
  4068. }
  4069. if (localIdx >= pkiMsgSz) {
  4070. ret = BUFFER_E;
  4071. }
  4072. /* Save idx to back up in case of PKCS#7 eContent */
  4073. start = localIdx;
  4074. /* get length of content in the case that there is multiple parts */
  4075. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  4076. ret = ASN_PARSE_E;
  4077. if (ret == 0 &&
  4078. (tag != (ASN_OCTET_STRING | ASN_CONSTRUCTED) &&
  4079. (tag != ASN_OCTET_STRING))) {
  4080. /* If reached end of ContentInfo, or we see the next element
  4081. * ([0] IMPLICIT CertificateSet), set error state. Either
  4082. * true error or detached */
  4083. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  4084. ret = ASN_PARSE_E;
  4085. }
  4086. /* Back up before getting tag, process as PKCS#7 ANY and use
  4087. * this as start of content. */
  4088. localIdx = start;
  4089. pkcs7->contentIsPkcs7Type = 1;
  4090. }
  4091. else {
  4092. /* CMS eContent OCTET_STRING */
  4093. if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
  4094. multiPart = 1;
  4095. /* Get length of all OCTET_STRINGs. */
  4096. if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,
  4097. NO_USER_CHECK) < 0)
  4098. ret = ASN_PARSE_E;
  4099. /* Check whether there is one OCTET_STRING inside. */
  4100. start = localIdx;
  4101. if (localIdx >= pkiMsgSz) {
  4102. ret = BUFFER_E;
  4103. }
  4104. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)
  4105. != 0)
  4106. ret = ASN_PARSE_E;
  4107. if (ret == 0 && tag != ASN_OCTET_STRING)
  4108. ret = ASN_PARSE_E;
  4109. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length,
  4110. pkiMsgSz, NO_USER_CHECK) < 0)
  4111. ret = ASN_PARSE_E;
  4112. if (ret == 0) {
  4113. /* Use single OCTET_STRING directly, or reset length. */
  4114. if (localIdx - start + length == (word32)contentLen) {
  4115. multiPart = 0;
  4116. } else {
  4117. /* reset length to outer OCTET_STRING for bundle
  4118. * size check below */
  4119. length = contentLen;
  4120. }
  4121. localIdx = start;
  4122. }
  4123. if (ret != 0) {
  4124. /* failed ASN1 parsing during OCTET_STRING checks */
  4125. break;
  4126. }
  4127. }
  4128. /* get length of content in case of single part */
  4129. if (ret == 0 && !multiPart) {
  4130. if (tag != ASN_OCTET_STRING)
  4131. ret = ASN_PARSE_E;
  4132. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
  4133. &length, pkiMsgSz, NO_USER_CHECK) < 0)
  4134. ret = ASN_PARSE_E;
  4135. }
  4136. }
  4137. /* update idx if successful */
  4138. if (ret == 0) {
  4139. /* support using header and footer without content */
  4140. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  4141. localIdx = 0;
  4142. } else if (pkiMsg2 == NULL && hashBuf == NULL) {
  4143. /* header/footer not separate, check content length is
  4144. * not larger than total bundle size */
  4145. if ((localIdx + length) > pkiMsgSz) {
  4146. WOLFSSL_MSG("Content length detected is larger than "
  4147. "total bundle size");
  4148. ret = BUFFER_E;
  4149. break;
  4150. }
  4151. }
  4152. idx = localIdx;
  4153. }
  4154. else {
  4155. /* If either pkcs7->content and pkcs7->contentSz are set
  4156. * (detached signature where user has set content explicitly
  4157. * into pkcs7->content/contentSz) OR pkcs7->hashBuf and
  4158. * pkcs7->hashSz are set (user has pre-computed content
  4159. * digest and passed in instead of content directly), try to
  4160. * process as a detached signature */
  4161. if (!degenerate &&
  4162. ((pkcs7->content != NULL && pkcs7->contentSz != 0) ||
  4163. (hashBuf != NULL && hashSz > 0)) ) {
  4164. WOLFSSL_MSG("Trying to process as detached signature");
  4165. detached = 1;
  4166. }
  4167. if (!degenerate && !detached && ret != 0)
  4168. break;
  4169. /* no content to read */
  4170. length = 0;
  4171. contentLen = 0;
  4172. pkiMsg2 = pkiMsg;
  4173. pkiMsg2Sz = pkiMsgSz;
  4174. /* reset ret */
  4175. ret = 0;
  4176. }
  4177. #ifndef NO_PKCS7_STREAM
  4178. /* save detached flag value */
  4179. pkcs7->stream->detached = detached;
  4180. /* save contentType */
  4181. pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,
  4182. DYNAMIC_TYPE_PKCS7);
  4183. if (pkcs7->stream->nonce == NULL) {
  4184. ret = MEMORY_E;
  4185. break;
  4186. }
  4187. else {
  4188. pkcs7->stream->nonceSz = contentTypeSz;
  4189. XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);
  4190. }
  4191. /* content expected? */
  4192. if ((ret == 0 && length > 0) &&
  4193. !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
  4194. pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;
  4195. }
  4196. else {
  4197. pkcs7->stream->expected = ASN_TAG_SZ + MAX_LENGTH_SZ;
  4198. }
  4199. if (pkcs7->stream->expected > (pkcs7->stream->maxLen - idx)) {
  4200. pkcs7->stream->expected = pkcs7->stream->maxLen - idx;
  4201. }
  4202. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4203. break;
  4204. }
  4205. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);
  4206. /* content length is in multiple parts */
  4207. if (multiPart) {
  4208. pkcs7->stream->expected = contentLen + ASN_TAG_SZ;
  4209. }
  4210. pkcs7->stream->multi = (byte)multiPart;
  4211. #endif
  4212. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);
  4213. FALL_THROUGH;
  4214. case WC_PKCS7_VERIFY_STAGE3:
  4215. #ifndef NO_PKCS7_STREAM
  4216. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4217. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4218. break;
  4219. }
  4220. #ifdef ASN_BER_TO_DER
  4221. if (pkcs7->derSz != 0)
  4222. pkiMsgSz = pkcs7->derSz;
  4223. else
  4224. #endif
  4225. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  4226. inSz;
  4227. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);
  4228. if (pkcs7->stream->length > 0) {
  4229. localIdx = 0;
  4230. }
  4231. multiPart = pkcs7->stream->multi;
  4232. detached = pkcs7->stream->detached;
  4233. maxIdx = idx + pkcs7->stream->expected;
  4234. #endif
  4235. /* Break out before content because it can be optional in degenerate
  4236. * cases. */
  4237. if (ret != 0 && !degenerate)
  4238. break;
  4239. /* get parts of content */
  4240. if (ret == 0 && multiPart) {
  4241. int i = 0;
  4242. keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
  4243. if (keepContent) {
  4244. /* Create a buffer to hold content of OCTET_STRINGs. */
  4245. pkcs7->contentDynamic = (byte*)XMALLOC(contentLen, pkcs7->heap,
  4246. DYNAMIC_TYPE_PKCS7);
  4247. if (pkcs7->contentDynamic == NULL)
  4248. ret = MEMORY_E;
  4249. }
  4250. start = localIdx;
  4251. /* Use the data from each OCTET_STRING. */
  4252. while (ret == 0 && localIdx < start + contentLen) {
  4253. if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)
  4254. ret = ASN_PARSE_E;
  4255. if (ret == 0 && tag != ASN_OCTET_STRING)
  4256. ret = ASN_PARSE_E;
  4257. if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
  4258. ret = ASN_PARSE_E;
  4259. if (ret == 0 && length + localIdx > start + contentLen)
  4260. ret = ASN_PARSE_E;
  4261. if (ret == 0) {
  4262. if (keepContent) {
  4263. XMEMCPY(pkcs7->contentDynamic + i, pkiMsg + localIdx,
  4264. length);
  4265. }
  4266. i += length;
  4267. localIdx += length;
  4268. }
  4269. }
  4270. localIdx = start; /* reset for sanity check, increment later */
  4271. length = i;
  4272. }
  4273. /* Save the inner data as the content. */
  4274. if (ret == 0 && length > 0) {
  4275. contentSz = length;
  4276. /* support using header and footer without content */
  4277. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  4278. /* Content not provided, use provided pkiMsg2 footer */
  4279. content = NULL;
  4280. localIdx = 0;
  4281. if (contentSz != (int)pkcs7->contentSz) {
  4282. WOLFSSL_MSG("Data signed does not match contentSz provided");
  4283. ret = BUFFER_E;
  4284. }
  4285. }
  4286. else {
  4287. if ((word32)length > pkiMsgSz - localIdx) {
  4288. ret = BUFFER_E;
  4289. }
  4290. /* Content pointer for calculating hashes later */
  4291. if (ret == 0 && !multiPart) {
  4292. content = &pkiMsg[localIdx];
  4293. }
  4294. if (ret == 0 && multiPart) {
  4295. content = pkcs7->contentDynamic;
  4296. }
  4297. if (ret == 0) {
  4298. idx += length;
  4299. }
  4300. pkiMsg2 = pkiMsg;
  4301. pkiMsg2Sz = pkiMsgSz;
  4302. #ifndef NO_PKCS7_STREAM
  4303. pkiMsg2Sz = pkcs7->stream->maxLen;
  4304. pkcs7->stream->varOne = pkiMsg2Sz;
  4305. pkcs7->stream->flagOne = 1;
  4306. #endif
  4307. }
  4308. }
  4309. else {
  4310. pkiMsg2 = pkiMsg;
  4311. pkiMsg2Sz = pkiMsgSz;
  4312. #ifndef NO_PKCS7_STREAM
  4313. pkiMsg2Sz = pkcs7->stream->maxLen;
  4314. pkcs7->stream->varOne = pkiMsg2Sz;
  4315. pkcs7->stream->flagOne = 1;
  4316. #endif
  4317. }
  4318. /* If getting the content info failed with non degenerate then return the
  4319. * error case. Otherwise with a degenerate it is ok if the content
  4320. * info was omitted */
  4321. if (!degenerate && !detached && (ret != 0)) {
  4322. break;
  4323. }
  4324. else {
  4325. ret = 0; /* reset ret state on degenerate case */
  4326. }
  4327. /* save content */
  4328. if (detached == 1) {
  4329. /* if detached, use content from user in pkcs7 struct */
  4330. content = pkcs7->content;
  4331. contentSz = pkcs7->contentSz;
  4332. }
  4333. #ifndef NO_PKCS7_STREAM
  4334. if (content != NULL) {
  4335. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4336. pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,
  4337. DYNAMIC_TYPE_PKCS7);
  4338. if (pkcs7->stream->content == NULL) {
  4339. ret = MEMORY_E;
  4340. break;
  4341. }
  4342. else {
  4343. XMEMCPY(pkcs7->stream->content, content, contentSz);
  4344. pkcs7->stream->contentSz = contentSz;
  4345. }
  4346. }
  4347. #endif /* !NO_PKCS7_STREAM */
  4348. /* Certificates begin "footer" section (ie pkiMsg2) if being used */
  4349. /* Get the implicit[0] set of certificates */
  4350. if (ret == 0 && idx >= pkiMsg2Sz)
  4351. ret = BUFFER_E;
  4352. length = 0; /* set length to 0 to check if reading in any certs */
  4353. localIdx = idx;
  4354. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  4355. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  4356. idx++;
  4357. if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)
  4358. < 0)
  4359. ret = ASN_PARSE_E;
  4360. }
  4361. if (ret != 0) {
  4362. break;
  4363. }
  4364. #ifndef NO_PKCS7_STREAM
  4365. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  4366. stateIdx = idx; /* case where all data was read from in2 */
  4367. }
  4368. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4369. break;
  4370. }
  4371. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4372. if (length > 0) {
  4373. pkcs7->stream->expected = length;
  4374. }
  4375. else {
  4376. pkcs7->stream->expected = MAX_SEQ_SZ;
  4377. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  4378. pkcs7->stream->totalRd) + pkcs7->stream->length) {
  4379. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4380. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4381. }
  4382. }
  4383. #endif
  4384. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
  4385. FALL_THROUGH;
  4386. case WC_PKCS7_VERIFY_STAGE4:
  4387. #ifndef NO_PKCS7_STREAM
  4388. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4389. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4390. break;
  4391. }
  4392. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4393. if (pkcs7->stream->flagOne) {
  4394. pkiMsg2 = pkiMsg;
  4395. }
  4396. /* restore content */
  4397. content = pkcs7->stream->content;
  4398. contentSz = pkcs7->stream->contentSz;
  4399. /* restore detached flag */
  4400. detached = pkcs7->stream->detached;
  4401. /* store certificate if needed */
  4402. if (length > 0 && in2Sz == 0) {
  4403. /* free tmpCert if not NULL */
  4404. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4405. pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
  4406. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4407. if ((pkiMsg2 == NULL) || (pkcs7->stream->tmpCert == NULL)) {
  4408. ret = MEMORY_E;
  4409. break;
  4410. }
  4411. XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
  4412. pkiMsg2 = pkcs7->stream->tmpCert;
  4413. pkiMsg2Sz = length;
  4414. idx = 0;
  4415. }
  4416. #endif
  4417. if (length > 0) {
  4418. /* At this point, idx is at the first certificate in
  4419. * a set of certificates. There may be more than one,
  4420. * or none, or they may be a PKCS 6 extended
  4421. * certificate. We want to save the first cert if it
  4422. * is X.509. */
  4423. word32 certIdx = idx;
  4424. if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)
  4425. ret = BUFFER_E;
  4426. if (ret == 0)
  4427. ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);
  4428. if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4429. if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
  4430. ret = ASN_PARSE_E;
  4431. cert = &pkiMsg2[idx];
  4432. certSz += (certIdx - idx);
  4433. if (certSz > length) {
  4434. ret = BUFFER_E;
  4435. break;
  4436. }
  4437. }
  4438. #ifdef ASN_BER_TO_DER
  4439. der = pkcs7->der;
  4440. pkcs7->der = NULL;
  4441. #endif
  4442. version = pkcs7->version;
  4443. contentIsPkcs7Type = pkcs7->contentIsPkcs7Type;
  4444. if (ret == 0) {
  4445. byte isDynamic = (byte)pkcs7->isDynamic;
  4446. #ifndef NO_PKCS7_STREAM
  4447. PKCS7State* stream = pkcs7->stream;
  4448. pkcs7->stream = NULL;
  4449. #endif
  4450. /* Save dynamic content before freeing PKCS7 struct */
  4451. if (pkcs7->contentDynamic != NULL) {
  4452. contentDynamic = (byte*)XMALLOC(contentSz,
  4453. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4454. if (contentDynamic == NULL) {
  4455. ret = MEMORY_E;
  4456. break;
  4457. }
  4458. XMEMCPY(contentDynamic, pkcs7->contentDynamic,
  4459. contentSz);
  4460. }
  4461. /* Free pkcs7 resources but not the structure itself */
  4462. pkcs7->isDynamic = 0;
  4463. wc_PKCS7_Free(pkcs7);
  4464. pkcs7->isDynamic = isDynamic;
  4465. /* This will reset PKCS7 structure and then set the
  4466. * certificate */
  4467. ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
  4468. /* Restore pkcs7->contentDynamic from above, will be
  4469. * freed by application with wc_PKCS7_Free() */
  4470. if (contentDynamic != NULL) {
  4471. pkcs7->contentDynamic = contentDynamic;
  4472. contentDynamic = NULL;
  4473. }
  4474. /* Restore content is PKCS#7 flag */
  4475. pkcs7->contentIsPkcs7Type = contentIsPkcs7Type;
  4476. #ifndef NO_PKCS7_STREAM
  4477. pkcs7->stream = stream;
  4478. #endif
  4479. }
  4480. pkcs7->version = (byte)version;
  4481. #ifdef ASN_BER_TO_DER
  4482. pkcs7->der = der;
  4483. #endif
  4484. if (ret != 0)
  4485. break;
  4486. /* iterate through any additional certificates */
  4487. if (ret == 0 && MAX_PKCS7_CERTS > 0) {
  4488. int sz = 0;
  4489. int i;
  4490. pkcs7->cert[0] = cert;
  4491. pkcs7->certSz[0] = certSz;
  4492. certIdx = idx + certSz;
  4493. for (i = 1; i < MAX_PKCS7_CERTS &&
  4494. certIdx + 1 < pkiMsg2Sz &&
  4495. certIdx + 1 < (word32)length; i++) {
  4496. localIdx = certIdx;
  4497. if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,
  4498. pkiMsg2Sz) < 0) {
  4499. ret = ASN_PARSE_E;
  4500. break;
  4501. }
  4502. if (ret == 0 &&
  4503. tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4504. if (GetLength(pkiMsg2, &certIdx, &sz,
  4505. pkiMsg2Sz) < 0) {
  4506. ret = ASN_PARSE_E;
  4507. break;
  4508. }
  4509. pkcs7->cert[i] = &pkiMsg2[localIdx];
  4510. pkcs7->certSz[i] = sz + (certIdx - localIdx);
  4511. certIdx += sz;
  4512. }
  4513. }
  4514. }
  4515. }
  4516. idx += length;
  4517. if (!detached) {
  4518. /* set content and size after init of PKCS7 structure */
  4519. pkcs7->content = content;
  4520. pkcs7->contentSz = contentSz;
  4521. }
  4522. #ifndef NO_PKCS7_STREAM
  4523. else {
  4524. /* save content if detached and using streaming API */
  4525. if (pkcs7->content != NULL) {
  4526. XFREE(pkcs7->stream->content, pkcs7->heap,
  4527. DYNAMIC_TYPE_PKCS7);
  4528. pkcs7->stream->content = (byte*)XMALLOC(pkcs7->contentSz,
  4529. pkcs7->heap,
  4530. DYNAMIC_TYPE_PKCS7);
  4531. if (pkcs7->stream->content == NULL) {
  4532. ret = MEMORY_E;
  4533. break;
  4534. }
  4535. else {
  4536. XMEMCPY(pkcs7->stream->content, pkcs7->content,
  4537. contentSz);
  4538. pkcs7->stream->contentSz = pkcs7->contentSz;
  4539. }
  4540. }
  4541. }
  4542. #endif
  4543. if (ret != 0) {
  4544. break;
  4545. }
  4546. #ifndef NO_PKCS7_STREAM
  4547. /* factor in that recent idx was in cert buffer. If in2 buffer was
  4548. * used then don't advance idx. */
  4549. if (length > 0 && pkcs7->stream->flagOne &&
  4550. pkcs7->stream->length == 0) {
  4551. idx = stateIdx + idx;
  4552. if (idx > inSz) {
  4553. /* index is more than input size */
  4554. ret = BUFFER_E;
  4555. break;
  4556. }
  4557. }
  4558. else {
  4559. stateIdx = idx; /* didn't read any from internal buffer */
  4560. }
  4561. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4562. break;
  4563. }
  4564. if (pkcs7->stream->flagOne && pkcs7->stream->length > 0) {
  4565. idx = stateIdx + idx;
  4566. }
  4567. pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +
  4568. MAX_SET_SZ;
  4569. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  4570. pkcs7->stream->totalRd) + pkcs7->stream->length)
  4571. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4572. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4573. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0);
  4574. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4575. #endif
  4576. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
  4577. FALL_THROUGH;
  4578. case WC_PKCS7_VERIFY_STAGE5:
  4579. #ifndef NO_PKCS7_STREAM
  4580. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4581. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4582. break;
  4583. }
  4584. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4585. if (pkcs7->stream->flagOne) {
  4586. pkiMsg2 = pkiMsg;
  4587. /* check if using internal stream buffer and should adjust sz */
  4588. if (pkiMsg != in && pkcs7->stream->length > 0) {
  4589. pkiMsg2Sz = pkcs7->stream->length;
  4590. }
  4591. }
  4592. /* restore content type */
  4593. contentType = pkcs7->stream->nonce;
  4594. contentTypeSz = pkcs7->stream->nonceSz;
  4595. maxIdx = idx + pkcs7->stream->expected;
  4596. if (maxIdx > pkiMsg2Sz) {
  4597. ret = BUFFER_E;
  4598. break;
  4599. }
  4600. stateIdx = idx;
  4601. #else
  4602. /* if not streaming, maxIdx is just pkiMsg2Sz */
  4603. maxIdx = pkiMsg2Sz;
  4604. #endif
  4605. /* set contentType and size after init of PKCS7 structure */
  4606. if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,
  4607. contentTypeSz) < 0)
  4608. ret = ASN_PARSE_E;
  4609. /* Get the implicit[1] set of crls */
  4610. if (ret == 0 && idx >= maxIdx)
  4611. ret = BUFFER_E;
  4612. localIdx = idx;
  4613. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  4614. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  4615. idx++;
  4616. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4617. ret = ASN_PARSE_E;
  4618. /* Skip the set */
  4619. idx += length;
  4620. }
  4621. /* Get the set of signerInfos */
  4622. if (ret == 0 && GetSet_ex(pkiMsg2, &idx, &length, maxIdx,
  4623. NO_USER_CHECK) < 0)
  4624. ret = ASN_PARSE_E;
  4625. if (ret != 0)
  4626. break;
  4627. #ifndef NO_PKCS7_STREAM
  4628. if (!pkcs7->stream->flagOne) {
  4629. stateIdx = idx; /* didn't read any from internal buffer */
  4630. }
  4631. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4632. break;
  4633. }
  4634. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4635. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  4636. if (length > 0) {
  4637. pkcs7->stream->expected = length;
  4638. }
  4639. else {
  4640. pkcs7->stream->expected = 0;
  4641. }
  4642. }
  4643. else {
  4644. /* last state expect the rest of the buffer */
  4645. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4646. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4647. }
  4648. #endif
  4649. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);
  4650. FALL_THROUGH;
  4651. case WC_PKCS7_VERIFY_STAGE6:
  4652. #ifndef NO_PKCS7_STREAM
  4653. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4654. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4655. break;
  4656. }
  4657. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4658. if (pkcs7->stream->flagOne) {
  4659. pkiMsg2 = pkiMsg;
  4660. /* check if using internal stream buffer and should adjust sz */
  4661. if (pkiMsg != in && pkcs7->stream->length > 0) {
  4662. pkiMsg2Sz = pkcs7->stream->length;
  4663. }
  4664. else {
  4665. /* if pkiMsg2 is pkiMsg and not using an internal stream
  4666. * buffer then the size is limited by inSz */
  4667. pkiMsg2Sz = inSz;
  4668. }
  4669. }
  4670. /* restore content */
  4671. content = pkcs7->stream->content;
  4672. contentSz = pkcs7->stream->contentSz;
  4673. #endif
  4674. ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx,
  4675. degenerate, &signedAttrib, &signedAttribSz);
  4676. /* parse out the signature if present and verify it */
  4677. if (ret == 0 && length > 0 && degenerate == 0) {
  4678. WOLFSSL_MSG("Parsing signature and verifying");
  4679. if (idx >= pkiMsg2Sz)
  4680. ret = BUFFER_E;
  4681. /* Get the signature */
  4682. localIdx = idx;
  4683. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,
  4684. pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {
  4685. idx++;
  4686. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4687. ret = ASN_PARSE_E;
  4688. /* save pointer and length */
  4689. sig = &pkiMsg2[idx];
  4690. sigSz = length;
  4691. idx += length;
  4692. }
  4693. pkcs7->content = content;
  4694. pkcs7->contentSz = contentSz;
  4695. if (ret == 0) {
  4696. ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
  4697. signedAttrib, signedAttribSz,
  4698. hashBuf, hashSz);
  4699. }
  4700. }
  4701. if (ret < 0)
  4702. break;
  4703. ret = 0; /* success */
  4704. #ifndef NO_PKCS7_STREAM
  4705. wc_PKCS7_ResetStream(pkcs7);
  4706. #endif
  4707. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4708. break;
  4709. default:
  4710. WOLFSSL_MSG("PKCS7 Unknown verify state");
  4711. ret = BAD_FUNC_ARG;
  4712. }
  4713. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  4714. #ifndef NO_PKCS7_STREAM
  4715. wc_PKCS7_ResetStream(pkcs7);
  4716. #endif
  4717. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4718. }
  4719. return ret;
  4720. }
  4721. /* Gets a copy of the SID parsed from signerInfo. This can be called after
  4722. * wc_PKCS7_VerifySignedData has been called. SID can be SKID in version 3 case
  4723. * or issuerAndSerialNumber.
  4724. *
  4725. * return 0 on success and LENGTH_ONLY_E if just setting "outSz" for buffer
  4726. * length needed.
  4727. */
  4728. int wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz)
  4729. {
  4730. if (outSz == NULL || pkcs7 == NULL) {
  4731. return BAD_FUNC_ARG;
  4732. }
  4733. if (pkcs7->signerInfo == NULL) {
  4734. WOLFSSL_MSG("Either the bundle had no signers or"
  4735. "wc_PKCS7_VerifySignedData needs called yet");
  4736. return PKCS7_NO_SIGNER_E;
  4737. }
  4738. if (pkcs7->signerInfo->sidSz == 0) {
  4739. WOLFSSL_MSG("Bundle had no signer SID set");
  4740. return PKCS7_NO_SIGNER_E;
  4741. }
  4742. if (out == NULL) {
  4743. *outSz = pkcs7->signerInfo->sidSz;
  4744. return LENGTH_ONLY_E;
  4745. }
  4746. if (*outSz < pkcs7->signerInfo->sidSz) {
  4747. WOLFSSL_MSG("Buffer being passed in is not large enough for SKID");
  4748. return BUFFER_E;
  4749. }
  4750. XMEMCPY(out, pkcs7->signerInfo->sid, pkcs7->signerInfo->sidSz);
  4751. *outSz = pkcs7->signerInfo->sidSz;
  4752. return 0;
  4753. }
  4754. /* SignedData verification function variant that allows pre-computed content
  4755. * message digest and optional PKCS7/CMS bundle content header/footer to be
  4756. * used for verification. Useful for large data signing.
  4757. *
  4758. * pkcs7 - pointer to initialized PKCS7 structure
  4759. * hashBuf - message digest of content
  4760. * hashSz - size of hashBuf, octets
  4761. * pkiMsgHead - PKCS7/CMS header that goes on top of the raw data signed,
  4762. * as output from wc_PKCS7_EncodeSignedData_ex (if also using
  4763. * pkiMsgFoot). Otherwise, PKCS7/CMS bundle with
  4764. * detached signature - will use hashBuf/hashSz to verify.
  4765. * pkiMsgHeadSz - size of pkiMsgHead, octets
  4766. * pkiMsgFoot - PKCS7/CMS footer that goes at the end of the raw data signed,
  4767. * as output from wc_PKCS7_EncodeSignedData_ex. Can be NULL
  4768. * if pkiMsgHead is a direct detached signature bundle to be used
  4769. * with hashBuf/hashSz.
  4770. * pkiMsgFootSz - size of pkiMsgFoot, octets. Should be 0 if pkiMsgFoot is NULL.
  4771. *
  4772. * Returns 0 on success, negative upon error.
  4773. *
  4774. */
  4775. int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  4776. word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
  4777. word32 pkiMsgFootSz)
  4778. {
  4779. return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,
  4780. pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);
  4781. }
  4782. int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
  4783. {
  4784. return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);
  4785. }
  4786. /* Generate random content encryption key, store into pkcs7->cek and
  4787. * pkcs7->cekSz.
  4788. *
  4789. * pkcs7 - pointer to initialized PKCS7 structure
  4790. * len - length of key to be generated
  4791. *
  4792. * Returns 0 on success, negative upon error */
  4793. static int PKCS7_GenerateContentEncryptionKey(PKCS7* pkcs7, word32 len)
  4794. {
  4795. int ret;
  4796. WC_RNG rng;
  4797. byte* tmpKey;
  4798. if (pkcs7 == NULL || len == 0)
  4799. return BAD_FUNC_ARG;
  4800. /* if key already exists, don't need to re-generate */
  4801. if (pkcs7->cek != NULL && pkcs7->cekSz != 0) {
  4802. /* if key exists, but is different size, return error */
  4803. if (pkcs7->cekSz != len) {
  4804. WOLFSSL_MSG("Random content-encryption key size is inconsistent "
  4805. "between CMS recipients");
  4806. return WC_KEY_SIZE_E;
  4807. }
  4808. return 0;
  4809. }
  4810. /* allocate space for cek */
  4811. tmpKey = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4812. if (tmpKey == NULL)
  4813. return MEMORY_E;
  4814. XMEMSET(tmpKey, 0, len);
  4815. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  4816. if (ret != 0) {
  4817. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4818. return ret;
  4819. }
  4820. ret = wc_RNG_GenerateBlock(&rng, tmpKey, len);
  4821. if (ret != 0) {
  4822. wc_FreeRng(&rng);
  4823. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4824. return ret;
  4825. }
  4826. /* store into PKCS7, memory freed during final cleanup */
  4827. pkcs7->cek = tmpKey;
  4828. pkcs7->cekSz = len;
  4829. wc_FreeRng(&rng);
  4830. return 0;
  4831. }
  4832. /* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */
  4833. static int wc_PKCS7_KeyWrap(byte* cek, word32 cekSz, byte* kek,
  4834. word32 kekSz, byte* out, word32 outSz,
  4835. int keyWrapAlgo, int direction)
  4836. {
  4837. int ret = 0;
  4838. if (cek == NULL || kek == NULL || out == NULL)
  4839. return BAD_FUNC_ARG;
  4840. switch (keyWrapAlgo) {
  4841. #ifndef NO_AES
  4842. #ifdef WOLFSSL_AES_128
  4843. case AES128_WRAP:
  4844. #endif
  4845. #ifdef WOLFSSL_AES_192
  4846. case AES192_WRAP:
  4847. #endif
  4848. #ifdef WOLFSSL_AES_256
  4849. case AES256_WRAP:
  4850. #endif
  4851. if (direction == AES_ENCRYPTION) {
  4852. ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,
  4853. out, outSz, NULL);
  4854. } else if (direction == AES_DECRYPTION) {
  4855. ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,
  4856. out, outSz, NULL);
  4857. } else {
  4858. WOLFSSL_MSG("Bad key un/wrap direction");
  4859. return BAD_FUNC_ARG;
  4860. }
  4861. if (ret <= 0)
  4862. return ret;
  4863. break;
  4864. #endif /* NO_AES */
  4865. default:
  4866. WOLFSSL_MSG("Unsupported key wrap algorithm");
  4867. return BAD_KEYWRAP_ALG_E;
  4868. };
  4869. (void)cekSz;
  4870. (void)kekSz;
  4871. (void)outSz;
  4872. (void)direction;
  4873. return ret;
  4874. }
  4875. #ifdef HAVE_ECC
  4876. /* KARI == KeyAgreeRecipientInfo (key agreement) */
  4877. typedef struct WC_PKCS7_KARI {
  4878. DecodedCert* decoded; /* decoded recip cert */
  4879. void* heap; /* user heap, points to PKCS7->heap */
  4880. int devId; /* device ID for HW based private key */
  4881. ecc_key* recipKey; /* recip key (pub | priv) */
  4882. ecc_key* senderKey; /* sender key (pub | priv) */
  4883. byte* senderKeyExport; /* sender ephemeral key DER */
  4884. byte* kek; /* key encryption key */
  4885. byte* ukm; /* OPTIONAL user keying material */
  4886. byte* sharedInfo; /* ECC-CMS-SharedInfo ASN.1 encoded blob */
  4887. word32 senderKeyExportSz; /* size of sender ephemeral key DER */
  4888. word32 kekSz; /* size of key encryption key */
  4889. word32 ukmSz; /* size of user keying material */
  4890. word32 sharedInfoSz; /* size of ECC-CMS-SharedInfo encoded */
  4891. byte ukmOwner; /* do we own ukm buffer? 1:yes, 0:no */
  4892. byte direction; /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */
  4893. byte decodedInit : 1; /* indicates decoded was initialized */
  4894. byte recipKeyInit : 1; /* indicates recipKey was initialized */
  4895. byte senderKeyInit : 1; /* indicates senderKey was initialized */
  4896. } WC_PKCS7_KARI;
  4897. /* allocate and create new WC_PKCS7_KARI struct,
  4898. * returns struct pointer on success, NULL on failure */
  4899. static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)
  4900. {
  4901. WC_PKCS7_KARI* kari = NULL;
  4902. if (pkcs7 == NULL)
  4903. return NULL;
  4904. kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,
  4905. DYNAMIC_TYPE_PKCS7);
  4906. if (kari == NULL) {
  4907. WOLFSSL_MSG("Failed to allocate WC_PKCS7_KARI");
  4908. return NULL;
  4909. }
  4910. kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  4911. DYNAMIC_TYPE_PKCS7);
  4912. if (kari->decoded == NULL) {
  4913. WOLFSSL_MSG("Failed to allocate DecodedCert");
  4914. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4915. return NULL;
  4916. }
  4917. XMEMSET(kari->decoded, 0, sizeof(DecodedCert));
  4918. kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4919. DYNAMIC_TYPE_PKCS7);
  4920. if (kari->recipKey == NULL) {
  4921. WOLFSSL_MSG("Failed to allocate recipient ecc_key");
  4922. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4923. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4924. return NULL;
  4925. }
  4926. kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4927. DYNAMIC_TYPE_PKCS7);
  4928. if (kari->senderKey == NULL) {
  4929. WOLFSSL_MSG("Failed to allocate sender ecc_key");
  4930. XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4931. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4932. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4933. return NULL;
  4934. }
  4935. kari->senderKeyExport = NULL;
  4936. kari->senderKeyExportSz = 0;
  4937. kari->kek = NULL;
  4938. kari->kekSz = 0;
  4939. kari->ukm = NULL;
  4940. kari->ukmSz = 0;
  4941. kari->ukmOwner = 0;
  4942. kari->sharedInfo = NULL;
  4943. kari->sharedInfoSz = 0;
  4944. kari->direction = direction;
  4945. kari->decodedInit = 0;
  4946. kari->recipKeyInit = 0;
  4947. kari->senderKeyInit = 0;
  4948. kari->heap = pkcs7->heap;
  4949. kari->devId = pkcs7->devId;
  4950. return kari;
  4951. }
  4952. /* free WC_PKCS7_KARI struct, return 0 on success */
  4953. static int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)
  4954. {
  4955. void* heap;
  4956. if (kari) {
  4957. heap = kari->heap;
  4958. if (kari->decoded) {
  4959. if (kari->decodedInit)
  4960. FreeDecodedCert(kari->decoded);
  4961. XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);
  4962. }
  4963. if (kari->senderKey) {
  4964. if (kari->senderKeyInit)
  4965. wc_ecc_free(kari->senderKey);
  4966. XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);
  4967. }
  4968. if (kari->recipKey) {
  4969. if (kari->recipKeyInit)
  4970. wc_ecc_free(kari->recipKey);
  4971. XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);
  4972. }
  4973. if (kari->senderKeyExport) {
  4974. ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);
  4975. XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);
  4976. kari->senderKeyExportSz = 0;
  4977. }
  4978. if (kari->kek) {
  4979. ForceZero(kari->kek, kari->kekSz);
  4980. XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);
  4981. kari->kekSz = 0;
  4982. }
  4983. if (kari->ukm) {
  4984. if (kari->ukmOwner == 1) {
  4985. XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);
  4986. }
  4987. kari->ukmSz = 0;
  4988. }
  4989. if (kari->sharedInfo) {
  4990. ForceZero(kari->sharedInfo, kari->sharedInfoSz);
  4991. XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);
  4992. kari->sharedInfoSz = 0;
  4993. }
  4994. XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);
  4995. }
  4996. (void)heap;
  4997. return 0;
  4998. }
  4999. /* parse recipient cert/key, return 0 on success, negative on error
  5000. * key/keySz only needed during decoding (WC_PKCS7_DECODE) */
  5001. static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
  5002. word32 certSz, const byte* key,
  5003. word32 keySz)
  5004. {
  5005. int ret;
  5006. word32 idx;
  5007. if (kari == NULL || kari->decoded == NULL) {
  5008. return BAD_FUNC_ARG;
  5009. }
  5010. /* decode certificate */
  5011. if (cert != NULL) {
  5012. InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
  5013. kari->decodedInit = 1;
  5014. ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
  5015. if (ret < 0)
  5016. return ret;
  5017. /* only supports ECDSA for now */
  5018. if (kari->decoded->keyOID != ECDSAk) {
  5019. WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
  5020. return BAD_FUNC_ARG;
  5021. }
  5022. /* make sure subject key id was read from cert */
  5023. if (kari->decoded->extSubjKeyIdSet == 0) {
  5024. WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
  5025. return BAD_FUNC_ARG;
  5026. }
  5027. }
  5028. ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
  5029. if (ret != 0)
  5030. return ret;
  5031. kari->recipKeyInit = 1;
  5032. /* get recip public key */
  5033. if (kari->direction == WC_PKCS7_ENCODE) {
  5034. if (cert == NULL) {
  5035. WOLFSSL_MSG("Error recipient cert can not be null with encode");
  5036. return BAD_FUNC_ARG;
  5037. }
  5038. idx = 0;
  5039. ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
  5040. kari->recipKey, kari->decoded->pubKeySize);
  5041. if (ret != 0)
  5042. return ret;
  5043. }
  5044. /* get recip private key */
  5045. else if (kari->direction == WC_PKCS7_DECODE) {
  5046. if (key != NULL && keySz > 0) {
  5047. idx = 0;
  5048. ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);
  5049. }
  5050. else if (kari->devId == INVALID_DEVID) {
  5051. ret = BAD_FUNC_ARG;
  5052. }
  5053. if (ret != 0)
  5054. return ret;
  5055. } else {
  5056. /* bad direction */
  5057. return BAD_FUNC_ARG;
  5058. }
  5059. (void)idx;
  5060. return 0;
  5061. }
  5062. /* create ephemeral ECC key, places ecc_key in kari->senderKey,
  5063. * DER encoded in kari->senderKeyExport. return 0 on success,
  5064. * negative on error */
  5065. static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari)
  5066. {
  5067. int ret;
  5068. WC_RNG rng;
  5069. if (kari == NULL || kari->decoded == NULL ||
  5070. kari->recipKey == NULL || kari->recipKey->dp == NULL)
  5071. return BAD_FUNC_ARG;
  5072. kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,
  5073. kari->heap, DYNAMIC_TYPE_PKCS7);
  5074. if (kari->senderKeyExport == NULL)
  5075. return MEMORY_E;
  5076. kari->senderKeyExportSz = kari->decoded->pubKeySize;
  5077. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  5078. if (ret != 0) {
  5079. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  5080. kari->senderKeyExportSz = 0;
  5081. kari->senderKeyExport = NULL;
  5082. return ret;
  5083. }
  5084. kari->senderKeyInit = 1;
  5085. ret = wc_InitRng_ex(&rng, kari->heap, kari->devId);
  5086. if (ret != 0) {
  5087. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  5088. kari->senderKeyExportSz = 0;
  5089. kari->senderKeyExport = NULL;
  5090. return ret;
  5091. }
  5092. ret = wc_ecc_make_key_ex(&rng, kari->recipKey->dp->size,
  5093. kari->senderKey, kari->recipKey->dp->id);
  5094. if (ret != 0) {
  5095. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  5096. kari->senderKeyExportSz = 0;
  5097. kari->senderKeyExport = NULL;
  5098. wc_FreeRng(&rng);
  5099. return ret;
  5100. }
  5101. wc_FreeRng(&rng);
  5102. /* dump generated key to X.963 DER for output in CMS bundle */
  5103. PRIVATE_KEY_UNLOCK();
  5104. ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,
  5105. &kari->senderKeyExportSz);
  5106. PRIVATE_KEY_LOCK();
  5107. if (ret != 0) {
  5108. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  5109. kari->senderKeyExportSz = 0;
  5110. kari->senderKeyExport = NULL;
  5111. return ret;
  5112. }
  5113. return 0;
  5114. }
  5115. /* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,
  5116. * place in kari->sharedInfo. returns 0 on success, negative on error */
  5117. static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)
  5118. {
  5119. int idx = 0;
  5120. int sharedInfoSeqSz = 0;
  5121. int keyInfoSz = 0;
  5122. int suppPubInfoSeqSz = 0;
  5123. int entityUInfoOctetSz = 0;
  5124. int entityUInfoExplicitSz = 0;
  5125. int kekOctetSz = 0;
  5126. int sharedInfoSz = 0;
  5127. word32 kekBitSz = 0;
  5128. byte sharedInfoSeq[MAX_SEQ_SZ];
  5129. byte keyInfo[MAX_ALGO_SZ];
  5130. byte suppPubInfoSeq[MAX_SEQ_SZ];
  5131. byte entityUInfoOctet[MAX_OCTET_STR_SZ];
  5132. byte entityUInfoExplicitSeq[MAX_SEQ_SZ];
  5133. byte kekOctet[MAX_OCTET_STR_SZ];
  5134. if (kari == NULL)
  5135. return BAD_FUNC_ARG;
  5136. if ((kari->ukmSz > 0) && (kari->ukm == NULL))
  5137. return BAD_FUNC_ARG;
  5138. /* kekOctet */
  5139. kekOctetSz = SetOctetString(sizeof(word32), kekOctet);
  5140. sharedInfoSz += (kekOctetSz + sizeof(word32));
  5141. /* suppPubInfo */
  5142. suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,
  5143. kekOctetSz + sizeof(word32),
  5144. suppPubInfoSeq);
  5145. sharedInfoSz += suppPubInfoSeqSz;
  5146. /* optional ukm/entityInfo */
  5147. if (kari->ukmSz > 0) {
  5148. entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);
  5149. sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);
  5150. entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +
  5151. kari->ukmSz,
  5152. entityUInfoExplicitSeq);
  5153. sharedInfoSz += entityUInfoExplicitSz;
  5154. }
  5155. /* keyInfo */
  5156. keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);
  5157. sharedInfoSz += keyInfoSz;
  5158. /* sharedInfo */
  5159. sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);
  5160. sharedInfoSz += sharedInfoSeqSz;
  5161. kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,
  5162. DYNAMIC_TYPE_PKCS7);
  5163. if (kari->sharedInfo == NULL)
  5164. return MEMORY_E;
  5165. kari->sharedInfoSz = sharedInfoSz;
  5166. XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);
  5167. idx += sharedInfoSeqSz;
  5168. XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);
  5169. idx += keyInfoSz;
  5170. if (kari->ukmSz > 0) {
  5171. XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,
  5172. entityUInfoExplicitSz);
  5173. idx += entityUInfoExplicitSz;
  5174. XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);
  5175. idx += entityUInfoOctetSz;
  5176. XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);
  5177. idx += kari->ukmSz;
  5178. }
  5179. XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);
  5180. idx += suppPubInfoSeqSz;
  5181. XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);
  5182. idx += kekOctetSz;
  5183. kekBitSz = (kari->kekSz) * 8; /* convert to bits */
  5184. #ifdef LITTLE_ENDIAN_ORDER
  5185. kekBitSz = ByteReverseWord32(kekBitSz); /* network byte order */
  5186. #endif
  5187. XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));
  5188. return 0;
  5189. }
  5190. /* create key encryption key (KEK) using key wrap algorithm and key encryption
  5191. * algorithm, place in kari->kek. return 0 on success, <0 on error. */
  5192. static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng,
  5193. int keyWrapOID, int keyEncOID)
  5194. {
  5195. int ret;
  5196. int kSz;
  5197. enum wc_HashType kdfType;
  5198. byte* secret;
  5199. word32 secretSz;
  5200. if (kari == NULL || kari->recipKey == NULL ||
  5201. kari->senderKey == NULL || kari->senderKey->dp == NULL)
  5202. return BAD_FUNC_ARG;
  5203. /* get KEK size, allocate buff */
  5204. kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);
  5205. if (kSz < 0)
  5206. return kSz;
  5207. kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  5208. if (kari->kek == NULL)
  5209. return MEMORY_E;
  5210. kari->kekSz = (word32)kSz;
  5211. /* generate ECC-CMS-SharedInfo */
  5212. ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);
  5213. if (ret != 0)
  5214. return ret;
  5215. /* generate shared secret */
  5216. secretSz = kari->senderKey->dp->size;
  5217. secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  5218. if (secret == NULL)
  5219. return MEMORY_E;
  5220. #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
  5221. (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
  5222. !defined(HAVE_SELFTEST)
  5223. ret = wc_ecc_set_rng(kari->senderKey, rng);
  5224. if (ret != 0) {
  5225. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5226. return ret;
  5227. }
  5228. ret = wc_ecc_set_rng(kari->recipKey, rng);
  5229. if (ret != 0) {
  5230. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5231. return ret;
  5232. }
  5233. #else
  5234. (void)rng;
  5235. #endif
  5236. if (kari->direction == WC_PKCS7_ENCODE) {
  5237. PRIVATE_KEY_UNLOCK();
  5238. ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,
  5239. secret, &secretSz);
  5240. PRIVATE_KEY_LOCK();
  5241. } else if (kari->direction == WC_PKCS7_DECODE) {
  5242. PRIVATE_KEY_UNLOCK();
  5243. ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,
  5244. secret, &secretSz);
  5245. PRIVATE_KEY_LOCK();
  5246. } else {
  5247. /* bad direction */
  5248. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5249. return BAD_FUNC_ARG;
  5250. }
  5251. if (ret != 0) {
  5252. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5253. return ret;
  5254. }
  5255. /* run through KDF */
  5256. switch (keyEncOID) {
  5257. #ifndef NO_SHA
  5258. case dhSinglePass_stdDH_sha1kdf_scheme:
  5259. kdfType = WC_HASH_TYPE_SHA;
  5260. break;
  5261. #endif
  5262. #ifndef WOLFSSL_SHA224
  5263. case dhSinglePass_stdDH_sha224kdf_scheme:
  5264. kdfType = WC_HASH_TYPE_SHA224;
  5265. break;
  5266. #endif
  5267. #ifndef NO_SHA256
  5268. case dhSinglePass_stdDH_sha256kdf_scheme:
  5269. kdfType = WC_HASH_TYPE_SHA256;
  5270. break;
  5271. #endif
  5272. #ifdef WOLFSSL_SHA384
  5273. case dhSinglePass_stdDH_sha384kdf_scheme:
  5274. kdfType = WC_HASH_TYPE_SHA384;
  5275. break;
  5276. #endif
  5277. #ifdef WOLFSSL_SHA512
  5278. case dhSinglePass_stdDH_sha512kdf_scheme:
  5279. kdfType = WC_HASH_TYPE_SHA512;
  5280. break;
  5281. #endif
  5282. default:
  5283. WOLFSSL_MSG("Unsupported key agreement algorithm");
  5284. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5285. return BAD_FUNC_ARG;
  5286. };
  5287. ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,
  5288. kari->sharedInfoSz, kari->kek, kari->kekSz);
  5289. if (ret != 0) {
  5290. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5291. return ret;
  5292. }
  5293. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5294. return 0;
  5295. }
  5296. /* Encode and add CMS EnvelopedData KARI (KeyAgreeRecipientInfo) RecipientInfo
  5297. * to CMS/PKCS#7 EnvelopedData structure.
  5298. *
  5299. * Returns 0 on success, negative upon error */
  5300. int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  5301. int keyWrapOID, int keyAgreeOID, byte* ukm,
  5302. word32 ukmSz, int options)
  5303. {
  5304. Pkcs7EncodedRecip* recip;
  5305. Pkcs7EncodedRecip* lastRecip = NULL;
  5306. WC_PKCS7_KARI* kari = NULL;
  5307. word32 idx = 0;
  5308. word32 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  5309. int ret = 0;
  5310. int keySz, direction = 0;
  5311. int blockKeySz = 0;
  5312. int keyIdSize;
  5313. /* ASN.1 layout */
  5314. int totalSz = 0;
  5315. int kariSeqSz = 0;
  5316. byte kariSeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  5317. int verSz = 0;
  5318. byte ver[MAX_VERSION_SZ];
  5319. int origIdOrKeySeqSz = 0;
  5320. byte origIdOrKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  5321. int origPubKeySeqSz = 0;
  5322. byte origPubKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  5323. int origAlgIdSz = 0;
  5324. byte origAlgId[MAX_ALGO_SZ];
  5325. int origPubKeyStrSz = 0;
  5326. byte origPubKeyStr[MAX_OCTET_STR_SZ];
  5327. /* optional user keying material */
  5328. int ukmOctetSz = 0;
  5329. byte ukmOctetStr[MAX_OCTET_STR_SZ];
  5330. int ukmExplicitSz = 0;
  5331. byte ukmExplicitSeq[MAX_SEQ_SZ];
  5332. int keyEncryptAlgoIdSz = 0;
  5333. byte keyEncryptAlgoId[MAX_ALGO_SZ];
  5334. int keyWrapAlgSz = 0;
  5335. byte keyWrapAlg[MAX_ALGO_SZ];
  5336. int recipEncKeysSeqSz = 0;
  5337. byte recipEncKeysSeq[MAX_SEQ_SZ];
  5338. int recipEncKeySeqSz = 0;
  5339. byte recipEncKeySeq[MAX_SEQ_SZ];
  5340. int recipKeyIdSeqSz = 0;
  5341. byte recipKeyIdSeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  5342. int subjKeyIdOctetSz = 0;
  5343. byte subjKeyIdOctet[MAX_OCTET_STR_SZ];
  5344. int encryptedKeyOctetSz = 0;
  5345. byte encryptedKeyOctet[MAX_OCTET_STR_SZ];
  5346. #ifdef WOLFSSL_SMALL_STACK
  5347. byte* encryptedKey;
  5348. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  5349. DYNAMIC_TYPE_TMP_BUFFER);
  5350. if (encryptedKey == NULL) {
  5351. return MEMORY_E;
  5352. }
  5353. #else
  5354. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  5355. #endif
  5356. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  5357. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  5358. pkcs7->publicKeyOID)));
  5359. #else
  5360. keyIdSize = KEYID_SIZE;
  5361. #endif
  5362. /* allocate and init memory for recipient */
  5363. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  5364. DYNAMIC_TYPE_PKCS7);
  5365. if (recip == NULL) {
  5366. #ifdef WOLFSSL_SMALL_STACK
  5367. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5368. #endif
  5369. return MEMORY_E;
  5370. }
  5371. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5372. /* get key size for content-encryption key based on algorithm */
  5373. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5374. if (blockKeySz < 0) {
  5375. #ifdef WOLFSSL_SMALL_STACK
  5376. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5377. #endif
  5378. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5379. return blockKeySz;
  5380. }
  5381. /* generate random content encryption key, if needed */
  5382. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5383. if (ret < 0) {
  5384. #ifdef WOLFSSL_SMALL_STACK
  5385. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5386. #endif
  5387. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5388. return ret;
  5389. }
  5390. /* set direction based on keyWrapAlgo */
  5391. switch (keyWrapOID) {
  5392. #ifndef NO_AES
  5393. #ifdef WOLFSSL_AES_128
  5394. case AES128_WRAP:
  5395. #endif
  5396. #ifdef WOLFSSL_AES_192
  5397. case AES192_WRAP:
  5398. #endif
  5399. #ifdef WOLFSSL_AES_256
  5400. case AES256_WRAP:
  5401. #endif
  5402. direction = AES_ENCRYPTION;
  5403. break;
  5404. #endif
  5405. default:
  5406. WOLFSSL_MSG("Unsupported key wrap algorithm");
  5407. #ifdef WOLFSSL_SMALL_STACK
  5408. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5409. #endif
  5410. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5411. return BAD_KEYWRAP_ALG_E;
  5412. }
  5413. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);
  5414. if (kari == NULL) {
  5415. #ifdef WOLFSSL_SMALL_STACK
  5416. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5417. #endif
  5418. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5419. return MEMORY_E;
  5420. }
  5421. /* set user keying material if available */
  5422. if (ukmSz > 0 && ukm != NULL) {
  5423. kari->ukm = ukm;
  5424. kari->ukmSz = ukmSz;
  5425. kari->ukmOwner = 0;
  5426. }
  5427. /* parse recipient cert, get public key */
  5428. ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);
  5429. if (ret != 0) {
  5430. wc_PKCS7_KariFree(kari);
  5431. #ifdef WOLFSSL_SMALL_STACK
  5432. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5433. #endif
  5434. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5435. return ret;
  5436. }
  5437. /* generate sender ephemeral ECC key */
  5438. ret = wc_PKCS7_KariGenerateEphemeralKey(kari);
  5439. if (ret != 0) {
  5440. wc_PKCS7_KariFree(kari);
  5441. #ifdef WOLFSSL_SMALL_STACK
  5442. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5443. #endif
  5444. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5445. return ret;
  5446. }
  5447. /* generate KEK (key encryption key) */
  5448. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID, keyAgreeOID);
  5449. if (ret != 0) {
  5450. wc_PKCS7_KariFree(kari);
  5451. #ifdef WOLFSSL_SMALL_STACK
  5452. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5453. #endif
  5454. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5455. return ret;
  5456. }
  5457. /* encrypt CEK with KEK */
  5458. keySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kari->kek,
  5459. kari->kekSz, encryptedKey, encryptedKeySz,
  5460. keyWrapOID, direction);
  5461. if (keySz <= 0) {
  5462. wc_PKCS7_KariFree(kari);
  5463. #ifdef WOLFSSL_SMALL_STACK
  5464. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5465. #endif
  5466. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5467. return keySz;
  5468. }
  5469. encryptedKeySz = (word32)keySz;
  5470. /* Start of RecipientEncryptedKeys */
  5471. /* EncryptedKey */
  5472. encryptedKeyOctetSz = SetOctetString(encryptedKeySz, encryptedKeyOctet);
  5473. totalSz += (encryptedKeyOctetSz + encryptedKeySz);
  5474. /* SubjectKeyIdentifier */
  5475. subjKeyIdOctetSz = SetOctetString(keyIdSize, subjKeyIdOctet);
  5476. totalSz += (subjKeyIdOctetSz + keyIdSize);
  5477. /* RecipientKeyIdentifier IMPLICIT [0] */
  5478. recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +
  5479. keyIdSize, recipKeyIdSeq);
  5480. totalSz += recipKeyIdSeqSz;
  5481. /* RecipientEncryptedKey */
  5482. recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);
  5483. totalSz += recipEncKeySeqSz;
  5484. /* RecipientEncryptedKeys */
  5485. recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);
  5486. totalSz += recipEncKeysSeqSz;
  5487. /* Start of optional UserKeyingMaterial */
  5488. if (kari->ukmSz > 0) {
  5489. ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);
  5490. totalSz += (ukmOctetSz + kari->ukmSz);
  5491. ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,
  5492. ukmExplicitSeq);
  5493. totalSz += ukmExplicitSz;
  5494. }
  5495. /* Start of KeyEncryptionAlgorithmIdentifier */
  5496. /* KeyWrapAlgorithm */
  5497. keyWrapAlgSz = SetAlgoID(keyWrapOID, keyWrapAlg, oidKeyWrapType, 0);
  5498. totalSz += keyWrapAlgSz;
  5499. /* KeyEncryptionAlgorithmIdentifier */
  5500. keyEncryptAlgoIdSz = SetAlgoID(keyAgreeOID, keyEncryptAlgoId,
  5501. oidCmsKeyAgreeType, keyWrapAlgSz);
  5502. totalSz += keyEncryptAlgoIdSz;
  5503. /* Start of OriginatorIdentifierOrKey */
  5504. /* recipient ECPoint, public key */
  5505. XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */
  5506. origPubKeyStr[0] = ASN_BIT_STRING;
  5507. origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,
  5508. origPubKeyStr + 1) + 2;
  5509. totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);
  5510. /* Originator AlgorithmIdentifier, params set to NULL for interop
  5511. compatibility */
  5512. origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 2);
  5513. origAlgId[origAlgIdSz++] = ASN_TAG_NULL;
  5514. origAlgId[origAlgIdSz++] = 0;
  5515. totalSz += origAlgIdSz;
  5516. /* outer OriginatorPublicKey IMPLICIT [1] */
  5517. origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,
  5518. origAlgIdSz + origPubKeyStrSz +
  5519. kari->senderKeyExportSz, origPubKeySeq);
  5520. totalSz += origPubKeySeqSz;
  5521. /* outer OriginatorIdentifierOrKey IMPLICIT [0] */
  5522. origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,
  5523. origPubKeySeqSz + origAlgIdSz +
  5524. origPubKeyStrSz + kari->senderKeyExportSz,
  5525. origIdOrKeySeq);
  5526. totalSz += origIdOrKeySeqSz;
  5527. /* version, always 3 */
  5528. verSz = SetMyVersion(3, ver, 0);
  5529. totalSz += verSz;
  5530. recip->recipVersion = 3;
  5531. /* outer IMPLICIT [1] kari */
  5532. kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);
  5533. totalSz += kariSeqSz;
  5534. if (totalSz > MAX_RECIP_SZ) {
  5535. WOLFSSL_MSG("KeyAgreeRecipientInfo output buffer too small");
  5536. wc_PKCS7_KariFree(kari);
  5537. #ifdef WOLFSSL_SMALL_STACK
  5538. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5539. #endif
  5540. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5541. return BUFFER_E;
  5542. }
  5543. XMEMCPY(recip->recip + idx, kariSeq, kariSeqSz);
  5544. idx += kariSeqSz;
  5545. XMEMCPY(recip->recip + idx, ver, verSz);
  5546. idx += verSz;
  5547. XMEMCPY(recip->recip + idx, origIdOrKeySeq, origIdOrKeySeqSz);
  5548. idx += origIdOrKeySeqSz;
  5549. XMEMCPY(recip->recip + idx, origPubKeySeq, origPubKeySeqSz);
  5550. idx += origPubKeySeqSz;
  5551. /* AlgorithmIdentifier with NULL parameter */
  5552. XMEMCPY(recip->recip + idx, origAlgId, origAlgIdSz);
  5553. idx += origAlgIdSz;
  5554. XMEMCPY(recip->recip + idx, origPubKeyStr, origPubKeyStrSz);
  5555. idx += origPubKeyStrSz;
  5556. /* ephemeral public key */
  5557. XMEMCPY(recip->recip + idx, kari->senderKeyExport, kari->senderKeyExportSz);
  5558. idx += kari->senderKeyExportSz;
  5559. if (kari->ukmSz > 0) {
  5560. XMEMCPY(recip->recip + idx, ukmExplicitSeq, ukmExplicitSz);
  5561. idx += ukmExplicitSz;
  5562. XMEMCPY(recip->recip + idx, ukmOctetStr, ukmOctetSz);
  5563. idx += ukmOctetSz;
  5564. XMEMCPY(recip->recip + idx, kari->ukm, kari->ukmSz);
  5565. idx += kari->ukmSz;
  5566. }
  5567. XMEMCPY(recip->recip + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);
  5568. idx += keyEncryptAlgoIdSz;
  5569. XMEMCPY(recip->recip + idx, keyWrapAlg, keyWrapAlgSz);
  5570. idx += keyWrapAlgSz;
  5571. XMEMCPY(recip->recip + idx, recipEncKeysSeq, recipEncKeysSeqSz);
  5572. idx += recipEncKeysSeqSz;
  5573. XMEMCPY(recip->recip + idx, recipEncKeySeq, recipEncKeySeqSz);
  5574. idx += recipEncKeySeqSz;
  5575. XMEMCPY(recip->recip + idx, recipKeyIdSeq, recipKeyIdSeqSz);
  5576. idx += recipKeyIdSeqSz;
  5577. XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz);
  5578. idx += subjKeyIdOctetSz;
  5579. /* subject key id */
  5580. XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, keyIdSize);
  5581. idx += keyIdSize;
  5582. XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz);
  5583. idx += encryptedKeyOctetSz;
  5584. /* encrypted CEK */
  5585. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5586. idx += encryptedKeySz;
  5587. wc_PKCS7_KariFree(kari);
  5588. #ifdef WOLFSSL_SMALL_STACK
  5589. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5590. #endif
  5591. /* store recipient size */
  5592. recip->recipSz = idx;
  5593. recip->recipType = PKCS7_KARI;
  5594. /* add recipient to recip list */
  5595. if (pkcs7->recipList == NULL) {
  5596. pkcs7->recipList = recip;
  5597. } else {
  5598. lastRecip = pkcs7->recipList;
  5599. while (lastRecip->next != NULL) {
  5600. lastRecip = lastRecip->next;
  5601. }
  5602. lastRecip->next = recip;
  5603. }
  5604. (void)options;
  5605. return idx;
  5606. }
  5607. #endif /* HAVE_ECC */
  5608. #ifndef NO_RSA
  5609. /* Encode and add CMS EnvelopedData KTRI (KeyTransRecipientInfo) RecipientInfo
  5610. * to CMS/PKCS#7 EnvelopedData structure.
  5611. *
  5612. * Returns 0 on success, negative upon error */
  5613. int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  5614. int options)
  5615. {
  5616. Pkcs7EncodedRecip* recip = NULL;
  5617. Pkcs7EncodedRecip* lastRecip = NULL;
  5618. WC_RNG rng;
  5619. word32 idx = 0;
  5620. word32 encryptedKeySz = 0;
  5621. int keyIdSize;
  5622. int ret = 0, blockKeySz;
  5623. int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0;
  5624. int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0;
  5625. int encKeyOctetStrSz;
  5626. int sidType;
  5627. byte ver[MAX_VERSION_SZ];
  5628. byte issuerSerialSeq[MAX_SEQ_SZ];
  5629. byte recipSeq[MAX_SEQ_SZ];
  5630. byte issuerSeq[MAX_SEQ_SZ];
  5631. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  5632. byte issuerSKID[MAX_LENGTH_SZ];
  5633. word32 issuerSKIDSz = 0;
  5634. byte* encryptedKey;
  5635. #ifdef WOLFSSL_SMALL_STACK
  5636. byte* serial;
  5637. byte* keyAlgArray;
  5638. RsaKey* pubKey;
  5639. DecodedCert* decoded;
  5640. serial = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5641. keyAlgArray = (byte*)XMALLOC(MAX_ALGO_SZ, pkcs7->heap,
  5642. DYNAMIC_TYPE_TMP_BUFFER);
  5643. decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  5644. DYNAMIC_TYPE_TMP_BUFFER);
  5645. if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
  5646. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5647. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5648. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5649. return MEMORY_E;
  5650. }
  5651. #else
  5652. byte serial[MAX_SN_SZ];
  5653. byte keyAlgArray[MAX_ALGO_SZ];
  5654. RsaKey pubKey[1];
  5655. DecodedCert decoded[1];
  5656. #endif
  5657. /* Always allocate to ensure aligned use with RSA */
  5658. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  5659. DYNAMIC_TYPE_WOLF_BIGINT);
  5660. if (encryptedKey == NULL) {
  5661. #ifdef WOLFSSL_SMALL_STACK
  5662. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5663. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5664. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5665. #endif
  5666. return MEMORY_E;
  5667. }
  5668. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  5669. XMEMSET(encryptedKey, 0, encryptedKeySz);
  5670. /* default to IssuerAndSerialNumber if not set */
  5671. if (pkcs7->sidType != 0) {
  5672. sidType = pkcs7->sidType;
  5673. } else {
  5674. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5675. }
  5676. /* allow options to override SubjectIdentifier type if set */
  5677. if (options & CMS_SKID) {
  5678. sidType = CMS_SKID;
  5679. } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) {
  5680. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5681. }
  5682. /* allocate recipient struct */
  5683. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  5684. DYNAMIC_TYPE_PKCS7);
  5685. if (recip == NULL) {
  5686. #ifdef WOLFSSL_SMALL_STACK
  5687. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5688. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5689. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5690. #endif
  5691. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5692. return MEMORY_E;
  5693. }
  5694. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5695. /* get key size for content-encryption key based on algorithm */
  5696. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5697. if (blockKeySz < 0) {
  5698. #ifdef WOLFSSL_SMALL_STACK
  5699. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5700. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5701. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5702. #endif
  5703. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5704. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5705. return blockKeySz;
  5706. }
  5707. /* generate random content encryption key, if needed */
  5708. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5709. if (ret < 0) {
  5710. #ifdef WOLFSSL_SMALL_STACK
  5711. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5712. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5713. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5714. #endif
  5715. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5716. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5717. return ret;
  5718. }
  5719. InitDecodedCert(decoded, (byte*)cert, certSz, pkcs7->heap);
  5720. ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
  5721. if (ret < 0) {
  5722. FreeDecodedCert(decoded);
  5723. #ifdef WOLFSSL_SMALL_STACK
  5724. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5725. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5726. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5727. #endif
  5728. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5729. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5730. return ret;
  5731. }
  5732. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  5733. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  5734. decoded->signatureOID)));
  5735. #else
  5736. keyIdSize = KEYID_SIZE;
  5737. #endif
  5738. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5739. /* version, must be 0 for IssuerAndSerialNumber */
  5740. verSz = SetMyVersion(0, ver, 0);
  5741. recip->recipVersion = 0;
  5742. /* IssuerAndSerialNumber */
  5743. if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
  5744. WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
  5745. FreeDecodedCert(decoded);
  5746. #ifdef WOLFSSL_SMALL_STACK
  5747. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5748. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5749. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5750. #endif
  5751. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5752. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5753. return -1;
  5754. }
  5755. issuerSz = decoded->issuerRawLen;
  5756. issuerSeqSz = SetSequence(issuerSz, issuerSeq);
  5757. if (decoded->serialSz == 0) {
  5758. WOLFSSL_MSG("DecodedCert missing serial number");
  5759. FreeDecodedCert(decoded);
  5760. #ifdef WOLFSSL_SMALL_STACK
  5761. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5762. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5763. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5764. #endif
  5765. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5766. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5767. return -1;
  5768. }
  5769. snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial,
  5770. MAX_SN_SZ, MAX_SN_SZ);
  5771. if (snSz < 0) {
  5772. WOLFSSL_MSG("Error setting the serial number");
  5773. FreeDecodedCert(decoded);
  5774. #ifdef WOLFSSL_SMALL_STACK
  5775. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5776. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5777. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5778. #endif
  5779. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5780. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5781. return -1;
  5782. }
  5783. issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
  5784. issuerSerialSeq);
  5785. } else if (sidType == CMS_SKID) {
  5786. /* version, must be 2 for SubjectKeyIdentifier */
  5787. verSz = SetMyVersion(2, ver, 0);
  5788. recip->recipVersion = 2;
  5789. issuerSKIDSz = SetLength(keyIdSize, issuerSKID);
  5790. } else {
  5791. FreeDecodedCert(decoded);
  5792. #ifdef WOLFSSL_SMALL_STACK
  5793. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5794. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5795. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5796. #endif
  5797. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5798. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5799. return PKCS7_RECIP_E;
  5800. }
  5801. pkcs7->publicKeyOID = decoded->keyOID;
  5802. /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
  5803. if (pkcs7->publicKeyOID != RSAk) {
  5804. FreeDecodedCert(decoded);
  5805. #ifdef WOLFSSL_SMALL_STACK
  5806. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5807. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5808. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5809. #endif
  5810. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5811. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5812. return ALGO_ID_E;
  5813. }
  5814. keyEncAlgSz = SetAlgoID(pkcs7->publicKeyOID, keyAlgArray, oidKeyType, 0);
  5815. if (keyEncAlgSz == 0) {
  5816. FreeDecodedCert(decoded);
  5817. #ifdef WOLFSSL_SMALL_STACK
  5818. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5819. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5820. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5821. #endif
  5822. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5823. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5824. return BAD_FUNC_ARG;
  5825. }
  5826. #ifdef WOLFSSL_SMALL_STACK
  5827. pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  5828. DYNAMIC_TYPE_TMP_BUFFER);
  5829. if (pubKey == NULL) {
  5830. FreeDecodedCert(decoded);
  5831. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5832. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5833. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5834. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5835. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5836. return MEMORY_E;
  5837. }
  5838. #endif
  5839. /* EncryptedKey */
  5840. ret = wc_InitRsaKey_ex(pubKey, pkcs7->heap, pkcs7->devId);
  5841. if (ret != 0) {
  5842. FreeDecodedCert(decoded);
  5843. #ifdef WOLFSSL_SMALL_STACK
  5844. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5845. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5846. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5847. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5848. #endif
  5849. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5850. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5851. return ret;
  5852. }
  5853. if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
  5854. decoded->pubKeySize) < 0) {
  5855. WOLFSSL_MSG("ASN RSA key decode error");
  5856. wc_FreeRsaKey(pubKey);
  5857. FreeDecodedCert(decoded);
  5858. #ifdef WOLFSSL_SMALL_STACK
  5859. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5860. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5861. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5862. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5863. #endif
  5864. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5865. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5866. return PUBLIC_KEY_E;
  5867. }
  5868. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  5869. if (ret != 0) {
  5870. wc_FreeRsaKey(pubKey);
  5871. FreeDecodedCert(decoded);
  5872. #ifdef WOLFSSL_SMALL_STACK
  5873. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5874. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5875. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5876. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5877. #endif
  5878. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5879. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5880. return MEMORY_E;
  5881. }
  5882. #ifdef WOLFSSL_ASYNC_CRYPT
  5883. /* Currently the call to RSA public encrypt here is blocking @TODO */
  5884. do {
  5885. ret = wc_AsyncWait(ret, &pubKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
  5886. if (ret >= 0)
  5887. #endif
  5888. {
  5889. ret = wc_RsaPublicEncrypt(pkcs7->cek, pkcs7->cekSz, encryptedKey,
  5890. encryptedKeySz, pubKey, &rng);
  5891. }
  5892. #ifdef WOLFSSL_ASYNC_CRYPT
  5893. } while (ret == WC_PENDING_E);
  5894. #endif
  5895. wc_FreeRsaKey(pubKey);
  5896. wc_FreeRng(&rng);
  5897. #ifdef WOLFSSL_SMALL_STACK
  5898. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5899. #endif
  5900. if (ret < 0) {
  5901. WOLFSSL_MSG("RSA Public Encrypt failed");
  5902. FreeDecodedCert(decoded);
  5903. #ifdef WOLFSSL_SMALL_STACK
  5904. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5905. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5906. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5907. #endif
  5908. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5909. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5910. return ret;
  5911. }
  5912. encryptedKeySz = ret;
  5913. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  5914. /* RecipientInfo */
  5915. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5916. recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
  5917. issuerSz + snSz + keyEncAlgSz +
  5918. encKeyOctetStrSz + encryptedKeySz, recipSeq);
  5919. if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
  5920. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5921. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5922. FreeDecodedCert(decoded);
  5923. #ifdef WOLFSSL_SMALL_STACK
  5924. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5925. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5926. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5927. #endif
  5928. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5929. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5930. return BUFFER_E;
  5931. }
  5932. } else {
  5933. recipSeqSz = SetSequence(verSz + ASN_TAG_SZ + issuerSKIDSz +
  5934. keyIdSize + keyEncAlgSz + encKeyOctetStrSz +
  5935. encryptedKeySz, recipSeq);
  5936. if (recipSeqSz + verSz + ASN_TAG_SZ + issuerSKIDSz + keyIdSize +
  5937. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5938. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5939. FreeDecodedCert(decoded);
  5940. #ifdef WOLFSSL_SMALL_STACK
  5941. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5942. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5943. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5944. #endif
  5945. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5946. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5947. return BUFFER_E;
  5948. }
  5949. }
  5950. idx = 0;
  5951. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  5952. idx += recipSeqSz;
  5953. XMEMCPY(recip->recip + idx, ver, verSz);
  5954. idx += verSz;
  5955. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5956. XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz);
  5957. idx += issuerSerialSeqSz;
  5958. XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz);
  5959. idx += issuerSeqSz;
  5960. XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz);
  5961. idx += issuerSz;
  5962. XMEMCPY(recip->recip + idx, serial, snSz);
  5963. idx += snSz;
  5964. } else {
  5965. recip->recip[idx] = ASN_CONTEXT_SPECIFIC;
  5966. idx += ASN_TAG_SZ;
  5967. XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz);
  5968. idx += issuerSKIDSz;
  5969. XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, keyIdSize);
  5970. idx += keyIdSize;
  5971. }
  5972. XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz);
  5973. idx += keyEncAlgSz;
  5974. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  5975. idx += encKeyOctetStrSz;
  5976. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5977. idx += encryptedKeySz;
  5978. FreeDecodedCert(decoded);
  5979. #ifdef WOLFSSL_SMALL_STACK
  5980. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5981. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5982. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5983. #endif
  5984. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5985. /* store recipient size */
  5986. recip->recipSz = idx;
  5987. recip->recipType = PKCS7_KTRI;
  5988. /* add recipient to recip list */
  5989. if (pkcs7->recipList == NULL) {
  5990. pkcs7->recipList = recip;
  5991. } else {
  5992. lastRecip = pkcs7->recipList;
  5993. while (lastRecip->next != NULL) {
  5994. lastRecip = lastRecip->next;
  5995. }
  5996. lastRecip->next = recip;
  5997. }
  5998. return idx;
  5999. }
  6000. #endif /* !NO_RSA */
  6001. /* encrypt content using encryptOID algo */
  6002. static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
  6003. byte* iv, int ivSz, byte* aad, word32 aadSz,
  6004. byte* authTag, word32 authTagSz, byte* in,
  6005. int inSz, byte* out, int devId, void* heap)
  6006. {
  6007. int ret;
  6008. #ifndef NO_AES
  6009. #ifdef WOLFSSL_SMALL_STACK
  6010. Aes* aes;
  6011. #else
  6012. Aes aes[1];
  6013. #endif
  6014. #endif
  6015. #ifndef NO_DES3
  6016. Des des;
  6017. Des3 des3;
  6018. #endif
  6019. if (key == NULL || iv == NULL || in == NULL || out == NULL)
  6020. return BAD_FUNC_ARG;
  6021. switch (encryptOID) {
  6022. #ifndef NO_AES
  6023. #ifdef HAVE_AES_CBC
  6024. #ifdef WOLFSSL_AES_128
  6025. case AES128CBCb:
  6026. #endif
  6027. #ifdef WOLFSSL_AES_192
  6028. case AES192CBCb:
  6029. #endif
  6030. #ifdef WOLFSSL_AES_256
  6031. case AES256CBCb:
  6032. #endif
  6033. if (
  6034. #ifdef WOLFSSL_AES_128
  6035. (encryptOID == AES128CBCb && keySz != 16 ) ||
  6036. #endif
  6037. #ifdef WOLFSSL_AES_192
  6038. (encryptOID == AES192CBCb && keySz != 24 ) ||
  6039. #endif
  6040. #ifdef WOLFSSL_AES_256
  6041. (encryptOID == AES256CBCb && keySz != 32 ) ||
  6042. #endif
  6043. (ivSz != AES_BLOCK_SIZE) )
  6044. return BAD_FUNC_ARG;
  6045. #ifdef WOLFSSL_SMALL_STACK
  6046. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6047. DYNAMIC_TYPE_AES)) == NULL)
  6048. return MEMORY_E;
  6049. #endif
  6050. ret = wc_AesInit(aes, heap, devId);
  6051. if (ret == 0) {
  6052. ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
  6053. if (ret == 0) {
  6054. ret = wc_AesCbcEncrypt(aes, out, in, inSz);
  6055. #ifdef WOLFSSL_ASYNC_CRYPT
  6056. /* async encrypt not available here, so block till done */
  6057. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6058. #endif
  6059. }
  6060. wc_AesFree(aes);
  6061. }
  6062. #ifdef WOLFSSL_SMALL_STACK
  6063. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6064. #endif
  6065. break;
  6066. #endif /* HAVE_AES_CBC */
  6067. #ifdef HAVE_AESGCM
  6068. #ifdef WOLFSSL_AES_128
  6069. case AES128GCMb:
  6070. #endif
  6071. #ifdef WOLFSSL_AES_192
  6072. case AES192GCMb:
  6073. #endif
  6074. #ifdef WOLFSSL_AES_256
  6075. case AES256GCMb:
  6076. #endif
  6077. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6078. defined(WOLFSSL_AES_256)
  6079. if (authTag == NULL)
  6080. return BAD_FUNC_ARG;
  6081. #ifdef WOLFSSL_SMALL_STACK
  6082. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6083. DYNAMIC_TYPE_AES)) == NULL)
  6084. return MEMORY_E;
  6085. #endif
  6086. ret = wc_AesInit(aes, heap, devId);
  6087. if (ret == 0) {
  6088. ret = wc_AesGcmSetKey(aes, key, keySz);
  6089. if (ret == 0) {
  6090. ret = wc_AesGcmEncrypt(aes, out, in, inSz, iv, ivSz,
  6091. authTag, authTagSz, aad, aadSz);
  6092. #ifdef WOLFSSL_ASYNC_CRYPT
  6093. /* async encrypt not available here, so block till done */
  6094. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6095. #endif
  6096. }
  6097. wc_AesFree(aes);
  6098. }
  6099. #ifdef WOLFSSL_SMALL_STACK
  6100. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6101. #endif
  6102. break;
  6103. #endif
  6104. #endif /* HAVE_AESGCM */
  6105. #ifdef HAVE_AESCCM
  6106. #ifdef WOLFSSL_AES_128
  6107. case AES128CCMb:
  6108. #endif
  6109. #ifdef WOLFSSL_AES_192
  6110. case AES192CCMb:
  6111. #endif
  6112. #ifdef WOLFSSL_AES_256
  6113. case AES256CCMb:
  6114. #endif
  6115. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6116. defined(WOLFSSL_AES_256)
  6117. if (authTag == NULL)
  6118. return BAD_FUNC_ARG;
  6119. #ifdef WOLFSSL_SMALL_STACK
  6120. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6121. DYNAMIC_TYPE_AES)) == NULL)
  6122. return MEMORY_E;
  6123. #endif
  6124. ret = wc_AesInit(aes, heap, devId);
  6125. if (ret == 0) {
  6126. ret = wc_AesCcmSetKey(aes, key, keySz);
  6127. if (ret == 0) {
  6128. ret = wc_AesCcmEncrypt(aes, out, in, inSz, iv, ivSz,
  6129. authTag, authTagSz, aad, aadSz);
  6130. #ifdef WOLFSSL_ASYNC_CRYPT
  6131. /* async encrypt not available here, so block till done */
  6132. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6133. #endif
  6134. }
  6135. wc_AesFree(aes);
  6136. }
  6137. #ifdef WOLFSSL_SMALL_STACK
  6138. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6139. #endif
  6140. break;
  6141. #endif
  6142. #endif /* HAVE_AESCCM */
  6143. #endif /* !NO_AES */
  6144. #ifndef NO_DES3
  6145. case DESb:
  6146. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6147. return BAD_FUNC_ARG;
  6148. ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
  6149. if (ret == 0)
  6150. ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
  6151. break;
  6152. case DES3b:
  6153. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6154. return BAD_FUNC_ARG;
  6155. ret = wc_Des3Init(&des3, heap, devId);
  6156. if (ret == 0) {
  6157. ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
  6158. if (ret == 0) {
  6159. ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
  6160. #ifdef WOLFSSL_ASYNC_CRYPT
  6161. /* async encrypt not available here, so block till done */
  6162. ret = wc_AsyncWait(ret, &des3.asyncDev, WC_ASYNC_FLAG_NONE);
  6163. #endif
  6164. }
  6165. wc_Des3Free(&des3);
  6166. }
  6167. break;
  6168. #endif /* !NO_DES3 */
  6169. default:
  6170. WOLFSSL_MSG("Unsupported content cipher type");
  6171. return ALGO_ID_E;
  6172. };
  6173. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  6174. (void)authTag;
  6175. (void)authTagSz;
  6176. (void)aad;
  6177. (void)aadSz;
  6178. #endif
  6179. return ret;
  6180. }
  6181. /* decrypt content using encryptOID algo
  6182. * returns 0 on success */
  6183. static int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,
  6184. int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,
  6185. word32 authTagSz, byte* in, int inSz, byte* out, int devId, void* heap)
  6186. {
  6187. int ret;
  6188. #ifndef NO_AES
  6189. #ifdef WOLFSSL_SMALL_STACK
  6190. Aes *aes;
  6191. #else
  6192. Aes aes[1];
  6193. #endif
  6194. #endif
  6195. #ifndef NO_DES3
  6196. Des des;
  6197. Des3 des3;
  6198. #endif
  6199. if (iv == NULL || in == NULL || out == NULL)
  6200. return BAD_FUNC_ARG;
  6201. if (pkcs7->decryptionCb != NULL) {
  6202. return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,
  6203. aad, aadSz, authTag, authTagSz, in,
  6204. inSz, out, pkcs7->decryptionCtx);
  6205. }
  6206. if (key == NULL)
  6207. return BAD_FUNC_ARG;
  6208. switch (encryptOID) {
  6209. #ifndef NO_AES
  6210. #ifdef HAVE_AES_CBC
  6211. #ifdef WOLFSSL_AES_128
  6212. case AES128CBCb:
  6213. #endif
  6214. #ifdef WOLFSSL_AES_192
  6215. case AES192CBCb:
  6216. #endif
  6217. #ifdef WOLFSSL_AES_256
  6218. case AES256CBCb:
  6219. #endif
  6220. if (
  6221. #ifdef WOLFSSL_AES_128
  6222. (encryptOID == AES128CBCb && keySz != 16 ) ||
  6223. #endif
  6224. #ifdef WOLFSSL_AES_192
  6225. (encryptOID == AES192CBCb && keySz != 24 ) ||
  6226. #endif
  6227. #ifdef WOLFSSL_AES_256
  6228. (encryptOID == AES256CBCb && keySz != 32 ) ||
  6229. #endif
  6230. (ivSz != AES_BLOCK_SIZE) )
  6231. return BAD_FUNC_ARG;
  6232. #ifdef WOLFSSL_SMALL_STACK
  6233. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6234. DYNAMIC_TYPE_AES)) == NULL)
  6235. return MEMORY_E;
  6236. #endif
  6237. ret = wc_AesInit(aes, heap, devId);
  6238. if (ret == 0) {
  6239. ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
  6240. if (ret == 0) {
  6241. ret = wc_AesCbcDecrypt(aes, out, in, inSz);
  6242. #ifdef WOLFSSL_ASYNC_CRYPT
  6243. /* async decrypt not available here, so block till done */
  6244. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6245. #endif
  6246. }
  6247. wc_AesFree(aes);
  6248. }
  6249. #ifdef WOLFSSL_SMALL_STACK
  6250. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6251. #endif
  6252. break;
  6253. #endif /* HAVE_AES_CBC */
  6254. #ifdef HAVE_AESGCM
  6255. #ifdef WOLFSSL_AES_128
  6256. case AES128GCMb:
  6257. #endif
  6258. #ifdef WOLFSSL_AES_192
  6259. case AES192GCMb:
  6260. #endif
  6261. #ifdef WOLFSSL_AES_256
  6262. case AES256GCMb:
  6263. #endif
  6264. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6265. defined(WOLFSSL_AES_256)
  6266. if (authTag == NULL)
  6267. return BAD_FUNC_ARG;
  6268. #ifdef WOLFSSL_SMALL_STACK
  6269. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6270. DYNAMIC_TYPE_AES)) == NULL)
  6271. return MEMORY_E;
  6272. #endif
  6273. ret = wc_AesInit(aes, heap, devId);
  6274. if (ret == 0) {
  6275. ret = wc_AesGcmSetKey(aes, key, keySz);
  6276. if (ret == 0) {
  6277. ret = wc_AesGcmDecrypt(aes, out, in, inSz, iv, ivSz,
  6278. authTag, authTagSz, aad, aadSz);
  6279. #ifdef WOLFSSL_ASYNC_CRYPT
  6280. /* async decrypt not available here, so block till done */
  6281. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6282. #endif
  6283. }
  6284. wc_AesFree(aes);
  6285. }
  6286. #ifdef WOLFSSL_SMALL_STACK
  6287. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6288. #endif
  6289. break;
  6290. #endif
  6291. #endif /* HAVE_AESGCM */
  6292. #ifdef HAVE_AESCCM
  6293. #ifdef WOLFSSL_AES_128
  6294. case AES128CCMb:
  6295. #endif
  6296. #ifdef WOLFSSL_AES_192
  6297. case AES192CCMb:
  6298. #endif
  6299. #ifdef WOLFSSL_AES_256
  6300. case AES256CCMb:
  6301. #endif
  6302. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6303. defined(WOLFSSL_AES_256)
  6304. if (authTag == NULL)
  6305. return BAD_FUNC_ARG;
  6306. #ifdef WOLFSSL_SMALL_STACK
  6307. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6308. DYNAMIC_TYPE_AES)) == NULL)
  6309. return MEMORY_E;
  6310. #endif
  6311. ret = wc_AesInit(aes, heap, devId);
  6312. if (ret == 0) {
  6313. ret = wc_AesCcmSetKey(aes, key, keySz);
  6314. if (ret == 0) {
  6315. ret = wc_AesCcmDecrypt(aes, out, in, inSz, iv, ivSz,
  6316. authTag, authTagSz, aad, aadSz);
  6317. #ifdef WOLFSSL_ASYNC_CRYPT
  6318. /* async decrypt not available here, so block till done */
  6319. ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE);
  6320. #endif
  6321. }
  6322. wc_AesFree(aes);
  6323. }
  6324. #ifdef WOLFSSL_SMALL_STACK
  6325. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6326. #endif
  6327. break;
  6328. #endif
  6329. #endif /* HAVE_AESCCM */
  6330. #endif /* !NO_AES */
  6331. #ifndef NO_DES3
  6332. case DESb:
  6333. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6334. return BAD_FUNC_ARG;
  6335. ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
  6336. if (ret == 0)
  6337. ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
  6338. break;
  6339. case DES3b:
  6340. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6341. return BAD_FUNC_ARG;
  6342. ret = wc_Des3Init(&des3, heap, devId);
  6343. if (ret == 0) {
  6344. ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
  6345. if (ret == 0) {
  6346. ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
  6347. #ifdef WOLFSSL_ASYNC_CRYPT
  6348. /* async decrypt not available here, so block till done */
  6349. ret = wc_AsyncWait(ret, &des3.asyncDev, WC_ASYNC_FLAG_NONE);
  6350. #endif
  6351. }
  6352. wc_Des3Free(&des3);
  6353. }
  6354. break;
  6355. #endif /* !NO_DES3 */
  6356. default:
  6357. WOLFSSL_MSG("Unsupported content cipher type");
  6358. return ALGO_ID_E;
  6359. };
  6360. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  6361. (void)authTag;
  6362. (void)authTagSz;
  6363. (void)aad;
  6364. (void)aadSz;
  6365. #endif
  6366. return ret;
  6367. }
  6368. /* Generate random block, place in out, return 0 on success negative on error.
  6369. * Used for generation of IV, nonce, etc */
  6370. static int wc_PKCS7_GenerateBlock(PKCS7* pkcs7, WC_RNG* rng, byte* out,
  6371. word32 outSz)
  6372. {
  6373. int ret;
  6374. WC_RNG* rnd = NULL;
  6375. if (out == NULL || outSz == 0)
  6376. return BAD_FUNC_ARG;
  6377. /* input RNG is optional, init local one if input rng is NULL */
  6378. if (rng == NULL) {
  6379. rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);
  6380. if (rnd == NULL)
  6381. return MEMORY_E;
  6382. ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);
  6383. if (ret != 0) {
  6384. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  6385. return ret;
  6386. }
  6387. } else {
  6388. rnd = rng;
  6389. }
  6390. ret = wc_RNG_GenerateBlock(rnd, out, outSz);
  6391. if (rng == NULL) {
  6392. wc_FreeRng(rnd);
  6393. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  6394. }
  6395. return ret;
  6396. }
  6397. /* Set default SignerIdentifier type to be used. Is either
  6398. * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using
  6399. * IssuerAndSerialNumber unless set with this function or explicitly
  6400. * overridden via options when adding RecipientInfo type.
  6401. *
  6402. * Using the type DEGENERATE_SID skips over signer information. In degenerate
  6403. * cases there are no signers.
  6404. *
  6405. * pkcs7 - pointer to initialized PKCS7 structure
  6406. * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID
  6407. *
  6408. * return 0 on success, negative upon error */
  6409. int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type)
  6410. {
  6411. if (pkcs7 == NULL)
  6412. return BAD_FUNC_ARG;
  6413. if (type != CMS_ISSUER_AND_SERIAL_NUMBER &&
  6414. type != CMS_SKID &&
  6415. type != DEGENERATE_SID) {
  6416. return BAD_FUNC_ARG;
  6417. }
  6418. pkcs7->sidType = type;
  6419. return 0;
  6420. }
  6421. /* Set custom contentType, currently supported with SignedData type
  6422. *
  6423. * pkcs7 - pointer to initialized PKCS7 structure
  6424. * contentType - pointer to array with ASN.1 encoded OID value
  6425. * sz - length of contentType array, octets
  6426. *
  6427. * return 0 on success, negative upon error */
  6428. int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, word32 sz)
  6429. {
  6430. if (pkcs7 == NULL || contentType == NULL || sz == 0)
  6431. return BAD_FUNC_ARG;
  6432. if (sz > MAX_OID_SZ) {
  6433. WOLFSSL_MSG("input array too large, bounded by MAX_OID_SZ");
  6434. return BAD_FUNC_ARG;
  6435. }
  6436. XMEMCPY(pkcs7->contentType, contentType, sz);
  6437. pkcs7->contentTypeSz = sz;
  6438. return 0;
  6439. }
  6440. /* return size of padded data, padded to blockSz chunks, or negative on error */
  6441. int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
  6442. {
  6443. int padSz;
  6444. if (blockSz == 0)
  6445. return BAD_FUNC_ARG;
  6446. padSz = blockSz - (inputSz % blockSz);
  6447. return padSz;
  6448. }
  6449. /* pad input data to blockSz chunk, place in outSz. out must be big enough
  6450. * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */
  6451. int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
  6452. word32 blockSz)
  6453. {
  6454. int i, padSz;
  6455. if (in == NULL || inSz == 0 ||
  6456. out == NULL || outSz == 0)
  6457. return BAD_FUNC_ARG;
  6458. padSz = wc_PKCS7_GetPadSize(inSz, blockSz);
  6459. if (outSz < (inSz + padSz))
  6460. return BAD_FUNC_ARG;
  6461. XMEMCPY(out, in, inSz);
  6462. for (i = 0; i < padSz; i++) {
  6463. out[inSz + i] = (byte)padSz;
  6464. }
  6465. return inSz + padSz;
  6466. }
  6467. /* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo
  6468. * to CMS/PKCS#7 EnvelopedData structure.
  6469. *
  6470. * Return 0 on success, negative upon error */
  6471. int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb,
  6472. int options)
  6473. {
  6474. int oriTypeLenSz, blockKeySz, ret;
  6475. word32 idx, recipSeqSz;
  6476. Pkcs7EncodedRecip* recip = NULL;
  6477. Pkcs7EncodedRecip* lastRecip = NULL;
  6478. byte recipSeq[MAX_SEQ_SZ];
  6479. byte oriTypeLen[MAX_LENGTH_SZ];
  6480. byte oriType[MAX_ORI_TYPE_SZ];
  6481. byte oriValue[MAX_ORI_VALUE_SZ];
  6482. word32 oriTypeSz = MAX_ORI_TYPE_SZ;
  6483. word32 oriValueSz = MAX_ORI_VALUE_SZ;
  6484. if (pkcs7 == NULL || oriEncryptCb == NULL) {
  6485. return BAD_FUNC_ARG;
  6486. }
  6487. /* allocate memory for RecipientInfo, KEK, encrypted key */
  6488. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  6489. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6490. if (recip == NULL)
  6491. return MEMORY_E;
  6492. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6493. /* get key size for content-encryption key based on algorithm */
  6494. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6495. if (blockKeySz < 0) {
  6496. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6497. return blockKeySz;
  6498. }
  6499. /* generate random content encryption key, if needed */
  6500. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  6501. if (ret < 0) {
  6502. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6503. return ret;
  6504. }
  6505. /* call user callback to encrypt CEK and get oriType and oriValue
  6506. values back */
  6507. ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz,
  6508. oriValue, &oriValueSz, pkcs7->oriEncryptCtx);
  6509. if (ret != 0) {
  6510. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6511. return ret;
  6512. }
  6513. oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen);
  6514. recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz +
  6515. oriValueSz, recipSeq);
  6516. idx = 0;
  6517. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6518. idx += recipSeqSz;
  6519. /* oriType */
  6520. recip->recip[idx] = ASN_OBJECT_ID;
  6521. idx += 1;
  6522. XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz);
  6523. idx += oriTypeLenSz;
  6524. XMEMCPY(recip->recip + idx, oriType, oriTypeSz);
  6525. idx += oriTypeSz;
  6526. /* oriValue, input MUST already be ASN.1 encoded */
  6527. XMEMCPY(recip->recip + idx, oriValue, oriValueSz);
  6528. idx += oriValueSz;
  6529. /* store recipient size */
  6530. recip->recipSz = idx;
  6531. recip->recipType = PKCS7_ORI;
  6532. recip->recipVersion = 4;
  6533. /* add recipient to recip list */
  6534. if (pkcs7->recipList == NULL) {
  6535. pkcs7->recipList = recip;
  6536. } else {
  6537. lastRecip = pkcs7->recipList;
  6538. while (lastRecip->next != NULL) {
  6539. lastRecip = lastRecip->next;
  6540. }
  6541. lastRecip->next = recip;
  6542. }
  6543. (void)options;
  6544. return idx;
  6545. }
  6546. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  6547. static int wc_PKCS7_GenerateKEK_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  6548. byte* salt, word32 saltSz, int kdfOID,
  6549. int prfOID, int iterations, byte* out,
  6550. word32 outSz)
  6551. {
  6552. int ret;
  6553. if (pkcs7 == NULL || passwd == NULL || salt == NULL || out == NULL)
  6554. return BAD_FUNC_ARG;
  6555. switch (kdfOID) {
  6556. case PBKDF2_OID:
  6557. ret = wc_PBKDF2(out, passwd, pLen, salt, saltSz, iterations,
  6558. outSz, prfOID);
  6559. if (ret != 0) {
  6560. return ret;
  6561. }
  6562. break;
  6563. default:
  6564. WOLFSSL_MSG("Unsupported KDF OID");
  6565. return PKCS7_OID_E;
  6566. }
  6567. return 0;
  6568. }
  6569. /* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK).
  6570. *
  6571. * Returns output size on success, negative upon error */
  6572. static int wc_PKCS7_PwriKek_KeyWrap(PKCS7* pkcs7, const byte* kek, word32 kekSz,
  6573. const byte* cek, word32 cekSz,
  6574. byte* out, word32 *outSz,
  6575. const byte* iv, word32 ivSz, int algID)
  6576. {
  6577. WC_RNG rng;
  6578. int blockSz, outLen, ret;
  6579. word32 padSz;
  6580. byte* lastBlock;
  6581. if (kek == NULL || cek == NULL || iv == NULL || outSz == NULL)
  6582. return BAD_FUNC_ARG;
  6583. /* get encryption algorithm block size */
  6584. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  6585. if (blockSz <= 0) {
  6586. if (blockSz < 0)
  6587. return blockSz;
  6588. else
  6589. return ALGO_ID_E;
  6590. }
  6591. /* get pad bytes needed to block boundary */
  6592. padSz = blockSz - ((4 + cekSz) % blockSz);
  6593. outLen = 4 + cekSz + padSz;
  6594. /* must be at least two blocks long */
  6595. if (outLen < 2 * blockSz)
  6596. padSz += blockSz;
  6597. /* if user set out to NULL, give back required length */
  6598. if (out == NULL) {
  6599. *outSz = outLen;
  6600. return LENGTH_ONLY_E;
  6601. }
  6602. /* verify output buffer is large enough */
  6603. if (*outSz < (word32)outLen)
  6604. return BUFFER_E;
  6605. out[0] = (byte)cekSz;
  6606. out[1] = ~cek[0];
  6607. out[2] = ~cek[1];
  6608. out[3] = ~cek[2];
  6609. XMEMCPY(out + 4, cek, cekSz);
  6610. /* random padding of size padSz */
  6611. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  6612. if (ret != 0)
  6613. return ret;
  6614. ret = wc_RNG_GenerateBlock(&rng, out + 4 + cekSz, padSz);
  6615. if (ret == 0) {
  6616. /* encrypt, normal */
  6617. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, (byte*)iv,
  6618. ivSz, NULL, 0, NULL, 0, out, outLen, out,
  6619. pkcs7->devId, pkcs7->heap);
  6620. }
  6621. if (ret == 0) {
  6622. /* encrypt again, using last ciphertext block as IV */
  6623. lastBlock = out + (((outLen / blockSz) - 1) * blockSz);
  6624. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, lastBlock,
  6625. blockSz, NULL, 0, NULL, 0, out,
  6626. outLen, out, pkcs7->devId, pkcs7->heap);
  6627. }
  6628. if (ret == 0) {
  6629. *outSz = outLen;
  6630. } else {
  6631. outLen = ret;
  6632. }
  6633. wc_FreeRng(&rng);
  6634. return outLen;
  6635. }
  6636. /* RFC3211 (Section 2.3.2) key unwrap algorithm (id-alg-PWRI-KEK).
  6637. *
  6638. * Returns cek size on success, negative upon error */
  6639. static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,
  6640. word32 kekSz, const byte* in, word32 inSz,
  6641. byte* out, word32 outSz, const byte* iv,
  6642. word32 ivSz, int algID)
  6643. {
  6644. int blockSz, cekLen, ret;
  6645. byte* tmpIv = NULL;
  6646. byte* lastBlock = NULL;
  6647. byte* outTmp = NULL;
  6648. if (pkcs7 == NULL || kek == NULL || in == NULL ||
  6649. out == NULL || iv == NULL) {
  6650. return BAD_FUNC_ARG;
  6651. }
  6652. outTmp = (byte*)XMALLOC(inSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6653. if (outTmp == NULL)
  6654. return MEMORY_E;
  6655. /* get encryption algorithm block size */
  6656. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  6657. if (blockSz <= 0) {
  6658. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6659. if (blockSz < 0)
  6660. return blockSz;
  6661. else
  6662. return ALGO_ID_E;
  6663. }
  6664. /* input needs to be blockSz multiple and at least 2 * blockSz */
  6665. if (((inSz % blockSz) != 0) || (inSz < (2 * (word32)blockSz))) {
  6666. WOLFSSL_MSG("PWRI-KEK unwrap input must of block size and >= 2 "
  6667. "times block size");
  6668. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6669. return BAD_FUNC_ARG;
  6670. }
  6671. /* use block out[n-1] as IV to decrypt block out[n] */
  6672. lastBlock = (byte*)in + inSz - blockSz;
  6673. tmpIv = lastBlock - blockSz;
  6674. /* decrypt last block */
  6675. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,
  6676. blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,
  6677. outTmp + inSz - blockSz, pkcs7->devId, pkcs7->heap);
  6678. if (ret == 0) {
  6679. /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
  6680. lastBlock = outTmp + inSz - blockSz;
  6681. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6682. lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,
  6683. outTmp, pkcs7->devId, pkcs7->heap);
  6684. }
  6685. if (ret == 0) {
  6686. /* decrypt using original kek and iv */
  6687. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6688. (byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp,
  6689. pkcs7->devId, pkcs7->heap);
  6690. }
  6691. if (ret != 0) {
  6692. ForceZero(outTmp, inSz);
  6693. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6694. return ret;
  6695. }
  6696. cekLen = outTmp[0];
  6697. /* verify length */
  6698. if ((word32)cekLen > inSz) {
  6699. ForceZero(outTmp, inSz);
  6700. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6701. return BAD_FUNC_ARG;
  6702. }
  6703. /* verify check bytes */
  6704. if ((outTmp[1] ^ outTmp[4]) != 0xFF ||
  6705. (outTmp[2] ^ outTmp[5]) != 0xFF ||
  6706. (outTmp[3] ^ outTmp[6]) != 0xFF) {
  6707. ForceZero(outTmp, inSz);
  6708. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6709. return BAD_FUNC_ARG;
  6710. }
  6711. if (outSz < (word32)cekLen) {
  6712. ForceZero(outTmp, inSz);
  6713. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6714. return BUFFER_E;
  6715. }
  6716. XMEMCPY(out, outTmp + 4, outTmp[0]);
  6717. ForceZero(outTmp, inSz);
  6718. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6719. return cekLen;
  6720. }
  6721. /* Encode and add CMS EnvelopedData PWRI (PasswordRecipientInfo) RecipientInfo
  6722. * to CMS/PKCS#7 EnvelopedData structure.
  6723. *
  6724. * Return 0 on success, negative upon error */
  6725. int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  6726. byte* salt, word32 saltSz, int kdfOID,
  6727. int hashOID, int iterations, int kekEncryptOID,
  6728. int options)
  6729. {
  6730. Pkcs7EncodedRecip* recip = NULL;
  6731. Pkcs7EncodedRecip* lastRecip = NULL;
  6732. /* PasswordRecipientInfo */
  6733. byte recipSeq[MAX_SEQ_SZ];
  6734. byte ver[MAX_VERSION_SZ];
  6735. word32 recipSeqSz, verSz;
  6736. /* KeyDerivationAlgorithmIdentifier */
  6737. byte kdfAlgoIdSeq[MAX_SEQ_SZ];
  6738. byte kdfAlgoId[MAX_OID_SZ];
  6739. byte kdfParamsSeq[MAX_SEQ_SZ]; /* PBKDF2-params */
  6740. byte kdfSaltOctetStr[MAX_OCTET_STR_SZ]; /* salt OCTET STRING */
  6741. byte kdfIterations[MAX_VERSION_SZ];
  6742. word32 kdfAlgoIdSeqSz, kdfAlgoIdSz;
  6743. word32 kdfParamsSeqSz, kdfSaltOctetStrSz, kdfIterationsSz;
  6744. /* OPTIONAL: keyLength, not supported yet */
  6745. /* OPTIONAL: prf AlgorithmIdentifier, not supported yet */
  6746. /* KeyEncryptionAlgorithmIdentifier */
  6747. byte keyEncAlgoIdSeq[MAX_SEQ_SZ];
  6748. byte keyEncAlgoId[MAX_OID_SZ]; /* id-alg-PWRI-KEK */
  6749. byte pwriEncAlgoId[MAX_ALGO_SZ];
  6750. byte ivOctetString[MAX_OCTET_STR_SZ];
  6751. word32 keyEncAlgoIdSeqSz, keyEncAlgoIdSz;
  6752. word32 pwriEncAlgoIdSz, ivOctetStringSz;
  6753. /* EncryptedKey */
  6754. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6755. word32 encKeyOctetStrSz;
  6756. byte tmpIv[MAX_CONTENT_IV_SIZE];
  6757. byte* encryptedKey = NULL;
  6758. byte* kek = NULL;
  6759. int cekKeySz = 0, kekKeySz = 0, kekBlockSz = 0, ret = 0;
  6760. int encryptOID;
  6761. word32 idx, totalSz = 0, encryptedKeySz;
  6762. if (pkcs7 == NULL || passwd == NULL || pLen == 0 ||
  6763. salt == NULL || saltSz == 0) {
  6764. return BAD_FUNC_ARG;
  6765. }
  6766. /* allow user to use different KEK encryption algorithm than used for
  6767. * main content encryption algorithm, if passed in */
  6768. if (kekEncryptOID != 0) {
  6769. encryptOID = kekEncryptOID;
  6770. } else {
  6771. encryptOID = pkcs7->encryptOID;
  6772. }
  6773. /* get content-encryption key size, based on algorithm */
  6774. cekKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6775. if (cekKeySz < 0)
  6776. return cekKeySz;
  6777. /* get KEK encryption key size, based on algorithm */
  6778. if (encryptOID != pkcs7->encryptOID) {
  6779. kekKeySz = wc_PKCS7_GetOIDKeySize(encryptOID);
  6780. } else {
  6781. kekKeySz = cekKeySz;
  6782. }
  6783. /* get KEK encryption block size */
  6784. kekBlockSz = wc_PKCS7_GetOIDBlockSize(encryptOID);
  6785. if (kekBlockSz < 0)
  6786. return kekBlockSz;
  6787. /* generate random CEK */
  6788. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, cekKeySz);
  6789. if (ret < 0)
  6790. return ret;
  6791. /* generate random IV */
  6792. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, kekBlockSz);
  6793. if (ret != 0)
  6794. return ret;
  6795. /* allocate memory for RecipientInfo, KEK, encrypted key */
  6796. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  6797. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6798. if (recip == NULL)
  6799. return MEMORY_E;
  6800. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6801. if (kek == NULL) {
  6802. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6803. return MEMORY_E;
  6804. }
  6805. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ,
  6806. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6807. if (encryptedKey == NULL) {
  6808. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6809. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6810. return MEMORY_E;
  6811. }
  6812. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  6813. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6814. XMEMSET(kek, 0, kekKeySz);
  6815. XMEMSET(encryptedKey, 0, encryptedKeySz);
  6816. /* generate KEK: expand password into KEK */
  6817. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, passwd, pLen, salt, saltSz,
  6818. kdfOID, hashOID, iterations, kek,
  6819. kekKeySz);
  6820. if (ret < 0) {
  6821. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6822. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6823. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6824. return ret;
  6825. }
  6826. /* generate encrypted key: encrypt CEK with KEK */
  6827. ret = wc_PKCS7_PwriKek_KeyWrap(pkcs7, kek, kekKeySz, pkcs7->cek,
  6828. pkcs7->cekSz, encryptedKey, &encryptedKeySz,
  6829. tmpIv, kekBlockSz, encryptOID);
  6830. if (ret < 0) {
  6831. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6832. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6833. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6834. return ret;
  6835. }
  6836. encryptedKeySz = ret;
  6837. /* put together encrypted key OCTET STRING */
  6838. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  6839. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  6840. /* put together IV OCTET STRING */
  6841. ivOctetStringSz = SetOctetString(kekBlockSz, ivOctetString);
  6842. totalSz += (ivOctetStringSz + kekBlockSz);
  6843. /* set PWRIAlgorithms AlgorithmIdentifier, adding (ivOctetStringSz +
  6844. blockKeySz) for IV OCTET STRING */
  6845. pwriEncAlgoIdSz = SetAlgoID(encryptOID, pwriEncAlgoId,
  6846. oidBlkType, ivOctetStringSz + kekBlockSz);
  6847. totalSz += pwriEncAlgoIdSz;
  6848. /* set KeyEncryptionAlgorithms OID */
  6849. ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId));
  6850. if (ret <= 0) {
  6851. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6852. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6853. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6854. return ret;
  6855. }
  6856. keyEncAlgoIdSz = ret;
  6857. totalSz += keyEncAlgoIdSz;
  6858. /* KeyEncryptionAlgorithm SEQ */
  6859. keyEncAlgoIdSeqSz = SetSequence(keyEncAlgoIdSz + pwriEncAlgoIdSz +
  6860. ivOctetStringSz + kekBlockSz,
  6861. keyEncAlgoIdSeq);
  6862. totalSz += keyEncAlgoIdSeqSz;
  6863. /* set KDF salt */
  6864. kdfSaltOctetStrSz = SetOctetString(saltSz, kdfSaltOctetStr);
  6865. totalSz += (kdfSaltOctetStrSz + saltSz);
  6866. /* set KDF iteration count */
  6867. kdfIterationsSz = SetMyVersion(iterations, kdfIterations, 0);
  6868. totalSz += kdfIterationsSz;
  6869. /* set KDF params SEQ */
  6870. kdfParamsSeqSz = SetSequence(kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6871. kdfParamsSeq);
  6872. totalSz += kdfParamsSeqSz;
  6873. /* set KDF algo OID */
  6874. ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId));
  6875. if (ret <= 0) {
  6876. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6877. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6878. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6879. return ret;
  6880. }
  6881. kdfAlgoIdSz = ret;
  6882. totalSz += kdfAlgoIdSz;
  6883. /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */
  6884. kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz +
  6885. kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6886. kdfAlgoIdSeq);
  6887. totalSz += kdfAlgoIdSeqSz;
  6888. /* set PasswordRecipientInfo CMSVersion, MUST be 0 */
  6889. verSz = SetMyVersion(0, ver, 0);
  6890. totalSz += verSz;
  6891. recip->recipVersion = 0;
  6892. /* set PasswordRecipientInfo SEQ */
  6893. recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq);
  6894. totalSz += recipSeqSz;
  6895. if (totalSz > MAX_RECIP_SZ) {
  6896. WOLFSSL_MSG("CMS Recipient output buffer too small");
  6897. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6898. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6899. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6900. return BUFFER_E;
  6901. }
  6902. idx = 0;
  6903. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6904. idx += recipSeqSz;
  6905. XMEMCPY(recip->recip + idx, ver, verSz);
  6906. idx += verSz;
  6907. XMEMCPY(recip->recip + idx, kdfAlgoIdSeq, kdfAlgoIdSeqSz);
  6908. idx += kdfAlgoIdSeqSz;
  6909. XMEMCPY(recip->recip + idx, kdfAlgoId, kdfAlgoIdSz);
  6910. idx += kdfAlgoIdSz;
  6911. XMEMCPY(recip->recip + idx, kdfParamsSeq, kdfParamsSeqSz);
  6912. idx += kdfParamsSeqSz;
  6913. XMEMCPY(recip->recip + idx, kdfSaltOctetStr, kdfSaltOctetStrSz);
  6914. idx += kdfSaltOctetStrSz;
  6915. XMEMCPY(recip->recip + idx, salt, saltSz);
  6916. idx += saltSz;
  6917. XMEMCPY(recip->recip + idx, kdfIterations, kdfIterationsSz);
  6918. idx += kdfIterationsSz;
  6919. XMEMCPY(recip->recip + idx, keyEncAlgoIdSeq, keyEncAlgoIdSeqSz);
  6920. idx += keyEncAlgoIdSeqSz;
  6921. XMEMCPY(recip->recip + idx, keyEncAlgoId, keyEncAlgoIdSz);
  6922. idx += keyEncAlgoIdSz;
  6923. XMEMCPY(recip->recip + idx, pwriEncAlgoId, pwriEncAlgoIdSz);
  6924. idx += pwriEncAlgoIdSz;
  6925. XMEMCPY(recip->recip + idx, ivOctetString, ivOctetStringSz);
  6926. idx += ivOctetStringSz;
  6927. XMEMCPY(recip->recip + idx, tmpIv, kekBlockSz);
  6928. idx += kekBlockSz;
  6929. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  6930. idx += encKeyOctetStrSz;
  6931. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  6932. idx += encryptedKeySz;
  6933. ForceZero(kek, kekBlockSz);
  6934. ForceZero(encryptedKey, encryptedKeySz);
  6935. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6936. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6937. /* store recipient size */
  6938. recip->recipSz = idx;
  6939. recip->recipType = PKCS7_PWRI;
  6940. /* add recipient to recip list */
  6941. if (pkcs7->recipList == NULL) {
  6942. pkcs7->recipList = recip;
  6943. } else {
  6944. lastRecip = pkcs7->recipList;
  6945. while (lastRecip->next != NULL) {
  6946. lastRecip = lastRecip->next;
  6947. }
  6948. lastRecip->next = recip;
  6949. }
  6950. (void)options;
  6951. return idx;
  6952. }
  6953. /* Import password and KDF settings into a PKCS7 structure. Used for setting
  6954. * the password info for decryption a EnvelopedData PWRI RecipientInfo.
  6955. *
  6956. * Returns 0 on success, negative upon error */
  6957. int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen)
  6958. {
  6959. if (pkcs7 == NULL || passwd == NULL || pLen == 0)
  6960. return BAD_FUNC_ARG;
  6961. pkcs7->pass = passwd;
  6962. pkcs7->passSz = pLen;
  6963. return 0;
  6964. }
  6965. #endif /* NO_PWDBASED */
  6966. /* Encode and add CMS EnvelopedData KEKRI (KEKRecipientInfo) RecipientInfo
  6967. * to CMS/PKCS#7 EnvelopedData structure.
  6968. *
  6969. * pkcs7 - pointer to initialized PKCS7 structure
  6970. * keyWrapOID - OID sum of key wrap algorithm identifier
  6971. * kek - key encryption key
  6972. * kekSz - size of kek, bytes
  6973. * keyID - key-encryption key identifier, pre-distributed to endpoints
  6974. * keyIDSz - size of keyID, bytes
  6975. * timePtr - pointer to "time_t", which is typically "long" (OPTIONAL)
  6976. * otherOID - ASN.1 encoded OID of other attribute (OPTIONAL)
  6977. * otherOIDSz - size of otherOID, bytes (OPTIONAL)
  6978. * other - other attribute (OPTIONAL)
  6979. * otherSz - size of other (OPTIONAL)
  6980. *
  6981. * Returns 0 on success, negative upon error */
  6982. int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek,
  6983. word32 kekSz, byte* keyId, word32 keyIdSz,
  6984. void* timePtr, byte* otherOID,
  6985. word32 otherOIDSz, byte* other, word32 otherSz,
  6986. int options)
  6987. {
  6988. Pkcs7EncodedRecip* recip = NULL;
  6989. Pkcs7EncodedRecip* lastRecip = NULL;
  6990. byte recipSeq[MAX_SEQ_SZ];
  6991. byte ver[MAX_VERSION_SZ];
  6992. byte kekIdSeq[MAX_SEQ_SZ];
  6993. byte kekIdOctetStr[MAX_OCTET_STR_SZ];
  6994. byte genTime[ASN_GENERALIZED_TIME_SIZE];
  6995. byte otherAttSeq[MAX_SEQ_SZ];
  6996. byte encAlgoId[MAX_ALGO_SZ];
  6997. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6998. #ifdef WOLFSSL_SMALL_STACK
  6999. byte* encryptedKey;
  7000. #else
  7001. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  7002. #endif
  7003. int blockKeySz = 0, ret = 0, direction;
  7004. word32 idx = 0;
  7005. word32 totalSz = 0;
  7006. word32 recipSeqSz = 0, verSz = 0;
  7007. word32 kekIdSeqSz = 0, kekIdOctetStrSz = 0;
  7008. word32 otherAttSeqSz = 0, encAlgoIdSz = 0, encKeyOctetStrSz = 0;
  7009. int encryptedKeySz;
  7010. int timeSz = 0;
  7011. #ifndef NO_ASN_TIME
  7012. time_t* tm = NULL;
  7013. #endif
  7014. if (pkcs7 == NULL || kek == NULL || keyId == NULL)
  7015. return BAD_FUNC_ARG;
  7016. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  7017. DYNAMIC_TYPE_PKCS7);
  7018. if (recip == NULL)
  7019. return MEMORY_E;
  7020. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  7021. /* get key size for content-encryption key based on algorithm */
  7022. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  7023. if (blockKeySz < 0) {
  7024. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7025. return blockKeySz;
  7026. }
  7027. /* generate random content encryption key, if needed */
  7028. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  7029. if (ret < 0) {
  7030. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7031. return ret;
  7032. }
  7033. /* EncryptedKey */
  7034. #ifdef WOLFSSL_SMALL_STACK
  7035. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  7036. DYNAMIC_TYPE_PKCS7);
  7037. if (encryptedKey == NULL) {
  7038. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7039. return MEMORY_E;
  7040. }
  7041. #endif
  7042. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  7043. XMEMSET(encryptedKey, 0, encryptedKeySz);
  7044. #ifndef NO_AES
  7045. direction = AES_ENCRYPTION;
  7046. #else
  7047. direction = DES_ENCRYPTION;
  7048. #endif
  7049. encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz,
  7050. encryptedKey, encryptedKeySz, keyWrapOID,
  7051. direction);
  7052. if (encryptedKeySz < 0) {
  7053. #ifdef WOLFSSL_SMALL_STACK
  7054. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7055. #endif
  7056. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7057. return encryptedKeySz;
  7058. }
  7059. /* handle a zero size encKey case as WC_KEY_SIZE_E */
  7060. if (encryptedKeySz == 0 || encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  7061. #ifdef WOLFSSL_SMALL_STACK
  7062. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7063. #endif
  7064. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7065. return WC_KEY_SIZE_E;
  7066. }
  7067. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  7068. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  7069. /* KeyEncryptionAlgorithmIdentifier */
  7070. encAlgoIdSz = SetAlgoID(keyWrapOID, encAlgoId, oidKeyWrapType, 0);
  7071. totalSz += encAlgoIdSz;
  7072. /* KEKIdentifier: keyIdentifier */
  7073. kekIdOctetStrSz = SetOctetString(keyIdSz, kekIdOctetStr);
  7074. totalSz += (kekIdOctetStrSz + keyIdSz);
  7075. /* KEKIdentifier: GeneralizedTime (OPTIONAL) */
  7076. #ifndef NO_ASN_TIME
  7077. if (timePtr != NULL) {
  7078. tm = (time_t*)timePtr;
  7079. timeSz = GetAsnTimeString(tm, genTime, sizeof(genTime));
  7080. if (timeSz < 0) {
  7081. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7082. #ifdef WOLFSSL_SMALL_STACK
  7083. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7084. #endif
  7085. return timeSz;
  7086. }
  7087. totalSz += timeSz;
  7088. }
  7089. #endif
  7090. /* KEKIdentifier: OtherKeyAttribute SEQ (OPTIONAL) */
  7091. if (other != NULL && otherSz > 0) {
  7092. otherAttSeqSz = SetSequence(otherOIDSz + otherSz, otherAttSeq);
  7093. totalSz += otherAttSeqSz + otherOIDSz + otherSz;
  7094. }
  7095. /* KEKIdentifier SEQ */
  7096. kekIdSeqSz = SetSequence(kekIdOctetStrSz + keyIdSz + timeSz +
  7097. otherAttSeqSz + otherOIDSz + otherSz, kekIdSeq);
  7098. totalSz += kekIdSeqSz;
  7099. /* version */
  7100. verSz = SetMyVersion(4, ver, 0);
  7101. totalSz += verSz;
  7102. recip->recipVersion = 4;
  7103. /* KEKRecipientInfo SEQ */
  7104. recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq);
  7105. totalSz += recipSeqSz;
  7106. if (totalSz > MAX_RECIP_SZ) {
  7107. WOLFSSL_MSG("CMS Recipient output buffer too small");
  7108. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7109. #ifdef WOLFSSL_SMALL_STACK
  7110. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7111. #endif
  7112. return BUFFER_E;
  7113. }
  7114. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  7115. idx += recipSeqSz;
  7116. XMEMCPY(recip->recip + idx, ver, verSz);
  7117. idx += verSz;
  7118. XMEMCPY(recip->recip + idx, kekIdSeq, kekIdSeqSz);
  7119. idx += kekIdSeqSz;
  7120. XMEMCPY(recip->recip + idx, kekIdOctetStr, kekIdOctetStrSz);
  7121. idx += kekIdOctetStrSz;
  7122. XMEMCPY(recip->recip + idx, keyId, keyIdSz);
  7123. idx += keyIdSz;
  7124. if (timePtr != NULL) {
  7125. XMEMCPY(recip->recip + idx, genTime, timeSz);
  7126. idx += timeSz;
  7127. }
  7128. if (other != NULL && otherSz > 0) {
  7129. XMEMCPY(recip->recip + idx, otherAttSeq, otherAttSeqSz);
  7130. idx += otherAttSeqSz;
  7131. XMEMCPY(recip->recip + idx, otherOID, otherOIDSz);
  7132. idx += otherOIDSz;
  7133. XMEMCPY(recip->recip + idx, other, otherSz);
  7134. idx += otherSz;
  7135. }
  7136. XMEMCPY(recip->recip + idx, encAlgoId, encAlgoIdSz);
  7137. idx += encAlgoIdSz;
  7138. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  7139. idx += encKeyOctetStrSz;
  7140. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  7141. idx += encryptedKeySz;
  7142. #ifdef WOLFSSL_SMALL_STACK
  7143. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7144. #endif
  7145. /* store recipient size */
  7146. recip->recipSz = idx;
  7147. recip->recipType = PKCS7_KEKRI;
  7148. /* add recipient to recip list */
  7149. if (pkcs7->recipList == NULL) {
  7150. pkcs7->recipList = recip;
  7151. } else {
  7152. lastRecip = pkcs7->recipList;
  7153. while(lastRecip->next != NULL) {
  7154. lastRecip = lastRecip->next;
  7155. }
  7156. lastRecip->next = recip;
  7157. }
  7158. (void)options;
  7159. return idx;
  7160. }
  7161. static int wc_PKCS7_GetCMSVersion(PKCS7* pkcs7, int cmsContentType)
  7162. {
  7163. int version = -1;
  7164. if (pkcs7 == NULL)
  7165. return BAD_FUNC_ARG;
  7166. switch (cmsContentType) {
  7167. case ENVELOPED_DATA:
  7168. /* NOTE: EnvelopedData does not currently support
  7169. originatorInfo or unprotectedAttributes. When either of these
  7170. are added, version checking below needs to be updated to match
  7171. Section 6.1 of RFC 5652 */
  7172. /* if RecipientInfos include pwri or ori, version is 3 */
  7173. if (wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_PWRI) ||
  7174. wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_ORI)) {
  7175. version = 3;
  7176. break;
  7177. }
  7178. /* if unprotectedAttrs is absent AND all RecipientInfo structs
  7179. are version 0, version is 0 */
  7180. if (wc_PKCS7_RecipientListVersionsAllZero(pkcs7)) {
  7181. version = 0;
  7182. break;
  7183. }
  7184. /* otherwise, version is 2 */
  7185. version = 2;
  7186. break;
  7187. default:
  7188. break;
  7189. }
  7190. return version;
  7191. }
  7192. /* build PKCS#7 envelopedData content type, return enveloped size */
  7193. int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  7194. {
  7195. int ret, idx = 0;
  7196. int totalSz, padSz, encryptedOutSz;
  7197. int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz;
  7198. byte contentInfoSeq[MAX_SEQ_SZ];
  7199. byte outerContentType[MAX_ALGO_SZ];
  7200. byte outerContent[MAX_SEQ_SZ];
  7201. int kariVersion;
  7202. int envDataSeqSz, verSz;
  7203. byte envDataSeq[MAX_SEQ_SZ];
  7204. byte ver[MAX_VERSION_SZ];
  7205. WC_RNG rng;
  7206. int blockSz, blockKeySz;
  7207. byte* plain;
  7208. byte* encryptedContent;
  7209. Pkcs7EncodedRecip* tmpRecip = NULL;
  7210. int recipSz, recipSetSz;
  7211. byte recipSet[MAX_SET_SZ];
  7212. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  7213. int contentEncAlgoSz, ivOctetStringSz;
  7214. byte encContentSeq[MAX_SEQ_SZ];
  7215. byte contentType[MAX_ALGO_SZ];
  7216. byte contentEncAlgo[MAX_ALGO_SZ];
  7217. byte tmpIv[MAX_CONTENT_IV_SIZE];
  7218. byte ivOctetString[MAX_OCTET_STR_SZ];
  7219. byte encContentOctet[MAX_OCTET_STR_SZ];
  7220. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  7221. return BAD_FUNC_ARG;
  7222. if (output == NULL || outputSz == 0)
  7223. return BAD_FUNC_ARG;
  7224. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  7225. if (blockKeySz < 0)
  7226. return blockKeySz;
  7227. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  7228. if (blockSz < 0)
  7229. return blockSz;
  7230. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7231. /* outer content type */
  7232. ret = wc_SetContentType(ENVELOPED_DATA, outerContentType,
  7233. sizeof(outerContentType));
  7234. if (ret < 0)
  7235. return ret;
  7236. outerContentTypeSz = ret;
  7237. }
  7238. /* generate random content encryption key */
  7239. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  7240. if (ret != 0) {
  7241. return ret;
  7242. }
  7243. /* build RecipientInfo, only if user manually set singleCert and size */
  7244. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  7245. switch (pkcs7->publicKeyOID) {
  7246. #ifndef NO_RSA
  7247. case RSAk:
  7248. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  7249. pkcs7->singleCertSz, 0);
  7250. break;
  7251. #endif
  7252. #ifdef HAVE_ECC
  7253. case ECDSAk:
  7254. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  7255. pkcs7->singleCertSz,
  7256. pkcs7->keyWrapOID,
  7257. pkcs7->keyAgreeOID, pkcs7->ukm,
  7258. pkcs7->ukmSz, 0);
  7259. break;
  7260. #endif
  7261. default:
  7262. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  7263. return BAD_FUNC_ARG;
  7264. };
  7265. if (ret < 0) {
  7266. WOLFSSL_MSG("Failed to create RecipientInfo");
  7267. return ret;
  7268. }
  7269. }
  7270. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  7271. if (recipSz < 0) {
  7272. return ret;
  7273. } else if (recipSz == 0) {
  7274. WOLFSSL_MSG("You must add at least one CMS recipient");
  7275. return PKCS7_RECIP_E;
  7276. }
  7277. recipSetSz = SetSet(recipSz, recipSet);
  7278. /* version, defined in Section 6.1 of RFC 5652 */
  7279. kariVersion = wc_PKCS7_GetCMSVersion(pkcs7, ENVELOPED_DATA);
  7280. if (kariVersion < 0) {
  7281. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7282. WOLFSSL_MSG("Failed to set CMS EnvelopedData version");
  7283. return PKCS7_RECIP_E;
  7284. }
  7285. verSz = SetMyVersion(kariVersion, ver, 0);
  7286. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  7287. if (ret != 0) {
  7288. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7289. return ret;
  7290. }
  7291. /* generate IV for block cipher */
  7292. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, tmpIv, blockSz);
  7293. wc_FreeRng(&rng);
  7294. if (ret != 0) {
  7295. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7296. return ret;
  7297. }
  7298. /* EncryptedContentInfo */
  7299. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  7300. sizeof(contentType));
  7301. if (ret < 0) {
  7302. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7303. return ret;
  7304. }
  7305. contentTypeSz = ret;
  7306. /* allocate encrypted content buffer and PKCS#7 padding */
  7307. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  7308. if (padSz < 0) {
  7309. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7310. return padSz;
  7311. }
  7312. encryptedOutSz = pkcs7->contentSz + padSz;
  7313. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7314. if (plain == NULL) {
  7315. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7316. return MEMORY_E;
  7317. }
  7318. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  7319. encryptedOutSz, blockSz);
  7320. if (ret < 0) {
  7321. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7322. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7323. return ret;
  7324. }
  7325. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  7326. DYNAMIC_TYPE_PKCS7);
  7327. if (encryptedContent == NULL) {
  7328. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7329. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7330. return MEMORY_E;
  7331. }
  7332. /* put together IV OCTET STRING */
  7333. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  7334. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  7335. * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  7336. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  7337. oidBlkType, ivOctetStringSz + blockSz);
  7338. if (contentEncAlgoSz == 0) {
  7339. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7340. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7341. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7342. return BAD_FUNC_ARG;
  7343. }
  7344. /* encrypt content */
  7345. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  7346. pkcs7->cekSz, tmpIv, blockSz, NULL, 0, NULL, 0, plain,
  7347. encryptedOutSz, encryptedContent,
  7348. pkcs7->devId, pkcs7->heap);
  7349. if (ret != 0) {
  7350. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7351. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7352. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7353. return ret;
  7354. }
  7355. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  7356. encContentOctet);
  7357. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  7358. ivOctetStringSz + blockSz +
  7359. encContentOctetSz + encryptedOutSz,
  7360. encContentSeq);
  7361. /* keep track of sizes for outer wrapper layering */
  7362. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  7363. contentEncAlgoSz + ivOctetStringSz + blockSz +
  7364. encContentOctetSz + encryptedOutSz;
  7365. /* EnvelopedData */
  7366. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  7367. totalSz += envDataSeqSz;
  7368. /* outer content */
  7369. outerContentSz = SetExplicit(0, totalSz, outerContent);
  7370. totalSz += outerContentTypeSz;
  7371. totalSz += outerContentSz;
  7372. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7373. /* ContentInfo */
  7374. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  7375. totalSz += contentInfoSeqSz;
  7376. }
  7377. if (totalSz > (int)outputSz) {
  7378. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  7379. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7380. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7381. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7382. return BUFFER_E;
  7383. }
  7384. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7385. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  7386. idx += contentInfoSeqSz;
  7387. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  7388. idx += outerContentTypeSz;
  7389. XMEMCPY(output + idx, outerContent, outerContentSz);
  7390. idx += outerContentSz;
  7391. }
  7392. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  7393. idx += envDataSeqSz;
  7394. XMEMCPY(output + idx, ver, verSz);
  7395. idx += verSz;
  7396. XMEMCPY(output + idx, recipSet, recipSetSz);
  7397. idx += recipSetSz;
  7398. /* copy in recipients from list */
  7399. tmpRecip = pkcs7->recipList;
  7400. while (tmpRecip != NULL) {
  7401. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  7402. idx += tmpRecip->recipSz;
  7403. tmpRecip = tmpRecip->next;
  7404. }
  7405. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7406. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  7407. idx += encContentSeqSz;
  7408. XMEMCPY(output + idx, contentType, contentTypeSz);
  7409. idx += contentTypeSz;
  7410. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  7411. idx += contentEncAlgoSz;
  7412. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  7413. idx += ivOctetStringSz;
  7414. XMEMCPY(output + idx, tmpIv, blockSz);
  7415. idx += blockSz;
  7416. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  7417. idx += encContentOctetSz;
  7418. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  7419. idx += encryptedOutSz;
  7420. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7421. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7422. return idx;
  7423. }
  7424. #ifndef NO_RSA
  7425. /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */
  7426. static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
  7427. word32* idx, byte* decryptedKey,
  7428. word32* decryptedKeySz, int* recipFound)
  7429. {
  7430. int length, encryptedKeySz = 0, ret = 0;
  7431. int keySz, version, sidType = 0;
  7432. int keyIdSize;
  7433. word32 encOID = 0;
  7434. word32 keyIdx;
  7435. byte issuerHash[KEYID_SIZE];
  7436. byte* outKey = NULL;
  7437. byte* pkiMsg = in;
  7438. word32 pkiMsgSz = inSz;
  7439. byte tag;
  7440. #ifndef NO_PKCS7_STREAM
  7441. word32 tmpIdx = *idx;
  7442. #endif
  7443. #ifdef WC_RSA_BLINDING
  7444. WC_RNG rng;
  7445. #endif
  7446. byte* encryptedKey = NULL;
  7447. #ifdef WOLFSSL_SMALL_STACK
  7448. mp_int* serialNum = NULL;
  7449. RsaKey* privKey = NULL;
  7450. #else
  7451. mp_int serialNum[1];
  7452. RsaKey privKey[1];
  7453. #endif
  7454. XMEMSET(issuerHash, 0, sizeof(issuerHash));
  7455. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  7456. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  7457. pkcs7->publicKeyOID)));
  7458. #else
  7459. keyIdSize = KEYID_SIZE;
  7460. #endif
  7461. switch (pkcs7->state) {
  7462. case WC_PKCS7_DECRYPT_KTRI:
  7463. #ifndef NO_PKCS7_STREAM
  7464. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_VERSION_SZ,
  7465. &pkiMsg, idx)) != 0) {
  7466. return ret;
  7467. }
  7468. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  7469. #endif
  7470. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  7471. return ASN_PARSE_E;
  7472. if (version == 0) {
  7473. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  7474. } else if (version == 2) {
  7475. sidType = CMS_SKID;
  7476. } else {
  7477. return ASN_VERSION_E;
  7478. }
  7479. #ifndef NO_PKCS7_STREAM
  7480. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7481. break;
  7482. }
  7483. wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version);
  7484. /* @TODO getting total amount left because of GetInt call later on
  7485. * this could be optimized to stream better */
  7486. if (pkcs7->stream->totalRd > pkcs7->stream->maxLen) {
  7487. WOLFSSL_MSG("PKCS7 read more than expected");
  7488. ret = BUFFER_E;
  7489. break;
  7490. }
  7491. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  7492. pkcs7->stream->totalRd) + pkcs7->stream->length;
  7493. #endif
  7494. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2);
  7495. FALL_THROUGH;
  7496. case WC_PKCS7_DECRYPT_KTRI_2:
  7497. #ifndef NO_PKCS7_STREAM
  7498. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7499. pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
  7500. return ret;
  7501. }
  7502. if (in != pkiMsg) {
  7503. pkiMsgSz = pkcs7->stream->length;
  7504. }
  7505. wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version);
  7506. /* @TODO get expected size for next part, does not account for
  7507. * GetInt call well */
  7508. if (pkcs7->stream->expected == MAX_SEQ_SZ) {
  7509. int sz;
  7510. word32 lidx;
  7511. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  7512. lidx = *idx;
  7513. ret = GetSequence(pkiMsg, &lidx, &sz, pkiMsgSz);
  7514. if (ret < 0)
  7515. return ret;
  7516. }
  7517. else {
  7518. lidx = *idx + ASN_TAG_SZ;
  7519. ret = GetLength(pkiMsg, &lidx, &sz, pkiMsgSz);
  7520. if (ret < 0)
  7521. return ret;
  7522. }
  7523. pkcs7->stream->expected = sz + MAX_ALGO_SZ + ASN_TAG_SZ +
  7524. MAX_LENGTH_SZ;
  7525. if (pkcs7->stream->length > 0 &&
  7526. pkcs7->stream->length < pkcs7->stream->expected) {
  7527. return WC_PKCS7_WANT_READ_E;
  7528. }
  7529. }
  7530. #endif /* !NO_PKCS7_STREAM */
  7531. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  7532. /* remove IssuerAndSerialNumber */
  7533. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7534. return ASN_PARSE_E;
  7535. if (GetNameHash_ex(pkiMsg, idx, issuerHash, pkiMsgSz,
  7536. pkcs7->publicKeyOID) < 0)
  7537. return ASN_PARSE_E;
  7538. /* if we found correct recipient, issuer hashes will match */
  7539. if (XMEMCMP(issuerHash, pkcs7->issuerHash, keyIdSize) == 0) {
  7540. *recipFound = 1;
  7541. }
  7542. #ifdef WOLFSSL_SMALL_STACK
  7543. serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,
  7544. DYNAMIC_TYPE_TMP_BUFFER);
  7545. if (serialNum == NULL)
  7546. return MEMORY_E;
  7547. #endif
  7548. if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {
  7549. #ifdef WOLFSSL_SMALL_STACK
  7550. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7551. #endif
  7552. return ASN_PARSE_E;
  7553. }
  7554. mp_clear(serialNum);
  7555. #ifdef WOLFSSL_SMALL_STACK
  7556. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7557. #endif
  7558. } else {
  7559. /* parse SubjectKeyIdentifier
  7560. * RFC 5652 lists SubjectKeyIdentifier as [0] followed by
  7561. * simple type of octet string
  7562. *
  7563. * RecipientIdentifier ::= CHOICE {
  7564. * issuerAndSerialNumber IssuerAndSerialNumber,
  7565. * subjectKeyIdentifier [0] SubjectKeyIdentifier }
  7566. *
  7567. * The choice of subjectKeyIdentifier (where version was 2) is
  7568. * context specific with tag number 0 within the class.
  7569. */
  7570. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7571. return ASN_PARSE_E;
  7572. /* should be context specific and tag number 0: [0] (0x80) */
  7573. if (tag != ASN_CONTEXT_SPECIFIC) {
  7574. return ASN_PARSE_E;
  7575. }
  7576. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7577. return ASN_PARSE_E;
  7578. if ((word32)keyIdSize > pkiMsgSz - (*idx))
  7579. return BUFFER_E;
  7580. /* if we found correct recipient, SKID will match */
  7581. if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId,
  7582. keyIdSize) == 0) {
  7583. *recipFound = 1;
  7584. }
  7585. (*idx) += keyIdSize;
  7586. }
  7587. if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)
  7588. return ASN_PARSE_E;
  7589. /* key encryption algorithm must be RSA for now */
  7590. if (encOID != RSAk
  7591. #ifndef WC_NO_RSA_OAEP
  7592. && encOID != RSAESOAEPk
  7593. #endif
  7594. )
  7595. return ALGO_ID_E;
  7596. #ifndef WC_NO_RSA_OAEP
  7597. if (encOID == RSAESOAEPk) {
  7598. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7599. return ASN_PARSE_E;
  7600. }
  7601. if (length > 0) {
  7602. WOLFSSL_MSG("only supported default OAEP");
  7603. WOLFSSL_ERROR(ALGO_ID_E);
  7604. return ALGO_ID_E;
  7605. }
  7606. }
  7607. #endif
  7608. /* read encryptedKey */
  7609. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7610. return ASN_PARSE_E;
  7611. if (tag != ASN_OCTET_STRING)
  7612. return ASN_PARSE_E;
  7613. if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
  7614. return ASN_PARSE_E;
  7615. }
  7616. if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  7617. return BUFFER_E;
  7618. }
  7619. #ifndef NO_PKCS7_STREAM
  7620. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7621. break;
  7622. }
  7623. wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version);
  7624. pkcs7->stream->expected = encryptedKeySz;
  7625. #endif
  7626. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3);
  7627. FALL_THROUGH;
  7628. case WC_PKCS7_DECRYPT_KTRI_3:
  7629. #ifndef NO_PKCS7_STREAM
  7630. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7631. pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
  7632. return ret;
  7633. }
  7634. encryptedKeySz = pkcs7->stream->expected;
  7635. #endif
  7636. /* Always allocate to ensure aligned use with RSA */
  7637. encryptedKey = (byte*)XMALLOC(encryptedKeySz, pkcs7->heap,
  7638. DYNAMIC_TYPE_WOLF_BIGINT);
  7639. if (encryptedKey == NULL)
  7640. return MEMORY_E;
  7641. if (*recipFound == 1)
  7642. XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);
  7643. *idx += encryptedKeySz;
  7644. /* load private key */
  7645. #ifdef WOLFSSL_SMALL_STACK
  7646. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  7647. DYNAMIC_TYPE_TMP_BUFFER);
  7648. if (privKey == NULL) {
  7649. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7650. return MEMORY_E;
  7651. }
  7652. #endif
  7653. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
  7654. if (ret != 0) {
  7655. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7656. #ifdef WOLFSSL_SMALL_STACK
  7657. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7658. #endif
  7659. return ret;
  7660. }
  7661. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  7662. keyIdx = 0;
  7663. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx,
  7664. privKey, pkcs7->privateKeySz);
  7665. }
  7666. else if (pkcs7->devId == INVALID_DEVID) {
  7667. ret = BAD_FUNC_ARG;
  7668. }
  7669. if (ret != 0) {
  7670. WOLFSSL_MSG("Failed to decode RSA private key");
  7671. wc_FreeRsaKey(privKey);
  7672. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7673. #ifdef WOLFSSL_SMALL_STACK
  7674. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7675. #endif
  7676. return ret;
  7677. }
  7678. /* decrypt encryptedKey */
  7679. #ifdef WC_RSA_BLINDING
  7680. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  7681. if (ret == 0) {
  7682. ret = wc_RsaSetRNG(privKey, &rng);
  7683. }
  7684. #endif
  7685. if (ret == 0) {
  7686. #ifdef WOLFSSL_ASYNC_CRYPT
  7687. /* Currently the call to RSA decrypt here is blocking @TODO */
  7688. keySz = 0; /* set initial "ret" value to 0 */
  7689. do {
  7690. keySz = wc_AsyncWait(keySz, &privKey->asyncDev,
  7691. WC_ASYNC_FLAG_CALL_AGAIN);
  7692. if (keySz >= 0)
  7693. #endif
  7694. {
  7695. #ifndef WC_NO_RSA_OAEP
  7696. if (encOID != RSAESOAEPk) {
  7697. #endif
  7698. keySz = wc_RsaPrivateDecryptInline(encryptedKey,
  7699. encryptedKeySz, &outKey,
  7700. privKey);
  7701. #ifndef WC_NO_RSA_OAEP
  7702. }
  7703. else {
  7704. word32 outLen = wc_RsaEncryptSize(privKey);
  7705. outKey = (byte*)XMALLOC(outLen, pkcs7->heap,
  7706. DYNAMIC_TYPE_TMP_BUFFER);
  7707. if (!outKey) {
  7708. WOLFSSL_MSG("Failed to allocate out key buffer");
  7709. wc_FreeRsaKey(privKey);
  7710. XFREE(encryptedKey, pkcs7->heap,
  7711. DYNAMIC_TYPE_WOLF_BIGINT);
  7712. #ifdef WOLFSSL_SMALL_STACK
  7713. XFREE(privKey, pkcs7->heap,
  7714. DYNAMIC_TYPE_TMP_BUFFER);
  7715. #endif
  7716. WOLFSSL_ERROR_VERBOSE(MEMORY_E);
  7717. return MEMORY_E;
  7718. }
  7719. keySz = wc_RsaPrivateDecrypt_ex(encryptedKey,
  7720. encryptedKeySz, outKey, outLen, privKey,
  7721. WC_RSA_OAEP_PAD,
  7722. WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0);
  7723. }
  7724. #endif
  7725. }
  7726. #ifdef WOLFSSL_ASYNC_CRYPT
  7727. } while (keySz == WC_PENDING_E);
  7728. #endif
  7729. #ifdef WC_RSA_BLINDING
  7730. wc_FreeRng(&rng);
  7731. #endif
  7732. } else {
  7733. keySz = ret;
  7734. }
  7735. wc_FreeRsaKey(privKey);
  7736. if (keySz <= 0 || outKey == NULL) {
  7737. ForceZero(encryptedKey, encryptedKeySz);
  7738. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7739. #ifdef WOLFSSL_SMALL_STACK
  7740. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7741. #endif
  7742. #ifndef WC_NO_RSA_OAEP
  7743. if (encOID == RSAESOAEPk) {
  7744. if (!outKey) {
  7745. XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7746. }
  7747. }
  7748. #endif
  7749. return keySz;
  7750. } else {
  7751. *decryptedKeySz = keySz;
  7752. XMEMCPY(decryptedKey, outKey, keySz);
  7753. ForceZero(encryptedKey, encryptedKeySz);
  7754. }
  7755. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7756. #ifdef WOLFSSL_SMALL_STACK
  7757. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7758. #endif
  7759. #ifndef WC_NO_RSA_OAEP
  7760. if (encOID == RSAESOAEPk) {
  7761. if (!outKey) {
  7762. XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7763. }
  7764. }
  7765. #endif
  7766. #ifndef NO_PKCS7_STREAM
  7767. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7768. break;
  7769. }
  7770. #endif
  7771. ret = 0; /* success */
  7772. break;
  7773. default:
  7774. WOLFSSL_MSG("PKCS7 Unknown KTRI decrypt state");
  7775. ret = BAD_FUNC_ARG;
  7776. }
  7777. return ret;
  7778. }
  7779. #endif /* !NO_RSA */
  7780. #ifdef HAVE_ECC
  7781. /* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */
  7782. static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
  7783. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7784. {
  7785. int ret, length;
  7786. word32 keyOID, oidSum = 0;
  7787. int curve_id = ECC_CURVE_DEF;
  7788. byte tag;
  7789. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7790. return BAD_FUNC_ARG;
  7791. /* remove OriginatorIdentifierOrKey */
  7792. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7793. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7794. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7795. return ASN_PARSE_E;
  7796. } else {
  7797. return ASN_PARSE_E;
  7798. }
  7799. /* remove OriginatorPublicKey */
  7800. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7801. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7802. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7803. return ASN_PARSE_E;
  7804. } else {
  7805. return ASN_PARSE_E;
  7806. }
  7807. /* remove AlgorithmIdentifier */
  7808. if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)
  7809. return ASN_PARSE_E;
  7810. if (keyOID != ECDSAk)
  7811. return ASN_PARSE_E;
  7812. /* optional algorithm parameters */
  7813. ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);
  7814. if (ret == 0) {
  7815. /* get curve id */
  7816. curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
  7817. if (curve_id < 0)
  7818. return ECC_CURVE_OID_E;
  7819. }
  7820. /* remove ECPoint BIT STRING */
  7821. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7822. return ASN_PARSE_E;
  7823. if (tag != ASN_BIT_STRING)
  7824. return ASN_PARSE_E;
  7825. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7826. return ASN_PARSE_E;
  7827. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7828. return ASN_EXPECT_0_E;
  7829. if (tag != ASN_OTHER_TYPE)
  7830. return ASN_EXPECT_0_E;
  7831. /* get sender ephemeral public ECDSA key */
  7832. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  7833. if (ret != 0)
  7834. return ret;
  7835. kari->senderKeyInit = 1;
  7836. /* length-1 for unused bits counter */
  7837. ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,
  7838. curve_id);
  7839. if (ret != 0) {
  7840. ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
  7841. if (ret != 0)
  7842. return ret;
  7843. }
  7844. else {
  7845. (*idx) += length - 1;
  7846. }
  7847. return 0;
  7848. }
  7849. /* remove optional UserKeyingMaterial if available, return 0 on success,
  7850. * < 0 on error */
  7851. static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
  7852. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7853. {
  7854. int length;
  7855. word32 savedIdx;
  7856. byte tag;
  7857. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7858. return BAD_FUNC_ARG;
  7859. savedIdx = *idx;
  7860. /* starts with EXPLICIT [1] */
  7861. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7862. *idx = savedIdx;
  7863. return 0;
  7864. }
  7865. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7866. *idx = savedIdx;
  7867. return 0;
  7868. }
  7869. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7870. *idx = savedIdx;
  7871. return 0;
  7872. }
  7873. /* get OCTET STRING */
  7874. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7875. *idx = savedIdx;
  7876. return 0;
  7877. }
  7878. if (tag != ASN_OCTET_STRING) {
  7879. *idx = savedIdx;
  7880. return 0;
  7881. }
  7882. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7883. *idx = savedIdx;
  7884. return 0;
  7885. }
  7886. kari->ukm = NULL;
  7887. if (length > 0) {
  7888. kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
  7889. if (kari->ukm == NULL)
  7890. return MEMORY_E;
  7891. XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
  7892. kari->ukmOwner = 1;
  7893. }
  7894. (*idx) += length;
  7895. kari->ukmSz = length;
  7896. return 0;
  7897. }
  7898. /* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,
  7899. * < 0 on error */
  7900. static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
  7901. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7902. word32* keyAgreeOID, word32* keyWrapOID)
  7903. {
  7904. int length = 0;
  7905. word32 localIdx;
  7906. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  7907. keyAgreeOID == NULL || keyWrapOID == NULL)
  7908. return BAD_FUNC_ARG;
  7909. localIdx = *idx;
  7910. /* remove KeyEncryptionAlgorithmIdentifier */
  7911. if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  7912. return ASN_PARSE_E;
  7913. localIdx = *idx;
  7914. if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,
  7915. pkiMsgSz) < 0) {
  7916. return ASN_PARSE_E;
  7917. }
  7918. if (localIdx < *idx + length) {
  7919. *idx = localIdx;
  7920. }
  7921. /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
  7922. if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  7923. return ASN_PARSE_E;
  7924. return 0;
  7925. }
  7926. /* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
  7927. * if subject key ID matches, recipFound is set to 1 */
  7928. static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
  7929. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7930. int* recipFound, byte* rid)
  7931. {
  7932. int length;
  7933. byte tag;
  7934. int keyIdSize;
  7935. if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
  7936. rid == NULL)
  7937. return BAD_FUNC_ARG;
  7938. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  7939. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  7940. kari->decoded->signatureOID)));
  7941. #else
  7942. keyIdSize = KEYID_SIZE;
  7943. #endif
  7944. /* remove RecipientKeyIdentifier IMPLICIT [0] */
  7945. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7946. return ASN_PARSE_E;
  7947. }
  7948. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7949. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7950. return ASN_PARSE_E;
  7951. } else {
  7952. return ASN_PARSE_E;
  7953. }
  7954. /* remove SubjectKeyIdentifier */
  7955. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7956. return ASN_PARSE_E;
  7957. }
  7958. if (tag != ASN_OCTET_STRING)
  7959. return ASN_PARSE_E;
  7960. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7961. return ASN_PARSE_E;
  7962. if (length != keyIdSize)
  7963. return ASN_PARSE_E;
  7964. XMEMCPY(rid, pkiMsg + (*idx), keyIdSize);
  7965. (*idx) += length;
  7966. /* subject key id should match if recipient found */
  7967. if (XMEMCMP(rid, kari->decoded->extSubjKeyId, keyIdSize) == 0) {
  7968. *recipFound = 1;
  7969. }
  7970. return 0;
  7971. }
  7972. /* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
  7973. * if issuer and serial number match, recipFound is set to 1 */
  7974. static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
  7975. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7976. int* recipFound, byte* rid)
  7977. {
  7978. int length, ret;
  7979. int keyIdSize;
  7980. #ifdef WOLFSSL_SMALL_STACK
  7981. mp_int* serial;
  7982. mp_int* recipSerial;
  7983. #else
  7984. mp_int serial[1];
  7985. mp_int recipSerial[1];
  7986. #endif
  7987. if (rid == NULL) {
  7988. return BAD_FUNC_ARG;
  7989. }
  7990. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  7991. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  7992. kari->decoded->signatureOID)));
  7993. #else
  7994. keyIdSize = KEYID_SIZE;
  7995. #endif
  7996. /* remove IssuerAndSerialNumber */
  7997. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7998. return ASN_PARSE_E;
  7999. if (GetNameHash_ex(pkiMsg, idx, rid, pkiMsgSz,
  8000. kari->decoded->signatureOID) < 0) {
  8001. return ASN_PARSE_E;
  8002. }
  8003. /* if we found correct recipient, issuer hashes will match */
  8004. if (kari->decodedInit == 1) {
  8005. if (XMEMCMP(rid, kari->decoded->issuerHash, keyIdSize) == 0) {
  8006. *recipFound = 1;
  8007. }
  8008. }
  8009. else {
  8010. /* can not confirm recipient serial number with no cert provided */
  8011. WOLFSSL_MSG("No recipient cert loaded to match with CMS serial number");
  8012. *recipFound = 1;
  8013. }
  8014. #ifdef WOLFSSL_SMALL_STACK
  8015. serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  8016. DYNAMIC_TYPE_TMP_BUFFER);
  8017. if (serial == NULL)
  8018. return MEMORY_E;
  8019. recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  8020. DYNAMIC_TYPE_TMP_BUFFER);
  8021. if (recipSerial == NULL) {
  8022. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8023. return MEMORY_E;
  8024. }
  8025. #endif
  8026. if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
  8027. #ifdef WOLFSSL_SMALL_STACK
  8028. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8029. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8030. #endif
  8031. return ASN_PARSE_E;
  8032. }
  8033. ret = mp_init(recipSerial);
  8034. if (ret == MP_OKAY)
  8035. ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
  8036. kari->decoded->serialSz);
  8037. if (ret != MP_OKAY) {
  8038. mp_clear(serial);
  8039. WOLFSSL_MSG("Failed to parse CMS recipient serial number");
  8040. #ifdef WOLFSSL_SMALL_STACK
  8041. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8042. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8043. #endif
  8044. return ret;
  8045. }
  8046. if (kari->decodedInit == 1 &&
  8047. mp_cmp(recipSerial, serial) != MP_EQ) {
  8048. mp_clear(serial);
  8049. mp_clear(recipSerial);
  8050. WOLFSSL_MSG("CMS serial number does not match recipient");
  8051. #ifdef WOLFSSL_SMALL_STACK
  8052. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8053. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8054. #endif
  8055. return PKCS7_RECIP_E;
  8056. }
  8057. mp_clear(serial);
  8058. mp_clear(recipSerial);
  8059. #ifdef WOLFSSL_SMALL_STACK
  8060. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8061. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8062. #endif
  8063. return 0;
  8064. }
  8065. /* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
  8066. static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
  8067. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  8068. int* recipFound, byte* encryptedKey,
  8069. int* encryptedKeySz, byte* rid)
  8070. {
  8071. int length;
  8072. int ret = 0;
  8073. byte tag;
  8074. word32 localIdx;
  8075. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  8076. recipFound == NULL || encryptedKey == NULL)
  8077. return BAD_FUNC_ARG;
  8078. /* remove RecipientEncryptedKeys */
  8079. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8080. return ASN_PARSE_E;
  8081. /* remove RecipientEncryptedKeys */
  8082. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8083. return ASN_PARSE_E;
  8084. /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
  8085. * or [0] IMPLICIT RecipientKeyIdentifier */
  8086. localIdx = *idx;
  8087. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  8088. return ASN_PARSE_E;
  8089. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  8090. /* try to get RecipientKeyIdentifier */
  8091. ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
  8092. idx, recipFound, rid);
  8093. } else {
  8094. /* try to get IssuerAndSerialNumber */
  8095. ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
  8096. idx, recipFound, rid);
  8097. }
  8098. /* if we don't have either option, malformed CMS */
  8099. if (ret != 0)
  8100. return ret;
  8101. /* remove EncryptedKey */
  8102. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8103. return ASN_PARSE_E;
  8104. if (tag != ASN_OCTET_STRING)
  8105. return ASN_PARSE_E;
  8106. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8107. return ASN_PARSE_E;
  8108. /* put encrypted CEK in decryptedKey buffer for now, decrypt later */
  8109. if (length > *encryptedKeySz)
  8110. return BUFFER_E;
  8111. XMEMCPY(encryptedKey, pkiMsg + (*idx), length);
  8112. *encryptedKeySz = length;
  8113. (*idx) += length;
  8114. return 0;
  8115. }
  8116. #endif /* HAVE_ECC */
  8117. int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx)
  8118. {
  8119. if (pkcs7 == NULL)
  8120. return BAD_FUNC_ARG;
  8121. pkcs7->oriEncryptCtx = ctx;
  8122. return 0;
  8123. }
  8124. int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx)
  8125. {
  8126. if (pkcs7 == NULL)
  8127. return BAD_FUNC_ARG;
  8128. pkcs7->oriDecryptCtx = ctx;
  8129. return 0;
  8130. }
  8131. int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb)
  8132. {
  8133. if (pkcs7 == NULL)
  8134. return BAD_FUNC_ARG;
  8135. pkcs7->oriDecryptCb = cb;
  8136. return 0;
  8137. }
  8138. /* return 0 on success */
  8139. int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, CallbackWrapCEK cb)
  8140. {
  8141. if (pkcs7 == NULL)
  8142. return BAD_FUNC_ARG;
  8143. pkcs7->wrapCEKCb = cb;
  8144. return 0;
  8145. }
  8146. /* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by:
  8147. *
  8148. * OtherRecipientInfo ::= SEQUENCE {
  8149. * oriType OBJECT IDENTIFIER,
  8150. * oriValue ANY DEFINED BY oriType }
  8151. *
  8152. * pkcs7 - pointer to initialized PKCS7 structure
  8153. * pkiMsg - pointer to encoded CMS bundle
  8154. * pkiMsgSz - size of pkiMsg, bytes
  8155. * idx - [IN/OUT] pointer to index into pkiMsg
  8156. * decryptedKey - [OUT] output buf for decrypted content encryption key
  8157. * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key
  8158. * recipFound - [OUT] 1 if recipient has been found, 0 if not
  8159. *
  8160. * Return 0 on success, negative upon error.
  8161. */
  8162. static int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* in, word32 inSz,
  8163. word32* idx, byte* decryptedKey,
  8164. word32* decryptedKeySz, int* recipFound)
  8165. {
  8166. int ret, seqSz, oriOIDSz;
  8167. word32 oriValueSz, tmpIdx;
  8168. byte* oriValue;
  8169. byte oriOID[MAX_OID_SZ];
  8170. byte* pkiMsg = in;
  8171. word32 pkiMsgSz = inSz;
  8172. #ifndef NO_PKCS7_STREAM
  8173. word32 stateIdx = *idx;
  8174. #endif
  8175. if (pkcs7->oriDecryptCb == NULL) {
  8176. WOLFSSL_MSG("You must register an ORI Decrypt callback");
  8177. return BAD_FUNC_ARG;
  8178. }
  8179. switch (pkcs7->state) {
  8180. case WC_PKCS7_DECRYPT_ORI:
  8181. #ifndef NO_PKCS7_STREAM
  8182. /* @TODO for now just get full buffer, needs divided up */
  8183. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8184. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8185. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8186. return ret;
  8187. }
  8188. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8189. #endif
  8190. /* get OtherRecipientInfo sequence length */
  8191. if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0)
  8192. return ASN_PARSE_E;
  8193. tmpIdx = *idx;
  8194. /* remove and store oriType OBJECT IDENTIFIER */
  8195. if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0)
  8196. return ASN_PARSE_E;
  8197. XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz);
  8198. *idx += oriOIDSz;
  8199. /* get oriValue, increment idx */
  8200. oriValue = pkiMsg + *idx;
  8201. oriValueSz = seqSz - (*idx - tmpIdx);
  8202. *idx += oriValueSz;
  8203. /* pass oriOID and oriValue to user callback, expect back
  8204. decryptedKey and size */
  8205. ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue,
  8206. oriValueSz, decryptedKey, decryptedKeySz,
  8207. pkcs7->oriDecryptCtx);
  8208. if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) {
  8209. /* decrypt operation failed */
  8210. *recipFound = 0;
  8211. return PKCS7_RECIP_E;
  8212. }
  8213. /* mark recipFound, since we only support one RecipientInfo for now */
  8214. *recipFound = 1;
  8215. #ifndef NO_PKCS7_STREAM
  8216. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, idx)) != 0) {
  8217. break;
  8218. }
  8219. #endif
  8220. ret = 0; /* success */
  8221. break;
  8222. default:
  8223. WOLFSSL_MSG("PKCS7 ORI unknown state");
  8224. ret = BAD_FUNC_ARG;
  8225. }
  8226. return ret;
  8227. }
  8228. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8229. /* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success,
  8230. * < 0 on error */
  8231. static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
  8232. word32* idx, byte* decryptedKey,
  8233. word32* decryptedKeySz, int* recipFound)
  8234. {
  8235. byte* salt;
  8236. byte* cek;
  8237. byte* kek;
  8238. byte tmpIv[MAX_CONTENT_IV_SIZE];
  8239. int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
  8240. int hashOID = WC_SHA; /* default to SHA1 */
  8241. word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
  8242. byte* pkiMsg = in;
  8243. word32 pkiMsgSz = inSz;
  8244. byte tag;
  8245. #ifndef NO_PKCS7_STREAM
  8246. word32 tmpIdx = *idx;
  8247. #endif
  8248. switch (pkcs7->state) {
  8249. case WC_PKCS7_DECRYPT_PWRI:
  8250. #ifndef NO_PKCS7_STREAM
  8251. /*@TODO for now just get full buffer, needs divided up */
  8252. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8253. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8254. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8255. return ret;
  8256. }
  8257. #ifdef ASN_BER_TO_DER
  8258. /* check if pkcs7->der is being used after BER to DER */
  8259. if (pkcs7->derSz > 0) {
  8260. pkiMsgSz = pkcs7->derSz;
  8261. }
  8262. else
  8263. #endif
  8264. {
  8265. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  8266. inSz;
  8267. }
  8268. #endif
  8269. /* remove KeyDerivationAlgorithmIdentifier */
  8270. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8271. return ASN_PARSE_E;
  8272. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  8273. return ASN_PARSE_E;
  8274. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8275. return ASN_PARSE_E;
  8276. /* get KeyDerivationAlgorithmIdentifier */
  8277. if (wc_GetContentType(pkiMsg, idx, &kdfAlgoId, pkiMsgSz) < 0)
  8278. return ASN_PARSE_E;
  8279. /* get KDF params SEQ */
  8280. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8281. return ASN_PARSE_E;
  8282. /* get KDF salt OCTET STRING */
  8283. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8284. return ASN_PARSE_E;
  8285. if (tag != ASN_OCTET_STRING)
  8286. return ASN_PARSE_E;
  8287. if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)
  8288. return ASN_PARSE_E;
  8289. salt = (byte*)XMALLOC(saltSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8290. if (salt == NULL)
  8291. return MEMORY_E;
  8292. XMEMCPY(salt, pkiMsg + (*idx), saltSz);
  8293. *idx += saltSz;
  8294. /* get KDF iterations */
  8295. if (GetMyVersion(pkiMsg, idx, &iterations, pkiMsgSz) < 0) {
  8296. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8297. return ASN_PARSE_E;
  8298. }
  8299. /* get KeyEncAlgoId SEQ */
  8300. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8301. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8302. return ASN_PARSE_E;
  8303. }
  8304. /* get KeyEncAlgoId */
  8305. if (wc_GetContentType(pkiMsg, idx, &keyEncAlgoId, pkiMsgSz) < 0) {
  8306. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8307. return ASN_PARSE_E;
  8308. }
  8309. /* get pwriEncAlgoId */
  8310. if (GetAlgoId(pkiMsg, idx, &pwriEncAlgoId, oidBlkType, pkiMsgSz) < 0) {
  8311. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8312. return ASN_PARSE_E;
  8313. }
  8314. blockSz = wc_PKCS7_GetOIDBlockSize(pwriEncAlgoId);
  8315. if (blockSz < 0) {
  8316. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8317. return blockSz;
  8318. }
  8319. /* get content-encryption key size, based on algorithm */
  8320. kekKeySz = wc_PKCS7_GetOIDKeySize(pwriEncAlgoId);
  8321. if (kekKeySz < 0) {
  8322. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8323. return kekKeySz;
  8324. }
  8325. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  8326. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  8327. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8328. return ASN_PARSE_E;
  8329. }
  8330. if (tag != ASN_OCTET_STRING) {
  8331. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8332. return ASN_PARSE_E;
  8333. }
  8334. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8335. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8336. return ASN_PARSE_E;
  8337. }
  8338. if (length != blockSz) {
  8339. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  8340. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8341. return ASN_PARSE_E;
  8342. }
  8343. XMEMCPY(tmpIv, pkiMsg + (*idx), length);
  8344. *idx += length;
  8345. /* get EncryptedKey */
  8346. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  8347. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8348. return ASN_PARSE_E;
  8349. }
  8350. if (tag != ASN_OCTET_STRING) {
  8351. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8352. return ASN_PARSE_E;
  8353. }
  8354. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8355. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8356. return ASN_PARSE_E;
  8357. }
  8358. /* allocate temporary space for decrypted key */
  8359. cekSz = length;
  8360. cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8361. if (cek == NULL) {
  8362. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8363. return MEMORY_E;
  8364. }
  8365. /* generate KEK */
  8366. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8367. if (kek == NULL) {
  8368. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8369. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8370. return MEMORY_E;
  8371. }
  8372. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, pkcs7->pass, pkcs7->passSz,
  8373. salt, saltSz, kdfAlgoId, hashOID,
  8374. iterations, kek, kekKeySz);
  8375. if (ret < 0) {
  8376. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8377. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8378. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8379. return ASN_PARSE_E;
  8380. }
  8381. /* decrypt CEK with KEK */
  8382. ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, kekKeySz,
  8383. pkiMsg + (*idx), length, cek,
  8384. cekSz, tmpIv, blockSz,
  8385. pwriEncAlgoId);
  8386. if (ret < 0) {
  8387. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8388. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8389. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8390. return ret;
  8391. }
  8392. cekSz = ret;
  8393. if (*decryptedKeySz < cekSz) {
  8394. WOLFSSL_MSG("Decrypted key buffer too small for CEK");
  8395. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8396. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8397. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8398. return BUFFER_E;
  8399. }
  8400. XMEMCPY(decryptedKey, cek, cekSz);
  8401. *decryptedKeySz = cekSz;
  8402. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8403. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8404. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8405. /* mark recipFound, since we only support one RecipientInfo for now */
  8406. *recipFound = 1;
  8407. *idx += length;
  8408. #ifndef NO_PKCS7_STREAM
  8409. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8410. break;
  8411. }
  8412. #endif
  8413. ret = 0; /* success */
  8414. break;
  8415. default:
  8416. WOLFSSL_MSG("PKCS7 PWRI unknown state");
  8417. ret = BAD_FUNC_ARG;
  8418. }
  8419. return ret;
  8420. }
  8421. #endif /* NO_PWDBASED | NO_SHA */
  8422. /* decode ASN.1 KEKRecipientInfo (kekri), return 0 on success,
  8423. * < 0 on error */
  8424. static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
  8425. word32* idx, byte* decryptedKey,
  8426. word32* decryptedKeySz, int* recipFound)
  8427. {
  8428. int length, keySz, dateLen, direction;
  8429. byte* keyId = NULL;
  8430. const byte* datePtr = NULL;
  8431. byte dateFormat, tag;
  8432. word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;
  8433. int ret = 0;
  8434. byte* pkiMsg = in;
  8435. word32 pkiMsgSz = inSz;
  8436. #ifndef NO_PKCS7_STREAM
  8437. word32 tmpIdx = *idx;
  8438. #endif
  8439. WOLFSSL_ENTER("wc_PKCS7_DecryptKekri");
  8440. switch (pkcs7->state) {
  8441. case WC_PKCS7_DECRYPT_KEKRI:
  8442. #ifndef NO_PKCS7_STREAM
  8443. /* @TODO for now just get full buffer, needs divided up */
  8444. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8445. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8446. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8447. return ret;
  8448. }
  8449. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8450. #endif
  8451. /* remove KEKIdentifier */
  8452. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8453. return ASN_PARSE_E;
  8454. kekIdSz = length;
  8455. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8456. return ASN_PARSE_E;
  8457. if (tag != ASN_OCTET_STRING)
  8458. return ASN_PARSE_E;
  8459. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8460. return ASN_PARSE_E;
  8461. /* save keyIdentifier and length */
  8462. keyId = pkiMsg + *idx;
  8463. keyIdSz = length;
  8464. *idx += keyIdSz;
  8465. /* may have OPTIONAL GeneralizedTime */
  8466. localIdx = *idx;
  8467. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  8468. pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {
  8469. if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,
  8470. &dateLen) != 0) {
  8471. return ASN_PARSE_E;
  8472. }
  8473. *idx += (dateLen + 1);
  8474. }
  8475. if (*idx > pkiMsgSz) {
  8476. return ASN_PARSE_E;
  8477. }
  8478. /* may have OPTIONAL OtherKeyAttribute */
  8479. localIdx = *idx;
  8480. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  8481. pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |
  8482. ASN_CONSTRUCTED)) {
  8483. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8484. return ASN_PARSE_E;
  8485. /* skip it */
  8486. *idx += length;
  8487. }
  8488. if (*idx > pkiMsgSz) {
  8489. return ASN_PARSE_E;
  8490. }
  8491. /* get KeyEncryptionAlgorithmIdentifier */
  8492. if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  8493. return ASN_PARSE_E;
  8494. /* get EncryptedKey */
  8495. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8496. return ASN_PARSE_E;
  8497. if (tag != ASN_OCTET_STRING)
  8498. return ASN_PARSE_E;
  8499. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8500. return ASN_PARSE_E;
  8501. #ifndef NO_AES
  8502. direction = AES_DECRYPTION;
  8503. #else
  8504. direction = DES_DECRYPTION;
  8505. #endif
  8506. /* decrypt CEK with KEK */
  8507. if (pkcs7->wrapCEKCb) {
  8508. keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,
  8509. keyIdSz, NULL, 0, decryptedKey,
  8510. *decryptedKeySz, keyWrapOID,
  8511. (int)PKCS7_KEKRI, direction);
  8512. }
  8513. else {
  8514. keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,
  8515. pkcs7->privateKeySz, decryptedKey, *decryptedKeySz,
  8516. keyWrapOID, direction);
  8517. }
  8518. if (keySz <= 0)
  8519. return keySz;
  8520. *decryptedKeySz = (word32)keySz;
  8521. /* mark recipFound, since we only support one RecipientInfo for now */
  8522. *recipFound = 1;
  8523. *idx += length;
  8524. #ifndef NO_PKCS7_STREAM
  8525. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8526. break;
  8527. }
  8528. #endif
  8529. ret = 0; /* success */
  8530. break;
  8531. default:
  8532. WOLFSSL_MSG("PKCS7 KEKRI unknown state");
  8533. ret = BAD_FUNC_ARG;
  8534. }
  8535. (void)keyId;
  8536. return ret;
  8537. }
  8538. /* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,
  8539. * < 0 on error */
  8540. static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
  8541. word32* idx, byte* decryptedKey,
  8542. word32* decryptedKeySz, int* recipFound)
  8543. {
  8544. #ifdef HAVE_ECC
  8545. int ret, keySz;
  8546. int encryptedKeySz;
  8547. int direction = 0;
  8548. int keyIdSize;
  8549. word32 keyAgreeOID, keyWrapOID;
  8550. byte rid[KEYID_SIZE];
  8551. #ifdef WOLFSSL_SMALL_STACK
  8552. byte* encryptedKey;
  8553. #else
  8554. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  8555. #endif
  8556. byte* pkiMsg = in;
  8557. word32 pkiMsgSz = inSz;
  8558. #ifndef NO_PKCS7_STREAM
  8559. word32 tmpIdx = (idx) ? *idx : 0;
  8560. #endif
  8561. WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
  8562. if (pkcs7 == NULL || pkiMsg == NULL ||
  8563. idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
  8564. return BAD_FUNC_ARG;
  8565. }
  8566. #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
  8567. keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
  8568. pkcs7->publicKeyOID)));
  8569. #else
  8570. keyIdSize = KEYID_SIZE;
  8571. #endif
  8572. switch (pkcs7->state) {
  8573. case WC_PKCS7_DECRYPT_KARI: {
  8574. WC_PKCS7_KARI* kari;
  8575. #ifndef NO_PKCS7_STREAM
  8576. /* @TODO for now just get full buffer, needs divided up */
  8577. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8578. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8579. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8580. return ret;
  8581. }
  8582. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8583. #endif
  8584. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);
  8585. if (kari == NULL)
  8586. return MEMORY_E;
  8587. #ifdef WOLFSSL_SMALL_STACK
  8588. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  8589. DYNAMIC_TYPE_PKCS7);
  8590. if (encryptedKey == NULL) {
  8591. wc_PKCS7_KariFree(kari);
  8592. return MEMORY_E;
  8593. }
  8594. #endif
  8595. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  8596. /* parse cert and key */
  8597. ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
  8598. pkcs7->singleCertSz, pkcs7->privateKey,
  8599. pkcs7->privateKeySz);
  8600. if (ret != 0) {
  8601. wc_PKCS7_KariFree(kari);
  8602. #ifdef WOLFSSL_SMALL_STACK
  8603. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8604. #endif
  8605. return ret;
  8606. }
  8607. /* remove OriginatorIdentifierOrKey */
  8608. ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
  8609. pkiMsgSz, idx);
  8610. if (ret != 0) {
  8611. wc_PKCS7_KariFree(kari);
  8612. #ifdef WOLFSSL_SMALL_STACK
  8613. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8614. #endif
  8615. return ret;
  8616. }
  8617. /* try and remove optional UserKeyingMaterial */
  8618. ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);
  8619. if (ret != 0) {
  8620. wc_PKCS7_KariFree(kari);
  8621. #ifdef WOLFSSL_SMALL_STACK
  8622. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8623. #endif
  8624. return ret;
  8625. }
  8626. /* remove KeyEncryptionAlgorithmIdentifier */
  8627. ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,
  8628. pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);
  8629. if (ret != 0) {
  8630. wc_PKCS7_KariFree(kari);
  8631. #ifdef WOLFSSL_SMALL_STACK
  8632. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8633. #endif
  8634. return ret;
  8635. }
  8636. /* if user has not explicitly set keyAgreeOID, set from one in bundle */
  8637. if (pkcs7->keyAgreeOID == 0)
  8638. pkcs7->keyAgreeOID = keyAgreeOID;
  8639. /* set direction based on key wrap algorithm */
  8640. switch (keyWrapOID) {
  8641. #ifndef NO_AES
  8642. #ifdef WOLFSSL_AES_128
  8643. case AES128_WRAP:
  8644. #endif
  8645. #ifdef WOLFSSL_AES_192
  8646. case AES192_WRAP:
  8647. #endif
  8648. #ifdef WOLFSSL_AES_256
  8649. case AES256_WRAP:
  8650. #endif
  8651. direction = AES_DECRYPTION;
  8652. break;
  8653. #endif
  8654. default:
  8655. WOLFSSL_MSG("AES key wrap algorithm unsupported");
  8656. if (pkcs7->wrapCEKCb) {
  8657. WOLFSSL_MSG("Direction not set!");
  8658. break; /* if unwrapping callback is set then do not
  8659. * force restriction of supported wrap
  8660. * algorithms */
  8661. }
  8662. wc_PKCS7_KariFree(kari);
  8663. #ifdef WOLFSSL_SMALL_STACK
  8664. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8665. #endif
  8666. return BAD_KEYWRAP_ALG_E;
  8667. }
  8668. /* remove RecipientEncryptedKeys */
  8669. ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
  8670. idx, recipFound, encryptedKey, &encryptedKeySz, rid);
  8671. if (ret != 0) {
  8672. wc_PKCS7_KariFree(kari);
  8673. #ifdef WOLFSSL_SMALL_STACK
  8674. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8675. #endif
  8676. return ret;
  8677. }
  8678. /* decrypt CEK with KEK */
  8679. if (pkcs7->wrapCEKCb) {
  8680. word32 tmpKeySz = 0;
  8681. byte* tmpKeyDer = NULL;
  8682. PRIVATE_KEY_UNLOCK();
  8683. ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);
  8684. PRIVATE_KEY_LOCK();
  8685. if (ret != LENGTH_ONLY_E) {
  8686. return ret;
  8687. }
  8688. /* buffer space for algorithm/curve */
  8689. tmpKeySz += MAX_SEQ_SZ;
  8690. tmpKeySz += 2 * MAX_ALGO_SZ;
  8691. /* buffer space for public key sequence */
  8692. tmpKeySz += MAX_SEQ_SZ;
  8693. tmpKeySz += TRAILING_ZERO;
  8694. tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,
  8695. DYNAMIC_TYPE_TMP_BUFFER);
  8696. if (tmpKeyDer == NULL) {
  8697. return MEMORY_E;
  8698. }
  8699. ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,
  8700. tmpKeySz, 1);
  8701. if (ret < 0) {
  8702. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8703. return ret;
  8704. }
  8705. tmpKeySz = (word32)ret;
  8706. keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,
  8707. rid, keyIdSize, tmpKeyDer, tmpKeySz,
  8708. decryptedKey, *decryptedKeySz,
  8709. keyWrapOID, (int)PKCS7_KARI, direction);
  8710. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8711. if (keySz > 0) {
  8712. /* If unwrapping was successful then consider recipient
  8713. * found. Checking for NULL singleCert to confirm previous
  8714. * SID check was not done */
  8715. if (pkcs7->singleCert == NULL)
  8716. *recipFound = 1;
  8717. }
  8718. }
  8719. else {
  8720. /* create KEK */
  8721. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID,
  8722. pkcs7->keyAgreeOID);
  8723. if (ret != 0) {
  8724. wc_PKCS7_KariFree(kari);
  8725. #ifdef WOLFSSL_SMALL_STACK
  8726. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8727. #endif
  8728. return ret;
  8729. }
  8730. /* decrypt CEK with KEK */
  8731. keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,
  8732. kari->kekSz, decryptedKey, *decryptedKeySz,
  8733. keyWrapOID, direction);
  8734. }
  8735. if (keySz <= 0) {
  8736. wc_PKCS7_KariFree(kari);
  8737. #ifdef WOLFSSL_SMALL_STACK
  8738. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8739. #endif
  8740. return keySz;
  8741. }
  8742. *decryptedKeySz = (word32)keySz;
  8743. wc_PKCS7_KariFree(kari);
  8744. #ifdef WOLFSSL_SMALL_STACK
  8745. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8746. #endif
  8747. #ifndef NO_PKCS7_STREAM
  8748. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8749. break;
  8750. }
  8751. #endif
  8752. ret = 0; /* success */
  8753. }
  8754. break;
  8755. default:
  8756. WOLFSSL_MSG("PKCS7 kari unknown state");
  8757. ret = BAD_FUNC_ARG;
  8758. }
  8759. (void)pkiMsg;
  8760. (void)pkiMsgSz;
  8761. return ret;
  8762. #else
  8763. (void)in;
  8764. (void)inSz;
  8765. (void)pkcs7;
  8766. (void)idx;
  8767. (void)decryptedKey;
  8768. (void)decryptedKeySz;
  8769. (void)recipFound;
  8770. return NOT_COMPILED_IN;
  8771. #endif /* HAVE_ECC */
  8772. }
  8773. /* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */
  8774. static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
  8775. word32 inSz, word32* idx, byte* decryptedKey,
  8776. word32* decryptedKeySz, int* recipFound)
  8777. {
  8778. word32 savedIdx;
  8779. int version, ret = 0, length;
  8780. byte* pkiMsg = in;
  8781. word32 pkiMsgSz = inSz;
  8782. byte tag;
  8783. #ifndef NO_PKCS7_STREAM
  8784. word32 tmpIdx;
  8785. #endif
  8786. if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||
  8787. decryptedKey == NULL || decryptedKeySz == NULL ||
  8788. recipFound == NULL) {
  8789. return BAD_FUNC_ARG;
  8790. }
  8791. WOLFSSL_ENTER("wc_PKCS7_DecryptRecipientInfos");
  8792. #ifndef NO_PKCS7_STREAM
  8793. tmpIdx = *idx;
  8794. #endif
  8795. /* check if in the process of decrypting */
  8796. switch (pkcs7->state) {
  8797. case WC_PKCS7_DECRYPT_KTRI:
  8798. case WC_PKCS7_DECRYPT_KTRI_2:
  8799. case WC_PKCS7_DECRYPT_KTRI_3:
  8800. #ifndef NO_RSA
  8801. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8802. decryptedKey, decryptedKeySz, recipFound);
  8803. #else
  8804. return NOT_COMPILED_IN;
  8805. #endif
  8806. break;
  8807. case WC_PKCS7_DECRYPT_KARI:
  8808. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8809. decryptedKey, decryptedKeySz, recipFound);
  8810. break;
  8811. case WC_PKCS7_DECRYPT_KEKRI:
  8812. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8813. decryptedKey, decryptedKeySz, recipFound);
  8814. break;
  8815. case WC_PKCS7_DECRYPT_PWRI:
  8816. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8817. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8818. decryptedKey, decryptedKeySz, recipFound);
  8819. break;
  8820. #else
  8821. return NOT_COMPILED_IN;
  8822. #endif
  8823. case WC_PKCS7_DECRYPT_ORI:
  8824. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8825. decryptedKey, decryptedKeySz, recipFound);
  8826. break;
  8827. default:
  8828. /* not in decrypting state */
  8829. break;
  8830. }
  8831. if (ret < 0) {
  8832. return ret;
  8833. }
  8834. savedIdx = *idx;
  8835. #ifndef NO_PKCS7_STREAM
  8836. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8837. if (pkcs7->stream->length > 0)
  8838. pkiMsg = pkcs7->stream->buffer;
  8839. #endif
  8840. /* when looking for next recipient, use first sequence and version to
  8841. * indicate there is another, if not, move on */
  8842. while(*recipFound == 0) {
  8843. /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
  8844. * last good saved one */
  8845. if (GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz, NO_USER_CHECK) > 0) {
  8846. #ifndef NO_RSA
  8847. /* found ktri */
  8848. #ifndef NO_PKCS7_STREAM
  8849. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8850. break;
  8851. }
  8852. #endif
  8853. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI);
  8854. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8855. decryptedKey, decryptedKeySz,
  8856. recipFound);
  8857. if (ret != 0)
  8858. return ret;
  8859. #else
  8860. return NOT_COMPILED_IN;
  8861. #endif
  8862. }
  8863. else {
  8864. word32 localIdx;
  8865. /* kari is IMPLICIT[1] */
  8866. *idx = savedIdx;
  8867. localIdx = *idx;
  8868. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {
  8869. /* no room for recipient info */
  8870. break;
  8871. }
  8872. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  8873. (*idx)++;
  8874. if (GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
  8875. NO_USER_CHECK) < 0)
  8876. return ASN_PARSE_E;
  8877. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8878. *idx = savedIdx;
  8879. break;
  8880. }
  8881. if (version != 3)
  8882. return ASN_VERSION_E;
  8883. /* found kari */
  8884. #ifndef NO_PKCS7_STREAM
  8885. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8886. break;
  8887. }
  8888. #endif
  8889. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KARI);
  8890. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8891. decryptedKey, decryptedKeySz,
  8892. recipFound);
  8893. if (ret != 0)
  8894. return ret;
  8895. /* kekri is IMPLICIT[2] */
  8896. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {
  8897. (*idx)++;
  8898. if (GetLength_ex(pkiMsg, idx, &version, pkiMsgSz,
  8899. NO_USER_CHECK) < 0)
  8900. return ASN_PARSE_E;
  8901. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8902. *idx = savedIdx;
  8903. break;
  8904. }
  8905. if (version != 4)
  8906. return ASN_VERSION_E;
  8907. /* found kekri */
  8908. #ifndef NO_PKCS7_STREAM
  8909. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8910. break;
  8911. }
  8912. #endif
  8913. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KEKRI);
  8914. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8915. decryptedKey, decryptedKeySz,
  8916. recipFound);
  8917. if (ret != 0)
  8918. return ret;
  8919. /* pwri is IMPLICIT[3] */
  8920. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {
  8921. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8922. (*idx)++;
  8923. if (GetLength_ex(pkiMsg, idx, &version, pkiMsgSz,
  8924. NO_USER_CHECK) < 0)
  8925. return ASN_PARSE_E;
  8926. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8927. *idx = savedIdx;
  8928. break;
  8929. }
  8930. if (version != 0)
  8931. return ASN_VERSION_E;
  8932. /* found pwri */
  8933. #ifndef NO_PKCS7_STREAM
  8934. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8935. break;
  8936. }
  8937. #endif
  8938. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_PWRI);
  8939. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8940. decryptedKey, decryptedKeySz,
  8941. recipFound);
  8942. if (ret != 0)
  8943. return ret;
  8944. #else
  8945. return NOT_COMPILED_IN;
  8946. #endif
  8947. /* ori is IMPLICIT[4] */
  8948. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {
  8949. (*idx)++;
  8950. /* found ori */
  8951. #ifndef NO_PKCS7_STREAM
  8952. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8953. break;
  8954. }
  8955. #endif
  8956. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_ORI);
  8957. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8958. decryptedKey, decryptedKeySz,
  8959. recipFound);
  8960. if (ret != 0)
  8961. return ret;
  8962. } else {
  8963. /* failed to find RecipientInfo, restore idx and continue */
  8964. *idx = savedIdx;
  8965. break;
  8966. }
  8967. }
  8968. /* update good idx */
  8969. savedIdx = *idx;
  8970. }
  8971. return ret;
  8972. }
  8973. /* Parse encoded EnvelopedData bundle up to RecipientInfo set.
  8974. *
  8975. * return size of RecipientInfo SET on success, negative upon error */
  8976. static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
  8977. word32 inSz, word32* idx,
  8978. int type)
  8979. {
  8980. int version = 0, length, ret = 0;
  8981. word32 contentType;
  8982. byte* pkiMsg = in;
  8983. word32 pkiMsgSz = inSz;
  8984. byte tag;
  8985. #ifndef NO_PKCS7_STREAM
  8986. word32 tmpIdx = 0;
  8987. #endif
  8988. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 || idx == NULL)
  8989. return BAD_FUNC_ARG;
  8990. if ((type != ENVELOPED_DATA) && (type != AUTH_ENVELOPED_DATA) &&
  8991. pkcs7->contentOID != FIRMWARE_PKG_DATA
  8992. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  8993. && pkcs7->contentOID != COMPRESSED_DATA
  8994. #endif
  8995. )
  8996. return BAD_FUNC_ARG;
  8997. #ifndef NO_PKCS7_STREAM
  8998. if (pkcs7->stream == NULL) {
  8999. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  9000. return ret;
  9001. }
  9002. }
  9003. #endif
  9004. switch (pkcs7->state) {
  9005. case WC_PKCS7_INFOSET_START:
  9006. case WC_PKCS7_INFOSET_BER:
  9007. case WC_PKCS7_INFOSET_STAGE1:
  9008. case WC_PKCS7_INFOSET_STAGE2:
  9009. case WC_PKCS7_INFOSET_END:
  9010. break;
  9011. default:
  9012. WOLFSSL_MSG("Warning, setting PKCS7 info state to start");
  9013. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_START);
  9014. }
  9015. switch (pkcs7->state) {
  9016. case WC_PKCS7_INFOSET_START:
  9017. #ifndef NO_PKCS7_STREAM
  9018. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  9019. ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  9020. return ret;
  9021. }
  9022. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  9023. break;
  9024. }
  9025. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9026. #endif
  9027. /* read past ContentInfo, verify type is envelopedData */
  9028. if (ret == 0 && GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz,
  9029. NO_USER_CHECK) < 0)
  9030. {
  9031. ret = ASN_PARSE_E;
  9032. }
  9033. if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) {
  9034. #ifdef ASN_BER_TO_DER
  9035. word32 len;
  9036. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER);
  9037. FALL_THROUGH;
  9038. /* full buffer is needed for conversion */
  9039. case WC_PKCS7_INFOSET_BER:
  9040. #ifndef NO_PKCS7_STREAM
  9041. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9042. pkcs7->stream->maxLen - pkcs7->stream->length,
  9043. &pkiMsg, idx)) != 0) {
  9044. return ret;
  9045. }
  9046. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  9047. inSz;
  9048. #endif
  9049. len = 0;
  9050. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  9051. if (ret != LENGTH_ONLY_E)
  9052. return ret;
  9053. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9054. if (pkcs7->der == NULL)
  9055. return MEMORY_E;
  9056. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  9057. if (ret < 0)
  9058. return ret;
  9059. pkiMsg = in = pkcs7->der;
  9060. pkiMsgSz = pkcs7->derSz = inSz = len;
  9061. *idx = 0;
  9062. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  9063. return ASN_PARSE_E;
  9064. #else
  9065. return BER_INDEF_E;
  9066. #endif
  9067. }
  9068. #ifndef NO_PKCS7_STREAM
  9069. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  9070. break;
  9071. }
  9072. #endif
  9073. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE1);
  9074. FALL_THROUGH;
  9075. case WC_PKCS7_INFOSET_STAGE1:
  9076. #ifndef NO_PKCS7_STREAM
  9077. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +
  9078. MAX_LENGTH_SZ + ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  9079. return ret;
  9080. }
  9081. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
  9082. #endif
  9083. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  9084. type == AUTH_ENVELOPED_DATA) {
  9085. if (ret == 0 && wc_GetContentType(pkiMsg, idx, &contentType,
  9086. pkiMsgSz) < 0)
  9087. ret = ASN_PARSE_E;
  9088. if (ret == 0) {
  9089. if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) {
  9090. WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
  9091. ret = PKCS7_OID_E;
  9092. } else if (type == AUTH_ENVELOPED_DATA &&
  9093. contentType != AUTH_ENVELOPED_DATA) {
  9094. WOLFSSL_MSG("PKCS#7 input not of type AuthEnvelopedData");
  9095. ret = PKCS7_OID_E;
  9096. }
  9097. }
  9098. if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)
  9099. ret = ASN_PARSE_E;
  9100. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
  9101. | 0))
  9102. ret = ASN_PARSE_E;
  9103. if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
  9104. NO_USER_CHECK) < 0)
  9105. ret = ASN_PARSE_E;
  9106. }
  9107. if (ret < 0)
  9108. break;
  9109. #ifndef NO_PKCS7_STREAM
  9110. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  9111. break;
  9112. }
  9113. #endif
  9114. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE2);
  9115. FALL_THROUGH;
  9116. case WC_PKCS7_INFOSET_STAGE2:
  9117. #ifndef NO_PKCS7_STREAM
  9118. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  9119. MAX_VERSION_SZ, &pkiMsg, idx)) != 0) {
  9120. return ret;
  9121. }
  9122. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9123. #endif
  9124. /* remove EnvelopedData and version */
  9125. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  9126. type == AUTH_ENVELOPED_DATA) {
  9127. if (ret == 0 && GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz,
  9128. NO_USER_CHECK) < 0)
  9129. ret = ASN_PARSE_E;
  9130. }
  9131. if (ret == 0 && GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  9132. ret = ASN_PARSE_E;
  9133. if (ret < 0)
  9134. break;
  9135. #ifndef NO_PKCS7_STREAM
  9136. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  9137. break;
  9138. }
  9139. pkcs7->stream->varOne = version;
  9140. #endif
  9141. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_END);
  9142. FALL_THROUGH;
  9143. case WC_PKCS7_INFOSET_END:
  9144. #ifndef NO_PKCS7_STREAM
  9145. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9146. MAX_SET_SZ, &pkiMsg, idx)) != 0) {
  9147. return ret;
  9148. }
  9149. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9150. version = pkcs7->stream->varOne;
  9151. #endif
  9152. if (type == ENVELOPED_DATA) {
  9153. /* TODO :: make this more accurate */
  9154. if ((pkcs7->publicKeyOID == RSAk &&
  9155. (version != 0 && version != 2))
  9156. #ifdef HAVE_ECC
  9157. || (pkcs7->publicKeyOID == ECDSAk &&
  9158. (version != 0 && version != 2 && version != 3))
  9159. #endif
  9160. ) {
  9161. WOLFSSL_MSG("PKCS#7 envelopedData version incorrect");
  9162. ret = ASN_VERSION_E;
  9163. }
  9164. } else {
  9165. /* AuthEnvelopedData version MUST be 0 */
  9166. if (version != 0) {
  9167. WOLFSSL_MSG("PKCS#7 AuthEnvelopedData needs to be of version 0");
  9168. ret = ASN_VERSION_E;
  9169. }
  9170. }
  9171. /* remove RecipientInfo set, get length of set */
  9172. if (ret == 0 && GetSet_ex(pkiMsg, idx, &length, pkiMsgSz,
  9173. NO_USER_CHECK) < 0)
  9174. ret = ASN_PARSE_E;
  9175. if (ret < 0)
  9176. break;
  9177. #ifndef NO_PKCS7_STREAM
  9178. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  9179. break;
  9180. }
  9181. #endif
  9182. if (ret == 0)
  9183. ret = length;
  9184. break;
  9185. default:
  9186. WOLFSSL_MSG("Bad PKCS7 info set state");
  9187. ret = BAD_FUNC_ARG;
  9188. break;
  9189. }
  9190. return ret;
  9191. }
  9192. /* Import secret/private key into a PKCS7 structure. Used for setting
  9193. * the secret key for decryption a EnvelopedData KEKRI RecipientInfo.
  9194. *
  9195. * Returns 0 on success, negative upon error */
  9196. WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz)
  9197. {
  9198. if (pkcs7 == NULL || key == NULL || keySz == 0)
  9199. return BAD_FUNC_ARG;
  9200. pkcs7->privateKey = key;
  9201. pkcs7->privateKeySz = keySz;
  9202. return 0;
  9203. }
  9204. /* append data to encrypted content cache in PKCS7 structure
  9205. * return 0 on success, negative on error */
  9206. static int PKCS7_CacheEncryptedContent(PKCS7* pkcs7, byte* in, word32 inSz)
  9207. {
  9208. byte* oldCache;
  9209. word32 oldCacheSz;
  9210. if (pkcs7 == NULL || in == NULL)
  9211. return BAD_FUNC_ARG;
  9212. /* save pointer to old cache */
  9213. oldCache = pkcs7->cachedEncryptedContent;
  9214. oldCacheSz = pkcs7->cachedEncryptedContentSz;
  9215. /* re-allocate new buffer to fit appended data */
  9216. pkcs7->cachedEncryptedContent = (byte*)XMALLOC(oldCacheSz + inSz,
  9217. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9218. if (pkcs7->cachedEncryptedContent == NULL) {
  9219. pkcs7->cachedEncryptedContentSz = 0;
  9220. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9221. return MEMORY_E;
  9222. }
  9223. if (oldCache != NULL) {
  9224. XMEMCPY(pkcs7->cachedEncryptedContent, oldCache, oldCacheSz);
  9225. }
  9226. XMEMCPY(pkcs7->cachedEncryptedContent + oldCacheSz, in, inSz);
  9227. pkcs7->cachedEncryptedContentSz += inSz;
  9228. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9229. return 0;
  9230. }
  9231. /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
  9232. WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
  9233. word32 inSz, byte* output,
  9234. word32 outputSz)
  9235. {
  9236. int recipFound = 0;
  9237. int ret, length = 0;
  9238. word32 idx = 0;
  9239. #ifndef NO_PKCS7_STREAM
  9240. word32 tmpIdx = 0;
  9241. #endif
  9242. word32 contentType = 0, encOID = 0;
  9243. word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9244. int expBlockSz = 0, blockKeySz = 0;
  9245. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  9246. byte* tmpIv = tmpIvBuf;
  9247. byte* pkiMsg = in;
  9248. word32 pkiMsgSz = inSz;
  9249. byte* decryptedKey = NULL;
  9250. int encryptedContentTotalSz = 0;
  9251. int encryptedContentSz = 0;
  9252. byte padLen;
  9253. byte* encryptedContent = NULL;
  9254. int explicitOctet = 0;
  9255. word32 localIdx;
  9256. byte tag = 0;
  9257. if (pkcs7 == NULL)
  9258. return BAD_FUNC_ARG;
  9259. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  9260. output == NULL || outputSz == 0)
  9261. return BAD_FUNC_ARG;
  9262. #ifndef NO_PKCS7_STREAM
  9263. (void)tmpIv; /* help out static analysis */
  9264. if (pkcs7->stream == NULL) {
  9265. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  9266. return ret;
  9267. }
  9268. }
  9269. #endif
  9270. switch (pkcs7->state) {
  9271. case WC_PKCS7_START:
  9272. case WC_PKCS7_INFOSET_START:
  9273. case WC_PKCS7_INFOSET_BER:
  9274. case WC_PKCS7_INFOSET_STAGE1:
  9275. case WC_PKCS7_INFOSET_STAGE2:
  9276. case WC_PKCS7_INFOSET_END:
  9277. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  9278. &idx, ENVELOPED_DATA);
  9279. if (ret < 0) {
  9280. break;
  9281. }
  9282. #ifdef ASN_BER_TO_DER
  9283. /* check if content was BER and has been converted to DER */
  9284. if (pkcs7->derSz > 0) {
  9285. pkiMsg = in = pkcs7->der;
  9286. inSz = pkcs7->derSz;
  9287. #ifdef NO_PKCS7_STREAM
  9288. pkiMsgSz = pkcs7->derSz;
  9289. #endif
  9290. }
  9291. #endif
  9292. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  9293. DYNAMIC_TYPE_PKCS7);
  9294. if (decryptedKey == NULL)
  9295. return MEMORY_E;
  9296. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);
  9297. #ifndef NO_PKCS7_STREAM
  9298. tmpIdx = idx;
  9299. pkcs7->stream->aad = decryptedKey;
  9300. #endif
  9301. FALL_THROUGH;
  9302. case WC_PKCS7_ENV_2:
  9303. #ifndef NO_PKCS7_STREAM
  9304. /* store up enough buffer for initial info set decode */
  9305. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9306. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  9307. return ret;
  9308. }
  9309. #endif
  9310. FALL_THROUGH;
  9311. case WC_PKCS7_DECRYPT_KTRI:
  9312. case WC_PKCS7_DECRYPT_KTRI_2:
  9313. case WC_PKCS7_DECRYPT_KTRI_3:
  9314. case WC_PKCS7_DECRYPT_KARI:
  9315. case WC_PKCS7_DECRYPT_KEKRI:
  9316. case WC_PKCS7_DECRYPT_PWRI:
  9317. case WC_PKCS7_DECRYPT_ORI:
  9318. #ifndef NO_PKCS7_STREAM
  9319. decryptedKey = pkcs7->stream->aad;
  9320. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9321. #endif
  9322. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  9323. decryptedKey, &decryptedKeySz,
  9324. &recipFound);
  9325. if (ret == 0 && recipFound == 0) {
  9326. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  9327. ret = PKCS7_RECIP_E;
  9328. }
  9329. if (ret != 0)
  9330. break;
  9331. #ifndef NO_PKCS7_STREAM
  9332. tmpIdx = idx;
  9333. pkcs7->stream->aadSz = decryptedKeySz;
  9334. #endif
  9335. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
  9336. FALL_THROUGH;
  9337. case WC_PKCS7_ENV_3:
  9338. #ifndef NO_PKCS7_STREAM
  9339. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9340. MAX_VERSION_SZ + ASN_TAG_SZ +
  9341. MAX_LENGTH_SZ, &pkiMsg, &idx))
  9342. != 0) {
  9343. return ret;
  9344. }
  9345. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9346. #else
  9347. ret = 0;
  9348. #endif
  9349. /* remove EncryptedContentInfo */
  9350. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  9351. NO_USER_CHECK) < 0) {
  9352. ret = ASN_PARSE_E;
  9353. }
  9354. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  9355. pkiMsgSz) < 0) {
  9356. ret = ASN_PARSE_E;
  9357. }
  9358. if (ret == 0) {
  9359. pkcs7->contentOID = contentType;
  9360. }
  9361. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  9362. pkiMsgSz) < 0) {
  9363. ret = ASN_PARSE_E;
  9364. }
  9365. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  9366. if (ret == 0 && blockKeySz < 0) {
  9367. ret = blockKeySz;
  9368. }
  9369. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  9370. if (ret == 0 && expBlockSz < 0) {
  9371. ret = expBlockSz;
  9372. }
  9373. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  9374. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {
  9375. ret = ASN_PARSE_E;
  9376. }
  9377. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9378. ret = ASN_PARSE_E;
  9379. }
  9380. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz,
  9381. NO_USER_CHECK) < 0) {
  9382. ret = ASN_PARSE_E;
  9383. }
  9384. if (ret == 0 && length != expBlockSz) {
  9385. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  9386. ret = ASN_PARSE_E;
  9387. }
  9388. if (ret != 0)
  9389. break;
  9390. #ifndef NO_PKCS7_STREAM
  9391. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9392. break;
  9393. }
  9394. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length);
  9395. pkcs7->stream->contentSz = blockKeySz;
  9396. pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ +
  9397. ASN_TAG_SZ + ASN_TAG_SZ;
  9398. #endif
  9399. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4);
  9400. FALL_THROUGH;
  9401. case WC_PKCS7_ENV_4:
  9402. #ifndef NO_PKCS7_STREAM
  9403. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9404. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9405. return ret;
  9406. }
  9407. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9408. wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length);
  9409. tmpIv = pkcs7->stream->tmpIv;
  9410. if (tmpIv == NULL) {
  9411. /* check added to help out static analysis tool */
  9412. ret = MEMORY_E;
  9413. break;
  9414. }
  9415. #else
  9416. ret = 0;
  9417. #endif
  9418. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  9419. idx += length;
  9420. explicitOctet = 0;
  9421. localIdx = idx;
  9422. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  9423. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9424. explicitOctet = 1;
  9425. }
  9426. /* read encryptedContent, cont[0] */
  9427. if (tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  9428. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9429. ret = ASN_PARSE_E;
  9430. }
  9431. idx++;
  9432. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz,
  9433. pkiMsgSz) <= 0) {
  9434. ret = ASN_PARSE_E;
  9435. }
  9436. if (ret != 0)
  9437. break;
  9438. #ifndef NO_PKCS7_STREAM
  9439. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9440. break;
  9441. }
  9442. pkcs7->stream->expected = encryptedContentTotalSz;
  9443. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0);
  9444. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet);
  9445. #endif
  9446. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5);
  9447. FALL_THROUGH;
  9448. case WC_PKCS7_ENV_5:
  9449. #ifndef NO_PKCS7_STREAM
  9450. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9451. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9452. return ret;
  9453. }
  9454. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet);
  9455. tmpIv = pkcs7->stream->tmpIv;
  9456. encryptedContentTotalSz = pkcs7->stream->expected;
  9457. /* restore decrypted key */
  9458. decryptedKey = pkcs7->stream->aad;
  9459. decryptedKeySz = pkcs7->stream->aadSz;
  9460. blockKeySz = pkcs7->stream->contentSz;
  9461. #else
  9462. ret = 0;
  9463. #endif
  9464. if (explicitOctet) {
  9465. /* encrypted content may be fragmented into multiple
  9466. * consecutive OCTET STRINGs, if so loop through
  9467. * collecting and caching encrypted content bytes */
  9468. localIdx = idx;
  9469. while (idx < (localIdx + encryptedContentTotalSz)) {
  9470. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9471. ret = ASN_PARSE_E;
  9472. }
  9473. if (ret == 0 && (tag != ASN_OCTET_STRING)) {
  9474. ret = ASN_PARSE_E;
  9475. }
  9476. if (ret == 0 && GetLength(pkiMsg, &idx,
  9477. &encryptedContentSz, pkiMsgSz) <= 0) {
  9478. ret = ASN_PARSE_E;
  9479. }
  9480. if (ret == 0) {
  9481. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  9482. encryptedContentSz);
  9483. }
  9484. if (ret != 0) {
  9485. break;
  9486. }
  9487. /* advance idx past encrypted content */
  9488. idx += encryptedContentSz;
  9489. }
  9490. if (ret != 0) {
  9491. break;
  9492. }
  9493. } else {
  9494. /* cache encrypted content, no OCTET STRING */
  9495. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  9496. encryptedContentTotalSz);
  9497. if (ret != 0) {
  9498. break;
  9499. }
  9500. idx += encryptedContentTotalSz;
  9501. }
  9502. /* use cached content */
  9503. encryptedContent = pkcs7->cachedEncryptedContent;
  9504. encryptedContentSz = pkcs7->cachedEncryptedContentSz;
  9505. /* decrypt encryptedContent */
  9506. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  9507. blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,
  9508. encryptedContent, encryptedContentSz, encryptedContent,
  9509. pkcs7->devId, pkcs7->heap);
  9510. if (ret != 0) {
  9511. break;
  9512. }
  9513. padLen = encryptedContent[encryptedContentSz-1];
  9514. /* copy plaintext to output */
  9515. if (padLen > encryptedContentSz ||
  9516. (word32)(encryptedContentSz - padLen) > outputSz) {
  9517. ret = BUFFER_E;
  9518. break;
  9519. }
  9520. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  9521. /* free memory, zero out keys */
  9522. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9523. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9524. if (pkcs7->cachedEncryptedContent != NULL) {
  9525. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  9526. DYNAMIC_TYPE_PKCS7);
  9527. pkcs7->cachedEncryptedContent = NULL;
  9528. pkcs7->cachedEncryptedContentSz = 0;
  9529. }
  9530. ret = encryptedContentSz - padLen;
  9531. #ifndef NO_PKCS7_STREAM
  9532. pkcs7->stream->aad = NULL;
  9533. pkcs7->stream->aadSz = 0;
  9534. wc_PKCS7_ResetStream(pkcs7);
  9535. #endif
  9536. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  9537. break;
  9538. default:
  9539. WOLFSSL_MSG("PKCS#7 unknown decode enveloped state");
  9540. ret = BAD_FUNC_ARG;
  9541. }
  9542. #ifndef NO_PKCS7_STREAM
  9543. if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {
  9544. wc_PKCS7_ResetStream(pkcs7);
  9545. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  9546. if (pkcs7->cachedEncryptedContent != NULL) {
  9547. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  9548. DYNAMIC_TYPE_PKCS7);
  9549. pkcs7->cachedEncryptedContent = NULL;
  9550. pkcs7->cachedEncryptedContentSz = 0;
  9551. }
  9552. }
  9553. #else
  9554. if (decryptedKey != NULL && ret < 0) {
  9555. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9556. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9557. }
  9558. if (pkcs7->cachedEncryptedContent != NULL && ret < 0) {
  9559. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9560. pkcs7->cachedEncryptedContent = NULL;
  9561. pkcs7->cachedEncryptedContentSz = 0;
  9562. }
  9563. #endif
  9564. return ret;
  9565. }
  9566. /* build PKCS#7 authEnvelopedData content type, return enveloped size */
  9567. int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
  9568. word32 outputSz)
  9569. {
  9570. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  9571. int ret, idx = 0;
  9572. int totalSz, encryptedAllocSz, encryptedOutSz;
  9573. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  9574. byte contentInfoSeq[MAX_SEQ_SZ];
  9575. byte outerContentType[MAX_ALGO_SZ];
  9576. byte outerContent[MAX_SEQ_SZ];
  9577. int envDataSeqSz, verSz;
  9578. byte envDataSeq[MAX_SEQ_SZ];
  9579. byte ver[MAX_VERSION_SZ];
  9580. WC_RNG rng;
  9581. int blockSz, blockKeySz;
  9582. byte* plain;
  9583. byte* encryptedContent;
  9584. Pkcs7EncodedRecip* tmpRecip = NULL;
  9585. int recipSz, recipSetSz;
  9586. byte recipSet[MAX_SET_SZ];
  9587. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  9588. int contentEncAlgoSz, nonceOctetStringSz, macOctetStringSz;
  9589. byte encContentSeq[MAX_SEQ_SZ];
  9590. byte contentType[MAX_ALGO_SZ];
  9591. byte contentEncAlgo[MAX_ALGO_SZ];
  9592. byte nonceOctetString[MAX_OCTET_STR_SZ];
  9593. byte encContentOctet[MAX_OCTET_STR_SZ];
  9594. byte macOctetString[MAX_OCTET_STR_SZ];
  9595. byte authTag[AES_BLOCK_SIZE];
  9596. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  9597. byte macInt[MAX_VERSION_SZ];
  9598. byte algoParamSeq[MAX_SEQ_SZ];
  9599. word32 nonceSz = 0, macIntSz = 0, algoParamSeqSz = 0;
  9600. /* authAttribs */
  9601. byte* flatAuthAttribs = NULL;
  9602. byte authAttribSet[MAX_SET_SZ];
  9603. EncodedAttrib authAttribs[MAX_AUTH_ATTRIBS_SZ];
  9604. word32 authAttribsSz = 0, authAttribsCount = 0;
  9605. word32 authAttribsSetSz = 0;
  9606. byte* aadBuffer = NULL;
  9607. word32 aadBufferSz = 0;
  9608. byte authAttribAadSet[MAX_SET_SZ];
  9609. word32 authAttribsAadSetSz = 0;
  9610. /* unauthAttribs */
  9611. byte* flatUnauthAttribs = NULL;
  9612. byte unauthAttribSet[MAX_SET_SZ];
  9613. EncodedAttrib unauthAttribs[MAX_UNAUTH_ATTRIBS_SZ];
  9614. word32 unauthAttribsSz = 0, unauthAttribsCount = 0;
  9615. word32 unauthAttribsSetSz = 0;
  9616. PKCS7Attrib contentTypeAttrib;
  9617. byte contentTypeValue[MAX_OID_SZ];
  9618. /* contentType OID (1.2.840.113549.1.9.3) */
  9619. const byte contentTypeOid[] =
  9620. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  9621. 0x09, 0x03 };
  9622. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  9623. return BAD_FUNC_ARG;
  9624. if (output == NULL || outputSz == 0)
  9625. return BAD_FUNC_ARG;
  9626. switch (pkcs7->encryptOID) {
  9627. #ifdef HAVE_AESGCM
  9628. #ifdef WOLFSSL_AES_128
  9629. case AES128GCMb:
  9630. break;
  9631. #endif
  9632. #ifdef WOLFSSL_AES_192
  9633. case AES192GCMb:
  9634. break;
  9635. #endif
  9636. #ifdef WOLFSSL_AES_256
  9637. case AES256GCMb:
  9638. break;
  9639. #endif
  9640. #endif
  9641. #ifdef HAVE_AESCCM
  9642. #ifdef WOLFSSL_AES_128
  9643. case AES128CCMb:
  9644. break;
  9645. #endif
  9646. #ifdef WOLFSSL_AES_192
  9647. case AES192CCMb:
  9648. break;
  9649. #endif
  9650. #ifdef WOLFSSL_AES_256
  9651. case AES256CCMb:
  9652. break;
  9653. #endif
  9654. #endif
  9655. default:
  9656. WOLFSSL_MSG("CMS AuthEnvelopedData must use AES-GCM or AES-CCM");
  9657. return BAD_FUNC_ARG;
  9658. }
  9659. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  9660. if (blockKeySz < 0)
  9661. return blockKeySz;
  9662. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  9663. if (blockSz < 0)
  9664. return blockSz;
  9665. /* outer content type */
  9666. ret = wc_SetContentType(AUTH_ENVELOPED_DATA, outerContentType,
  9667. sizeof(outerContentType));
  9668. if (ret < 0)
  9669. return ret;
  9670. outerContentTypeSz = ret;
  9671. /* version, defined as 0 in RFC 5083 */
  9672. verSz = SetMyVersion(0, ver, 0);
  9673. /* generate random content encryption key */
  9674. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  9675. if (ret != 0) {
  9676. return ret;
  9677. }
  9678. /* build RecipientInfo, only if user manually set singleCert and size */
  9679. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  9680. switch (pkcs7->publicKeyOID) {
  9681. #ifndef NO_RSA
  9682. case RSAk:
  9683. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  9684. pkcs7->singleCertSz, 0);
  9685. break;
  9686. #endif
  9687. #ifdef HAVE_ECC
  9688. case ECDSAk:
  9689. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  9690. pkcs7->singleCertSz,
  9691. pkcs7->keyWrapOID,
  9692. pkcs7->keyAgreeOID, pkcs7->ukm,
  9693. pkcs7->ukmSz, 0);
  9694. break;
  9695. #endif
  9696. default:
  9697. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  9698. return BAD_FUNC_ARG;
  9699. };
  9700. if (ret < 0) {
  9701. WOLFSSL_MSG("Failed to create RecipientInfo");
  9702. return ret;
  9703. }
  9704. }
  9705. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  9706. if (recipSz < 0) {
  9707. return ret;
  9708. } else if (recipSz == 0) {
  9709. WOLFSSL_MSG("You must add at least one CMS recipient");
  9710. return PKCS7_RECIP_E;
  9711. }
  9712. recipSetSz = SetSet(recipSz, recipSet);
  9713. /* generate random nonce and IV for encryption */
  9714. switch (pkcs7->encryptOID) {
  9715. #ifdef HAVE_AESGCM
  9716. #ifdef WOLFSSL_AES_128
  9717. case AES128GCMb:
  9718. FALL_THROUGH;
  9719. #endif
  9720. #ifdef WOLFSSL_AES_192
  9721. case AES192GCMb:
  9722. FALL_THROUGH;
  9723. #endif
  9724. #ifdef WOLFSSL_AES_256
  9725. case AES256GCMb:
  9726. #endif
  9727. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  9728. defined(WOLFSSL_AES_256)
  9729. /* GCM nonce is GCM_NONCE_MID_SZ (12) */
  9730. nonceSz = GCM_NONCE_MID_SZ;
  9731. break;
  9732. #endif
  9733. #endif /* HAVE_AESGCM */
  9734. #ifdef HAVE_AESCCM
  9735. #ifdef WOLFSSL_AES_128
  9736. case AES128CCMb:
  9737. FALL_THROUGH;
  9738. #endif
  9739. #ifdef WOLFSSL_AES_192
  9740. case AES192CCMb:
  9741. FALL_THROUGH;
  9742. #endif
  9743. #ifdef WOLFSSL_AES_256
  9744. case AES256CCMb:
  9745. #endif
  9746. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  9747. defined(WOLFSSL_AES_256)
  9748. /* CCM nonce is CCM_NONCE_MIN_SZ (7) */
  9749. nonceSz = CCM_NONCE_MIN_SZ;
  9750. break;
  9751. #endif
  9752. #endif /* HAVE_AESCCM */
  9753. }
  9754. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  9755. if (ret != 0) {
  9756. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9757. return ret;
  9758. }
  9759. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, nonce, nonceSz);
  9760. wc_FreeRng(&rng);
  9761. if (ret != 0) {
  9762. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9763. return ret;
  9764. }
  9765. /* authAttribs: add contentType attrib if needed */
  9766. if (pkcs7->contentOID != DATA) {
  9767. XMEMSET(&contentTypeAttrib, 0, sizeof contentTypeAttrib);
  9768. /* if type is not id-data, contentType attribute MUST be added */
  9769. contentTypeAttrib.oid = contentTypeOid;
  9770. contentTypeAttrib.oidSz = sizeof(contentTypeOid);
  9771. /* try to set from contentOID first, known types */
  9772. ret = wc_SetContentType(pkcs7->contentOID, contentTypeValue,
  9773. sizeof(contentTypeValue));
  9774. if (ret > 0) {
  9775. contentTypeAttrib.value = contentTypeValue;
  9776. contentTypeAttrib.valueSz = ret;
  9777. /* otherwise, try to set from custom content type */
  9778. } else {
  9779. if (pkcs7->contentTypeSz == 0) {
  9780. WOLFSSL_MSG("CMS pkcs7->contentType must be set if "
  9781. "contentOID is not");
  9782. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9783. return BAD_FUNC_ARG;
  9784. }
  9785. contentTypeAttrib.value = pkcs7->contentType;
  9786. contentTypeAttrib.valueSz = pkcs7->contentTypeSz;
  9787. }
  9788. authAttribsSz += EncodeAttributes(authAttribs, 1,
  9789. &contentTypeAttrib, 1);
  9790. authAttribsCount += 1;
  9791. }
  9792. /* authAttribs: add in user authenticated attributes */
  9793. if (pkcs7->authAttribs != NULL && pkcs7->authAttribsSz > 0) {
  9794. authAttribsSz += EncodeAttributes(authAttribs + authAttribsCount,
  9795. MAX_AUTH_ATTRIBS_SZ - authAttribsCount,
  9796. pkcs7->authAttribs,
  9797. pkcs7->authAttribsSz);
  9798. authAttribsCount += pkcs7->authAttribsSz;
  9799. }
  9800. /* authAttribs: flatten authAttribs */
  9801. if (authAttribsSz > 0 && authAttribsCount > 0) {
  9802. flatAuthAttribs = (byte*)XMALLOC(authAttribsSz, pkcs7->heap,
  9803. DYNAMIC_TYPE_PKCS7);
  9804. if (flatAuthAttribs == NULL) {
  9805. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9806. return MEMORY_E;
  9807. }
  9808. FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,
  9809. authAttribsCount);
  9810. authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,
  9811. authAttribSet);
  9812. /* From RFC5083, "For the purpose of constructing the AAD, the
  9813. * IMPLICIT [1] tag in the authAttrs field is not used for the
  9814. * DER encoding: rather a universal SET OF tag is used. */
  9815. authAttribsAadSetSz = SetSet(authAttribsSz, authAttribAadSet);
  9816. /* allocate temp buffer to hold alternate attrib encoding for aad */
  9817. aadBuffer = (byte*)XMALLOC(authAttribsSz + authAttribsAadSetSz,
  9818. pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9819. if (aadBuffer == NULL) {
  9820. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9821. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9822. return MEMORY_E;
  9823. }
  9824. /* build up alternate attrib encoding for aad */
  9825. aadBufferSz = 0;
  9826. XMEMCPY(aadBuffer + aadBufferSz, authAttribAadSet, authAttribsAadSetSz);
  9827. aadBufferSz += authAttribsAadSetSz;
  9828. XMEMCPY(aadBuffer + aadBufferSz, flatAuthAttribs, authAttribsSz);
  9829. aadBufferSz += authAttribsSz;
  9830. }
  9831. /* build up unauthenticated attributes (unauthAttrs) */
  9832. if (pkcs7->unauthAttribsSz > 0) {
  9833. unauthAttribsSz = EncodeAttributes(unauthAttribs + unauthAttribsCount,
  9834. MAX_UNAUTH_ATTRIBS_SZ - unauthAttribsCount,
  9835. pkcs7->unauthAttribs,
  9836. pkcs7->unauthAttribsSz);
  9837. unauthAttribsCount = pkcs7->unauthAttribsSz;
  9838. flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap,
  9839. DYNAMIC_TYPE_PKCS7);
  9840. if (flatUnauthAttribs == NULL) {
  9841. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9842. if (aadBuffer)
  9843. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9844. if (flatAuthAttribs)
  9845. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9846. return MEMORY_E;
  9847. }
  9848. FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,
  9849. unauthAttribsCount);
  9850. unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,
  9851. unauthAttribSet);
  9852. }
  9853. /* AES-GCM/CCM does NOT require padding for plaintext content or
  9854. * AAD inputs RFC 5084 section 3.1 and 3.2, but we must alloc
  9855. * full blocks to ensure crypto only gets full blocks */
  9856. encryptedOutSz = pkcs7->contentSz;
  9857. encryptedAllocSz = (encryptedOutSz % blockSz) ?
  9858. encryptedOutSz + blockSz -
  9859. (encryptedOutSz % blockSz) :
  9860. encryptedOutSz;
  9861. /* Copy content to plain buffer (zero-padded) to encrypt in full,
  9862. * contiguous blocks */
  9863. plain = (byte*)XMALLOC(encryptedAllocSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9864. if (plain == NULL) {
  9865. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9866. if (aadBuffer)
  9867. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9868. if (flatUnauthAttribs)
  9869. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9870. if (flatAuthAttribs)
  9871. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9872. return MEMORY_E;
  9873. }
  9874. XMEMCPY(plain, pkcs7->content, pkcs7->contentSz);
  9875. if ((encryptedAllocSz - encryptedOutSz) > 0) {
  9876. XMEMSET(plain + encryptedOutSz, 0, encryptedAllocSz - encryptedOutSz);
  9877. }
  9878. encryptedContent = (byte*)XMALLOC(encryptedAllocSz, pkcs7->heap,
  9879. DYNAMIC_TYPE_PKCS7);
  9880. if (encryptedContent == NULL) {
  9881. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9882. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9883. if (aadBuffer)
  9884. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9885. if (flatUnauthAttribs)
  9886. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9887. if (flatAuthAttribs)
  9888. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9889. return MEMORY_E;
  9890. }
  9891. /* encrypt content */
  9892. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  9893. pkcs7->cekSz, nonce, nonceSz, aadBuffer, aadBufferSz, authTag,
  9894. sizeof(authTag), plain, encryptedOutSz, encryptedContent,
  9895. pkcs7->devId, pkcs7->heap);
  9896. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9897. plain = NULL;
  9898. if (aadBuffer) {
  9899. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9900. aadBuffer = NULL;
  9901. }
  9902. if (ret != 0) {
  9903. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9904. if (flatUnauthAttribs)
  9905. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9906. if (flatAuthAttribs)
  9907. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9908. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9909. return ret;
  9910. }
  9911. /* EncryptedContentInfo */
  9912. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  9913. sizeof(contentType));
  9914. if (ret < 0) {
  9915. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9916. if (flatUnauthAttribs)
  9917. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9918. if (flatAuthAttribs)
  9919. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9920. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9921. return ret;
  9922. }
  9923. contentTypeSz = ret;
  9924. /* put together nonce OCTET STRING */
  9925. nonceOctetStringSz = SetOctetString(nonceSz, nonceOctetString);
  9926. /* put together aes-ICVlen INTEGER */
  9927. macIntSz = SetMyVersion(sizeof(authTag), macInt, 0);
  9928. /* add nonce and icv len into parameters string RFC5084 */
  9929. algoParamSeqSz = SetSequence(nonceOctetStringSz + nonceSz + macIntSz,
  9930. algoParamSeq);
  9931. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  9932. * adding (nonceOctetStringSz + blockSz + macIntSz) for nonce OCTET STRING
  9933. * and tag size */
  9934. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  9935. oidBlkType, nonceOctetStringSz + nonceSz +
  9936. macIntSz + algoParamSeqSz);
  9937. if (contentEncAlgoSz == 0) {
  9938. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9939. if (flatUnauthAttribs)
  9940. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9941. if (flatAuthAttribs)
  9942. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9943. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9944. return BAD_FUNC_ARG;
  9945. }
  9946. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  9947. encContentOctet);
  9948. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  9949. nonceOctetStringSz + nonceSz + macIntSz +
  9950. algoParamSeqSz + encContentOctetSz +
  9951. encryptedOutSz, encContentSeq);
  9952. macOctetStringSz = SetOctetString(sizeof(authTag), macOctetString);
  9953. /* keep track of sizes for outer wrapper layering */
  9954. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  9955. contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz +
  9956. algoParamSeqSz + encContentOctetSz + encryptedOutSz +
  9957. authAttribsSz + authAttribsSetSz + macOctetStringSz +
  9958. sizeof(authTag) + unauthAttribsSz + unauthAttribsSetSz;
  9959. /* EnvelopedData */
  9960. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  9961. totalSz += envDataSeqSz;
  9962. /* outer content */
  9963. outerContentSz = SetExplicit(0, totalSz, outerContent);
  9964. totalSz += outerContentTypeSz;
  9965. totalSz += outerContentSz;
  9966. /* ContentInfo */
  9967. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  9968. totalSz += contentInfoSeqSz;
  9969. if (totalSz > (int)outputSz) {
  9970. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  9971. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9972. if (flatUnauthAttribs)
  9973. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9974. if (flatAuthAttribs)
  9975. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9976. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9977. return BUFFER_E;
  9978. }
  9979. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  9980. idx += contentInfoSeqSz;
  9981. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  9982. idx += outerContentTypeSz;
  9983. XMEMCPY(output + idx, outerContent, outerContentSz);
  9984. idx += outerContentSz;
  9985. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  9986. idx += envDataSeqSz;
  9987. XMEMCPY(output + idx, ver, verSz);
  9988. idx += verSz;
  9989. XMEMCPY(output + idx, recipSet, recipSetSz);
  9990. idx += recipSetSz;
  9991. /* copy in recipients from list */
  9992. tmpRecip = pkcs7->recipList;
  9993. while (tmpRecip != NULL) {
  9994. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  9995. idx += tmpRecip->recipSz;
  9996. tmpRecip = tmpRecip->next;
  9997. }
  9998. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9999. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  10000. idx += encContentSeqSz;
  10001. XMEMCPY(output + idx, contentType, contentTypeSz);
  10002. idx += contentTypeSz;
  10003. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  10004. idx += contentEncAlgoSz;
  10005. XMEMCPY(output + idx, algoParamSeq, algoParamSeqSz);
  10006. idx += algoParamSeqSz;
  10007. XMEMCPY(output + idx, nonceOctetString, nonceOctetStringSz);
  10008. idx += nonceOctetStringSz;
  10009. XMEMCPY(output + idx, nonce, nonceSz);
  10010. idx += nonceSz;
  10011. XMEMCPY(output + idx, macInt, macIntSz);
  10012. idx += macIntSz;
  10013. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  10014. idx += encContentOctetSz;
  10015. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  10016. idx += encryptedOutSz;
  10017. /* authenticated attributes */
  10018. if (flatAuthAttribs && authAttribsSz > 0) {
  10019. XMEMCPY(output + idx, authAttribSet, authAttribsSetSz);
  10020. idx += authAttribsSetSz;
  10021. XMEMCPY(output + idx, flatAuthAttribs, authAttribsSz);
  10022. idx += authAttribsSz;
  10023. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10024. }
  10025. XMEMCPY(output + idx, macOctetString, macOctetStringSz);
  10026. idx += macOctetStringSz;
  10027. XMEMCPY(output + idx, authTag, sizeof(authTag));
  10028. idx += sizeof(authTag);
  10029. /* unauthenticated attributes */
  10030. if (unauthAttribsSz > 0) {
  10031. XMEMCPY(output + idx, unauthAttribSet, unauthAttribsSetSz);
  10032. idx += unauthAttribsSetSz;
  10033. XMEMCPY(output + idx, flatUnauthAttribs, unauthAttribsSz);
  10034. idx += unauthAttribsSz;
  10035. }
  10036. if (flatUnauthAttribs != NULL) {
  10037. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10038. }
  10039. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10040. return idx;
  10041. #else
  10042. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  10043. (void)pkcs7;
  10044. (void)output;
  10045. (void)outputSz;
  10046. return NOT_COMPILED_IN;
  10047. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  10048. }
  10049. /* unwrap and decrypt PKCS#7 AuthEnvelopedData object, return decoded size */
  10050. WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
  10051. word32 inSz, byte* output,
  10052. word32 outputSz)
  10053. {
  10054. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  10055. int recipFound = 0;
  10056. int ret = 0, length = 0;
  10057. word32 idx = 0;
  10058. #ifndef NO_PKCS7_STREAM
  10059. word32 tmpIdx = 0;
  10060. #endif
  10061. word32 contentType = 0, encOID = 0;
  10062. word32 decryptedKeySz = 0;
  10063. byte* pkiMsg = in;
  10064. word32 pkiMsgSz = inSz;
  10065. int expBlockSz = 0, blockKeySz = 0;
  10066. byte authTag[AES_BLOCK_SIZE];
  10067. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  10068. int nonceSz = 0, authTagSz = 0, macSz = 0;
  10069. #ifdef WOLFSSL_SMALL_STACK
  10070. byte* decryptedKey = NULL;
  10071. #else
  10072. byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
  10073. #endif
  10074. int encryptedContentSz = 0;
  10075. int encryptedAllocSz = 0;
  10076. byte* encryptedContent = NULL;
  10077. int explicitOctet = 0;
  10078. byte authAttribSetByte = 0;
  10079. byte* encodedAttribs = NULL;
  10080. word32 encodedAttribIdx = 0, encodedAttribSz = 0;
  10081. byte* authAttrib = NULL;
  10082. int authAttribSz = 0;
  10083. word32 localIdx;
  10084. byte tag;
  10085. if (pkcs7 == NULL)
  10086. return BAD_FUNC_ARG;
  10087. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  10088. output == NULL || outputSz == 0)
  10089. return BAD_FUNC_ARG;
  10090. #ifndef NO_PKCS7_STREAM
  10091. if (pkcs7->stream == NULL) {
  10092. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  10093. return ret;
  10094. }
  10095. }
  10096. #endif
  10097. #ifndef WOLFSSL_SMALL_STACK
  10098. XMEMSET(decryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
  10099. #endif
  10100. switch (pkcs7->state) {
  10101. case WC_PKCS7_START:
  10102. case WC_PKCS7_INFOSET_START:
  10103. case WC_PKCS7_INFOSET_STAGE1:
  10104. case WC_PKCS7_INFOSET_STAGE2:
  10105. case WC_PKCS7_INFOSET_END:
  10106. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  10107. &idx, AUTH_ENVELOPED_DATA);
  10108. if (ret < 0)
  10109. break;
  10110. #ifndef NO_PKCS7_STREAM
  10111. tmpIdx = idx;
  10112. #endif
  10113. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_2);
  10114. FALL_THROUGH;
  10115. case WC_PKCS7_AUTHENV_2:
  10116. #ifndef NO_PKCS7_STREAM
  10117. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10118. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  10119. break;
  10120. }
  10121. #endif
  10122. #ifdef WOLFSSL_SMALL_STACK
  10123. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  10124. DYNAMIC_TYPE_PKCS7);
  10125. if (decryptedKey == NULL) {
  10126. ret = MEMORY_E;
  10127. break;
  10128. }
  10129. else {
  10130. XMEMSET(decryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
  10131. }
  10132. #ifndef NO_PKCS7_STREAM
  10133. pkcs7->stream->key = decryptedKey;
  10134. #endif
  10135. #endif
  10136. FALL_THROUGH;
  10137. case WC_PKCS7_DECRYPT_KTRI:
  10138. case WC_PKCS7_DECRYPT_KTRI_2:
  10139. case WC_PKCS7_DECRYPT_KTRI_3:
  10140. case WC_PKCS7_DECRYPT_KARI:
  10141. case WC_PKCS7_DECRYPT_KEKRI:
  10142. case WC_PKCS7_DECRYPT_PWRI:
  10143. case WC_PKCS7_DECRYPT_ORI:
  10144. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  10145. #ifdef WOLFSSL_SMALL_STACK
  10146. #ifndef NO_PKCS7_STREAM
  10147. decryptedKey = pkcs7->stream->key;
  10148. #endif
  10149. #endif
  10150. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  10151. decryptedKey, &decryptedKeySz,
  10152. &recipFound);
  10153. if (ret != 0) {
  10154. break;
  10155. }
  10156. if (recipFound == 0) {
  10157. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  10158. ret = PKCS7_RECIP_E;
  10159. break;
  10160. }
  10161. #ifndef NO_PKCS7_STREAM
  10162. tmpIdx = idx;
  10163. #endif
  10164. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3);
  10165. FALL_THROUGH;
  10166. case WC_PKCS7_AUTHENV_3:
  10167. #ifndef NO_PKCS7_STREAM
  10168. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  10169. MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ,
  10170. &pkiMsg, &idx)) != 0) {
  10171. break;
  10172. }
  10173. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10174. #endif
  10175. /* remove EncryptedContentInfo */
  10176. if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  10177. ret = ASN_PARSE_E;
  10178. }
  10179. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10180. pkiMsgSz) < 0) {
  10181. ret = ASN_PARSE_E;
  10182. }
  10183. if (ret == 0) {
  10184. pkcs7->contentOID = contentType;
  10185. }
  10186. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  10187. pkiMsgSz) < 0) {
  10188. ret = ASN_PARSE_E;
  10189. }
  10190. if (ret == 0) {
  10191. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  10192. if (blockKeySz < 0) {
  10193. ret = blockKeySz;
  10194. }
  10195. }
  10196. if (ret == 0) {
  10197. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  10198. if (expBlockSz < 0) {
  10199. ret = expBlockSz;
  10200. }
  10201. }
  10202. /* get nonce, stored in OPTIONAL parameter of AlgoID
  10203. * RFC 5084 Appendix lists GCM parameters as
  10204. * seq
  10205. * ---->octet string with nonce
  10206. * ---->aes gcm icvlen
  10207. */
  10208. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  10209. ret = ASN_PARSE_E;
  10210. }
  10211. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  10212. WOLFSSL_MSG("Optional parameters is not wrapped in a sequence");
  10213. ret = ASN_PARSE_E;
  10214. }
  10215. if (ret < 0)
  10216. break;
  10217. #ifndef NO_PKCS7_STREAM
  10218. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10219. break;
  10220. }
  10221. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0);
  10222. #endif
  10223. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4);
  10224. FALL_THROUGH;
  10225. case WC_PKCS7_AUTHENV_4:
  10226. #ifndef NO_PKCS7_STREAM
  10227. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10228. MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ,
  10229. &pkiMsg, &idx)) != 0) {
  10230. break;
  10231. }
  10232. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10233. #endif
  10234. /* get length of optional parameter sequence */
  10235. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  10236. ret = ASN_PARSE_E;
  10237. }
  10238. /* get nonce from octet string */
  10239. if (ret == 0 &&
  10240. GetOctetString(pkiMsg, &idx, &nonceSz, pkiMsgSz) < 0) {
  10241. ret = ASN_PARSE_E;
  10242. }
  10243. if (ret == 0 && nonceSz > (int)sizeof(nonce)) {
  10244. WOLFSSL_MSG("AuthEnvelopedData nonce too large for buffer");
  10245. ret = ASN_PARSE_E;
  10246. }
  10247. if (ret == 0) {
  10248. XMEMCPY(nonce, &pkiMsg[idx], nonceSz);
  10249. idx += nonceSz;
  10250. }
  10251. /* get mac size, also stored in OPTIONAL parameter of AlgoID */
  10252. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &macSz, pkiMsgSz) < 0) {
  10253. ret = ASN_PARSE_E;
  10254. }
  10255. if (ret == 0) {
  10256. explicitOctet = 0;
  10257. localIdx = idx;
  10258. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  10259. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
  10260. explicitOctet = 1;
  10261. /* read encryptedContent, cont[0] */
  10262. ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);
  10263. }
  10264. if (ret == 0 &&
  10265. tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  10266. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  10267. ret = ASN_PARSE_E;
  10268. }
  10269. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  10270. pkiMsgSz) <= 0) {
  10271. ret = ASN_PARSE_E;
  10272. }
  10273. if (explicitOctet) {
  10274. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  10275. ret = ASN_PARSE_E;
  10276. }
  10277. if (ret == 0 && tag != ASN_OCTET_STRING) {
  10278. ret = ASN_PARSE_E;
  10279. }
  10280. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  10281. pkiMsgSz) <= 0) {
  10282. ret = ASN_PARSE_E;
  10283. }
  10284. }
  10285. if (ret < 0)
  10286. break;
  10287. #ifndef NO_PKCS7_STREAM
  10288. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10289. break;
  10290. }
  10291. /* store nonce for later */
  10292. if (nonceSz > 0) {
  10293. pkcs7->stream->nonceSz = nonceSz;
  10294. pkcs7->stream->nonce = (byte*)XMALLOC(nonceSz, pkcs7->heap,
  10295. DYNAMIC_TYPE_PKCS7);
  10296. if (pkcs7->stream->nonce == NULL) {
  10297. ret = MEMORY_E;
  10298. break;
  10299. }
  10300. else {
  10301. XMEMCPY(pkcs7->stream->nonce, nonce, nonceSz);
  10302. }
  10303. }
  10304. pkcs7->stream->expected = encryptedContentSz;
  10305. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz,
  10306. encryptedContentSz);
  10307. #endif
  10308. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5);
  10309. FALL_THROUGH;
  10310. case WC_PKCS7_AUTHENV_5:
  10311. #ifndef NO_PKCS7_STREAM
  10312. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10313. ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected,
  10314. &pkiMsg, &idx)) != 0) {
  10315. break;
  10316. }
  10317. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10318. encryptedContentSz = pkcs7->stream->expected;
  10319. #else
  10320. pkiMsgSz = inSz;
  10321. #endif
  10322. if (expBlockSz == 0) {
  10323. #ifndef NO_PKCS7_STREAM
  10324. wc_PKCS7_StreamGetVar(pkcs7, &encOID, NULL, NULL);
  10325. #endif
  10326. if (encOID == 0)
  10327. expBlockSz = 1;
  10328. else {
  10329. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  10330. if (expBlockSz < 0) {
  10331. ret = expBlockSz;
  10332. break;
  10333. } else if (expBlockSz == 0)
  10334. expBlockSz = 1;
  10335. }
  10336. }
  10337. /* AES-GCM/CCM does NOT require padding for plaintext content or
  10338. * AAD inputs RFC 5084 section 3.1 and 3.2, but we must alloc
  10339. * full blocks to ensure crypto only gets full blocks */
  10340. encryptedAllocSz = (encryptedContentSz % expBlockSz) ?
  10341. encryptedContentSz + expBlockSz -
  10342. (encryptedContentSz % expBlockSz) :
  10343. encryptedContentSz;
  10344. encryptedContent = (byte*)XMALLOC(encryptedAllocSz, pkcs7->heap,
  10345. DYNAMIC_TYPE_PKCS7);
  10346. if (ret == 0 && encryptedContent == NULL) {
  10347. ret = MEMORY_E;
  10348. }
  10349. if (ret == 0) {
  10350. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  10351. idx += encryptedContentSz;
  10352. }
  10353. #ifndef NO_PKCS7_STREAM
  10354. pkcs7->stream->bufferPt = encryptedContent;
  10355. #endif
  10356. /* may have IMPLICIT [1] authenticatedAttributes */
  10357. localIdx = idx;
  10358. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  10359. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  10360. encodedAttribIdx = idx;
  10361. encodedAttribs = pkiMsg + idx;
  10362. idx++;
  10363. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0)
  10364. ret = ASN_PARSE_E;
  10365. #ifndef NO_PKCS7_STREAM
  10366. pkcs7->stream->expected = length;
  10367. #endif
  10368. encodedAttribSz = length + (idx - encodedAttribIdx);
  10369. if (ret != 0)
  10370. break;
  10371. #ifndef NO_PKCS7_STREAM
  10372. if (encodedAttribSz > 0) {
  10373. pkcs7->stream->aadSz = encodedAttribSz;
  10374. pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz,
  10375. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10376. if (pkcs7->stream->aad == NULL) {
  10377. ret = MEMORY_E;
  10378. break;
  10379. }
  10380. else {
  10381. XMEMCPY(pkcs7->stream->aad, encodedAttribs,
  10382. (idx - encodedAttribIdx));
  10383. }
  10384. }
  10385. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10386. break;
  10387. }
  10388. #endif
  10389. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRB);
  10390. }
  10391. else {
  10392. #ifndef NO_PKCS7_STREAM
  10393. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10394. break;
  10395. }
  10396. #endif
  10397. goto authenv_atrbend; /* jump over attribute cases */
  10398. }
  10399. FALL_THROUGH;
  10400. case WC_PKCS7_AUTHENV_ATRB:
  10401. #ifndef NO_PKCS7_STREAM
  10402. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10403. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10404. return ret;
  10405. }
  10406. length = pkcs7->stream->expected;
  10407. encodedAttribs = pkcs7->stream->aad;
  10408. #endif
  10409. /* save pointer and length */
  10410. authAttrib = &pkiMsg[idx];
  10411. authAttribSz = length;
  10412. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) {
  10413. WOLFSSL_MSG("Error parsing authenticated attributes");
  10414. ret = ASN_PARSE_E;
  10415. break;
  10416. }
  10417. idx += length;
  10418. #ifndef NO_PKCS7_STREAM
  10419. if (encodedAttribSz > 0) {
  10420. XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - length),
  10421. authAttrib, authAttribSz);
  10422. }
  10423. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10424. break;
  10425. }
  10426. #endif
  10427. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND);
  10428. FALL_THROUGH;
  10429. case WC_PKCS7_AUTHENV_ATRBEND:
  10430. authenv_atrbend:
  10431. #ifndef NO_PKCS7_STREAM
  10432. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10433. ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  10434. return ret;
  10435. }
  10436. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10437. if (pkcs7->stream->aadSz > 0) {
  10438. encodedAttribSz = pkcs7->stream->aadSz;
  10439. encodedAttribs = pkcs7->stream->aad;
  10440. }
  10441. #endif
  10442. /* get authTag OCTET STRING */
  10443. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  10444. ret = ASN_PARSE_E;
  10445. }
  10446. if (ret == 0 && tag != ASN_OCTET_STRING) {
  10447. ret = ASN_PARSE_E;
  10448. }
  10449. if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) {
  10450. ret = ASN_PARSE_E;
  10451. }
  10452. if (ret == 0 && authTagSz > (int)sizeof(authTag)) {
  10453. WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer");
  10454. ret = ASN_PARSE_E;
  10455. }
  10456. if (ret == 0) {
  10457. XMEMCPY(authTag, &pkiMsg[idx], authTagSz);
  10458. idx += authTagSz;
  10459. }
  10460. if (ret == 0 && authAttrib != NULL) {
  10461. /* temporarily swap authAttribs byte[0] to SET OF instead of
  10462. * IMPLICIT [1], for aad calculation */
  10463. authAttribSetByte = encodedAttribs[0];
  10464. encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED;
  10465. }
  10466. if (ret < 0)
  10467. break;
  10468. #ifndef NO_PKCS7_STREAM
  10469. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10470. break;
  10471. }
  10472. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  10473. pkcs7->stream->totalRd) + pkcs7->stream->length;
  10474. /* store tag for later */
  10475. if (authTagSz > 0) {
  10476. pkcs7->stream->tagSz = authTagSz;
  10477. pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap,
  10478. DYNAMIC_TYPE_PKCS7);
  10479. if (pkcs7->stream->tag == NULL) {
  10480. ret = MEMORY_E;
  10481. break;
  10482. }
  10483. else {
  10484. XMEMCPY(pkcs7->stream->tag, authTag, authTagSz);
  10485. }
  10486. }
  10487. #endif
  10488. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_6);
  10489. FALL_THROUGH;
  10490. case WC_PKCS7_AUTHENV_6:
  10491. #ifndef NO_PKCS7_STREAM
  10492. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10493. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10494. break;
  10495. }
  10496. /* restore all variables needed */
  10497. if (pkcs7->stream->nonceSz > 0) {
  10498. nonceSz = pkcs7->stream->nonceSz;
  10499. if (nonceSz > GCM_NONCE_MID_SZ) {
  10500. WOLFSSL_MSG("PKCS7 saved nonce is too large");
  10501. ret = BUFFER_E;
  10502. break;
  10503. }
  10504. else {
  10505. XMEMCPY(nonce, pkcs7->stream->nonce, nonceSz);
  10506. }
  10507. }
  10508. if (pkcs7->stream->tagSz > 0) {
  10509. authTagSz = pkcs7->stream->tagSz;
  10510. if (authTagSz > AES_BLOCK_SIZE) {
  10511. WOLFSSL_MSG("PKCS7 saved tag is too large");
  10512. ret = BUFFER_E;
  10513. break;
  10514. }
  10515. else {
  10516. XMEMCPY(authTag, pkcs7->stream->tag, authTagSz);
  10517. }
  10518. }
  10519. if (pkcs7->stream->aadSz > 0) {
  10520. encodedAttribSz = pkcs7->stream->aadSz;
  10521. encodedAttribs = pkcs7->stream->aad;
  10522. }
  10523. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz,
  10524. &encryptedContentSz);
  10525. encryptedContent = pkcs7->stream->bufferPt;
  10526. #ifdef WOLFSSL_SMALL_STACK
  10527. decryptedKey = pkcs7->stream->key;
  10528. #endif
  10529. #endif
  10530. /* decrypt encryptedContent */
  10531. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  10532. blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,
  10533. authTag, authTagSz, encryptedContent, encryptedContentSz,
  10534. encryptedContent, pkcs7->devId, pkcs7->heap);
  10535. if (ret != 0) {
  10536. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10537. return ret;
  10538. }
  10539. if (authAttrib != NULL) {
  10540. /* restore authAttrib IMPLICIT [1] */
  10541. encodedAttribs[0] = authAttribSetByte;
  10542. }
  10543. /* copy plaintext to output */
  10544. XMEMCPY(output, encryptedContent, encryptedContentSz);
  10545. /* free memory, zero out keys */
  10546. ForceZero(encryptedContent, encryptedContentSz);
  10547. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10548. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  10549. #ifdef WOLFSSL_SMALL_STACK
  10550. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10551. decryptedKey = NULL;
  10552. #ifndef NO_PKCS7_STREAM
  10553. pkcs7->stream->key = NULL;
  10554. #endif
  10555. #endif
  10556. ret = encryptedContentSz;
  10557. #ifndef NO_PKCS7_STREAM
  10558. wc_PKCS7_ResetStream(pkcs7);
  10559. #endif
  10560. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10561. break;
  10562. default:
  10563. WOLFSSL_MSG("Unknown PKCS7 state");
  10564. ret = BAD_FUNC_ARG;
  10565. }
  10566. #ifdef WOLFSSL_SMALL_STACK
  10567. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  10568. if (decryptedKey != NULL) {
  10569. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  10570. }
  10571. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10572. }
  10573. #endif
  10574. #ifndef NO_PKCS7_STREAM
  10575. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  10576. wc_PKCS7_ResetStream(pkcs7);
  10577. }
  10578. #endif
  10579. return ret;
  10580. #else
  10581. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  10582. (void)pkcs7;
  10583. (void)in;
  10584. (void)inSz;
  10585. (void)output;
  10586. (void)outputSz;
  10587. return NOT_COMPILED_IN;
  10588. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  10589. }
  10590. #ifndef NO_PKCS7_ENCRYPTED_DATA
  10591. /* build PKCS#7 encryptedData content type, return encrypted size */
  10592. int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  10593. {
  10594. int ret, idx = 0;
  10595. int totalSz, padSz, encryptedOutSz;
  10596. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  10597. byte contentInfoSeq[MAX_SEQ_SZ];
  10598. byte outerContentType[MAX_ALGO_SZ];
  10599. byte outerContent[MAX_SEQ_SZ];
  10600. int encDataSeqSz, verSz, blockSz;
  10601. byte encDataSeq[MAX_SEQ_SZ];
  10602. byte ver[MAX_VERSION_SZ];
  10603. byte* plain = NULL;
  10604. byte* encryptedContent = NULL;
  10605. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  10606. int contentEncAlgoSz, ivOctetStringSz;
  10607. byte encContentSeq[MAX_SEQ_SZ];
  10608. byte contentType[MAX_OID_SZ];
  10609. byte contentEncAlgo[MAX_ALGO_SZ];
  10610. byte tmpIv[MAX_CONTENT_IV_SIZE];
  10611. byte ivOctetString[MAX_OCTET_STR_SZ];
  10612. byte encContentOctet[MAX_OCTET_STR_SZ];
  10613. byte attribSet[MAX_SET_SZ];
  10614. EncodedAttrib* attribs = NULL;
  10615. word32 attribsSz;
  10616. word32 attribsCount;
  10617. word32 attribsSetSz;
  10618. byte* flatAttribs = NULL;
  10619. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  10620. pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
  10621. pkcs7->encryptionKeySz == 0)
  10622. return BAD_FUNC_ARG;
  10623. if (output == NULL || outputSz == 0)
  10624. return BAD_FUNC_ARG;
  10625. if (pkcs7->version == 3) {
  10626. verSz = SetMyVersion(0, ver, 0);
  10627. outerContentTypeSz = 0;
  10628. }
  10629. else {
  10630. /* outer content type */
  10631. ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType,
  10632. sizeof(outerContentType));
  10633. if (ret < 0)
  10634. return ret;
  10635. outerContentTypeSz = ret;
  10636. /* version, 2 if unprotectedAttrs present, 0 if absent */
  10637. if (pkcs7->unprotectedAttribsSz > 0) {
  10638. verSz = SetMyVersion(2, ver, 0);
  10639. } else {
  10640. verSz = SetMyVersion(0, ver, 0);
  10641. }
  10642. }
  10643. /* EncryptedContentInfo */
  10644. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  10645. sizeof(contentType));
  10646. if (ret < 0)
  10647. return ret;
  10648. contentTypeSz = ret;
  10649. /* allocate encrypted content buffer, do PKCS#7 padding */
  10650. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  10651. if (blockSz < 0)
  10652. return blockSz;
  10653. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  10654. if (padSz < 0)
  10655. return padSz;
  10656. encryptedOutSz = pkcs7->contentSz + padSz;
  10657. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  10658. DYNAMIC_TYPE_PKCS7);
  10659. if (plain == NULL)
  10660. return MEMORY_E;
  10661. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  10662. encryptedOutSz, blockSz);
  10663. if (ret < 0) {
  10664. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10665. return ret;
  10666. }
  10667. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  10668. DYNAMIC_TYPE_PKCS7);
  10669. if (encryptedContent == NULL) {
  10670. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10671. return MEMORY_E;
  10672. }
  10673. /* put together IV OCTET STRING */
  10674. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  10675. /* build up ContentEncryptionAlgorithmIdentifier sequence,
  10676. adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  10677. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  10678. oidBlkType, ivOctetStringSz + blockSz);
  10679. if (contentEncAlgoSz == 0) {
  10680. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10681. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10682. return BAD_FUNC_ARG;
  10683. }
  10684. /* encrypt content */
  10685. WOLFSSL_MSG("Encrypting the content");
  10686. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, blockSz);
  10687. if (ret != 0) {
  10688. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10689. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10690. return ret;
  10691. }
  10692. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
  10693. pkcs7->encryptionKeySz, tmpIv, blockSz, NULL, 0, NULL, 0,
  10694. plain, encryptedOutSz, encryptedContent,
  10695. pkcs7->devId, pkcs7->heap);
  10696. if (ret != 0) {
  10697. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10698. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10699. return ret;
  10700. }
  10701. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
  10702. encryptedOutSz, encContentOctet);
  10703. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  10704. ivOctetStringSz + blockSz +
  10705. encContentOctetSz + encryptedOutSz,
  10706. encContentSeq);
  10707. /* optional UnprotectedAttributes */
  10708. if (pkcs7->unprotectedAttribsSz != 0) {
  10709. if (pkcs7->unprotectedAttribs == NULL) {
  10710. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10711. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10712. return BAD_FUNC_ARG;
  10713. }
  10714. attribs = (EncodedAttrib*)XMALLOC(
  10715. sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,
  10716. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10717. if (attribs == NULL) {
  10718. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10719. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10720. return MEMORY_E;
  10721. }
  10722. attribsCount = pkcs7->unprotectedAttribsSz;
  10723. attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,
  10724. pkcs7->unprotectedAttribs,
  10725. pkcs7->unprotectedAttribsSz);
  10726. flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10727. if (flatAttribs == NULL) {
  10728. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10729. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10730. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10731. return MEMORY_E;
  10732. }
  10733. FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);
  10734. attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
  10735. } else {
  10736. attribsSz = 0;
  10737. attribsSetSz = 0;
  10738. }
  10739. /* keep track of sizes for outer wrapper layering */
  10740. totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
  10741. ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +
  10742. attribsSz + attribsSetSz;
  10743. /* EncryptedData */
  10744. encDataSeqSz = SetSequence(totalSz, encDataSeq);
  10745. totalSz += encDataSeqSz;
  10746. if (pkcs7->version != 3) {
  10747. /* outer content */
  10748. outerContentSz = SetExplicit(0, totalSz, outerContent);
  10749. totalSz += outerContentTypeSz;
  10750. totalSz += outerContentSz;
  10751. /* ContentInfo */
  10752. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  10753. totalSz += contentInfoSeqSz;
  10754. } else {
  10755. contentInfoSeqSz = 0;
  10756. outerContentSz = 0;
  10757. }
  10758. if (totalSz > (int)outputSz) {
  10759. WOLFSSL_MSG("PKCS#7 output buffer too small");
  10760. if (attribs != NULL)
  10761. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10762. if (flatAttribs != NULL)
  10763. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10764. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10765. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10766. return BUFFER_E;
  10767. }
  10768. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  10769. idx += contentInfoSeqSz;
  10770. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  10771. idx += outerContentTypeSz;
  10772. XMEMCPY(output + idx, outerContent, outerContentSz);
  10773. idx += outerContentSz;
  10774. XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
  10775. idx += encDataSeqSz;
  10776. XMEMCPY(output + idx, ver, verSz);
  10777. idx += verSz;
  10778. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  10779. idx += encContentSeqSz;
  10780. XMEMCPY(output + idx, contentType, contentTypeSz);
  10781. idx += contentTypeSz;
  10782. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  10783. idx += contentEncAlgoSz;
  10784. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  10785. idx += ivOctetStringSz;
  10786. XMEMCPY(output + idx, tmpIv, blockSz);
  10787. idx += blockSz;
  10788. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  10789. idx += encContentOctetSz;
  10790. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  10791. idx += encryptedOutSz;
  10792. if (pkcs7->unprotectedAttribsSz != 0) {
  10793. XMEMCPY(output + idx, attribSet, attribsSetSz);
  10794. idx += attribsSetSz;
  10795. XMEMCPY(output + idx, flatAttribs, attribsSz);
  10796. idx += attribsSz;
  10797. }
  10798. if (attribs != NULL)
  10799. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10800. if (flatAttribs != NULL)
  10801. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10802. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10803. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10804. return idx;
  10805. }
  10806. /* decode and store unprotected attributes in PKCS7->decodedAttrib. Return
  10807. * 0 on success, negative on error. User must call wc_PKCS7_Free(). */
  10808. static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
  10809. word32 pkiMsgSz, word32* inOutIdx)
  10810. {
  10811. int ret, attribLen;
  10812. word32 idx;
  10813. byte tag;
  10814. if (pkcs7 == NULL || pkiMsg == NULL ||
  10815. pkiMsgSz == 0 || inOutIdx == NULL)
  10816. return BAD_FUNC_ARG;
  10817. idx = *inOutIdx;
  10818. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10819. return ASN_PARSE_E;
  10820. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
  10821. return ASN_PARSE_E;
  10822. if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
  10823. return ASN_PARSE_E;
  10824. /* loop through attributes */
  10825. if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {
  10826. return ret;
  10827. }
  10828. *inOutIdx = idx;
  10829. return 0;
  10830. }
  10831. /* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */
  10832. int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
  10833. byte* output, word32 outputSz)
  10834. {
  10835. int ret = 0, version, length = 0, haveAttribs = 0;
  10836. word32 idx = 0;
  10837. #ifndef NO_PKCS7_STREAM
  10838. word32 tmpIdx = 0;
  10839. #endif
  10840. word32 contentType = 0, encOID = 0;
  10841. int expBlockSz = 0;
  10842. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  10843. byte *tmpIv = tmpIvBuf;
  10844. int encryptedContentSz = 0;
  10845. byte padLen = 0;
  10846. byte* encryptedContent = NULL;
  10847. byte* pkiMsg = in;
  10848. word32 pkiMsgSz = inSz;
  10849. byte tag;
  10850. if (pkcs7 == NULL ||
  10851. ((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
  10852. pkcs7->decryptionCb == NULL))
  10853. return BAD_FUNC_ARG;
  10854. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  10855. output == NULL || outputSz == 0)
  10856. return BAD_FUNC_ARG;
  10857. #ifndef NO_PKCS7_STREAM
  10858. (void)tmpIv; /* help out static analysis */
  10859. if (pkcs7->stream == NULL) {
  10860. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  10861. return ret;
  10862. }
  10863. }
  10864. #endif
  10865. switch (pkcs7->state) {
  10866. case WC_PKCS7_START:
  10867. #ifndef NO_PKCS7_STREAM
  10868. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  10869. MAX_ALGO_SZ, &pkiMsg, &idx)) != 0) {
  10870. return ret;
  10871. }
  10872. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  10873. return ret;
  10874. }
  10875. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10876. #endif
  10877. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10878. NO_USER_CHECK) < 0)
  10879. ret = ASN_PARSE_E;
  10880. if (pkcs7->version != 3) { /* ContentInfo not in firmware bundles */
  10881. /* read past ContentInfo, verify type is encrypted-data */
  10882. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10883. pkiMsgSz) < 0)
  10884. ret = ASN_PARSE_E;
  10885. if (ret == 0 && contentType != ENCRYPTED_DATA) {
  10886. WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
  10887. ret = PKCS7_OID_E;
  10888. }
  10889. }
  10890. if (ret != 0) break;
  10891. #ifndef NO_PKCS7_STREAM
  10892. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10893. break;
  10894. }
  10895. #endif
  10896. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE2);
  10897. FALL_THROUGH;
  10898. /* end of stage 1 */
  10899. case WC_PKCS7_STAGE2:
  10900. #ifndef NO_PKCS7_STREAM
  10901. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10902. MAX_LENGTH_SZ + MAX_SEQ_SZ + ASN_TAG_SZ, &pkiMsg,
  10903. &idx)) != 0) {
  10904. return ret;
  10905. }
  10906. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10907. #endif
  10908. if (pkcs7->version != 3) {
  10909. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10910. ret = ASN_PARSE_E;
  10911. if (ret == 0 && tag !=
  10912. (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  10913. ret = ASN_PARSE_E;
  10914. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10915. NO_USER_CHECK) < 0)
  10916. ret = ASN_PARSE_E;
  10917. /* remove EncryptedData and version */
  10918. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10919. NO_USER_CHECK) < 0)
  10920. ret = ASN_PARSE_E;
  10921. }
  10922. if (ret != 0) break;
  10923. #ifndef NO_PKCS7_STREAM
  10924. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10925. break;
  10926. }
  10927. #endif
  10928. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE3);
  10929. FALL_THROUGH;
  10930. /* end of stage 2 */
  10931. case WC_PKCS7_STAGE3:
  10932. #ifndef NO_PKCS7_STREAM
  10933. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10934. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ * 2,
  10935. &pkiMsg, &idx)) != 0) {
  10936. return ret;
  10937. }
  10938. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10939. #endif
  10940. /* get version, check later */
  10941. haveAttribs = 0;
  10942. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  10943. ret = ASN_PARSE_E;
  10944. /* remove EncryptedContentInfo */
  10945. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10946. NO_USER_CHECK) < 0)
  10947. ret = ASN_PARSE_E;
  10948. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10949. pkiMsgSz) < 0)
  10950. ret = ASN_PARSE_E;
  10951. if (ret == 0) {
  10952. pkcs7->contentOID = contentType;
  10953. }
  10954. if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  10955. pkiMsgSz)) < 0)
  10956. ret = ASN_PARSE_E;
  10957. if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID)) < 0)
  10958. ret = expBlockSz;
  10959. if (ret != 0) break;
  10960. #ifndef NO_PKCS7_STREAM
  10961. /* store expBlockSz for later */
  10962. pkcs7->stream->varOne = expBlockSz;
  10963. pkcs7->stream->varTwo = encOID;
  10964. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10965. break;
  10966. }
  10967. /* store version for later */
  10968. pkcs7->stream->vers = version;
  10969. #endif
  10970. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE4);
  10971. FALL_THROUGH;
  10972. /* end of stage 3 */
  10973. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  10974. case WC_PKCS7_STAGE4:
  10975. #ifndef NO_PKCS7_STREAM
  10976. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10977. ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  10978. return ret;
  10979. }
  10980. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10981. /* restore saved variables */
  10982. expBlockSz = pkcs7->stream->varOne;
  10983. #endif
  10984. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10985. ret = ASN_PARSE_E;
  10986. if (ret == 0 && tag != ASN_OCTET_STRING)
  10987. ret = ASN_PARSE_E;
  10988. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10989. ret = ASN_PARSE_E;
  10990. if (ret == 0 && length != expBlockSz) {
  10991. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  10992. ret = ASN_PARSE_E;
  10993. }
  10994. if (ret != 0) break;
  10995. #ifndef NO_PKCS7_STREAM
  10996. /* next chunk of data expected should have the IV */
  10997. pkcs7->stream->expected = length;
  10998. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10999. break;
  11000. }
  11001. #endif
  11002. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE5);
  11003. FALL_THROUGH;
  11004. /* end of stage 4 */
  11005. case WC_PKCS7_STAGE5:
  11006. #ifndef NO_PKCS7_STREAM
  11007. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  11008. pkcs7->stream->expected + ASN_TAG_SZ +
  11009. MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  11010. return ret;
  11011. }
  11012. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  11013. /* use IV buffer from stream structure */
  11014. tmpIv = pkcs7->stream->tmpIv;
  11015. length = pkcs7->stream->expected;
  11016. #endif
  11017. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  11018. idx += length;
  11019. /* read encryptedContent, cont[0] */
  11020. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  11021. ret = ASN_PARSE_E;
  11022. if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))
  11023. ret = ASN_PARSE_E;
  11024. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &encryptedContentSz,
  11025. pkiMsgSz, NO_USER_CHECK) <= 0)
  11026. ret = ASN_PARSE_E;
  11027. if (ret < 0)
  11028. break;
  11029. #ifndef NO_PKCS7_STREAM
  11030. /* next chunk of data should contain encrypted content */
  11031. pkcs7->stream->varThree = encryptedContentSz;
  11032. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  11033. break;
  11034. }
  11035. if (pkcs7->stream->totalRd + encryptedContentSz <
  11036. pkcs7->stream->maxLen) {
  11037. pkcs7->stream->flagOne = 1;
  11038. }
  11039. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  11040. pkcs7->stream->totalRd) + pkcs7->stream->length;
  11041. #endif
  11042. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE6);
  11043. FALL_THROUGH;
  11044. /* end of stage 5 */
  11045. case WC_PKCS7_STAGE6:
  11046. #ifndef NO_PKCS7_STREAM
  11047. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  11048. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  11049. return ret;
  11050. }
  11051. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  11052. /* restore saved variables */
  11053. expBlockSz = pkcs7->stream->varOne;
  11054. encOID = pkcs7->stream->varTwo;
  11055. encryptedContentSz = pkcs7->stream->varThree;
  11056. version = pkcs7->stream->vers;
  11057. tmpIv = pkcs7->stream->tmpIv;
  11058. #endif
  11059. if (ret == 0 && (encryptedContent = (byte*)XMALLOC(
  11060. encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) {
  11061. ret = MEMORY_E;
  11062. break;
  11063. }
  11064. if (ret == 0) {
  11065. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  11066. idx += encryptedContentSz;
  11067. /* decrypt encryptedContent */
  11068. ret = wc_PKCS7_DecryptContent(pkcs7, encOID,
  11069. pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,
  11070. expBlockSz, NULL, 0, NULL, 0, encryptedContent,
  11071. encryptedContentSz, encryptedContent,
  11072. pkcs7->devId, pkcs7->heap);
  11073. if (ret != 0) {
  11074. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11075. }
  11076. }
  11077. if (ret == 0) {
  11078. padLen = encryptedContent[encryptedContentSz-1];
  11079. if (padLen > encryptedContentSz) {
  11080. WOLFSSL_MSG("Bad padding size found");
  11081. ret = BUFFER_E;
  11082. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11083. break;
  11084. }
  11085. /* copy plaintext to output */
  11086. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  11087. /* get implicit[1] unprotected attributes, optional */
  11088. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  11089. pkcs7->decodedAttrib = NULL;
  11090. #ifndef NO_PKCS7_STREAM
  11091. if (pkcs7->stream->flagOne)
  11092. #else
  11093. if (idx < pkiMsgSz)
  11094. #endif
  11095. {
  11096. haveAttribs = 1;
  11097. ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
  11098. pkiMsgSz, &idx);
  11099. if (ret != 0) {
  11100. ForceZero(encryptedContent, encryptedContentSz);
  11101. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11102. ret = ASN_PARSE_E;
  11103. }
  11104. }
  11105. }
  11106. if (ret == 0) {
  11107. ForceZero(encryptedContent, encryptedContentSz);
  11108. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11109. /* go back and check the version now that attribs have been processed */
  11110. if (pkcs7->version == 3 && version != 0) {
  11111. WOLFSSL_MSG("Wrong PKCS#7 FirmwareEncryptedData version");
  11112. return ASN_VERSION_E;
  11113. }
  11114. if (pkcs7->version != 3 &&
  11115. ((haveAttribs == 0 && version != 0) ||
  11116. (haveAttribs == 1 && version != 2))) {
  11117. WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version");
  11118. return ASN_VERSION_E;
  11119. }
  11120. ret = encryptedContentSz - padLen;
  11121. }
  11122. if (ret != 0) break;
  11123. #ifndef NO_PKCS7_STREAM
  11124. wc_PKCS7_ResetStream(pkcs7);
  11125. #endif
  11126. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  11127. break;
  11128. default:
  11129. WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
  11130. return BAD_STATE_E;
  11131. }
  11132. if (ret != 0) {
  11133. #ifndef NO_PKCS7_STREAM
  11134. /* restart in error case */
  11135. wc_PKCS7_ResetStream(pkcs7);
  11136. #endif
  11137. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  11138. }
  11139. return ret;
  11140. }
  11141. /* Function to set callback during decryption, this overrides the default
  11142. * decryption function and can be used for choosing a key at run time based
  11143. * on the parsed bundle so far.
  11144. * returns 0 on success
  11145. */
  11146. int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,
  11147. CallbackDecryptContent decryptionCb)
  11148. {
  11149. if (pkcs7 != NULL) {
  11150. pkcs7->decryptionCb = decryptionCb;
  11151. }
  11152. return 0;
  11153. }
  11154. /* Set an optional user context that gets passed to callback
  11155. * returns 0 on success
  11156. */
  11157. int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx)
  11158. {
  11159. if (pkcs7 != NULL) {
  11160. pkcs7->decryptionCtx = ctx;
  11161. }
  11162. return 0;
  11163. }
  11164. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  11165. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  11166. /* build PKCS#7 compressedData content type, return encrypted size */
  11167. int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  11168. {
  11169. byte contentInfoSeq[MAX_SEQ_SZ];
  11170. byte contentInfoTypeOid[MAX_OID_SZ];
  11171. byte contentInfoContentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  11172. byte compressedDataSeq[MAX_SEQ_SZ];
  11173. byte cmsVersion[MAX_VERSION_SZ];
  11174. byte compressAlgId[MAX_ALGO_SZ];
  11175. byte encapContentInfoSeq[MAX_SEQ_SZ];
  11176. byte contentTypeOid[MAX_OID_SZ];
  11177. byte contentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  11178. byte contentOctetStr[MAX_OCTET_STR_SZ];
  11179. int ret;
  11180. word32 totalSz, idx;
  11181. word32 contentInfoSeqSz, contentInfoContentSeqSz, contentInfoTypeOidSz;
  11182. word32 compressedDataSeqSz, cmsVersionSz, compressAlgIdSz;
  11183. word32 encapContentInfoSeqSz, contentTypeOidSz, contentSeqSz;
  11184. word32 contentOctetStrSz;
  11185. byte* compressed;
  11186. word32 compressedSz;
  11187. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  11188. output == NULL || outputSz == 0) {
  11189. return BAD_FUNC_ARG;
  11190. }
  11191. /* allocate space for compressed content. The libz code says the compressed
  11192. * buffer should be srcSz + 0.1% + 12. */
  11193. compressedSz = (pkcs7->contentSz + (word32)(pkcs7->contentSz * 0.001) + 12);
  11194. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11195. if (compressed == NULL) {
  11196. WOLFSSL_MSG("Error allocating memory for CMS compressed content");
  11197. return MEMORY_E;
  11198. }
  11199. /* compress content */
  11200. ret = wc_Compress(compressed, compressedSz, pkcs7->content,
  11201. pkcs7->contentSz, 0);
  11202. if (ret < 0) {
  11203. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11204. return ret;
  11205. }
  11206. compressedSz = (word32)ret;
  11207. /* eContent OCTET STRING, working backwards */
  11208. contentOctetStrSz = SetOctetString(compressedSz, contentOctetStr);
  11209. totalSz = contentOctetStrSz + compressedSz;
  11210. /* EXPLICIT [0] eContentType */
  11211. contentSeqSz = SetExplicit(0, totalSz, contentSeq);
  11212. totalSz += contentSeqSz;
  11213. /* eContentType OBJECT IDENTIFIER */
  11214. ret = wc_SetContentType(pkcs7->contentOID, contentTypeOid,
  11215. sizeof(contentTypeOid));
  11216. if (ret < 0) {
  11217. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11218. return ret;
  11219. }
  11220. contentTypeOidSz = ret;
  11221. totalSz += contentTypeOidSz;
  11222. /* EncapsulatedContentInfo SEQUENCE */
  11223. encapContentInfoSeqSz = SetSequence(totalSz, encapContentInfoSeq);
  11224. totalSz += encapContentInfoSeqSz;
  11225. /* compressionAlgorithm AlgorithmIdentifier */
  11226. /* Only supports zlib for compression currently:
  11227. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  11228. compressAlgIdSz = SetAlgoID(ZLIBc, compressAlgId, oidCompressType, 0);
  11229. totalSz += compressAlgIdSz;
  11230. /* version */
  11231. cmsVersionSz = SetMyVersion(0, cmsVersion, 0);
  11232. totalSz += cmsVersionSz;
  11233. /* CompressedData SEQUENCE */
  11234. compressedDataSeqSz = SetSequence(totalSz, compressedDataSeq);
  11235. totalSz += compressedDataSeqSz;
  11236. if (pkcs7->version == 3) {
  11237. /* RFC 4108 section 2
  11238. * When the SignedData is version 3 and eContent is compressedData then
  11239. * the encoding is :
  11240. * CompressedData {
  11241. * version
  11242. * compressionAlgorithm
  11243. * encapContentInfo
  11244. * }
  11245. */
  11246. contentInfoSeqSz = 0;
  11247. contentInfoTypeOidSz = 0;
  11248. contentInfoContentSeqSz = 0;
  11249. }
  11250. else {
  11251. /* EncryptedData eContent type is encoded with:
  11252. * EncryptedData {
  11253. * version
  11254. * EncryptedContentInfo {
  11255. * contentType (i.e id-ct-compressedData)
  11256. * contentEncryptionAlgorithm
  11257. * octet string of CompressedData or FirmwarePkgData
  11258. * }
  11259. * attributes
  11260. * }
  11261. */
  11262. /* ContentInfo content EXPLICIT SEQUENCE */
  11263. contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq);
  11264. totalSz += contentInfoContentSeqSz;
  11265. ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid,
  11266. sizeof(contentInfoTypeOid));
  11267. if (ret < 0) {
  11268. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11269. return ret;
  11270. }
  11271. contentInfoTypeOidSz = ret;
  11272. totalSz += contentInfoTypeOidSz;
  11273. /* ContentInfo SEQUENCE */
  11274. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  11275. totalSz += contentInfoSeqSz;
  11276. }
  11277. if (outputSz < totalSz) {
  11278. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11279. return BUFFER_E;
  11280. }
  11281. idx = 0;
  11282. if (contentInfoSeqSz > 0) {
  11283. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  11284. idx += contentInfoSeqSz;
  11285. }
  11286. if (contentInfoTypeOidSz > 0) {
  11287. XMEMCPY(output + idx, contentInfoTypeOid, contentInfoTypeOidSz);
  11288. idx += contentInfoTypeOidSz;
  11289. }
  11290. if (contentInfoContentSeqSz > 0) {
  11291. XMEMCPY(output + idx, contentInfoContentSeq, contentInfoContentSeqSz);
  11292. idx += contentInfoContentSeqSz;
  11293. }
  11294. XMEMCPY(output + idx, compressedDataSeq, compressedDataSeqSz);
  11295. idx += compressedDataSeqSz;
  11296. XMEMCPY(output + idx, cmsVersion, cmsVersionSz);
  11297. idx += cmsVersionSz;
  11298. XMEMCPY(output + idx, compressAlgId, compressAlgIdSz);
  11299. idx += compressAlgIdSz;
  11300. XMEMCPY(output + idx, encapContentInfoSeq, encapContentInfoSeqSz);
  11301. idx += encapContentInfoSeqSz;
  11302. XMEMCPY(output + idx, contentTypeOid, contentTypeOidSz);
  11303. idx += contentTypeOidSz;
  11304. XMEMCPY(output + idx, contentSeq, contentSeqSz);
  11305. idx += contentSeqSz;
  11306. XMEMCPY(output + idx, contentOctetStr, contentOctetStrSz);
  11307. idx += contentOctetStrSz;
  11308. XMEMCPY(output + idx, compressed, compressedSz);
  11309. idx += compressedSz;
  11310. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11311. return idx;
  11312. }
  11313. /* unwrap and decompress PKCS#7/CMS compressedData object,
  11314. * Handles content wrapped compressed data and raw compressed data packet
  11315. * returned decoded size */
  11316. int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
  11317. byte* output, word32 outputSz)
  11318. {
  11319. int length, version, ret;
  11320. word32 idx = 0, algOID, contentType;
  11321. byte tag;
  11322. byte* decompressed;
  11323. word32 decompressedSz;
  11324. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 ||
  11325. output == NULL || outputSz == 0) {
  11326. return BAD_FUNC_ARG;
  11327. }
  11328. /* unwarp content surrounding if found */
  11329. {
  11330. word32 localIdx = idx;
  11331. int err = 0;
  11332. /* get ContentInfo SEQUENCE */
  11333. if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  11334. err = ASN_PARSE_E;
  11335. if (err == 0 && pkcs7->version != 3) {
  11336. /* get ContentInfo contentType */
  11337. if (wc_GetContentType(pkiMsg, &localIdx, &contentType, pkiMsgSz)
  11338. < 0)
  11339. err = ASN_PARSE_E;
  11340. if (err == 0 && contentType != COMPRESSED_DATA)
  11341. err = ASN_PARSE_E;
  11342. }
  11343. /* get ContentInfo content EXPLICIT SEQUENCE */
  11344. if (err == 0) {
  11345. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  11346. err = ASN_PARSE_E;
  11347. }
  11348. if (err == 0) {
  11349. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  11350. err = ASN_PARSE_E;
  11351. }
  11352. if (err == 0) {
  11353. if (GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  11354. err = ASN_PARSE_E;
  11355. }
  11356. /* successful content unwrap, update index */
  11357. if (err == 0) {
  11358. idx = localIdx;
  11359. }
  11360. }
  11361. /* get CompressedData SEQUENCE */
  11362. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11363. return ASN_PARSE_E;
  11364. /* get version */
  11365. if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  11366. return ASN_PARSE_E;
  11367. if (version != 0) {
  11368. WOLFSSL_MSG("CMS CompressedData version MUST be 0, but is not");
  11369. return ASN_PARSE_E;
  11370. }
  11371. /* get CompressionAlgorithmIdentifier */
  11372. if (GetAlgoId(pkiMsg, &idx, &algOID, oidIgnoreType, pkiMsgSz) < 0)
  11373. return ASN_PARSE_E;
  11374. /* Only supports zlib for compression currently:
  11375. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  11376. if (algOID != ZLIBc) {
  11377. WOLFSSL_MSG("CMS CompressedData only supports zlib algorithm");
  11378. return ASN_PARSE_E;
  11379. }
  11380. /* get EncapsulatedContentInfo SEQUENCE */
  11381. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11382. return ASN_PARSE_E;
  11383. /* get ContentType OID */
  11384. if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
  11385. return ASN_PARSE_E;
  11386. pkcs7->contentOID = contentType;
  11387. /* get eContent EXPLICIT SEQUENCE */
  11388. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  11389. return ASN_PARSE_E;
  11390. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  11391. return ASN_PARSE_E;
  11392. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11393. return ASN_PARSE_E;
  11394. /* get content OCTET STRING */
  11395. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  11396. return ASN_PARSE_E;
  11397. if (tag != ASN_OCTET_STRING)
  11398. return ASN_PARSE_E;
  11399. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11400. return ASN_PARSE_E;
  11401. /* decompress content */
  11402. ret = wc_DeCompressDynamic(&decompressed, WOLFSSL_PKCS7_MAX_DECOMPRESSION,
  11403. DYNAMIC_TYPE_PKCS7, &pkiMsg[idx], length, 0, pkcs7->heap);
  11404. if (ret < 0) {
  11405. return ret;
  11406. }
  11407. decompressedSz = (word32)ret;
  11408. /* get content */
  11409. if (outputSz < decompressedSz) {
  11410. WOLFSSL_MSG("CMS output buffer too small to hold decompressed data");
  11411. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11412. return BUFFER_E;
  11413. }
  11414. XMEMCPY(output, decompressed, decompressedSz);
  11415. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11416. return decompressedSz;
  11417. }
  11418. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  11419. #else /* HAVE_PKCS7 */
  11420. #ifdef _MSC_VER
  11421. /* 4206 warning for blank file */
  11422. #pragma warning(disable: 4206)
  11423. #endif
  11424. #endif /* HAVE_PKCS7 */