pkcs7.c 401 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537
  1. /* pkcs7.c
  2. *
  3. * Copyright (C) 2006-2020 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 NO_PKCS7_STREAM
  61. #define MAX_PKCS7_STREAM_BUFFER 256
  62. struct PKCS7State {
  63. byte* tmpCert;
  64. byte* bufferPt;
  65. byte* key;
  66. byte* nonce; /* stored nonce */
  67. byte* aad; /* additional data for AEAD algos */
  68. byte* tag; /* tag data for AEAD algos */
  69. byte* content;
  70. byte* buffer; /* main internal read buffer */
  71. /* stack variables to store for when returning */
  72. word32 varOne;
  73. int varTwo;
  74. int varThree;
  75. word32 vers;
  76. word32 idx; /* index read into current input buffer */
  77. word32 maxLen; /* sanity cap on maximum amount of data to allow
  78. * needed for GetSequence and other calls */
  79. word32 length; /* amount of data stored */
  80. word32 bufferSz; /* size of internal buffer */
  81. word32 expected; /* next amount of data expected, if needed */
  82. word32 totalRd; /* total amount of bytes read */
  83. word32 nonceSz; /* size of nonce stored */
  84. word32 aadSz; /* size of additional AEAD data */
  85. word32 tagSz; /* size of tag for AEAD */
  86. word32 contentSz;
  87. byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
  88. #ifdef WC_PKCS7_STREAM_DEBUG
  89. word32 peakUsed; /* most bytes used for struct at any one time */
  90. word32 peakRead; /* most bytes used by read buffer */
  91. #endif
  92. byte multi:1; /* flag for if content is in multiple parts */
  93. byte flagOne:1;
  94. byte detached:1; /* flag to indicate detached signature is present */
  95. };
  96. enum PKCS7_MaxLen {
  97. PKCS7_DEFAULT_PEEK = 0,
  98. PKCS7_SEQ_PEEK
  99. };
  100. /* creates a PKCS7State structure and returns 0 on success */
  101. static int wc_PKCS7_CreateStream(PKCS7* pkcs7)
  102. {
  103. WOLFSSL_MSG("creating PKCS7 stream structure");
  104. pkcs7->stream = (PKCS7State*)XMALLOC(sizeof(PKCS7State), pkcs7->heap,
  105. DYNAMIC_TYPE_PKCS7);
  106. if (pkcs7->stream == NULL) {
  107. return MEMORY_E;
  108. }
  109. XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State));
  110. #ifdef WC_PKCS7_STREAM_DEBUG
  111. printf("\nCreating new PKCS#7 stream %p\n", pkcs7->stream);
  112. #endif
  113. return 0;
  114. }
  115. static void wc_PKCS7_ResetStream(PKCS7* pkcs7)
  116. {
  117. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  118. #ifdef WC_PKCS7_STREAM_DEBUG
  119. /* collect final data point in case more was read right before reset */
  120. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  121. pkcs7->stream->peakRead = pkcs7->stream->length;
  122. }
  123. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz +
  124. pkcs7->stream->nonceSz + pkcs7->stream->tagSz >
  125. pkcs7->stream->peakUsed) {
  126. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  127. pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  128. pkcs7->stream->tagSz;
  129. }
  130. /* print out debugging statistics */
  131. if (pkcs7->stream->peakUsed > 0 || pkcs7->stream->peakRead > 0) {
  132. printf("PKCS#7 STREAM:\n\tPeak heap used by struct = %d"
  133. "\n\tPeak read buffer bytes = %d"
  134. "\n\tTotal bytes read = %d"
  135. "\n",
  136. pkcs7->stream->peakUsed, pkcs7->stream->peakRead,
  137. pkcs7->stream->totalRd);
  138. }
  139. printf("PKCS#7 stream reset : Address [%p]\n", pkcs7->stream);
  140. #endif
  141. /* free any buffers that may be allocated */
  142. XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  143. XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  144. XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  145. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  146. XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  147. pkcs7->stream->aad = NULL;
  148. pkcs7->stream->tag = NULL;
  149. pkcs7->stream->nonce = NULL;
  150. pkcs7->stream->buffer = NULL;
  151. pkcs7->stream->key = NULL;
  152. /* reset values, note that content and tmpCert are saved */
  153. pkcs7->stream->maxLen = 0;
  154. pkcs7->stream->length = 0;
  155. pkcs7->stream->idx = 0;
  156. pkcs7->stream->expected = 0;
  157. pkcs7->stream->totalRd = 0;
  158. pkcs7->stream->bufferSz = 0;
  159. pkcs7->stream->multi = 0;
  160. pkcs7->stream->flagOne = 0;
  161. pkcs7->stream->detached = 0;
  162. pkcs7->stream->varOne = 0;
  163. pkcs7->stream->varTwo = 0;
  164. pkcs7->stream->varThree = 0;
  165. }
  166. }
  167. static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
  168. {
  169. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  170. wc_PKCS7_ResetStream(pkcs7);
  171. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  172. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  173. pkcs7->stream->content = NULL;
  174. pkcs7->stream->tmpCert = NULL;
  175. XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  176. pkcs7->stream = NULL;
  177. }
  178. }
  179. /* used to increase the max size for internal buffer
  180. * returns 0 on success */
  181. static int wc_PKCS7_GrowStream(PKCS7* pkcs7, word32 newSz)
  182. {
  183. byte* pt;
  184. pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  185. if (pt == NULL) {
  186. return MEMORY_E;
  187. }
  188. XMEMCPY(pt, pkcs7->stream->buffer, pkcs7->stream->bufferSz);
  189. #ifdef WC_PKCS7_STREAM_DEBUG
  190. printf("PKCS7 increasing internal stream buffer %d -> %d\n",
  191. pkcs7->stream->bufferSz, newSz);
  192. #endif
  193. pkcs7->stream->bufferSz = newSz;
  194. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  195. pkcs7->stream->buffer = pt;
  196. return 0;
  197. }
  198. /* pt gets set to the buffer that is holding data in the case that stream struct
  199. * is used.
  200. *
  201. * Sets idx to be the current offset into "pt" buffer
  202. * returns 0 on success
  203. */
  204. static int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz,
  205. word32 expected, byte** pt, word32* idx)
  206. {
  207. word32 rdSz = pkcs7->stream->idx;
  208. /* If the input size minus current index into input buffer is greater than
  209. * the expected size then use the input buffer. If data is already stored
  210. * in stream buffer or if there is not enough input data available then use
  211. * the stream buffer. */
  212. if (inSz - rdSz >= expected && pkcs7->stream->length == 0) {
  213. /* storing input buffer is not needed */
  214. *pt = in; /* reset in case previously used internal buffer */
  215. *idx = rdSz;
  216. return 0;
  217. }
  218. /* is there enough stored in buffer already? */
  219. if (pkcs7->stream->length >= expected) {
  220. *idx = 0; /* start reading from beginning of stream buffer */
  221. *pt = pkcs7->stream->buffer;
  222. return 0;
  223. }
  224. /* check if all data has been read from input */
  225. if (rdSz >= inSz) {
  226. /* no more input to read, reset input index and request more data */
  227. pkcs7->stream->idx = 0;
  228. return WC_PKCS7_WANT_READ_E;
  229. }
  230. /* try to store input data into stream buffer */
  231. if (inSz - rdSz > 0 && pkcs7->stream->length < expected) {
  232. int len = min(inSz - rdSz, expected - pkcs7->stream->length);
  233. /* sanity check that the input buffer is not internal buffer */
  234. if (in == pkcs7->stream->buffer) {
  235. return WC_PKCS7_WANT_READ_E;
  236. }
  237. /* check if internal buffer size needs to be increased */
  238. if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) {
  239. int ret = wc_PKCS7_GrowStream(pkcs7, expected);
  240. if (ret < 0) {
  241. return ret;
  242. }
  243. }
  244. XMEMCPY(pkcs7->stream->buffer + pkcs7->stream->length, in + rdSz, len);
  245. pkcs7->stream->length += len;
  246. pkcs7->stream->idx += len;
  247. pkcs7->stream->totalRd += len;
  248. }
  249. #ifdef WC_PKCS7_STREAM_DEBUG
  250. /* collects memory usage for debugging */
  251. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  252. pkcs7->stream->peakRead = pkcs7->stream->length;
  253. }
  254. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  255. pkcs7->stream->tagSz > pkcs7->stream->peakUsed) {
  256. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  257. pkcs7->stream->aadSz + pkcs7->stream->nonceSz + pkcs7->stream->tagSz;
  258. }
  259. #endif
  260. /* if not enough data was read in then request more */
  261. if (pkcs7->stream->length < expected) {
  262. pkcs7->stream->idx = 0;
  263. return WC_PKCS7_WANT_READ_E;
  264. }
  265. /* adjust pointer to read from stored buffer */
  266. *idx = 0;
  267. *pt = pkcs7->stream->buffer;
  268. return 0;
  269. }
  270. /* Does two things
  271. * 1) Tries to get the length from current buffer and set it as max length
  272. * 2) Retrieves the set max length
  273. *
  274. * if no flag value is set then the stored max length is returned.
  275. * returns length found on success and defSz if no stored data is found
  276. */
  277. static long wc_PKCS7_GetMaxStream(PKCS7* pkcs7, byte flag, byte* in,
  278. word32 defSz)
  279. {
  280. /* check there is a buffer to read from */
  281. if (pkcs7) {
  282. int length = 0, ret;
  283. word32 idx = 0, maxIdx;
  284. byte* pt;
  285. if (flag != PKCS7_DEFAULT_PEEK) {
  286. if (pkcs7->stream->length > 0) {
  287. length = pkcs7->stream->length;
  288. pt = pkcs7->stream->buffer;
  289. }
  290. else {
  291. length = defSz;
  292. pt = in;
  293. }
  294. maxIdx = (word32)length;
  295. if (length < MAX_SEQ_SZ) {
  296. WOLFSSL_MSG("PKCS7 Error not enough data for SEQ peek\n");
  297. return 0;
  298. }
  299. if (flag == PKCS7_SEQ_PEEK) {
  300. if ((ret = GetSequence_ex(pt, &idx, &length, maxIdx,
  301. NO_USER_CHECK)) < 0) {
  302. return ret;
  303. }
  304. #ifdef ASN_BER_TO_DER
  305. if (length == 0 && ret == 0) {
  306. idx = 0;
  307. if ((ret = wc_BerToDer(pt, defSz, NULL,
  308. (word32*)&length)) != LENGTH_ONLY_E) {
  309. return ret;
  310. }
  311. }
  312. #endif /* ASN_BER_TO_DER */
  313. pkcs7->stream->maxLen = length + idx;
  314. }
  315. }
  316. if (pkcs7->stream->maxLen == 0) {
  317. pkcs7->stream->maxLen = defSz;
  318. }
  319. return pkcs7->stream->maxLen;
  320. }
  321. return defSz;
  322. }
  323. /* setter function for stored variables */
  324. static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2,
  325. int var3)
  326. {
  327. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  328. pkcs7->stream->varOne = var1;
  329. pkcs7->stream->varTwo = var2;
  330. pkcs7->stream->varThree = var3;
  331. }
  332. }
  333. /* getter function for stored variables */
  334. static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2,
  335. int* var3)
  336. {
  337. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  338. if (var1 != NULL) *var1 = pkcs7->stream->varOne;
  339. if (var2 != NULL) *var2 = pkcs7->stream->varTwo;
  340. if (var3 != NULL) *var3 = pkcs7->stream->varThree;
  341. }
  342. }
  343. /* common update of index and total read after section complete
  344. * returns 0 on success */
  345. static int wc_PKCS7_StreamEndCase(PKCS7* pkcs7, word32* tmpIdx, word32* idx)
  346. {
  347. int ret = 0;
  348. if (pkcs7->stream->length > 0) {
  349. if (pkcs7->stream->length < *idx) {
  350. WOLFSSL_MSG("PKCS7 read too much data from internal buffer");
  351. ret = BUFFER_E;
  352. }
  353. else {
  354. XMEMMOVE(pkcs7->stream->buffer, pkcs7->stream->buffer + *idx,
  355. pkcs7->stream->length - *idx);
  356. pkcs7->stream->length -= *idx;
  357. }
  358. }
  359. else {
  360. pkcs7->stream->totalRd += *idx - *tmpIdx;
  361. pkcs7->stream->idx = *idx; /* adjust index into input buffer */
  362. *tmpIdx = *idx;
  363. }
  364. return ret;
  365. }
  366. #endif /* NO_PKCS7_STREAM */
  367. #ifdef WC_PKCS7_STREAM_DEBUG
  368. /* used to print out human readable state for debugging */
  369. static const char* wc_PKCS7_GetStateName(int in)
  370. {
  371. switch (in) {
  372. case WC_PKCS7_START: return "WC_PKCS7_START";
  373. case WC_PKCS7_STAGE2: return "WC_PKCS7_STAGE2";
  374. case WC_PKCS7_STAGE3: return "WC_PKCS7_STAGE3";
  375. case WC_PKCS7_STAGE4: return "WC_PKCS7_STAGE4";
  376. case WC_PKCS7_STAGE5: return "WC_PKCS7_STAGE5";
  377. case WC_PKCS7_STAGE6: return "WC_PKCS7_STAGE6";
  378. /* parse info set */
  379. case WC_PKCS7_INFOSET_START: return "WC_PKCS7_INFOSET_START";
  380. case WC_PKCS7_INFOSET_BER: return "WC_PKCS7_INFOSET_BER";
  381. case WC_PKCS7_INFOSET_STAGE1: return "WC_PKCS7_INFOSET_STAGE1";
  382. case WC_PKCS7_INFOSET_STAGE2: return "WC_PKCS7_INFOSET_STAGE2";
  383. case WC_PKCS7_INFOSET_END: return "WC_PKCS7_INFOSET_END";
  384. /* decode enveloped data */
  385. case WC_PKCS7_ENV_2: return "WC_PKCS7_ENV_2";
  386. case WC_PKCS7_ENV_3: return "WC_PKCS7_ENV_3";
  387. case WC_PKCS7_ENV_4: return "WC_PKCS7_ENV_4";
  388. case WC_PKCS7_ENV_5: return "WC_PKCS7_ENV_5";
  389. /* decode auth enveloped */
  390. case WC_PKCS7_AUTHENV_2: return "WC_PKCS7_AUTHENV_2";
  391. case WC_PKCS7_AUTHENV_3: return "WC_PKCS7_AUTHENV_3";
  392. case WC_PKCS7_AUTHENV_4: return "WC_PKCS7_AUTHENV_4";
  393. case WC_PKCS7_AUTHENV_5: return "WC_PKCS7_AUTHENV_5";
  394. case WC_PKCS7_AUTHENV_6: return "WC_PKCS7_AUTHENV_6";
  395. case WC_PKCS7_AUTHENV_ATRB: return "WC_PKCS7_AUTHENV_ATRB";
  396. case WC_PKCS7_AUTHENV_ATRBEND: return "WC_PKCS7_AUTHENV_ATRBEND";
  397. case WC_PKCS7_AUTHENV_7: return "WC_PKCS7_AUTHENV_7";
  398. /* decryption state types */
  399. case WC_PKCS7_DECRYPT_KTRI: return "WC_PKCS7_DECRYPT_KTRI";
  400. case WC_PKCS7_DECRYPT_KTRI_2: return "WC_PKCS7_DECRYPT_KTRI_2";
  401. case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
  402. case WC_PKCS7_DECRYPT_KARI: return "WC_PKCS7_DECRYPT_KARI";
  403. case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
  404. case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
  405. case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
  406. case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
  407. case WC_PKCS7_VERIFY_STAGE2: return "WC_PKCS7_VERIFY_STAGE2";
  408. case WC_PKCS7_VERIFY_STAGE3: return "WC_PKCS7_VERIFY_STAGE3";
  409. case WC_PKCS7_VERIFY_STAGE4: return "WC_PKCS7_VERIFY_STAGE4";
  410. case WC_PKCS7_VERIFY_STAGE5: return "WC_PKCS7_VERIFY_STAGE5";
  411. case WC_PKCS7_VERIFY_STAGE6: return "WC_PKCS7_VERIFY_STAGE6";
  412. default:
  413. return "Unknown state";
  414. }
  415. }
  416. #endif
  417. /* Used to change the PKCS7 state. Having state change as a function allows
  418. * for easier debugging */
  419. static void wc_PKCS7_ChangeState(PKCS7* pkcs7, int newState)
  420. {
  421. #ifdef WC_PKCS7_STREAM_DEBUG
  422. printf("\tChanging from state [%02d] %s to [%02d] %s\n",
  423. pkcs7->state, wc_PKCS7_GetStateName(pkcs7->state),
  424. newState, wc_PKCS7_GetStateName(newState));
  425. #endif
  426. pkcs7->state = newState;
  427. }
  428. #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \
  429. MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)
  430. /* placed ASN.1 contentType OID into *output, return idx on success,
  431. * 0 upon failure */
  432. static int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz)
  433. {
  434. /* PKCS#7 content types, RFC 2315, section 14 */
  435. const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  436. 0x0D, 0x01, 0x07 };
  437. const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  438. 0x0D, 0x01, 0x07, 0x01 };
  439. const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  440. 0x0D, 0x01, 0x07, 0x02};
  441. const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  442. 0x0D, 0x01, 0x07, 0x03 };
  443. const byte authEnvelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  444. 0x0D, 0x01, 0x09, 0x10, 0x01, 0x17};
  445. const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  446. 0x0D, 0x01, 0x07, 0x04 };
  447. const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  448. 0x0D, 0x01, 0x07, 0x05 };
  449. #ifndef NO_PKCS7_ENCRYPTED_DATA
  450. const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
  451. 0x0D, 0x01, 0x07, 0x06 };
  452. #endif
  453. /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), RFC 4108 */
  454. const byte firmwarePkgData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
  455. 0x01, 0x09, 0x10, 0x01, 0x10 };
  456. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  457. /* id-ct-compressedData (1.2.840.113549.1.9.16.1.9), RFC 3274 */
  458. const byte compressedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
  459. 0x01, 0x09, 0x10, 0x01, 0x09 };
  460. #endif
  461. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  462. const byte pwriKek[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
  463. 0x01, 0x09, 0x10, 0x03, 0x09 };
  464. const byte pbkdf2[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
  465. 0x01, 0x05, 0x0C };
  466. #endif
  467. int idSz, idx = 0;
  468. word32 typeSz = 0;
  469. const byte* typeName = 0;
  470. byte ID_Length[MAX_LENGTH_SZ];
  471. switch (pkcs7TypeOID) {
  472. case PKCS7_MSG:
  473. typeSz = sizeof(pkcs7);
  474. typeName = pkcs7;
  475. break;
  476. case DATA:
  477. typeSz = sizeof(data);
  478. typeName = data;
  479. break;
  480. case SIGNED_DATA:
  481. typeSz = sizeof(signedData);
  482. typeName = signedData;
  483. break;
  484. case ENVELOPED_DATA:
  485. typeSz = sizeof(envelopedData);
  486. typeName = envelopedData;
  487. break;
  488. case AUTH_ENVELOPED_DATA:
  489. typeSz = sizeof(authEnvelopedData);
  490. typeName = authEnvelopedData;
  491. break;
  492. case SIGNED_AND_ENVELOPED_DATA:
  493. typeSz = sizeof(signedAndEnveloped);
  494. typeName = signedAndEnveloped;
  495. break;
  496. case DIGESTED_DATA:
  497. typeSz = sizeof(digestedData);
  498. typeName = digestedData;
  499. break;
  500. #ifndef NO_PKCS7_ENCRYPTED_DATA
  501. case ENCRYPTED_DATA:
  502. typeSz = sizeof(encryptedData);
  503. typeName = encryptedData;
  504. break;
  505. #endif
  506. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  507. case COMPRESSED_DATA:
  508. typeSz = sizeof(compressedData);
  509. typeName = compressedData;
  510. break;
  511. #endif
  512. case FIRMWARE_PKG_DATA:
  513. typeSz = sizeof(firmwarePkgData);
  514. typeName = firmwarePkgData;
  515. break;
  516. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  517. case PWRI_KEK_WRAP:
  518. typeSz = sizeof(pwriKek);
  519. typeName = pwriKek;
  520. break;
  521. case PBKDF2_OID:
  522. typeSz = sizeof(pbkdf2);
  523. typeName = pbkdf2;
  524. break;
  525. #endif
  526. default:
  527. WOLFSSL_MSG("Unknown PKCS#7 Type");
  528. return 0;
  529. };
  530. if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) {
  531. WOLFSSL_MSG("CMS content type buffer too small");
  532. return BAD_FUNC_ARG;
  533. }
  534. idSz = SetLength(typeSz, ID_Length);
  535. output[idx++] = ASN_OBJECT_ID;
  536. XMEMCPY(output + idx, ID_Length, idSz);
  537. idx += idSz;
  538. XMEMCPY(output + idx, typeName, typeSz);
  539. idx += typeSz;
  540. return idx;
  541. }
  542. /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
  543. static int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
  544. word32 maxIdx)
  545. {
  546. WOLFSSL_ENTER("wc_GetContentType");
  547. if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0)
  548. return ASN_PARSE_E;
  549. return 0;
  550. }
  551. /* return block size for algorithm represented by oid, or <0 on error */
  552. static int wc_PKCS7_GetOIDBlockSize(int oid)
  553. {
  554. int blockSz;
  555. switch (oid) {
  556. #ifndef NO_AES
  557. #ifdef WOLFSSL_AES_128
  558. case AES128CBCb:
  559. case AES128GCMb:
  560. case AES128CCMb:
  561. #endif
  562. #ifdef WOLFSSL_AES_192
  563. case AES192CBCb:
  564. case AES192GCMb:
  565. case AES192CCMb:
  566. #endif
  567. #ifdef WOLFSSL_AES_256
  568. case AES256CBCb:
  569. case AES256GCMb:
  570. case AES256CCMb:
  571. #endif
  572. blockSz = AES_BLOCK_SIZE;
  573. break;
  574. #endif
  575. #ifndef NO_DES3
  576. case DESb:
  577. case DES3b:
  578. blockSz = DES_BLOCK_SIZE;
  579. break;
  580. #endif
  581. default:
  582. WOLFSSL_MSG("Unsupported content cipher type");
  583. return ALGO_ID_E;
  584. };
  585. return blockSz;
  586. }
  587. /* get key size for algorithm represented by oid, or <0 on error */
  588. static int wc_PKCS7_GetOIDKeySize(int oid)
  589. {
  590. int blockKeySz;
  591. switch (oid) {
  592. #ifndef NO_AES
  593. #ifdef WOLFSSL_AES_128
  594. case AES128CBCb:
  595. case AES128GCMb:
  596. case AES128CCMb:
  597. case AES128_WRAP:
  598. blockKeySz = 16;
  599. break;
  600. #endif
  601. #ifdef WOLFSSL_AES_192
  602. case AES192CBCb:
  603. case AES192GCMb:
  604. case AES192CCMb:
  605. case AES192_WRAP:
  606. blockKeySz = 24;
  607. break;
  608. #endif
  609. #ifdef WOLFSSL_AES_256
  610. case AES256CBCb:
  611. case AES256GCMb:
  612. case AES256CCMb:
  613. case AES256_WRAP:
  614. blockKeySz = 32;
  615. break;
  616. #endif
  617. #endif
  618. #ifndef NO_DES3
  619. case DESb:
  620. blockKeySz = DES_KEYLEN;
  621. break;
  622. case DES3b:
  623. blockKeySz = DES3_KEYLEN;
  624. break;
  625. #endif
  626. default:
  627. WOLFSSL_MSG("Unsupported content cipher type");
  628. return ALGO_ID_E;
  629. };
  630. return blockKeySz;
  631. }
  632. PKCS7* wc_PKCS7_New(void* heap, int devId)
  633. {
  634. PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);
  635. if (pkcs7) {
  636. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  637. if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {
  638. pkcs7->isDynamic = 1;
  639. }
  640. else {
  641. XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);
  642. pkcs7 = NULL;
  643. }
  644. }
  645. return pkcs7;
  646. }
  647. /* This is to initialize a PKCS7 structure. It sets all values to 0 and can be
  648. * used to set the heap hint.
  649. *
  650. * pkcs7 PKCS7 structure to initialize
  651. * heap memory heap hint for PKCS7 structure to use
  652. * devId currently not used but a place holder for async operations
  653. *
  654. * returns 0 on success or a negative value for failure
  655. */
  656. int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)
  657. {
  658. word16 isDynamic;
  659. WOLFSSL_ENTER("wc_PKCS7_Init");
  660. if (pkcs7 == NULL) {
  661. return BAD_FUNC_ARG;
  662. }
  663. isDynamic = pkcs7->isDynamic;
  664. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  665. pkcs7->isDynamic = isDynamic;
  666. #ifdef WOLFSSL_HEAP_TEST
  667. pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;
  668. #else
  669. pkcs7->heap = heap;
  670. #endif
  671. pkcs7->devId = devId;
  672. return 0;
  673. }
  674. /* Certificate structure holding der pointer, size, and pointer to next
  675. * Pkcs7Cert struct. Used when creating SignedData types with multiple
  676. * certificates. */
  677. struct Pkcs7Cert {
  678. byte* der;
  679. word32 derSz;
  680. Pkcs7Cert* next;
  681. };
  682. /* Linked list of ASN.1 encoded RecipientInfos */
  683. struct Pkcs7EncodedRecip {
  684. byte recip[MAX_RECIP_SZ];
  685. word32 recipSz;
  686. int recipType;
  687. int recipVersion;
  688. Pkcs7EncodedRecip* next;
  689. };
  690. /* free all members of Pkcs7Cert linked list */
  691. static void wc_PKCS7_FreeCertSet(PKCS7* pkcs7)
  692. {
  693. Pkcs7Cert* curr = NULL;
  694. Pkcs7Cert* next = NULL;
  695. if (pkcs7 == NULL)
  696. return;
  697. curr = pkcs7->certList;
  698. pkcs7->certList = NULL;
  699. while (curr != NULL) {
  700. next = curr->next;
  701. curr->next = NULL;
  702. XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  703. curr = next;
  704. }
  705. return;
  706. }
  707. /* Get total size of all recipients in recipient list.
  708. *
  709. * Returns total size of recipients, or negative upon error */
  710. static int wc_PKCS7_GetRecipientListSize(PKCS7* pkcs7)
  711. {
  712. int totalSz = 0;
  713. Pkcs7EncodedRecip* tmp = NULL;
  714. if (pkcs7 == NULL)
  715. return BAD_FUNC_ARG;
  716. tmp = pkcs7->recipList;
  717. while (tmp != NULL) {
  718. totalSz += tmp->recipSz;
  719. tmp = tmp->next;
  720. }
  721. return totalSz;
  722. }
  723. /* free all members of Pkcs7EncodedRecip linked list */
  724. static void wc_PKCS7_FreeEncodedRecipientSet(PKCS7* pkcs7)
  725. {
  726. Pkcs7EncodedRecip* curr = NULL;
  727. Pkcs7EncodedRecip* next = NULL;
  728. if (pkcs7 == NULL)
  729. return;
  730. curr = pkcs7->recipList;
  731. pkcs7->recipList = 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. /* search through RecipientInfo list for specific type.
  741. * return 1 if ANY recipient of type specified is present, otherwise
  742. * return 0 */
  743. static int wc_PKCS7_RecipientListIncludesType(PKCS7* pkcs7, int type)
  744. {
  745. Pkcs7EncodedRecip* tmp = NULL;
  746. if (pkcs7 == NULL)
  747. return BAD_FUNC_ARG;
  748. tmp = pkcs7->recipList;
  749. while (tmp != NULL) {
  750. if (tmp->recipType == type)
  751. return 1;
  752. tmp = tmp->next;
  753. }
  754. return 0;
  755. }
  756. /* searches through RecipientInfo list, returns 1 if all structure
  757. * versions are set to 0, otherwise returns 0 */
  758. static int wc_PKCS7_RecipientListVersionsAllZero(PKCS7* pkcs7)
  759. {
  760. Pkcs7EncodedRecip* tmp = NULL;
  761. if (pkcs7 == NULL)
  762. return BAD_FUNC_ARG;
  763. tmp = pkcs7->recipList;
  764. while (tmp != NULL) {
  765. if (tmp->recipVersion != 0)
  766. return 0;
  767. tmp = tmp->next;
  768. }
  769. return 1;
  770. }
  771. /* Init PKCS7 struct with recipient cert, decode into DecodedCert
  772. * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */
  773. int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  774. {
  775. int ret = 0;
  776. void* heap;
  777. int devId;
  778. Pkcs7Cert* cert;
  779. Pkcs7Cert* lastCert;
  780. if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) {
  781. return BAD_FUNC_ARG;
  782. }
  783. heap = pkcs7->heap;
  784. devId = pkcs7->devId;
  785. cert = pkcs7->certList;
  786. ret = wc_PKCS7_Init(pkcs7, heap, devId);
  787. if (ret != 0)
  788. return ret;
  789. pkcs7->certList = cert;
  790. if (derCert != NULL && derCertSz > 0) {
  791. #ifdef WOLFSSL_SMALL_STACK
  792. DecodedCert* dCert;
  793. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  794. DYNAMIC_TYPE_DCERT);
  795. if (dCert == NULL)
  796. return MEMORY_E;
  797. #else
  798. DecodedCert dCert[1];
  799. #endif
  800. pkcs7->singleCert = derCert;
  801. pkcs7->singleCertSz = derCertSz;
  802. pkcs7->cert[0] = derCert;
  803. pkcs7->certSz[0] = derCertSz;
  804. /* create new Pkcs7Cert for recipient, freed during cleanup */
  805. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  806. DYNAMIC_TYPE_PKCS7);
  807. XMEMSET(cert, 0, sizeof(Pkcs7Cert));
  808. cert->der = derCert;
  809. cert->derSz = derCertSz;
  810. cert->next = NULL;
  811. /* free existing cert list if existing */
  812. wc_PKCS7_FreeCertSet(pkcs7);
  813. /* add cert to list */
  814. if (pkcs7->certList == NULL) {
  815. pkcs7->certList = cert;
  816. } else {
  817. lastCert = pkcs7->certList;
  818. while (lastCert->next != NULL) {
  819. lastCert = lastCert->next;
  820. }
  821. lastCert->next = cert;
  822. }
  823. InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap);
  824. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  825. if (ret < 0) {
  826. FreeDecodedCert(dCert);
  827. #ifdef WOLFSSL_SMALL_STACK
  828. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  829. #endif
  830. return ret;
  831. }
  832. XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
  833. pkcs7->publicKeySz = dCert->pubKeySize;
  834. pkcs7->publicKeyOID = dCert->keyOID;
  835. XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
  836. pkcs7->issuer = dCert->issuerRaw;
  837. pkcs7->issuerSz = dCert->issuerRawLen;
  838. XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
  839. pkcs7->issuerSnSz = dCert->serialSz;
  840. XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE);
  841. /* default to IssuerAndSerialNumber for SignerIdentifier */
  842. pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  843. /* free existing recipient list if existing */
  844. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  845. FreeDecodedCert(dCert);
  846. #ifdef WOLFSSL_SMALL_STACK
  847. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  848. #endif
  849. }
  850. return ret;
  851. }
  852. /* Adds one DER-formatted certificate to the internal PKCS7/CMS certificate
  853. * list, to be added as part of the certificates CertificateSet. Currently
  854. * used in SignedData content type.
  855. *
  856. * Must be called after wc_PKCS7_Init() or wc_PKCS7_InitWithCert().
  857. *
  858. * Does not represent the recipient/signer certificate, only certificates that
  859. * are part of the certificate chain used to build and verify signer
  860. * certificates.
  861. *
  862. * This API does not currently validate certificates.
  863. *
  864. * Returns 0 on success, negative upon error */
  865. int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  866. {
  867. Pkcs7Cert* cert;
  868. if (pkcs7 == NULL || derCert == NULL || derCertSz == 0)
  869. return BAD_FUNC_ARG;
  870. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  871. DYNAMIC_TYPE_PKCS7);
  872. if (cert == NULL)
  873. return MEMORY_E;
  874. cert->der = derCert;
  875. cert->derSz = derCertSz;
  876. if (pkcs7->certList == NULL) {
  877. pkcs7->certList = cert;
  878. } else {
  879. cert->next = pkcs7->certList;
  880. pkcs7->certList = cert;
  881. }
  882. return 0;
  883. }
  884. /* free linked list of PKCS7DecodedAttrib structs */
  885. static void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)
  886. {
  887. PKCS7DecodedAttrib* current;
  888. if (attrib == NULL) {
  889. return;
  890. }
  891. current = attrib;
  892. while (current != NULL) {
  893. PKCS7DecodedAttrib* next = current->next;
  894. if (current->oid != NULL) {
  895. XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);
  896. }
  897. if (current->value != NULL) {
  898. XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);
  899. }
  900. XFREE(current, heap, DYNAMIC_TYPE_PKCS7);
  901. current = next;
  902. }
  903. (void)heap;
  904. }
  905. /* return 0 on success */
  906. static int wc_PKCS7_SignerInfoNew(PKCS7* pkcs7)
  907. {
  908. if (pkcs7->signerInfo != NULL) {
  909. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  910. pkcs7->signerInfo = NULL;
  911. }
  912. pkcs7->signerInfo = (PKCS7SignerInfo*)XMALLOC(sizeof(PKCS7SignerInfo),
  913. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  914. if (pkcs7->signerInfo == NULL) {
  915. WOLFSSL_MSG("Unable to malloc memory for signer info");
  916. return MEMORY_E;
  917. }
  918. XMEMSET(pkcs7->signerInfo, 0, sizeof(PKCS7SignerInfo));
  919. return 0;
  920. }
  921. static void wc_PKCS7_SignerInfoFree(PKCS7* pkcs7)
  922. {
  923. if (pkcs7->signerInfo != NULL) {
  924. if (pkcs7->signerInfo->sid != NULL) {
  925. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  926. pkcs7->signerInfo->sid = NULL;
  927. }
  928. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  929. pkcs7->signerInfo = NULL;
  930. }
  931. }
  932. /* free's any current SID and sets it to "in"
  933. * returns 0 on success
  934. */
  935. static int wc_PKCS7_SignerInfoSetSID(PKCS7* pkcs7, byte* in, int inSz)
  936. {
  937. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  938. return BAD_FUNC_ARG;
  939. }
  940. if (pkcs7->signerInfo->sid != NULL) {
  941. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  942. pkcs7->signerInfo->sid = NULL;
  943. }
  944. pkcs7->signerInfo->sid = (byte*)XMALLOC(inSz, pkcs7->heap,
  945. DYNAMIC_TYPE_PKCS7);
  946. if (pkcs7->signerInfo->sid == NULL) {
  947. return MEMORY_E;
  948. }
  949. XMEMCPY(pkcs7->signerInfo->sid, in, inSz);
  950. pkcs7->signerInfo->sidSz = inSz;
  951. return 0;
  952. }
  953. /* releases any memory allocated by a PKCS7 initializer */
  954. void wc_PKCS7_Free(PKCS7* pkcs7)
  955. {
  956. if (pkcs7 == NULL)
  957. return;
  958. #ifndef NO_PKCS7_STREAM
  959. wc_PKCS7_FreeStream(pkcs7);
  960. #endif
  961. wc_PKCS7_SignerInfoFree(pkcs7);
  962. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  963. wc_PKCS7_FreeCertSet(pkcs7);
  964. #ifdef ASN_BER_TO_DER
  965. if (pkcs7->der != NULL)
  966. XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  967. #endif
  968. if (pkcs7->contentDynamic != NULL)
  969. XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  970. if (pkcs7->cek != NULL) {
  971. ForceZero(pkcs7->cek, pkcs7->cekSz);
  972. XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  973. }
  974. pkcs7->contentTypeSz = 0;
  975. if (pkcs7->signature) {
  976. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  977. pkcs7->signature = NULL;
  978. pkcs7->signatureSz = 0;
  979. }
  980. if (pkcs7->plainDigest) {
  981. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  982. pkcs7->plainDigest = NULL;
  983. pkcs7->plainDigestSz = 0;
  984. }
  985. if (pkcs7->pkcs7Digest) {
  986. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  987. pkcs7->pkcs7Digest = NULL;
  988. pkcs7->pkcs7DigestSz = 0;
  989. }
  990. if (pkcs7->cachedEncryptedContent != NULL) {
  991. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  992. pkcs7->cachedEncryptedContent = NULL;
  993. pkcs7->cachedEncryptedContentSz = 0;
  994. }
  995. if (pkcs7->isDynamic) {
  996. pkcs7->isDynamic = 0;
  997. XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  998. }
  999. }
  1000. /* helper function for parsing through attributes and finding a specific one.
  1001. * returns PKCS7DecodedAttrib pointer on success */
  1002. static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)
  1003. {
  1004. PKCS7DecodedAttrib* list;
  1005. if (pkcs7 == NULL || oid == NULL) {
  1006. return NULL;
  1007. }
  1008. /* search attributes for pkiStatus */
  1009. list = pkcs7->decodedAttrib;
  1010. while (list != NULL) {
  1011. word32 sz = oidSz;
  1012. word32 idx = 0;
  1013. int length = 0;
  1014. byte tag;
  1015. if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {
  1016. return NULL;
  1017. }
  1018. if (tag != ASN_OBJECT_ID) {
  1019. WOLFSSL_MSG("Bad attribute ASN1 syntax");
  1020. return NULL;
  1021. }
  1022. if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {
  1023. WOLFSSL_MSG("Bad attribute length");
  1024. return NULL;
  1025. }
  1026. sz = (sz < (word32)length)? sz : (word32)length;
  1027. if (XMEMCMP(oid, list->oid + idx, sz) == 0) {
  1028. return list;
  1029. }
  1030. list = list->next;
  1031. }
  1032. return NULL;
  1033. }
  1034. /* Searches through decoded attributes and returns the value for the first one
  1035. * matching the oid passed in. Note that this value includes the leading ASN1
  1036. * syntax. So for a printable string of "3" this would be something like
  1037. *
  1038. * 0x13, 0x01, 0x33
  1039. * ID SIZE "3"
  1040. *
  1041. * pkcs7 structure to get value from
  1042. * oid OID value to search for with attributes
  1043. * oidSz size of oid buffer
  1044. * out buffer to hold result
  1045. * outSz size of out buffer (if out is NULL this is set to needed size and
  1046. LENGTH_ONLY_E is returned)
  1047. *
  1048. * returns size of value on success
  1049. */
  1050. int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,
  1051. byte* out, word32* outSz)
  1052. {
  1053. PKCS7DecodedAttrib* attrib;
  1054. if (pkcs7 == NULL || oid == NULL || outSz == NULL) {
  1055. return BAD_FUNC_ARG;
  1056. }
  1057. attrib = findAttrib(pkcs7, oid, oidSz);
  1058. if (attrib == NULL) {
  1059. return ASN_PARSE_E;
  1060. }
  1061. if (out == NULL) {
  1062. *outSz = attrib->valueSz;
  1063. return LENGTH_ONLY_E;
  1064. }
  1065. if (*outSz < attrib->valueSz) {
  1066. return BUFFER_E;
  1067. }
  1068. XMEMCPY(out, attrib->value, attrib->valueSz);
  1069. return attrib->valueSz;
  1070. }
  1071. /* build PKCS#7 data content type */
  1072. int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
  1073. {
  1074. static const byte oid[] =
  1075. { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
  1076. 0x07, 0x01 };
  1077. byte seq[MAX_SEQ_SZ];
  1078. byte octetStr[MAX_OCTET_STR_SZ];
  1079. word32 seqSz;
  1080. word32 octetStrSz;
  1081. word32 oidSz = (word32)sizeof(oid);
  1082. int idx = 0;
  1083. if (pkcs7 == NULL || output == NULL) {
  1084. return BAD_FUNC_ARG;
  1085. }
  1086. octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
  1087. seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
  1088. if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
  1089. return BUFFER_E;
  1090. XMEMCPY(output, seq, seqSz);
  1091. idx += seqSz;
  1092. XMEMCPY(output + idx, oid, oidSz);
  1093. idx += oidSz;
  1094. XMEMCPY(output + idx, octetStr, octetStrSz);
  1095. idx += octetStrSz;
  1096. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  1097. idx += pkcs7->contentSz;
  1098. return idx;
  1099. }
  1100. typedef struct EncodedAttrib {
  1101. byte valueSeq[MAX_SEQ_SZ];
  1102. const byte* oid;
  1103. byte valueSet[MAX_SET_SZ];
  1104. const byte* value;
  1105. word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
  1106. } EncodedAttrib;
  1107. typedef struct ESD {
  1108. wc_HashAlg hash;
  1109. enum wc_HashType hashType;
  1110. byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
  1111. byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];
  1112. byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];
  1113. byte outerSeq[MAX_SEQ_SZ];
  1114. byte outerContent[MAX_EXP_SZ];
  1115. byte innerSeq[MAX_SEQ_SZ];
  1116. byte version[MAX_VERSION_SZ];
  1117. byte digAlgoIdSet[MAX_SET_SZ];
  1118. byte singleDigAlgoId[MAX_ALGO_SZ];
  1119. byte contentInfoSeq[MAX_SEQ_SZ];
  1120. byte innerContSeq[MAX_EXP_SZ];
  1121. byte innerOctets[MAX_OCTET_STR_SZ];
  1122. byte certsSet[MAX_SET_SZ];
  1123. byte signerInfoSet[MAX_SET_SZ];
  1124. byte signerInfoSeq[MAX_SEQ_SZ];
  1125. byte signerVersion[MAX_VERSION_SZ];
  1126. /* issuerAndSerialNumber ...*/
  1127. byte issuerSnSeq[MAX_SEQ_SZ];
  1128. byte issuerName[MAX_SEQ_SZ];
  1129. byte issuerSn[MAX_SN_SZ];
  1130. /* OR subjectKeyIdentifier */
  1131. byte issuerSKIDSeq[MAX_SEQ_SZ];
  1132. byte issuerSKID[MAX_OCTET_STR_SZ];
  1133. byte signerDigAlgoId[MAX_ALGO_SZ];
  1134. byte digEncAlgoId[MAX_ALGO_SZ];
  1135. byte signedAttribSet[MAX_SET_SZ];
  1136. EncodedAttrib signedAttribs[7];
  1137. byte signerDigest[MAX_OCTET_STR_SZ];
  1138. word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
  1139. word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
  1140. singleDigAlgoIdSz, certsSetSz;
  1141. word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
  1142. issuerSnSeqSz, issuerNameSz, issuerSnSz, issuerSKIDSz,
  1143. issuerSKIDSeqSz, signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
  1144. word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
  1145. signedAttribSetSz;
  1146. } ESD;
  1147. static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
  1148. PKCS7Attrib* attribs, int attribsSz)
  1149. {
  1150. int i;
  1151. int maxSz = min(eaSz, attribsSz);
  1152. int allAttribsSz = 0;
  1153. for (i = 0; i < maxSz; i++)
  1154. {
  1155. int attribSz = 0;
  1156. ea[i].value = attribs[i].value;
  1157. ea[i].valueSz = attribs[i].valueSz;
  1158. attribSz += ea[i].valueSz;
  1159. ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
  1160. attribSz += ea[i].valueSetSz;
  1161. ea[i].oid = attribs[i].oid;
  1162. ea[i].oidSz = attribs[i].oidSz;
  1163. attribSz += ea[i].oidSz;
  1164. ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
  1165. attribSz += ea[i].valueSeqSz;
  1166. ea[i].totalSz = attribSz;
  1167. allAttribsSz += attribSz;
  1168. }
  1169. return allAttribsSz;
  1170. }
  1171. typedef struct FlatAttrib {
  1172. byte* data;
  1173. word32 dataSz;
  1174. } FlatAttrib;
  1175. /* Returns a pointer to FlatAttrib whose members are initialized to 0.
  1176. * Caller is expected to free.
  1177. */
  1178. static FlatAttrib* NewAttrib(void* heap)
  1179. {
  1180. FlatAttrib* fb = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), heap,
  1181. DYNAMIC_TYPE_TMP_BUFFER);
  1182. if (fb != NULL) {
  1183. ForceZero(fb, sizeof(FlatAttrib));
  1184. }
  1185. (void)heap;
  1186. return fb;
  1187. }
  1188. /* Free FlatAttrib array and memory allocated to internal struct members */
  1189. static void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)
  1190. {
  1191. int i;
  1192. if (arr) {
  1193. for (i = 0; i < rows; i++) {
  1194. if (arr[i]) {
  1195. if (arr[i]->data) {
  1196. ForceZero(arr[i]->data, arr[i]->dataSz);
  1197. XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1198. }
  1199. ForceZero(arr[i], sizeof(FlatAttrib));
  1200. XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1201. }
  1202. }
  1203. ForceZero(arr, rows);
  1204. XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1205. }
  1206. (void)pkcs7;
  1207. }
  1208. /* Sort FlatAttrib array in ascending order */
  1209. static int SortAttribArray(FlatAttrib** arr, int rows)
  1210. {
  1211. int i, j;
  1212. word32 minSz, minIdx;
  1213. FlatAttrib* a = NULL;
  1214. FlatAttrib* b = NULL;
  1215. FlatAttrib* tmp = NULL;
  1216. if (arr == NULL) {
  1217. return BAD_FUNC_ARG;
  1218. }
  1219. for (i = 0; i < rows; i++) {
  1220. a = arr[i];
  1221. minSz = a->dataSz;
  1222. minIdx = i;
  1223. for (j = i+1; j < rows; j++) {
  1224. b = arr[j];
  1225. if (b->dataSz < minSz) {
  1226. minSz = b->dataSz;
  1227. minIdx = j;
  1228. }
  1229. }
  1230. if (minSz < a->dataSz) {
  1231. /* swap array positions */
  1232. tmp = arr[i];
  1233. arr[i] = arr[minIdx];
  1234. arr[minIdx] = tmp;
  1235. }
  1236. }
  1237. return 0;
  1238. }
  1239. /* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib
  1240. * holds flattened DER encoding of each attribute */
  1241. static int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,
  1242. EncodedAttrib* ea, int eaSz)
  1243. {
  1244. int i, idx, sz;
  1245. byte* output = NULL;
  1246. FlatAttrib* fa = NULL;
  1247. if (pkcs7 == NULL || derArr == NULL || ea == NULL) {
  1248. WOLFSSL_MSG("Invalid arguments to FlattenEncodedAttribs");
  1249. return BAD_FUNC_ARG;
  1250. }
  1251. if (rows != eaSz) {
  1252. WOLFSSL_MSG("DER array not large enough to hold attribute count");
  1253. return BAD_FUNC_ARG;
  1254. }
  1255. for (i = 0; i < eaSz; i++) {
  1256. sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;
  1257. output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1258. if (output == NULL) {
  1259. return MEMORY_E;
  1260. }
  1261. idx = 0;
  1262. XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
  1263. idx += ea[i].valueSeqSz;
  1264. XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
  1265. idx += ea[i].oidSz;
  1266. XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
  1267. idx += ea[i].valueSetSz;
  1268. XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
  1269. fa = derArr[i];
  1270. fa->data = output;
  1271. fa->dataSz = sz;
  1272. }
  1273. return 0;
  1274. }
  1275. /* Sort and Flatten EncodedAttrib attributes into output buffer */
  1276. static int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,
  1277. int eaSz)
  1278. {
  1279. int i, idx, ret;
  1280. FlatAttrib** derArr = NULL;
  1281. FlatAttrib* fa = NULL;
  1282. if (pkcs7 == NULL || output == NULL || ea == NULL) {
  1283. return BAD_FUNC_ARG;
  1284. }
  1285. /* create array of FlatAttrib struct pointers to hold DER attribs */
  1286. derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,
  1287. DYNAMIC_TYPE_TMP_BUFFER);
  1288. if (derArr == NULL) {
  1289. return MEMORY_E;
  1290. }
  1291. XMEMSET(derArr, 0, eaSz * sizeof(FlatAttrib*));
  1292. for (i = 0; i < eaSz; i++) {
  1293. derArr[i] = NewAttrib(pkcs7->heap);
  1294. if (derArr[i] == NULL) {
  1295. FreeAttribArray(pkcs7, derArr, eaSz);
  1296. return MEMORY_E;
  1297. }
  1298. ForceZero(derArr[i], sizeof(FlatAttrib));
  1299. }
  1300. /* flatten EncodedAttrib into DER byte arrays */
  1301. ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);
  1302. if (ret != 0) {
  1303. FreeAttribArray(pkcs7, derArr, eaSz);
  1304. return ret;
  1305. }
  1306. /* SET OF DER signed attributes must be sorted in ascending order */
  1307. ret = SortAttribArray(derArr, eaSz);
  1308. if (ret != 0) {
  1309. FreeAttribArray(pkcs7, derArr, eaSz);
  1310. return ret;
  1311. }
  1312. /* copy sorted DER attribute arrays into output buffer */
  1313. idx = 0;
  1314. for (i = 0; i < eaSz; i++) {
  1315. fa = derArr[i];
  1316. XMEMCPY(output + idx, fa->data, fa->dataSz);
  1317. idx += fa->dataSz;
  1318. }
  1319. FreeAttribArray(pkcs7, derArr, eaSz);
  1320. return 0;
  1321. }
  1322. #ifndef NO_RSA
  1323. /* returns size of signature put into out, negative on error */
  1324. static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1325. {
  1326. int ret;
  1327. word32 idx;
  1328. #ifdef WOLFSSL_SMALL_STACK
  1329. RsaKey* privKey;
  1330. #else
  1331. RsaKey privKey[1];
  1332. #endif
  1333. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1334. return BAD_FUNC_ARG;
  1335. }
  1336. #ifdef WOLFSSL_SMALL_STACK
  1337. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  1338. DYNAMIC_TYPE_TMP_BUFFER);
  1339. if (privKey == NULL)
  1340. return MEMORY_E;
  1341. #endif
  1342. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
  1343. if (ret == 0) {
  1344. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1345. idx = 0;
  1346. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1347. pkcs7->privateKeySz);
  1348. }
  1349. else if (pkcs7->devId == INVALID_DEVID) {
  1350. ret = BAD_FUNC_ARG;
  1351. }
  1352. }
  1353. if (ret == 0) {
  1354. #ifdef WOLFSSL_ASYNC_CRYPT
  1355. do {
  1356. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1357. WC_ASYNC_FLAG_CALL_AGAIN);
  1358. if (ret >= 0)
  1359. #endif
  1360. {
  1361. ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
  1362. sizeof(esd->encContentDigest),
  1363. privKey, pkcs7->rng);
  1364. }
  1365. #ifdef WOLFSSL_ASYNC_CRYPT
  1366. } while (ret == WC_PENDING_E);
  1367. #endif
  1368. }
  1369. wc_FreeRsaKey(privKey);
  1370. #ifdef WOLFSSL_SMALL_STACK
  1371. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1372. #endif
  1373. return ret;
  1374. }
  1375. #endif /* NO_RSA */
  1376. #ifdef HAVE_ECC
  1377. /* returns size of signature put into out, negative on error */
  1378. static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1379. {
  1380. int ret;
  1381. word32 outSz, idx;
  1382. #ifdef WOLFSSL_SMALL_STACK
  1383. ecc_key* privKey;
  1384. #else
  1385. ecc_key privKey[1];
  1386. #endif
  1387. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1388. return BAD_FUNC_ARG;
  1389. }
  1390. #ifdef WOLFSSL_SMALL_STACK
  1391. privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  1392. DYNAMIC_TYPE_TMP_BUFFER);
  1393. if (privKey == NULL)
  1394. return MEMORY_E;
  1395. #endif
  1396. ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);
  1397. if (ret == 0) {
  1398. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1399. idx = 0;
  1400. ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1401. pkcs7->privateKeySz);
  1402. }
  1403. else if (pkcs7->devId == INVALID_DEVID) {
  1404. ret = BAD_FUNC_ARG;
  1405. }
  1406. }
  1407. if (ret == 0) {
  1408. outSz = sizeof(esd->encContentDigest);
  1409. #ifdef WOLFSSL_ASYNC_CRYPT
  1410. do {
  1411. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1412. WC_ASYNC_FLAG_CALL_AGAIN);
  1413. if (ret >= 0)
  1414. #endif
  1415. {
  1416. ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
  1417. &outSz, pkcs7->rng, privKey);
  1418. }
  1419. #ifdef WOLFSSL_ASYNC_CRYPT
  1420. } while (ret == WC_PENDING_E);
  1421. #endif
  1422. if (ret == 0)
  1423. ret = (int)outSz;
  1424. }
  1425. wc_ecc_free(privKey);
  1426. #ifdef WOLFSSL_SMALL_STACK
  1427. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1428. #endif
  1429. return ret;
  1430. }
  1431. #endif /* HAVE_ECC */
  1432. /* builds up SignedData signed attributes, including default ones.
  1433. *
  1434. * pkcs7 - pointer to initialized PKCS7 structure
  1435. * esd - pointer to initialized ESD structure, used for output
  1436. *
  1437. * return 0 on success, negative on error */
  1438. static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
  1439. const byte* contentType, word32 contentTypeSz,
  1440. const byte* contentTypeOid, word32 contentTypeOidSz,
  1441. const byte* messageDigestOid, word32 messageDigestOidSz,
  1442. const byte* signingTimeOid, word32 signingTimeOidSz,
  1443. byte* signingTime, word32 signingTimeSz)
  1444. {
  1445. int hashSz;
  1446. #ifdef NO_ASN_TIME
  1447. PKCS7Attrib cannedAttribs[2];
  1448. #else
  1449. time_t tm;
  1450. int timeSz;
  1451. PKCS7Attrib cannedAttribs[3];
  1452. #endif
  1453. word32 idx = 0;
  1454. word32 cannedAttribsCount;
  1455. if (pkcs7 == NULL || esd == NULL || contentType == NULL ||
  1456. contentTypeOid == NULL || messageDigestOid == NULL ||
  1457. signingTimeOid == NULL) {
  1458. return BAD_FUNC_ARG;
  1459. }
  1460. if (pkcs7->skipDefaultSignedAttribs == 0) {
  1461. hashSz = wc_HashGetDigestSize(esd->hashType);
  1462. if (hashSz < 0)
  1463. return hashSz;
  1464. #ifndef NO_ASN_TIME
  1465. if (signingTime == NULL || signingTimeSz == 0)
  1466. return BAD_FUNC_ARG;
  1467. tm = XTIME(0);
  1468. timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz);
  1469. if (timeSz < 0)
  1470. return timeSz;
  1471. #endif
  1472. cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
  1473. cannedAttribs[idx].oid = contentTypeOid;
  1474. cannedAttribs[idx].oidSz = contentTypeOidSz;
  1475. cannedAttribs[idx].value = contentType;
  1476. cannedAttribs[idx].valueSz = contentTypeSz;
  1477. idx++;
  1478. #ifndef NO_ASN_TIME
  1479. cannedAttribs[idx].oid = signingTimeOid;
  1480. cannedAttribs[idx].oidSz = signingTimeOidSz;
  1481. cannedAttribs[idx].value = signingTime;
  1482. cannedAttribs[idx].valueSz = timeSz;
  1483. idx++;
  1484. #endif
  1485. cannedAttribs[idx].oid = messageDigestOid;
  1486. cannedAttribs[idx].oidSz = messageDigestOidSz;
  1487. cannedAttribs[idx].value = esd->contentDigest;
  1488. cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */
  1489. esd->signedAttribsCount += cannedAttribsCount;
  1490. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3,
  1491. cannedAttribs, cannedAttribsCount);
  1492. } else {
  1493. esd->signedAttribsCount = 0;
  1494. esd->signedAttribsSz = 0;
  1495. }
  1496. /* add custom signed attributes if set */
  1497. if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) {
  1498. esd->signedAttribsCount += pkcs7->signedAttribsSz;
  1499. #ifdef NO_ASN_TIME
  1500. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
  1501. pkcs7->signedAttribs, pkcs7->signedAttribsSz);
  1502. #else
  1503. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4,
  1504. pkcs7->signedAttribs, pkcs7->signedAttribsSz);
  1505. #endif
  1506. }
  1507. #ifdef NO_ASN_TIME
  1508. (void)signingTimeOidSz;
  1509. (void)signingTime;
  1510. (void)signingTimeSz;
  1511. #endif
  1512. return 0;
  1513. }
  1514. /* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or
  1515. * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.
  1516. *
  1517. * pkcs7 - pointer to PKCS7 structure
  1518. * digEncAlgoId - [OUT] output int to store correct algo ID in
  1519. * digEncAlgoType - [OUT] output for algo ID type
  1520. *
  1521. * return 0 on success, negative on error */
  1522. static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
  1523. int* digEncAlgoType)
  1524. {
  1525. int algoId = 0;
  1526. int algoType = 0;
  1527. if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
  1528. return BAD_FUNC_ARG;
  1529. if (pkcs7->publicKeyOID == RSAk) {
  1530. algoType = oidSigType;
  1531. switch (pkcs7->hashOID) {
  1532. #ifndef NO_SHA
  1533. case SHAh:
  1534. algoId = CTC_SHAwRSA;
  1535. break;
  1536. #endif
  1537. #ifdef WOLFSSL_SHA224
  1538. case SHA224h:
  1539. algoId = CTC_SHA224wRSA;
  1540. break;
  1541. #endif
  1542. #ifndef NO_SHA256
  1543. case SHA256h:
  1544. algoId = CTC_SHA256wRSA;
  1545. break;
  1546. #endif
  1547. #ifdef WOLFSSL_SHA384
  1548. case SHA384h:
  1549. algoId = CTC_SHA384wRSA;
  1550. break;
  1551. #endif
  1552. #ifdef WOLFSSL_SHA512
  1553. case SHA512h:
  1554. algoId = CTC_SHA512wRSA;
  1555. break;
  1556. #endif
  1557. }
  1558. }
  1559. #ifdef HAVE_ECC
  1560. else if (pkcs7->publicKeyOID == ECDSAk) {
  1561. algoType = oidSigType;
  1562. switch (pkcs7->hashOID) {
  1563. #ifndef NO_SHA
  1564. case SHAh:
  1565. algoId = CTC_SHAwECDSA;
  1566. break;
  1567. #endif
  1568. #ifdef WOLFSSL_SHA224
  1569. case SHA224h:
  1570. algoId = CTC_SHA224wECDSA;
  1571. break;
  1572. #endif
  1573. #ifndef NO_SHA256
  1574. case SHA256h:
  1575. algoId = CTC_SHA256wECDSA;
  1576. break;
  1577. #endif
  1578. #ifdef WOLFSSL_SHA384
  1579. case SHA384h:
  1580. algoId = CTC_SHA384wECDSA;
  1581. break;
  1582. #endif
  1583. #ifdef WOLFSSL_SHA512
  1584. case SHA512h:
  1585. algoId = CTC_SHA512wECDSA;
  1586. break;
  1587. #endif
  1588. }
  1589. }
  1590. #endif /* HAVE_ECC */
  1591. if (algoId == 0) {
  1592. WOLFSSL_MSG("Invalid signature algorithm type");
  1593. return BAD_FUNC_ARG;
  1594. }
  1595. *digEncAlgoId = algoId;
  1596. *digEncAlgoType = algoType;
  1597. return 0;
  1598. }
  1599. /* build SignedData DigestInfo for use with PKCS#7/RSA
  1600. *
  1601. * pkcs7 - pointer to initialized PKCS7 struct
  1602. * flatSignedAttribs - flattened, signed attributes
  1603. * flatSignedAttrbsSz - size of flatSignedAttribs, octets
  1604. * esd - pointer to initialized ESD struct
  1605. * digestInfo - [OUT] output array for DigestInfo
  1606. * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
  1607. *
  1608. * return 0 on success, negative on error */
  1609. static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
  1610. word32 flatSignedAttribsSz, ESD* esd,
  1611. byte* digestInfo, word32* digestInfoSz)
  1612. {
  1613. int ret, hashSz, digIdx = 0;
  1614. byte digestInfoSeq[MAX_SEQ_SZ];
  1615. byte digestStr[MAX_OCTET_STR_SZ];
  1616. byte attribSet[MAX_SET_SZ];
  1617. byte algoId[MAX_ALGO_SZ];
  1618. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  1619. word32 attribSetSz;
  1620. if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||
  1621. digestInfoSz == NULL) {
  1622. return BAD_FUNC_ARG;
  1623. }
  1624. hashSz = wc_HashGetDigestSize(esd->hashType);
  1625. if (hashSz < 0)
  1626. return hashSz;
  1627. if (flatSignedAttribsSz != 0) {
  1628. if (flatSignedAttribs == NULL)
  1629. return BAD_FUNC_ARG;
  1630. attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
  1631. ret = wc_HashInit(&esd->hash, esd->hashType);
  1632. if (ret < 0)
  1633. return ret;
  1634. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1635. attribSet, attribSetSz);
  1636. if (ret == 0)
  1637. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1638. flatSignedAttribs, flatSignedAttribsSz);
  1639. if (ret == 0)
  1640. ret = wc_HashFinal(&esd->hash, esd->hashType,
  1641. esd->contentAttribsDigest);
  1642. wc_HashFree(&esd->hash, esd->hashType);
  1643. if (ret < 0)
  1644. return ret;
  1645. } else {
  1646. /* when no attrs, digest is contentDigest without tag and length */
  1647. XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);
  1648. }
  1649. /* set algoID, with NULL attributes */
  1650. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  1651. digestStrSz = SetOctetString(hashSz, digestStr);
  1652. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  1653. digestInfoSeq);
  1654. if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {
  1655. return BUFFER_E;
  1656. }
  1657. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  1658. digIdx += digestInfoSeqSz;
  1659. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  1660. digIdx += algoIdSz;
  1661. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  1662. digIdx += digestStrSz;
  1663. XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);
  1664. digIdx += hashSz;
  1665. *digestInfoSz = digIdx;
  1666. return 0;
  1667. }
  1668. /* build SignedData signature over DigestInfo or content digest
  1669. *
  1670. * pkcs7 - pointer to initialized PKCS7 struct
  1671. * flatSignedAttribs - flattened, signed attributes
  1672. * flatSignedAttribsSz - size of flatSignedAttribs, octets
  1673. * esd - pointer to initialized ESD struct
  1674. *
  1675. * returns length of signature on success, negative on error */
  1676. static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
  1677. byte* flatSignedAttribs,
  1678. word32 flatSignedAttribsSz,
  1679. ESD* esd)
  1680. {
  1681. int ret = 0;
  1682. #if defined(HAVE_ECC) || \
  1683. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1684. int hashSz = 0;
  1685. #endif
  1686. #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
  1687. int hashOID;
  1688. #endif
  1689. word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
  1690. #ifdef WOLFSSL_SMALL_STACK
  1691. byte* digestInfo;
  1692. #else
  1693. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  1694. #endif
  1695. if (pkcs7 == NULL || esd == NULL)
  1696. return BAD_FUNC_ARG;
  1697. #ifdef WOLFSSL_SMALL_STACK
  1698. digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,
  1699. DYNAMIC_TYPE_TMP_BUFFER);
  1700. if (digestInfo == NULL) {
  1701. return MEMORY_E;
  1702. }
  1703. #endif
  1704. XMEMSET(digestInfo, 0, digestInfoSz);
  1705. ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
  1706. flatSignedAttribsSz, esd, digestInfo,
  1707. &digestInfoSz);
  1708. if (ret < 0) {
  1709. #ifdef WOLFSSL_SMALL_STACK
  1710. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1711. #endif
  1712. return ret;
  1713. }
  1714. #if defined(HAVE_ECC) || \
  1715. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1716. /* get digest size from hash type */
  1717. hashSz = wc_HashGetDigestSize(esd->hashType);
  1718. if (hashSz < 0) {
  1719. #ifdef WOLFSSL_SMALL_STACK
  1720. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1721. #endif
  1722. return hashSz;
  1723. }
  1724. #endif
  1725. /* sign digestInfo */
  1726. switch (pkcs7->publicKeyOID) {
  1727. #ifndef NO_RSA
  1728. case RSAk:
  1729. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  1730. if (pkcs7->rsaSignRawDigestCb != NULL) {
  1731. /* get hash OID */
  1732. hashOID = wc_HashGetOID(esd->hashType);
  1733. /* user signing plain digest, build DigestInfo themselves */
  1734. ret = pkcs7->rsaSignRawDigestCb(pkcs7,
  1735. esd->contentAttribsDigest, hashSz,
  1736. esd->encContentDigest, sizeof(esd->encContentDigest),
  1737. pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
  1738. hashOID);
  1739. break;
  1740. }
  1741. #endif
  1742. ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
  1743. break;
  1744. #endif
  1745. #ifdef HAVE_ECC
  1746. case ECDSAk:
  1747. /* CMS with ECDSA does not sign DigestInfo structure
  1748. * like PKCS#7 with RSA does */
  1749. ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
  1750. hashSz, esd);
  1751. break;
  1752. #endif
  1753. default:
  1754. WOLFSSL_MSG("Unsupported public key type");
  1755. ret = BAD_FUNC_ARG;
  1756. }
  1757. #ifdef WOLFSSL_SMALL_STACK
  1758. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1759. #endif
  1760. if (ret >= 0) {
  1761. esd->encContentDigestSz = (word32)ret;
  1762. }
  1763. return ret;
  1764. }
  1765. /* build PKCS#7 signedData content type */
  1766. static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
  1767. const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,
  1768. byte* output2, word32* output2Sz)
  1769. {
  1770. /* contentType OID (1.2.840.113549.1.9.3) */
  1771. const byte contentTypeOid[] =
  1772. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  1773. 0x09, 0x03 };
  1774. /* messageDigest OID (1.2.840.113549.1.9.4) */
  1775. const byte messageDigestOid[] =
  1776. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  1777. 0x09, 0x04 };
  1778. /* signingTime OID () */
  1779. byte signingTimeOid[] =
  1780. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  1781. 0x09, 0x05};
  1782. Pkcs7Cert* certPtr = NULL;
  1783. word32 certSetSz = 0;
  1784. word32 signerInfoSz = 0;
  1785. word32 totalSz, total2Sz;
  1786. int idx = 0, ret = 0;
  1787. int digEncAlgoId, digEncAlgoType;
  1788. byte* flatSignedAttribs = NULL;
  1789. word32 flatSignedAttribsSz = 0;
  1790. byte signedDataOid[MAX_OID_SZ];
  1791. word32 signedDataOidSz;
  1792. byte signingTime[MAX_TIME_STRING_SZ];
  1793. if (pkcs7 == NULL || pkcs7->contentSz == 0 ||
  1794. pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
  1795. output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 ||
  1796. hashBuf == NULL) {
  1797. return BAD_FUNC_ARG;
  1798. }
  1799. /* verify the hash size matches */
  1800. #ifdef WOLFSSL_SMALL_STACK
  1801. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1802. if (esd == NULL)
  1803. return MEMORY_E;
  1804. #endif
  1805. XMEMSET(esd, 0, sizeof(ESD));
  1806. /* set content type based on contentOID, unless user has set custom one
  1807. with wc_PKCS7_SetContentType() */
  1808. if (pkcs7->contentTypeSz == 0) {
  1809. /* default to DATA content type if user has not set */
  1810. if (pkcs7->contentOID == 0) {
  1811. pkcs7->contentOID = DATA;
  1812. }
  1813. ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType,
  1814. sizeof(pkcs7->contentType));
  1815. if (ret < 0) {
  1816. #ifdef WOLFSSL_SMALL_STACK
  1817. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1818. #endif
  1819. return ret;
  1820. }
  1821. pkcs7->contentTypeSz = ret;
  1822. }
  1823. /* set signedData outer content type */
  1824. ret = wc_SetContentType(SIGNED_DATA, signedDataOid, sizeof(signedDataOid));
  1825. if (ret < 0) {
  1826. #ifdef WOLFSSL_SMALL_STACK
  1827. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1828. #endif
  1829. return ret;
  1830. }
  1831. signedDataOidSz = ret;
  1832. if (pkcs7->sidType != DEGENERATE_SID) {
  1833. esd->hashType = wc_OidGetHash(pkcs7->hashOID);
  1834. if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
  1835. WOLFSSL_MSG("hashSz did not match hashOID");
  1836. #ifdef WOLFSSL_SMALL_STACK
  1837. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1838. #endif
  1839. return BUFFER_E;
  1840. }
  1841. /* include hash */
  1842. esd->contentDigest[0] = ASN_OCTET_STRING;
  1843. esd->contentDigest[1] = (byte)hashSz;
  1844. XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
  1845. }
  1846. if (pkcs7->detached == 1) {
  1847. /* do not include content if generating detached signature */
  1848. esd->innerOctetsSz = 0;
  1849. esd->innerContSeqSz = 0;
  1850. esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz,
  1851. esd->contentInfoSeq);
  1852. } else {
  1853. esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
  1854. esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz +
  1855. pkcs7->contentSz, esd->innerContSeq);
  1856. esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz +
  1857. esd->innerOctetsSz + pkcs7->contentTypeSz +
  1858. esd->innerContSeqSz, esd->contentInfoSeq);
  1859. }
  1860. /* SignerIdentifier */
  1861. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  1862. /* IssuerAndSerialNumber */
  1863. esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
  1864. esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ);
  1865. signerInfoSz += esd->issuerSnSz;
  1866. esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
  1867. signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
  1868. esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
  1869. signerInfoSz += esd->issuerSnSeqSz;
  1870. if (pkcs7->version == 3) {
  1871. /* RFC 4108 version MUST be 3 for firmware package signer */
  1872. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  1873. }
  1874. else {
  1875. /* version MUST be 1 otherwise*/
  1876. esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
  1877. }
  1878. } else if (pkcs7->sidType == CMS_SKID) {
  1879. /* SubjectKeyIdentifier */
  1880. esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID);
  1881. esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE,
  1882. esd->issuerSKIDSeq);
  1883. signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz +
  1884. KEYID_SIZE);
  1885. /* version MUST be 3 */
  1886. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  1887. } else if (pkcs7->sidType == DEGENERATE_SID) {
  1888. /* no signer info added */
  1889. } else {
  1890. #ifdef WOLFSSL_SMALL_STACK
  1891. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1892. #endif
  1893. return SKID_E;
  1894. }
  1895. if (pkcs7->sidType != DEGENERATE_SID) {
  1896. signerInfoSz += esd->signerVersionSz;
  1897. esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
  1898. oidHashType, 0);
  1899. signerInfoSz += esd->signerDigAlgoIdSz;
  1900. /* set signatureAlgorithm */
  1901. ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
  1902. &digEncAlgoType);
  1903. if (ret < 0) {
  1904. #ifdef WOLFSSL_SMALL_STACK
  1905. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1906. #endif
  1907. return ret;
  1908. }
  1909. esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
  1910. digEncAlgoType, 0);
  1911. signerInfoSz += esd->digEncAlgoIdSz;
  1912. /* build up signed attributes, include contentType, signingTime, and
  1913. messageDigest by default */
  1914. ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType,
  1915. pkcs7->contentTypeSz,
  1916. contentTypeOid, sizeof(contentTypeOid),
  1917. messageDigestOid, sizeof(messageDigestOid),
  1918. signingTimeOid, sizeof(signingTimeOid),
  1919. signingTime, sizeof(signingTime));
  1920. if (ret < 0) {
  1921. #ifdef WOLFSSL_SMALL_STACK
  1922. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1923. #endif
  1924. return ret;
  1925. }
  1926. if (esd->signedAttribsSz > 0) {
  1927. flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
  1928. DYNAMIC_TYPE_PKCS7);
  1929. flatSignedAttribsSz = esd->signedAttribsSz;
  1930. if (flatSignedAttribs == NULL) {
  1931. #ifdef WOLFSSL_SMALL_STACK
  1932. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1933. #endif
  1934. return MEMORY_E;
  1935. }
  1936. FlattenAttributes(pkcs7, flatSignedAttribs,
  1937. esd->signedAttribs, esd->signedAttribsCount);
  1938. esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
  1939. esd->signedAttribSet);
  1940. } else {
  1941. esd->signedAttribSetSz = 0;
  1942. }
  1943. /* Calculate the final hash and encrypt it. */
  1944. ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
  1945. flatSignedAttribsSz, esd);
  1946. if (ret < 0) {
  1947. if (pkcs7->signedAttribsSz != 0)
  1948. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1949. #ifdef WOLFSSL_SMALL_STACK
  1950. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1951. #endif
  1952. return ret;
  1953. }
  1954. signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
  1955. esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
  1956. esd->signerDigest);
  1957. signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
  1958. esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
  1959. signerInfoSz += esd->signerInfoSeqSz;
  1960. }
  1961. esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
  1962. signerInfoSz += esd->signerInfoSetSz;
  1963. /* certificates [0] IMPLICIT CertificateSet */
  1964. /* get total certificates size */
  1965. certPtr = pkcs7->certList;
  1966. while (certPtr != NULL) {
  1967. certSetSz += certPtr->derSz;
  1968. certPtr = certPtr->next;
  1969. }
  1970. certPtr = NULL;
  1971. if (certSetSz > 0)
  1972. esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet);
  1973. if (pkcs7->sidType != DEGENERATE_SID) {
  1974. esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
  1975. oidHashType, 0);
  1976. }
  1977. esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
  1978. if (pkcs7->version == 3) {
  1979. /* RFC 4108 version MUST be 3 for firmware package signer */
  1980. esd->versionSz = SetMyVersion(3, esd->version, 0);
  1981. }
  1982. else {
  1983. esd->versionSz = SetMyVersion(1, esd->version, 0);
  1984. }
  1985. totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
  1986. esd->contentInfoSeqSz + pkcs7->contentTypeSz +
  1987. esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz;
  1988. total2Sz = esd->certsSetSz + certSetSz + signerInfoSz;
  1989. if (pkcs7->detached) {
  1990. totalSz -= pkcs7->contentSz;
  1991. }
  1992. esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
  1993. totalSz += esd->innerSeqSz;
  1994. esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
  1995. totalSz += esd->outerContentSz + signedDataOidSz;
  1996. esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
  1997. totalSz += esd->outerSeqSz;
  1998. /* if using header/footer, we are not returning the content */
  1999. if (output2 && output2Sz) {
  2000. if (total2Sz > *output2Sz) {
  2001. if (pkcs7->signedAttribsSz != 0)
  2002. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2003. #ifdef WOLFSSL_SMALL_STACK
  2004. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2005. #endif
  2006. return BUFFER_E;
  2007. }
  2008. if (!pkcs7->detached) {
  2009. totalSz -= pkcs7->contentSz;
  2010. }
  2011. }
  2012. else {
  2013. /* if using single output buffer include content and footer */
  2014. totalSz += total2Sz;
  2015. }
  2016. if (totalSz > *outputSz) {
  2017. if (pkcs7->signedAttribsSz != 0)
  2018. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2019. #ifdef WOLFSSL_SMALL_STACK
  2020. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2021. #endif
  2022. return BUFFER_E;
  2023. }
  2024. idx = 0;
  2025. XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
  2026. idx += esd->outerSeqSz;
  2027. XMEMCPY(output + idx, signedDataOid, signedDataOidSz);
  2028. idx += signedDataOidSz;
  2029. XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
  2030. idx += esd->outerContentSz;
  2031. XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
  2032. idx += esd->innerSeqSz;
  2033. XMEMCPY(output + idx, esd->version, esd->versionSz);
  2034. idx += esd->versionSz;
  2035. XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
  2036. idx += esd->digAlgoIdSetSz;
  2037. XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
  2038. idx += esd->singleDigAlgoIdSz;
  2039. XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
  2040. idx += esd->contentInfoSeqSz;
  2041. XMEMCPY(output + idx, pkcs7->contentType, pkcs7->contentTypeSz);
  2042. idx += pkcs7->contentTypeSz;
  2043. XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
  2044. idx += esd->innerContSeqSz;
  2045. XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
  2046. idx += esd->innerOctetsSz;
  2047. /* support returning header and footer without content */
  2048. if (output2 && output2Sz) {
  2049. *outputSz = idx;
  2050. idx = 0;
  2051. }
  2052. else {
  2053. if (!pkcs7->detached) {
  2054. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  2055. idx += pkcs7->contentSz;
  2056. }
  2057. output2 = output;
  2058. }
  2059. /* certificates */
  2060. XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);
  2061. idx += esd->certsSetSz;
  2062. certPtr = pkcs7->certList;
  2063. while (certPtr != NULL) {
  2064. XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz);
  2065. idx += certPtr->derSz;
  2066. certPtr = certPtr->next;
  2067. }
  2068. wc_PKCS7_FreeCertSet(pkcs7);
  2069. XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
  2070. idx += esd->signerInfoSetSz;
  2071. XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
  2072. idx += esd->signerInfoSeqSz;
  2073. XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
  2074. idx += esd->signerVersionSz;
  2075. /* SignerIdentifier */
  2076. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  2077. /* IssuerAndSerialNumber */
  2078. XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
  2079. idx += esd->issuerSnSeqSz;
  2080. XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
  2081. idx += esd->issuerNameSz;
  2082. XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
  2083. idx += pkcs7->issuerSz;
  2084. XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
  2085. idx += esd->issuerSnSz;
  2086. } else if (pkcs7->sidType == CMS_SKID) {
  2087. /* SubjectKeyIdentifier */
  2088. XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz);
  2089. idx += esd->issuerSKIDSeqSz;
  2090. XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz);
  2091. idx += esd->issuerSKIDSz;
  2092. XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
  2093. idx += KEYID_SIZE;
  2094. } else if (pkcs7->sidType == DEGENERATE_SID) {
  2095. /* no signer infos in degenerate case */
  2096. } else {
  2097. #ifdef WOLFSSL_SMALL_STACK
  2098. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2099. #endif
  2100. return SKID_E;
  2101. }
  2102. XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
  2103. idx += esd->signerDigAlgoIdSz;
  2104. /* SignerInfo:Attributes */
  2105. if (flatSignedAttribsSz > 0) {
  2106. XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
  2107. idx += esd->signedAttribSetSz;
  2108. XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
  2109. idx += flatSignedAttribsSz;
  2110. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2111. }
  2112. XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
  2113. idx += esd->digEncAlgoIdSz;
  2114. XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
  2115. idx += esd->signerDigestSz;
  2116. XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
  2117. idx += esd->encContentDigestSz;
  2118. if (output2 && output2Sz) {
  2119. *output2Sz = idx;
  2120. idx = 0; /* success */
  2121. }
  2122. else {
  2123. *outputSz = idx;
  2124. }
  2125. #ifdef WOLFSSL_SMALL_STACK
  2126. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2127. #endif
  2128. return idx;
  2129. }
  2130. /* hashBuf: The computed digest for the pkcs7->content
  2131. * hashSz: The size of computed digest for the pkcs7->content based on hashOID
  2132. * outputHead: The PKCS7 header that goes on top of the raw data signed.
  2133. * outputFoot: The PKCS7 footer that goes at the end of the raw data signed.
  2134. * pkcs7->content: Not used
  2135. * pkcs7->contentSz: Must be provided as actual sign of raw data
  2136. * return codes: 0=success, negative=error
  2137. */
  2138. int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  2139. word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
  2140. word32* outputFootSz)
  2141. {
  2142. int ret;
  2143. #ifdef WOLFSSL_SMALL_STACK
  2144. ESD* esd;
  2145. #else
  2146. ESD esd[1];
  2147. #endif
  2148. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2149. if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {
  2150. return BAD_FUNC_ARG;
  2151. }
  2152. #ifdef WOLFSSL_SMALL_STACK
  2153. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2154. if (esd == NULL)
  2155. return MEMORY_E;
  2156. #endif
  2157. XMEMSET(esd, 0, sizeof(ESD));
  2158. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2159. outputHead, outputHeadSz, outputFoot, outputFootSz);
  2160. #ifdef WOLFSSL_SMALL_STACK
  2161. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2162. #endif
  2163. return ret;
  2164. }
  2165. /* Toggle detached signature mode on/off for PKCS#7/CMS SignedData content type.
  2166. * By default wolfCrypt includes the data to be signed in the SignedData
  2167. * bundle. This data can be omitted in the case when a detached signature is
  2168. * being created. To enable generation of detached signatures, set flag to "1",
  2169. * otherwise set to "0":
  2170. *
  2171. * flag 1 turns on support
  2172. * flag 0 turns off support
  2173. *
  2174. * pkcs7 - pointer to initialized PKCS7 structure
  2175. * flag - turn on/off detached signature generation (1 or 0)
  2176. *
  2177. * Returns 0 on success, negative upon error. */
  2178. int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag)
  2179. {
  2180. if (pkcs7 == NULL || (flag != 0 && flag != 1))
  2181. return BAD_FUNC_ARG;
  2182. pkcs7->detached = flag;
  2183. return 0;
  2184. }
  2185. /* By default, SignedData bundles have the following signed attributes attached:
  2186. * contentType (1.2.840.113549.1.9.3)
  2187. * signgingTime (1.2.840.113549.1.9.5)
  2188. * messageDigest (1.2.840.113549.1.9.4)
  2189. *
  2190. * Calling this API before wc_PKCS7_EncodeSignedData() will disable the
  2191. * inclusion of those attributes.
  2192. *
  2193. * pkcs7 - pointer to initialized PKCS7 structure
  2194. *
  2195. * Returns 0 on success, negative upon error. */
  2196. int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7)
  2197. {
  2198. if (pkcs7 == NULL)
  2199. return BAD_FUNC_ARG;
  2200. pkcs7->skipDefaultSignedAttribs = 1;
  2201. return 0;
  2202. }
  2203. /* return codes: >0: Size of signed PKCS7 output buffer, negative: error */
  2204. int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  2205. {
  2206. int ret;
  2207. int hashSz;
  2208. enum wc_HashType hashType;
  2209. byte hashBuf[WC_MAX_DIGEST_SIZE];
  2210. #ifdef WOLFSSL_SMALL_STACK
  2211. ESD* esd;
  2212. #else
  2213. ESD esd[1];
  2214. #endif
  2215. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2216. if (pkcs7 == NULL || pkcs7->contentSz == 0 || pkcs7->content == NULL) {
  2217. return BAD_FUNC_ARG;
  2218. }
  2219. /* get hash type and size, validate hashOID */
  2220. hashType = wc_OidGetHash(pkcs7->hashOID);
  2221. hashSz = wc_HashGetDigestSize(hashType);
  2222. if (hashSz < 0)
  2223. return hashSz;
  2224. #ifdef WOLFSSL_SMALL_STACK
  2225. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2226. if (esd == NULL)
  2227. return MEMORY_E;
  2228. #endif
  2229. XMEMSET(esd, 0, sizeof(ESD));
  2230. esd->hashType = hashType;
  2231. /* calculate hash for content */
  2232. ret = wc_HashInit(&esd->hash, esd->hashType);
  2233. if (ret == 0) {
  2234. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  2235. pkcs7->content, pkcs7->contentSz);
  2236. if (ret == 0) {
  2237. ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);
  2238. }
  2239. wc_HashFree(&esd->hash, esd->hashType);
  2240. }
  2241. if (ret == 0) {
  2242. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2243. output, &outputSz, NULL, NULL);
  2244. }
  2245. #ifdef WOLFSSL_SMALL_STACK
  2246. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2247. #endif
  2248. return ret;
  2249. }
  2250. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2251. * content of type FirmwarePkgData. Any recipient certificates should be
  2252. * loaded into the PKCS7 structure prior to calling this function, using
  2253. * wc_PKCS7_InitWithCert() and/or wc_PKCS7_AddCertificate().
  2254. *
  2255. * pkcs7 - pointer to initialized PKCS7 struct
  2256. * privateKey - private RSA/ECC key, used for signing SignedData
  2257. * privateKeySz - size of privateKey, octets
  2258. * signOID - public key algorithm OID, used for sign operation
  2259. * hashOID - hash algorithm OID, used for signature generation
  2260. * content - content to be encapsulated, of type FirmwarePkgData
  2261. * contentSz - size of content, octets
  2262. * signedAttribs - optional signed attributes
  2263. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2264. * output - output buffer for final bundle
  2265. * outputSz - size of output buffer, octets
  2266. *
  2267. * Returns length of generated bundle on success, negative upon error. */
  2268. int wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,
  2269. word32 privateKeySz, int signOID, int hashOID,
  2270. byte* content, word32 contentSz,
  2271. PKCS7Attrib* signedAttribs, word32 signedAttribsSz,
  2272. byte* output, word32 outputSz)
  2273. {
  2274. int ret = 0;
  2275. WC_RNG rng;
  2276. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2277. content == NULL || contentSz == 0 || output == NULL || outputSz == 0)
  2278. return BAD_FUNC_ARG;
  2279. ret = wc_InitRng(&rng);
  2280. if (ret != 0)
  2281. return ret;
  2282. pkcs7->rng = &rng;
  2283. pkcs7->content = content;
  2284. pkcs7->contentSz = contentSz;
  2285. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2286. pkcs7->hashOID = hashOID;
  2287. pkcs7->encryptOID = signOID;
  2288. pkcs7->privateKey = privateKey;
  2289. pkcs7->privateKeySz = privateKeySz;
  2290. pkcs7->signedAttribs = signedAttribs;
  2291. pkcs7->signedAttribsSz = signedAttribsSz;
  2292. pkcs7->version = 3;
  2293. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2294. if (ret <= 0) {
  2295. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2296. }
  2297. pkcs7->rng = NULL;
  2298. wc_FreeRng(&rng);
  2299. return ret;
  2300. }
  2301. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2302. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2303. * CMS EncryptedData bundle. Content of inner EncryptedData is set to that
  2304. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2305. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2306. * and/or wc_PKCS7_AddCertificate().
  2307. *
  2308. * pkcs7 - pointer to initialized PKCS7 struct
  2309. * encryptKey - encryption key used for encrypting EncryptedData
  2310. * encryptKeySz - size of encryptKey, octets
  2311. * privateKey - private RSA/ECC key, used for signing SignedData
  2312. * privateKeySz - size of privateKey, octets
  2313. * encryptOID - encryption algorithm OID, to be used as encryption
  2314. * algorithm for EncryptedData
  2315. * signOID - public key algorithm OID, to be used for sign
  2316. * operation in SignedData generation
  2317. * hashOID - hash algorithm OID, to be used for signature in
  2318. * SignedData generation
  2319. * content - content to be encapsulated
  2320. * contentSz - size of content, octets
  2321. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2322. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2323. * signedAttribs - optional signed attributes, for SignedData
  2324. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2325. * output - output buffer for final bundle
  2326. * outputSz - size of output buffer, octets
  2327. *
  2328. * Returns length of generated bundle on success, negative upon error. */
  2329. int wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, byte* encryptKey,
  2330. word32 encryptKeySz, byte* privateKey,
  2331. word32 privateKeySz, int encryptOID,
  2332. int signOID, int hashOID,
  2333. byte* content, word32 contentSz,
  2334. PKCS7Attrib* unprotectedAttribs,
  2335. word32 unprotectedAttribsSz,
  2336. PKCS7Attrib* signedAttribs,
  2337. word32 signedAttribsSz,
  2338. byte* output, word32 outputSz)
  2339. {
  2340. int ret = 0, encryptedSz = 0;
  2341. byte* encrypted = NULL;
  2342. WC_RNG rng;
  2343. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2344. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2345. contentSz == 0 || output == NULL || outputSz == 0) {
  2346. return BAD_FUNC_ARG;
  2347. }
  2348. /* 1: build up EncryptedData using FirmwarePkgData type, use output
  2349. * buffer as tmp for storage and to get size */
  2350. /* set struct elements, inner content type is FirmwarePkgData */
  2351. pkcs7->content = content;
  2352. pkcs7->contentSz = contentSz;
  2353. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2354. pkcs7->encryptOID = encryptOID;
  2355. pkcs7->encryptionKey = encryptKey;
  2356. pkcs7->encryptionKeySz = encryptKeySz;
  2357. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2358. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2359. pkcs7->version = 3;
  2360. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2361. if (encryptedSz < 0) {
  2362. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2363. return encryptedSz;
  2364. }
  2365. /* save encryptedData, reset output buffer and struct */
  2366. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2367. if (encrypted == NULL) {
  2368. ForceZero(output, outputSz);
  2369. return MEMORY_E;
  2370. }
  2371. XMEMCPY(encrypted, output, encryptedSz);
  2372. ForceZero(output, outputSz);
  2373. ret = wc_InitRng(&rng);
  2374. if (ret != 0) {
  2375. ForceZero(encrypted, encryptedSz);
  2376. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2377. return ret;
  2378. }
  2379. /* 2: build up SignedData, encapsulating EncryptedData */
  2380. pkcs7->rng = &rng;
  2381. pkcs7->content = encrypted;
  2382. pkcs7->contentSz = encryptedSz;
  2383. pkcs7->contentOID = ENCRYPTED_DATA;
  2384. pkcs7->hashOID = hashOID;
  2385. pkcs7->encryptOID = signOID;
  2386. pkcs7->privateKey = privateKey;
  2387. pkcs7->privateKeySz = privateKeySz;
  2388. pkcs7->signedAttribs = signedAttribs;
  2389. pkcs7->signedAttribsSz = signedAttribsSz;
  2390. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2391. if (ret <= 0) {
  2392. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2393. }
  2394. ForceZero(encrypted, encryptedSz);
  2395. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2396. pkcs7->rng = NULL;
  2397. wc_FreeRng(&rng);
  2398. return ret;
  2399. }
  2400. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  2401. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  2402. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2403. * CMS CompressedData bundle. Content of inner CompressedData is set to that
  2404. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2405. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2406. * and/or wc_PKCS7_AddCertificate().
  2407. *
  2408. * pkcs7 - pointer to initialized PKCS7 struct
  2409. * privateKey - private RSA/ECC key, used for signing SignedData
  2410. * privateKeySz - size of privateKey, octets
  2411. * signOID - public key algorithm OID, to be used for sign
  2412. * operation in SignedData generation
  2413. * hashOID - hash algorithm OID, to be used for signature in
  2414. * SignedData generation
  2415. * content - content to be encapsulated
  2416. * contentSz - size of content, octets
  2417. * signedAttribs - optional signed attributes, for SignedData
  2418. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2419. * output - output buffer for final bundle
  2420. * outputSz - size of output buffer, octets
  2421. *
  2422. * Returns length of generated bundle on success, negative upon error. */
  2423. int wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, byte* privateKey,
  2424. word32 privateKeySz, int signOID,
  2425. int hashOID, byte* content,
  2426. word32 contentSz,
  2427. PKCS7Attrib* signedAttribs,
  2428. word32 signedAttribsSz, byte* output,
  2429. word32 outputSz)
  2430. {
  2431. int ret = 0, compressedSz = 0;
  2432. byte* compressed = NULL;
  2433. WC_RNG rng;
  2434. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2435. content == NULL || contentSz == 0 || output == NULL || outputSz == 0) {
  2436. return BAD_FUNC_ARG;
  2437. }
  2438. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2439. * buffer as tmp for storage and to get size */
  2440. /* set struct elements, inner content type is FirmwarePkgData */
  2441. pkcs7->content = content;
  2442. pkcs7->contentSz = contentSz;
  2443. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2444. pkcs7->version = 3;
  2445. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2446. if (compressedSz < 0) {
  2447. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2448. return compressedSz;
  2449. }
  2450. /* save compressedData, reset output buffer and struct */
  2451. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2452. if (compressed == NULL) {
  2453. ForceZero(output, outputSz);
  2454. return MEMORY_E;
  2455. }
  2456. XMEMCPY(compressed, output, compressedSz);
  2457. ForceZero(output, outputSz);
  2458. ret = wc_InitRng(&rng);
  2459. if (ret != 0) {
  2460. ForceZero(compressed, compressedSz);
  2461. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2462. return ret;
  2463. }
  2464. /* 2: build up SignedData, encapsulating EncryptedData */
  2465. pkcs7->rng = &rng;
  2466. pkcs7->content = compressed;
  2467. pkcs7->contentSz = compressedSz;
  2468. pkcs7->contentOID = COMPRESSED_DATA;
  2469. pkcs7->hashOID = hashOID;
  2470. pkcs7->encryptOID = signOID;
  2471. pkcs7->privateKey = privateKey;
  2472. pkcs7->privateKeySz = privateKeySz;
  2473. pkcs7->signedAttribs = signedAttribs;
  2474. pkcs7->signedAttribsSz = signedAttribsSz;
  2475. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2476. if (ret <= 0) {
  2477. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2478. }
  2479. ForceZero(compressed, compressedSz);
  2480. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2481. pkcs7->rng = NULL;
  2482. wc_FreeRng(&rng);
  2483. return ret;
  2484. }
  2485. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2486. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2487. * CMS EncryptedData bundle, which then encapsulates a CMS CompressedData
  2488. * bundle. Content of inner CompressedData is set to that of FirmwarePkgData.
  2489. * Any recipient certificates should be loaded into the PKCS7 structure prior
  2490. * to calling this function, using wc_PKCS7_InitWithCert() and/or
  2491. * wc_PKCS7_AddCertificate().
  2492. *
  2493. * pkcs7 - pointer to initialized PKCS7 struct
  2494. * encryptKey - encryption key used for encrypting EncryptedData
  2495. * encryptKeySz - size of encryptKey, octets
  2496. * privateKey - private RSA/ECC key, used for signing SignedData
  2497. * privateKeySz - size of privateKey, octets
  2498. * encryptOID - encryption algorithm OID, to be used as encryption
  2499. * algorithm for EncryptedData
  2500. * signOID - public key algorithm OID, to be used for sign
  2501. * operation in SignedData generation
  2502. * hashOID - hash algorithm OID, to be used for signature in
  2503. * SignedData generation
  2504. * content - content to be encapsulated
  2505. * contentSz - size of content, octets
  2506. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2507. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2508. * signedAttribs - optional signed attributes, for SignedData
  2509. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2510. * output - output buffer for final bundle
  2511. * outputSz - size of output buffer, octets
  2512. *
  2513. * Returns length of generated bundle on success, negative upon error. */
  2514. int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,
  2515. word32 encryptKeySz, byte* privateKey,
  2516. word32 privateKeySz, int encryptOID,
  2517. int signOID, int hashOID, byte* content,
  2518. word32 contentSz,
  2519. PKCS7Attrib* unprotectedAttribs,
  2520. word32 unprotectedAttribsSz,
  2521. PKCS7Attrib* signedAttribs,
  2522. word32 signedAttribsSz,
  2523. byte* output, word32 outputSz)
  2524. {
  2525. int ret = 0, compressedSz = 0, encryptedSz = 0;
  2526. byte* compressed = NULL;
  2527. byte* encrypted = NULL;
  2528. WC_RNG rng;
  2529. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2530. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2531. contentSz == 0 || output == NULL || outputSz == 0) {
  2532. return BAD_FUNC_ARG;
  2533. }
  2534. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2535. * buffer as tmp for storage and to get size */
  2536. pkcs7->content = content;
  2537. pkcs7->contentSz = contentSz;
  2538. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2539. pkcs7->version = 3;
  2540. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2541. if (compressedSz < 0) {
  2542. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2543. return compressedSz;
  2544. }
  2545. /* save compressedData, reset output buffer and struct */
  2546. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2547. if (compressed == NULL)
  2548. return MEMORY_E;
  2549. XMEMCPY(compressed, output, compressedSz);
  2550. ForceZero(output, outputSz);
  2551. /* 2: build up EncryptedData using CompressedData, use output
  2552. * buffer as tmp for storage and to get size */
  2553. pkcs7->content = compressed;
  2554. pkcs7->contentSz = compressedSz;
  2555. pkcs7->contentOID = COMPRESSED_DATA;
  2556. pkcs7->encryptOID = encryptOID;
  2557. pkcs7->encryptionKey = encryptKey;
  2558. pkcs7->encryptionKeySz = encryptKeySz;
  2559. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2560. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2561. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2562. if (encryptedSz < 0) {
  2563. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2564. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2565. return encryptedSz;
  2566. }
  2567. /* save encryptedData, reset output buffer and struct */
  2568. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2569. if (encrypted == NULL) {
  2570. ForceZero(compressed, compressedSz);
  2571. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2572. return MEMORY_E;
  2573. }
  2574. XMEMCPY(encrypted, output, encryptedSz);
  2575. ForceZero(compressed, compressedSz);
  2576. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2577. ForceZero(output, outputSz);
  2578. ret = wc_InitRng(&rng);
  2579. if (ret != 0) {
  2580. ForceZero(encrypted, encryptedSz);
  2581. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2582. return ret;
  2583. }
  2584. /* 3: build up SignedData, encapsulating EncryptedData */
  2585. pkcs7->rng = &rng;
  2586. pkcs7->content = encrypted;
  2587. pkcs7->contentSz = encryptedSz;
  2588. pkcs7->contentOID = ENCRYPTED_DATA;
  2589. pkcs7->hashOID = hashOID;
  2590. pkcs7->encryptOID = signOID;
  2591. pkcs7->privateKey = privateKey;
  2592. pkcs7->privateKeySz = privateKeySz;
  2593. pkcs7->signedAttribs = signedAttribs;
  2594. pkcs7->signedAttribsSz = signedAttribsSz;
  2595. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2596. if (ret <= 0) {
  2597. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2598. }
  2599. ForceZero(encrypted, encryptedSz);
  2600. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2601. pkcs7->rng = NULL;
  2602. wc_FreeRng(&rng);
  2603. return ret;
  2604. }
  2605. #endif /* !NO_PKCS7_ENCRYPTED_DATA */
  2606. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  2607. #ifndef NO_RSA
  2608. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  2609. /* register raw RSA sign digest callback */
  2610. int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
  2611. {
  2612. if (pkcs7 == NULL || cb == NULL) {
  2613. return BAD_FUNC_ARG;
  2614. }
  2615. pkcs7->rsaSignRawDigestCb = cb;
  2616. return 0;
  2617. }
  2618. #endif
  2619. /* returns size of signature put into out, negative on error */
  2620. static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  2621. byte* hash, word32 hashSz)
  2622. {
  2623. int ret = 0, i;
  2624. word32 scratch = 0, verified = 0;
  2625. #ifdef WOLFSSL_SMALL_STACK
  2626. byte* digest;
  2627. RsaKey* key;
  2628. DecodedCert* dCert;
  2629. #else
  2630. byte digest[MAX_PKCS7_DIGEST_SZ];
  2631. RsaKey key[1];
  2632. DecodedCert stack_dCert;
  2633. DecodedCert* dCert = &stack_dCert;
  2634. #endif
  2635. if (pkcs7 == NULL || sig == NULL || hash == NULL) {
  2636. return BAD_FUNC_ARG;
  2637. }
  2638. #ifdef WOLFSSL_SMALL_STACK
  2639. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2640. DYNAMIC_TYPE_TMP_BUFFER);
  2641. if (digest == NULL)
  2642. return MEMORY_E;
  2643. key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2644. if (key == NULL) {
  2645. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2646. return MEMORY_E;
  2647. }
  2648. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  2649. DYNAMIC_TYPE_DCERT);
  2650. if (dCert == NULL) {
  2651. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2652. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2653. return MEMORY_E;
  2654. }
  2655. #endif
  2656. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  2657. /* loop over certs received in certificates set, try to find one
  2658. * that will validate signature */
  2659. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  2660. verified = 0;
  2661. scratch = 0;
  2662. if (pkcs7->certSz[i] == 0)
  2663. continue;
  2664. ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);
  2665. if (ret != 0) {
  2666. #ifdef WOLFSSL_SMALL_STACK
  2667. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2668. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2669. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2670. #endif
  2671. return ret;
  2672. }
  2673. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  2674. /* not verifying, only using this to extract public key */
  2675. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  2676. if (ret < 0) {
  2677. WOLFSSL_MSG("ASN RSA cert parse error");
  2678. FreeDecodedCert(dCert);
  2679. wc_FreeRsaKey(key);
  2680. continue;
  2681. }
  2682. if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key,
  2683. dCert->pubKeySize) < 0) {
  2684. WOLFSSL_MSG("ASN RSA key decode error");
  2685. FreeDecodedCert(dCert);
  2686. wc_FreeRsaKey(key);
  2687. continue;
  2688. }
  2689. #ifdef WOLFSSL_ASYNC_CRYPT
  2690. do {
  2691. ret = wc_AsyncWait(ret, &key->asyncDev,
  2692. WC_ASYNC_FLAG_CALL_AGAIN);
  2693. #endif
  2694. if (ret >= 0) {
  2695. ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,
  2696. key);
  2697. }
  2698. #ifdef WOLFSSL_ASYNC_CRYPT
  2699. } while (ret == WC_PENDING_E);
  2700. #endif
  2701. FreeDecodedCert(dCert);
  2702. wc_FreeRsaKey(key);
  2703. if ((ret > 0) && (hashSz == (word32)ret)) {
  2704. if (XMEMCMP(digest, hash, hashSz) == 0) {
  2705. /* found signer that successfully verified signature */
  2706. verified = 1;
  2707. break;
  2708. }
  2709. }
  2710. }
  2711. if (verified == 0) {
  2712. ret = SIG_VERIFY_E;
  2713. }
  2714. #ifdef WOLFSSL_SMALL_STACK
  2715. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2716. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2717. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2718. #endif
  2719. return ret;
  2720. }
  2721. #endif /* NO_RSA */
  2722. #ifdef HAVE_ECC
  2723. /* returns size of signature put into out, negative on error */
  2724. static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  2725. byte* hash, word32 hashSz)
  2726. {
  2727. int ret = 0, i;
  2728. int res = 0;
  2729. int verified = 0;
  2730. #ifdef WOLFSSL_SMALL_STACK
  2731. byte* digest;
  2732. ecc_key* key;
  2733. DecodedCert* dCert;
  2734. #else
  2735. byte digest[MAX_PKCS7_DIGEST_SZ];
  2736. ecc_key key[1];
  2737. DecodedCert stack_dCert;
  2738. DecodedCert* dCert = &stack_dCert;
  2739. #endif
  2740. word32 idx = 0;
  2741. if (pkcs7 == NULL || sig == NULL)
  2742. return BAD_FUNC_ARG;
  2743. #ifdef WOLFSSL_SMALL_STACK
  2744. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2745. DYNAMIC_TYPE_TMP_BUFFER);
  2746. if (digest == NULL)
  2747. return MEMORY_E;
  2748. key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2749. if (key == NULL) {
  2750. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2751. return MEMORY_E;
  2752. }
  2753. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  2754. DYNAMIC_TYPE_DCERT);
  2755. if (dCert == NULL) {
  2756. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2757. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2758. return MEMORY_E;
  2759. }
  2760. #endif
  2761. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  2762. /* loop over certs received in certificates set, try to find one
  2763. * that will validate signature */
  2764. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  2765. verified = 0;
  2766. if (pkcs7->certSz[i] == 0)
  2767. continue;
  2768. ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);
  2769. if (ret != 0) {
  2770. #ifdef WOLFSSL_SMALL_STACK
  2771. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2772. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2773. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2774. #endif
  2775. return ret;
  2776. }
  2777. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  2778. /* not verifying, only using this to extract public key */
  2779. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  2780. if (ret < 0) {
  2781. WOLFSSL_MSG("ASN ECC cert parse error");
  2782. FreeDecodedCert(dCert);
  2783. wc_ecc_free(key);
  2784. continue;
  2785. }
  2786. if (wc_EccPublicKeyDecode(pkcs7->publicKey, &idx, key,
  2787. pkcs7->publicKeySz) < 0) {
  2788. WOLFSSL_MSG("ASN ECC key decode error");
  2789. FreeDecodedCert(dCert);
  2790. wc_ecc_free(key);
  2791. continue;
  2792. }
  2793. #ifdef WOLFSSL_ASYNC_CRYPT
  2794. do {
  2795. ret = wc_AsyncWait(ret, &key->asyncDev,
  2796. WC_ASYNC_FLAG_CALL_AGAIN);
  2797. #endif
  2798. if (ret >= 0) {
  2799. ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);
  2800. }
  2801. #ifdef WOLFSSL_ASYNC_CRYPT
  2802. } while (ret == WC_PENDING_E);
  2803. #endif
  2804. FreeDecodedCert(dCert);
  2805. wc_ecc_free(key);
  2806. if (ret == 0 && res == 1) {
  2807. /* found signer that successfully verified signature */
  2808. verified = 1;
  2809. break;
  2810. }
  2811. }
  2812. if (verified == 0) {
  2813. ret = SIG_VERIFY_E;
  2814. }
  2815. #ifdef WOLFSSL_SMALL_STACK
  2816. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2817. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2818. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2819. #endif
  2820. return ret;
  2821. }
  2822. #endif /* HAVE_ECC */
  2823. /* build SignedData digest, both in PKCS#7 DigestInfo format and
  2824. * as plain digest for CMS.
  2825. *
  2826. * pkcs7 - pointer to initialized PKCS7 struct
  2827. * signedAttrib - signed attributes
  2828. * signedAttribSz - size of signedAttrib, octets
  2829. * pkcs7Digest - [OUT] PKCS#7 DigestInfo
  2830. * pkcs7DigestSz - [IN/OUT] size of pkcs7Digest
  2831. * plainDigest - [OUT] pointer to plain digest, offset into pkcs7Digest
  2832. * plainDigestSz - [OUT] size of digest at plainDigest
  2833. *
  2834. * returns 0 on success, negative on error */
  2835. static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
  2836. word32 signedAttribSz, byte* pkcs7Digest,
  2837. word32* pkcs7DigestSz, byte** plainDigest,
  2838. word32* plainDigestSz,
  2839. const byte* hashBuf, word32 hashBufSz)
  2840. {
  2841. int ret = 0, digIdx = 0;
  2842. word32 attribSetSz = 0, hashSz = 0;
  2843. byte attribSet[MAX_SET_SZ];
  2844. byte digest[WC_MAX_DIGEST_SIZE];
  2845. byte digestInfoSeq[MAX_SEQ_SZ];
  2846. byte digestStr[MAX_OCTET_STR_SZ];
  2847. byte algoId[MAX_ALGO_SZ];
  2848. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  2849. #ifdef WOLFSSL_SMALL_STACK
  2850. byte* digestInfo;
  2851. #else
  2852. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  2853. #endif
  2854. wc_HashAlg hash;
  2855. enum wc_HashType hashType;
  2856. /* check arguments */
  2857. if (pkcs7 == NULL || pkcs7Digest == NULL ||
  2858. pkcs7DigestSz == NULL || plainDigest == NULL) {
  2859. return BAD_FUNC_ARG;
  2860. }
  2861. hashType = wc_OidGetHash(pkcs7->hashOID);
  2862. ret = wc_HashGetDigestSize(hashType);
  2863. if (ret < 0)
  2864. return ret;
  2865. hashSz = ret;
  2866. if (signedAttribSz > 0) {
  2867. if (signedAttrib == NULL)
  2868. return BAD_FUNC_ARG;
  2869. }
  2870. else {
  2871. if (hashBuf && hashBufSz > 0) {
  2872. if (hashSz != hashBufSz)
  2873. return BAD_FUNC_ARG;
  2874. }
  2875. else if (pkcs7->content == NULL)
  2876. return BAD_FUNC_ARG;
  2877. }
  2878. #ifdef WOLFSSL_SMALL_STACK
  2879. digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2880. DYNAMIC_TYPE_TMP_BUFFER);
  2881. if (digestInfo == NULL)
  2882. return MEMORY_E;
  2883. #endif
  2884. XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);
  2885. XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE);
  2886. XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ);
  2887. /* calculate digest */
  2888. if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
  2889. XMEMCPY(digest, hashBuf, hashBufSz);
  2890. }
  2891. else {
  2892. ret = wc_HashInit(&hash, hashType);
  2893. if (ret < 0) {
  2894. #ifdef WOLFSSL_SMALL_STACK
  2895. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2896. #endif
  2897. return ret;
  2898. }
  2899. if (signedAttribSz > 0) {
  2900. attribSetSz = SetSet(signedAttribSz, attribSet);
  2901. /* calculate digest */
  2902. ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
  2903. if (ret == 0)
  2904. ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
  2905. if (ret == 0)
  2906. ret = wc_HashFinal(&hash, hashType, digest);
  2907. } else {
  2908. ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
  2909. if (ret == 0)
  2910. ret = wc_HashFinal(&hash, hashType, digest);
  2911. }
  2912. wc_HashFree(&hash, hashType);
  2913. if (ret < 0) {
  2914. #ifdef WOLFSSL_SMALL_STACK
  2915. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2916. #endif
  2917. return ret;
  2918. }
  2919. }
  2920. /* Set algoID, with NULL attributes */
  2921. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  2922. digestStrSz = SetOctetString(hashSz, digestStr);
  2923. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  2924. digestInfoSeq);
  2925. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  2926. digIdx += digestInfoSeqSz;
  2927. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  2928. digIdx += algoIdSz;
  2929. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  2930. digIdx += digestStrSz;
  2931. XMEMCPY(digestInfo + digIdx, digest, hashSz);
  2932. digIdx += hashSz;
  2933. XMEMCPY(pkcs7Digest, digestInfo, digIdx);
  2934. *pkcs7DigestSz = digIdx;
  2935. /* set plain digest pointer */
  2936. *plainDigest = pkcs7Digest + digIdx - hashSz;
  2937. *plainDigestSz = hashSz;
  2938. #ifdef WOLFSSL_SMALL_STACK
  2939. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2940. #endif
  2941. return 0;
  2942. }
  2943. /* Verifies CMS/PKCS7 SignedData content digest matches that which is
  2944. * included in the messageDigest signed attribute. Only called when
  2945. * signed attributes are present, otherwise original signature verification
  2946. * is done over content.
  2947. *
  2948. * pkcs7 - pointer to initialized PKCS7 struct
  2949. * hashBuf - pointer to user-provided hash buffer, used with
  2950. * wc_PKCS7_VerifySignedData_ex()
  2951. * hashBufSz - size of hashBuf, octets
  2952. *
  2953. * return 0 on success, negative on error */
  2954. static int wc_PKCS7_VerifyContentMessageDigest(PKCS7* pkcs7,
  2955. const byte* hashBuf,
  2956. word32 hashSz)
  2957. {
  2958. int ret = 0, digestSz = 0, innerAttribSz = 0;
  2959. word32 idx = 0;
  2960. byte* digestBuf = NULL;
  2961. #ifdef WOLFSSL_SMALL_STACK
  2962. byte* digest = NULL;
  2963. #else
  2964. byte digest[MAX_PKCS7_DIGEST_SZ];
  2965. #endif
  2966. PKCS7DecodedAttrib* attrib;
  2967. enum wc_HashType hashType;
  2968. /* messageDigest OID (1.2.840.113549.1.9.4) */
  2969. const byte mdOid[] =
  2970. { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };
  2971. if (pkcs7 == NULL)
  2972. return BAD_FUNC_ARG;
  2973. if ((pkcs7->content == NULL || pkcs7->contentSz == 0) &&
  2974. (hashBuf == NULL || hashSz == 0)) {
  2975. WOLFSSL_MSG("SignedData bundle has no content or hash to verify");
  2976. return BAD_FUNC_ARG;
  2977. }
  2978. /* lookup messageDigest attribute */
  2979. attrib = findAttrib(pkcs7, mdOid, sizeof(mdOid));
  2980. if (attrib == NULL) {
  2981. WOLFSSL_MSG("messageDigest attribute not in bundle, must be when "
  2982. "signed attribs are present");
  2983. return ASN_PARSE_E;
  2984. }
  2985. /* advance past attrib->value ASN.1 header and length */
  2986. if (attrib->value == NULL || attrib->valueSz == 0)
  2987. return ASN_PARSE_E;
  2988. if (attrib->value[idx++] != ASN_OCTET_STRING)
  2989. return ASN_PARSE_E;
  2990. if (GetLength(attrib->value, &idx, &innerAttribSz, attrib->valueSz) < 0)
  2991. return ASN_PARSE_E;
  2992. /* get hash type and size */
  2993. hashType = wc_OidGetHash(pkcs7->hashOID);
  2994. if (hashType == WC_HASH_TYPE_NONE) {
  2995. WOLFSSL_MSG("Error getting hash type for PKCS7 content verification");
  2996. return BAD_FUNC_ARG;
  2997. }
  2998. /* build content hash if needed, or use existing hash value */
  2999. if (hashBuf == NULL) {
  3000. #ifdef WOLFSSL_SMALL_STACK
  3001. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3002. DYNAMIC_TYPE_TMP_BUFFER);
  3003. if (digest == NULL)
  3004. return MEMORY_E;
  3005. #endif
  3006. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  3007. ret = wc_Hash(hashType, pkcs7->content, pkcs7->contentSz, digest,
  3008. MAX_PKCS7_DIGEST_SZ);
  3009. if (ret < 0) {
  3010. WOLFSSL_MSG("Error hashing PKCS7 content for verification");
  3011. #ifdef WOLFSSL_SMALL_STACK
  3012. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3013. #endif
  3014. return ret;
  3015. }
  3016. digestBuf = digest;
  3017. digestSz = wc_HashGetDigestSize(hashType);
  3018. if (digestSz < 0) {
  3019. WOLFSSL_MSG("Invalid hash type");
  3020. #ifdef WOLFSSL_SMALL_STACK
  3021. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3022. #endif
  3023. return digestSz;
  3024. }
  3025. } else {
  3026. /* user passed in pre-computed hash */
  3027. digestBuf = (byte*)hashBuf;
  3028. digestSz = (int)hashSz;
  3029. }
  3030. /* compare generated to hash in messageDigest attribute */
  3031. if ((innerAttribSz != digestSz) ||
  3032. (XMEMCMP(attrib->value + idx, digestBuf, (word32)digestSz) != 0)) {
  3033. WOLFSSL_MSG("Content digest does not match messageDigest attrib value");
  3034. #ifdef WOLFSSL_SMALL_STACK
  3035. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3036. #endif
  3037. return SIG_VERIFY_E;
  3038. }
  3039. if (hashBuf == NULL) {
  3040. #ifdef WOLFSSL_SMALL_STACK
  3041. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3042. #endif
  3043. }
  3044. return 0;
  3045. }
  3046. /* verifies SignedData signature, over either PKCS#7 DigestInfo or
  3047. * content digest.
  3048. *
  3049. * pkcs7 - pointer to initialized PKCS7 struct
  3050. * sig - signature to verify
  3051. * sigSz - size of sig
  3052. * signedAttrib - signed attributes, or null if empty
  3053. * signedAttribSz - size of signedAttributes
  3054. *
  3055. * return 0 on success, negative on error */
  3056. static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
  3057. word32 sigSz, byte* signedAttrib,
  3058. word32 signedAttribSz,
  3059. const byte* hashBuf, word32 hashSz)
  3060. {
  3061. int ret = 0;
  3062. word32 plainDigestSz = 0, pkcs7DigestSz;
  3063. byte* plainDigest = NULL; /* offset into pkcs7Digest */
  3064. #ifdef WOLFSSL_SMALL_STACK
  3065. byte* pkcs7Digest;
  3066. #else
  3067. byte pkcs7Digest[MAX_PKCS7_DIGEST_SZ];
  3068. #endif
  3069. if (pkcs7 == NULL)
  3070. return BAD_FUNC_ARG;
  3071. /* allocate space to build hash */
  3072. pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;
  3073. #ifdef WOLFSSL_SMALL_STACK
  3074. pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3075. DYNAMIC_TYPE_TMP_BUFFER);
  3076. if (pkcs7Digest == NULL)
  3077. return MEMORY_E;
  3078. #endif
  3079. XMEMSET(pkcs7Digest, 0, pkcs7DigestSz);
  3080. /* verify signed attrib digest matches that of content */
  3081. if (signedAttrib != NULL) {
  3082. ret = wc_PKCS7_VerifyContentMessageDigest(pkcs7, hashBuf, hashSz);
  3083. if (ret != 0) {
  3084. #ifdef WOLFSSL_SMALL_STACK
  3085. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3086. #endif
  3087. return ret;
  3088. }
  3089. }
  3090. /* build hash to verify against */
  3091. ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
  3092. signedAttribSz, pkcs7Digest,
  3093. &pkcs7DigestSz, &plainDigest,
  3094. &plainDigestSz, hashBuf, hashSz);
  3095. if (ret < 0) {
  3096. #ifdef WOLFSSL_SMALL_STACK
  3097. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3098. #endif
  3099. return ret;
  3100. }
  3101. /* If no certificates are available then store the signature and hash for
  3102. * user to verify. Make sure that different return value than success is
  3103. * returned because the signature was not verified here. */
  3104. if (ret == 0) {
  3105. byte haveCert = 0;
  3106. int i;
  3107. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  3108. if (pkcs7->certSz[i] == 0)
  3109. continue;
  3110. haveCert = 1;
  3111. }
  3112. if (!haveCert) {
  3113. WOLFSSL_MSG("No certificates in bundle to verify signature");
  3114. /* store signature */
  3115. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  3116. pkcs7->signature = NULL;
  3117. pkcs7->signatureSz = 0;
  3118. pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap,
  3119. DYNAMIC_TYPE_SIGNATURE);
  3120. if (pkcs7->signature == NULL) {
  3121. #ifdef WOLFSSL_SMALL_STACK
  3122. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3123. #endif
  3124. return MEMORY_E;
  3125. }
  3126. XMEMCPY(pkcs7->signature, sig, sigSz);
  3127. pkcs7->signatureSz = sigSz;
  3128. /* store plain digest (CMS and ECC) */
  3129. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3130. pkcs7->plainDigest = NULL;
  3131. pkcs7->plainDigestSz = 0;
  3132. pkcs7->plainDigest = (byte*)XMALLOC(plainDigestSz, pkcs7->heap,
  3133. DYNAMIC_TYPE_DIGEST);
  3134. if (pkcs7->plainDigest == NULL) {
  3135. #ifdef WOLFSSL_SMALL_STACK
  3136. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3137. #endif
  3138. return MEMORY_E;
  3139. }
  3140. XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz);
  3141. pkcs7->plainDigestSz = plainDigestSz;
  3142. /* store pkcs7 digest (default RSA) */
  3143. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3144. pkcs7->pkcs7Digest = NULL;
  3145. pkcs7->pkcs7DigestSz = 0;
  3146. pkcs7->pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3147. DYNAMIC_TYPE_DIGEST);
  3148. if (pkcs7->pkcs7Digest == NULL) {
  3149. #ifdef WOLFSSL_SMALL_STACK
  3150. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3151. #endif
  3152. return MEMORY_E;
  3153. }
  3154. XMEMCPY(pkcs7->pkcs7Digest, pkcs7Digest, pkcs7DigestSz);
  3155. pkcs7->pkcs7DigestSz = pkcs7DigestSz;
  3156. #ifdef WOLFSSL_SMALL_STACK
  3157. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3158. #endif
  3159. return PKCS7_SIGNEEDS_CHECK;
  3160. }
  3161. }
  3162. switch (pkcs7->publicKeyOID) {
  3163. #ifndef NO_RSA
  3164. case RSAk:
  3165. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,
  3166. pkcs7DigestSz);
  3167. if (ret < 0) {
  3168. WOLFSSL_MSG("PKCS#7 verification failed, trying CMS");
  3169. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,
  3170. plainDigestSz);
  3171. }
  3172. break;
  3173. #endif
  3174. #ifdef HAVE_ECC
  3175. case ECDSAk:
  3176. ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,
  3177. plainDigestSz);
  3178. break;
  3179. #endif
  3180. default:
  3181. WOLFSSL_MSG("Unsupported public key type");
  3182. ret = BAD_FUNC_ARG;
  3183. }
  3184. #ifdef WOLFSSL_SMALL_STACK
  3185. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3186. #endif
  3187. return ret;
  3188. }
  3189. /* set correct public key OID based on signature OID, stores in
  3190. * pkcs7->publicKeyOID and returns same value */
  3191. static int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)
  3192. {
  3193. if (pkcs7 == NULL)
  3194. return BAD_FUNC_ARG;
  3195. pkcs7->publicKeyOID = 0;
  3196. switch (sigOID) {
  3197. #ifndef NO_RSA
  3198. /* RSA signature types */
  3199. case CTC_MD2wRSA:
  3200. case CTC_MD5wRSA:
  3201. case CTC_SHAwRSA:
  3202. case CTC_SHA224wRSA:
  3203. case CTC_SHA256wRSA:
  3204. case CTC_SHA384wRSA:
  3205. case CTC_SHA512wRSA:
  3206. pkcs7->publicKeyOID = RSAk;
  3207. break;
  3208. /* if sigOID is already RSAk */
  3209. case RSAk:
  3210. pkcs7->publicKeyOID = sigOID;
  3211. break;
  3212. #endif
  3213. #ifndef NO_DSA
  3214. /* DSA signature types */
  3215. case CTC_SHAwDSA:
  3216. pkcs7->publicKeyOID = DSAk;
  3217. break;
  3218. /* if sigOID is already DSAk */
  3219. case DSAk:
  3220. pkcs7->publicKeyOID = sigOID;
  3221. break;
  3222. #endif
  3223. #ifdef HAVE_ECC
  3224. /* ECDSA signature types */
  3225. case CTC_SHAwECDSA:
  3226. case CTC_SHA224wECDSA:
  3227. case CTC_SHA256wECDSA:
  3228. case CTC_SHA384wECDSA:
  3229. case CTC_SHA512wECDSA:
  3230. pkcs7->publicKeyOID = ECDSAk;
  3231. break;
  3232. /* if sigOID is already ECDSAk */
  3233. case ECDSAk:
  3234. pkcs7->publicKeyOID = sigOID;
  3235. break;
  3236. #endif
  3237. default:
  3238. WOLFSSL_MSG("Unsupported public key algorithm");
  3239. return ASN_SIG_KEY_E;
  3240. }
  3241. return pkcs7->publicKeyOID;
  3242. }
  3243. /* Parses through the attributes and adds them to the PKCS7 structure
  3244. * Creates dynamic attribute structures that are free'd with calling
  3245. * wc_PKCS7_Free()
  3246. *
  3247. * NOTE: An attribute has the ASN1 format of
  3248. ** Sequence
  3249. ****** Object ID
  3250. ****** Set
  3251. ********** {PritnableString, UTCTime, OCTET STRING ...}
  3252. *
  3253. * pkcs7 the PKCS7 structure to put the parsed attributes into
  3254. * in buffer holding all attributes
  3255. * inSz size of in buffer
  3256. *
  3257. * returns the number of attributes parsed on success
  3258. */
  3259. static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
  3260. {
  3261. int found = 0;
  3262. word32 idx = 0;
  3263. word32 oid;
  3264. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  3265. return BAD_FUNC_ARG;
  3266. }
  3267. while (idx < (word32)inSz) {
  3268. int length = 0;
  3269. int oidIdx;
  3270. PKCS7DecodedAttrib* attrib;
  3271. if (GetSequence(in, &idx, &length, inSz) < 0)
  3272. return ASN_PARSE_E;
  3273. attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),
  3274. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3275. if (attrib == NULL) {
  3276. return MEMORY_E;
  3277. }
  3278. XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));
  3279. oidIdx = idx;
  3280. if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)
  3281. < 0) {
  3282. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3283. return ASN_PARSE_E;
  3284. }
  3285. attrib->oidSz = idx - oidIdx;
  3286. attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,
  3287. DYNAMIC_TYPE_PKCS7);
  3288. if (attrib->oid == NULL) {
  3289. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3290. return MEMORY_E;
  3291. }
  3292. XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);
  3293. /* Get Set that contains the printable string value */
  3294. if (GetSet(in, &idx, &length, inSz) < 0) {
  3295. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3296. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3297. return ASN_PARSE_E;
  3298. }
  3299. if ((inSz - idx) < (word32)length) {
  3300. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3301. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3302. return ASN_PARSE_E;
  3303. }
  3304. attrib->valueSz = (word32)length;
  3305. attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,
  3306. DYNAMIC_TYPE_PKCS7);
  3307. if (attrib->value == NULL) {
  3308. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3309. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3310. return MEMORY_E;
  3311. }
  3312. XMEMCPY(attrib->value, in + idx, attrib->valueSz);
  3313. idx += length;
  3314. /* store attribute in linked list */
  3315. if (pkcs7->decodedAttrib != NULL) {
  3316. attrib->next = pkcs7->decodedAttrib;
  3317. pkcs7->decodedAttrib = attrib;
  3318. } else {
  3319. pkcs7->decodedAttrib = attrib;
  3320. }
  3321. found++;
  3322. }
  3323. return found;
  3324. }
  3325. /* option to turn off support for degenerate cases
  3326. * flag 0 turns off support
  3327. * flag 1 turns on support
  3328. *
  3329. * by default support for SignedData degenerate cases is on
  3330. */
  3331. void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
  3332. {
  3333. if (pkcs7) {
  3334. if (flag) { /* flag of 1 turns on support for degenerate */
  3335. pkcs7->noDegenerate = 0;
  3336. }
  3337. else { /* flag of 0 turns off support */
  3338. pkcs7->noDegenerate = 1;
  3339. }
  3340. }
  3341. }
  3342. /* Parses through a signerInfo set. Reads buffer "in" from "idxIn" to "idxIn" +
  3343. * length treating the current "idxIn" plus the length of set as max possible
  3344. * index.
  3345. *
  3346. * In the case that signed attributes are found "signedAttrib" gets set to point
  3347. * at their location in the buffer "in". Also in this case signedAttribSz gets
  3348. * set to the size of the signedAttrib buffer.
  3349. *
  3350. * returns 0 on success
  3351. */
  3352. static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
  3353. word32* idxIn, int degenerate, byte** signedAttrib, int* signedAttribSz)
  3354. {
  3355. int ret = 0;
  3356. int length;
  3357. int version;
  3358. word32 sigOID = 0, hashOID = 0;
  3359. word32 idx = *idxIn, localIdx;
  3360. byte tag;
  3361. WOLFSSL_ENTER("wc_PKCS7_ParseSignerInfo");
  3362. /* require a signer if degenerate case not allowed */
  3363. if (inSz == 0 && pkcs7->noDegenerate == 1) {
  3364. WOLFSSL_MSG("Set to not allow degenerate cases");
  3365. return PKCS7_NO_SIGNER_E;
  3366. }
  3367. if (inSz == 0 && degenerate == 0) {
  3368. WOLFSSL_MSG("PKCS7 signers expected");
  3369. return PKCS7_NO_SIGNER_E;
  3370. }
  3371. /* not a degenerate case and there is elements in the set */
  3372. if (inSz > 0 && degenerate == 0) {
  3373. ret = wc_PKCS7_SignerInfoNew(pkcs7);
  3374. /* Get the sequence of the first signerInfo */
  3375. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3376. ret = ASN_PARSE_E;
  3377. /* Get the version */
  3378. if (ret == 0 && GetMyVersion(in, &idx, &version, inSz) < 0)
  3379. ret = ASN_PARSE_E;
  3380. if (ret == 0) {
  3381. pkcs7->signerInfo->version = version;
  3382. }
  3383. if (ret == 0 && version == 1) {
  3384. /* Get the sequence of IssuerAndSerialNumber */
  3385. if (GetSequence(in, &idx, &length, inSz) < 0)
  3386. ret = ASN_PARSE_E;
  3387. if (ret == 0) {
  3388. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3389. idx += length;
  3390. }
  3391. } else if (ret == 0 && version == 3) {
  3392. /* Get the sequence of SubjectKeyIdentifier */
  3393. if (idx + 1 > inSz)
  3394. ret = BUFFER_E;
  3395. localIdx = idx;
  3396. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3397. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3398. idx++;
  3399. if (GetLength(in, &idx, &length, inSz) <= 0)
  3400. ret = ASN_PARSE_E;
  3401. if (ret == 0 && idx + 1 > inSz)
  3402. ret = BUFFER_E;
  3403. if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)
  3404. ret = ASN_PARSE_E;
  3405. if (ret == 0 && tag != ASN_OCTET_STRING)
  3406. ret = ASN_PARSE_E;
  3407. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3408. ret = ASN_PARSE_E;
  3409. }
  3410. else {
  3411. /* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version
  3412. * 3 try to get issuerAndSerial */
  3413. localIdx = idx;
  3414. if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3415. tag == ASN_CONTEXT_SPECIFIC) {
  3416. idx++;
  3417. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3418. ret = ASN_PARSE_E;
  3419. }
  3420. else {
  3421. if (pkcs7->version != 3) {
  3422. WOLFSSL_MSG("Unexpected signer info found with version");
  3423. ret = ASN_PARSE_E;
  3424. }
  3425. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3426. ret = ASN_PARSE_E;
  3427. }
  3428. }
  3429. if (ret == 0) {
  3430. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3431. idx += length;
  3432. }
  3433. } else {
  3434. WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3");
  3435. ret = ASN_VERSION_E;
  3436. }
  3437. /* Get the sequence of digestAlgorithm */
  3438. if (ret == 0 && GetAlgoId(in, &idx, &hashOID, oidHashType, inSz) < 0) {
  3439. ret = ASN_PARSE_E;
  3440. }
  3441. pkcs7->hashOID = (int)hashOID;
  3442. /* Get the IMPLICIT[0] SET OF signedAttributes */
  3443. localIdx = idx;
  3444. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3445. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3446. idx++;
  3447. if (GetLength(in, &idx, &length, inSz) < 0)
  3448. ret = ASN_PARSE_E;
  3449. /* save pointer and length */
  3450. *signedAttrib = &in[idx];
  3451. *signedAttribSz = length;
  3452. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, *signedAttrib,
  3453. *signedAttribSz) < 0) {
  3454. WOLFSSL_MSG("Error parsing signed attributes");
  3455. ret = ASN_PARSE_E;
  3456. }
  3457. idx += length;
  3458. }
  3459. /* Get digestEncryptionAlgorithm */
  3460. if (ret == 0 && GetAlgoId(in, &idx, &sigOID, oidSigType, inSz) < 0) {
  3461. ret = ASN_PARSE_E;
  3462. }
  3463. /* store public key type based on digestEncryptionAlgorithm */
  3464. if (ret == 0) {
  3465. ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
  3466. if (ret < 0) {
  3467. WOLFSSL_MSG("Failed to set public key OID from signature");
  3468. }
  3469. else {
  3470. /* if previous return was positive then was success */
  3471. ret = 0;
  3472. }
  3473. }
  3474. }
  3475. /* update index on success */
  3476. if (ret == 0) {
  3477. *idxIn = idx;
  3478. }
  3479. return ret;
  3480. }
  3481. /* Finds the certificates in the message and saves it. By default allows
  3482. * degenerate cases which can have no signer.
  3483. *
  3484. * By default expects type SIGNED_DATA (SignedData) which can have any number of
  3485. * elements in signerInfos collection, including zero. (RFC2315 section 9.1)
  3486. * When adding support for the case of SignedAndEnvelopedData content types a
  3487. * signer is required. In this case the PKCS7 flag noDegenerate could be set.
  3488. */
  3489. static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
  3490. word32 hashSz, byte* in, word32 inSz,
  3491. byte* in2, word32 in2Sz)
  3492. {
  3493. word32 idx, maxIdx = inSz, outerContentType, contentTypeSz = 0, totalSz = 0;
  3494. int length = 0, version = 0, ret = 0;
  3495. byte* content = NULL;
  3496. byte* contentDynamic = NULL;
  3497. byte* sig = NULL;
  3498. byte* cert = NULL;
  3499. byte* signedAttrib = NULL;
  3500. byte* contentType = NULL;
  3501. int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
  3502. word32 localIdx, start;
  3503. byte degenerate = 0;
  3504. byte detached = 0;
  3505. byte tag = 0;
  3506. #ifdef ASN_BER_TO_DER
  3507. byte* der;
  3508. #endif
  3509. int multiPart = 0, keepContent;
  3510. int contentLen = 0;
  3511. byte* pkiMsg = in;
  3512. word32 pkiMsgSz = inSz;
  3513. #ifndef NO_PKCS7_STREAM
  3514. word32 stateIdx = 0;
  3515. long rc;
  3516. #endif
  3517. byte* pkiMsg2 = in2;
  3518. word32 pkiMsg2Sz = in2Sz;
  3519. if (pkcs7 == NULL)
  3520. return BAD_FUNC_ARG;
  3521. #ifndef NO_PKCS7_STREAM
  3522. /* allow for 0 size inputs with stream mode */
  3523. if (pkiMsg == NULL && pkiMsgSz > 0)
  3524. return BAD_FUNC_ARG;
  3525. #else
  3526. if (pkiMsg == NULL || pkiMsgSz == 0)
  3527. return BAD_FUNC_ARG;
  3528. #endif
  3529. if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
  3530. return BAD_FUNC_ARG;
  3531. }
  3532. idx = 0;
  3533. #ifdef ASN_BER_TO_DER
  3534. if (pkcs7->derSz > 0 && pkcs7->der) {
  3535. pkiMsg = in = pkcs7->der;
  3536. }
  3537. #endif
  3538. #ifndef NO_PKCS7_STREAM
  3539. if (pkcs7->stream == NULL) {
  3540. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  3541. return ret;
  3542. }
  3543. }
  3544. #endif
  3545. switch (pkcs7->state) {
  3546. case WC_PKCS7_START:
  3547. #ifndef NO_PKCS7_STREAM
  3548. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  3549. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
  3550. ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
  3551. &pkiMsg, &idx)) != 0) {
  3552. break;
  3553. }
  3554. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
  3555. if (rc < 0) {
  3556. ret = (int)rc;
  3557. break;
  3558. }
  3559. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
  3560. #endif
  3561. /* determine total message size */
  3562. totalSz = pkiMsgSz;
  3563. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3564. totalSz += pkiMsg2Sz + pkcs7->contentSz;
  3565. }
  3566. /* Get the contentInfo sequence */
  3567. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3568. NO_USER_CHECK) < 0)
  3569. ret = ASN_PARSE_E;
  3570. if (ret == 0 && length == 0 && pkiMsg[idx-1] == 0x80) {
  3571. #ifdef ASN_BER_TO_DER
  3572. word32 len = 0;
  3573. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  3574. if (ret != LENGTH_ONLY_E)
  3575. return ret;
  3576. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3577. if (pkcs7->der == NULL)
  3578. return MEMORY_E;
  3579. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  3580. if (ret < 0)
  3581. return ret;
  3582. pkiMsg = in = pkcs7->der;
  3583. pkiMsgSz = pkcs7->derSz = len;
  3584. idx = 0;
  3585. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  3586. NO_USER_CHECK) < 0)
  3587. return ASN_PARSE_E;
  3588. #ifndef NO_PKCS7_STREAM
  3589. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK,
  3590. pkiMsg, pkiMsgSz);
  3591. if (rc < 0) {
  3592. ret = (int)rc;
  3593. break;
  3594. }
  3595. #endif
  3596. #else
  3597. ret = BER_INDEF_E;
  3598. #endif
  3599. }
  3600. /* Get the contentInfo contentType */
  3601. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,
  3602. pkiMsgSz) < 0)
  3603. ret = ASN_PARSE_E;
  3604. if (ret == 0 && outerContentType != SIGNED_DATA) {
  3605. WOLFSSL_MSG("PKCS#7 input not of type SignedData");
  3606. ret = PKCS7_OID_E;
  3607. }
  3608. /* get the ContentInfo content */
  3609. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)
  3610. ret = ASN_PARSE_E;
  3611. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  3612. ret = ASN_PARSE_E;
  3613. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,
  3614. NO_USER_CHECK) < 0)
  3615. ret = ASN_PARSE_E;
  3616. /* Get the signedData sequence */
  3617. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3618. NO_USER_CHECK) < 0)
  3619. ret = ASN_PARSE_E;
  3620. /* Get the version */
  3621. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  3622. ret = ASN_PARSE_E;
  3623. /* version 1 follows RFC 2315 */
  3624. /* version 3 follows RFC 4108 */
  3625. if (ret == 0 && (version != 1 && version != 3)) {
  3626. WOLFSSL_MSG("PKCS#7 signedData needs to be version 1 or 3");
  3627. ret = ASN_VERSION_E;
  3628. }
  3629. pkcs7->version = version;
  3630. /* Get the set of DigestAlgorithmIdentifiers */
  3631. if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  3632. ret = ASN_PARSE_E;
  3633. /* Skip the set. */
  3634. idx += length;
  3635. degenerate = (length == 0)? 1 : 0;
  3636. if (pkcs7->noDegenerate == 1 && degenerate == 1) {
  3637. ret = PKCS7_NO_SIGNER_E;
  3638. }
  3639. if (ret != 0)
  3640. break;
  3641. #ifndef NO_PKCS7_STREAM
  3642. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  3643. break;
  3644. }
  3645. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3646. pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz;
  3647. }
  3648. wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);
  3649. #endif
  3650. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);
  3651. FALL_THROUGH;
  3652. case WC_PKCS7_VERIFY_STAGE2:
  3653. #ifndef NO_PKCS7_STREAM
  3654. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  3655. MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ
  3656. + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  3657. break;
  3658. }
  3659. wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
  3660. if (pkcs7->stream->length > 0)
  3661. pkiMsgSz = pkcs7->stream->length;
  3662. #ifdef ASN_BER_TO_DER
  3663. else if (pkcs7->der)
  3664. pkiMsgSz = pkcs7->derSz;
  3665. #endif
  3666. else
  3667. pkiMsgSz = inSz;
  3668. #endif
  3669. /* Get the inner ContentInfo sequence */
  3670. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  3671. NO_USER_CHECK) < 0)
  3672. ret = ASN_PARSE_E;
  3673. /* Get the inner ContentInfo contentType */
  3674. if (ret == 0) {
  3675. word32 tmpIdx = idx;
  3676. if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) != 0)
  3677. ret = ASN_PARSE_E;
  3678. contentType = pkiMsg + tmpIdx;
  3679. contentTypeSz = length + (idx - tmpIdx);
  3680. idx += length;
  3681. }
  3682. if (ret != 0)
  3683. break;
  3684. /* Check for content info, it could be omitted when degenerate */
  3685. localIdx = idx;
  3686. ret = 0;
  3687. if (localIdx + 1 > pkiMsgSz) {
  3688. ret = BUFFER_E;
  3689. break;
  3690. }
  3691. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)
  3692. ret = ASN_PARSE_E;
  3693. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  3694. ret = ASN_PARSE_E;
  3695. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
  3696. NO_USER_CHECK) <= 0)
  3697. ret = ASN_PARSE_E;
  3698. if (localIdx >= pkiMsgSz) {
  3699. ret = BUFFER_E;
  3700. }
  3701. /* get length of content in the case that there is multiple parts */
  3702. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  3703. ret = ASN_PARSE_E;
  3704. if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
  3705. multiPart = 1;
  3706. /* Get length of all OCTET_STRINGs. */
  3707. if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,
  3708. NO_USER_CHECK) < 0)
  3709. ret = ASN_PARSE_E;
  3710. /* Check whether there is one OCTET_STRING inside. */
  3711. start = localIdx;
  3712. if (localIdx >= pkiMsgSz) {
  3713. ret = BUFFER_E;
  3714. }
  3715. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)
  3716. != 0)
  3717. ret = ASN_PARSE_E;
  3718. if (ret == 0 && tag != ASN_OCTET_STRING)
  3719. ret = ASN_PARSE_E;
  3720. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
  3721. NO_USER_CHECK) < 0)
  3722. ret = ASN_PARSE_E;
  3723. if (ret == 0) {
  3724. /* Use single OCTET_STRING directly. */
  3725. if (localIdx - start + length == (word32)contentLen)
  3726. multiPart = 0;
  3727. localIdx = start;
  3728. }
  3729. }
  3730. /* get length of content in case of single part */
  3731. if (ret == 0 && !multiPart) {
  3732. if (tag != ASN_OCTET_STRING)
  3733. ret = ASN_PARSE_E;
  3734. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
  3735. &length, pkiMsgSz, NO_USER_CHECK) < 0)
  3736. ret = ASN_PARSE_E;
  3737. }
  3738. /* update idx if successful */
  3739. if (ret == 0) {
  3740. /* support using header and footer without content */
  3741. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  3742. localIdx = 0;
  3743. }
  3744. idx = localIdx;
  3745. }
  3746. else {
  3747. /* if pkcs7->content and pkcs7->contentSz are set, try to
  3748. process as a detached signature */
  3749. if (!degenerate &&
  3750. (pkcs7->content != NULL && pkcs7->contentSz != 0)) {
  3751. detached = 1;
  3752. }
  3753. if (!degenerate && !detached && ret != 0)
  3754. break;
  3755. length = 0; /* no content to read */
  3756. pkiMsg2 = pkiMsg;
  3757. pkiMsg2Sz = pkiMsgSz;
  3758. }
  3759. #ifndef NO_PKCS7_STREAM
  3760. /* save detached flag value */
  3761. pkcs7->stream->detached = detached;
  3762. /* save contentType */
  3763. pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,
  3764. DYNAMIC_TYPE_PKCS7);
  3765. if (pkcs7->stream->nonce == NULL) {
  3766. ret = MEMORY_E;
  3767. break;
  3768. }
  3769. else {
  3770. pkcs7->stream->nonceSz = contentTypeSz;
  3771. XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);
  3772. }
  3773. /* content expected? */
  3774. if ((ret == 0 && length > 0) &&
  3775. !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
  3776. pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;
  3777. }
  3778. else {
  3779. pkcs7->stream->expected = ASN_TAG_SZ + MAX_LENGTH_SZ;
  3780. }
  3781. if (pkcs7->stream->expected > (pkcs7->stream->maxLen - idx)) {
  3782. pkcs7->stream->expected = pkcs7->stream->maxLen - idx;
  3783. }
  3784. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  3785. break;
  3786. }
  3787. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);
  3788. /* content length is in multiple parts */
  3789. if (multiPart) {
  3790. pkcs7->stream->expected = contentLen + ASN_TAG_SZ;
  3791. }
  3792. pkcs7->stream->multi = multiPart;
  3793. #endif
  3794. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);
  3795. FALL_THROUGH;
  3796. case WC_PKCS7_VERIFY_STAGE3:
  3797. #ifndef NO_PKCS7_STREAM
  3798. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  3799. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  3800. break;
  3801. }
  3802. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  3803. pkiMsg, pkiMsgSz);
  3804. if (rc < 0) {
  3805. ret = (int)rc;
  3806. break;
  3807. }
  3808. #ifdef ASN_BER_TO_DER
  3809. if (pkcs7->derSz != 0)
  3810. pkiMsgSz = pkcs7->derSz;
  3811. else
  3812. #endif
  3813. pkiMsgSz = (word32)rc;
  3814. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);
  3815. if (pkcs7->stream->length > 0) {
  3816. localIdx = 0;
  3817. }
  3818. multiPart = pkcs7->stream->multi;
  3819. detached = pkcs7->stream->detached;
  3820. maxIdx = idx + pkcs7->stream->expected;
  3821. #endif
  3822. /* Break out before content because it can be optional in degenerate
  3823. * cases. */
  3824. if (ret != 0 && !degenerate)
  3825. break;
  3826. /* get parts of content */
  3827. if (ret == 0 && multiPart) {
  3828. int i = 0;
  3829. keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
  3830. if (keepContent) {
  3831. /* Create a buffer to hold content of OCTET_STRINGs. */
  3832. pkcs7->contentDynamic = (byte*)XMALLOC(contentLen, pkcs7->heap,
  3833. DYNAMIC_TYPE_PKCS7);
  3834. if (pkcs7->contentDynamic == NULL)
  3835. ret = MEMORY_E;
  3836. }
  3837. start = localIdx;
  3838. /* Use the data from each OCTET_STRING. */
  3839. while (ret == 0 && localIdx < start + contentLen) {
  3840. if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)
  3841. ret = ASN_PARSE_E;
  3842. if (ret == 0 && tag != ASN_OCTET_STRING)
  3843. ret = ASN_PARSE_E;
  3844. if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
  3845. ret = ASN_PARSE_E;
  3846. if (ret == 0 && length + localIdx > start + contentLen)
  3847. ret = ASN_PARSE_E;
  3848. if (ret == 0) {
  3849. if (keepContent) {
  3850. XMEMCPY(pkcs7->contentDynamic + i, pkiMsg + localIdx,
  3851. length);
  3852. }
  3853. i += length;
  3854. localIdx += length;
  3855. }
  3856. }
  3857. localIdx = start; /* reset for sanity check, increment later */
  3858. length = i;
  3859. }
  3860. /* Save the inner data as the content. */
  3861. if (ret == 0 && length > 0) {
  3862. contentSz = length;
  3863. /* support using header and footer without content */
  3864. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  3865. /* Content not provided, use provided pkiMsg2 footer */
  3866. content = NULL;
  3867. localIdx = 0;
  3868. if (contentSz != (int)pkcs7->contentSz) {
  3869. WOLFSSL_MSG("Data signed does not match contentSz provided");
  3870. ret = BUFFER_E;
  3871. }
  3872. }
  3873. else {
  3874. if ((word32)length > pkiMsgSz - localIdx) {
  3875. ret = BUFFER_E;
  3876. }
  3877. /* Content pointer for calculating hashes later */
  3878. if (ret == 0 && !multiPart) {
  3879. content = &pkiMsg[localIdx];
  3880. }
  3881. if (ret == 0 && multiPart) {
  3882. content = pkcs7->contentDynamic;
  3883. }
  3884. if (ret == 0) {
  3885. idx += length;
  3886. pkiMsg2 = pkiMsg;
  3887. pkiMsg2Sz = pkiMsgSz;
  3888. #ifndef NO_PKCS7_STREAM
  3889. pkcs7->stream->varOne = pkiMsg2Sz;
  3890. pkcs7->stream->flagOne = 1;
  3891. #endif
  3892. }
  3893. }
  3894. }
  3895. else {
  3896. pkiMsg2 = pkiMsg;
  3897. pkiMsg2Sz = pkiMsgSz;
  3898. #ifndef NO_PKCS7_STREAM
  3899. pkcs7->stream->varOne = pkiMsg2Sz;
  3900. pkcs7->stream->flagOne = 1;
  3901. #endif
  3902. }
  3903. /* If getting the content info failed with non degenerate then return the
  3904. * error case. Otherwise with a degenerate it is ok if the content
  3905. * info was omitted */
  3906. if (!degenerate && !detached && (ret != 0)) {
  3907. break;
  3908. }
  3909. else {
  3910. ret = 0; /* reset ret state on degenerate case */
  3911. }
  3912. #ifndef NO_PKCS7_STREAM
  3913. /* save content */
  3914. if (detached == 1) {
  3915. /* if detached, use content from user in pkcs7 struct */
  3916. content = pkcs7->content;
  3917. contentSz = pkcs7->contentSz;
  3918. }
  3919. if (content != NULL) {
  3920. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3921. pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,
  3922. DYNAMIC_TYPE_PKCS7);
  3923. if (pkcs7->stream->content == NULL) {
  3924. ret = MEMORY_E;
  3925. break;
  3926. }
  3927. else {
  3928. XMEMCPY(pkcs7->stream->content, content, contentSz);
  3929. pkcs7->stream->contentSz = contentSz;
  3930. }
  3931. }
  3932. #endif /* !NO_PKCS7_STREAM */
  3933. /* Get the implicit[0] set of certificates */
  3934. if (ret == 0 && idx >= pkiMsg2Sz)
  3935. ret = BUFFER_E;
  3936. length = 0; /* set length to 0 to check if reading in any certs */
  3937. localIdx = idx;
  3938. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  3939. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3940. idx++;
  3941. if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)
  3942. < 0)
  3943. ret = ASN_PARSE_E;
  3944. }
  3945. if (ret != 0) {
  3946. break;
  3947. }
  3948. #ifndef NO_PKCS7_STREAM
  3949. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  3950. stateIdx = idx; /* case where all data was read from in2 */
  3951. }
  3952. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  3953. break;
  3954. }
  3955. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  3956. if (length > 0) {
  3957. pkcs7->stream->expected = length;
  3958. }
  3959. else {
  3960. pkcs7->stream->expected = MAX_SEQ_SZ;
  3961. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  3962. pkcs7->stream->totalRd) + pkcs7->stream->length) {
  3963. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  3964. pkcs7->stream->totalRd) + pkcs7->stream->length;
  3965. }
  3966. }
  3967. #endif
  3968. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
  3969. FALL_THROUGH;
  3970. case WC_PKCS7_VERIFY_STAGE4:
  3971. #ifndef NO_PKCS7_STREAM
  3972. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  3973. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  3974. break;
  3975. }
  3976. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  3977. if (pkcs7->stream->flagOne) {
  3978. pkiMsg2 = pkiMsg;
  3979. }
  3980. /* restore content */
  3981. content = pkcs7->stream->content;
  3982. contentSz = pkcs7->stream->contentSz;
  3983. /* restore detached flag */
  3984. detached = pkcs7->stream->detached;
  3985. /* store certificate if needed */
  3986. if (length > 0 && in2Sz == 0) {
  3987. /* free tmpCert if not NULL */
  3988. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3989. pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
  3990. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3991. if ((pkiMsg2 == NULL) || (pkcs7->stream->tmpCert == NULL)) {
  3992. ret = MEMORY_E;
  3993. break;
  3994. }
  3995. XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
  3996. pkiMsg2 = pkcs7->stream->tmpCert;
  3997. pkiMsg2Sz = length;
  3998. idx = 0;
  3999. }
  4000. #endif
  4001. if (length > 0) {
  4002. /* At this point, idx is at the first certificate in
  4003. * a set of certificates. There may be more than one,
  4004. * or none, or they may be a PKCS 6 extended
  4005. * certificate. We want to save the first cert if it
  4006. * is X.509. */
  4007. word32 certIdx = idx;
  4008. if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)
  4009. ret = BUFFER_E;
  4010. if (ret == 0)
  4011. ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);
  4012. if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4013. if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
  4014. ret = ASN_PARSE_E;
  4015. cert = &pkiMsg2[idx];
  4016. certSz += (certIdx - idx);
  4017. if (certSz > length) {
  4018. ret = BUFFER_E;
  4019. break;
  4020. }
  4021. }
  4022. #ifdef ASN_BER_TO_DER
  4023. der = pkcs7->der;
  4024. #endif
  4025. contentDynamic = pkcs7->contentDynamic;
  4026. version = pkcs7->version;
  4027. if (ret == 0) {
  4028. #ifndef NO_PKCS7_STREAM
  4029. PKCS7State* stream = pkcs7->stream;
  4030. #endif
  4031. /* This will reset PKCS7 structure and then set the
  4032. * certificate */
  4033. ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
  4034. #ifndef NO_PKCS7_STREAM
  4035. pkcs7->stream = stream;
  4036. #endif
  4037. }
  4038. pkcs7->contentDynamic = contentDynamic;
  4039. pkcs7->version = version;
  4040. #ifdef ASN_BER_TO_DER
  4041. pkcs7->der = der;
  4042. #endif
  4043. if (ret != 0)
  4044. break;
  4045. /* iterate through any additional certificates */
  4046. if (ret == 0 && MAX_PKCS7_CERTS > 0) {
  4047. int sz = 0;
  4048. int i;
  4049. pkcs7->cert[0] = cert;
  4050. pkcs7->certSz[0] = certSz;
  4051. certIdx = idx + certSz;
  4052. for (i = 1; i < MAX_PKCS7_CERTS &&
  4053. certIdx + 1 < pkiMsg2Sz &&
  4054. certIdx + 1 < (word32)length; i++) {
  4055. localIdx = certIdx;
  4056. if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,
  4057. pkiMsg2Sz) < 0) {
  4058. ret = ASN_PARSE_E;
  4059. break;
  4060. }
  4061. if (ret == 0 &&
  4062. tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4063. if (GetLength(pkiMsg2, &certIdx, &sz,
  4064. pkiMsg2Sz) < 0) {
  4065. ret = ASN_PARSE_E;
  4066. break;
  4067. }
  4068. pkcs7->cert[i] = &pkiMsg2[localIdx];
  4069. pkcs7->certSz[i] = sz + (certIdx - localIdx);
  4070. certIdx += sz;
  4071. }
  4072. }
  4073. }
  4074. }
  4075. idx += length;
  4076. if (!detached) {
  4077. /* set content and size after init of PKCS7 structure */
  4078. pkcs7->content = content;
  4079. pkcs7->contentSz = contentSz;
  4080. }
  4081. #ifndef NO_PKCS7_STREAM
  4082. else {
  4083. /* save content if detached and using streaming API */
  4084. if (pkcs7->content != NULL) {
  4085. XFREE(pkcs7->stream->content, pkcs7->heap,
  4086. DYNAMIC_TYPE_PKCS7);
  4087. pkcs7->stream->content = (byte*)XMALLOC(pkcs7->contentSz,
  4088. pkcs7->heap,
  4089. DYNAMIC_TYPE_PKCS7);
  4090. if (pkcs7->stream->content == NULL) {
  4091. ret = MEMORY_E;
  4092. break;
  4093. }
  4094. else {
  4095. XMEMCPY(pkcs7->stream->content, pkcs7->content,
  4096. contentSz);
  4097. pkcs7->stream->contentSz = pkcs7->contentSz;
  4098. }
  4099. }
  4100. }
  4101. #endif
  4102. if (ret != 0) {
  4103. break;
  4104. }
  4105. #ifndef NO_PKCS7_STREAM
  4106. /* factor in that recent idx was in cert buffer. If in2 buffer was
  4107. * used then don't advance idx. */
  4108. if (length > 0 && pkcs7->stream->flagOne &&
  4109. pkcs7->stream->length == 0) {
  4110. idx = stateIdx + idx;
  4111. if (idx > inSz) {
  4112. /* index is more than input size */
  4113. ret = BUFFER_E;
  4114. break;
  4115. }
  4116. }
  4117. else {
  4118. stateIdx = idx; /* didn't read any from internal buffer */
  4119. }
  4120. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4121. break;
  4122. }
  4123. if (pkcs7->stream->flagOne && pkcs7->stream->length > 0) {
  4124. idx = stateIdx + idx;
  4125. }
  4126. pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +
  4127. MAX_SET_SZ;
  4128. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  4129. pkcs7->stream->totalRd) + pkcs7->stream->length)
  4130. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4131. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4132. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0);
  4133. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4134. #endif
  4135. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
  4136. FALL_THROUGH;
  4137. case WC_PKCS7_VERIFY_STAGE5:
  4138. #ifndef NO_PKCS7_STREAM
  4139. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4140. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4141. break;
  4142. }
  4143. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4144. if (pkcs7->stream->flagOne) {
  4145. pkiMsg2 = pkiMsg;
  4146. }
  4147. /* restore content type */
  4148. contentType = pkcs7->stream->nonce;
  4149. contentTypeSz = pkcs7->stream->nonceSz;
  4150. maxIdx = idx + pkcs7->stream->expected;
  4151. if (maxIdx > pkiMsg2Sz) {
  4152. ret = BUFFER_E;
  4153. break;
  4154. }
  4155. stateIdx = idx;
  4156. #endif
  4157. /* set contentType and size after init of PKCS7 structure */
  4158. if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,
  4159. contentTypeSz) < 0)
  4160. ret = ASN_PARSE_E;
  4161. /* Get the implicit[1] set of crls */
  4162. if (ret == 0 && idx >= maxIdx)
  4163. ret = BUFFER_E;
  4164. localIdx = idx;
  4165. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  4166. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  4167. idx++;
  4168. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4169. ret = ASN_PARSE_E;
  4170. /* Skip the set */
  4171. idx += length;
  4172. }
  4173. /* Get the set of signerInfos */
  4174. if (ret == 0 && GetSet_ex(pkiMsg2, &idx, &length, maxIdx,
  4175. NO_USER_CHECK) < 0)
  4176. ret = ASN_PARSE_E;
  4177. if (ret != 0)
  4178. break;
  4179. #ifndef NO_PKCS7_STREAM
  4180. if (!pkcs7->stream->flagOne) {
  4181. stateIdx = idx; /* didn't read any from internal buffer */
  4182. }
  4183. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4184. break;
  4185. }
  4186. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4187. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  4188. if (length > 0) {
  4189. pkcs7->stream->expected = length;
  4190. }
  4191. else {
  4192. pkcs7->stream->expected = 0;
  4193. }
  4194. }
  4195. else {
  4196. /* last state expect the reset of the buffer */
  4197. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4198. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4199. }
  4200. #endif
  4201. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);
  4202. FALL_THROUGH;
  4203. case WC_PKCS7_VERIFY_STAGE6:
  4204. #ifndef NO_PKCS7_STREAM
  4205. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4206. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4207. break;
  4208. }
  4209. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4210. if (pkcs7->stream->flagOne) {
  4211. pkiMsg2 = pkiMsg;
  4212. }
  4213. /* restore content */
  4214. content = pkcs7->stream->content;
  4215. contentSz = pkcs7->stream->contentSz;
  4216. #endif
  4217. ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx,
  4218. degenerate, &signedAttrib, &signedAttribSz);
  4219. /* parse out the signature if present and verify it */
  4220. if (ret == 0 && length > 0 && degenerate == 0) {
  4221. WOLFSSL_MSG("Parsing signature and verifying");
  4222. if (idx >= pkiMsg2Sz)
  4223. ret = BUFFER_E;
  4224. /* Get the signature */
  4225. localIdx = idx;
  4226. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,
  4227. pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {
  4228. idx++;
  4229. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4230. ret = ASN_PARSE_E;
  4231. /* save pointer and length */
  4232. sig = &pkiMsg2[idx];
  4233. sigSz = length;
  4234. idx += length;
  4235. }
  4236. pkcs7->content = content;
  4237. pkcs7->contentSz = contentSz;
  4238. if (ret == 0) {
  4239. ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
  4240. signedAttrib, signedAttribSz,
  4241. hashBuf, hashSz);
  4242. }
  4243. }
  4244. if (ret < 0)
  4245. break;
  4246. ret = 0; /* success */
  4247. #ifndef NO_PKCS7_STREAM
  4248. wc_PKCS7_ResetStream(pkcs7);
  4249. #endif
  4250. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4251. break;
  4252. default:
  4253. WOLFSSL_MSG("PKCS7 Unknown verify state");
  4254. ret = BAD_FUNC_ARG;
  4255. }
  4256. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  4257. #ifndef NO_PKCS7_STREAM
  4258. wc_PKCS7_ResetStream(pkcs7);
  4259. #endif
  4260. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4261. }
  4262. return ret;
  4263. }
  4264. /* Gets a copy of the SID parsed from signerInfo. This can be called after
  4265. * wc_PKCS7_VerifySignedData has been called. SID can be SKID in version 3 case
  4266. * or issuerAndSerialNumber.
  4267. *
  4268. * return 0 on success and LENGTH_ONLY_E if just setting "outSz" for buffer
  4269. * length needed.
  4270. */
  4271. int wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz)
  4272. {
  4273. if (outSz == NULL || pkcs7 == NULL) {
  4274. return BAD_FUNC_ARG;
  4275. }
  4276. if (pkcs7->signerInfo == NULL) {
  4277. WOLFSSL_MSG("Either the bundle had no signers or"
  4278. "wc_PKCS7_VerifySignedData needs called yet");
  4279. return PKCS7_NO_SIGNER_E;
  4280. }
  4281. if (pkcs7->signerInfo->sidSz == 0) {
  4282. WOLFSSL_MSG("Bundle had no signer SID set");
  4283. return PKCS7_NO_SIGNER_E;
  4284. }
  4285. if (out == NULL) {
  4286. *outSz = pkcs7->signerInfo->sidSz;
  4287. return LENGTH_ONLY_E;
  4288. }
  4289. if (*outSz < pkcs7->signerInfo->sidSz) {
  4290. WOLFSSL_MSG("Buffer being passed in is not large enough for SKID");
  4291. return BUFFER_E;
  4292. }
  4293. XMEMCPY(out, pkcs7->signerInfo->sid, pkcs7->signerInfo->sidSz);
  4294. *outSz = pkcs7->signerInfo->sidSz;
  4295. return 0;
  4296. }
  4297. /* variant that allows computed data hash and header/foot,
  4298. * which is useful for large data signing */
  4299. int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  4300. word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
  4301. word32 pkiMsgFootSz)
  4302. {
  4303. return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,
  4304. pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);
  4305. }
  4306. int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
  4307. {
  4308. return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);
  4309. }
  4310. /* Generate random content encryption key, store into pkcs7->cek and
  4311. * pkcs7->cekSz.
  4312. *
  4313. * pkcs7 - pointer to initialized PKCS7 structure
  4314. * len - length of key to be generated
  4315. *
  4316. * Returns 0 on success, negative upon error */
  4317. static int PKCS7_GenerateContentEncryptionKey(PKCS7* pkcs7, word32 len)
  4318. {
  4319. int ret;
  4320. WC_RNG rng;
  4321. byte* tmpKey;
  4322. if (pkcs7 == NULL || len == 0)
  4323. return BAD_FUNC_ARG;
  4324. /* if key already exists, don't need to re-generate */
  4325. if (pkcs7->cek != NULL && pkcs7->cekSz != 0) {
  4326. /* if key exists, but is different size, return error */
  4327. if (pkcs7->cekSz != len) {
  4328. WOLFSSL_MSG("Random content-encryption key size is inconsistent "
  4329. "between CMS recipients");
  4330. return WC_KEY_SIZE_E;
  4331. }
  4332. return 0;
  4333. }
  4334. /* allocate space for cek */
  4335. tmpKey = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4336. if (tmpKey == NULL)
  4337. return MEMORY_E;
  4338. XMEMSET(tmpKey, 0, len);
  4339. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  4340. if (ret != 0) {
  4341. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4342. return ret;
  4343. }
  4344. ret = wc_RNG_GenerateBlock(&rng, tmpKey, len);
  4345. if (ret != 0) {
  4346. wc_FreeRng(&rng);
  4347. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4348. return ret;
  4349. }
  4350. /* store into PKCS7, memory freed during final cleanup */
  4351. pkcs7->cek = tmpKey;
  4352. pkcs7->cekSz = len;
  4353. wc_FreeRng(&rng);
  4354. return 0;
  4355. }
  4356. /* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */
  4357. static int wc_PKCS7_KeyWrap(byte* cek, word32 cekSz, byte* kek,
  4358. word32 kekSz, byte* out, word32 outSz,
  4359. int keyWrapAlgo, int direction)
  4360. {
  4361. int ret = 0;
  4362. if (cek == NULL || kek == NULL || out == NULL)
  4363. return BAD_FUNC_ARG;
  4364. switch (keyWrapAlgo) {
  4365. #ifndef NO_AES
  4366. #ifdef WOLFSSL_AES_128
  4367. case AES128_WRAP:
  4368. #endif
  4369. #ifdef WOLFSSL_AES_192
  4370. case AES192_WRAP:
  4371. #endif
  4372. #ifdef WOLFSSL_AES_256
  4373. case AES256_WRAP:
  4374. #endif
  4375. if (direction == AES_ENCRYPTION) {
  4376. ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,
  4377. out, outSz, NULL);
  4378. } else if (direction == AES_DECRYPTION) {
  4379. ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,
  4380. out, outSz, NULL);
  4381. } else {
  4382. WOLFSSL_MSG("Bad key un/wrap direction");
  4383. return BAD_FUNC_ARG;
  4384. }
  4385. if (ret <= 0)
  4386. return ret;
  4387. break;
  4388. #endif /* NO_AES */
  4389. default:
  4390. WOLFSSL_MSG("Unsupported key wrap algorithm");
  4391. return BAD_KEYWRAP_ALG_E;
  4392. };
  4393. (void)cekSz;
  4394. (void)kekSz;
  4395. (void)outSz;
  4396. (void)direction;
  4397. return ret;
  4398. }
  4399. #ifdef HAVE_ECC
  4400. /* KARI == KeyAgreeRecipientInfo (key agreement) */
  4401. typedef struct WC_PKCS7_KARI {
  4402. DecodedCert* decoded; /* decoded recip cert */
  4403. void* heap; /* user heap, points to PKCS7->heap */
  4404. int devId; /* device ID for HW based private key */
  4405. ecc_key* recipKey; /* recip key (pub | priv) */
  4406. ecc_key* senderKey; /* sender key (pub | priv) */
  4407. byte* senderKeyExport; /* sender ephemeral key DER */
  4408. byte* kek; /* key encryption key */
  4409. byte* ukm; /* OPTIONAL user keying material */
  4410. byte* sharedInfo; /* ECC-CMS-SharedInfo ASN.1 encoded blob */
  4411. word32 senderKeyExportSz; /* size of sender ephemeral key DER */
  4412. word32 kekSz; /* size of key encryption key */
  4413. word32 ukmSz; /* size of user keying material */
  4414. word32 sharedInfoSz; /* size of ECC-CMS-SharedInfo encoded */
  4415. byte ukmOwner; /* do we own ukm buffer? 1:yes, 0:no */
  4416. byte direction; /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */
  4417. byte decodedInit : 1; /* indicates decoded was initialized */
  4418. byte recipKeyInit : 1; /* indicates recipKey was initialized */
  4419. byte senderKeyInit : 1; /* indicates senderKey was initialized */
  4420. } WC_PKCS7_KARI;
  4421. /* allocate and create new WC_PKCS7_KARI struct,
  4422. * returns struct pointer on success, NULL on failure */
  4423. static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)
  4424. {
  4425. WC_PKCS7_KARI* kari = NULL;
  4426. if (pkcs7 == NULL)
  4427. return NULL;
  4428. kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,
  4429. DYNAMIC_TYPE_PKCS7);
  4430. if (kari == NULL) {
  4431. WOLFSSL_MSG("Failed to allocate WC_PKCS7_KARI");
  4432. return NULL;
  4433. }
  4434. kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  4435. DYNAMIC_TYPE_PKCS7);
  4436. if (kari->decoded == NULL) {
  4437. WOLFSSL_MSG("Failed to allocate DecodedCert");
  4438. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4439. return NULL;
  4440. }
  4441. kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4442. DYNAMIC_TYPE_PKCS7);
  4443. if (kari->recipKey == NULL) {
  4444. WOLFSSL_MSG("Failed to allocate recipient ecc_key");
  4445. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4446. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4447. return NULL;
  4448. }
  4449. kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4450. DYNAMIC_TYPE_PKCS7);
  4451. if (kari->senderKey == NULL) {
  4452. WOLFSSL_MSG("Failed to allocate sender ecc_key");
  4453. XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4454. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4455. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4456. return NULL;
  4457. }
  4458. kari->senderKeyExport = NULL;
  4459. kari->senderKeyExportSz = 0;
  4460. kari->kek = NULL;
  4461. kari->kekSz = 0;
  4462. kari->ukm = NULL;
  4463. kari->ukmSz = 0;
  4464. kari->ukmOwner = 0;
  4465. kari->sharedInfo = NULL;
  4466. kari->sharedInfoSz = 0;
  4467. kari->direction = direction;
  4468. kari->decodedInit = 0;
  4469. kari->recipKeyInit = 0;
  4470. kari->senderKeyInit = 0;
  4471. kari->heap = pkcs7->heap;
  4472. kari->devId = pkcs7->devId;
  4473. return kari;
  4474. }
  4475. /* free WC_PKCS7_KARI struct, return 0 on success */
  4476. static int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)
  4477. {
  4478. void* heap;
  4479. if (kari) {
  4480. heap = kari->heap;
  4481. if (kari->decoded) {
  4482. if (kari->decodedInit)
  4483. FreeDecodedCert(kari->decoded);
  4484. XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);
  4485. }
  4486. if (kari->senderKey) {
  4487. if (kari->senderKeyInit)
  4488. wc_ecc_free(kari->senderKey);
  4489. XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);
  4490. }
  4491. if (kari->recipKey) {
  4492. if (kari->recipKeyInit)
  4493. wc_ecc_free(kari->recipKey);
  4494. XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);
  4495. }
  4496. if (kari->senderKeyExport) {
  4497. ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);
  4498. XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);
  4499. kari->senderKeyExportSz = 0;
  4500. }
  4501. if (kari->kek) {
  4502. ForceZero(kari->kek, kari->kekSz);
  4503. XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);
  4504. kari->kekSz = 0;
  4505. }
  4506. if (kari->ukm) {
  4507. if (kari->ukmOwner == 1) {
  4508. XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);
  4509. }
  4510. kari->ukmSz = 0;
  4511. }
  4512. if (kari->sharedInfo) {
  4513. ForceZero(kari->sharedInfo, kari->sharedInfoSz);
  4514. XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);
  4515. kari->sharedInfoSz = 0;
  4516. }
  4517. XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);
  4518. }
  4519. (void)heap;
  4520. return 0;
  4521. }
  4522. /* parse recipient cert/key, return 0 on success, negative on error
  4523. * key/keySz only needed during decoding (WC_PKCS7_DECODE) */
  4524. static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
  4525. word32 certSz, const byte* key,
  4526. word32 keySz)
  4527. {
  4528. int ret;
  4529. word32 idx;
  4530. if (kari == NULL || kari->decoded == NULL ||
  4531. cert == NULL || certSz == 0)
  4532. return BAD_FUNC_ARG;
  4533. /* decode certificate */
  4534. InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
  4535. kari->decodedInit = 1;
  4536. ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
  4537. if (ret < 0)
  4538. return ret;
  4539. /* only supports ECDSA for now */
  4540. if (kari->decoded->keyOID != ECDSAk) {
  4541. WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
  4542. return BAD_FUNC_ARG;
  4543. }
  4544. /* make sure subject key id was read from cert */
  4545. if (kari->decoded->extSubjKeyIdSet == 0) {
  4546. WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
  4547. return BAD_FUNC_ARG;
  4548. }
  4549. ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
  4550. if (ret != 0)
  4551. return ret;
  4552. kari->recipKeyInit = 1;
  4553. /* get recip public key */
  4554. if (kari->direction == WC_PKCS7_ENCODE) {
  4555. idx = 0;
  4556. ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
  4557. kari->recipKey, kari->decoded->pubKeySize);
  4558. if (ret != 0)
  4559. return ret;
  4560. }
  4561. /* get recip private key */
  4562. else if (kari->direction == WC_PKCS7_DECODE) {
  4563. if (key != NULL && keySz > 0) {
  4564. idx = 0;
  4565. ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);
  4566. }
  4567. else if (kari->devId == INVALID_DEVID) {
  4568. ret = BAD_FUNC_ARG;
  4569. }
  4570. if (ret != 0)
  4571. return ret;
  4572. } else {
  4573. /* bad direction */
  4574. return BAD_FUNC_ARG;
  4575. }
  4576. (void)idx;
  4577. return 0;
  4578. }
  4579. /* create ephemeral ECC key, places ecc_key in kari->senderKey,
  4580. * DER encoded in kari->senderKeyExport. return 0 on success,
  4581. * negative on error */
  4582. static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari)
  4583. {
  4584. int ret;
  4585. WC_RNG rng;
  4586. if (kari == NULL || kari->decoded == NULL ||
  4587. kari->recipKey == NULL || kari->recipKey->dp == NULL)
  4588. return BAD_FUNC_ARG;
  4589. kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,
  4590. kari->heap, DYNAMIC_TYPE_PKCS7);
  4591. if (kari->senderKeyExport == NULL)
  4592. return MEMORY_E;
  4593. kari->senderKeyExportSz = kari->decoded->pubKeySize;
  4594. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  4595. if (ret != 0) {
  4596. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4597. return ret;
  4598. }
  4599. kari->senderKeyInit = 1;
  4600. ret = wc_InitRng_ex(&rng, kari->heap, kari->devId);
  4601. if (ret != 0) {
  4602. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4603. return ret;
  4604. }
  4605. ret = wc_ecc_make_key_ex(&rng, kari->recipKey->dp->size,
  4606. kari->senderKey, kari->recipKey->dp->id);
  4607. if (ret != 0) {
  4608. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4609. wc_FreeRng(&rng);
  4610. return ret;
  4611. }
  4612. wc_FreeRng(&rng);
  4613. /* dump generated key to X.963 DER for output in CMS bundle */
  4614. ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,
  4615. &kari->senderKeyExportSz);
  4616. if (ret != 0) {
  4617. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4618. return ret;
  4619. }
  4620. return 0;
  4621. }
  4622. /* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,
  4623. * place in kari->sharedInfo. returns 0 on success, negative on error */
  4624. static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)
  4625. {
  4626. int idx = 0;
  4627. int sharedInfoSeqSz = 0;
  4628. int keyInfoSz = 0;
  4629. int suppPubInfoSeqSz = 0;
  4630. int entityUInfoOctetSz = 0;
  4631. int entityUInfoExplicitSz = 0;
  4632. int kekOctetSz = 0;
  4633. int sharedInfoSz = 0;
  4634. word32 kekBitSz = 0;
  4635. byte sharedInfoSeq[MAX_SEQ_SZ];
  4636. byte keyInfo[MAX_ALGO_SZ];
  4637. byte suppPubInfoSeq[MAX_SEQ_SZ];
  4638. byte entityUInfoOctet[MAX_OCTET_STR_SZ];
  4639. byte entityUInfoExplicitSeq[MAX_SEQ_SZ];
  4640. byte kekOctet[MAX_OCTET_STR_SZ];
  4641. if (kari == NULL)
  4642. return BAD_FUNC_ARG;
  4643. if ((kari->ukmSz > 0) && (kari->ukm == NULL))
  4644. return BAD_FUNC_ARG;
  4645. /* kekOctet */
  4646. kekOctetSz = SetOctetString(sizeof(word32), kekOctet);
  4647. sharedInfoSz += (kekOctetSz + sizeof(word32));
  4648. /* suppPubInfo */
  4649. suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,
  4650. kekOctetSz + sizeof(word32),
  4651. suppPubInfoSeq);
  4652. sharedInfoSz += suppPubInfoSeqSz;
  4653. /* optional ukm/entityInfo */
  4654. if (kari->ukmSz > 0) {
  4655. entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);
  4656. sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);
  4657. entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +
  4658. kari->ukmSz,
  4659. entityUInfoExplicitSeq);
  4660. sharedInfoSz += entityUInfoExplicitSz;
  4661. }
  4662. /* keyInfo */
  4663. keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);
  4664. sharedInfoSz += keyInfoSz;
  4665. /* sharedInfo */
  4666. sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);
  4667. sharedInfoSz += sharedInfoSeqSz;
  4668. kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,
  4669. DYNAMIC_TYPE_PKCS7);
  4670. if (kari->sharedInfo == NULL)
  4671. return MEMORY_E;
  4672. kari->sharedInfoSz = sharedInfoSz;
  4673. XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);
  4674. idx += sharedInfoSeqSz;
  4675. XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);
  4676. idx += keyInfoSz;
  4677. if (kari->ukmSz > 0) {
  4678. XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,
  4679. entityUInfoExplicitSz);
  4680. idx += entityUInfoExplicitSz;
  4681. XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);
  4682. idx += entityUInfoOctetSz;
  4683. XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);
  4684. idx += kari->ukmSz;
  4685. }
  4686. XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);
  4687. idx += suppPubInfoSeqSz;
  4688. XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);
  4689. idx += kekOctetSz;
  4690. kekBitSz = (kari->kekSz) * 8; /* convert to bits */
  4691. #ifdef LITTLE_ENDIAN_ORDER
  4692. kekBitSz = ByteReverseWord32(kekBitSz); /* network byte order */
  4693. #endif
  4694. XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));
  4695. return 0;
  4696. }
  4697. /* create key encryption key (KEK) using key wrap algorithm and key encryption
  4698. * algorithm, place in kari->kek. return 0 on success, <0 on error. */
  4699. static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng,
  4700. int keyWrapOID, int keyEncOID)
  4701. {
  4702. int ret;
  4703. int kSz;
  4704. enum wc_HashType kdfType;
  4705. byte* secret;
  4706. word32 secretSz;
  4707. if (kari == NULL || kari->recipKey == NULL ||
  4708. kari->senderKey == NULL || kari->senderKey->dp == NULL)
  4709. return BAD_FUNC_ARG;
  4710. /* get KEK size, allocate buff */
  4711. kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);
  4712. if (kSz < 0)
  4713. return kSz;
  4714. kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  4715. if (kari->kek == NULL)
  4716. return MEMORY_E;
  4717. kari->kekSz = (word32)kSz;
  4718. /* generate ECC-CMS-SharedInfo */
  4719. ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);
  4720. if (ret != 0)
  4721. return ret;
  4722. /* generate shared secret */
  4723. secretSz = kari->senderKey->dp->size;
  4724. secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  4725. if (secret == NULL)
  4726. return MEMORY_E;
  4727. #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
  4728. (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))) && \
  4729. !defined(HAVE_SELFTEST)
  4730. ret = wc_ecc_set_rng(kari->senderKey, rng);
  4731. if (ret != 0)
  4732. return ret;
  4733. ret = wc_ecc_set_rng(kari->recipKey, rng);
  4734. if (ret != 0)
  4735. return ret;
  4736. #else
  4737. (void)rng;
  4738. #endif
  4739. if (kari->direction == WC_PKCS7_ENCODE) {
  4740. ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,
  4741. secret, &secretSz);
  4742. } else if (kari->direction == WC_PKCS7_DECODE) {
  4743. ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,
  4744. secret, &secretSz);
  4745. } else {
  4746. /* bad direction */
  4747. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  4748. return BAD_FUNC_ARG;
  4749. }
  4750. if (ret != 0) {
  4751. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  4752. return ret;
  4753. }
  4754. /* run through KDF */
  4755. switch (keyEncOID) {
  4756. #ifndef NO_SHA
  4757. case dhSinglePass_stdDH_sha1kdf_scheme:
  4758. kdfType = WC_HASH_TYPE_SHA;
  4759. break;
  4760. #endif
  4761. #ifndef WOLFSSL_SHA224
  4762. case dhSinglePass_stdDH_sha224kdf_scheme:
  4763. kdfType = WC_HASH_TYPE_SHA224;
  4764. break;
  4765. #endif
  4766. #ifndef NO_SHA256
  4767. case dhSinglePass_stdDH_sha256kdf_scheme:
  4768. kdfType = WC_HASH_TYPE_SHA256;
  4769. break;
  4770. #endif
  4771. #ifdef WOLFSSL_SHA384
  4772. case dhSinglePass_stdDH_sha384kdf_scheme:
  4773. kdfType = WC_HASH_TYPE_SHA384;
  4774. break;
  4775. #endif
  4776. #ifdef WOLFSSL_SHA512
  4777. case dhSinglePass_stdDH_sha512kdf_scheme:
  4778. kdfType = WC_HASH_TYPE_SHA512;
  4779. break;
  4780. #endif
  4781. default:
  4782. WOLFSSL_MSG("Unsupported key agreement algorithm");
  4783. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  4784. return BAD_FUNC_ARG;
  4785. };
  4786. ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,
  4787. kari->sharedInfoSz, kari->kek, kari->kekSz);
  4788. if (ret != 0) {
  4789. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  4790. return ret;
  4791. }
  4792. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  4793. return 0;
  4794. }
  4795. /* Encode and add CMS EnvelopedData KARI (KeyAgreeRecipientInfo) RecipientInfo
  4796. * to CMS/PKCS#7 EnvelopedData structure.
  4797. *
  4798. * Returns 0 on success, negative upon error */
  4799. int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  4800. int keyWrapOID, int keyAgreeOID, byte* ukm,
  4801. word32 ukmSz, int options)
  4802. {
  4803. Pkcs7EncodedRecip* recip;
  4804. Pkcs7EncodedRecip* lastRecip = NULL;
  4805. WC_PKCS7_KARI* kari = NULL;
  4806. word32 idx = 0;
  4807. word32 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  4808. int ret = 0;
  4809. int keySz, direction = 0;
  4810. int blockKeySz = 0;
  4811. /* ASN.1 layout */
  4812. int totalSz = 0;
  4813. int kariSeqSz = 0;
  4814. byte kariSeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  4815. int verSz = 0;
  4816. byte ver[MAX_VERSION_SZ];
  4817. int origIdOrKeySeqSz = 0;
  4818. byte origIdOrKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  4819. int origPubKeySeqSz = 0;
  4820. byte origPubKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  4821. int origAlgIdSz = 0;
  4822. byte origAlgId[MAX_ALGO_SZ];
  4823. int origPubKeyStrSz = 0;
  4824. byte origPubKeyStr[MAX_OCTET_STR_SZ];
  4825. /* optional user keying material */
  4826. int ukmOctetSz = 0;
  4827. byte ukmOctetStr[MAX_OCTET_STR_SZ];
  4828. int ukmExplicitSz = 0;
  4829. byte ukmExplicitSeq[MAX_SEQ_SZ];
  4830. int keyEncryptAlgoIdSz = 0;
  4831. byte keyEncryptAlgoId[MAX_ALGO_SZ];
  4832. int keyWrapAlgSz = 0;
  4833. byte keyWrapAlg[MAX_ALGO_SZ];
  4834. int recipEncKeysSeqSz = 0;
  4835. byte recipEncKeysSeq[MAX_SEQ_SZ];
  4836. int recipEncKeySeqSz = 0;
  4837. byte recipEncKeySeq[MAX_SEQ_SZ];
  4838. int recipKeyIdSeqSz = 0;
  4839. byte recipKeyIdSeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  4840. int subjKeyIdOctetSz = 0;
  4841. byte subjKeyIdOctet[MAX_OCTET_STR_SZ];
  4842. int encryptedKeyOctetSz = 0;
  4843. byte encryptedKeyOctet[MAX_OCTET_STR_SZ];
  4844. #ifdef WOLFSSL_SMALL_STACK
  4845. byte* encryptedKey;
  4846. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  4847. DYNAMIC_TYPE_TMP_BUFFER);
  4848. if (encryptedKey == NULL) {
  4849. return MEMORY_E;
  4850. }
  4851. #else
  4852. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  4853. #endif
  4854. /* allocate and init memory for recipient */
  4855. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  4856. DYNAMIC_TYPE_PKCS7);
  4857. if (recip == NULL) {
  4858. #ifdef WOLFSSL_SMALL_STACK
  4859. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4860. #endif
  4861. return MEMORY_E;
  4862. }
  4863. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  4864. /* get key size for content-encryption key based on algorithm */
  4865. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  4866. if (blockKeySz < 0) {
  4867. #ifdef WOLFSSL_SMALL_STACK
  4868. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4869. #endif
  4870. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4871. return blockKeySz;
  4872. }
  4873. /* generate random content encryption key, if needed */
  4874. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  4875. if (ret < 0) {
  4876. #ifdef WOLFSSL_SMALL_STACK
  4877. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4878. #endif
  4879. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4880. return ret;
  4881. }
  4882. /* set direction based on keyWrapAlgo */
  4883. switch (keyWrapOID) {
  4884. #ifndef NO_AES
  4885. #ifdef WOLFSSL_AES_128
  4886. case AES128_WRAP:
  4887. #endif
  4888. #ifdef WOLFSSL_AES_192
  4889. case AES192_WRAP:
  4890. #endif
  4891. #ifdef WOLFSSL_AES_256
  4892. case AES256_WRAP:
  4893. #endif
  4894. direction = AES_ENCRYPTION;
  4895. break;
  4896. #endif
  4897. default:
  4898. WOLFSSL_MSG("Unsupported key wrap algorithm");
  4899. #ifdef WOLFSSL_SMALL_STACK
  4900. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4901. #endif
  4902. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4903. return BAD_KEYWRAP_ALG_E;
  4904. }
  4905. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);
  4906. if (kari == NULL) {
  4907. #ifdef WOLFSSL_SMALL_STACK
  4908. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4909. #endif
  4910. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4911. return MEMORY_E;
  4912. }
  4913. /* set user keying material if available */
  4914. if (ukmSz > 0 && ukm != NULL) {
  4915. kari->ukm = ukm;
  4916. kari->ukmSz = ukmSz;
  4917. kari->ukmOwner = 0;
  4918. }
  4919. /* parse recipient cert, get public key */
  4920. ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);
  4921. if (ret != 0) {
  4922. wc_PKCS7_KariFree(kari);
  4923. #ifdef WOLFSSL_SMALL_STACK
  4924. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4925. #endif
  4926. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4927. return ret;
  4928. }
  4929. /* generate sender ephemeral ECC key */
  4930. ret = wc_PKCS7_KariGenerateEphemeralKey(kari);
  4931. if (ret != 0) {
  4932. wc_PKCS7_KariFree(kari);
  4933. #ifdef WOLFSSL_SMALL_STACK
  4934. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4935. #endif
  4936. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4937. return ret;
  4938. }
  4939. /* generate KEK (key encryption key) */
  4940. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID, keyAgreeOID);
  4941. if (ret != 0) {
  4942. wc_PKCS7_KariFree(kari);
  4943. #ifdef WOLFSSL_SMALL_STACK
  4944. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4945. #endif
  4946. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4947. return ret;
  4948. }
  4949. /* encrypt CEK with KEK */
  4950. keySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kari->kek,
  4951. kari->kekSz, encryptedKey, encryptedKeySz,
  4952. keyWrapOID, direction);
  4953. if (keySz <= 0) {
  4954. wc_PKCS7_KariFree(kari);
  4955. #ifdef WOLFSSL_SMALL_STACK
  4956. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  4957. #endif
  4958. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4959. return keySz;
  4960. }
  4961. encryptedKeySz = (word32)keySz;
  4962. /* Start of RecipientEncryptedKeys */
  4963. /* EncryptedKey */
  4964. encryptedKeyOctetSz = SetOctetString(encryptedKeySz, encryptedKeyOctet);
  4965. totalSz += (encryptedKeyOctetSz + encryptedKeySz);
  4966. /* SubjectKeyIdentifier */
  4967. subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet);
  4968. totalSz += (subjKeyIdOctetSz + KEYID_SIZE);
  4969. /* RecipientKeyIdentifier IMPLICIT [0] */
  4970. recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +
  4971. KEYID_SIZE, recipKeyIdSeq);
  4972. totalSz += recipKeyIdSeqSz;
  4973. /* RecipientEncryptedKey */
  4974. recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);
  4975. totalSz += recipEncKeySeqSz;
  4976. /* RecipientEncryptedKeys */
  4977. recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);
  4978. totalSz += recipEncKeysSeqSz;
  4979. /* Start of optional UserKeyingMaterial */
  4980. if (kari->ukmSz > 0) {
  4981. ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);
  4982. totalSz += (ukmOctetSz + kari->ukmSz);
  4983. ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,
  4984. ukmExplicitSeq);
  4985. totalSz += ukmExplicitSz;
  4986. }
  4987. /* Start of KeyEncryptionAlgorithmIdentifier */
  4988. /* KeyWrapAlgorithm */
  4989. keyWrapAlgSz = SetAlgoID(keyWrapOID, keyWrapAlg, oidKeyWrapType, 0);
  4990. totalSz += keyWrapAlgSz;
  4991. /* KeyEncryptionAlgorithmIdentifier */
  4992. keyEncryptAlgoIdSz = SetAlgoID(keyAgreeOID, keyEncryptAlgoId,
  4993. oidCmsKeyAgreeType, keyWrapAlgSz);
  4994. totalSz += keyEncryptAlgoIdSz;
  4995. /* Start of OriginatorIdentifierOrKey */
  4996. /* recipient ECPoint, public key */
  4997. XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */
  4998. origPubKeyStr[0] = ASN_BIT_STRING;
  4999. origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,
  5000. origPubKeyStr + 1) + 2;
  5001. totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);
  5002. /* Originator AlgorithmIdentifier, params set to NULL for interop
  5003. compatibility */
  5004. origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 2);
  5005. origAlgId[origAlgIdSz++] = ASN_TAG_NULL;
  5006. origAlgId[origAlgIdSz++] = 0;
  5007. totalSz += origAlgIdSz;
  5008. /* outer OriginatorPublicKey IMPLICIT [1] */
  5009. origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,
  5010. origAlgIdSz + origPubKeyStrSz +
  5011. kari->senderKeyExportSz, origPubKeySeq);
  5012. totalSz += origPubKeySeqSz;
  5013. /* outer OriginatorIdentiferOrKey IMPLICIT [0] */
  5014. origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,
  5015. origPubKeySeqSz + origAlgIdSz +
  5016. origPubKeyStrSz + kari->senderKeyExportSz,
  5017. origIdOrKeySeq);
  5018. totalSz += origIdOrKeySeqSz;
  5019. /* version, always 3 */
  5020. verSz = SetMyVersion(3, ver, 0);
  5021. totalSz += verSz;
  5022. recip->recipVersion = 3;
  5023. /* outer IMPLICIT [1] kari */
  5024. kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);
  5025. totalSz += kariSeqSz;
  5026. if (totalSz > MAX_RECIP_SZ) {
  5027. WOLFSSL_MSG("KeyAgreeRecipientInfo output buffer too small");
  5028. wc_PKCS7_KariFree(kari);
  5029. #ifdef WOLFSSL_SMALL_STACK
  5030. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5031. #endif
  5032. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5033. return BUFFER_E;
  5034. }
  5035. XMEMCPY(recip->recip + idx, kariSeq, kariSeqSz);
  5036. idx += kariSeqSz;
  5037. XMEMCPY(recip->recip + idx, ver, verSz);
  5038. idx += verSz;
  5039. XMEMCPY(recip->recip + idx, origIdOrKeySeq, origIdOrKeySeqSz);
  5040. idx += origIdOrKeySeqSz;
  5041. XMEMCPY(recip->recip + idx, origPubKeySeq, origPubKeySeqSz);
  5042. idx += origPubKeySeqSz;
  5043. /* AlgorithmIdentifier with NULL parameter */
  5044. XMEMCPY(recip->recip + idx, origAlgId, origAlgIdSz);
  5045. idx += origAlgIdSz;
  5046. XMEMCPY(recip->recip + idx, origPubKeyStr, origPubKeyStrSz);
  5047. idx += origPubKeyStrSz;
  5048. /* ephemeral public key */
  5049. XMEMCPY(recip->recip + idx, kari->senderKeyExport, kari->senderKeyExportSz);
  5050. idx += kari->senderKeyExportSz;
  5051. if (kari->ukmSz > 0) {
  5052. XMEMCPY(recip->recip + idx, ukmExplicitSeq, ukmExplicitSz);
  5053. idx += ukmExplicitSz;
  5054. XMEMCPY(recip->recip + idx, ukmOctetStr, ukmOctetSz);
  5055. idx += ukmOctetSz;
  5056. XMEMCPY(recip->recip + idx, kari->ukm, kari->ukmSz);
  5057. idx += kari->ukmSz;
  5058. }
  5059. XMEMCPY(recip->recip + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);
  5060. idx += keyEncryptAlgoIdSz;
  5061. XMEMCPY(recip->recip + idx, keyWrapAlg, keyWrapAlgSz);
  5062. idx += keyWrapAlgSz;
  5063. XMEMCPY(recip->recip + idx, recipEncKeysSeq, recipEncKeysSeqSz);
  5064. idx += recipEncKeysSeqSz;
  5065. XMEMCPY(recip->recip + idx, recipEncKeySeq, recipEncKeySeqSz);
  5066. idx += recipEncKeySeqSz;
  5067. XMEMCPY(recip->recip + idx, recipKeyIdSeq, recipKeyIdSeqSz);
  5068. idx += recipKeyIdSeqSz;
  5069. XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz);
  5070. idx += subjKeyIdOctetSz;
  5071. /* subject key id */
  5072. XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, KEYID_SIZE);
  5073. idx += KEYID_SIZE;
  5074. XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz);
  5075. idx += encryptedKeyOctetSz;
  5076. /* encrypted CEK */
  5077. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5078. idx += encryptedKeySz;
  5079. wc_PKCS7_KariFree(kari);
  5080. #ifdef WOLFSSL_SMALL_STACK
  5081. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5082. #endif
  5083. /* store recipient size */
  5084. recip->recipSz = idx;
  5085. recip->recipType = PKCS7_KARI;
  5086. /* add recipient to recip list */
  5087. if (pkcs7->recipList == NULL) {
  5088. pkcs7->recipList = recip;
  5089. } else {
  5090. lastRecip = pkcs7->recipList;
  5091. while (lastRecip->next != NULL) {
  5092. lastRecip = lastRecip->next;
  5093. }
  5094. lastRecip->next = recip;
  5095. }
  5096. (void)options;
  5097. return idx;
  5098. }
  5099. #endif /* HAVE_ECC */
  5100. #ifndef NO_RSA
  5101. /* Encode and add CMS EnvelopedData KTRI (KeyTransRecipientInfo) RecipientInfo
  5102. * to CMS/PKCS#7 EnvelopedData structure.
  5103. *
  5104. * Returns 0 on success, negative upon error */
  5105. int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  5106. int options)
  5107. {
  5108. Pkcs7EncodedRecip* recip = NULL;
  5109. Pkcs7EncodedRecip* lastRecip = NULL;
  5110. WC_RNG rng;
  5111. word32 idx = 0;
  5112. word32 encryptedKeySz = 0;
  5113. int ret = 0, blockKeySz;
  5114. int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0;
  5115. int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0;
  5116. int encKeyOctetStrSz;
  5117. int sidType;
  5118. byte ver[MAX_VERSION_SZ];
  5119. byte issuerSerialSeq[MAX_SEQ_SZ];
  5120. byte recipSeq[MAX_SEQ_SZ];
  5121. byte issuerSeq[MAX_SEQ_SZ];
  5122. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  5123. byte issuerSKIDSeq[MAX_SEQ_SZ];
  5124. byte issuerSKID[MAX_OCTET_STR_SZ];
  5125. word32 issuerSKIDSeqSz = 0, issuerSKIDSz = 0;
  5126. #ifdef WOLFSSL_SMALL_STACK
  5127. byte* serial;
  5128. byte* keyAlgArray;
  5129. byte* encryptedKey;
  5130. RsaKey* pubKey;
  5131. DecodedCert* decoded;
  5132. serial = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5133. keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap,
  5134. DYNAMIC_TYPE_TMP_BUFFER);
  5135. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  5136. DYNAMIC_TYPE_TMP_BUFFER);
  5137. decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  5138. DYNAMIC_TYPE_TMP_BUFFER);
  5139. if (decoded == NULL || serial == NULL ||
  5140. encryptedKey == NULL || keyAlgArray == NULL) {
  5141. if (serial)
  5142. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5143. if (keyAlgArray)
  5144. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5145. if (encryptedKey)
  5146. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5147. if (decoded)
  5148. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5149. return MEMORY_E;
  5150. }
  5151. #else
  5152. byte serial[MAX_SN_SZ];
  5153. byte keyAlgArray[MAX_ALGO_SZ];
  5154. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  5155. RsaKey pubKey[1];
  5156. DecodedCert decoded[1];
  5157. #endif
  5158. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  5159. XMEMSET(encryptedKey, 0, encryptedKeySz);
  5160. /* default to IssuerAndSerialNumber if not set */
  5161. if (pkcs7->sidType != 0) {
  5162. sidType = pkcs7->sidType;
  5163. } else {
  5164. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5165. }
  5166. /* allow options to override SubjectIdentifier type if set */
  5167. if (options & CMS_SKID) {
  5168. sidType = CMS_SKID;
  5169. } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) {
  5170. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5171. }
  5172. /* allocate recipient struct */
  5173. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  5174. DYNAMIC_TYPE_PKCS7);
  5175. if (recip == NULL) {
  5176. #ifdef WOLFSSL_SMALL_STACK
  5177. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5178. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5179. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5180. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5181. #endif
  5182. return MEMORY_E;
  5183. }
  5184. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5185. /* get key size for content-encryption key based on algorithm */
  5186. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5187. if (blockKeySz < 0) {
  5188. #ifdef WOLFSSL_SMALL_STACK
  5189. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5190. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5191. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5192. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5193. #endif
  5194. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5195. return blockKeySz;
  5196. }
  5197. /* generate random content encryption key, if needed */
  5198. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5199. if (ret < 0) {
  5200. #ifdef WOLFSSL_SMALL_STACK
  5201. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5202. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5203. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5204. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5205. #endif
  5206. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5207. return ret;
  5208. }
  5209. InitDecodedCert(decoded, (byte*)cert, certSz, pkcs7->heap);
  5210. ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
  5211. if (ret < 0) {
  5212. FreeDecodedCert(decoded);
  5213. #ifdef WOLFSSL_SMALL_STACK
  5214. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5215. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5216. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5217. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5218. #endif
  5219. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5220. return ret;
  5221. }
  5222. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5223. /* version, must be 0 for IssuerAndSerialNumber */
  5224. verSz = SetMyVersion(0, ver, 0);
  5225. recip->recipVersion = 0;
  5226. /* IssuerAndSerialNumber */
  5227. if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
  5228. WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
  5229. FreeDecodedCert(decoded);
  5230. #ifdef WOLFSSL_SMALL_STACK
  5231. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5232. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5233. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5234. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5235. #endif
  5236. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5237. return -1;
  5238. }
  5239. issuerSz = decoded->issuerRawLen;
  5240. issuerSeqSz = SetSequence(issuerSz, issuerSeq);
  5241. if (decoded->serialSz == 0) {
  5242. WOLFSSL_MSG("DecodedCert missing serial number");
  5243. FreeDecodedCert(decoded);
  5244. #ifdef WOLFSSL_SMALL_STACK
  5245. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5246. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5247. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5248. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5249. #endif
  5250. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5251. return -1;
  5252. }
  5253. snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial,
  5254. MAX_SN_SZ, MAX_SN_SZ);
  5255. issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
  5256. issuerSerialSeq);
  5257. } else if (sidType == CMS_SKID) {
  5258. /* version, must be 2 for SubjectKeyIdentifier */
  5259. verSz = SetMyVersion(2, ver, 0);
  5260. recip->recipVersion = 2;
  5261. issuerSKIDSz = SetOctetString(KEYID_SIZE, issuerSKID);
  5262. issuerSKIDSeqSz = SetExplicit(0, issuerSKIDSz + KEYID_SIZE,
  5263. issuerSKIDSeq);
  5264. } else {
  5265. FreeDecodedCert(decoded);
  5266. #ifdef WOLFSSL_SMALL_STACK
  5267. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5268. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5269. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5270. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5271. #endif
  5272. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5273. return PKCS7_RECIP_E;
  5274. }
  5275. pkcs7->publicKeyOID = decoded->keyOID;
  5276. /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
  5277. if (pkcs7->publicKeyOID != RSAk) {
  5278. FreeDecodedCert(decoded);
  5279. #ifdef WOLFSSL_SMALL_STACK
  5280. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5281. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5282. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5283. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5284. #endif
  5285. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5286. return ALGO_ID_E;
  5287. }
  5288. keyEncAlgSz = SetAlgoID(pkcs7->publicKeyOID, keyAlgArray, oidKeyType, 0);
  5289. if (keyEncAlgSz == 0) {
  5290. FreeDecodedCert(decoded);
  5291. #ifdef WOLFSSL_SMALL_STACK
  5292. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5293. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5294. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5295. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5296. #endif
  5297. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5298. return BAD_FUNC_ARG;
  5299. }
  5300. #ifdef WOLFSSL_SMALL_STACK
  5301. pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  5302. DYNAMIC_TYPE_TMP_BUFFER);
  5303. if (pubKey == NULL) {
  5304. FreeDecodedCert(decoded);
  5305. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5306. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5307. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5308. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5309. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5310. return MEMORY_E;
  5311. }
  5312. #endif
  5313. /* EncryptedKey */
  5314. ret = wc_InitRsaKey_ex(pubKey, pkcs7->heap, INVALID_DEVID);
  5315. if (ret != 0) {
  5316. FreeDecodedCert(decoded);
  5317. #ifdef WOLFSSL_SMALL_STACK
  5318. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5319. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5320. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5321. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5322. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5323. #endif
  5324. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5325. return ret;
  5326. }
  5327. if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
  5328. decoded->pubKeySize) < 0) {
  5329. WOLFSSL_MSG("ASN RSA key decode error");
  5330. wc_FreeRsaKey(pubKey);
  5331. FreeDecodedCert(decoded);
  5332. #ifdef WOLFSSL_SMALL_STACK
  5333. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5334. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5335. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5336. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5337. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5338. #endif
  5339. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5340. return PUBLIC_KEY_E;
  5341. }
  5342. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  5343. if (ret != 0) {
  5344. wc_FreeRsaKey(pubKey);
  5345. FreeDecodedCert(decoded);
  5346. #ifdef WOLFSSL_SMALL_STACK
  5347. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5348. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5349. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5350. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5351. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5352. #endif
  5353. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5354. return MEMORY_E;
  5355. }
  5356. ret = wc_RsaPublicEncrypt(pkcs7->cek, pkcs7->cekSz, encryptedKey,
  5357. encryptedKeySz, pubKey, &rng);
  5358. wc_FreeRsaKey(pubKey);
  5359. wc_FreeRng(&rng);
  5360. #ifdef WOLFSSL_SMALL_STACK
  5361. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5362. #endif
  5363. if (ret < 0) {
  5364. WOLFSSL_MSG("RSA Public Encrypt failed");
  5365. FreeDecodedCert(decoded);
  5366. #ifdef WOLFSSL_SMALL_STACK
  5367. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5368. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5369. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5370. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5371. #endif
  5372. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5373. return ret;
  5374. }
  5375. encryptedKeySz = ret;
  5376. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  5377. /* RecipientInfo */
  5378. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5379. recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
  5380. issuerSz + snSz + keyEncAlgSz +
  5381. encKeyOctetStrSz + encryptedKeySz, recipSeq);
  5382. if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
  5383. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5384. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5385. FreeDecodedCert(decoded);
  5386. #ifdef WOLFSSL_SMALL_STACK
  5387. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5388. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5389. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5390. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5391. #endif
  5392. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5393. return BUFFER_E;
  5394. }
  5395. } else {
  5396. recipSeqSz = SetSequence(verSz + issuerSKIDSeqSz + issuerSKIDSz +
  5397. KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz +
  5398. encryptedKeySz, recipSeq);
  5399. if (recipSeqSz + verSz + issuerSKIDSeqSz + issuerSKIDSz + KEYID_SIZE +
  5400. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5401. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5402. FreeDecodedCert(decoded);
  5403. #ifdef WOLFSSL_SMALL_STACK
  5404. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5405. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5406. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5407. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5408. #endif
  5409. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5410. return BUFFER_E;
  5411. }
  5412. }
  5413. idx = 0;
  5414. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  5415. idx += recipSeqSz;
  5416. XMEMCPY(recip->recip + idx, ver, verSz);
  5417. idx += verSz;
  5418. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5419. XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz);
  5420. idx += issuerSerialSeqSz;
  5421. XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz);
  5422. idx += issuerSeqSz;
  5423. XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz);
  5424. idx += issuerSz;
  5425. XMEMCPY(recip->recip + idx, serial, snSz);
  5426. idx += snSz;
  5427. } else {
  5428. XMEMCPY(recip->recip + idx, issuerSKIDSeq, issuerSKIDSeqSz);
  5429. idx += issuerSKIDSeqSz;
  5430. XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz);
  5431. idx += issuerSKIDSz;
  5432. XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
  5433. idx += KEYID_SIZE;
  5434. }
  5435. XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz);
  5436. idx += keyEncAlgSz;
  5437. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  5438. idx += encKeyOctetStrSz;
  5439. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5440. idx += encryptedKeySz;
  5441. FreeDecodedCert(decoded);
  5442. #ifdef WOLFSSL_SMALL_STACK
  5443. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5444. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5445. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5446. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5447. #endif
  5448. /* store recipient size */
  5449. recip->recipSz = idx;
  5450. recip->recipType = PKCS7_KTRI;
  5451. /* add recipient to recip list */
  5452. if (pkcs7->recipList == NULL) {
  5453. pkcs7->recipList = recip;
  5454. } else {
  5455. lastRecip = pkcs7->recipList;
  5456. while (lastRecip->next != NULL) {
  5457. lastRecip = lastRecip->next;
  5458. }
  5459. lastRecip->next = recip;
  5460. }
  5461. return idx;
  5462. }
  5463. #endif /* !NO_RSA */
  5464. /* encrypt content using encryptOID algo */
  5465. static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
  5466. byte* iv, int ivSz, byte* aad, word32 aadSz,
  5467. byte* authTag, word32 authTagSz, byte* in,
  5468. int inSz, byte* out)
  5469. {
  5470. int ret;
  5471. #ifndef NO_AES
  5472. Aes aes;
  5473. #endif
  5474. #ifndef NO_DES3
  5475. Des des;
  5476. Des3 des3;
  5477. #endif
  5478. if (key == NULL || iv == NULL || in == NULL || out == NULL)
  5479. return BAD_FUNC_ARG;
  5480. switch (encryptOID) {
  5481. #ifndef NO_AES
  5482. #ifdef WOLFSSL_AES_128
  5483. case AES128CBCb:
  5484. #endif
  5485. #ifdef WOLFSSL_AES_192
  5486. case AES192CBCb:
  5487. #endif
  5488. #ifdef WOLFSSL_AES_256
  5489. case AES256CBCb:
  5490. #endif
  5491. if (
  5492. #ifdef WOLFSSL_AES_128
  5493. (encryptOID == AES128CBCb && keySz != 16 ) ||
  5494. #endif
  5495. #ifdef WOLFSSL_AES_192
  5496. (encryptOID == AES192CBCb && keySz != 24 ) ||
  5497. #endif
  5498. #ifdef WOLFSSL_AES_256
  5499. (encryptOID == AES256CBCb && keySz != 32 ) ||
  5500. #endif
  5501. (ivSz != AES_BLOCK_SIZE) )
  5502. return BAD_FUNC_ARG;
  5503. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5504. if (ret == 0) {
  5505. ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION);
  5506. if (ret == 0)
  5507. ret = wc_AesCbcEncrypt(&aes, out, in, inSz);
  5508. wc_AesFree(&aes);
  5509. }
  5510. break;
  5511. #ifdef HAVE_AESGCM
  5512. #ifdef WOLFSSL_AES_128
  5513. case AES128GCMb:
  5514. #endif
  5515. #ifdef WOLFSSL_AES_192
  5516. case AES192GCMb:
  5517. #endif
  5518. #ifdef WOLFSSL_AES_256
  5519. case AES256GCMb:
  5520. #endif
  5521. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5522. defined(WOLFSSL_AES_256)
  5523. if (authTag == NULL)
  5524. return BAD_FUNC_ARG;
  5525. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5526. if (ret == 0) {
  5527. ret = wc_AesGcmSetKey(&aes, key, keySz);
  5528. if (ret == 0)
  5529. ret = wc_AesGcmEncrypt(&aes, out, in, inSz, iv, ivSz,
  5530. authTag, authTagSz, aad, aadSz);
  5531. wc_AesFree(&aes);
  5532. }
  5533. break;
  5534. #endif
  5535. #endif /* HAVE_AESGCM */
  5536. #ifdef HAVE_AESCCM
  5537. #ifdef WOLFSSL_AES_128
  5538. case AES128CCMb:
  5539. #endif
  5540. #ifdef WOLFSSL_AES_192
  5541. case AES192CCMb:
  5542. #endif
  5543. #ifdef WOLFSSL_AES_256
  5544. case AES256CCMb:
  5545. #endif
  5546. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5547. defined(WOLFSSL_AES_256)
  5548. if (authTag == NULL)
  5549. return BAD_FUNC_ARG;
  5550. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5551. if (ret == 0) {
  5552. ret = wc_AesCcmSetKey(&aes, key, keySz);
  5553. if (ret == 0)
  5554. ret = wc_AesCcmEncrypt(&aes, out, in, inSz, iv, ivSz,
  5555. authTag, authTagSz, aad, aadSz);
  5556. wc_AesFree(&aes);
  5557. }
  5558. break;
  5559. #endif
  5560. #endif /* HAVE_AESCCM */
  5561. #endif /* NO_AES */
  5562. #ifndef NO_DES3
  5563. case DESb:
  5564. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5565. return BAD_FUNC_ARG;
  5566. ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
  5567. if (ret == 0)
  5568. ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
  5569. break;
  5570. case DES3b:
  5571. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5572. return BAD_FUNC_ARG;
  5573. ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
  5574. if (ret == 0) {
  5575. ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
  5576. if (ret == 0)
  5577. ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
  5578. wc_Des3Free(&des3);
  5579. }
  5580. break;
  5581. #endif
  5582. default:
  5583. WOLFSSL_MSG("Unsupported content cipher type");
  5584. return ALGO_ID_E;
  5585. };
  5586. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  5587. (void)authTag;
  5588. (void)authTagSz;
  5589. (void)aad;
  5590. (void)aadSz;
  5591. #endif
  5592. return ret;
  5593. }
  5594. /* decrypt content using encryptOID algo
  5595. * returns 0 on success */
  5596. static int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,
  5597. int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,
  5598. word32 authTagSz, byte* in, int inSz, byte* out)
  5599. {
  5600. int ret;
  5601. #ifndef NO_AES
  5602. Aes aes;
  5603. #endif
  5604. #ifndef NO_DES3
  5605. Des des;
  5606. Des3 des3;
  5607. #endif
  5608. if (iv == NULL || in == NULL || out == NULL)
  5609. return BAD_FUNC_ARG;
  5610. if (pkcs7->decryptionCb != NULL) {
  5611. return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,
  5612. aad, aadSz, authTag, authTagSz, in,
  5613. inSz, out, pkcs7->decryptionCtx);
  5614. }
  5615. if (key == NULL)
  5616. return BAD_FUNC_ARG;
  5617. switch (encryptOID) {
  5618. #ifndef NO_AES
  5619. #ifdef WOLFSSL_AES_128
  5620. case AES128CBCb:
  5621. #endif
  5622. #ifdef WOLFSSL_AES_192
  5623. case AES192CBCb:
  5624. #endif
  5625. #ifdef WOLFSSL_AES_256
  5626. case AES256CBCb:
  5627. #endif
  5628. if (
  5629. #ifdef WOLFSSL_AES_128
  5630. (encryptOID == AES128CBCb && keySz != 16 ) ||
  5631. #endif
  5632. #ifdef WOLFSSL_AES_192
  5633. (encryptOID == AES192CBCb && keySz != 24 ) ||
  5634. #endif
  5635. #ifdef WOLFSSL_AES_256
  5636. (encryptOID == AES256CBCb && keySz != 32 ) ||
  5637. #endif
  5638. (ivSz != AES_BLOCK_SIZE) )
  5639. return BAD_FUNC_ARG;
  5640. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5641. if (ret == 0) {
  5642. ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION);
  5643. if (ret == 0)
  5644. ret = wc_AesCbcDecrypt(&aes, out, in, inSz);
  5645. wc_AesFree(&aes);
  5646. }
  5647. break;
  5648. #ifdef HAVE_AESGCM
  5649. #ifdef WOLFSSL_AES_128
  5650. case AES128GCMb:
  5651. #endif
  5652. #ifdef WOLFSSL_AES_192
  5653. case AES192GCMb:
  5654. #endif
  5655. #ifdef WOLFSSL_AES_256
  5656. case AES256GCMb:
  5657. #endif
  5658. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5659. defined(WOLFSSL_AES_256)
  5660. if (authTag == NULL)
  5661. return BAD_FUNC_ARG;
  5662. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5663. if (ret == 0) {
  5664. ret = wc_AesGcmSetKey(&aes, key, keySz);
  5665. if (ret == 0)
  5666. ret = wc_AesGcmDecrypt(&aes, out, in, inSz, iv, ivSz,
  5667. authTag, authTagSz, aad, aadSz);
  5668. wc_AesFree(&aes);
  5669. }
  5670. break;
  5671. #endif
  5672. #endif /* HAVE_AESGCM */
  5673. #ifdef HAVE_AESCCM
  5674. #ifdef WOLFSSL_AES_128
  5675. case AES128CCMb:
  5676. #endif
  5677. #ifdef WOLFSSL_AES_192
  5678. case AES192CCMb:
  5679. #endif
  5680. #ifdef WOLFSSL_AES_256
  5681. case AES256CCMb:
  5682. #endif
  5683. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5684. defined(WOLFSSL_AES_256)
  5685. if (authTag == NULL)
  5686. return BAD_FUNC_ARG;
  5687. ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
  5688. if (ret == 0) {
  5689. ret = wc_AesCcmSetKey(&aes, key, keySz);
  5690. if (ret == 0)
  5691. ret = wc_AesCcmDecrypt(&aes, out, in, inSz, iv, ivSz,
  5692. authTag, authTagSz, aad, aadSz);
  5693. wc_AesFree(&aes);
  5694. }
  5695. break;
  5696. #endif
  5697. #endif /* HAVE_AESCCM */
  5698. #endif /* NO_AES */
  5699. #ifndef NO_DES3
  5700. case DESb:
  5701. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5702. return BAD_FUNC_ARG;
  5703. ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
  5704. if (ret == 0)
  5705. ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
  5706. break;
  5707. case DES3b:
  5708. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5709. return BAD_FUNC_ARG;
  5710. ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
  5711. if (ret == 0) {
  5712. ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
  5713. if (ret == 0)
  5714. ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
  5715. wc_Des3Free(&des3);
  5716. }
  5717. break;
  5718. #endif
  5719. default:
  5720. WOLFSSL_MSG("Unsupported content cipher type");
  5721. return ALGO_ID_E;
  5722. };
  5723. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  5724. (void)authTag;
  5725. (void)authTagSz;
  5726. (void)aad;
  5727. (void)aadSz;
  5728. #endif
  5729. return ret;
  5730. }
  5731. /* Generate random block, place in out, return 0 on success negative on error.
  5732. * Used for generation of IV, nonce, etc */
  5733. static int wc_PKCS7_GenerateBlock(PKCS7* pkcs7, WC_RNG* rng, byte* out,
  5734. word32 outSz)
  5735. {
  5736. int ret;
  5737. WC_RNG* rnd = NULL;
  5738. if (out == NULL || outSz == 0)
  5739. return BAD_FUNC_ARG;
  5740. /* input RNG is optional, init local one if input rng is NULL */
  5741. if (rng == NULL) {
  5742. rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);
  5743. if (rnd == NULL)
  5744. return MEMORY_E;
  5745. ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);
  5746. if (ret != 0) {
  5747. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  5748. return ret;
  5749. }
  5750. } else {
  5751. rnd = rng;
  5752. }
  5753. ret = wc_RNG_GenerateBlock(rnd, out, outSz);
  5754. if (rng == NULL) {
  5755. wc_FreeRng(rnd);
  5756. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  5757. }
  5758. return ret;
  5759. }
  5760. /* Set default SignerIdentifier type to be used. Is either
  5761. * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using
  5762. * IssuerAndSerialNumber unless set with this function or explicitly
  5763. * overridden via options when adding RecipientInfo type.
  5764. *
  5765. * Using the type DEGENERATE_SID skips over signer information. In degenerate
  5766. * cases there are no signers.
  5767. *
  5768. * pkcs7 - pointer to initialized PKCS7 structure
  5769. * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID
  5770. *
  5771. * return 0 on success, negative upon error */
  5772. int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type)
  5773. {
  5774. if (pkcs7 == NULL)
  5775. return BAD_FUNC_ARG;
  5776. if (type != CMS_ISSUER_AND_SERIAL_NUMBER &&
  5777. type != CMS_SKID &&
  5778. type != DEGENERATE_SID) {
  5779. return BAD_FUNC_ARG;
  5780. }
  5781. pkcs7->sidType = type;
  5782. return 0;
  5783. }
  5784. /* Set custom contentType, currently supported with SignedData type
  5785. *
  5786. * pkcs7 - pointer to initialized PKCS7 structure
  5787. * contentType - pointer to array with ASN.1 encoded OID value
  5788. * sz - length of contentType array, octets
  5789. *
  5790. * return 0 on success, negative upon error */
  5791. int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, word32 sz)
  5792. {
  5793. if (pkcs7 == NULL || contentType == NULL || sz == 0)
  5794. return BAD_FUNC_ARG;
  5795. if (sz > MAX_OID_SZ) {
  5796. WOLFSSL_MSG("input array too large, bounded by MAX_OID_SZ");
  5797. return BAD_FUNC_ARG;
  5798. }
  5799. XMEMCPY(pkcs7->contentType, contentType, sz);
  5800. pkcs7->contentTypeSz = sz;
  5801. return 0;
  5802. }
  5803. /* return size of padded data, padded to blockSz chunks, or negative on error */
  5804. int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
  5805. {
  5806. int padSz;
  5807. if (blockSz == 0)
  5808. return BAD_FUNC_ARG;
  5809. padSz = blockSz - (inputSz % blockSz);
  5810. return padSz;
  5811. }
  5812. /* pad input data to blockSz chunk, place in outSz. out must be big enough
  5813. * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */
  5814. int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
  5815. word32 blockSz)
  5816. {
  5817. int i, padSz;
  5818. if (in == NULL || inSz == 0 ||
  5819. out == NULL || outSz == 0)
  5820. return BAD_FUNC_ARG;
  5821. padSz = wc_PKCS7_GetPadSize(inSz, blockSz);
  5822. if (outSz < (inSz + padSz))
  5823. return BAD_FUNC_ARG;
  5824. XMEMCPY(out, in, inSz);
  5825. for (i = 0; i < padSz; i++) {
  5826. out[inSz + i] = (byte)padSz;
  5827. }
  5828. return inSz + padSz;
  5829. }
  5830. /* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo
  5831. * to CMS/PKCS#7 EnvelopedData structure.
  5832. *
  5833. * Return 0 on success, negative upon error */
  5834. int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb,
  5835. int options)
  5836. {
  5837. int oriTypeLenSz, blockKeySz, ret;
  5838. word32 idx, recipSeqSz;
  5839. Pkcs7EncodedRecip* recip = NULL;
  5840. Pkcs7EncodedRecip* lastRecip = NULL;
  5841. byte recipSeq[MAX_SEQ_SZ];
  5842. byte oriTypeLen[MAX_LENGTH_SZ];
  5843. byte oriType[MAX_ORI_TYPE_SZ];
  5844. byte oriValue[MAX_ORI_VALUE_SZ];
  5845. word32 oriTypeSz = MAX_ORI_TYPE_SZ;
  5846. word32 oriValueSz = MAX_ORI_VALUE_SZ;
  5847. if (pkcs7 == NULL || oriEncryptCb == NULL) {
  5848. return BAD_FUNC_ARG;
  5849. }
  5850. /* allocate memory for RecipientInfo, KEK, encrypted key */
  5851. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  5852. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5853. if (recip == NULL)
  5854. return MEMORY_E;
  5855. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5856. /* get key size for content-encryption key based on algorithm */
  5857. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5858. if (blockKeySz < 0) {
  5859. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5860. return blockKeySz;
  5861. }
  5862. /* generate random content encryption key, if needed */
  5863. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5864. if (ret < 0) {
  5865. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5866. return ret;
  5867. }
  5868. /* call user callback to encrypt CEK and get oriType and oriValue
  5869. values back */
  5870. ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz,
  5871. oriValue, &oriValueSz, pkcs7->oriEncryptCtx);
  5872. if (ret != 0) {
  5873. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5874. return ret;
  5875. }
  5876. oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen);
  5877. recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz +
  5878. oriValueSz, recipSeq);
  5879. idx = 0;
  5880. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  5881. idx += recipSeqSz;
  5882. /* oriType */
  5883. recip->recip[idx] = ASN_OBJECT_ID;
  5884. idx += 1;
  5885. XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz);
  5886. idx += oriTypeLenSz;
  5887. XMEMCPY(recip->recip + idx, oriType, oriTypeSz);
  5888. idx += oriTypeSz;
  5889. /* oriValue, input MUST already be ASN.1 encoded */
  5890. XMEMCPY(recip->recip + idx, oriValue, oriValueSz);
  5891. idx += oriValueSz;
  5892. /* store recipient size */
  5893. recip->recipSz = idx;
  5894. recip->recipType = PKCS7_ORI;
  5895. recip->recipVersion = 4;
  5896. /* add recipient to recip list */
  5897. if (pkcs7->recipList == NULL) {
  5898. pkcs7->recipList = recip;
  5899. } else {
  5900. lastRecip = pkcs7->recipList;
  5901. while (lastRecip->next != NULL) {
  5902. lastRecip = lastRecip->next;
  5903. }
  5904. lastRecip->next = recip;
  5905. }
  5906. (void)options;
  5907. return idx;
  5908. }
  5909. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  5910. static int wc_PKCS7_GenerateKEK_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  5911. byte* salt, word32 saltSz, int kdfOID,
  5912. int prfOID, int iterations, byte* out,
  5913. word32 outSz)
  5914. {
  5915. int ret;
  5916. if (pkcs7 == NULL || passwd == NULL || salt == NULL || out == NULL)
  5917. return BAD_FUNC_ARG;
  5918. switch (kdfOID) {
  5919. case PBKDF2_OID:
  5920. ret = wc_PBKDF2(out, passwd, pLen, salt, saltSz, iterations,
  5921. outSz, prfOID);
  5922. if (ret != 0) {
  5923. return ret;
  5924. }
  5925. break;
  5926. default:
  5927. WOLFSSL_MSG("Unsupported KDF OID");
  5928. return PKCS7_OID_E;
  5929. }
  5930. return 0;
  5931. }
  5932. /* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK).
  5933. *
  5934. * Returns output size on success, negative upon error */
  5935. static int wc_PKCS7_PwriKek_KeyWrap(PKCS7* pkcs7, const byte* kek, word32 kekSz,
  5936. const byte* cek, word32 cekSz,
  5937. byte* out, word32 *outSz,
  5938. const byte* iv, word32 ivSz, int algID)
  5939. {
  5940. WC_RNG rng;
  5941. int blockSz, outLen, ret;
  5942. word32 padSz;
  5943. byte* lastBlock;
  5944. if (kek == NULL || cek == NULL || iv == NULL || outSz == NULL)
  5945. return BAD_FUNC_ARG;
  5946. /* get encryption algorithm block size */
  5947. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  5948. if (blockSz < 0)
  5949. return blockSz;
  5950. /* get pad bytes needed to block boundary */
  5951. padSz = blockSz - ((4 + cekSz) % blockSz);
  5952. outLen = 4 + cekSz + padSz;
  5953. /* must be at least two blocks long */
  5954. if (outLen < 2 * blockSz)
  5955. padSz += blockSz;
  5956. /* if user set out to NULL, give back required length */
  5957. if (out == NULL) {
  5958. *outSz = outLen;
  5959. return LENGTH_ONLY_E;
  5960. }
  5961. /* verify output buffer is large enough */
  5962. if (*outSz < (word32)outLen)
  5963. return BUFFER_E;
  5964. out[0] = cekSz;
  5965. out[1] = ~cek[0];
  5966. out[2] = ~cek[1];
  5967. out[3] = ~cek[2];
  5968. XMEMCPY(out + 4, cek, cekSz);
  5969. /* random padding of size padSz */
  5970. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  5971. if (ret != 0)
  5972. return ret;
  5973. ret = wc_RNG_GenerateBlock(&rng, out + 4 + cekSz, padSz);
  5974. if (ret == 0) {
  5975. /* encrypt, normal */
  5976. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, (byte*)iv,
  5977. ivSz, NULL, 0, NULL, 0, out, outLen, out);
  5978. }
  5979. if (ret == 0) {
  5980. /* encrypt again, using last ciphertext block as IV */
  5981. lastBlock = out + (((outLen / blockSz) - 1) * blockSz);
  5982. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, lastBlock,
  5983. blockSz, NULL, 0, NULL, 0, out,
  5984. outLen, out);
  5985. }
  5986. if (ret == 0) {
  5987. *outSz = outLen;
  5988. } else {
  5989. outLen = ret;
  5990. }
  5991. wc_FreeRng(&rng);
  5992. return outLen;
  5993. }
  5994. /* RFC3211 (Section 2.3.2) key unwrap algorithm (id-alg-PWRI-KEK).
  5995. *
  5996. * Returns cek size on success, negative upon error */
  5997. static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,
  5998. word32 kekSz, const byte* in, word32 inSz,
  5999. byte* out, word32 outSz, const byte* iv,
  6000. word32 ivSz, int algID)
  6001. {
  6002. int blockSz, cekLen, ret;
  6003. byte* tmpIv = NULL;
  6004. byte* lastBlock = NULL;
  6005. byte* outTmp = NULL;
  6006. if (pkcs7 == NULL || kek == NULL || in == NULL ||
  6007. out == NULL || iv == NULL) {
  6008. return BAD_FUNC_ARG;
  6009. }
  6010. outTmp = (byte*)XMALLOC(inSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6011. if (outTmp == NULL)
  6012. return MEMORY_E;
  6013. /* get encryption algorithm block size */
  6014. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  6015. if (blockSz < 0) {
  6016. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6017. return blockSz;
  6018. }
  6019. /* input needs to be blockSz multiple and at least 2 * blockSz */
  6020. if (((inSz % blockSz) != 0) || (inSz < (2 * (word32)blockSz))) {
  6021. WOLFSSL_MSG("PWRI-KEK unwrap input must of block size and >= 2 "
  6022. "times block size");
  6023. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6024. return BAD_FUNC_ARG;
  6025. }
  6026. /* use block out[n-1] as IV to decrypt block out[n] */
  6027. lastBlock = (byte*)in + inSz - blockSz;
  6028. tmpIv = lastBlock - blockSz;
  6029. /* decrypt last block */
  6030. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,
  6031. blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,
  6032. outTmp + inSz - blockSz);
  6033. if (ret == 0) {
  6034. /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
  6035. lastBlock = outTmp + inSz - blockSz;
  6036. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6037. lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,
  6038. outTmp);
  6039. }
  6040. if (ret == 0) {
  6041. /* decrypt using original kek and iv */
  6042. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6043. (byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp);
  6044. }
  6045. if (ret != 0) {
  6046. ForceZero(outTmp, inSz);
  6047. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6048. return ret;
  6049. }
  6050. cekLen = outTmp[0];
  6051. /* verify length */
  6052. if ((word32)cekLen > inSz) {
  6053. ForceZero(outTmp, inSz);
  6054. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6055. return BAD_FUNC_ARG;
  6056. }
  6057. /* verify check bytes */
  6058. if ((outTmp[1] ^ outTmp[4]) != 0xFF ||
  6059. (outTmp[2] ^ outTmp[5]) != 0xFF ||
  6060. (outTmp[3] ^ outTmp[6]) != 0xFF) {
  6061. ForceZero(outTmp, inSz);
  6062. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6063. return BAD_FUNC_ARG;
  6064. }
  6065. if (outSz < (word32)cekLen) {
  6066. ForceZero(outTmp, inSz);
  6067. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6068. return BUFFER_E;
  6069. }
  6070. XMEMCPY(out, outTmp + 4, outTmp[0]);
  6071. ForceZero(outTmp, inSz);
  6072. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6073. return cekLen;
  6074. }
  6075. /* Encode and add CMS EnvelopedData PWRI (PasswordRecipientInfo) RecipientInfo
  6076. * to CMS/PKCS#7 EnvelopedData structure.
  6077. *
  6078. * Return 0 on success, negative upon error */
  6079. int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  6080. byte* salt, word32 saltSz, int kdfOID,
  6081. int hashOID, int iterations, int kekEncryptOID,
  6082. int options)
  6083. {
  6084. Pkcs7EncodedRecip* recip = NULL;
  6085. Pkcs7EncodedRecip* lastRecip = NULL;
  6086. /* PasswordRecipientInfo */
  6087. byte recipSeq[MAX_SEQ_SZ];
  6088. byte ver[MAX_VERSION_SZ];
  6089. word32 recipSeqSz, verSz;
  6090. /* KeyDerivationAlgorithmIdentifier */
  6091. byte kdfAlgoIdSeq[MAX_SEQ_SZ];
  6092. byte kdfAlgoId[MAX_OID_SZ];
  6093. byte kdfParamsSeq[MAX_SEQ_SZ]; /* PBKDF2-params */
  6094. byte kdfSaltOctetStr[MAX_OCTET_STR_SZ]; /* salt OCTET STRING */
  6095. byte kdfIterations[MAX_VERSION_SZ];
  6096. word32 kdfAlgoIdSeqSz, kdfAlgoIdSz;
  6097. word32 kdfParamsSeqSz, kdfSaltOctetStrSz, kdfIterationsSz;
  6098. /* OPTIONAL: keyLength, not supported yet */
  6099. /* OPTIONAL: prf AlgorithIdentifier, not supported yet */
  6100. /* KeyEncryptionAlgorithmIdentifier */
  6101. byte keyEncAlgoIdSeq[MAX_SEQ_SZ];
  6102. byte keyEncAlgoId[MAX_OID_SZ]; /* id-alg-PWRI-KEK */
  6103. byte pwriEncAlgoId[MAX_ALGO_SZ];
  6104. byte ivOctetString[MAX_OCTET_STR_SZ];
  6105. word32 keyEncAlgoIdSeqSz, keyEncAlgoIdSz;
  6106. word32 pwriEncAlgoIdSz, ivOctetStringSz;
  6107. /* EncryptedKey */
  6108. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6109. word32 encKeyOctetStrSz;
  6110. byte tmpIv[MAX_CONTENT_IV_SIZE];
  6111. byte* encryptedKey = NULL;
  6112. byte* kek = NULL;
  6113. int cekKeySz = 0, kekKeySz = 0, kekBlockSz = 0, ret = 0;
  6114. int encryptOID;
  6115. word32 idx, totalSz = 0, encryptedKeySz;
  6116. if (pkcs7 == NULL || passwd == NULL || pLen == 0 ||
  6117. salt == NULL || saltSz == 0) {
  6118. return BAD_FUNC_ARG;
  6119. }
  6120. /* allow user to use different KEK encryption algorithm than used for
  6121. * main content encryption algorithm, if passed in */
  6122. if (kekEncryptOID != 0) {
  6123. encryptOID = kekEncryptOID;
  6124. } else {
  6125. encryptOID = pkcs7->encryptOID;
  6126. }
  6127. /* get content-encryption key size, based on algorithm */
  6128. cekKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6129. if (cekKeySz < 0)
  6130. return cekKeySz;
  6131. /* get KEK encryption key size, based on algorithm */
  6132. if (encryptOID != pkcs7->encryptOID) {
  6133. kekKeySz = wc_PKCS7_GetOIDKeySize(encryptOID);
  6134. } else {
  6135. kekKeySz = cekKeySz;
  6136. }
  6137. /* get KEK encryption block size */
  6138. kekBlockSz = wc_PKCS7_GetOIDBlockSize(encryptOID);
  6139. if (kekBlockSz < 0)
  6140. return kekBlockSz;
  6141. /* generate random CEK */
  6142. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, cekKeySz);
  6143. if (ret < 0)
  6144. return ret;
  6145. /* generate random IV */
  6146. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, kekBlockSz);
  6147. if (ret != 0)
  6148. return ret;
  6149. /* allocate memory for RecipientInfo, KEK, encrypted key */
  6150. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  6151. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6152. if (recip == NULL)
  6153. return MEMORY_E;
  6154. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6155. if (kek == NULL) {
  6156. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6157. return MEMORY_E;
  6158. }
  6159. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ,
  6160. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6161. if (encryptedKey == NULL) {
  6162. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6163. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6164. return MEMORY_E;
  6165. }
  6166. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  6167. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6168. XMEMSET(kek, 0, kekKeySz);
  6169. XMEMSET(encryptedKey, 0, encryptedKeySz);
  6170. /* generate KEK: expand password into KEK */
  6171. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, passwd, pLen, salt, saltSz,
  6172. kdfOID, hashOID, iterations, kek,
  6173. kekKeySz);
  6174. if (ret < 0) {
  6175. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6176. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6177. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6178. return ret;
  6179. }
  6180. /* generate encrypted key: encrypt CEK with KEK */
  6181. ret = wc_PKCS7_PwriKek_KeyWrap(pkcs7, kek, kekKeySz, pkcs7->cek,
  6182. pkcs7->cekSz, encryptedKey, &encryptedKeySz,
  6183. tmpIv, kekBlockSz, encryptOID);
  6184. if (ret < 0) {
  6185. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6186. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6187. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6188. return ret;
  6189. }
  6190. encryptedKeySz = ret;
  6191. /* put together encrypted key OCTET STRING */
  6192. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  6193. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  6194. /* put together IV OCTET STRING */
  6195. ivOctetStringSz = SetOctetString(kekBlockSz, ivOctetString);
  6196. totalSz += (ivOctetStringSz + kekBlockSz);
  6197. /* set PWRIAlgorithms AlgorithmIdentifier, adding (ivOctetStringSz +
  6198. blockKeySz) for IV OCTET STRING */
  6199. pwriEncAlgoIdSz = SetAlgoID(encryptOID, pwriEncAlgoId,
  6200. oidBlkType, ivOctetStringSz + kekBlockSz);
  6201. totalSz += pwriEncAlgoIdSz;
  6202. /* set KeyEncryptionAlgorithms OID */
  6203. ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId));
  6204. if (ret <= 0) {
  6205. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6206. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6207. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6208. return ret;
  6209. }
  6210. keyEncAlgoIdSz = ret;
  6211. totalSz += keyEncAlgoIdSz;
  6212. /* KeyEncryptionAlgorithm SEQ */
  6213. keyEncAlgoIdSeqSz = SetSequence(keyEncAlgoIdSz + pwriEncAlgoIdSz +
  6214. ivOctetStringSz + kekBlockSz,
  6215. keyEncAlgoIdSeq);
  6216. totalSz += keyEncAlgoIdSeqSz;
  6217. /* set KDF salt */
  6218. kdfSaltOctetStrSz = SetOctetString(saltSz, kdfSaltOctetStr);
  6219. totalSz += (kdfSaltOctetStrSz + saltSz);
  6220. /* set KDF iteration count */
  6221. kdfIterationsSz = SetMyVersion(iterations, kdfIterations, 0);
  6222. totalSz += kdfIterationsSz;
  6223. /* set KDF params SEQ */
  6224. kdfParamsSeqSz = SetSequence(kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6225. kdfParamsSeq);
  6226. totalSz += kdfParamsSeqSz;
  6227. /* set KDF algo OID */
  6228. ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId));
  6229. if (ret <= 0) {
  6230. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6231. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6232. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6233. return ret;
  6234. }
  6235. kdfAlgoIdSz = ret;
  6236. totalSz += kdfAlgoIdSz;
  6237. /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */
  6238. kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz +
  6239. kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6240. kdfAlgoIdSeq);
  6241. totalSz += kdfAlgoIdSeqSz;
  6242. /* set PasswordRecipientInfo CMSVersion, MUST be 0 */
  6243. verSz = SetMyVersion(0, ver, 0);
  6244. totalSz += verSz;
  6245. recip->recipVersion = 0;
  6246. /* set PasswordRecipientInfo SEQ */
  6247. recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq);
  6248. totalSz += recipSeqSz;
  6249. if (totalSz > MAX_RECIP_SZ) {
  6250. WOLFSSL_MSG("CMS Recipient output buffer too small");
  6251. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6252. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6253. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6254. return BUFFER_E;
  6255. }
  6256. idx = 0;
  6257. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6258. idx += recipSeqSz;
  6259. XMEMCPY(recip->recip + idx, ver, verSz);
  6260. idx += verSz;
  6261. XMEMCPY(recip->recip + idx, kdfAlgoIdSeq, kdfAlgoIdSeqSz);
  6262. idx += kdfAlgoIdSeqSz;
  6263. XMEMCPY(recip->recip + idx, kdfAlgoId, kdfAlgoIdSz);
  6264. idx += kdfAlgoIdSz;
  6265. XMEMCPY(recip->recip + idx, kdfParamsSeq, kdfParamsSeqSz);
  6266. idx += kdfParamsSeqSz;
  6267. XMEMCPY(recip->recip + idx, kdfSaltOctetStr, kdfSaltOctetStrSz);
  6268. idx += kdfSaltOctetStrSz;
  6269. XMEMCPY(recip->recip + idx, salt, saltSz);
  6270. idx += saltSz;
  6271. XMEMCPY(recip->recip + idx, kdfIterations, kdfIterationsSz);
  6272. idx += kdfIterationsSz;
  6273. XMEMCPY(recip->recip + idx, keyEncAlgoIdSeq, keyEncAlgoIdSeqSz);
  6274. idx += keyEncAlgoIdSeqSz;
  6275. XMEMCPY(recip->recip + idx, keyEncAlgoId, keyEncAlgoIdSz);
  6276. idx += keyEncAlgoIdSz;
  6277. XMEMCPY(recip->recip + idx, pwriEncAlgoId, pwriEncAlgoIdSz);
  6278. idx += pwriEncAlgoIdSz;
  6279. XMEMCPY(recip->recip + idx, ivOctetString, ivOctetStringSz);
  6280. idx += ivOctetStringSz;
  6281. XMEMCPY(recip->recip + idx, tmpIv, kekBlockSz);
  6282. idx += kekBlockSz;
  6283. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  6284. idx += encKeyOctetStrSz;
  6285. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  6286. idx += encryptedKeySz;
  6287. ForceZero(kek, kekBlockSz);
  6288. ForceZero(encryptedKey, encryptedKeySz);
  6289. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6290. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6291. /* store recipient size */
  6292. recip->recipSz = idx;
  6293. recip->recipType = PKCS7_PWRI;
  6294. /* add recipient to recip list */
  6295. if (pkcs7->recipList == NULL) {
  6296. pkcs7->recipList = recip;
  6297. } else {
  6298. lastRecip = pkcs7->recipList;
  6299. while (lastRecip->next != NULL) {
  6300. lastRecip = lastRecip->next;
  6301. }
  6302. lastRecip->next = recip;
  6303. }
  6304. (void)options;
  6305. return idx;
  6306. }
  6307. /* Import password and KDF settings into a PKCS7 structure. Used for setting
  6308. * the password info for decryption a EnvelopedData PWRI RecipientInfo.
  6309. *
  6310. * Returns 0 on success, negative upon error */
  6311. int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen)
  6312. {
  6313. if (pkcs7 == NULL || passwd == NULL || pLen == 0)
  6314. return BAD_FUNC_ARG;
  6315. pkcs7->pass = passwd;
  6316. pkcs7->passSz = pLen;
  6317. return 0;
  6318. }
  6319. #endif /* NO_PWDBASED */
  6320. /* Encode and add CMS EnvelopedData KEKRI (KEKRecipientInfo) RecipientInfo
  6321. * to CMS/PKCS#7 EnvelopedData structure.
  6322. *
  6323. * pkcs7 - pointer to initialized PKCS7 structure
  6324. * keyWrapOID - OID sum of key wrap algorithm identifier
  6325. * kek - key encryption key
  6326. * kekSz - size of kek, bytes
  6327. * keyID - key-encryption key identifier, pre-distributed to endpoints
  6328. * keyIDSz - size of keyID, bytes
  6329. * timePtr - pointer to "time_t", which is typically "long" (OPTIONAL)
  6330. * otherOID - ASN.1 encoded OID of other attribute (OPTIONAL)
  6331. * otherOIDSz - size of otherOID, bytes (OPTIONAL)
  6332. * other - other attribute (OPTIONAL)
  6333. * otherSz - size of other (OPTIONAL)
  6334. *
  6335. * Returns 0 on success, negative upon error */
  6336. int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek,
  6337. word32 kekSz, byte* keyId, word32 keyIdSz,
  6338. void* timePtr, byte* otherOID,
  6339. word32 otherOIDSz, byte* other, word32 otherSz,
  6340. int options)
  6341. {
  6342. Pkcs7EncodedRecip* recip = NULL;
  6343. Pkcs7EncodedRecip* lastRecip = NULL;
  6344. byte recipSeq[MAX_SEQ_SZ];
  6345. byte ver[MAX_VERSION_SZ];
  6346. byte kekIdSeq[MAX_SEQ_SZ];
  6347. byte kekIdOctetStr[MAX_OCTET_STR_SZ];
  6348. byte genTime[ASN_GENERALIZED_TIME_SIZE];
  6349. byte otherAttSeq[MAX_SEQ_SZ];
  6350. byte encAlgoId[MAX_ALGO_SZ];
  6351. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6352. #ifdef WOLFSSL_SMALL_STACK
  6353. byte* encryptedKey;
  6354. #else
  6355. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  6356. #endif
  6357. int blockKeySz = 0, ret = 0, direction;
  6358. word32 idx = 0;
  6359. word32 totalSz = 0;
  6360. word32 recipSeqSz = 0, verSz = 0;
  6361. word32 kekIdSeqSz = 0, kekIdOctetStrSz = 0;
  6362. word32 otherAttSeqSz = 0, encAlgoIdSz = 0, encKeyOctetStrSz = 0;
  6363. int encryptedKeySz;
  6364. int timeSz = 0;
  6365. #ifndef NO_ASN_TIME
  6366. time_t* tm = NULL;
  6367. #endif
  6368. if (pkcs7 == NULL || kek == NULL || keyId == NULL)
  6369. return BAD_FUNC_ARG;
  6370. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  6371. DYNAMIC_TYPE_PKCS7);
  6372. if (recip == NULL)
  6373. return MEMORY_E;
  6374. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6375. /* get key size for content-encryption key based on algorithm */
  6376. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6377. if (blockKeySz < 0) {
  6378. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6379. return blockKeySz;
  6380. }
  6381. /* generate random content encryption key, if needed */
  6382. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  6383. if (ret < 0) {
  6384. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6385. return ret;
  6386. }
  6387. /* EncryptedKey */
  6388. #ifdef WOLFSSL_SMALL_STACK
  6389. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  6390. DYNAMIC_TYPE_PKCS7);
  6391. if (encryptedKey == NULL) {
  6392. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6393. return MEMORY_E;
  6394. }
  6395. #endif
  6396. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  6397. XMEMSET(encryptedKey, 0, encryptedKeySz);
  6398. #ifndef NO_AES
  6399. direction = AES_ENCRYPTION;
  6400. #else
  6401. direction = DES_ENCRYPTION;
  6402. #endif
  6403. encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz,
  6404. encryptedKey, encryptedKeySz, keyWrapOID,
  6405. direction);
  6406. if (encryptedKeySz < 0) {
  6407. #ifdef WOLFSSL_SMALL_STACK
  6408. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6409. #endif
  6410. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6411. return encryptedKeySz;
  6412. }
  6413. /* handle a zero size encKey case as WC_KEY_SIZE_E */
  6414. if (encryptedKeySz == 0 || encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  6415. #ifdef WOLFSSL_SMALL_STACK
  6416. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6417. #endif
  6418. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6419. return WC_KEY_SIZE_E;
  6420. }
  6421. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  6422. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  6423. /* KeyEncryptionAlgorithmIdentifier */
  6424. encAlgoIdSz = SetAlgoID(keyWrapOID, encAlgoId, oidKeyWrapType, 0);
  6425. totalSz += encAlgoIdSz;
  6426. /* KEKIdentifier: keyIdentifier */
  6427. kekIdOctetStrSz = SetOctetString(keyIdSz, kekIdOctetStr);
  6428. totalSz += (kekIdOctetStrSz + keyIdSz);
  6429. /* KEKIdentifier: GeneralizedTime (OPTIONAL) */
  6430. #ifndef NO_ASN_TIME
  6431. if (timePtr != NULL) {
  6432. tm = (time_t*)timePtr;
  6433. timeSz = GetAsnTimeString(tm, genTime, sizeof(genTime));
  6434. if (timeSz < 0) {
  6435. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6436. #ifdef WOLFSSL_SMALL_STACK
  6437. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6438. #endif
  6439. return timeSz;
  6440. }
  6441. totalSz += timeSz;
  6442. }
  6443. #endif
  6444. /* KEKIdentifier: OtherKeyAttribute SEQ (OPTIONAL) */
  6445. if (other != NULL && otherSz > 0) {
  6446. otherAttSeqSz = SetSequence(otherOIDSz + otherSz, otherAttSeq);
  6447. totalSz += otherAttSeqSz + otherOIDSz + otherSz;
  6448. }
  6449. /* KEKIdentifier SEQ */
  6450. kekIdSeqSz = SetSequence(kekIdOctetStrSz + keyIdSz + timeSz +
  6451. otherAttSeqSz + otherOIDSz + otherSz, kekIdSeq);
  6452. totalSz += kekIdSeqSz;
  6453. /* version */
  6454. verSz = SetMyVersion(4, ver, 0);
  6455. totalSz += verSz;
  6456. recip->recipVersion = 4;
  6457. /* KEKRecipientInfo SEQ */
  6458. recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq);
  6459. totalSz += recipSeqSz;
  6460. if (totalSz > MAX_RECIP_SZ) {
  6461. WOLFSSL_MSG("CMS Recipient output buffer too small");
  6462. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6463. #ifdef WOLFSSL_SMALL_STACK
  6464. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6465. #endif
  6466. return BUFFER_E;
  6467. }
  6468. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6469. idx += recipSeqSz;
  6470. XMEMCPY(recip->recip + idx, ver, verSz);
  6471. idx += verSz;
  6472. XMEMCPY(recip->recip + idx, kekIdSeq, kekIdSeqSz);
  6473. idx += kekIdSeqSz;
  6474. XMEMCPY(recip->recip + idx, kekIdOctetStr, kekIdOctetStrSz);
  6475. idx += kekIdOctetStrSz;
  6476. XMEMCPY(recip->recip + idx, keyId, keyIdSz);
  6477. idx += keyIdSz;
  6478. if (timePtr != NULL) {
  6479. XMEMCPY(recip->recip + idx, genTime, timeSz);
  6480. idx += timeSz;
  6481. }
  6482. if (other != NULL && otherSz > 0) {
  6483. XMEMCPY(recip->recip + idx, otherAttSeq, otherAttSeqSz);
  6484. idx += otherAttSeqSz;
  6485. XMEMCPY(recip->recip + idx, otherOID, otherOIDSz);
  6486. idx += otherOIDSz;
  6487. XMEMCPY(recip->recip + idx, other, otherSz);
  6488. idx += otherSz;
  6489. }
  6490. XMEMCPY(recip->recip + idx, encAlgoId, encAlgoIdSz);
  6491. idx += encAlgoIdSz;
  6492. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  6493. idx += encKeyOctetStrSz;
  6494. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  6495. idx += encryptedKeySz;
  6496. #ifdef WOLFSSL_SMALL_STACK
  6497. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6498. #endif
  6499. /* store recipient size */
  6500. recip->recipSz = idx;
  6501. recip->recipType = PKCS7_KEKRI;
  6502. /* add recipient to recip list */
  6503. if (pkcs7->recipList == NULL) {
  6504. pkcs7->recipList = recip;
  6505. } else {
  6506. lastRecip = pkcs7->recipList;
  6507. while(lastRecip->next != NULL) {
  6508. lastRecip = lastRecip->next;
  6509. }
  6510. lastRecip->next = recip;
  6511. }
  6512. (void)options;
  6513. return idx;
  6514. }
  6515. static int wc_PKCS7_GetCMSVersion(PKCS7* pkcs7, int cmsContentType)
  6516. {
  6517. int version = -1;
  6518. if (pkcs7 == NULL)
  6519. return BAD_FUNC_ARG;
  6520. switch (cmsContentType) {
  6521. case ENVELOPED_DATA:
  6522. /* NOTE: EnvelopedData does not currently support
  6523. originatorInfo or unprotectedAttributes. When either of these
  6524. are added, version checking below needs to be updated to match
  6525. Section 6.1 of RFC 5652 */
  6526. /* if RecipientInfos include pwri or ori, version is 3 */
  6527. if (wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_PWRI) ||
  6528. wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_ORI)) {
  6529. version = 3;
  6530. break;
  6531. }
  6532. /* if unprotectedAttrs is absent AND all RecipientInfo structs
  6533. are version 0, version is 0 */
  6534. if (wc_PKCS7_RecipientListVersionsAllZero(pkcs7)) {
  6535. version = 0;
  6536. break;
  6537. }
  6538. /* otherwise, version is 2 */
  6539. version = 2;
  6540. break;
  6541. default:
  6542. break;
  6543. }
  6544. return version;
  6545. }
  6546. /* build PKCS#7 envelopedData content type, return enveloped size */
  6547. int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  6548. {
  6549. int ret, idx = 0;
  6550. int totalSz, padSz, encryptedOutSz;
  6551. int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz;
  6552. byte contentInfoSeq[MAX_SEQ_SZ];
  6553. byte outerContentType[MAX_ALGO_SZ];
  6554. byte outerContent[MAX_SEQ_SZ];
  6555. int kariVersion;
  6556. int envDataSeqSz, verSz;
  6557. byte envDataSeq[MAX_SEQ_SZ];
  6558. byte ver[MAX_VERSION_SZ];
  6559. WC_RNG rng;
  6560. int blockSz, blockKeySz;
  6561. byte* plain;
  6562. byte* encryptedContent;
  6563. Pkcs7EncodedRecip* tmpRecip = NULL;
  6564. int recipSz, recipSetSz;
  6565. byte recipSet[MAX_SET_SZ];
  6566. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  6567. int contentEncAlgoSz, ivOctetStringSz;
  6568. byte encContentSeq[MAX_SEQ_SZ];
  6569. byte contentType[MAX_ALGO_SZ];
  6570. byte contentEncAlgo[MAX_ALGO_SZ];
  6571. byte tmpIv[MAX_CONTENT_IV_SIZE];
  6572. byte ivOctetString[MAX_OCTET_STR_SZ];
  6573. byte encContentOctet[MAX_OCTET_STR_SZ];
  6574. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  6575. return BAD_FUNC_ARG;
  6576. if (output == NULL || outputSz == 0)
  6577. return BAD_FUNC_ARG;
  6578. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6579. if (blockKeySz < 0)
  6580. return blockKeySz;
  6581. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  6582. if (blockSz < 0)
  6583. return blockSz;
  6584. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  6585. /* outer content type */
  6586. ret = wc_SetContentType(ENVELOPED_DATA, outerContentType,
  6587. sizeof(outerContentType));
  6588. if (ret < 0)
  6589. return ret;
  6590. outerContentTypeSz = ret;
  6591. }
  6592. /* generate random content encryption key */
  6593. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  6594. if (ret != 0) {
  6595. return ret;
  6596. }
  6597. /* build RecipientInfo, only if user manually set singleCert and size */
  6598. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  6599. switch (pkcs7->publicKeyOID) {
  6600. #ifndef NO_RSA
  6601. case RSAk:
  6602. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  6603. pkcs7->singleCertSz, 0);
  6604. break;
  6605. #endif
  6606. #ifdef HAVE_ECC
  6607. case ECDSAk:
  6608. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  6609. pkcs7->singleCertSz,
  6610. pkcs7->keyWrapOID,
  6611. pkcs7->keyAgreeOID, pkcs7->ukm,
  6612. pkcs7->ukmSz, 0);
  6613. break;
  6614. #endif
  6615. default:
  6616. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  6617. return BAD_FUNC_ARG;
  6618. };
  6619. if (ret < 0) {
  6620. WOLFSSL_MSG("Failed to create RecipientInfo");
  6621. return ret;
  6622. }
  6623. }
  6624. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  6625. if (recipSz < 0) {
  6626. return ret;
  6627. } else if (recipSz == 0) {
  6628. WOLFSSL_MSG("You must add at least one CMS recipient");
  6629. return PKCS7_RECIP_E;
  6630. }
  6631. recipSetSz = SetSet(recipSz, recipSet);
  6632. /* version, defined in Section 6.1 of RFC 5652 */
  6633. kariVersion = wc_PKCS7_GetCMSVersion(pkcs7, ENVELOPED_DATA);
  6634. if (kariVersion < 0) {
  6635. WOLFSSL_MSG("Failed to set CMS EnvelopedData version");
  6636. return PKCS7_RECIP_E;
  6637. }
  6638. verSz = SetMyVersion(kariVersion, ver, 0);
  6639. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  6640. if (ret != 0)
  6641. return ret;
  6642. /* generate IV for block cipher */
  6643. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, tmpIv, blockSz);
  6644. wc_FreeRng(&rng);
  6645. if (ret != 0)
  6646. return ret;
  6647. /* EncryptedContentInfo */
  6648. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  6649. sizeof(contentType));
  6650. if (ret < 0)
  6651. return ret;
  6652. contentTypeSz = ret;
  6653. /* allocate encrypted content buffer and PKCS#7 padding */
  6654. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  6655. if (padSz < 0)
  6656. return padSz;
  6657. encryptedOutSz = pkcs7->contentSz + padSz;
  6658. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6659. if (plain == NULL)
  6660. return MEMORY_E;
  6661. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  6662. encryptedOutSz, blockSz);
  6663. if (ret < 0) {
  6664. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6665. return ret;
  6666. }
  6667. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  6668. DYNAMIC_TYPE_PKCS7);
  6669. if (encryptedContent == NULL) {
  6670. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6671. return MEMORY_E;
  6672. }
  6673. /* put together IV OCTET STRING */
  6674. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  6675. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  6676. * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  6677. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  6678. oidBlkType, ivOctetStringSz + blockSz);
  6679. if (contentEncAlgoSz == 0) {
  6680. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6681. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6682. return BAD_FUNC_ARG;
  6683. }
  6684. /* encrypt content */
  6685. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  6686. pkcs7->cekSz, tmpIv, blockSz, NULL, 0, NULL, 0, plain,
  6687. encryptedOutSz, encryptedContent);
  6688. if (ret != 0) {
  6689. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6690. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6691. return ret;
  6692. }
  6693. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  6694. encContentOctet);
  6695. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  6696. ivOctetStringSz + blockSz +
  6697. encContentOctetSz + encryptedOutSz,
  6698. encContentSeq);
  6699. /* keep track of sizes for outer wrapper layering */
  6700. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  6701. contentEncAlgoSz + ivOctetStringSz + blockSz +
  6702. encContentOctetSz + encryptedOutSz;
  6703. /* EnvelopedData */
  6704. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  6705. totalSz += envDataSeqSz;
  6706. /* outer content */
  6707. outerContentSz = SetExplicit(0, totalSz, outerContent);
  6708. totalSz += outerContentTypeSz;
  6709. totalSz += outerContentSz;
  6710. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  6711. /* ContentInfo */
  6712. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  6713. totalSz += contentInfoSeqSz;
  6714. }
  6715. if (totalSz > (int)outputSz) {
  6716. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  6717. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6718. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6719. return BUFFER_E;
  6720. }
  6721. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  6722. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  6723. idx += contentInfoSeqSz;
  6724. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  6725. idx += outerContentTypeSz;
  6726. XMEMCPY(output + idx, outerContent, outerContentSz);
  6727. idx += outerContentSz;
  6728. }
  6729. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  6730. idx += envDataSeqSz;
  6731. XMEMCPY(output + idx, ver, verSz);
  6732. idx += verSz;
  6733. XMEMCPY(output + idx, recipSet, recipSetSz);
  6734. idx += recipSetSz;
  6735. /* copy in recipients from list */
  6736. tmpRecip = pkcs7->recipList;
  6737. while (tmpRecip != NULL) {
  6738. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  6739. idx += tmpRecip->recipSz;
  6740. tmpRecip = tmpRecip->next;
  6741. }
  6742. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  6743. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  6744. idx += encContentSeqSz;
  6745. XMEMCPY(output + idx, contentType, contentTypeSz);
  6746. idx += contentTypeSz;
  6747. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  6748. idx += contentEncAlgoSz;
  6749. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  6750. idx += ivOctetStringSz;
  6751. XMEMCPY(output + idx, tmpIv, blockSz);
  6752. idx += blockSz;
  6753. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  6754. idx += encContentOctetSz;
  6755. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  6756. idx += encryptedOutSz;
  6757. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6758. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6759. return idx;
  6760. }
  6761. #ifndef NO_RSA
  6762. /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */
  6763. static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
  6764. word32* idx, byte* decryptedKey,
  6765. word32* decryptedKeySz, int* recipFound)
  6766. {
  6767. int length, encryptedKeySz = 0, ret = 0;
  6768. int keySz, version, sidType = 0;
  6769. word32 encOID;
  6770. word32 keyIdx;
  6771. byte issuerHash[KEYID_SIZE];
  6772. byte* outKey = NULL;
  6773. byte* pkiMsg = in;
  6774. word32 pkiMsgSz = inSz;
  6775. byte tag;
  6776. #ifndef NO_PKCS7_STREAM
  6777. word32 tmpIdx = *idx;
  6778. long rc;
  6779. #endif
  6780. #ifdef WC_RSA_BLINDING
  6781. WC_RNG rng;
  6782. #endif
  6783. #ifdef WOLFSSL_SMALL_STACK
  6784. mp_int* serialNum = NULL;
  6785. byte* encryptedKey = NULL;
  6786. RsaKey* privKey = NULL;
  6787. #else
  6788. mp_int serialNum[1];
  6789. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  6790. RsaKey privKey[1];
  6791. #endif
  6792. switch (pkcs7->state) {
  6793. case WC_PKCS7_DECRYPT_KTRI:
  6794. #ifndef NO_PKCS7_STREAM
  6795. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_VERSION_SZ,
  6796. &pkiMsg, idx)) != 0) {
  6797. return ret;
  6798. }
  6799. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  6800. in, inSz);
  6801. if (rc < 0) {
  6802. ret = (int)rc;
  6803. break;
  6804. }
  6805. pkiMsgSz = (word32)rc;
  6806. #endif
  6807. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  6808. return ASN_PARSE_E;
  6809. if (version == 0) {
  6810. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  6811. } else if (version == 2) {
  6812. sidType = CMS_SKID;
  6813. } else {
  6814. return ASN_VERSION_E;
  6815. }
  6816. #ifndef NO_PKCS7_STREAM
  6817. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  6818. break;
  6819. }
  6820. wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version);
  6821. /* @TODO getting total amount left because of GetInt call later on
  6822. * this could be optimized to stream better */
  6823. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  6824. pkcs7->stream->totalRd) + pkcs7->stream->length;
  6825. #endif
  6826. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2);
  6827. FALL_THROUGH;
  6828. case WC_PKCS7_DECRYPT_KTRI_2:
  6829. #ifndef NO_PKCS7_STREAM
  6830. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, pkcs7->stream->expected,
  6831. &pkiMsg, idx)) != 0) {
  6832. return ret;
  6833. }
  6834. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  6835. in, inSz);
  6836. if (rc < 0) {
  6837. ret = (int)rc;
  6838. break;
  6839. }
  6840. pkiMsgSz = (word32)rc;
  6841. wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version);
  6842. /* @TODO get expected size for next part, does not account for
  6843. * GetInt call well */
  6844. if (pkcs7->stream->expected == MAX_SEQ_SZ) {
  6845. int sz;
  6846. word32 lidx;
  6847. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  6848. lidx = *idx;
  6849. ret = GetSequence(pkiMsg, &lidx, &sz, pkiMsgSz);
  6850. if (ret < 0)
  6851. return ret;
  6852. }
  6853. else {
  6854. lidx = *idx + ASN_TAG_SZ;
  6855. ret = GetLength(pkiMsg, &lidx, &sz, pkiMsgSz);
  6856. if (ret < 0)
  6857. return ret;
  6858. }
  6859. pkcs7->stream->expected = sz + MAX_ALGO_SZ + ASN_TAG_SZ +
  6860. MAX_LENGTH_SZ;
  6861. if (pkcs7->stream->length > 0 &&
  6862. pkcs7->stream->length < pkcs7->stream->expected) {
  6863. return WC_PKCS7_WANT_READ_E;
  6864. }
  6865. }
  6866. #endif /* !NO_PKCS7_STREAM */
  6867. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  6868. /* remove IssuerAndSerialNumber */
  6869. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  6870. return ASN_PARSE_E;
  6871. if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
  6872. return ASN_PARSE_E;
  6873. /* if we found correct recipient, issuer hashes will match */
  6874. if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) {
  6875. *recipFound = 1;
  6876. }
  6877. #ifdef WOLFSSL_SMALL_STACK
  6878. serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,
  6879. DYNAMIC_TYPE_TMP_BUFFER);
  6880. if (serialNum == NULL)
  6881. return MEMORY_E;
  6882. #endif
  6883. if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {
  6884. #ifdef WOLFSSL_SMALL_STACK
  6885. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6886. #endif
  6887. return ASN_PARSE_E;
  6888. }
  6889. mp_clear(serialNum);
  6890. #ifdef WOLFSSL_SMALL_STACK
  6891. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6892. #endif
  6893. } else {
  6894. /* remove SubjectKeyIdentifier */
  6895. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  6896. return ASN_PARSE_E;
  6897. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
  6898. return ASN_PARSE_E;
  6899. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  6900. return ASN_PARSE_E;
  6901. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  6902. return ASN_PARSE_E;
  6903. if (tag != ASN_OCTET_STRING)
  6904. return ASN_PARSE_E;
  6905. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  6906. return ASN_PARSE_E;
  6907. /* if we found correct recipient, SKID will match */
  6908. if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId,
  6909. KEYID_SIZE) == 0) {
  6910. *recipFound = 1;
  6911. }
  6912. (*idx) += KEYID_SIZE;
  6913. }
  6914. if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)
  6915. return ASN_PARSE_E;
  6916. /* key encryption algorithm must be RSA for now */
  6917. if (encOID != RSAk)
  6918. return ALGO_ID_E;
  6919. /* read encryptedKey */
  6920. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  6921. return ASN_PARSE_E;
  6922. if (tag != ASN_OCTET_STRING)
  6923. return ASN_PARSE_E;
  6924. if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
  6925. return ASN_PARSE_E;
  6926. }
  6927. if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  6928. return BUFFER_E;
  6929. }
  6930. #ifndef NO_PKCS7_STREAM
  6931. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  6932. break;
  6933. }
  6934. wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version);
  6935. pkcs7->stream->expected = encryptedKeySz;
  6936. #endif
  6937. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3);
  6938. FALL_THROUGH;
  6939. case WC_PKCS7_DECRYPT_KTRI_3:
  6940. #ifndef NO_PKCS7_STREAM
  6941. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  6942. pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
  6943. return ret;
  6944. }
  6945. encryptedKeySz = pkcs7->stream->expected;
  6946. #endif
  6947. #ifdef WOLFSSL_SMALL_STACK
  6948. encryptedKey = (byte*)XMALLOC(encryptedKeySz, pkcs7->heap,
  6949. DYNAMIC_TYPE_TMP_BUFFER);
  6950. if (encryptedKey == NULL)
  6951. return MEMORY_E;
  6952. #endif
  6953. if (*recipFound == 1)
  6954. XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);
  6955. *idx += encryptedKeySz;
  6956. /* load private key */
  6957. #ifdef WOLFSSL_SMALL_STACK
  6958. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  6959. DYNAMIC_TYPE_TMP_BUFFER);
  6960. if (privKey == NULL) {
  6961. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6962. return MEMORY_E;
  6963. }
  6964. #endif
  6965. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, INVALID_DEVID);
  6966. if (ret != 0) {
  6967. #ifdef WOLFSSL_SMALL_STACK
  6968. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6969. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6970. #endif
  6971. return ret;
  6972. }
  6973. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  6974. keyIdx = 0;
  6975. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx,
  6976. privKey, pkcs7->privateKeySz);
  6977. }
  6978. else if (pkcs7->devId == INVALID_DEVID) {
  6979. ret = BAD_FUNC_ARG;
  6980. }
  6981. if (ret != 0) {
  6982. WOLFSSL_MSG("Failed to decode RSA private key");
  6983. wc_FreeRsaKey(privKey);
  6984. #ifdef WOLFSSL_SMALL_STACK
  6985. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6986. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6987. #endif
  6988. return ret;
  6989. }
  6990. /* decrypt encryptedKey */
  6991. #ifdef WC_RSA_BLINDING
  6992. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  6993. if (ret == 0) {
  6994. ret = wc_RsaSetRNG(privKey, &rng);
  6995. }
  6996. #endif
  6997. if (ret == 0) {
  6998. keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
  6999. &outKey, privKey);
  7000. #ifdef WC_RSA_BLINDING
  7001. wc_FreeRng(&rng);
  7002. #endif
  7003. } else {
  7004. keySz = ret;
  7005. }
  7006. wc_FreeRsaKey(privKey);
  7007. if (keySz <= 0 || outKey == NULL) {
  7008. ForceZero(encryptedKey, encryptedKeySz);
  7009. #ifdef WOLFSSL_SMALL_STACK
  7010. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7011. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7012. #endif
  7013. return keySz;
  7014. } else {
  7015. *decryptedKeySz = keySz;
  7016. XMEMCPY(decryptedKey, outKey, keySz);
  7017. ForceZero(encryptedKey, encryptedKeySz);
  7018. }
  7019. #ifdef WOLFSSL_SMALL_STACK
  7020. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7021. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7022. #endif
  7023. #ifndef NO_PKCS7_STREAM
  7024. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7025. break;
  7026. }
  7027. #endif
  7028. ret = 0; /* success */
  7029. break;
  7030. default:
  7031. WOLFSSL_MSG("PKCS7 Unknown KTRI decrypt state");
  7032. ret = BAD_FUNC_ARG;
  7033. }
  7034. return ret;
  7035. }
  7036. #endif /* !NO_RSA */
  7037. #ifdef HAVE_ECC
  7038. /* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */
  7039. static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
  7040. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7041. {
  7042. int ret, length;
  7043. word32 keyOID, oidSum = 0;
  7044. int curve_id = ECC_CURVE_DEF;
  7045. byte tag;
  7046. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7047. return BAD_FUNC_ARG;
  7048. /* remove OriginatorIdentifierOrKey */
  7049. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7050. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7051. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7052. return ASN_PARSE_E;
  7053. } else {
  7054. return ASN_PARSE_E;
  7055. }
  7056. /* remove OriginatorPublicKey */
  7057. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7058. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7059. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7060. return ASN_PARSE_E;
  7061. } else {
  7062. return ASN_PARSE_E;
  7063. }
  7064. /* remove AlgorithmIdentifier */
  7065. if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)
  7066. return ASN_PARSE_E;
  7067. if (keyOID != ECDSAk)
  7068. return ASN_PARSE_E;
  7069. /* optional algorithm parameters */
  7070. ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);
  7071. if (ret == 0) {
  7072. /* get curve id */
  7073. curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
  7074. if (curve_id < 0)
  7075. return ECC_CURVE_OID_E;
  7076. }
  7077. /* remove ECPoint BIT STRING */
  7078. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7079. return ASN_PARSE_E;
  7080. if (tag != ASN_BIT_STRING)
  7081. return ASN_PARSE_E;
  7082. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7083. return ASN_PARSE_E;
  7084. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7085. return ASN_EXPECT_0_E;
  7086. if (tag != ASN_OTHER_TYPE)
  7087. return ASN_EXPECT_0_E;
  7088. /* get sender ephemeral public ECDSA key */
  7089. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  7090. if (ret != 0)
  7091. return ret;
  7092. kari->senderKeyInit = 1;
  7093. /* length-1 for unused bits counter */
  7094. ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,
  7095. curve_id);
  7096. if (ret != 0) {
  7097. ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
  7098. if (ret != 0)
  7099. return ret;
  7100. }
  7101. else {
  7102. (*idx) += length - 1;
  7103. }
  7104. return 0;
  7105. }
  7106. /* remove optional UserKeyingMaterial if available, return 0 on success,
  7107. * < 0 on error */
  7108. static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
  7109. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7110. {
  7111. int length;
  7112. word32 savedIdx;
  7113. byte tag;
  7114. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7115. return BAD_FUNC_ARG;
  7116. savedIdx = *idx;
  7117. /* starts with EXPLICIT [1] */
  7118. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7119. *idx = savedIdx;
  7120. return 0;
  7121. }
  7122. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7123. *idx = savedIdx;
  7124. return 0;
  7125. }
  7126. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7127. *idx = savedIdx;
  7128. return 0;
  7129. }
  7130. /* get OCTET STRING */
  7131. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7132. *idx = savedIdx;
  7133. return 0;
  7134. }
  7135. if (tag != ASN_OCTET_STRING) {
  7136. *idx = savedIdx;
  7137. return 0;
  7138. }
  7139. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7140. *idx = savedIdx;
  7141. return 0;
  7142. }
  7143. kari->ukm = NULL;
  7144. if (length > 0) {
  7145. kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
  7146. if (kari->ukm == NULL)
  7147. return MEMORY_E;
  7148. XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
  7149. kari->ukmOwner = 1;
  7150. }
  7151. (*idx) += length;
  7152. kari->ukmSz = length;
  7153. return 0;
  7154. }
  7155. /* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,
  7156. * < 0 on error */
  7157. static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
  7158. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7159. word32* keyAgreeOID, word32* keyWrapOID)
  7160. {
  7161. int length = 0;
  7162. word32 localIdx;
  7163. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  7164. keyAgreeOID == NULL || keyWrapOID == NULL)
  7165. return BAD_FUNC_ARG;
  7166. localIdx = *idx;
  7167. /* remove KeyEncryptionAlgorithmIdentifier */
  7168. if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  7169. return ASN_PARSE_E;
  7170. localIdx = *idx;
  7171. if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,
  7172. pkiMsgSz) < 0) {
  7173. return ASN_PARSE_E;
  7174. }
  7175. if (localIdx < *idx + length) {
  7176. *idx = localIdx;
  7177. }
  7178. /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
  7179. if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  7180. return ASN_PARSE_E;
  7181. return 0;
  7182. }
  7183. /* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
  7184. * if subject key ID matches, recipFound is set to 1 */
  7185. static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
  7186. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7187. int* recipFound, byte* rid)
  7188. {
  7189. int length;
  7190. byte tag;
  7191. if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
  7192. rid == NULL)
  7193. return BAD_FUNC_ARG;
  7194. /* remove RecipientKeyIdentifier IMPLICIT [0] */
  7195. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7196. return ASN_PARSE_E;
  7197. }
  7198. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7199. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7200. return ASN_PARSE_E;
  7201. } else {
  7202. return ASN_PARSE_E;
  7203. }
  7204. /* remove SubjectKeyIdentifier */
  7205. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7206. return ASN_PARSE_E;
  7207. }
  7208. if (tag != ASN_OCTET_STRING)
  7209. return ASN_PARSE_E;
  7210. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7211. return ASN_PARSE_E;
  7212. if (length != KEYID_SIZE)
  7213. return ASN_PARSE_E;
  7214. XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE);
  7215. (*idx) += length;
  7216. /* subject key id should match if recipient found */
  7217. if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {
  7218. *recipFound = 1;
  7219. }
  7220. return 0;
  7221. }
  7222. /* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
  7223. * if issuer and serial number match, recipFound is set to 1 */
  7224. static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
  7225. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7226. int* recipFound, byte* rid)
  7227. {
  7228. int length, ret;
  7229. #ifdef WOLFSSL_SMALL_STACK
  7230. mp_int* serial;
  7231. mp_int* recipSerial;
  7232. #else
  7233. mp_int serial[1];
  7234. mp_int recipSerial[1];
  7235. #endif
  7236. if (rid == NULL) {
  7237. return BAD_FUNC_ARG;
  7238. }
  7239. /* remove IssuerAndSerialNumber */
  7240. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7241. return ASN_PARSE_E;
  7242. if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0)
  7243. return ASN_PARSE_E;
  7244. /* if we found correct recipient, issuer hashes will match */
  7245. if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
  7246. *recipFound = 1;
  7247. }
  7248. #ifdef WOLFSSL_SMALL_STACK
  7249. serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  7250. DYNAMIC_TYPE_TMP_BUFFER);
  7251. if (serial == NULL)
  7252. return MEMORY_E;
  7253. recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  7254. DYNAMIC_TYPE_TMP_BUFFER);
  7255. if (recipSerial == NULL) {
  7256. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7257. return MEMORY_E;
  7258. }
  7259. #endif
  7260. if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
  7261. #ifdef WOLFSSL_SMALL_STACK
  7262. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7263. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7264. #endif
  7265. return ASN_PARSE_E;
  7266. }
  7267. ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
  7268. kari->decoded->serialSz);
  7269. if (ret != MP_OKAY) {
  7270. mp_clear(serial);
  7271. WOLFSSL_MSG("Failed to parse CMS recipient serial number");
  7272. #ifdef WOLFSSL_SMALL_STACK
  7273. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7274. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7275. #endif
  7276. return ret;
  7277. }
  7278. if (mp_cmp(recipSerial, serial) != MP_EQ) {
  7279. mp_clear(serial);
  7280. mp_clear(recipSerial);
  7281. WOLFSSL_MSG("CMS serial number does not match recipient");
  7282. #ifdef WOLFSSL_SMALL_STACK
  7283. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7284. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7285. #endif
  7286. return PKCS7_RECIP_E;
  7287. }
  7288. mp_clear(serial);
  7289. mp_clear(recipSerial);
  7290. #ifdef WOLFSSL_SMALL_STACK
  7291. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7292. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7293. #endif
  7294. return 0;
  7295. }
  7296. /* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
  7297. static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
  7298. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7299. int* recipFound, byte* encryptedKey,
  7300. int* encryptedKeySz, byte* rid)
  7301. {
  7302. int length;
  7303. int ret = 0;
  7304. byte tag;
  7305. word32 localIdx;
  7306. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  7307. recipFound == NULL || encryptedKey == NULL)
  7308. return BAD_FUNC_ARG;
  7309. /* remove RecipientEncryptedKeys */
  7310. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7311. return ASN_PARSE_E;
  7312. /* remove RecipientEncryptedKeys */
  7313. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7314. return ASN_PARSE_E;
  7315. /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
  7316. * or [0] IMMPLICIT RecipientKeyIdentifier */
  7317. localIdx = *idx;
  7318. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  7319. return ASN_PARSE_E;
  7320. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7321. /* try to get RecipientKeyIdentifier */
  7322. ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
  7323. idx, recipFound, rid);
  7324. } else {
  7325. /* try to get IssuerAndSerialNumber */
  7326. ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
  7327. idx, recipFound, rid);
  7328. }
  7329. /* if we don't have either option, malformed CMS */
  7330. if (ret != 0)
  7331. return ret;
  7332. /* remove EncryptedKey */
  7333. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7334. return ASN_PARSE_E;
  7335. if (tag != ASN_OCTET_STRING)
  7336. return ASN_PARSE_E;
  7337. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7338. return ASN_PARSE_E;
  7339. /* put encrypted CEK in decryptedKey buffer for now, decrypt later */
  7340. if (length > *encryptedKeySz)
  7341. return BUFFER_E;
  7342. XMEMCPY(encryptedKey, pkiMsg + (*idx), length);
  7343. *encryptedKeySz = length;
  7344. (*idx) += length;
  7345. return 0;
  7346. }
  7347. #endif /* HAVE_ECC */
  7348. int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx)
  7349. {
  7350. if (pkcs7 == NULL)
  7351. return BAD_FUNC_ARG;
  7352. pkcs7->oriEncryptCtx = ctx;
  7353. return 0;
  7354. }
  7355. int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx)
  7356. {
  7357. if (pkcs7 == NULL)
  7358. return BAD_FUNC_ARG;
  7359. pkcs7->oriDecryptCtx = ctx;
  7360. return 0;
  7361. }
  7362. int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb)
  7363. {
  7364. if (pkcs7 == NULL)
  7365. return BAD_FUNC_ARG;
  7366. pkcs7->oriDecryptCb = cb;
  7367. return 0;
  7368. }
  7369. /* return 0 on success */
  7370. int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, CallbackWrapCEK cb)
  7371. {
  7372. if (pkcs7 == NULL)
  7373. return BAD_FUNC_ARG;
  7374. pkcs7->wrapCEKCb = cb;
  7375. return 0;
  7376. }
  7377. /* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by:
  7378. *
  7379. * OtherRecipientInfo ::= SEQUENCE {
  7380. * oriType OBJECT IDENTIFIER,
  7381. * oriValue ANY DEFINED BY oriType }
  7382. *
  7383. * pkcs7 - pointer to initialized PKCS7 structure
  7384. * pkiMsg - pointer to encoded CMS bundle
  7385. * pkiMsgSz - size of pkiMsg, bytes
  7386. * idx - [IN/OUT] pointer to index into pkiMsg
  7387. * decryptedKey - [OUT] output buf for decrypted content encryption key
  7388. * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key
  7389. * recipFound - [OUT] 1 if recipient has been found, 0 if not
  7390. *
  7391. * Return 0 on success, negative upon error.
  7392. */
  7393. static int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* in, word32 inSz,
  7394. word32* idx, byte* decryptedKey,
  7395. word32* decryptedKeySz, int* recipFound)
  7396. {
  7397. int ret, seqSz, oriOIDSz;
  7398. word32 oriValueSz, tmpIdx;
  7399. byte* oriValue;
  7400. byte oriOID[MAX_OID_SZ];
  7401. byte* pkiMsg = in;
  7402. word32 pkiMsgSz = inSz;
  7403. #ifndef NO_PKCS7_STREAM
  7404. word32 stateIdx = *idx;
  7405. long rc;
  7406. #endif
  7407. if (pkcs7->oriDecryptCb == NULL) {
  7408. WOLFSSL_MSG("You must register an ORI Decrypt callback");
  7409. return BAD_FUNC_ARG;
  7410. }
  7411. switch (pkcs7->state) {
  7412. case WC_PKCS7_DECRYPT_ORI:
  7413. #ifndef NO_PKCS7_STREAM
  7414. /* @TODO for now just get full buffer, needs divided up */
  7415. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7416. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  7417. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  7418. return ret;
  7419. }
  7420. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  7421. inSz);
  7422. if (rc < 0) {
  7423. ret = (int)rc;
  7424. break;
  7425. }
  7426. pkiMsgSz = (word32)rc;
  7427. #endif
  7428. /* get OtherRecipientInfo sequence length */
  7429. if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0)
  7430. return ASN_PARSE_E;
  7431. tmpIdx = *idx;
  7432. /* remove and store oriType OBJECT IDENTIFIER */
  7433. if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0)
  7434. return ASN_PARSE_E;
  7435. XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz);
  7436. *idx += oriOIDSz;
  7437. /* get oriValue, increment idx */
  7438. oriValue = pkiMsg + *idx;
  7439. oriValueSz = seqSz - (*idx - tmpIdx);
  7440. *idx += oriValueSz;
  7441. /* pass oriOID and oriValue to user callback, expect back
  7442. decryptedKey and size */
  7443. ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue,
  7444. oriValueSz, decryptedKey, decryptedKeySz,
  7445. pkcs7->oriDecryptCtx);
  7446. if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) {
  7447. /* decrypt operation failed */
  7448. *recipFound = 0;
  7449. return PKCS7_RECIP_E;
  7450. }
  7451. /* mark recipFound, since we only support one RecipientInfo for now */
  7452. *recipFound = 1;
  7453. #ifndef NO_PKCS7_STREAM
  7454. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, idx)) != 0) {
  7455. break;
  7456. }
  7457. #endif
  7458. ret = 0; /* success */
  7459. break;
  7460. default:
  7461. WOLFSSL_MSG("PKCS7 ORI unknown state");
  7462. ret = BAD_FUNC_ARG;
  7463. }
  7464. return ret;
  7465. }
  7466. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  7467. /* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success,
  7468. * < 0 on error */
  7469. static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
  7470. word32* idx, byte* decryptedKey,
  7471. word32* decryptedKeySz, int* recipFound)
  7472. {
  7473. byte* salt;
  7474. byte* cek;
  7475. byte* kek;
  7476. byte tmpIv[MAX_CONTENT_IV_SIZE];
  7477. int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
  7478. int hashOID = WC_SHA; /* default to SHA1 */
  7479. word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
  7480. byte* pkiMsg = in;
  7481. word32 pkiMsgSz = inSz;
  7482. byte tag;
  7483. #ifndef NO_PKCS7_STREAM
  7484. word32 tmpIdx = *idx;
  7485. long rc;
  7486. #endif
  7487. switch (pkcs7->state) {
  7488. case WC_PKCS7_DECRYPT_PWRI:
  7489. #ifndef NO_PKCS7_STREAM
  7490. /*@TODO for now just get full buffer, needs divided up */
  7491. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7492. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  7493. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  7494. return ret;
  7495. }
  7496. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  7497. inSz);
  7498. if (rc < 0) {
  7499. ret = (int)rc;
  7500. break;
  7501. }
  7502. pkiMsgSz = (word32)rc;
  7503. #endif
  7504. /* remove KeyDerivationAlgorithmIdentifier */
  7505. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7506. return ASN_PARSE_E;
  7507. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  7508. return ASN_PARSE_E;
  7509. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7510. return ASN_PARSE_E;
  7511. /* get KeyDerivationAlgorithmIdentifier */
  7512. if (wc_GetContentType(pkiMsg, idx, &kdfAlgoId, pkiMsgSz) < 0)
  7513. return ASN_PARSE_E;
  7514. /* get KDF params SEQ */
  7515. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7516. return ASN_PARSE_E;
  7517. /* get KDF salt OCTET STRING */
  7518. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7519. return ASN_PARSE_E;
  7520. if (tag != ASN_OCTET_STRING)
  7521. return ASN_PARSE_E;
  7522. if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)
  7523. return ASN_PARSE_E;
  7524. salt = (byte*)XMALLOC(saltSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7525. if (salt == NULL)
  7526. return MEMORY_E;
  7527. XMEMCPY(salt, pkiMsg + (*idx), saltSz);
  7528. *idx += saltSz;
  7529. /* get KDF iterations */
  7530. if (GetMyVersion(pkiMsg, idx, &iterations, pkiMsgSz) < 0) {
  7531. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7532. return ASN_PARSE_E;
  7533. }
  7534. /* get KeyEncAlgoId SEQ */
  7535. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7536. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7537. return ASN_PARSE_E;
  7538. }
  7539. /* get KeyEncAlgoId */
  7540. if (wc_GetContentType(pkiMsg, idx, &keyEncAlgoId, pkiMsgSz) < 0) {
  7541. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7542. return ASN_PARSE_E;
  7543. }
  7544. /* get pwriEncAlgoId */
  7545. if (GetAlgoId(pkiMsg, idx, &pwriEncAlgoId, oidBlkType, pkiMsgSz) < 0) {
  7546. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7547. return ASN_PARSE_E;
  7548. }
  7549. blockSz = wc_PKCS7_GetOIDBlockSize(pwriEncAlgoId);
  7550. if (blockSz < 0) {
  7551. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7552. return blockSz;
  7553. }
  7554. /* get content-encryption key size, based on algorithm */
  7555. kekKeySz = wc_PKCS7_GetOIDKeySize(pwriEncAlgoId);
  7556. if (kekKeySz < 0) {
  7557. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7558. return kekKeySz;
  7559. }
  7560. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  7561. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7562. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7563. return ASN_PARSE_E;
  7564. }
  7565. if (tag != ASN_OCTET_STRING) {
  7566. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7567. return ASN_PARSE_E;
  7568. }
  7569. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7570. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7571. return ASN_PARSE_E;
  7572. }
  7573. if (length != blockSz) {
  7574. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  7575. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7576. return ASN_PARSE_E;
  7577. }
  7578. XMEMCPY(tmpIv, pkiMsg + (*idx), length);
  7579. *idx += length;
  7580. /* get EncryptedKey */
  7581. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7582. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7583. return ASN_PARSE_E;
  7584. }
  7585. if (tag != ASN_OCTET_STRING) {
  7586. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7587. return ASN_PARSE_E;
  7588. }
  7589. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7590. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7591. return ASN_PARSE_E;
  7592. }
  7593. /* allocate temporary space for decrypted key */
  7594. cekSz = length;
  7595. cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7596. if (cek == NULL) {
  7597. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7598. return MEMORY_E;
  7599. }
  7600. /* generate KEK */
  7601. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7602. if (kek == NULL) {
  7603. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7604. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7605. return MEMORY_E;
  7606. }
  7607. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, pkcs7->pass, pkcs7->passSz,
  7608. salt, saltSz, kdfAlgoId, hashOID,
  7609. iterations, kek, kekKeySz);
  7610. if (ret < 0) {
  7611. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7612. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7613. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7614. return ASN_PARSE_E;
  7615. }
  7616. /* decrypt CEK with KEK */
  7617. ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, kekKeySz,
  7618. pkiMsg + (*idx), length, cek,
  7619. cekSz, tmpIv, blockSz,
  7620. pwriEncAlgoId);
  7621. if (ret < 0) {
  7622. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7623. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7624. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7625. return ret;
  7626. }
  7627. cekSz = ret;
  7628. if (*decryptedKeySz < cekSz) {
  7629. WOLFSSL_MSG("Decrypted key buffer too small for CEK");
  7630. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7631. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7632. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7633. return BUFFER_E;
  7634. }
  7635. XMEMCPY(decryptedKey, cek, cekSz);
  7636. *decryptedKeySz = cekSz;
  7637. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7638. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7639. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7640. /* mark recipFound, since we only support one RecipientInfo for now */
  7641. *recipFound = 1;
  7642. *idx += length;
  7643. #ifndef NO_PKCS7_STREAM
  7644. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7645. break;
  7646. }
  7647. #endif
  7648. ret = 0; /* success */
  7649. break;
  7650. default:
  7651. WOLFSSL_MSG("PKCS7 PWRI unknown state");
  7652. ret = BAD_FUNC_ARG;
  7653. }
  7654. return ret;
  7655. }
  7656. #endif /* NO_PWDBASED | NO_SHA */
  7657. /* decode ASN.1 KEKRecipientInfo (kekri), return 0 on success,
  7658. * < 0 on error */
  7659. static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
  7660. word32* idx, byte* decryptedKey,
  7661. word32* decryptedKeySz, int* recipFound)
  7662. {
  7663. int length, keySz, dateLen, direction;
  7664. byte* keyId = NULL;
  7665. const byte* datePtr = NULL;
  7666. byte dateFormat, tag;
  7667. word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;
  7668. int ret = 0;
  7669. byte* pkiMsg = in;
  7670. word32 pkiMsgSz = inSz;
  7671. #ifndef NO_PKCS7_STREAM
  7672. word32 tmpIdx = *idx;
  7673. long rc;
  7674. #endif
  7675. WOLFSSL_ENTER("wc_PKCS7_DecryptKekri");
  7676. switch (pkcs7->state) {
  7677. case WC_PKCS7_DECRYPT_KEKRI:
  7678. #ifndef NO_PKCS7_STREAM
  7679. /* @TODO for now just get full buffer, needs divided up */
  7680. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7681. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  7682. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  7683. return ret;
  7684. }
  7685. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  7686. inSz);
  7687. if (rc < 0) {
  7688. ret = (int)rc;
  7689. break;
  7690. }
  7691. pkiMsgSz = (word32)rc;
  7692. #endif
  7693. /* remove KEKIdentifier */
  7694. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7695. return ASN_PARSE_E;
  7696. kekIdSz = length;
  7697. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7698. return ASN_PARSE_E;
  7699. if (tag != ASN_OCTET_STRING)
  7700. return ASN_PARSE_E;
  7701. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7702. return ASN_PARSE_E;
  7703. /* save keyIdentifier and length */
  7704. keyId = pkiMsg + *idx;
  7705. keyIdSz = length;
  7706. *idx += keyIdSz;
  7707. /* may have OPTIONAL GeneralizedTime */
  7708. localIdx = *idx;
  7709. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  7710. pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {
  7711. if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,
  7712. &dateLen) != 0) {
  7713. return ASN_PARSE_E;
  7714. }
  7715. *idx += (dateLen + 1);
  7716. }
  7717. /* may have OPTIONAL OtherKeyAttribute */
  7718. localIdx = *idx;
  7719. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  7720. pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |
  7721. ASN_CONSTRUCTED)) {
  7722. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7723. return ASN_PARSE_E;
  7724. /* skip it */
  7725. *idx += length;
  7726. }
  7727. /* get KeyEncryptionAlgorithmIdentifier */
  7728. if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  7729. return ASN_PARSE_E;
  7730. /* get EncryptedKey */
  7731. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7732. return ASN_PARSE_E;
  7733. if (tag != ASN_OCTET_STRING)
  7734. return ASN_PARSE_E;
  7735. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7736. return ASN_PARSE_E;
  7737. #ifndef NO_AES
  7738. direction = AES_DECRYPTION;
  7739. #else
  7740. direction = DES_DECRYPTION;
  7741. #endif
  7742. /* decrypt CEK with KEK */
  7743. if (pkcs7->wrapCEKCb) {
  7744. keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,
  7745. keyIdSz, NULL, 0, decryptedKey,
  7746. *decryptedKeySz, keyWrapOID,
  7747. (int)PKCS7_KEKRI, direction);
  7748. }
  7749. else {
  7750. keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,
  7751. pkcs7->privateKeySz, decryptedKey, *decryptedKeySz,
  7752. keyWrapOID, direction);
  7753. }
  7754. if (keySz <= 0)
  7755. return keySz;
  7756. *decryptedKeySz = (word32)keySz;
  7757. /* mark recipFound, since we only support one RecipientInfo for now */
  7758. *recipFound = 1;
  7759. *idx += length;
  7760. #ifndef NO_PKCS7_STREAM
  7761. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7762. break;
  7763. }
  7764. #endif
  7765. ret = 0; /* success */
  7766. break;
  7767. default:
  7768. WOLFSSL_MSG("PKCS7 KEKRI unknown state");
  7769. ret = BAD_FUNC_ARG;
  7770. }
  7771. (void)keyId;
  7772. return ret;
  7773. }
  7774. /* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,
  7775. * < 0 on error */
  7776. static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
  7777. word32* idx, byte* decryptedKey,
  7778. word32* decryptedKeySz, int* recipFound)
  7779. {
  7780. #ifdef HAVE_ECC
  7781. int ret, keySz;
  7782. int encryptedKeySz;
  7783. int direction = 0;
  7784. word32 keyAgreeOID, keyWrapOID;
  7785. byte rid[KEYID_SIZE];
  7786. #ifdef WOLFSSL_SMALL_STACK
  7787. byte* encryptedKey;
  7788. #else
  7789. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  7790. #endif
  7791. byte* pkiMsg = in;
  7792. word32 pkiMsgSz = inSz;
  7793. #ifndef NO_PKCS7_STREAM
  7794. word32 tmpIdx = (idx) ? *idx : 0;
  7795. long rc;
  7796. #endif
  7797. WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
  7798. if (pkcs7 == NULL || pkiMsg == NULL ||
  7799. ((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&
  7800. pkcs7->wrapCEKCb == NULL) ||
  7801. idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
  7802. return BAD_FUNC_ARG;
  7803. }
  7804. switch (pkcs7->state) {
  7805. case WC_PKCS7_DECRYPT_KARI: {
  7806. #ifndef NO_PKCS7_STREAM
  7807. /* @TODO for now just get full buffer, needs divided up */
  7808. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7809. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  7810. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  7811. return ret;
  7812. }
  7813. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  7814. inSz);
  7815. if (rc < 0) {
  7816. ret = (int)rc;
  7817. break;
  7818. }
  7819. pkiMsgSz = (word32)rc;
  7820. #endif
  7821. WC_PKCS7_KARI* kari;
  7822. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);
  7823. if (kari == NULL)
  7824. return MEMORY_E;
  7825. #ifdef WOLFSSL_SMALL_STACK
  7826. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  7827. DYNAMIC_TYPE_PKCS7);
  7828. if (encryptedKey == NULL) {
  7829. wc_PKCS7_KariFree(kari);
  7830. return MEMORY_E;
  7831. }
  7832. #endif
  7833. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  7834. /* parse cert and key */
  7835. if (pkcs7->singleCert != NULL) {
  7836. ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
  7837. pkcs7->singleCertSz, pkcs7->privateKey,
  7838. pkcs7->privateKeySz);
  7839. if (ret != 0) {
  7840. wc_PKCS7_KariFree(kari);
  7841. #ifdef WOLFSSL_SMALL_STACK
  7842. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7843. #endif
  7844. return ret;
  7845. }
  7846. }
  7847. /* remove OriginatorIdentifierOrKey */
  7848. ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
  7849. pkiMsgSz, idx);
  7850. if (ret != 0) {
  7851. wc_PKCS7_KariFree(kari);
  7852. #ifdef WOLFSSL_SMALL_STACK
  7853. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7854. #endif
  7855. return ret;
  7856. }
  7857. /* try and remove optional UserKeyingMaterial */
  7858. ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);
  7859. if (ret != 0) {
  7860. wc_PKCS7_KariFree(kari);
  7861. #ifdef WOLFSSL_SMALL_STACK
  7862. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7863. #endif
  7864. return ret;
  7865. }
  7866. /* remove KeyEncryptionAlgorithmIdentifier */
  7867. ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,
  7868. pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);
  7869. if (ret != 0) {
  7870. wc_PKCS7_KariFree(kari);
  7871. #ifdef WOLFSSL_SMALL_STACK
  7872. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7873. #endif
  7874. return ret;
  7875. }
  7876. /* if user has not explicitly set keyAgreeOID, set from one in bundle */
  7877. if (pkcs7->keyAgreeOID == 0)
  7878. pkcs7->keyAgreeOID = keyAgreeOID;
  7879. /* set direction based on key wrap algorithm */
  7880. switch (keyWrapOID) {
  7881. #ifndef NO_AES
  7882. #ifdef WOLFSSL_AES_128
  7883. case AES128_WRAP:
  7884. #endif
  7885. #ifdef WOLFSSL_AES_192
  7886. case AES192_WRAP:
  7887. #endif
  7888. #ifdef WOLFSSL_AES_256
  7889. case AES256_WRAP:
  7890. #endif
  7891. direction = AES_DECRYPTION;
  7892. break;
  7893. #endif
  7894. default:
  7895. WOLFSSL_MSG("AES key wrap algorithm unsupported");
  7896. if (pkcs7->wrapCEKCb) {
  7897. WOLFSSL_MSG("Direction not set!");
  7898. break; /* if unwrapping callback is set then do not
  7899. * force restriction of supported wrap
  7900. * algorithms */
  7901. }
  7902. wc_PKCS7_KariFree(kari);
  7903. #ifdef WOLFSSL_SMALL_STACK
  7904. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7905. #endif
  7906. return BAD_KEYWRAP_ALG_E;
  7907. }
  7908. /* remove RecipientEncryptedKeys */
  7909. ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
  7910. idx, recipFound, encryptedKey, &encryptedKeySz, rid);
  7911. if (ret != 0) {
  7912. wc_PKCS7_KariFree(kari);
  7913. #ifdef WOLFSSL_SMALL_STACK
  7914. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7915. #endif
  7916. return ret;
  7917. }
  7918. /* decrypt CEK with KEK */
  7919. if (pkcs7->wrapCEKCb) {
  7920. word32 tmpKeySz = 0;
  7921. byte* tmpKeyDer = NULL;
  7922. ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);
  7923. if (ret != LENGTH_ONLY_E) {
  7924. return ret;
  7925. }
  7926. /* buffer space for algorithm/curve */
  7927. tmpKeySz += MAX_SEQ_SZ;
  7928. tmpKeySz += 2 * MAX_ALGO_SZ;
  7929. /* buffer space for public key sequence */
  7930. tmpKeySz += MAX_SEQ_SZ;
  7931. tmpKeySz += TRAILING_ZERO;
  7932. tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,
  7933. DYNAMIC_TYPE_TMP_BUFFER);
  7934. if (tmpKeyDer == NULL) {
  7935. return MEMORY_E;
  7936. }
  7937. ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,
  7938. tmpKeySz, 1);
  7939. if (ret < 0) {
  7940. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7941. return ret;
  7942. }
  7943. tmpKeySz = (word32)ret;
  7944. keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,
  7945. rid, KEYID_SIZE, tmpKeyDer, tmpKeySz,
  7946. decryptedKey, *decryptedKeySz,
  7947. keyWrapOID, (int)PKCS7_KARI, direction);
  7948. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7949. if (keySz > 0) {
  7950. /* If unwrapping was successful then consider recipient
  7951. * found. Checking for NULL singleCert to confirm previous
  7952. * SID check was not done */
  7953. if (pkcs7->singleCert == NULL)
  7954. *recipFound = 1;
  7955. }
  7956. }
  7957. else {
  7958. /* create KEK */
  7959. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID,
  7960. pkcs7->keyAgreeOID);
  7961. if (ret != 0) {
  7962. wc_PKCS7_KariFree(kari);
  7963. #ifdef WOLFSSL_SMALL_STACK
  7964. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7965. #endif
  7966. return ret;
  7967. }
  7968. /* decrypt CEK with KEK */
  7969. keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,
  7970. kari->kekSz, decryptedKey, *decryptedKeySz,
  7971. keyWrapOID, direction);
  7972. }
  7973. if (keySz <= 0) {
  7974. wc_PKCS7_KariFree(kari);
  7975. #ifdef WOLFSSL_SMALL_STACK
  7976. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7977. #endif
  7978. return keySz;
  7979. }
  7980. *decryptedKeySz = (word32)keySz;
  7981. wc_PKCS7_KariFree(kari);
  7982. #ifdef WOLFSSL_SMALL_STACK
  7983. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7984. #endif
  7985. #ifndef NO_PKCS7_STREAM
  7986. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7987. break;
  7988. }
  7989. #endif
  7990. ret = 0; /* success */
  7991. }
  7992. break;
  7993. default:
  7994. WOLFSSL_MSG("PKCS7 kari unknown state");
  7995. ret = BAD_FUNC_ARG;
  7996. }
  7997. (void)pkiMsg;
  7998. (void)pkiMsgSz;
  7999. return ret;
  8000. #else
  8001. (void)in;
  8002. (void)inSz;
  8003. (void)pkcs7;
  8004. (void)idx;
  8005. (void)decryptedKey;
  8006. (void)decryptedKeySz;
  8007. (void)recipFound;
  8008. return NOT_COMPILED_IN;
  8009. #endif /* HAVE_ECC */
  8010. }
  8011. /* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */
  8012. static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
  8013. word32 inSz, word32* idx, byte* decryptedKey,
  8014. word32* decryptedKeySz, int* recipFound)
  8015. {
  8016. word32 savedIdx;
  8017. int version, ret = 0, length;
  8018. byte* pkiMsg = in;
  8019. word32 pkiMsgSz = inSz;
  8020. byte tag;
  8021. #ifndef NO_PKCS7_STREAM
  8022. word32 tmpIdx;
  8023. long rc;
  8024. #endif
  8025. if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||
  8026. decryptedKey == NULL || decryptedKeySz == NULL ||
  8027. recipFound == NULL) {
  8028. return BAD_FUNC_ARG;
  8029. }
  8030. WOLFSSL_ENTER("wc_PKCS7_DecryptRecipientInfos");
  8031. #ifndef NO_PKCS7_STREAM
  8032. tmpIdx = *idx;
  8033. #endif
  8034. /* check if in the process of decrypting */
  8035. switch (pkcs7->state) {
  8036. case WC_PKCS7_DECRYPT_KTRI:
  8037. case WC_PKCS7_DECRYPT_KTRI_2:
  8038. case WC_PKCS7_DECRYPT_KTRI_3:
  8039. #ifndef NO_RSA
  8040. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8041. decryptedKey, decryptedKeySz, recipFound);
  8042. #else
  8043. return NOT_COMPILED_IN;
  8044. #endif
  8045. break;
  8046. case WC_PKCS7_DECRYPT_KARI:
  8047. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8048. decryptedKey, decryptedKeySz, recipFound);
  8049. break;
  8050. case WC_PKCS7_DECRYPT_KEKRI:
  8051. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8052. decryptedKey, decryptedKeySz, recipFound);
  8053. break;
  8054. case WC_PKCS7_DECRYPT_PWRI:
  8055. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8056. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8057. decryptedKey, decryptedKeySz, recipFound);
  8058. #else
  8059. return NOT_COMPILED_IN;
  8060. #endif
  8061. break;
  8062. case WC_PKCS7_DECRYPT_ORI:
  8063. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8064. decryptedKey, decryptedKeySz, recipFound);
  8065. break;
  8066. default:
  8067. /* not in decrypting state */
  8068. break;
  8069. }
  8070. if (ret < 0) {
  8071. return ret;
  8072. }
  8073. savedIdx = *idx;
  8074. #ifndef NO_PKCS7_STREAM
  8075. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz);
  8076. if (rc < 0) {
  8077. return (int)rc;
  8078. }
  8079. pkiMsgSz = (word32)rc;
  8080. if (pkcs7->stream->length > 0)
  8081. pkiMsg = pkcs7->stream->buffer;
  8082. #endif
  8083. /* when looking for next recipient, use first sequence and version to
  8084. * indicate there is another, if not, move on */
  8085. while(*recipFound == 0) {
  8086. /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
  8087. * last good saved one */
  8088. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) > 0) {
  8089. #ifndef NO_RSA
  8090. /* found ktri */
  8091. #ifndef NO_PKCS7_STREAM
  8092. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8093. break;
  8094. }
  8095. #endif
  8096. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI);
  8097. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8098. decryptedKey, decryptedKeySz,
  8099. recipFound);
  8100. if (ret != 0)
  8101. return ret;
  8102. #else
  8103. return NOT_COMPILED_IN;
  8104. #endif
  8105. }
  8106. else {
  8107. word32 localIdx;
  8108. /* kari is IMPLICIT[1] */
  8109. *idx = savedIdx;
  8110. localIdx = *idx;
  8111. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {
  8112. /* no room for recipient info */
  8113. break;
  8114. }
  8115. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  8116. (*idx)++;
  8117. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8118. return ASN_PARSE_E;
  8119. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8120. *idx = savedIdx;
  8121. break;
  8122. }
  8123. if (version != 3)
  8124. return ASN_VERSION_E;
  8125. /* found kari */
  8126. #ifndef NO_PKCS7_STREAM
  8127. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8128. break;
  8129. }
  8130. #endif
  8131. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KARI);
  8132. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8133. decryptedKey, decryptedKeySz,
  8134. recipFound);
  8135. if (ret != 0)
  8136. return ret;
  8137. /* kekri is IMPLICIT[2] */
  8138. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {
  8139. (*idx)++;
  8140. if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)
  8141. return ASN_PARSE_E;
  8142. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8143. *idx = savedIdx;
  8144. break;
  8145. }
  8146. if (version != 4)
  8147. return ASN_VERSION_E;
  8148. /* found kekri */
  8149. #ifndef NO_PKCS7_STREAM
  8150. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8151. break;
  8152. }
  8153. #endif
  8154. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KEKRI);
  8155. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8156. decryptedKey, decryptedKeySz,
  8157. recipFound);
  8158. if (ret != 0)
  8159. return ret;
  8160. /* pwri is IMPLICIT[3] */
  8161. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {
  8162. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8163. (*idx)++;
  8164. if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)
  8165. return ASN_PARSE_E;
  8166. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8167. *idx = savedIdx;
  8168. break;
  8169. }
  8170. if (version != 0)
  8171. return ASN_VERSION_E;
  8172. /* found pwri */
  8173. #ifndef NO_PKCS7_STREAM
  8174. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8175. break;
  8176. }
  8177. #endif
  8178. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_PWRI);
  8179. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8180. decryptedKey, decryptedKeySz,
  8181. recipFound);
  8182. if (ret != 0)
  8183. return ret;
  8184. #else
  8185. return NOT_COMPILED_IN;
  8186. #endif
  8187. /* ori is IMPLICIT[4] */
  8188. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {
  8189. (*idx)++;
  8190. /* found ori */
  8191. #ifndef NO_PKCS7_STREAM
  8192. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8193. break;
  8194. }
  8195. #endif
  8196. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_ORI);
  8197. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8198. decryptedKey, decryptedKeySz,
  8199. recipFound);
  8200. if (ret != 0)
  8201. return ret;
  8202. } else {
  8203. /* failed to find RecipientInfo, restore idx and continue */
  8204. *idx = savedIdx;
  8205. break;
  8206. }
  8207. }
  8208. /* update good idx */
  8209. savedIdx = *idx;
  8210. }
  8211. return ret;
  8212. }
  8213. /* Parse encoded EnvelopedData bundle up to RecipientInfo set.
  8214. *
  8215. * return size of RecipientInfo SET on success, negative upon error */
  8216. static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
  8217. word32 inSz, word32* idx,
  8218. int type)
  8219. {
  8220. int version = 0, length, ret = 0;
  8221. word32 contentType;
  8222. byte* pkiMsg = in;
  8223. word32 pkiMsgSz = inSz;
  8224. byte tag;
  8225. #ifndef NO_PKCS7_STREAM
  8226. word32 tmpIdx = 0;
  8227. long rc;
  8228. #endif
  8229. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 || idx == NULL)
  8230. return BAD_FUNC_ARG;
  8231. if ((type != ENVELOPED_DATA) && (type != AUTH_ENVELOPED_DATA) &&
  8232. pkcs7->contentOID != FIRMWARE_PKG_DATA)
  8233. return BAD_FUNC_ARG;
  8234. #ifndef NO_PKCS7_STREAM
  8235. if (pkcs7->stream == NULL) {
  8236. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  8237. return ret;
  8238. }
  8239. }
  8240. #endif
  8241. switch (pkcs7->state) {
  8242. case WC_PKCS7_INFOSET_START:
  8243. case WC_PKCS7_INFOSET_BER:
  8244. case WC_PKCS7_INFOSET_STAGE1:
  8245. case WC_PKCS7_INFOSET_STAGE2:
  8246. case WC_PKCS7_INFOSET_END:
  8247. break;
  8248. default:
  8249. WOLFSSL_MSG("Warning, setting PKCS7 info state to start");
  8250. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_START);
  8251. }
  8252. switch (pkcs7->state) {
  8253. case WC_PKCS7_INFOSET_START:
  8254. #ifndef NO_PKCS7_STREAM
  8255. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  8256. ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  8257. return ret;
  8258. }
  8259. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
  8260. if (rc < 0) {
  8261. ret = (int)rc;
  8262. break;
  8263. }
  8264. pkiMsgSz = (word32)rc;
  8265. #endif
  8266. /* read past ContentInfo, verify type is envelopedData */
  8267. if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8268. {
  8269. ret = ASN_PARSE_E;
  8270. }
  8271. if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) {
  8272. #ifdef ASN_BER_TO_DER
  8273. word32 len;
  8274. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER);
  8275. FALL_THROUGH;
  8276. /* full buffer is needed for conversion */
  8277. case WC_PKCS7_INFOSET_BER:
  8278. #ifndef NO_PKCS7_STREAM
  8279. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8280. pkcs7->stream->maxLen - pkcs7->stream->length,
  8281. &pkiMsg, idx)) != 0) {
  8282. return ret;
  8283. }
  8284. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  8285. in, inSz);
  8286. if (rc < 0) {
  8287. ret = (int)rc;
  8288. break;
  8289. }
  8290. pkiMsgSz = (word32)rc;
  8291. #endif
  8292. len = 0;
  8293. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  8294. if (ret != LENGTH_ONLY_E)
  8295. return ret;
  8296. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8297. if (pkcs7->der == NULL)
  8298. return MEMORY_E;
  8299. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  8300. if (ret < 0)
  8301. return ret;
  8302. pkiMsg = in = pkcs7->der;
  8303. pkiMsgSz = pkcs7->derSz = len;
  8304. *idx = 0;
  8305. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8306. return ASN_PARSE_E;
  8307. #else
  8308. return BER_INDEF_E;
  8309. #endif
  8310. }
  8311. #ifndef NO_PKCS7_STREAM
  8312. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8313. break;
  8314. }
  8315. #endif
  8316. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE1);
  8317. FALL_THROUGH;
  8318. case WC_PKCS7_INFOSET_STAGE1:
  8319. #ifndef NO_PKCS7_STREAM
  8320. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +
  8321. MAX_LENGTH_SZ + ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  8322. return ret;
  8323. }
  8324. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
  8325. #endif
  8326. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  8327. type == AUTH_ENVELOPED_DATA) {
  8328. if (ret == 0 && wc_GetContentType(pkiMsg, idx, &contentType,
  8329. pkiMsgSz) < 0)
  8330. ret = ASN_PARSE_E;
  8331. if (ret == 0) {
  8332. if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) {
  8333. WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
  8334. ret = PKCS7_OID_E;
  8335. } else if (type == AUTH_ENVELOPED_DATA &&
  8336. contentType != AUTH_ENVELOPED_DATA) {
  8337. WOLFSSL_MSG("PKCS#7 input not of type AuthEnvelopedData");
  8338. ret = PKCS7_OID_E;
  8339. }
  8340. }
  8341. if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)
  8342. ret = ASN_PARSE_E;
  8343. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
  8344. | 0))
  8345. ret = ASN_PARSE_E;
  8346. if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
  8347. NO_USER_CHECK) < 0)
  8348. ret = ASN_PARSE_E;
  8349. }
  8350. if (ret < 0)
  8351. break;
  8352. #ifndef NO_PKCS7_STREAM
  8353. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8354. break;
  8355. }
  8356. #endif
  8357. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE2);
  8358. FALL_THROUGH;
  8359. case WC_PKCS7_INFOSET_STAGE2:
  8360. #ifndef NO_PKCS7_STREAM
  8361. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  8362. MAX_VERSION_SZ, &pkiMsg, idx)) != 0) {
  8363. return ret;
  8364. }
  8365. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  8366. inSz);
  8367. if (rc < 0) {
  8368. ret = (int)rc;
  8369. break;
  8370. }
  8371. pkiMsgSz = (word32)rc;
  8372. #endif
  8373. /* remove EnvelopedData and version */
  8374. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  8375. type == AUTH_ENVELOPED_DATA) {
  8376. if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8377. ret = ASN_PARSE_E;
  8378. }
  8379. if (ret == 0 && GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  8380. ret = ASN_PARSE_E;
  8381. if (ret < 0)
  8382. break;
  8383. #ifndef NO_PKCS7_STREAM
  8384. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8385. break;
  8386. }
  8387. pkcs7->stream->varOne = version;
  8388. #endif
  8389. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_END);
  8390. FALL_THROUGH;
  8391. case WC_PKCS7_INFOSET_END:
  8392. #ifndef NO_PKCS7_STREAM
  8393. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8394. MAX_SET_SZ, &pkiMsg, idx)) != 0) {
  8395. return ret;
  8396. }
  8397. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  8398. inSz);
  8399. if (rc < 0) {
  8400. ret = (int)rc;
  8401. break;
  8402. }
  8403. pkiMsgSz = (word32)rc;
  8404. version = pkcs7->stream->varOne;
  8405. #endif
  8406. if (type == ENVELOPED_DATA) {
  8407. /* TODO :: make this more accurate */
  8408. if ((pkcs7->publicKeyOID == RSAk &&
  8409. (version != 0 && version != 2))
  8410. #ifdef HAVE_ECC
  8411. || (pkcs7->publicKeyOID == ECDSAk &&
  8412. (version != 0 && version != 2 && version != 3))
  8413. #endif
  8414. ) {
  8415. WOLFSSL_MSG("PKCS#7 envelopedData version incorrect");
  8416. ret = ASN_VERSION_E;
  8417. }
  8418. } else {
  8419. /* AuthEnvelopedData version MUST be 0 */
  8420. if (version != 0) {
  8421. WOLFSSL_MSG("PKCS#7 AuthEnvelopedData needs to be of version 0");
  8422. ret = ASN_VERSION_E;
  8423. }
  8424. }
  8425. /* remove RecipientInfo set, get length of set */
  8426. if (ret == 0 && GetSet(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8427. ret = ASN_PARSE_E;
  8428. if (ret < 0)
  8429. break;
  8430. #ifndef NO_PKCS7_STREAM
  8431. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8432. break;
  8433. }
  8434. #endif
  8435. if (ret == 0)
  8436. ret = length;
  8437. break;
  8438. default:
  8439. WOLFSSL_MSG("Bad PKCS7 info set state");
  8440. ret = BAD_FUNC_ARG;
  8441. break;
  8442. }
  8443. return ret;
  8444. }
  8445. /* Import secret/private key into a PKCS7 structure. Used for setting
  8446. * the secret key for decryption a EnvelopedData KEKRI RecipientInfo.
  8447. *
  8448. * Returns 0 on success, negative upon error */
  8449. WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz)
  8450. {
  8451. if (pkcs7 == NULL || key == NULL || keySz == 0)
  8452. return BAD_FUNC_ARG;
  8453. pkcs7->privateKey = key;
  8454. pkcs7->privateKeySz = keySz;
  8455. return 0;
  8456. }
  8457. /* append data to encrypted content cache in PKCS7 structure
  8458. * return 0 on success, negative on error */
  8459. static int PKCS7_CacheEncryptedContent(PKCS7* pkcs7, byte* in, word32 inSz)
  8460. {
  8461. byte* oldCache;
  8462. word32 oldCacheSz;
  8463. if (pkcs7 == NULL || in == NULL)
  8464. return BAD_FUNC_ARG;
  8465. /* save pointer to old cache */
  8466. oldCache = pkcs7->cachedEncryptedContent;
  8467. oldCacheSz = pkcs7->cachedEncryptedContentSz;
  8468. /* re-allocate new buffer to fit appended data */
  8469. pkcs7->cachedEncryptedContent = (byte*)XMALLOC(oldCacheSz + inSz,
  8470. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8471. if (pkcs7->cachedEncryptedContent == NULL) {
  8472. pkcs7->cachedEncryptedContentSz = 0;
  8473. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8474. return MEMORY_E;
  8475. }
  8476. if (oldCache != NULL) {
  8477. XMEMCPY(pkcs7->cachedEncryptedContent, oldCache, oldCacheSz);
  8478. }
  8479. XMEMCPY(pkcs7->cachedEncryptedContent + oldCacheSz, in, inSz);
  8480. pkcs7->cachedEncryptedContentSz += inSz;
  8481. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8482. return 0;
  8483. }
  8484. /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
  8485. WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
  8486. word32 inSz, byte* output,
  8487. word32 outputSz)
  8488. {
  8489. int recipFound = 0;
  8490. int ret, length = 0;
  8491. word32 idx = 0;
  8492. #ifndef NO_PKCS7_STREAM
  8493. word32 tmpIdx = 0;
  8494. long rc;
  8495. #endif
  8496. word32 contentType, encOID = 0;
  8497. word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  8498. int expBlockSz = 0, blockKeySz = 0;
  8499. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  8500. byte* tmpIv = tmpIvBuf;
  8501. byte* pkiMsg = in;
  8502. word32 pkiMsgSz = inSz;
  8503. byte* decryptedKey = NULL;
  8504. int encryptedContentTotalSz = 0;
  8505. int encryptedContentSz = 0;
  8506. byte padLen;
  8507. byte* encryptedContent = NULL;
  8508. int explicitOctet = 0;
  8509. word32 localIdx;
  8510. byte tag;
  8511. if (pkcs7 == NULL)
  8512. return BAD_FUNC_ARG;
  8513. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  8514. output == NULL || outputSz == 0)
  8515. return BAD_FUNC_ARG;
  8516. #ifndef NO_PKCS7_STREAM
  8517. (void)tmpIv; /* help out static analysis */
  8518. if (pkcs7->stream == NULL) {
  8519. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  8520. return ret;
  8521. }
  8522. }
  8523. #endif
  8524. switch (pkcs7->state) {
  8525. case WC_PKCS7_START:
  8526. case WC_PKCS7_INFOSET_START:
  8527. case WC_PKCS7_INFOSET_BER:
  8528. case WC_PKCS7_INFOSET_STAGE1:
  8529. case WC_PKCS7_INFOSET_STAGE2:
  8530. case WC_PKCS7_INFOSET_END:
  8531. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  8532. &idx, ENVELOPED_DATA);
  8533. if (ret < 0) {
  8534. break;
  8535. }
  8536. #ifdef ASN_BER_TO_DER
  8537. /* check if content was BER and has been converted to DER */
  8538. if (pkcs7->derSz > 0)
  8539. pkiMsg = in = pkcs7->der;
  8540. #endif
  8541. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  8542. DYNAMIC_TYPE_PKCS7);
  8543. if (decryptedKey == NULL)
  8544. return MEMORY_E;
  8545. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);
  8546. #ifndef NO_PKCS7_STREAM
  8547. tmpIdx = idx;
  8548. pkcs7->stream->aad = decryptedKey;
  8549. #endif
  8550. FALL_THROUGH;
  8551. case WC_PKCS7_ENV_2:
  8552. #ifndef NO_PKCS7_STREAM
  8553. /* store up enough buffer for initial info set decode */
  8554. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  8555. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  8556. return ret;
  8557. }
  8558. #endif
  8559. FALL_THROUGH;
  8560. case WC_PKCS7_DECRYPT_KTRI:
  8561. case WC_PKCS7_DECRYPT_KTRI_2:
  8562. case WC_PKCS7_DECRYPT_KTRI_3:
  8563. case WC_PKCS7_DECRYPT_KARI:
  8564. case WC_PKCS7_DECRYPT_KEKRI:
  8565. case WC_PKCS7_DECRYPT_PWRI:
  8566. case WC_PKCS7_DECRYPT_ORI:
  8567. #ifndef NO_PKCS7_STREAM
  8568. decryptedKey = pkcs7->stream->aad;
  8569. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  8570. #endif
  8571. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  8572. decryptedKey, &decryptedKeySz,
  8573. &recipFound);
  8574. if (ret == 0 && recipFound == 0) {
  8575. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  8576. ret = PKCS7_RECIP_E;
  8577. }
  8578. if (ret != 0)
  8579. break;
  8580. #ifndef NO_PKCS7_STREAM
  8581. tmpIdx = idx;
  8582. pkcs7->stream->aadSz = decryptedKeySz;
  8583. #endif
  8584. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
  8585. FALL_THROUGH;
  8586. case WC_PKCS7_ENV_3:
  8587. #ifndef NO_PKCS7_STREAM
  8588. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  8589. MAX_VERSION_SZ + ASN_TAG_SZ +
  8590. MAX_LENGTH_SZ, &pkiMsg, &idx))
  8591. != 0) {
  8592. return ret;
  8593. }
  8594. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  8595. inSz);
  8596. if (rc < 0) {
  8597. ret = (int)rc;
  8598. break;
  8599. }
  8600. pkiMsgSz = (word32)rc;
  8601. #else
  8602. ret = 0;
  8603. #endif
  8604. /* remove EncryptedContentInfo */
  8605. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  8606. ret = ASN_PARSE_E;
  8607. }
  8608. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  8609. pkiMsgSz) < 0) {
  8610. ret = ASN_PARSE_E;
  8611. }
  8612. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  8613. pkiMsgSz) < 0) {
  8614. ret = ASN_PARSE_E;
  8615. }
  8616. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  8617. if (ret == 0 && blockKeySz < 0) {
  8618. ret = blockKeySz;
  8619. }
  8620. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  8621. if (ret == 0 && expBlockSz < 0) {
  8622. ret = expBlockSz;
  8623. }
  8624. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  8625. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {
  8626. ret = ASN_PARSE_E;
  8627. }
  8628. if (ret == 0 && tag != ASN_OCTET_STRING) {
  8629. ret = ASN_PARSE_E;
  8630. }
  8631. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  8632. ret = ASN_PARSE_E;
  8633. }
  8634. if (ret == 0 && length != expBlockSz) {
  8635. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  8636. ret = ASN_PARSE_E;
  8637. }
  8638. if (ret != 0)
  8639. break;
  8640. #ifndef NO_PKCS7_STREAM
  8641. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  8642. break;
  8643. }
  8644. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length);
  8645. pkcs7->stream->contentSz = blockKeySz;
  8646. pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ +
  8647. ASN_TAG_SZ + ASN_TAG_SZ;
  8648. #endif
  8649. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4);
  8650. FALL_THROUGH;
  8651. case WC_PKCS7_ENV_4:
  8652. #ifndef NO_PKCS7_STREAM
  8653. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8654. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  8655. return ret;
  8656. }
  8657. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  8658. inSz);
  8659. if (rc < 0) {
  8660. ret = (int)rc;
  8661. break;
  8662. }
  8663. pkiMsgSz = (word32)rc;
  8664. wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length);
  8665. tmpIv = pkcs7->stream->tmpIv;
  8666. if (tmpIv == NULL) {
  8667. /* check added to help out static analysis tool */
  8668. ret = MEMORY_E;
  8669. break;
  8670. }
  8671. #else
  8672. ret = 0;
  8673. #endif
  8674. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  8675. idx += length;
  8676. explicitOctet = 0;
  8677. localIdx = idx;
  8678. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  8679. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  8680. explicitOctet = 1;
  8681. }
  8682. /* read encryptedContent, cont[0] */
  8683. if (tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  8684. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  8685. ret = ASN_PARSE_E;
  8686. }
  8687. idx++;
  8688. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz,
  8689. pkiMsgSz) <= 0) {
  8690. ret = ASN_PARSE_E;
  8691. }
  8692. if (ret != 0)
  8693. break;
  8694. #ifndef NO_PKCS7_STREAM
  8695. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  8696. break;
  8697. }
  8698. pkcs7->stream->expected = encryptedContentTotalSz;
  8699. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0);
  8700. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet);
  8701. #endif
  8702. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5);
  8703. FALL_THROUGH;
  8704. case WC_PKCS7_ENV_5:
  8705. #ifndef NO_PKCS7_STREAM
  8706. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8707. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  8708. return ret;
  8709. }
  8710. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet);
  8711. tmpIv = pkcs7->stream->tmpIv;
  8712. encryptedContentTotalSz = pkcs7->stream->expected;
  8713. /* restore decrypted key */
  8714. decryptedKey = pkcs7->stream->aad;
  8715. decryptedKeySz = pkcs7->stream->aadSz;
  8716. blockKeySz = pkcs7->stream->contentSz;
  8717. #else
  8718. ret = 0;
  8719. #endif
  8720. if (explicitOctet) {
  8721. /* encrypted content may be fragmented into multiple
  8722. * consecutive OCTET STRINGs, if so loop through
  8723. * collecting and caching encrypted content bytes */
  8724. localIdx = idx;
  8725. while (idx < (localIdx + encryptedContentTotalSz)) {
  8726. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  8727. ret = ASN_PARSE_E;
  8728. }
  8729. if (ret == 0 && (tag != ASN_OCTET_STRING)) {
  8730. ret = ASN_PARSE_E;
  8731. }
  8732. if (ret == 0 && GetLength(pkiMsg, &idx,
  8733. &encryptedContentSz, pkiMsgSz) <= 0) {
  8734. ret = ASN_PARSE_E;
  8735. }
  8736. if (ret == 0) {
  8737. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  8738. encryptedContentSz);
  8739. }
  8740. if (ret != 0) {
  8741. break;
  8742. }
  8743. /* advance idx past encrypted content */
  8744. idx += encryptedContentSz;
  8745. }
  8746. if (ret != 0) {
  8747. break;
  8748. }
  8749. } else {
  8750. /* cache encrypted content, no OCTET STRING */
  8751. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  8752. encryptedContentTotalSz);
  8753. if (ret != 0) {
  8754. break;
  8755. }
  8756. idx += encryptedContentTotalSz;
  8757. }
  8758. /* use cached content */
  8759. encryptedContent = pkcs7->cachedEncryptedContent;
  8760. encryptedContentSz = pkcs7->cachedEncryptedContentSz;
  8761. /* decrypt encryptedContent */
  8762. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  8763. blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,
  8764. encryptedContent, encryptedContentSz, encryptedContent);
  8765. if (ret != 0) {
  8766. break;
  8767. }
  8768. padLen = encryptedContent[encryptedContentSz-1];
  8769. /* copy plaintext to output */
  8770. if (padLen > encryptedContentSz ||
  8771. (word32)(encryptedContentSz - padLen) > outputSz) {
  8772. ret = BUFFER_E;
  8773. break;
  8774. }
  8775. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  8776. /* free memory, zero out keys */
  8777. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  8778. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8779. if (pkcs7->cachedEncryptedContent != NULL) {
  8780. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  8781. DYNAMIC_TYPE_PKCS7);
  8782. pkcs7->cachedEncryptedContent = NULL;
  8783. pkcs7->cachedEncryptedContentSz = 0;
  8784. }
  8785. ret = encryptedContentSz - padLen;
  8786. #ifndef NO_PKCS7_STREAM
  8787. pkcs7->stream->aad = NULL;
  8788. pkcs7->stream->aadSz = 0;
  8789. wc_PKCS7_ResetStream(pkcs7);
  8790. #endif
  8791. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  8792. break;
  8793. default:
  8794. WOLFSSL_MSG("PKCS#7 unknown decode enveloped state");
  8795. ret = BAD_FUNC_ARG;
  8796. }
  8797. #ifndef NO_PKCS7_STREAM
  8798. if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {
  8799. wc_PKCS7_ResetStream(pkcs7);
  8800. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  8801. if (pkcs7->cachedEncryptedContent != NULL) {
  8802. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  8803. DYNAMIC_TYPE_PKCS7);
  8804. pkcs7->cachedEncryptedContent = NULL;
  8805. pkcs7->cachedEncryptedContentSz = 0;
  8806. }
  8807. }
  8808. #else
  8809. if (decryptedKey != NULL && ret < 0) {
  8810. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  8811. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8812. }
  8813. if (pkcs7->cachedEncryptedContent != NULL && ret < 0) {
  8814. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8815. pkcs7->cachedEncryptedContent = NULL;
  8816. pkcs7->cachedEncryptedContentSz = 0;
  8817. }
  8818. #endif
  8819. return ret;
  8820. }
  8821. /* build PKCS#7 authEnvelopedData content type, return enveloped size */
  8822. int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
  8823. word32 outputSz)
  8824. {
  8825. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  8826. int ret, idx = 0;
  8827. int totalSz, encryptedOutSz;
  8828. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  8829. byte contentInfoSeq[MAX_SEQ_SZ];
  8830. byte outerContentType[MAX_ALGO_SZ];
  8831. byte outerContent[MAX_SEQ_SZ];
  8832. int envDataSeqSz, verSz;
  8833. byte envDataSeq[MAX_SEQ_SZ];
  8834. byte ver[MAX_VERSION_SZ];
  8835. WC_RNG rng;
  8836. int blockSz, blockKeySz;
  8837. byte* encryptedContent;
  8838. Pkcs7EncodedRecip* tmpRecip = NULL;
  8839. int recipSz, recipSetSz;
  8840. byte recipSet[MAX_SET_SZ];
  8841. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  8842. int contentEncAlgoSz, nonceOctetStringSz, macOctetStringSz;
  8843. byte encContentSeq[MAX_SEQ_SZ];
  8844. byte contentType[MAX_ALGO_SZ];
  8845. byte contentEncAlgo[MAX_ALGO_SZ];
  8846. byte nonceOctetString[MAX_OCTET_STR_SZ];
  8847. byte encContentOctet[MAX_OCTET_STR_SZ];
  8848. byte macOctetString[MAX_OCTET_STR_SZ];
  8849. byte authTag[AES_BLOCK_SIZE];
  8850. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  8851. byte macInt[MAX_VERSION_SZ];
  8852. word32 nonceSz = 0, macIntSz = 0;
  8853. /* authAttribs */
  8854. byte* flatAuthAttribs = NULL;
  8855. byte authAttribSet[MAX_SET_SZ];
  8856. EncodedAttrib authAttribs[MAX_AUTH_ATTRIBS_SZ];
  8857. word32 authAttribsSz = 0, authAttribsCount = 0;
  8858. word32 authAttribsSetSz = 0;
  8859. byte* aadBuffer = NULL;
  8860. word32 aadBufferSz = 0;
  8861. byte authAttribAadSet[MAX_SET_SZ];
  8862. word32 authAttribsAadSetSz = 0;
  8863. /* unauthAttribs */
  8864. byte* flatUnauthAttribs = NULL;
  8865. byte unauthAttribSet[MAX_SET_SZ];
  8866. EncodedAttrib unauthAttribs[MAX_UNAUTH_ATTRIBS_SZ];
  8867. word32 unauthAttribsSz = 0, unauthAttribsCount = 0;
  8868. word32 unauthAttribsSetSz = 0;
  8869. PKCS7Attrib contentTypeAttrib;
  8870. byte contentTypeValue[MAX_OID_SZ];
  8871. /* contentType OID (1.2.840.113549.1.9.3) */
  8872. const byte contentTypeOid[] =
  8873. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  8874. 0x09, 0x03 };
  8875. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  8876. return BAD_FUNC_ARG;
  8877. if (output == NULL || outputSz == 0)
  8878. return BAD_FUNC_ARG;
  8879. switch (pkcs7->encryptOID) {
  8880. #ifdef HAVE_AESGCM
  8881. #ifdef WOLFSSL_AES_128
  8882. case AES128GCMb:
  8883. break;
  8884. #endif
  8885. #ifdef WOLFSSL_AES_192
  8886. case AES192GCMb:
  8887. break;
  8888. #endif
  8889. #ifdef WOLFSSL_AES_256
  8890. case AES256GCMb:
  8891. break;
  8892. #endif
  8893. #endif
  8894. #ifdef HAVE_AESCCM
  8895. #ifdef WOLFSSL_AES_128
  8896. case AES128CCMb:
  8897. break;
  8898. #endif
  8899. #ifdef WOLFSSL_AES_192
  8900. case AES192CCMb:
  8901. break;
  8902. #endif
  8903. #ifdef WOLFSSL_AES_256
  8904. case AES256CCMb:
  8905. break;
  8906. #endif
  8907. #endif
  8908. default:
  8909. WOLFSSL_MSG("CMS AuthEnvelopedData must use AES-GCM or AES-CCM");
  8910. return BAD_FUNC_ARG;
  8911. }
  8912. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  8913. if (blockKeySz < 0)
  8914. return blockKeySz;
  8915. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  8916. if (blockSz < 0)
  8917. return blockSz;
  8918. /* outer content type */
  8919. ret = wc_SetContentType(AUTH_ENVELOPED_DATA, outerContentType,
  8920. sizeof(outerContentType));
  8921. if (ret < 0)
  8922. return ret;
  8923. outerContentTypeSz = ret;
  8924. /* version, defined as 0 in RFC 5083 */
  8925. verSz = SetMyVersion(0, ver, 0);
  8926. /* generate random content encryption key */
  8927. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  8928. if (ret != 0) {
  8929. return ret;
  8930. }
  8931. /* build RecipientInfo, only if user manually set singleCert and size */
  8932. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  8933. switch (pkcs7->publicKeyOID) {
  8934. #ifndef NO_RSA
  8935. case RSAk:
  8936. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  8937. pkcs7->singleCertSz, 0);
  8938. break;
  8939. #endif
  8940. #ifdef HAVE_ECC
  8941. case ECDSAk:
  8942. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  8943. pkcs7->singleCertSz,
  8944. pkcs7->keyWrapOID,
  8945. pkcs7->keyAgreeOID, pkcs7->ukm,
  8946. pkcs7->ukmSz, 0);
  8947. break;
  8948. #endif
  8949. default:
  8950. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  8951. return BAD_FUNC_ARG;
  8952. };
  8953. if (ret < 0) {
  8954. WOLFSSL_MSG("Failed to create RecipientInfo");
  8955. return ret;
  8956. }
  8957. }
  8958. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  8959. if (recipSz < 0) {
  8960. return ret;
  8961. } else if (recipSz == 0) {
  8962. WOLFSSL_MSG("You must add at least one CMS recipient");
  8963. return PKCS7_RECIP_E;
  8964. }
  8965. recipSetSz = SetSet(recipSz, recipSet);
  8966. /* generate random nonce and IV for encryption */
  8967. switch (pkcs7->encryptOID) {
  8968. #ifdef HAVE_AESGCM
  8969. #ifdef WOLFSSL_AES_128
  8970. case AES128GCMb:
  8971. FALL_THROUGH;
  8972. #endif
  8973. #ifdef WOLFSSL_AES_192
  8974. case AES192GCMb:
  8975. FALL_THROUGH;
  8976. #endif
  8977. #ifdef WOLFSSL_AES_256
  8978. case AES256GCMb:
  8979. #endif
  8980. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  8981. defined(WOLFSSL_AES_256)
  8982. /* GCM nonce is GCM_NONCE_MID_SZ (12) */
  8983. nonceSz = GCM_NONCE_MID_SZ;
  8984. break;
  8985. #endif
  8986. #endif /* HAVE_AESGCM */
  8987. #ifdef HAVE_AESCCM
  8988. #ifdef WOLFSSL_AES_128
  8989. case AES128CCMb:
  8990. FALL_THROUGH;
  8991. #endif
  8992. #ifdef WOLFSSL_AES_192
  8993. case AES192CCMb:
  8994. FALL_THROUGH;
  8995. #endif
  8996. #ifdef WOLFSSL_AES_256
  8997. case AES256CCMb:
  8998. #endif
  8999. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  9000. defined(WOLFSSL_AES_256)
  9001. /* CCM nonce is CCM_NONCE_MIN_SZ (7) */
  9002. nonceSz = CCM_NONCE_MIN_SZ;
  9003. break;
  9004. #endif
  9005. #endif /* HAVE_AESCCM */
  9006. }
  9007. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  9008. if (ret != 0)
  9009. return ret;
  9010. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, nonce, nonceSz);
  9011. wc_FreeRng(&rng);
  9012. if (ret != 0) {
  9013. return ret;
  9014. }
  9015. /* authAttribs: add contentType attrib if needed */
  9016. if (pkcs7->contentOID != DATA) {
  9017. /* if type is not id-data, contentType attribute MUST be added */
  9018. contentTypeAttrib.oid = contentTypeOid;
  9019. contentTypeAttrib.oidSz = sizeof(contentTypeOid);
  9020. /* try to set from contentOID first, known types */
  9021. ret = wc_SetContentType(pkcs7->contentOID, contentTypeValue,
  9022. sizeof(contentTypeValue));
  9023. if (ret > 0) {
  9024. contentTypeAttrib.value = contentTypeValue;
  9025. contentTypeAttrib.valueSz = ret;
  9026. /* otherwise, try to set from custom content type */
  9027. } else {
  9028. if (pkcs7->contentTypeSz == 0) {
  9029. WOLFSSL_MSG("CMS pkcs7->contentType must be set if "
  9030. "contentOID is not");
  9031. return BAD_FUNC_ARG;
  9032. }
  9033. contentTypeAttrib.value = pkcs7->contentType;
  9034. contentTypeAttrib.valueSz = pkcs7->contentTypeSz;
  9035. }
  9036. authAttribsSz += EncodeAttributes(authAttribs, 1,
  9037. &contentTypeAttrib, 1);
  9038. authAttribsCount += 1;
  9039. }
  9040. /* authAttribs: add in user authenticated attributes */
  9041. if (pkcs7->authAttribs != NULL && pkcs7->authAttribsSz > 0) {
  9042. authAttribsSz += EncodeAttributes(authAttribs + authAttribsCount,
  9043. MAX_AUTH_ATTRIBS_SZ - authAttribsCount,
  9044. pkcs7->authAttribs,
  9045. pkcs7->authAttribsSz);
  9046. authAttribsCount += pkcs7->authAttribsSz;
  9047. }
  9048. /* authAttribs: flatten authAttribs */
  9049. if (authAttribsSz > 0 && authAttribsCount > 0) {
  9050. flatAuthAttribs = (byte*)XMALLOC(authAttribsSz, pkcs7->heap,
  9051. DYNAMIC_TYPE_PKCS7);
  9052. if (flatAuthAttribs == NULL) {
  9053. return MEMORY_E;
  9054. }
  9055. FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,
  9056. authAttribsCount);
  9057. authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,
  9058. authAttribSet);
  9059. /* From RFC5083, "For the purpose of constructing the AAD, the
  9060. * IMPLICIT [1] tag in the authAttrs field is not used for the
  9061. * DER encoding: rather a universal SET OF tag is used. */
  9062. authAttribsAadSetSz = SetSet(authAttribsSz, authAttribAadSet);
  9063. /* allocate temp buffer to hold alternate attrib encoding for aad */
  9064. aadBuffer = (byte*)XMALLOC(authAttribsSz + authAttribsAadSetSz,
  9065. pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9066. if (aadBuffer == NULL) {
  9067. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9068. return MEMORY_E;
  9069. }
  9070. /* build up alternate attrib encoding for aad */
  9071. aadBufferSz = 0;
  9072. XMEMCPY(aadBuffer + aadBufferSz, authAttribAadSet, authAttribsAadSetSz);
  9073. aadBufferSz += authAttribsAadSetSz;
  9074. XMEMCPY(aadBuffer + aadBufferSz, flatAuthAttribs, authAttribsSz);
  9075. aadBufferSz += authAttribsSz;
  9076. }
  9077. /* build up unauthenticated attributes (unauthAttrs) */
  9078. if (pkcs7->unauthAttribsSz > 0) {
  9079. unauthAttribsSz = EncodeAttributes(unauthAttribs + unauthAttribsCount,
  9080. MAX_UNAUTH_ATTRIBS_SZ - unauthAttribsCount,
  9081. pkcs7->unauthAttribs,
  9082. pkcs7->unauthAttribsSz);
  9083. unauthAttribsCount = pkcs7->unauthAttribsSz;
  9084. flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap,
  9085. DYNAMIC_TYPE_PKCS7);
  9086. if (flatUnauthAttribs == NULL) {
  9087. if (aadBuffer)
  9088. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9089. if (flatAuthAttribs)
  9090. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9091. return MEMORY_E;
  9092. }
  9093. FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,
  9094. unauthAttribsCount);
  9095. unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,
  9096. unauthAttribSet);
  9097. }
  9098. /* allocate encrypted content buffer */
  9099. encryptedOutSz = pkcs7->contentSz;
  9100. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  9101. DYNAMIC_TYPE_PKCS7);
  9102. if (encryptedContent == NULL) {
  9103. if (aadBuffer)
  9104. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9105. if (flatUnauthAttribs)
  9106. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9107. if (flatAuthAttribs)
  9108. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9109. return MEMORY_E;
  9110. }
  9111. /* encrypt content */
  9112. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  9113. pkcs7->cekSz, nonce, nonceSz, aadBuffer, aadBufferSz, authTag,
  9114. sizeof(authTag), pkcs7->content, encryptedOutSz, encryptedContent);
  9115. if (aadBuffer) {
  9116. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9117. aadBuffer = NULL;
  9118. }
  9119. if (ret != 0) {
  9120. if (flatUnauthAttribs)
  9121. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9122. if (flatAuthAttribs)
  9123. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9124. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9125. return ret;
  9126. }
  9127. /* EncryptedContentInfo */
  9128. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  9129. sizeof(contentType));
  9130. if (ret < 0) {
  9131. if (flatUnauthAttribs)
  9132. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9133. if (flatAuthAttribs)
  9134. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9135. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9136. return ret;
  9137. }
  9138. contentTypeSz = ret;
  9139. /* put together nonce OCTET STRING */
  9140. nonceOctetStringSz = SetOctetString(nonceSz, nonceOctetString);
  9141. /* put together aes-ICVlen INTEGER */
  9142. macIntSz = SetMyVersion(sizeof(authTag), macInt, 0);
  9143. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  9144. * adding (nonceOctetStringSz + blockSz + macIntSz) for nonce OCTET STRING
  9145. * and tag size */
  9146. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  9147. oidBlkType, nonceOctetStringSz + nonceSz +
  9148. macIntSz);
  9149. if (contentEncAlgoSz == 0) {
  9150. if (flatUnauthAttribs)
  9151. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9152. if (flatAuthAttribs)
  9153. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9154. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9155. return BAD_FUNC_ARG;
  9156. }
  9157. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  9158. encContentOctet);
  9159. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  9160. nonceOctetStringSz + nonceSz + macIntSz +
  9161. encContentOctetSz + encryptedOutSz,
  9162. encContentSeq);
  9163. macOctetStringSz = SetOctetString(sizeof(authTag), macOctetString);
  9164. /* keep track of sizes for outer wrapper layering */
  9165. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  9166. contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz +
  9167. encContentOctetSz + encryptedOutSz + authAttribsSz +
  9168. authAttribsSetSz + macOctetStringSz + sizeof(authTag) +
  9169. unauthAttribsSz + unauthAttribsSetSz;
  9170. /* EnvelopedData */
  9171. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  9172. totalSz += envDataSeqSz;
  9173. /* outer content */
  9174. outerContentSz = SetExplicit(0, totalSz, outerContent);
  9175. totalSz += outerContentTypeSz;
  9176. totalSz += outerContentSz;
  9177. /* ContentInfo */
  9178. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  9179. totalSz += contentInfoSeqSz;
  9180. if (totalSz > (int)outputSz) {
  9181. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  9182. if (flatUnauthAttribs)
  9183. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9184. if (flatAuthAttribs)
  9185. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9186. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9187. return BUFFER_E;
  9188. }
  9189. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  9190. idx += contentInfoSeqSz;
  9191. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  9192. idx += outerContentTypeSz;
  9193. XMEMCPY(output + idx, outerContent, outerContentSz);
  9194. idx += outerContentSz;
  9195. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  9196. idx += envDataSeqSz;
  9197. XMEMCPY(output + idx, ver, verSz);
  9198. idx += verSz;
  9199. XMEMCPY(output + idx, recipSet, recipSetSz);
  9200. idx += recipSetSz;
  9201. /* copy in recipients from list */
  9202. tmpRecip = pkcs7->recipList;
  9203. while (tmpRecip != NULL) {
  9204. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  9205. idx += tmpRecip->recipSz;
  9206. tmpRecip = tmpRecip->next;
  9207. }
  9208. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9209. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  9210. idx += encContentSeqSz;
  9211. XMEMCPY(output + idx, contentType, contentTypeSz);
  9212. idx += contentTypeSz;
  9213. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  9214. idx += contentEncAlgoSz;
  9215. XMEMCPY(output + idx, nonceOctetString, nonceOctetStringSz);
  9216. idx += nonceOctetStringSz;
  9217. XMEMCPY(output + idx, nonce, nonceSz);
  9218. idx += nonceSz;
  9219. XMEMCPY(output + idx, macInt, macIntSz);
  9220. idx += macIntSz;
  9221. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  9222. idx += encContentOctetSz;
  9223. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  9224. idx += encryptedOutSz;
  9225. /* authenticated attributes */
  9226. if (flatAuthAttribs && authAttribsSz > 0) {
  9227. XMEMCPY(output + idx, authAttribSet, authAttribsSetSz);
  9228. idx += authAttribsSetSz;
  9229. XMEMCPY(output + idx, flatAuthAttribs, authAttribsSz);
  9230. idx += authAttribsSz;
  9231. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9232. }
  9233. XMEMCPY(output + idx, macOctetString, macOctetStringSz);
  9234. idx += macOctetStringSz;
  9235. XMEMCPY(output + idx, authTag, sizeof(authTag));
  9236. idx += sizeof(authTag);
  9237. /* unauthenticated attributes */
  9238. if (unauthAttribsSz > 0) {
  9239. XMEMCPY(output + idx, unauthAttribSet, unauthAttribsSetSz);
  9240. idx += unauthAttribsSetSz;
  9241. XMEMCPY(output + idx, flatUnauthAttribs, unauthAttribsSz);
  9242. idx += unauthAttribsSz;
  9243. }
  9244. if (flatUnauthAttribs != NULL) {
  9245. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9246. }
  9247. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9248. return idx;
  9249. #else
  9250. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  9251. (void)pkcs7;
  9252. (void)output;
  9253. (void)outputSz;
  9254. return NOT_COMPILED_IN;
  9255. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  9256. }
  9257. /* unwrap and decrypt PKCS#7 AuthEnvelopedData object, return decoded size */
  9258. WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
  9259. word32 inSz, byte* output,
  9260. word32 outputSz)
  9261. {
  9262. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  9263. int recipFound = 0;
  9264. int ret = 0, length;
  9265. word32 idx = 0;
  9266. #ifndef NO_PKCS7_STREAM
  9267. word32 tmpIdx = 0;
  9268. long rc;
  9269. #endif
  9270. word32 contentType, encOID = 0;
  9271. word32 decryptedKeySz = 0;
  9272. byte* pkiMsg = in;
  9273. word32 pkiMsgSz = inSz;
  9274. int expBlockSz = 0, blockKeySz = 0;
  9275. byte authTag[AES_BLOCK_SIZE];
  9276. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  9277. int nonceSz = 0, authTagSz = 0, macSz = 0;
  9278. #ifdef WOLFSSL_SMALL_STACK
  9279. byte* decryptedKey = NULL;
  9280. #else
  9281. byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
  9282. #endif
  9283. int encryptedContentSz = 0;
  9284. byte* encryptedContent = NULL;
  9285. int explicitOctet = 0;
  9286. byte authAttribSetByte = 0;
  9287. byte* encodedAttribs = NULL;
  9288. word32 encodedAttribIdx = 0, encodedAttribSz = 0;
  9289. byte* authAttrib = NULL;
  9290. int authAttribSz = 0;
  9291. word32 localIdx;
  9292. byte tag;
  9293. if (pkcs7 == NULL)
  9294. return BAD_FUNC_ARG;
  9295. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  9296. output == NULL || outputSz == 0)
  9297. return BAD_FUNC_ARG;
  9298. #ifndef NO_PKCS7_STREAM
  9299. if (pkcs7->stream == NULL) {
  9300. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  9301. return ret;
  9302. }
  9303. }
  9304. #endif
  9305. switch (pkcs7->state) {
  9306. case WC_PKCS7_START:
  9307. case WC_PKCS7_INFOSET_START:
  9308. case WC_PKCS7_INFOSET_STAGE1:
  9309. case WC_PKCS7_INFOSET_STAGE2:
  9310. case WC_PKCS7_INFOSET_END:
  9311. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  9312. &idx, AUTH_ENVELOPED_DATA);
  9313. if (ret < 0)
  9314. break;
  9315. #ifndef NO_PKCS7_STREAM
  9316. tmpIdx = idx;
  9317. #endif
  9318. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_2);
  9319. FALL_THROUGH;
  9320. case WC_PKCS7_AUTHENV_2:
  9321. #ifndef NO_PKCS7_STREAM
  9322. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9323. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  9324. break;
  9325. }
  9326. #endif
  9327. #ifdef WOLFSSL_SMALL_STACK
  9328. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  9329. DYNAMIC_TYPE_PKCS7);
  9330. if (decryptedKey == NULL) {
  9331. ret = MEMORY_E;
  9332. break;
  9333. }
  9334. #ifndef NO_PKCS7_STREAM
  9335. pkcs7->stream->key = decryptedKey;
  9336. #endif
  9337. #endif
  9338. FALL_THROUGH;
  9339. case WC_PKCS7_DECRYPT_KTRI:
  9340. case WC_PKCS7_DECRYPT_KTRI_2:
  9341. case WC_PKCS7_DECRYPT_KTRI_3:
  9342. case WC_PKCS7_DECRYPT_KARI:
  9343. case WC_PKCS7_DECRYPT_KEKRI:
  9344. case WC_PKCS7_DECRYPT_PWRI:
  9345. case WC_PKCS7_DECRYPT_ORI:
  9346. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9347. #ifdef WOLFSSL_SMALL_STACK
  9348. #ifndef NO_PKCS7_STREAM
  9349. decryptedKey = pkcs7->stream->key;
  9350. #endif
  9351. #endif
  9352. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  9353. decryptedKey, &decryptedKeySz,
  9354. &recipFound);
  9355. if (ret != 0) {
  9356. break;
  9357. }
  9358. if (recipFound == 0) {
  9359. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  9360. ret = PKCS7_RECIP_E;
  9361. break;
  9362. }
  9363. #ifndef NO_PKCS7_STREAM
  9364. tmpIdx = idx;
  9365. #endif
  9366. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3);
  9367. FALL_THROUGH;
  9368. case WC_PKCS7_AUTHENV_3:
  9369. #ifndef NO_PKCS7_STREAM
  9370. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  9371. MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ,
  9372. &pkiMsg, &idx)) != 0) {
  9373. break;
  9374. }
  9375. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  9376. in, inSz);
  9377. if (rc < 0) {
  9378. ret = (int)rc;
  9379. break;
  9380. }
  9381. pkiMsgSz = (word32)rc;
  9382. #endif
  9383. /* remove EncryptedContentInfo */
  9384. if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  9385. ret = ASN_PARSE_E;
  9386. }
  9387. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  9388. pkiMsgSz) < 0) {
  9389. ret = ASN_PARSE_E;
  9390. }
  9391. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  9392. pkiMsgSz) < 0) {
  9393. ret = ASN_PARSE_E;
  9394. }
  9395. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  9396. if (ret == 0 && blockKeySz < 0) {
  9397. ret = blockKeySz;
  9398. }
  9399. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  9400. if (ret == 0 && expBlockSz < 0) {
  9401. ret = expBlockSz;
  9402. }
  9403. /* get nonce, stored in OPTIONAL parameter of AlgoID */
  9404. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9405. ret = ASN_PARSE_E;
  9406. }
  9407. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9408. ret = ASN_PARSE_E;
  9409. }
  9410. if (ret < 0)
  9411. break;
  9412. #ifndef NO_PKCS7_STREAM
  9413. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9414. break;
  9415. }
  9416. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0);
  9417. #endif
  9418. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4);
  9419. FALL_THROUGH;
  9420. case WC_PKCS7_AUTHENV_4:
  9421. #ifndef NO_PKCS7_STREAM
  9422. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9423. MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ,
  9424. &pkiMsg, &idx)) != 0) {
  9425. break;
  9426. }
  9427. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  9428. inSz);
  9429. if (rc < 0) {
  9430. ret = (int)rc;
  9431. break;
  9432. }
  9433. pkiMsgSz = (word32)rc;
  9434. #endif
  9435. if (ret == 0 && GetLength(pkiMsg, &idx, &nonceSz, pkiMsgSz) < 0) {
  9436. ret = ASN_PARSE_E;
  9437. }
  9438. if (ret == 0 && nonceSz > (int)sizeof(nonce)) {
  9439. WOLFSSL_MSG("AuthEnvelopedData nonce too large for buffer");
  9440. ret = ASN_PARSE_E;
  9441. }
  9442. if (ret == 0) {
  9443. XMEMCPY(nonce, &pkiMsg[idx], nonceSz);
  9444. idx += nonceSz;
  9445. }
  9446. /* get mac size, also stored in OPTIONAL parameter of AlgoID */
  9447. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &macSz, pkiMsgSz) < 0) {
  9448. ret = ASN_PARSE_E;
  9449. }
  9450. if (ret == 0) {
  9451. explicitOctet = 0;
  9452. localIdx = idx;
  9453. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  9454. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
  9455. explicitOctet = 1;
  9456. /* read encryptedContent, cont[0] */
  9457. ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);
  9458. }
  9459. if (ret == 0 &&
  9460. tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  9461. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9462. ret = ASN_PARSE_E;
  9463. }
  9464. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  9465. pkiMsgSz) <= 0) {
  9466. ret = ASN_PARSE_E;
  9467. }
  9468. if (explicitOctet) {
  9469. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9470. ret = ASN_PARSE_E;
  9471. }
  9472. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9473. ret = ASN_PARSE_E;
  9474. }
  9475. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  9476. pkiMsgSz) <= 0) {
  9477. ret = ASN_PARSE_E;
  9478. }
  9479. }
  9480. if (ret < 0)
  9481. break;
  9482. #ifndef NO_PKCS7_STREAM
  9483. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9484. break;
  9485. }
  9486. /* store nonce for later */
  9487. if (nonceSz > 0) {
  9488. pkcs7->stream->nonceSz = nonceSz;
  9489. pkcs7->stream->nonce = (byte*)XMALLOC(nonceSz, pkcs7->heap,
  9490. DYNAMIC_TYPE_PKCS7);
  9491. if (pkcs7->stream->nonce == NULL) {
  9492. ret = MEMORY_E;
  9493. break;
  9494. }
  9495. else {
  9496. XMEMCPY(pkcs7->stream->nonce, nonce, nonceSz);
  9497. }
  9498. }
  9499. pkcs7->stream->expected = encryptedContentSz;
  9500. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz,
  9501. encryptedContentSz);
  9502. #endif
  9503. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5);
  9504. FALL_THROUGH;
  9505. case WC_PKCS7_AUTHENV_5:
  9506. #ifndef NO_PKCS7_STREAM
  9507. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9508. ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected,
  9509. &pkiMsg, &idx)) != 0) {
  9510. break;
  9511. }
  9512. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  9513. inSz);
  9514. if (rc < 0) {
  9515. ret = (int)rc;
  9516. break;
  9517. }
  9518. pkiMsgSz = (word32)rc;
  9519. encryptedContentSz = pkcs7->stream->expected;
  9520. #endif
  9521. encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
  9522. DYNAMIC_TYPE_PKCS7);
  9523. if (ret == 0 && encryptedContent == NULL) {
  9524. ret = MEMORY_E;
  9525. }
  9526. if (ret == 0) {
  9527. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  9528. idx += encryptedContentSz;
  9529. }
  9530. #ifndef NO_PKCS7_STREAM
  9531. pkcs7->stream->bufferPt = encryptedContent;
  9532. #endif
  9533. /* may have IMPLICIT [1] authenticatedAttributes */
  9534. localIdx = idx;
  9535. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  9536. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  9537. encodedAttribIdx = idx;
  9538. encodedAttribs = pkiMsg + idx;
  9539. idx++;
  9540. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  9541. ret = ASN_PARSE_E;
  9542. #ifndef NO_PKCS7_STREAM
  9543. pkcs7->stream->expected = length;
  9544. #endif
  9545. encodedAttribSz = length + (idx - encodedAttribIdx);
  9546. if (ret != 0)
  9547. break;
  9548. #ifndef NO_PKCS7_STREAM
  9549. if (encodedAttribSz > 0) {
  9550. pkcs7->stream->aadSz = encodedAttribSz;
  9551. pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz,
  9552. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9553. if (pkcs7->stream->aad == NULL) {
  9554. ret = MEMORY_E;
  9555. break;
  9556. }
  9557. else {
  9558. XMEMCPY(pkcs7->stream->aad, encodedAttribs,
  9559. (idx - encodedAttribIdx));
  9560. }
  9561. }
  9562. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9563. break;
  9564. }
  9565. #endif
  9566. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRB);
  9567. }
  9568. else {
  9569. #ifndef NO_PKCS7_STREAM
  9570. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9571. break;
  9572. }
  9573. #endif
  9574. goto authenv_atrbend; /* jump over attribute cases */
  9575. }
  9576. FALL_THROUGH;
  9577. case WC_PKCS7_AUTHENV_ATRB:
  9578. #ifndef NO_PKCS7_STREAM
  9579. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9580. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9581. return ret;
  9582. }
  9583. length = pkcs7->stream->expected;
  9584. encodedAttribs = pkcs7->stream->aad;
  9585. #else
  9586. length = 0;
  9587. #endif
  9588. /* save pointer and length */
  9589. authAttrib = &pkiMsg[idx];
  9590. authAttribSz = length;
  9591. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) {
  9592. WOLFSSL_MSG("Error parsing authenticated attributes");
  9593. ret = ASN_PARSE_E;
  9594. break;
  9595. }
  9596. idx += length;
  9597. #ifndef NO_PKCS7_STREAM
  9598. if (encodedAttribSz > 0) {
  9599. XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - length),
  9600. authAttrib, authAttribSz);
  9601. }
  9602. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9603. break;
  9604. }
  9605. #endif
  9606. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND);
  9607. FALL_THROUGH;
  9608. authenv_atrbend:
  9609. case WC_PKCS7_AUTHENV_ATRBEND:
  9610. #ifndef NO_PKCS7_STREAM
  9611. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9612. ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  9613. return ret;
  9614. }
  9615. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
  9616. in, inSz);
  9617. if (rc < 0) {
  9618. ret = (int)rc;
  9619. break;
  9620. }
  9621. pkiMsgSz = (word32)rc;
  9622. if (pkcs7->stream->aadSz > 0) {
  9623. encodedAttribSz = pkcs7->stream->aadSz;
  9624. encodedAttribs = pkcs7->stream->aad;
  9625. }
  9626. #endif
  9627. /* get authTag OCTET STRING */
  9628. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9629. ret = ASN_PARSE_E;
  9630. }
  9631. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9632. ret = ASN_PARSE_E;
  9633. }
  9634. if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) {
  9635. ret = ASN_PARSE_E;
  9636. }
  9637. if (ret == 0 && authTagSz > (int)sizeof(authTag)) {
  9638. WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer");
  9639. ret = ASN_PARSE_E;
  9640. }
  9641. if (ret == 0) {
  9642. XMEMCPY(authTag, &pkiMsg[idx], authTagSz);
  9643. idx += authTagSz;
  9644. }
  9645. if (ret == 0 && authAttrib != NULL) {
  9646. /* temporarily swap authAttribs byte[0] to SET OF instead of
  9647. * IMPLICIT [1], for aad calculation */
  9648. authAttribSetByte = encodedAttribs[0];
  9649. encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED;
  9650. }
  9651. if (ret < 0)
  9652. break;
  9653. #ifndef NO_PKCS7_STREAM
  9654. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9655. break;
  9656. }
  9657. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  9658. pkcs7->stream->totalRd) + pkcs7->stream->length;
  9659. /* store tag for later */
  9660. if (authTagSz > 0) {
  9661. pkcs7->stream->tagSz = authTagSz;
  9662. pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap,
  9663. DYNAMIC_TYPE_PKCS7);
  9664. if (pkcs7->stream->tag == NULL) {
  9665. ret = MEMORY_E;
  9666. break;
  9667. }
  9668. else {
  9669. XMEMCPY(pkcs7->stream->tag, authTag, authTagSz);
  9670. }
  9671. }
  9672. #endif
  9673. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_6);
  9674. FALL_THROUGH;
  9675. case WC_PKCS7_AUTHENV_6:
  9676. #ifndef NO_PKCS7_STREAM
  9677. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9678. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9679. break;
  9680. }
  9681. /* restore all variables needed */
  9682. if (pkcs7->stream->nonceSz > 0) {
  9683. nonceSz = pkcs7->stream->nonceSz;
  9684. if (nonceSz > GCM_NONCE_MID_SZ) {
  9685. WOLFSSL_MSG("PKCS7 saved nonce is too large");
  9686. ret = BUFFER_E;
  9687. break;
  9688. }
  9689. else {
  9690. XMEMCPY(nonce, pkcs7->stream->nonce, nonceSz);
  9691. }
  9692. }
  9693. if (pkcs7->stream->tagSz > 0) {
  9694. authTagSz = pkcs7->stream->tagSz;
  9695. if (authTagSz > AES_BLOCK_SIZE) {
  9696. WOLFSSL_MSG("PKCS7 saved tag is too large");
  9697. ret = BUFFER_E;
  9698. break;
  9699. }
  9700. else {
  9701. XMEMCPY(authTag, pkcs7->stream->tag, authTagSz);
  9702. }
  9703. }
  9704. if (pkcs7->stream->aadSz > 0) {
  9705. encodedAttribSz = pkcs7->stream->aadSz;
  9706. encodedAttribs = pkcs7->stream->aad;
  9707. }
  9708. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz,
  9709. &encryptedContentSz);
  9710. encryptedContent = pkcs7->stream->bufferPt;
  9711. #ifdef WOLFSSL_SMALL_STACK
  9712. decryptedKey = pkcs7->stream->key;
  9713. #endif
  9714. #endif
  9715. /* decrypt encryptedContent */
  9716. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  9717. blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,
  9718. authTag, authTagSz, encryptedContent, encryptedContentSz,
  9719. encryptedContent);
  9720. if (ret != 0) {
  9721. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9722. return ret;
  9723. }
  9724. if (authAttrib != NULL) {
  9725. /* restore authAttrib IMPLICIT [1] */
  9726. encodedAttribs[0] = authAttribSetByte;
  9727. }
  9728. /* copy plaintext to output */
  9729. XMEMCPY(output, encryptedContent, encryptedContentSz);
  9730. /* free memory, zero out keys */
  9731. ForceZero(encryptedContent, encryptedContentSz);
  9732. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9733. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9734. #ifdef WOLFSSL_SMALL_STACK
  9735. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9736. decryptedKey = NULL;
  9737. #ifdef WOLFSSL_SMALL_STACK
  9738. #ifndef NO_PKCS7_STREAM
  9739. pkcs7->stream->key = NULL;
  9740. #endif
  9741. #endif
  9742. #endif
  9743. ret = encryptedContentSz;
  9744. #ifndef NO_PKCS7_STREAM
  9745. wc_PKCS7_ResetStream(pkcs7);
  9746. #endif
  9747. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  9748. break;
  9749. default:
  9750. WOLFSSL_MSG("Unknown PKCS7 state");
  9751. ret = BAD_FUNC_ARG;
  9752. }
  9753. #ifdef WOLFSSL_SMALL_STACK
  9754. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  9755. if (decryptedKey != NULL) {
  9756. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9757. }
  9758. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9759. }
  9760. #endif
  9761. #ifndef NO_PKCS7_STREAM
  9762. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  9763. wc_PKCS7_ResetStream(pkcs7);
  9764. }
  9765. #endif
  9766. return ret;
  9767. #else
  9768. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  9769. (void)pkcs7;
  9770. (void)in;
  9771. (void)inSz;
  9772. (void)output;
  9773. (void)outputSz;
  9774. return NOT_COMPILED_IN;
  9775. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  9776. }
  9777. #ifndef NO_PKCS7_ENCRYPTED_DATA
  9778. /* build PKCS#7 encryptedData content type, return encrypted size */
  9779. int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  9780. {
  9781. int ret, idx = 0;
  9782. int totalSz, padSz, encryptedOutSz;
  9783. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  9784. byte contentInfoSeq[MAX_SEQ_SZ];
  9785. byte outerContentType[MAX_ALGO_SZ];
  9786. byte outerContent[MAX_SEQ_SZ];
  9787. int encDataSeqSz, verSz, blockSz;
  9788. byte encDataSeq[MAX_SEQ_SZ];
  9789. byte ver[MAX_VERSION_SZ];
  9790. byte* plain = NULL;
  9791. byte* encryptedContent = NULL;
  9792. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  9793. int contentEncAlgoSz, ivOctetStringSz;
  9794. byte encContentSeq[MAX_SEQ_SZ];
  9795. byte contentType[MAX_OID_SZ];
  9796. byte contentEncAlgo[MAX_ALGO_SZ];
  9797. byte tmpIv[MAX_CONTENT_IV_SIZE];
  9798. byte ivOctetString[MAX_OCTET_STR_SZ];
  9799. byte encContentOctet[MAX_OCTET_STR_SZ];
  9800. byte attribSet[MAX_SET_SZ];
  9801. EncodedAttrib* attribs = NULL;
  9802. word32 attribsSz;
  9803. word32 attribsCount;
  9804. word32 attribsSetSz;
  9805. byte* flatAttribs = NULL;
  9806. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  9807. pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
  9808. pkcs7->encryptionKeySz == 0)
  9809. return BAD_FUNC_ARG;
  9810. if (output == NULL || outputSz == 0)
  9811. return BAD_FUNC_ARG;
  9812. if (pkcs7->version == 3) {
  9813. verSz = SetMyVersion(0, ver, 0);
  9814. outerContentTypeSz = 0;
  9815. }
  9816. else {
  9817. /* outer content type */
  9818. ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType,
  9819. sizeof(outerContentType));
  9820. if (ret < 0)
  9821. return ret;
  9822. outerContentTypeSz = ret;
  9823. /* version, 2 if unprotectedAttrs present, 0 if absent */
  9824. if (pkcs7->unprotectedAttribsSz > 0) {
  9825. verSz = SetMyVersion(2, ver, 0);
  9826. } else {
  9827. verSz = SetMyVersion(0, ver, 0);
  9828. }
  9829. }
  9830. /* EncryptedContentInfo */
  9831. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  9832. sizeof(contentType));
  9833. if (ret < 0)
  9834. return ret;
  9835. contentTypeSz = ret;
  9836. /* allocate encrypted content buffer, do PKCS#7 padding */
  9837. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  9838. if (blockSz < 0)
  9839. return blockSz;
  9840. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  9841. if (padSz < 0)
  9842. return padSz;
  9843. encryptedOutSz = pkcs7->contentSz + padSz;
  9844. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  9845. DYNAMIC_TYPE_PKCS7);
  9846. if (plain == NULL)
  9847. return MEMORY_E;
  9848. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  9849. encryptedOutSz, blockSz);
  9850. if (ret < 0) {
  9851. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9852. return ret;
  9853. }
  9854. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  9855. DYNAMIC_TYPE_PKCS7);
  9856. if (encryptedContent == NULL) {
  9857. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9858. return MEMORY_E;
  9859. }
  9860. /* put together IV OCTET STRING */
  9861. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  9862. /* build up ContentEncryptionAlgorithmIdentifier sequence,
  9863. adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  9864. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  9865. oidBlkType, ivOctetStringSz + blockSz);
  9866. if (contentEncAlgoSz == 0) {
  9867. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9868. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9869. return BAD_FUNC_ARG;
  9870. }
  9871. /* encrypt content */
  9872. WOLFSSL_MSG("Encrypting the content");
  9873. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, blockSz);
  9874. if (ret != 0) {
  9875. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9876. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9877. return ret;
  9878. }
  9879. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
  9880. pkcs7->encryptionKeySz, tmpIv, blockSz, NULL, 0, NULL, 0,
  9881. plain, encryptedOutSz, encryptedContent);
  9882. if (ret != 0) {
  9883. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9884. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9885. return ret;
  9886. }
  9887. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
  9888. encryptedOutSz, encContentOctet);
  9889. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  9890. ivOctetStringSz + blockSz +
  9891. encContentOctetSz + encryptedOutSz,
  9892. encContentSeq);
  9893. /* optional UnprotectedAttributes */
  9894. if (pkcs7->unprotectedAttribsSz != 0) {
  9895. if (pkcs7->unprotectedAttribs == NULL) {
  9896. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9897. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9898. return BAD_FUNC_ARG;
  9899. }
  9900. attribs = (EncodedAttrib*)XMALLOC(
  9901. sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,
  9902. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9903. if (attribs == NULL) {
  9904. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9905. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9906. return MEMORY_E;
  9907. }
  9908. attribsCount = pkcs7->unprotectedAttribsSz;
  9909. attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,
  9910. pkcs7->unprotectedAttribs,
  9911. pkcs7->unprotectedAttribsSz);
  9912. flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9913. if (flatAttribs == NULL) {
  9914. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9915. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9916. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9917. return MEMORY_E;
  9918. }
  9919. FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);
  9920. attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
  9921. } else {
  9922. attribsSz = 0;
  9923. attribsSetSz = 0;
  9924. }
  9925. /* keep track of sizes for outer wrapper layering */
  9926. totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
  9927. ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +
  9928. attribsSz + attribsSetSz;
  9929. /* EncryptedData */
  9930. encDataSeqSz = SetSequence(totalSz, encDataSeq);
  9931. totalSz += encDataSeqSz;
  9932. if (pkcs7->version != 3) {
  9933. /* outer content */
  9934. outerContentSz = SetExplicit(0, totalSz, outerContent);
  9935. totalSz += outerContentTypeSz;
  9936. totalSz += outerContentSz;
  9937. /* ContentInfo */
  9938. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  9939. totalSz += contentInfoSeqSz;
  9940. } else {
  9941. contentInfoSeqSz = 0;
  9942. outerContentSz = 0;
  9943. }
  9944. if (totalSz > (int)outputSz) {
  9945. WOLFSSL_MSG("PKCS#7 output buffer too small");
  9946. if (pkcs7->unprotectedAttribsSz != 0) {
  9947. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9948. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9949. }
  9950. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9951. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9952. return BUFFER_E;
  9953. }
  9954. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  9955. idx += contentInfoSeqSz;
  9956. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  9957. idx += outerContentTypeSz;
  9958. XMEMCPY(output + idx, outerContent, outerContentSz);
  9959. idx += outerContentSz;
  9960. XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
  9961. idx += encDataSeqSz;
  9962. XMEMCPY(output + idx, ver, verSz);
  9963. idx += verSz;
  9964. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  9965. idx += encContentSeqSz;
  9966. XMEMCPY(output + idx, contentType, contentTypeSz);
  9967. idx += contentTypeSz;
  9968. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  9969. idx += contentEncAlgoSz;
  9970. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  9971. idx += ivOctetStringSz;
  9972. XMEMCPY(output + idx, tmpIv, blockSz);
  9973. idx += blockSz;
  9974. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  9975. idx += encContentOctetSz;
  9976. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  9977. idx += encryptedOutSz;
  9978. if (pkcs7->unprotectedAttribsSz != 0) {
  9979. XMEMCPY(output + idx, attribSet, attribsSetSz);
  9980. idx += attribsSetSz;
  9981. XMEMCPY(output + idx, flatAttribs, attribsSz);
  9982. idx += attribsSz;
  9983. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9984. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9985. }
  9986. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9987. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9988. return idx;
  9989. }
  9990. /* decode and store unprotected attributes in PKCS7->decodedAttrib. Return
  9991. * 0 on success, negative on error. User must call wc_PKCS7_Free(). */
  9992. static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
  9993. word32 pkiMsgSz, word32* inOutIdx)
  9994. {
  9995. int ret, attribLen;
  9996. word32 idx;
  9997. byte tag;
  9998. if (pkcs7 == NULL || pkiMsg == NULL ||
  9999. pkiMsgSz == 0 || inOutIdx == NULL)
  10000. return BAD_FUNC_ARG;
  10001. idx = *inOutIdx;
  10002. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10003. return ASN_PARSE_E;
  10004. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
  10005. return ASN_PARSE_E;
  10006. if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
  10007. return ASN_PARSE_E;
  10008. /* loop through attributes */
  10009. if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {
  10010. return ret;
  10011. }
  10012. *inOutIdx = idx;
  10013. return 0;
  10014. }
  10015. /* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */
  10016. int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
  10017. byte* output, word32 outputSz)
  10018. {
  10019. int ret = 0, version, length = 0, haveAttribs = 0;
  10020. word32 idx = 0;
  10021. #ifndef NO_PKCS7_STREAM
  10022. word32 tmpIdx = 0;
  10023. long rc;
  10024. #endif
  10025. word32 contentType, encOID;
  10026. int expBlockSz = 0;
  10027. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  10028. byte *tmpIv = tmpIvBuf;
  10029. int encryptedContentSz = 0;
  10030. byte padLen;
  10031. byte* encryptedContent = NULL;
  10032. byte* pkiMsg = in;
  10033. word32 pkiMsgSz = inSz;
  10034. byte tag;
  10035. if (pkcs7 == NULL ||
  10036. ((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
  10037. pkcs7->decryptionCb == NULL))
  10038. return BAD_FUNC_ARG;
  10039. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  10040. output == NULL || outputSz == 0)
  10041. return BAD_FUNC_ARG;
  10042. #ifndef NO_PKCS7_STREAM
  10043. (void)tmpIv; /* help out static analysis */
  10044. if (pkcs7->stream == NULL) {
  10045. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  10046. return ret;
  10047. }
  10048. }
  10049. #endif
  10050. switch (pkcs7->state) {
  10051. case WC_PKCS7_START:
  10052. #ifndef NO_PKCS7_STREAM
  10053. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  10054. MAX_ALGO_SZ, &pkiMsg, &idx)) != 0) {
  10055. return ret;
  10056. }
  10057. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
  10058. if (rc < 0) {
  10059. ret = (int)rc;
  10060. break;
  10061. }
  10062. pkiMsgSz = (word32)rc;
  10063. #endif
  10064. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10065. ret = ASN_PARSE_E;
  10066. if (pkcs7->version != 3) { /* ContentInfo not in firmware bundles */
  10067. /* read past ContentInfo, verify type is encrypted-data */
  10068. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10069. pkiMsgSz) < 0)
  10070. ret = ASN_PARSE_E;
  10071. if (ret == 0 && contentType != ENCRYPTED_DATA) {
  10072. WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
  10073. ret = PKCS7_OID_E;
  10074. }
  10075. }
  10076. if (ret != 0) break;
  10077. #ifndef NO_PKCS7_STREAM
  10078. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10079. break;
  10080. }
  10081. #endif
  10082. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE2);
  10083. FALL_THROUGH;
  10084. /* end of stage 1 */
  10085. case WC_PKCS7_STAGE2:
  10086. #ifndef NO_PKCS7_STREAM
  10087. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10088. MAX_LENGTH_SZ + MAX_SEQ_SZ + ASN_TAG_SZ, &pkiMsg,
  10089. &idx)) != 0) {
  10090. return ret;
  10091. }
  10092. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  10093. inSz);
  10094. if (rc < 0) {
  10095. ret = (int)rc;
  10096. break;
  10097. }
  10098. pkiMsgSz = (word32)rc;
  10099. #endif
  10100. if (pkcs7->version != 3) {
  10101. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10102. ret = ASN_PARSE_E;
  10103. if (ret == 0 && tag !=
  10104. (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  10105. ret = ASN_PARSE_E;
  10106. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10107. ret = ASN_PARSE_E;
  10108. /* remove EncryptedData and version */
  10109. if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10110. ret = ASN_PARSE_E;
  10111. }
  10112. if (ret != 0) break;
  10113. #ifndef NO_PKCS7_STREAM
  10114. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10115. break;
  10116. }
  10117. #endif
  10118. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE3);
  10119. FALL_THROUGH;
  10120. /* end of stage 2 */
  10121. case WC_PKCS7_STAGE3:
  10122. #ifndef NO_PKCS7_STREAM
  10123. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10124. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ * 2,
  10125. &pkiMsg, &idx)) != 0) {
  10126. return ret;
  10127. }
  10128. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  10129. inSz);
  10130. if (rc < 0) {
  10131. ret = (int)rc;
  10132. break;
  10133. }
  10134. pkiMsgSz = (word32)rc;
  10135. #endif
  10136. /* get version, check later */
  10137. haveAttribs = 0;
  10138. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  10139. ret = ASN_PARSE_E;
  10140. /* remove EncryptedContentInfo */
  10141. if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10142. ret = ASN_PARSE_E;
  10143. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10144. pkiMsgSz) < 0)
  10145. ret = ASN_PARSE_E;
  10146. if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  10147. pkiMsgSz)) < 0)
  10148. ret = ASN_PARSE_E;
  10149. if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID)) < 0)
  10150. ret = expBlockSz;
  10151. if (ret != 0) break;
  10152. #ifndef NO_PKCS7_STREAM
  10153. /* store expBlockSz for later */
  10154. pkcs7->stream->varOne = expBlockSz;
  10155. pkcs7->stream->varTwo = encOID;
  10156. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10157. break;
  10158. }
  10159. /* store version for later */
  10160. pkcs7->stream->vers = version;
  10161. #endif
  10162. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE4);
  10163. FALL_THROUGH;
  10164. /* end of stage 3 */
  10165. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  10166. case WC_PKCS7_STAGE4:
  10167. #ifndef NO_PKCS7_STREAM
  10168. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10169. ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  10170. return ret;
  10171. }
  10172. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  10173. inSz);
  10174. if (rc < 0) {
  10175. ret = (int)rc;
  10176. break;
  10177. }
  10178. pkiMsgSz = (word32)rc;
  10179. /* restore saved variables */
  10180. expBlockSz = pkcs7->stream->varOne;
  10181. #endif
  10182. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10183. ret = ASN_PARSE_E;
  10184. if (ret == 0 && tag != ASN_OCTET_STRING)
  10185. ret = ASN_PARSE_E;
  10186. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10187. ret = ASN_PARSE_E;
  10188. if (ret == 0 && length != expBlockSz) {
  10189. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  10190. ret = ASN_PARSE_E;
  10191. }
  10192. if (ret != 0) break;
  10193. #ifndef NO_PKCS7_STREAM
  10194. /* next chunk of data expected should have the IV */
  10195. pkcs7->stream->expected = length;
  10196. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10197. break;
  10198. }
  10199. #endif
  10200. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE5);
  10201. FALL_THROUGH;
  10202. /* end of stage 4 */
  10203. case WC_PKCS7_STAGE5:
  10204. #ifndef NO_PKCS7_STREAM
  10205. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10206. pkcs7->stream->expected + ASN_TAG_SZ +
  10207. MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  10208. return ret;
  10209. }
  10210. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  10211. inSz);
  10212. if (rc < 0) {
  10213. ret = (int)rc;
  10214. break;
  10215. }
  10216. pkiMsgSz = (word32)rc;
  10217. /* use IV buffer from stream structure */
  10218. tmpIv = pkcs7->stream->tmpIv;
  10219. length = pkcs7->stream->expected;
  10220. #endif
  10221. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  10222. idx += length;
  10223. /* read encryptedContent, cont[0] */
  10224. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10225. ret = ASN_PARSE_E;
  10226. if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))
  10227. ret = ASN_PARSE_E;
  10228. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  10229. pkiMsgSz) <= 0)
  10230. ret = ASN_PARSE_E;
  10231. if (ret < 0)
  10232. break;
  10233. #ifndef NO_PKCS7_STREAM
  10234. /* next chunk of data should contain encrypted content */
  10235. pkcs7->stream->varThree = encryptedContentSz;
  10236. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10237. break;
  10238. }
  10239. if (pkcs7->stream->totalRd + encryptedContentSz < pkiMsgSz) {
  10240. pkcs7->stream->flagOne = 1;
  10241. }
  10242. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  10243. pkcs7->stream->totalRd) + pkcs7->stream->length;
  10244. #endif
  10245. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE6);
  10246. FALL_THROUGH;
  10247. /* end of stage 5 */
  10248. case WC_PKCS7_STAGE6:
  10249. #ifndef NO_PKCS7_STREAM
  10250. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10251. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10252. return ret;
  10253. }
  10254. rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
  10255. inSz);
  10256. if (rc < 0) {
  10257. ret = (int)rc;
  10258. break;
  10259. }
  10260. pkiMsgSz = (word32)rc;
  10261. /* restore saved variables */
  10262. expBlockSz = pkcs7->stream->varOne;
  10263. encOID = pkcs7->stream->varTwo;
  10264. encryptedContentSz = pkcs7->stream->varThree;
  10265. version = pkcs7->stream->vers;
  10266. tmpIv = pkcs7->stream->tmpIv;
  10267. #else
  10268. encOID = 0;
  10269. #endif
  10270. if (ret == 0 && (encryptedContent = (byte*)XMALLOC(
  10271. encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) {
  10272. ret = MEMORY_E;
  10273. break;
  10274. }
  10275. if (ret == 0) {
  10276. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  10277. idx += encryptedContentSz;
  10278. /* decrypt encryptedContent */
  10279. ret = wc_PKCS7_DecryptContent(pkcs7, encOID,
  10280. pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,
  10281. expBlockSz, NULL, 0, NULL, 0, encryptedContent,
  10282. encryptedContentSz, encryptedContent);
  10283. if (ret != 0) {
  10284. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10285. }
  10286. }
  10287. if (ret == 0) {
  10288. padLen = encryptedContent[encryptedContentSz-1];
  10289. if (padLen > encryptedContentSz) {
  10290. WOLFSSL_MSG("Bad padding size found");
  10291. ret = BUFFER_E;
  10292. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10293. break;
  10294. }
  10295. /* copy plaintext to output */
  10296. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  10297. /* get implicit[1] unprotected attributes, optional */
  10298. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  10299. pkcs7->decodedAttrib = NULL;
  10300. #ifndef NO_PKCS7_STREAM
  10301. if (pkcs7->stream->flagOne)
  10302. #else
  10303. if (idx < pkiMsgSz)
  10304. #endif
  10305. {
  10306. haveAttribs = 1;
  10307. ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
  10308. pkiMsgSz, &idx);
  10309. if (ret != 0) {
  10310. ForceZero(encryptedContent, encryptedContentSz);
  10311. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10312. ret = ASN_PARSE_E;
  10313. }
  10314. }
  10315. }
  10316. if (ret == 0) {
  10317. ForceZero(encryptedContent, encryptedContentSz);
  10318. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10319. /* go back and check the version now that attribs have been processed */
  10320. if (pkcs7->version == 3 && version != 0) {
  10321. WOLFSSL_MSG("Wrong PKCS#7 FirmwareEncryptedData version");
  10322. return ASN_VERSION_E;
  10323. }
  10324. if (pkcs7->version != 3 &&
  10325. ((haveAttribs == 0 && version != 0) ||
  10326. (haveAttribs == 1 && version != 2))) {
  10327. WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version");
  10328. return ASN_VERSION_E;
  10329. }
  10330. ret = encryptedContentSz - padLen;
  10331. }
  10332. if (ret != 0) break;
  10333. #ifndef NO_PKCS7_STREAM
  10334. wc_PKCS7_ResetStream(pkcs7);
  10335. #endif
  10336. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10337. break;
  10338. default:
  10339. WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
  10340. return BAD_STATE_E;
  10341. }
  10342. if (ret != 0) {
  10343. #ifndef NO_PKCS7_STREAM
  10344. /* restart in error case */
  10345. wc_PKCS7_ResetStream(pkcs7);
  10346. #endif
  10347. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10348. }
  10349. return ret;
  10350. }
  10351. /* Function to set callback during decryption, this overrides the default
  10352. * decryption function and can be used for choosing a key at run time based
  10353. * on the parsed bundle so far.
  10354. * returns 0 on success
  10355. */
  10356. int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,
  10357. CallbackDecryptContent decryptionCb)
  10358. {
  10359. if (pkcs7 != NULL) {
  10360. pkcs7->decryptionCb = decryptionCb;
  10361. }
  10362. return 0;
  10363. }
  10364. /* Set an optional user context that gets passed to callback
  10365. * returns 0 on success
  10366. */
  10367. int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx)
  10368. {
  10369. if (pkcs7 != NULL) {
  10370. pkcs7->decryptionCtx = ctx;
  10371. }
  10372. return 0;
  10373. }
  10374. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  10375. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  10376. /* build PKCS#7 compressedData content type, return encrypted size */
  10377. int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  10378. {
  10379. byte contentInfoSeq[MAX_SEQ_SZ];
  10380. byte contentInfoTypeOid[MAX_OID_SZ];
  10381. byte contentInfoContentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  10382. byte compressedDataSeq[MAX_SEQ_SZ];
  10383. byte cmsVersion[MAX_VERSION_SZ];
  10384. byte compressAlgId[MAX_ALGO_SZ];
  10385. byte encapContentInfoSeq[MAX_SEQ_SZ];
  10386. byte contentTypeOid[MAX_OID_SZ];
  10387. byte contentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  10388. byte contentOctetStr[MAX_OCTET_STR_SZ];
  10389. int ret;
  10390. word32 totalSz, idx;
  10391. word32 contentInfoSeqSz, contentInfoContentSeqSz, contentInfoTypeOidSz;
  10392. word32 compressedDataSeqSz, cmsVersionSz, compressAlgIdSz;
  10393. word32 encapContentInfoSeqSz, contentTypeOidSz, contentSeqSz;
  10394. word32 contentOctetStrSz;
  10395. byte* compressed;
  10396. word32 compressedSz;
  10397. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  10398. output == NULL || outputSz == 0) {
  10399. return BAD_FUNC_ARG;
  10400. }
  10401. /* allocate space for compressed content. The libz code says the compressed
  10402. * buffer should be srcSz + 0.1% + 12. */
  10403. compressedSz = (pkcs7->contentSz + (word32)(pkcs7->contentSz * 0.001) + 12);
  10404. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10405. if (compressed == NULL) {
  10406. WOLFSSL_MSG("Error allocating memory for CMS compressed content");
  10407. return MEMORY_E;
  10408. }
  10409. /* compress content */
  10410. ret = wc_Compress(compressed, compressedSz, pkcs7->content,
  10411. pkcs7->contentSz, 0);
  10412. if (ret < 0) {
  10413. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10414. return ret;
  10415. }
  10416. compressedSz = (word32)ret;
  10417. /* eContent OCTET STRING, working backwards */
  10418. contentOctetStrSz = SetOctetString(compressedSz, contentOctetStr);
  10419. totalSz = contentOctetStrSz + compressedSz;
  10420. /* EXPLICIT [0] eContentType */
  10421. contentSeqSz = SetExplicit(0, totalSz, contentSeq);
  10422. totalSz += contentSeqSz;
  10423. /* eContentType OBJECT IDENTIFIER */
  10424. ret = wc_SetContentType(pkcs7->contentOID, contentTypeOid,
  10425. sizeof(contentTypeOid));
  10426. if (ret < 0) {
  10427. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10428. return ret;
  10429. }
  10430. contentTypeOidSz = ret;
  10431. totalSz += contentTypeOidSz;
  10432. /* EncapsulatedContentInfo SEQUENCE */
  10433. encapContentInfoSeqSz = SetSequence(totalSz, encapContentInfoSeq);
  10434. totalSz += encapContentInfoSeqSz;
  10435. /* compressionAlgorithm AlgorithmIdentifier */
  10436. /* Only supports zlib for compression currently:
  10437. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  10438. compressAlgIdSz = SetAlgoID(ZLIBc, compressAlgId, oidCompressType, 0);
  10439. totalSz += compressAlgIdSz;
  10440. /* version */
  10441. cmsVersionSz = SetMyVersion(0, cmsVersion, 0);
  10442. totalSz += cmsVersionSz;
  10443. /* CompressedData SEQUENCE */
  10444. compressedDataSeqSz = SetSequence(totalSz, compressedDataSeq);
  10445. totalSz += compressedDataSeqSz;
  10446. /* ContentInfo content EXPLICIT SEQUENCE */
  10447. contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq);
  10448. totalSz += contentInfoContentSeqSz;
  10449. /* ContentInfo ContentType (compressedData) */
  10450. if (pkcs7->version == 3) {
  10451. contentInfoTypeOidSz = 0;
  10452. }
  10453. else {
  10454. ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid,
  10455. sizeof(contentInfoTypeOid));
  10456. if (ret < 0) {
  10457. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10458. return ret;
  10459. }
  10460. contentInfoTypeOidSz = ret;
  10461. totalSz += contentInfoTypeOidSz;
  10462. }
  10463. /* ContentInfo SEQUENCE */
  10464. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  10465. totalSz += contentInfoSeqSz;
  10466. if (outputSz < totalSz) {
  10467. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10468. return BUFFER_E;
  10469. }
  10470. idx = 0;
  10471. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  10472. idx += contentInfoSeqSz;
  10473. XMEMCPY(output + idx, contentInfoTypeOid, contentInfoTypeOidSz);
  10474. idx += contentInfoTypeOidSz;
  10475. XMEMCPY(output + idx, contentInfoContentSeq, contentInfoContentSeqSz);
  10476. idx += contentInfoContentSeqSz;
  10477. XMEMCPY(output + idx, compressedDataSeq, compressedDataSeqSz);
  10478. idx += compressedDataSeqSz;
  10479. XMEMCPY(output + idx, cmsVersion, cmsVersionSz);
  10480. idx += cmsVersionSz;
  10481. XMEMCPY(output + idx, compressAlgId, compressAlgIdSz);
  10482. idx += compressAlgIdSz;
  10483. XMEMCPY(output + idx, encapContentInfoSeq, encapContentInfoSeqSz);
  10484. idx += encapContentInfoSeqSz;
  10485. XMEMCPY(output + idx, contentTypeOid, contentTypeOidSz);
  10486. idx += contentTypeOidSz;
  10487. XMEMCPY(output + idx, contentSeq, contentSeqSz);
  10488. idx += contentSeqSz;
  10489. XMEMCPY(output + idx, contentOctetStr, contentOctetStrSz);
  10490. idx += contentOctetStrSz;
  10491. XMEMCPY(output + idx, compressed, compressedSz);
  10492. idx += compressedSz;
  10493. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10494. return idx;
  10495. }
  10496. /* unwrap and decompress PKCS#7/CMS compressedData object,
  10497. * returned decoded size */
  10498. int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
  10499. byte* output, word32 outputSz)
  10500. {
  10501. int length, version, ret;
  10502. word32 idx = 0, algOID, contentType;
  10503. byte tag;
  10504. byte* decompressed;
  10505. word32 decompressedSz;
  10506. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 ||
  10507. output == NULL || outputSz == 0) {
  10508. return BAD_FUNC_ARG;
  10509. }
  10510. /* get ContentInfo SEQUENCE */
  10511. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10512. return ASN_PARSE_E;
  10513. if (pkcs7->version != 3) {
  10514. /* get ContentInfo contentType */
  10515. if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
  10516. return ASN_PARSE_E;
  10517. if (contentType != COMPRESSED_DATA)
  10518. return ASN_PARSE_E;
  10519. }
  10520. /* get ContentInfo content EXPLICIT SEQUENCE */
  10521. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10522. return ASN_PARSE_E;
  10523. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  10524. return ASN_PARSE_E;
  10525. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10526. return ASN_PARSE_E;
  10527. /* get CompressedData SEQUENCE */
  10528. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10529. return ASN_PARSE_E;
  10530. /* get version */
  10531. if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  10532. return ASN_PARSE_E;
  10533. if (version != 0) {
  10534. WOLFSSL_MSG("CMS CompressedData version MUST be 0, but is not");
  10535. return ASN_PARSE_E;
  10536. }
  10537. /* get CompressionAlgorithmIdentifier */
  10538. if (GetAlgoId(pkiMsg, &idx, &algOID, oidIgnoreType, pkiMsgSz) < 0)
  10539. return ASN_PARSE_E;
  10540. /* Only supports zlib for compression currently:
  10541. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  10542. if (algOID != ZLIBc) {
  10543. WOLFSSL_MSG("CMS CompressedData only supports zlib algorithm");
  10544. return ASN_PARSE_E;
  10545. }
  10546. /* get EncapsulatedContentInfo SEQUENCE */
  10547. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10548. return ASN_PARSE_E;
  10549. /* get ContentType OID */
  10550. if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
  10551. return ASN_PARSE_E;
  10552. pkcs7->contentOID = contentType;
  10553. /* get eContent EXPLICIT SEQUENCE */
  10554. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10555. return ASN_PARSE_E;
  10556. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  10557. return ASN_PARSE_E;
  10558. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10559. return ASN_PARSE_E;
  10560. /* get content OCTET STRING */
  10561. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10562. return ASN_PARSE_E;
  10563. if (tag != ASN_OCTET_STRING)
  10564. return ASN_PARSE_E;
  10565. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10566. return ASN_PARSE_E;
  10567. /* allocate space for decompressed data */
  10568. decompressed = (byte*)XMALLOC(length, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10569. if (decompressed == NULL) {
  10570. WOLFSSL_MSG("Error allocating memory for CMS decompression buffer");
  10571. return MEMORY_E;
  10572. }
  10573. /* decompress content */
  10574. ret = wc_DeCompress(decompressed, length, &pkiMsg[idx], length);
  10575. if (ret < 0) {
  10576. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10577. return ret;
  10578. }
  10579. decompressedSz = (word32)ret;
  10580. /* get content */
  10581. if (outputSz < decompressedSz) {
  10582. WOLFSSL_MSG("CMS output buffer too small to hold decompressed data");
  10583. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10584. return BUFFER_E;
  10585. }
  10586. XMEMCPY(output, decompressed, decompressedSz);
  10587. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10588. return decompressedSz;
  10589. }
  10590. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  10591. #else /* HAVE_PKCS7 */
  10592. #ifdef _MSC_VER
  10593. /* 4206 warning for blank file */
  10594. #pragma warning(disable: 4206)
  10595. #endif
  10596. #endif /* HAVE_PKCS7 */