pkcs7.c 420 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068
  1. /* pkcs7.c
  2. *
  3. * Copyright (C) 2006-2022 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #ifdef HAVE_PKCS7
  26. #include <wolfssl/wolfcrypt/pkcs7.h>
  27. #include <wolfssl/wolfcrypt/error-crypt.h>
  28. #include <wolfssl/wolfcrypt/logging.h>
  29. #include <wolfssl/wolfcrypt/hash.h>
  30. #ifndef NO_RSA
  31. #include <wolfssl/wolfcrypt/rsa.h>
  32. #endif
  33. #ifdef HAVE_ECC
  34. #include <wolfssl/wolfcrypt/ecc.h>
  35. #endif
  36. #ifdef HAVE_LIBZ
  37. #include <wolfssl/wolfcrypt/compress.h>
  38. #endif
  39. #ifndef NO_PWDBASED
  40. #include <wolfssl/wolfcrypt/pwdbased.h>
  41. #endif
  42. #ifdef NO_INLINE
  43. #include <wolfssl/wolfcrypt/misc.h>
  44. #else
  45. #define WOLFSSL_MISC_INCLUDED
  46. #include <wolfcrypt/src/misc.c>
  47. #endif
  48. /* direction for processing, encoding or decoding */
  49. typedef enum {
  50. WC_PKCS7_ENCODE,
  51. WC_PKCS7_DECODE
  52. } pkcs7Direction;
  53. #define NO_USER_CHECK 0
  54. /* holds information about the signers */
  55. struct PKCS7SignerInfo {
  56. int version;
  57. byte *sid;
  58. word32 sidSz;
  59. };
  60. #ifndef WOLFSSL_PKCS7_MAX_DECOMPRESSION
  61. /* 1031 comes from "Maximum Compression Factor" in the zlib tech document,
  62. * typical compression is from 2:1 to 5:1 but there is rare cases where
  63. * 1030.3:1 could happen (like a file with all 0's)
  64. */
  65. #define WOLFSSL_PKCS7_MAX_DECOMPRESSION 1031
  66. #endif
  67. #ifndef NO_PKCS7_STREAM
  68. #define MAX_PKCS7_STREAM_BUFFER 256
  69. struct PKCS7State {
  70. byte* tmpCert;
  71. byte* bufferPt;
  72. byte* key;
  73. byte* nonce; /* stored nonce */
  74. byte* aad; /* additional data for AEAD algos */
  75. byte* tag; /* tag data for AEAD algos */
  76. byte* content;
  77. byte* buffer; /* main internal read buffer */
  78. /* stack variables to store for when returning */
  79. word32 varOne;
  80. int varTwo;
  81. int varThree;
  82. word32 vers;
  83. word32 idx; /* index read into current input buffer */
  84. word32 maxLen; /* sanity cap on maximum amount of data to allow
  85. * needed for GetSequence and other calls */
  86. word32 length; /* amount of data stored */
  87. word32 bufferSz; /* size of internal buffer */
  88. word32 expected; /* next amount of data expected, if needed */
  89. word32 totalRd; /* total amount of bytes read */
  90. word32 nonceSz; /* size of nonce stored */
  91. word32 aadSz; /* size of additional AEAD data */
  92. word32 tagSz; /* size of tag for AEAD */
  93. word32 contentSz;
  94. byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
  95. #ifdef WC_PKCS7_STREAM_DEBUG
  96. word32 peakUsed; /* most bytes used for struct at any one time */
  97. word32 peakRead; /* most bytes used by read buffer */
  98. #endif
  99. byte multi:1; /* flag for if content is in multiple parts */
  100. byte flagOne:1;
  101. byte detached:1; /* flag to indicate detached signature is present */
  102. };
  103. /* creates a PKCS7State structure and returns 0 on success */
  104. static int wc_PKCS7_CreateStream(PKCS7* pkcs7)
  105. {
  106. WOLFSSL_MSG("creating PKCS7 stream structure");
  107. pkcs7->stream = (PKCS7State*)XMALLOC(sizeof(PKCS7State), pkcs7->heap,
  108. DYNAMIC_TYPE_PKCS7);
  109. if (pkcs7->stream == NULL) {
  110. return MEMORY_E;
  111. }
  112. XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State));
  113. #ifdef WC_PKCS7_STREAM_DEBUG
  114. printf("\nCreating new PKCS#7 stream %p\n", pkcs7->stream);
  115. #endif
  116. return 0;
  117. }
  118. static void wc_PKCS7_ResetStream(PKCS7* pkcs7)
  119. {
  120. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  121. #ifdef WC_PKCS7_STREAM_DEBUG
  122. /* collect final data point in case more was read right before reset */
  123. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  124. pkcs7->stream->peakRead = pkcs7->stream->length;
  125. }
  126. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz +
  127. pkcs7->stream->nonceSz + pkcs7->stream->tagSz >
  128. pkcs7->stream->peakUsed) {
  129. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  130. pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  131. pkcs7->stream->tagSz;
  132. }
  133. /* print out debugging statistics */
  134. if (pkcs7->stream->peakUsed > 0 || pkcs7->stream->peakRead > 0) {
  135. printf("PKCS#7 STREAM:\n\tPeak heap used by struct = %d"
  136. "\n\tPeak read buffer bytes = %d"
  137. "\n\tTotal bytes read = %d"
  138. "\n",
  139. pkcs7->stream->peakUsed, pkcs7->stream->peakRead,
  140. pkcs7->stream->totalRd);
  141. }
  142. printf("PKCS#7 stream reset : Address [%p]\n", pkcs7->stream);
  143. #endif
  144. /* free any buffers that may be allocated */
  145. XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  146. XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  147. XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  148. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  149. XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  150. pkcs7->stream->aad = NULL;
  151. pkcs7->stream->tag = NULL;
  152. pkcs7->stream->nonce = NULL;
  153. pkcs7->stream->buffer = NULL;
  154. pkcs7->stream->key = NULL;
  155. /* reset values, note that content and tmpCert are saved */
  156. pkcs7->stream->maxLen = 0;
  157. pkcs7->stream->length = 0;
  158. pkcs7->stream->idx = 0;
  159. pkcs7->stream->expected = 0;
  160. pkcs7->stream->totalRd = 0;
  161. pkcs7->stream->bufferSz = 0;
  162. pkcs7->stream->multi = 0;
  163. pkcs7->stream->flagOne = 0;
  164. pkcs7->stream->detached = 0;
  165. pkcs7->stream->varOne = 0;
  166. pkcs7->stream->varTwo = 0;
  167. pkcs7->stream->varThree = 0;
  168. }
  169. }
  170. static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
  171. {
  172. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  173. wc_PKCS7_ResetStream(pkcs7);
  174. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  175. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  176. pkcs7->stream->content = NULL;
  177. pkcs7->stream->tmpCert = NULL;
  178. XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  179. pkcs7->stream = NULL;
  180. }
  181. }
  182. /* used to increase the max size for internal buffer
  183. * returns 0 on success */
  184. static int wc_PKCS7_GrowStream(PKCS7* pkcs7, word32 newSz)
  185. {
  186. byte* pt;
  187. pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  188. if (pt == NULL) {
  189. return MEMORY_E;
  190. }
  191. if (pkcs7->stream->buffer != NULL && pkcs7->stream->bufferSz > 0) {
  192. XMEMCPY(pt, pkcs7->stream->buffer, pkcs7->stream->bufferSz);
  193. }
  194. #ifdef WC_PKCS7_STREAM_DEBUG
  195. printf("PKCS7 increasing internal stream buffer %d -> %d\n",
  196. pkcs7->stream->bufferSz, newSz);
  197. #endif
  198. pkcs7->stream->bufferSz = newSz;
  199. XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  200. pkcs7->stream->buffer = pt;
  201. return 0;
  202. }
  203. /* pt gets set to the buffer that is holding data in the case that stream struct
  204. * is used.
  205. *
  206. * Sets idx to be the current offset into "pt" buffer
  207. * returns 0 on success
  208. */
  209. static int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz,
  210. word32 expected, byte** pt, word32* idx)
  211. {
  212. word32 rdSz = pkcs7->stream->idx;
  213. /* If the input size minus current index into input buffer is greater than
  214. * the expected size then use the input buffer. If data is already stored
  215. * in stream buffer or if there is not enough input data available then use
  216. * the stream buffer. */
  217. if (inSz - rdSz >= expected && pkcs7->stream->length == 0) {
  218. /* storing input buffer is not needed */
  219. *pt = in; /* reset in case previously used internal buffer */
  220. *idx = rdSz;
  221. return 0;
  222. }
  223. /* is there enough stored in buffer already? */
  224. if (pkcs7->stream->length >= expected) {
  225. *idx = 0; /* start reading from beginning of stream buffer */
  226. *pt = pkcs7->stream->buffer;
  227. return 0;
  228. }
  229. /* check if all data has been read from input */
  230. if (rdSz >= inSz) {
  231. /* no more input to read, reset input index and request more data */
  232. pkcs7->stream->idx = 0;
  233. return WC_PKCS7_WANT_READ_E;
  234. }
  235. /* try to store input data into stream buffer */
  236. if (inSz - rdSz > 0 && pkcs7->stream->length < expected) {
  237. int len = min(inSz - rdSz, expected - pkcs7->stream->length);
  238. /* sanity check that the input buffer is not internal buffer */
  239. if (in == pkcs7->stream->buffer) {
  240. return WC_PKCS7_WANT_READ_E;
  241. }
  242. /* check if internal buffer size needs to be increased */
  243. if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) {
  244. int ret = wc_PKCS7_GrowStream(pkcs7, expected);
  245. if (ret < 0) {
  246. return ret;
  247. }
  248. }
  249. XMEMCPY(pkcs7->stream->buffer + pkcs7->stream->length, in + rdSz, len);
  250. pkcs7->stream->length += len;
  251. pkcs7->stream->idx += len;
  252. pkcs7->stream->totalRd += len;
  253. }
  254. #ifdef WC_PKCS7_STREAM_DEBUG
  255. /* collects memory usage for debugging */
  256. if (pkcs7->stream->length > pkcs7->stream->peakRead) {
  257. pkcs7->stream->peakRead = pkcs7->stream->length;
  258. }
  259. if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
  260. pkcs7->stream->tagSz > pkcs7->stream->peakUsed) {
  261. pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
  262. pkcs7->stream->aadSz + pkcs7->stream->nonceSz + pkcs7->stream->tagSz;
  263. }
  264. #endif
  265. /* if not enough data was read in then request more */
  266. if (pkcs7->stream->length < expected) {
  267. pkcs7->stream->idx = 0;
  268. return WC_PKCS7_WANT_READ_E;
  269. }
  270. /* adjust pointer to read from stored buffer */
  271. *idx = 0;
  272. *pt = pkcs7->stream->buffer;
  273. return 0;
  274. }
  275. /* setter function for stored variables */
  276. static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2,
  277. int var3)
  278. {
  279. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  280. pkcs7->stream->varOne = var1;
  281. pkcs7->stream->varTwo = var2;
  282. pkcs7->stream->varThree = var3;
  283. }
  284. }
  285. /* Tries to peek at the SEQ and get the length
  286. * returns 0 on success
  287. */
  288. static int wc_PKCS7_SetMaxStream(PKCS7* pkcs7, byte* in, word32 defSz)
  289. {
  290. /* check there is a buffer to read from */
  291. if (pkcs7) {
  292. int length = 0, ret;
  293. word32 idx = 0, maxIdx;
  294. byte* pt;
  295. if (pkcs7->stream->length > 0) {
  296. length = pkcs7->stream->length;
  297. pt = pkcs7->stream->buffer;
  298. }
  299. else {
  300. length = defSz;
  301. pt = in;
  302. }
  303. maxIdx = (word32)length;
  304. if (length < MAX_SEQ_SZ) {
  305. WOLFSSL_MSG("PKCS7 Error not enough data for SEQ peek");
  306. return 0;
  307. }
  308. if ((ret = GetSequence_ex(pt, &idx, &length, maxIdx, NO_USER_CHECK))
  309. < 0) {
  310. return ret;
  311. }
  312. #ifdef ASN_BER_TO_DER
  313. if (length == 0 && ret == 0) {
  314. idx = 0;
  315. if ((ret = wc_BerToDer(pt, maxIdx, NULL,
  316. (word32*)&length)) != LENGTH_ONLY_E) {
  317. return ret;
  318. }
  319. }
  320. #endif /* ASN_BER_TO_DER */
  321. pkcs7->stream->maxLen = length + idx;
  322. if (pkcs7->stream->maxLen == 0) {
  323. pkcs7->stream->maxLen = defSz;
  324. }
  325. }
  326. return 0;
  327. }
  328. /* getter function for stored variables */
  329. static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2,
  330. int* var3)
  331. {
  332. if (pkcs7 != NULL && pkcs7->stream != NULL) {
  333. if (var1 != NULL) *var1 = pkcs7->stream->varOne;
  334. if (var2 != NULL) *var2 = pkcs7->stream->varTwo;
  335. if (var3 != NULL) *var3 = pkcs7->stream->varThree;
  336. }
  337. }
  338. /* common update of index and total read after section complete
  339. * returns 0 on success */
  340. static int wc_PKCS7_StreamEndCase(PKCS7* pkcs7, word32* tmpIdx, word32* idx)
  341. {
  342. int ret = 0;
  343. if (pkcs7->stream->length > 0) {
  344. if (pkcs7->stream->length < *idx) {
  345. WOLFSSL_MSG("PKCS7 read too much data from internal buffer");
  346. ret = BUFFER_E;
  347. }
  348. else {
  349. XMEMMOVE(pkcs7->stream->buffer, pkcs7->stream->buffer + *idx,
  350. pkcs7->stream->length - *idx);
  351. pkcs7->stream->length -= *idx;
  352. }
  353. }
  354. else {
  355. pkcs7->stream->totalRd += *idx - *tmpIdx;
  356. pkcs7->stream->idx = *idx; /* adjust index into input buffer */
  357. *tmpIdx = *idx;
  358. }
  359. return ret;
  360. }
  361. #endif /* NO_PKCS7_STREAM */
  362. #ifdef WC_PKCS7_STREAM_DEBUG
  363. /* used to print out human readable state for debugging */
  364. static const char* wc_PKCS7_GetStateName(int in)
  365. {
  366. switch (in) {
  367. case WC_PKCS7_START: return "WC_PKCS7_START";
  368. case WC_PKCS7_STAGE2: return "WC_PKCS7_STAGE2";
  369. case WC_PKCS7_STAGE3: return "WC_PKCS7_STAGE3";
  370. case WC_PKCS7_STAGE4: return "WC_PKCS7_STAGE4";
  371. case WC_PKCS7_STAGE5: return "WC_PKCS7_STAGE5";
  372. case WC_PKCS7_STAGE6: return "WC_PKCS7_STAGE6";
  373. /* parse info set */
  374. case WC_PKCS7_INFOSET_START: return "WC_PKCS7_INFOSET_START";
  375. case WC_PKCS7_INFOSET_BER: return "WC_PKCS7_INFOSET_BER";
  376. case WC_PKCS7_INFOSET_STAGE1: return "WC_PKCS7_INFOSET_STAGE1";
  377. case WC_PKCS7_INFOSET_STAGE2: return "WC_PKCS7_INFOSET_STAGE2";
  378. case WC_PKCS7_INFOSET_END: return "WC_PKCS7_INFOSET_END";
  379. /* decode enveloped data */
  380. case WC_PKCS7_ENV_2: return "WC_PKCS7_ENV_2";
  381. case WC_PKCS7_ENV_3: return "WC_PKCS7_ENV_3";
  382. case WC_PKCS7_ENV_4: return "WC_PKCS7_ENV_4";
  383. case WC_PKCS7_ENV_5: return "WC_PKCS7_ENV_5";
  384. /* decode auth enveloped */
  385. case WC_PKCS7_AUTHENV_2: return "WC_PKCS7_AUTHENV_2";
  386. case WC_PKCS7_AUTHENV_3: return "WC_PKCS7_AUTHENV_3";
  387. case WC_PKCS7_AUTHENV_4: return "WC_PKCS7_AUTHENV_4";
  388. case WC_PKCS7_AUTHENV_5: return "WC_PKCS7_AUTHENV_5";
  389. case WC_PKCS7_AUTHENV_6: return "WC_PKCS7_AUTHENV_6";
  390. case WC_PKCS7_AUTHENV_ATRB: return "WC_PKCS7_AUTHENV_ATRB";
  391. case WC_PKCS7_AUTHENV_ATRBEND: return "WC_PKCS7_AUTHENV_ATRBEND";
  392. case WC_PKCS7_AUTHENV_7: return "WC_PKCS7_AUTHENV_7";
  393. /* decryption state types */
  394. case WC_PKCS7_DECRYPT_KTRI: return "WC_PKCS7_DECRYPT_KTRI";
  395. case WC_PKCS7_DECRYPT_KTRI_2: return "WC_PKCS7_DECRYPT_KTRI_2";
  396. case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
  397. case WC_PKCS7_DECRYPT_KARI: return "WC_PKCS7_DECRYPT_KARI";
  398. case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
  399. case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
  400. case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
  401. case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
  402. case WC_PKCS7_VERIFY_STAGE2: return "WC_PKCS7_VERIFY_STAGE2";
  403. case WC_PKCS7_VERIFY_STAGE3: return "WC_PKCS7_VERIFY_STAGE3";
  404. case WC_PKCS7_VERIFY_STAGE4: return "WC_PKCS7_VERIFY_STAGE4";
  405. case WC_PKCS7_VERIFY_STAGE5: return "WC_PKCS7_VERIFY_STAGE5";
  406. case WC_PKCS7_VERIFY_STAGE6: return "WC_PKCS7_VERIFY_STAGE6";
  407. default:
  408. return "Unknown state";
  409. }
  410. }
  411. #endif
  412. /* Used to change the PKCS7 state. Having state change as a function allows
  413. * for easier debugging */
  414. static void wc_PKCS7_ChangeState(PKCS7* pkcs7, int newState)
  415. {
  416. #ifdef WC_PKCS7_STREAM_DEBUG
  417. printf("\tChanging from state [%02d] %s to [%02d] %s\n",
  418. pkcs7->state, wc_PKCS7_GetStateName(pkcs7->state),
  419. newState, wc_PKCS7_GetStateName(newState));
  420. #endif
  421. pkcs7->state = newState;
  422. }
  423. #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \
  424. MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)
  425. /* placed ASN.1 contentType OID into *output, return idx on success,
  426. * 0 upon failure */
  427. static int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz)
  428. {
  429. /* PKCS#7 content types, RFC 2315, section 14 */
  430. static const byte pkcs7[] =
  431. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07 };
  432. static const byte data[] =
  433. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
  434. static const byte signedData[] =
  435. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
  436. static const byte envelopedData[] =
  437. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03 };
  438. static const byte authEnvelopedData[] =
  439. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x17};
  440. static const byte signedAndEnveloped[] =
  441. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04 };
  442. static const byte digestedData[] =
  443. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05 };
  444. #ifndef NO_PKCS7_ENCRYPTED_DATA
  445. static const byte encryptedData[] =
  446. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
  447. #endif
  448. /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), RFC 4108 */
  449. static const byte firmwarePkgData[] =
  450. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x10 };
  451. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  452. /* id-ct-compressedData (1.2.840.113549.1.9.16.1.9), RFC 3274 */
  453. static const byte compressedData[] =
  454. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x01, 0x09 };
  455. #endif
  456. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  457. static const byte pwriKek[] =
  458. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x03, 0x09 };
  459. static const byte pbkdf2[] =
  460. { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C };
  461. #endif
  462. int idSz, idx = 0;
  463. word32 typeSz = 0;
  464. const byte* typeName = 0;
  465. byte ID_Length[MAX_LENGTH_SZ];
  466. switch (pkcs7TypeOID) {
  467. case PKCS7_MSG:
  468. typeSz = sizeof(pkcs7);
  469. typeName = pkcs7;
  470. break;
  471. case DATA:
  472. typeSz = sizeof(data);
  473. typeName = data;
  474. break;
  475. case SIGNED_DATA:
  476. typeSz = sizeof(signedData);
  477. typeName = signedData;
  478. break;
  479. case ENVELOPED_DATA:
  480. typeSz = sizeof(envelopedData);
  481. typeName = envelopedData;
  482. break;
  483. case AUTH_ENVELOPED_DATA:
  484. typeSz = sizeof(authEnvelopedData);
  485. typeName = authEnvelopedData;
  486. break;
  487. case SIGNED_AND_ENVELOPED_DATA:
  488. typeSz = sizeof(signedAndEnveloped);
  489. typeName = signedAndEnveloped;
  490. break;
  491. case DIGESTED_DATA:
  492. typeSz = sizeof(digestedData);
  493. typeName = digestedData;
  494. break;
  495. #ifndef NO_PKCS7_ENCRYPTED_DATA
  496. case ENCRYPTED_DATA:
  497. typeSz = sizeof(encryptedData);
  498. typeName = encryptedData;
  499. break;
  500. #endif
  501. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  502. case COMPRESSED_DATA:
  503. typeSz = sizeof(compressedData);
  504. typeName = compressedData;
  505. break;
  506. #endif
  507. case FIRMWARE_PKG_DATA:
  508. typeSz = sizeof(firmwarePkgData);
  509. typeName = firmwarePkgData;
  510. break;
  511. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  512. case PWRI_KEK_WRAP:
  513. typeSz = sizeof(pwriKek);
  514. typeName = pwriKek;
  515. break;
  516. case PBKDF2_OID:
  517. typeSz = sizeof(pbkdf2);
  518. typeName = pbkdf2;
  519. break;
  520. #endif
  521. default:
  522. WOLFSSL_MSG("Unknown PKCS#7 Type");
  523. return 0;
  524. };
  525. if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) {
  526. WOLFSSL_MSG("CMS content type buffer too small");
  527. return BAD_FUNC_ARG;
  528. }
  529. idSz = SetLength(typeSz, ID_Length);
  530. output[idx++] = ASN_OBJECT_ID;
  531. XMEMCPY(output + idx, ID_Length, idSz);
  532. idx += idSz;
  533. XMEMCPY(output + idx, typeName, typeSz);
  534. idx += typeSz;
  535. return idx;
  536. }
  537. /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
  538. static int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
  539. word32 maxIdx)
  540. {
  541. WOLFSSL_ENTER("wc_GetContentType");
  542. if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0) {
  543. WOLFSSL_LEAVE("wc_GetContentType", ASN_PARSE_E);
  544. return ASN_PARSE_E;
  545. }
  546. return 0;
  547. }
  548. /* return block size for algorithm represented by oid, or <0 on error */
  549. static int wc_PKCS7_GetOIDBlockSize(int oid)
  550. {
  551. int blockSz;
  552. switch (oid) {
  553. #ifndef NO_AES
  554. #ifdef WOLFSSL_AES_128
  555. #ifdef HAVE_AES_CBC
  556. case AES128CBCb:
  557. #endif
  558. #ifdef HAVE_AESGCM
  559. case AES128GCMb:
  560. #endif
  561. #ifdef HAVE_AESCCM
  562. case AES128CCMb:
  563. #endif
  564. #endif
  565. #ifdef WOLFSSL_AES_192
  566. #ifdef HAVE_AES_CBC
  567. case AES192CBCb:
  568. #endif
  569. #ifdef HAVE_AESGCM
  570. case AES192GCMb:
  571. #endif
  572. #ifdef HAVE_AESCCM
  573. case AES192CCMb:
  574. #endif
  575. #endif
  576. #ifdef WOLFSSL_AES_256
  577. #ifdef HAVE_AES_CBC
  578. case AES256CBCb:
  579. #endif
  580. #ifdef HAVE_AESGCM
  581. case AES256GCMb:
  582. #endif
  583. #ifdef HAVE_AESCCM
  584. case AES256CCMb:
  585. #endif
  586. #endif
  587. blockSz = AES_BLOCK_SIZE;
  588. break;
  589. #endif /* !NO_AES */
  590. #ifndef NO_DES3
  591. case DESb:
  592. case DES3b:
  593. blockSz = DES_BLOCK_SIZE;
  594. break;
  595. #endif
  596. default:
  597. WOLFSSL_MSG("Unsupported content cipher type");
  598. return ALGO_ID_E;
  599. };
  600. return blockSz;
  601. }
  602. /* get key size for algorithm represented by oid, or <0 on error */
  603. static int wc_PKCS7_GetOIDKeySize(int oid)
  604. {
  605. int blockKeySz;
  606. switch (oid) {
  607. #ifndef NO_AES
  608. #ifdef WOLFSSL_AES_128
  609. #ifdef HAVE_AES_CBC
  610. case AES128CBCb:
  611. #endif
  612. #ifdef HAVE_AESGCM
  613. case AES128GCMb:
  614. #endif
  615. #ifdef HAVE_AESCCM
  616. case AES128CCMb:
  617. #endif
  618. case AES128_WRAP:
  619. blockKeySz = 16;
  620. break;
  621. #endif
  622. #ifdef WOLFSSL_AES_192
  623. #ifdef HAVE_AES_CBC
  624. case AES192CBCb:
  625. #endif
  626. #ifdef HAVE_AESGCM
  627. case AES192GCMb:
  628. #endif
  629. #ifdef HAVE_AESCCM
  630. case AES192CCMb:
  631. #endif
  632. case AES192_WRAP:
  633. blockKeySz = 24;
  634. break;
  635. #endif
  636. #ifdef WOLFSSL_AES_256
  637. #ifdef HAVE_AES_CBC
  638. case AES256CBCb:
  639. #endif
  640. #ifdef HAVE_AESGCM
  641. case AES256GCMb:
  642. #endif
  643. #ifdef HAVE_AESCCM
  644. case AES256CCMb:
  645. #endif
  646. case AES256_WRAP:
  647. blockKeySz = 32;
  648. break;
  649. #endif
  650. #endif /* !NO_AES */
  651. #ifndef NO_DES3
  652. case DESb:
  653. blockKeySz = DES_KEYLEN;
  654. break;
  655. case DES3b:
  656. blockKeySz = DES3_KEYLEN;
  657. break;
  658. #endif
  659. default:
  660. WOLFSSL_MSG("Unsupported content cipher type");
  661. return ALGO_ID_E;
  662. };
  663. return blockKeySz;
  664. }
  665. PKCS7* wc_PKCS7_New(void* heap, int devId)
  666. {
  667. PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);
  668. if (pkcs7) {
  669. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  670. if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {
  671. pkcs7->isDynamic = 1;
  672. }
  673. else {
  674. XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);
  675. pkcs7 = NULL;
  676. }
  677. }
  678. return pkcs7;
  679. }
  680. /* This is to initialize a PKCS7 structure. It sets all values to 0 and can be
  681. * used to set the heap hint.
  682. *
  683. * pkcs7 PKCS7 structure to initialize
  684. * heap memory heap hint for PKCS7 structure to use
  685. * devId currently not used but a place holder for async operations
  686. *
  687. * returns 0 on success or a negative value for failure
  688. */
  689. int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)
  690. {
  691. word16 isDynamic;
  692. WOLFSSL_ENTER("wc_PKCS7_Init");
  693. if (pkcs7 == NULL) {
  694. return BAD_FUNC_ARG;
  695. }
  696. isDynamic = pkcs7->isDynamic;
  697. XMEMSET(pkcs7, 0, sizeof(PKCS7));
  698. pkcs7->isDynamic = isDynamic;
  699. #ifdef WOLFSSL_HEAP_TEST
  700. pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;
  701. #else
  702. pkcs7->heap = heap;
  703. #endif
  704. pkcs7->devId = devId;
  705. return 0;
  706. }
  707. /* Certificate structure holding der pointer, size, and pointer to next
  708. * Pkcs7Cert struct. Used when creating SignedData types with multiple
  709. * certificates. */
  710. struct Pkcs7Cert {
  711. byte* der;
  712. word32 derSz;
  713. Pkcs7Cert* next;
  714. };
  715. /* Linked list of ASN.1 encoded RecipientInfos */
  716. struct Pkcs7EncodedRecip {
  717. byte recip[MAX_RECIP_SZ];
  718. word32 recipSz;
  719. int recipType;
  720. int recipVersion;
  721. Pkcs7EncodedRecip* next;
  722. };
  723. /* free all members of Pkcs7Cert linked list */
  724. static void wc_PKCS7_FreeCertSet(PKCS7* pkcs7)
  725. {
  726. Pkcs7Cert* curr = NULL;
  727. Pkcs7Cert* next = NULL;
  728. if (pkcs7 == NULL)
  729. return;
  730. curr = pkcs7->certList;
  731. pkcs7->certList = NULL;
  732. while (curr != NULL) {
  733. next = curr->next;
  734. curr->next = NULL;
  735. XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  736. curr = next;
  737. }
  738. return;
  739. }
  740. /* Get total size of all recipients in recipient list.
  741. *
  742. * Returns total size of recipients, or negative upon error */
  743. static int wc_PKCS7_GetRecipientListSize(PKCS7* pkcs7)
  744. {
  745. int totalSz = 0;
  746. Pkcs7EncodedRecip* tmp = NULL;
  747. if (pkcs7 == NULL)
  748. return BAD_FUNC_ARG;
  749. tmp = pkcs7->recipList;
  750. while (tmp != NULL) {
  751. totalSz += tmp->recipSz;
  752. tmp = tmp->next;
  753. }
  754. return totalSz;
  755. }
  756. /* free all members of Pkcs7EncodedRecip linked list */
  757. static void wc_PKCS7_FreeEncodedRecipientSet(PKCS7* pkcs7)
  758. {
  759. Pkcs7EncodedRecip* curr = NULL;
  760. Pkcs7EncodedRecip* next = NULL;
  761. if (pkcs7 == NULL)
  762. return;
  763. curr = pkcs7->recipList;
  764. pkcs7->recipList = NULL;
  765. while (curr != NULL) {
  766. next = curr->next;
  767. curr->next = NULL;
  768. XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  769. curr = next;
  770. }
  771. return;
  772. }
  773. /* search through RecipientInfo list for specific type.
  774. * return 1 if ANY recipient of type specified is present, otherwise
  775. * return 0 */
  776. static int wc_PKCS7_RecipientListIncludesType(PKCS7* pkcs7, int type)
  777. {
  778. Pkcs7EncodedRecip* tmp = NULL;
  779. if (pkcs7 == NULL)
  780. return BAD_FUNC_ARG;
  781. tmp = pkcs7->recipList;
  782. while (tmp != NULL) {
  783. if (tmp->recipType == type)
  784. return 1;
  785. tmp = tmp->next;
  786. }
  787. return 0;
  788. }
  789. /* searches through RecipientInfo list, returns 1 if all structure
  790. * versions are set to 0, otherwise returns 0 */
  791. static int wc_PKCS7_RecipientListVersionsAllZero(PKCS7* pkcs7)
  792. {
  793. Pkcs7EncodedRecip* tmp = NULL;
  794. if (pkcs7 == NULL)
  795. return BAD_FUNC_ARG;
  796. tmp = pkcs7->recipList;
  797. while (tmp != NULL) {
  798. if (tmp->recipVersion != 0)
  799. return 0;
  800. tmp = tmp->next;
  801. }
  802. return 1;
  803. }
  804. /* Verify RSA/ECC key is correctly formatted, used as sanity check after
  805. * import of key/cert.
  806. *
  807. * keyOID - key OID (ex: RSAk, ECDSAk)
  808. * key - key in DER
  809. * keySz - size of key, octets
  810. *
  811. * Returns 0 on success, negative on error */
  812. static int wc_PKCS7_CheckPublicKeyDer(PKCS7* pkcs7, int keyOID,
  813. const byte* key, word32 keySz)
  814. {
  815. int ret = 0;
  816. word32 scratch = 0;
  817. #ifdef WOLFSSL_SMALL_STACK
  818. #ifndef NO_RSA
  819. RsaKey* rsa;
  820. #endif
  821. #ifdef HAVE_ECC
  822. ecc_key* ecc;
  823. #endif
  824. #else
  825. #ifndef NO_RSA
  826. RsaKey rsa[1];
  827. #endif
  828. #ifdef HAVE_ECC
  829. ecc_key ecc[1];
  830. #endif
  831. #endif
  832. if (pkcs7 == NULL || key == NULL || keySz == 0) {
  833. return BAD_FUNC_ARG;
  834. }
  835. #ifdef WOLFSSL_SMALL_STACK
  836. #ifndef NO_RSA
  837. rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  838. DYNAMIC_TYPE_TMP_BUFFER);
  839. if (rsa == NULL) {
  840. return MEMORY_E;
  841. }
  842. #endif
  843. #ifdef HAVE_ECC
  844. ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  845. DYNAMIC_TYPE_TMP_BUFFER);
  846. if (ecc == NULL) {
  847. #ifndef NO_RSA
  848. XFREE(rsa, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  849. #endif
  850. return MEMORY_E;
  851. }
  852. #endif
  853. #endif
  854. switch (keyOID) {
  855. #ifndef NO_RSA
  856. case RSAk:
  857. ret = wc_InitRsaKey_ex(rsa, pkcs7->heap, pkcs7->devId);
  858. if (ret != 0) {
  859. break;
  860. }
  861. /* Try to decode public key as sanity check. wc_CheckRsaKey()
  862. only checks private key not public. */
  863. ret = wc_RsaPublicKeyDecode(key, &scratch, rsa, keySz);
  864. wc_FreeRsaKey(rsa);
  865. break;
  866. #endif
  867. #ifdef HAVE_ECC
  868. case ECDSAk:
  869. ret = wc_ecc_init_ex(ecc, pkcs7->heap, pkcs7->devId);
  870. if (ret != 0) {
  871. break;
  872. }
  873. /* Try to decode public key and check with wc_ecc_check_key() */
  874. ret = wc_EccPublicKeyDecode(key, &scratch, ecc, keySz);
  875. if (ret == 0) {
  876. ret = wc_ecc_check_key(ecc);
  877. }
  878. wc_ecc_free(ecc);
  879. break;
  880. #endif
  881. }
  882. #ifdef WOLFSSL_SMALL_STACK
  883. #ifndef NO_RSA
  884. XFREE(rsa, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  885. #endif
  886. #ifdef HAVE_ECC
  887. XFREE(ecc, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  888. #endif
  889. #endif
  890. return ret;
  891. }
  892. /* Init PKCS7 struct with recipient cert, decode into DecodedCert
  893. * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */
  894. int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  895. {
  896. int ret = 0;
  897. void* heap;
  898. int devId;
  899. Pkcs7Cert* cert;
  900. Pkcs7Cert* lastCert;
  901. if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) {
  902. return BAD_FUNC_ARG;
  903. }
  904. heap = pkcs7->heap;
  905. devId = pkcs7->devId;
  906. cert = pkcs7->certList;
  907. ret = wc_PKCS7_Init(pkcs7, heap, devId);
  908. if (ret != 0)
  909. return ret;
  910. pkcs7->certList = cert;
  911. if (derCert != NULL && derCertSz > 0) {
  912. #ifdef WOLFSSL_SMALL_STACK
  913. DecodedCert* dCert;
  914. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  915. DYNAMIC_TYPE_DCERT);
  916. if (dCert == NULL)
  917. return MEMORY_E;
  918. #else
  919. DecodedCert dCert[1];
  920. #endif
  921. pkcs7->singleCert = derCert;
  922. pkcs7->singleCertSz = derCertSz;
  923. pkcs7->cert[0] = derCert;
  924. pkcs7->certSz[0] = derCertSz;
  925. /* create new Pkcs7Cert for recipient, freed during cleanup */
  926. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  927. DYNAMIC_TYPE_PKCS7);
  928. XMEMSET(cert, 0, sizeof(Pkcs7Cert));
  929. cert->der = derCert;
  930. cert->derSz = derCertSz;
  931. cert->next = NULL;
  932. /* free existing cert list if existing */
  933. wc_PKCS7_FreeCertSet(pkcs7);
  934. /* add cert to list */
  935. if (pkcs7->certList == NULL) {
  936. pkcs7->certList = cert;
  937. } else {
  938. lastCert = pkcs7->certList;
  939. while (lastCert->next != NULL) {
  940. lastCert = lastCert->next;
  941. }
  942. lastCert->next = cert;
  943. }
  944. InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap);
  945. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  946. if (ret < 0) {
  947. FreeDecodedCert(dCert);
  948. #ifdef WOLFSSL_SMALL_STACK
  949. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  950. #endif
  951. return ret;
  952. }
  953. /* verify extracted public key is valid before storing */
  954. ret = wc_PKCS7_CheckPublicKeyDer(pkcs7, dCert->keyOID,
  955. dCert->publicKey, dCert->pubKeySize);
  956. if (ret != 0) {
  957. WOLFSSL_MSG("Invalid public key, check pkcs7->cert");
  958. FreeDecodedCert(dCert);
  959. #ifdef WOLFSSL_SMALL_STACK
  960. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  961. #endif
  962. return ret;
  963. }
  964. if (dCert->pubKeySize > (MAX_RSA_INT_SZ + MAX_RSA_E_SZ) ||
  965. dCert->serialSz > MAX_SN_SZ) {
  966. WOLFSSL_MSG("Invalid size in certificate");
  967. FreeDecodedCert(dCert);
  968. #ifdef WOLFSSL_SMALL_STACK
  969. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  970. #endif
  971. return ASN_PARSE_E;
  972. }
  973. XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
  974. pkcs7->publicKeySz = dCert->pubKeySize;
  975. pkcs7->publicKeyOID = dCert->keyOID;
  976. XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
  977. pkcs7->issuer = dCert->issuerRaw;
  978. pkcs7->issuerSz = dCert->issuerRawLen;
  979. XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
  980. pkcs7->issuerSnSz = dCert->serialSz;
  981. XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE);
  982. /* default to IssuerAndSerialNumber for SignerIdentifier */
  983. pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  984. /* free existing recipient list if existing */
  985. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  986. FreeDecodedCert(dCert);
  987. #ifdef WOLFSSL_SMALL_STACK
  988. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  989. #endif
  990. }
  991. return ret;
  992. }
  993. /* Adds one DER-formatted certificate to the internal PKCS7/CMS certificate
  994. * list, to be added as part of the certificates CertificateSet. Currently
  995. * used in SignedData content type.
  996. *
  997. * Must be called after wc_PKCS7_Init() or wc_PKCS7_InitWithCert().
  998. *
  999. * Does not represent the recipient/signer certificate, only certificates that
  1000. * are part of the certificate chain used to build and verify signer
  1001. * certificates.
  1002. *
  1003. * This API does not currently validate certificates.
  1004. *
  1005. * Returns 0 on success, negative upon error */
  1006. int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
  1007. {
  1008. Pkcs7Cert* cert;
  1009. if (pkcs7 == NULL || derCert == NULL || derCertSz == 0)
  1010. return BAD_FUNC_ARG;
  1011. cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
  1012. DYNAMIC_TYPE_PKCS7);
  1013. if (cert == NULL)
  1014. return MEMORY_E;
  1015. XMEMSET(cert, 0, sizeof(Pkcs7Cert));
  1016. cert->der = derCert;
  1017. cert->derSz = derCertSz;
  1018. if (pkcs7->certList == NULL) {
  1019. pkcs7->certList = cert;
  1020. } else {
  1021. cert->next = pkcs7->certList;
  1022. pkcs7->certList = cert;
  1023. }
  1024. return 0;
  1025. }
  1026. /* free linked list of PKCS7DecodedAttrib structs */
  1027. static void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)
  1028. {
  1029. PKCS7DecodedAttrib* current;
  1030. if (attrib == NULL) {
  1031. return;
  1032. }
  1033. current = attrib;
  1034. while (current != NULL) {
  1035. PKCS7DecodedAttrib* next = current->next;
  1036. if (current->oid != NULL) {
  1037. XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);
  1038. }
  1039. if (current->value != NULL) {
  1040. XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);
  1041. }
  1042. XFREE(current, heap, DYNAMIC_TYPE_PKCS7);
  1043. current = next;
  1044. }
  1045. (void)heap;
  1046. }
  1047. /* return 0 on success */
  1048. static int wc_PKCS7_SignerInfoNew(PKCS7* pkcs7)
  1049. {
  1050. if (pkcs7->signerInfo != NULL) {
  1051. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1052. pkcs7->signerInfo = NULL;
  1053. }
  1054. pkcs7->signerInfo = (PKCS7SignerInfo*)XMALLOC(sizeof(PKCS7SignerInfo),
  1055. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1056. if (pkcs7->signerInfo == NULL) {
  1057. WOLFSSL_MSG("Unable to malloc memory for signer info");
  1058. return MEMORY_E;
  1059. }
  1060. XMEMSET(pkcs7->signerInfo, 0, sizeof(PKCS7SignerInfo));
  1061. return 0;
  1062. }
  1063. static void wc_PKCS7_SignerInfoFree(PKCS7* pkcs7)
  1064. {
  1065. if (pkcs7->signerInfo != NULL) {
  1066. if (pkcs7->signerInfo->sid != NULL) {
  1067. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1068. pkcs7->signerInfo->sid = NULL;
  1069. }
  1070. XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1071. pkcs7->signerInfo = NULL;
  1072. }
  1073. }
  1074. /* free's any current SID and sets it to "in"
  1075. * returns 0 on success
  1076. */
  1077. static int wc_PKCS7_SignerInfoSetSID(PKCS7* pkcs7, byte* in, int inSz)
  1078. {
  1079. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  1080. return BAD_FUNC_ARG;
  1081. }
  1082. if (pkcs7->signerInfo->sid != NULL) {
  1083. XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1084. pkcs7->signerInfo->sid = NULL;
  1085. }
  1086. pkcs7->signerInfo->sid = (byte*)XMALLOC(inSz, pkcs7->heap,
  1087. DYNAMIC_TYPE_PKCS7);
  1088. if (pkcs7->signerInfo->sid == NULL) {
  1089. return MEMORY_E;
  1090. }
  1091. XMEMCPY(pkcs7->signerInfo->sid, in, inSz);
  1092. pkcs7->signerInfo->sidSz = inSz;
  1093. return 0;
  1094. }
  1095. /* releases any memory allocated by a PKCS7 initializer */
  1096. void wc_PKCS7_Free(PKCS7* pkcs7)
  1097. {
  1098. if (pkcs7 == NULL)
  1099. return;
  1100. #ifndef NO_PKCS7_STREAM
  1101. wc_PKCS7_FreeStream(pkcs7);
  1102. #endif
  1103. wc_PKCS7_SignerInfoFree(pkcs7);
  1104. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  1105. pkcs7->decodedAttrib = NULL;
  1106. wc_PKCS7_FreeCertSet(pkcs7);
  1107. #ifdef ASN_BER_TO_DER
  1108. if (pkcs7->der != NULL) {
  1109. XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1110. pkcs7->der = NULL;
  1111. }
  1112. #endif
  1113. if (pkcs7->contentDynamic != NULL) {
  1114. XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1115. pkcs7->contentDynamic = NULL;
  1116. }
  1117. if (pkcs7->cek != NULL) {
  1118. ForceZero(pkcs7->cek, pkcs7->cekSz);
  1119. XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1120. pkcs7->cek = NULL;
  1121. }
  1122. pkcs7->contentTypeSz = 0;
  1123. if (pkcs7->signature) {
  1124. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  1125. pkcs7->signature = NULL;
  1126. pkcs7->signatureSz = 0;
  1127. }
  1128. if (pkcs7->plainDigest) {
  1129. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  1130. pkcs7->plainDigest = NULL;
  1131. pkcs7->plainDigestSz = 0;
  1132. }
  1133. if (pkcs7->pkcs7Digest) {
  1134. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  1135. pkcs7->pkcs7Digest = NULL;
  1136. pkcs7->pkcs7DigestSz = 0;
  1137. }
  1138. if (pkcs7->cachedEncryptedContent != NULL) {
  1139. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1140. pkcs7->cachedEncryptedContent = NULL;
  1141. pkcs7->cachedEncryptedContentSz = 0;
  1142. }
  1143. if (pkcs7->isDynamic) {
  1144. pkcs7->isDynamic = 0;
  1145. XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  1146. }
  1147. }
  1148. /* helper function for parsing through attributes and finding a specific one.
  1149. * returns PKCS7DecodedAttrib pointer on success */
  1150. static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)
  1151. {
  1152. PKCS7DecodedAttrib* list;
  1153. if (pkcs7 == NULL || oid == NULL) {
  1154. return NULL;
  1155. }
  1156. /* search attributes for pkiStatus */
  1157. list = pkcs7->decodedAttrib;
  1158. while (list != NULL) {
  1159. word32 sz = oidSz;
  1160. word32 idx = 0;
  1161. int length = 0;
  1162. byte tag;
  1163. if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {
  1164. return NULL;
  1165. }
  1166. if (tag != ASN_OBJECT_ID) {
  1167. WOLFSSL_MSG("Bad attribute ASN1 syntax");
  1168. return NULL;
  1169. }
  1170. if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {
  1171. WOLFSSL_MSG("Bad attribute length");
  1172. return NULL;
  1173. }
  1174. sz = (sz < (word32)length)? sz : (word32)length;
  1175. if (XMEMCMP(oid, list->oid + idx, sz) == 0) {
  1176. return list;
  1177. }
  1178. list = list->next;
  1179. }
  1180. return NULL;
  1181. }
  1182. /* Searches through decoded attributes and returns the value for the first one
  1183. * matching the oid passed in. Note that this value includes the leading ASN1
  1184. * syntax. So for a printable string of "3" this would be something like
  1185. *
  1186. * 0x13, 0x01, 0x33
  1187. * ID SIZE "3"
  1188. *
  1189. * pkcs7 structure to get value from
  1190. * oid OID value to search for with attributes
  1191. * oidSz size of oid buffer
  1192. * out buffer to hold result
  1193. * outSz size of out buffer (if out is NULL this is set to needed size and
  1194. LENGTH_ONLY_E is returned)
  1195. *
  1196. * returns size of value on success
  1197. */
  1198. int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,
  1199. byte* out, word32* outSz)
  1200. {
  1201. PKCS7DecodedAttrib* attrib;
  1202. if (pkcs7 == NULL || oid == NULL || outSz == NULL) {
  1203. return BAD_FUNC_ARG;
  1204. }
  1205. attrib = findAttrib(pkcs7, oid, oidSz);
  1206. if (attrib == NULL) {
  1207. return ASN_PARSE_E;
  1208. }
  1209. if (out == NULL) {
  1210. *outSz = attrib->valueSz;
  1211. return LENGTH_ONLY_E;
  1212. }
  1213. if (*outSz < attrib->valueSz) {
  1214. return BUFFER_E;
  1215. }
  1216. XMEMCPY(out, attrib->value, attrib->valueSz);
  1217. return attrib->valueSz;
  1218. }
  1219. /* build PKCS#7 data content type */
  1220. int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
  1221. {
  1222. static const byte oid[] =
  1223. { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
  1224. 0x07, 0x01 };
  1225. byte seq[MAX_SEQ_SZ];
  1226. byte octetStr[MAX_OCTET_STR_SZ];
  1227. word32 seqSz;
  1228. word32 octetStrSz;
  1229. word32 oidSz = (word32)sizeof(oid);
  1230. int idx = 0;
  1231. if (pkcs7 == NULL || output == NULL) {
  1232. return BAD_FUNC_ARG;
  1233. }
  1234. octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
  1235. seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
  1236. if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
  1237. return BUFFER_E;
  1238. XMEMCPY(output, seq, seqSz);
  1239. idx += seqSz;
  1240. XMEMCPY(output + idx, oid, oidSz);
  1241. idx += oidSz;
  1242. XMEMCPY(output + idx, octetStr, octetStrSz);
  1243. idx += octetStrSz;
  1244. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  1245. idx += pkcs7->contentSz;
  1246. return idx;
  1247. }
  1248. typedef struct EncodedAttrib {
  1249. byte valueSeq[MAX_SEQ_SZ];
  1250. const byte* oid;
  1251. byte valueSet[MAX_SET_SZ];
  1252. const byte* value;
  1253. word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
  1254. } EncodedAttrib;
  1255. typedef struct ESD {
  1256. wc_HashAlg hash;
  1257. enum wc_HashType hashType;
  1258. byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
  1259. byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];
  1260. byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];
  1261. byte outerSeq[MAX_SEQ_SZ];
  1262. byte outerContent[MAX_EXP_SZ];
  1263. byte innerSeq[MAX_SEQ_SZ];
  1264. byte version[MAX_VERSION_SZ];
  1265. byte digAlgoIdSet[MAX_SET_SZ];
  1266. byte singleDigAlgoId[MAX_ALGO_SZ];
  1267. byte contentInfoSeq[MAX_SEQ_SZ];
  1268. byte innerContSeq[MAX_EXP_SZ];
  1269. byte innerOctets[MAX_OCTET_STR_SZ];
  1270. byte certsSet[MAX_SET_SZ];
  1271. byte signerInfoSet[MAX_SET_SZ];
  1272. byte signerInfoSeq[MAX_SEQ_SZ];
  1273. byte signerVersion[MAX_VERSION_SZ];
  1274. /* issuerAndSerialNumber ...*/
  1275. byte issuerSnSeq[MAX_SEQ_SZ];
  1276. byte issuerName[MAX_SEQ_SZ];
  1277. byte issuerSn[MAX_SN_SZ];
  1278. /* OR subjectKeyIdentifier */
  1279. byte issuerSKIDSeq[MAX_SEQ_SZ];
  1280. byte issuerSKID[MAX_OCTET_STR_SZ];
  1281. byte signerDigAlgoId[MAX_ALGO_SZ];
  1282. byte digEncAlgoId[MAX_ALGO_SZ];
  1283. byte signedAttribSet[MAX_SET_SZ];
  1284. EncodedAttrib signedAttribs[7];
  1285. byte signerDigest[MAX_OCTET_STR_SZ];
  1286. word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
  1287. word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
  1288. singleDigAlgoIdSz, certsSetSz;
  1289. word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
  1290. issuerSnSeqSz, issuerNameSz, issuerSnSz, issuerSKIDSz,
  1291. issuerSKIDSeqSz, signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
  1292. word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
  1293. signedAttribSetSz;
  1294. } ESD;
  1295. static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
  1296. PKCS7Attrib* attribs, int attribsSz)
  1297. {
  1298. int i;
  1299. int maxSz = min(eaSz, attribsSz);
  1300. int allAttribsSz = 0;
  1301. for (i = 0; i < maxSz; i++)
  1302. {
  1303. int attribSz = 0;
  1304. ea[i].value = attribs[i].value;
  1305. ea[i].valueSz = attribs[i].valueSz;
  1306. attribSz += ea[i].valueSz;
  1307. ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
  1308. attribSz += ea[i].valueSetSz;
  1309. ea[i].oid = attribs[i].oid;
  1310. ea[i].oidSz = attribs[i].oidSz;
  1311. attribSz += ea[i].oidSz;
  1312. ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
  1313. attribSz += ea[i].valueSeqSz;
  1314. ea[i].totalSz = attribSz;
  1315. allAttribsSz += attribSz;
  1316. }
  1317. return allAttribsSz;
  1318. }
  1319. typedef struct FlatAttrib {
  1320. byte* data;
  1321. word32 dataSz;
  1322. } FlatAttrib;
  1323. /* Returns a pointer to FlatAttrib whose members are initialized to 0.
  1324. * Caller is expected to free.
  1325. */
  1326. static FlatAttrib* NewAttrib(void* heap)
  1327. {
  1328. FlatAttrib* fb = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), heap,
  1329. DYNAMIC_TYPE_TMP_BUFFER);
  1330. if (fb != NULL) {
  1331. ForceZero(fb, sizeof(FlatAttrib));
  1332. }
  1333. (void)heap;
  1334. return fb;
  1335. }
  1336. /* Free FlatAttrib array and memory allocated to internal struct members */
  1337. static void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)
  1338. {
  1339. int i;
  1340. if (arr) {
  1341. for (i = 0; i < rows; i++) {
  1342. if (arr[i]) {
  1343. if (arr[i]->data) {
  1344. ForceZero(arr[i]->data, arr[i]->dataSz);
  1345. XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1346. }
  1347. ForceZero(arr[i], sizeof(FlatAttrib));
  1348. XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1349. }
  1350. }
  1351. ForceZero(arr, rows);
  1352. XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1353. }
  1354. (void)pkcs7;
  1355. }
  1356. /* Sort FlatAttrib array in ascending order */
  1357. static int SortAttribArray(FlatAttrib** arr, int rows)
  1358. {
  1359. int i, j;
  1360. word32 minSz, minIdx;
  1361. FlatAttrib* a = NULL;
  1362. FlatAttrib* b = NULL;
  1363. FlatAttrib* tmp = NULL;
  1364. if (arr == NULL) {
  1365. return BAD_FUNC_ARG;
  1366. }
  1367. for (i = 0; i < rows; i++) {
  1368. a = arr[i];
  1369. minSz = a->dataSz;
  1370. minIdx = i;
  1371. for (j = i+1; j < rows; j++) {
  1372. b = arr[j];
  1373. if (b->dataSz < minSz) {
  1374. minSz = b->dataSz;
  1375. minIdx = j;
  1376. }
  1377. }
  1378. if (minSz < a->dataSz) {
  1379. /* swap array positions */
  1380. tmp = arr[i];
  1381. arr[i] = arr[minIdx];
  1382. arr[minIdx] = tmp;
  1383. }
  1384. }
  1385. return 0;
  1386. }
  1387. /* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib
  1388. * holds flattened DER encoding of each attribute */
  1389. static int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,
  1390. EncodedAttrib* ea, int eaSz)
  1391. {
  1392. int i, idx, sz;
  1393. byte* output = NULL;
  1394. FlatAttrib* fa = NULL;
  1395. if (pkcs7 == NULL || derArr == NULL || ea == NULL) {
  1396. WOLFSSL_MSG("Invalid arguments to FlattenEncodedAttribs");
  1397. return BAD_FUNC_ARG;
  1398. }
  1399. if (rows != eaSz) {
  1400. WOLFSSL_MSG("DER array not large enough to hold attribute count");
  1401. return BAD_FUNC_ARG;
  1402. }
  1403. for (i = 0; i < eaSz; i++) {
  1404. sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;
  1405. output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1406. if (output == NULL) {
  1407. return MEMORY_E;
  1408. }
  1409. idx = 0;
  1410. XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
  1411. idx += ea[i].valueSeqSz;
  1412. XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
  1413. idx += ea[i].oidSz;
  1414. XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
  1415. idx += ea[i].valueSetSz;
  1416. XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
  1417. fa = derArr[i];
  1418. fa->data = output;
  1419. fa->dataSz = sz;
  1420. }
  1421. return 0;
  1422. }
  1423. /* Sort and Flatten EncodedAttrib attributes into output buffer */
  1424. static int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,
  1425. int eaSz)
  1426. {
  1427. int i, idx, ret;
  1428. FlatAttrib** derArr = NULL;
  1429. FlatAttrib* fa = NULL;
  1430. if (pkcs7 == NULL || output == NULL || ea == NULL) {
  1431. return BAD_FUNC_ARG;
  1432. }
  1433. /* create array of FlatAttrib struct pointers to hold DER attribs */
  1434. derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,
  1435. DYNAMIC_TYPE_TMP_BUFFER);
  1436. if (derArr == NULL) {
  1437. return MEMORY_E;
  1438. }
  1439. XMEMSET(derArr, 0, eaSz * sizeof(FlatAttrib*));
  1440. for (i = 0; i < eaSz; i++) {
  1441. derArr[i] = NewAttrib(pkcs7->heap);
  1442. if (derArr[i] == NULL) {
  1443. FreeAttribArray(pkcs7, derArr, eaSz);
  1444. return MEMORY_E;
  1445. }
  1446. ForceZero(derArr[i], sizeof(FlatAttrib));
  1447. }
  1448. /* flatten EncodedAttrib into DER byte arrays */
  1449. ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);
  1450. if (ret != 0) {
  1451. FreeAttribArray(pkcs7, derArr, eaSz);
  1452. return ret;
  1453. }
  1454. /* SET OF DER signed attributes must be sorted in ascending order */
  1455. ret = SortAttribArray(derArr, eaSz);
  1456. if (ret != 0) {
  1457. FreeAttribArray(pkcs7, derArr, eaSz);
  1458. return ret;
  1459. }
  1460. /* copy sorted DER attribute arrays into output buffer */
  1461. idx = 0;
  1462. for (i = 0; i < eaSz; i++) {
  1463. fa = derArr[i];
  1464. XMEMCPY(output + idx, fa->data, fa->dataSz);
  1465. idx += fa->dataSz;
  1466. }
  1467. FreeAttribArray(pkcs7, derArr, eaSz);
  1468. return 0;
  1469. }
  1470. #ifndef NO_RSA
  1471. /* returns size of signature put into out, negative on error */
  1472. static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1473. {
  1474. int ret;
  1475. word32 idx;
  1476. #ifdef WOLFSSL_SMALL_STACK
  1477. RsaKey* privKey;
  1478. #else
  1479. RsaKey privKey[1];
  1480. #endif
  1481. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1482. return BAD_FUNC_ARG;
  1483. }
  1484. #ifdef WOLFSSL_SMALL_STACK
  1485. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  1486. DYNAMIC_TYPE_TMP_BUFFER);
  1487. if (privKey == NULL)
  1488. return MEMORY_E;
  1489. #endif
  1490. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
  1491. if (ret == 0) {
  1492. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1493. idx = 0;
  1494. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1495. pkcs7->privateKeySz);
  1496. /* If not using old FIPS or CAVP selftest, or not using FAST,
  1497. * or USER RSA, able to check RSA key. */
  1498. if (ret == 0) {
  1499. #ifdef WOLFSSL_RSA_KEY_CHECK
  1500. /* verify imported private key is a valid key before using it */
  1501. ret = wc_CheckRsaKey(privKey);
  1502. if (ret != 0) {
  1503. WOLFSSL_MSG("Invalid RSA private key, check "
  1504. "pkcs7->privateKey");
  1505. }
  1506. #endif
  1507. }
  1508. #ifdef WOLF_CRYPTO_CB
  1509. else if (ret == ASN_PARSE_E && pkcs7->devId != INVALID_DEVID) {
  1510. /* if using crypto callbacks, try public key decode */
  1511. idx = 0;
  1512. ret = wc_RsaPublicKeyDecode(pkcs7->privateKey, &idx, privKey,
  1513. pkcs7->privateKeySz);
  1514. }
  1515. #endif
  1516. }
  1517. else if (pkcs7->devId == INVALID_DEVID) {
  1518. ret = BAD_FUNC_ARG;
  1519. }
  1520. }
  1521. if (ret == 0) {
  1522. #ifdef WOLFSSL_ASYNC_CRYPT
  1523. do {
  1524. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1525. WC_ASYNC_FLAG_CALL_AGAIN);
  1526. if (ret >= 0)
  1527. #endif
  1528. {
  1529. ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
  1530. sizeof(esd->encContentDigest),
  1531. privKey, pkcs7->rng);
  1532. }
  1533. #ifdef WOLFSSL_ASYNC_CRYPT
  1534. } while (ret == WC_PENDING_E);
  1535. #endif
  1536. }
  1537. wc_FreeRsaKey(privKey);
  1538. #ifdef WOLFSSL_SMALL_STACK
  1539. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1540. #endif
  1541. return ret;
  1542. }
  1543. #endif /* NO_RSA */
  1544. #ifdef HAVE_ECC
  1545. /* returns size of signature put into out, negative on error */
  1546. static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
  1547. {
  1548. int ret;
  1549. word32 outSz, idx;
  1550. #ifdef WOLFSSL_SMALL_STACK
  1551. ecc_key* privKey;
  1552. #else
  1553. ecc_key privKey[1];
  1554. #endif
  1555. if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
  1556. return BAD_FUNC_ARG;
  1557. }
  1558. #ifdef WOLFSSL_SMALL_STACK
  1559. privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  1560. DYNAMIC_TYPE_TMP_BUFFER);
  1561. if (privKey == NULL)
  1562. return MEMORY_E;
  1563. #endif
  1564. ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);
  1565. if (ret == 0) {
  1566. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  1567. idx = 0;
  1568. ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
  1569. pkcs7->privateKeySz);
  1570. /* verify imported private key is a valid key before using it */
  1571. if (ret == 0) {
  1572. ret = wc_ecc_check_key(privKey);
  1573. if (ret != 0) {
  1574. WOLFSSL_MSG("Invalid ECC private key, check "
  1575. "pkcs7->privateKey");
  1576. }
  1577. }
  1578. #ifdef WOLF_CRYPTO_CB
  1579. else if (ret == ASN_PARSE_E && pkcs7->devId != INVALID_DEVID) {
  1580. /* if using crypto callbacks, try public key decode */
  1581. idx = 0;
  1582. ret = wc_EccPublicKeyDecode(pkcs7->privateKey, &idx, privKey,
  1583. pkcs7->privateKeySz);
  1584. }
  1585. #endif
  1586. }
  1587. else if (pkcs7->devId == INVALID_DEVID) {
  1588. ret = BAD_FUNC_ARG;
  1589. }
  1590. }
  1591. if (ret == 0) {
  1592. outSz = sizeof(esd->encContentDigest);
  1593. #ifdef WOLFSSL_ASYNC_CRYPT
  1594. do {
  1595. ret = wc_AsyncWait(ret, &privKey->asyncDev,
  1596. WC_ASYNC_FLAG_CALL_AGAIN);
  1597. if (ret >= 0)
  1598. #endif
  1599. {
  1600. ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
  1601. &outSz, pkcs7->rng, privKey);
  1602. }
  1603. #ifdef WOLFSSL_ASYNC_CRYPT
  1604. } while (ret == WC_PENDING_E);
  1605. #endif
  1606. if (ret == 0)
  1607. ret = (int)outSz;
  1608. }
  1609. wc_ecc_free(privKey);
  1610. #ifdef WOLFSSL_SMALL_STACK
  1611. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1612. #endif
  1613. return ret;
  1614. }
  1615. #endif /* HAVE_ECC */
  1616. /* builds up SignedData signed attributes, including default ones.
  1617. *
  1618. * pkcs7 - pointer to initialized PKCS7 structure
  1619. * esd - pointer to initialized ESD structure, used for output
  1620. *
  1621. * return 0 on success, negative on error */
  1622. static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
  1623. const byte* contentType, word32 contentTypeSz,
  1624. const byte* contentTypeOid, word32 contentTypeOidSz,
  1625. const byte* messageDigestOid, word32 messageDigestOidSz,
  1626. const byte* signingTimeOid, word32 signingTimeOidSz,
  1627. byte* signingTime, word32 signingTimeSz)
  1628. {
  1629. int hashSz;
  1630. #ifdef NO_ASN_TIME
  1631. PKCS7Attrib cannedAttribs[2];
  1632. #else
  1633. time_t tm;
  1634. int timeSz;
  1635. PKCS7Attrib cannedAttribs[3];
  1636. #endif
  1637. word32 idx = 0;
  1638. word32 atrIdx = 0;
  1639. word32 cannedAttribsCount;
  1640. if (pkcs7 == NULL || esd == NULL || contentType == NULL ||
  1641. contentTypeOid == NULL || messageDigestOid == NULL ||
  1642. signingTimeOid == NULL) {
  1643. return BAD_FUNC_ARG;
  1644. }
  1645. if (pkcs7->skipDefaultSignedAttribs == 0) {
  1646. hashSz = wc_HashGetDigestSize(esd->hashType);
  1647. if (hashSz < 0)
  1648. return hashSz;
  1649. #ifndef NO_ASN_TIME
  1650. if (signingTime == NULL || signingTimeSz == 0)
  1651. return BAD_FUNC_ARG;
  1652. tm = wc_Time(0);
  1653. timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz);
  1654. if (timeSz < 0)
  1655. return timeSz;
  1656. #endif
  1657. cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
  1658. cannedAttribs[idx].oid = contentTypeOid;
  1659. cannedAttribs[idx].oidSz = contentTypeOidSz;
  1660. cannedAttribs[idx].value = contentType;
  1661. cannedAttribs[idx].valueSz = contentTypeSz;
  1662. idx++;
  1663. #ifndef NO_ASN_TIME
  1664. cannedAttribs[idx].oid = signingTimeOid;
  1665. cannedAttribs[idx].oidSz = signingTimeOidSz;
  1666. cannedAttribs[idx].value = signingTime;
  1667. cannedAttribs[idx].valueSz = timeSz;
  1668. idx++;
  1669. #endif
  1670. cannedAttribs[idx].oid = messageDigestOid;
  1671. cannedAttribs[idx].oidSz = messageDigestOidSz;
  1672. cannedAttribs[idx].value = esd->contentDigest;
  1673. cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */
  1674. idx++;
  1675. esd->signedAttribsCount += cannedAttribsCount;
  1676. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx],
  1677. idx, cannedAttribs, cannedAttribsCount);
  1678. atrIdx += idx;
  1679. } else {
  1680. esd->signedAttribsCount = 0;
  1681. esd->signedAttribsSz = 0;
  1682. }
  1683. /* add custom signed attributes if set */
  1684. if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) {
  1685. esd->signedAttribsCount += pkcs7->signedAttribsSz;
  1686. #ifdef NO_ASN_TIME
  1687. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx],
  1688. esd->signedAttribsCount,
  1689. pkcs7->signedAttribs, pkcs7->signedAttribsSz);
  1690. #else
  1691. esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx],
  1692. esd->signedAttribsCount,
  1693. pkcs7->signedAttribs, pkcs7->signedAttribsSz);
  1694. #endif
  1695. }
  1696. #ifdef NO_ASN_TIME
  1697. (void)signingTimeOidSz;
  1698. (void)signingTime;
  1699. (void)signingTimeSz;
  1700. #endif
  1701. return 0;
  1702. }
  1703. /* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or
  1704. * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.
  1705. *
  1706. * pkcs7 - pointer to PKCS7 structure
  1707. * digEncAlgoId - [OUT] output int to store correct algo ID in
  1708. * digEncAlgoType - [OUT] output for algo ID type
  1709. *
  1710. * return 0 on success, negative on error */
  1711. static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
  1712. int* digEncAlgoType)
  1713. {
  1714. int algoId = 0;
  1715. int algoType = 0;
  1716. if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
  1717. return BAD_FUNC_ARG;
  1718. if (pkcs7->publicKeyOID == RSAk) {
  1719. algoType = oidSigType;
  1720. switch (pkcs7->hashOID) {
  1721. #ifndef NO_SHA
  1722. case SHAh:
  1723. algoId = CTC_SHAwRSA;
  1724. break;
  1725. #endif
  1726. #ifdef WOLFSSL_SHA224
  1727. case SHA224h:
  1728. algoId = CTC_SHA224wRSA;
  1729. break;
  1730. #endif
  1731. #ifndef NO_SHA256
  1732. case SHA256h:
  1733. algoId = CTC_SHA256wRSA;
  1734. break;
  1735. #endif
  1736. #ifdef WOLFSSL_SHA384
  1737. case SHA384h:
  1738. algoId = CTC_SHA384wRSA;
  1739. break;
  1740. #endif
  1741. #ifdef WOLFSSL_SHA512
  1742. case SHA512h:
  1743. algoId = CTC_SHA512wRSA;
  1744. break;
  1745. #endif
  1746. #ifdef WOLFSSL_SHA3
  1747. #ifndef WOLFSSL_NOSHA3_224
  1748. case SHA3_224h:
  1749. algoId = CTC_SHA3_224wRSA;
  1750. break;
  1751. #endif
  1752. #ifndef WOLFSSL_NOSHA3_256
  1753. case SHA3_256h:
  1754. algoId = CTC_SHA3_256wRSA;
  1755. break;
  1756. #endif
  1757. #ifndef WOLFSSL_NOSHA3_384
  1758. case SHA3_384h:
  1759. algoId = CTC_SHA3_384wRSA;
  1760. break;
  1761. #endif
  1762. #ifndef WOLFSSL_NOSHA3_512
  1763. case SHA3_512h:
  1764. algoId = CTC_SHA3_512wRSA;
  1765. break;
  1766. #endif
  1767. #endif
  1768. }
  1769. }
  1770. #ifdef HAVE_ECC
  1771. else if (pkcs7->publicKeyOID == ECDSAk) {
  1772. algoType = oidSigType;
  1773. switch (pkcs7->hashOID) {
  1774. #ifndef NO_SHA
  1775. case SHAh:
  1776. algoId = CTC_SHAwECDSA;
  1777. break;
  1778. #endif
  1779. #ifdef WOLFSSL_SHA224
  1780. case SHA224h:
  1781. algoId = CTC_SHA224wECDSA;
  1782. break;
  1783. #endif
  1784. #ifndef NO_SHA256
  1785. case SHA256h:
  1786. algoId = CTC_SHA256wECDSA;
  1787. break;
  1788. #endif
  1789. #ifdef WOLFSSL_SHA384
  1790. case SHA384h:
  1791. algoId = CTC_SHA384wECDSA;
  1792. break;
  1793. #endif
  1794. #ifdef WOLFSSL_SHA512
  1795. case SHA512h:
  1796. algoId = CTC_SHA512wECDSA;
  1797. break;
  1798. #endif
  1799. #ifdef WOLFSSL_SHA3
  1800. #ifndef WOLFSSL_NOSHA3_224
  1801. case SHA3_224h:
  1802. algoId = CTC_SHA3_224wECDSA;
  1803. break;
  1804. #endif
  1805. #ifndef WOLFSSL_NOSHA3_256
  1806. case SHA3_256h:
  1807. algoId = CTC_SHA3_256wECDSA;
  1808. break;
  1809. #endif
  1810. #ifndef WOLFSSL_NOSHA3_384
  1811. case SHA3_384h:
  1812. algoId = CTC_SHA3_384wECDSA;
  1813. break;
  1814. #endif
  1815. #ifndef WOLFSSL_NOSHA3_512
  1816. case SHA3_512h:
  1817. algoId = CTC_SHA3_512wECDSA;
  1818. break;
  1819. #endif
  1820. #endif
  1821. }
  1822. }
  1823. #endif /* HAVE_ECC */
  1824. if (algoId == 0) {
  1825. WOLFSSL_MSG("Invalid signature algorithm type");
  1826. return BAD_FUNC_ARG;
  1827. }
  1828. *digEncAlgoId = algoId;
  1829. *digEncAlgoType = algoType;
  1830. return 0;
  1831. }
  1832. /* build SignedData DigestInfo for use with PKCS#7/RSA
  1833. *
  1834. * pkcs7 - pointer to initialized PKCS7 struct
  1835. * flatSignedAttribs - flattened, signed attributes
  1836. * flatSignedAttrbsSz - size of flatSignedAttribs, octets
  1837. * esd - pointer to initialized ESD struct
  1838. * digestInfo - [OUT] output array for DigestInfo
  1839. * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
  1840. *
  1841. * return 0 on success, negative on error */
  1842. static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
  1843. word32 flatSignedAttribsSz, ESD* esd,
  1844. byte* digestInfo, word32* digestInfoSz)
  1845. {
  1846. int ret, hashSz, digIdx = 0;
  1847. byte digestInfoSeq[MAX_SEQ_SZ];
  1848. byte digestStr[MAX_OCTET_STR_SZ];
  1849. byte attribSet[MAX_SET_SZ];
  1850. byte algoId[MAX_ALGO_SZ];
  1851. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  1852. word32 attribSetSz;
  1853. if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||
  1854. digestInfoSz == NULL) {
  1855. return BAD_FUNC_ARG;
  1856. }
  1857. hashSz = wc_HashGetDigestSize(esd->hashType);
  1858. if (hashSz < 0)
  1859. return hashSz;
  1860. if (flatSignedAttribsSz != 0) {
  1861. if (flatSignedAttribs == NULL)
  1862. return BAD_FUNC_ARG;
  1863. attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
  1864. ret = wc_HashInit(&esd->hash, esd->hashType);
  1865. if (ret < 0)
  1866. return ret;
  1867. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1868. attribSet, attribSetSz);
  1869. if (ret == 0)
  1870. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  1871. flatSignedAttribs, flatSignedAttribsSz);
  1872. if (ret == 0)
  1873. ret = wc_HashFinal(&esd->hash, esd->hashType,
  1874. esd->contentAttribsDigest);
  1875. wc_HashFree(&esd->hash, esd->hashType);
  1876. if (ret < 0)
  1877. return ret;
  1878. } else {
  1879. /* when no attrs, digest is contentDigest without tag and length */
  1880. XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);
  1881. }
  1882. /* set algoID, with NULL attributes */
  1883. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  1884. digestStrSz = SetOctetString(hashSz, digestStr);
  1885. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  1886. digestInfoSeq);
  1887. if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {
  1888. return BUFFER_E;
  1889. }
  1890. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  1891. digIdx += digestInfoSeqSz;
  1892. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  1893. digIdx += algoIdSz;
  1894. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  1895. digIdx += digestStrSz;
  1896. XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);
  1897. digIdx += hashSz;
  1898. *digestInfoSz = digIdx;
  1899. return 0;
  1900. }
  1901. /* build SignedData signature over DigestInfo or content digest
  1902. *
  1903. * pkcs7 - pointer to initialized PKCS7 struct
  1904. * flatSignedAttribs - flattened, signed attributes
  1905. * flatSignedAttribsSz - size of flatSignedAttribs, octets
  1906. * esd - pointer to initialized ESD struct
  1907. *
  1908. * returns length of signature on success, negative on error */
  1909. static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
  1910. byte* flatSignedAttribs,
  1911. word32 flatSignedAttribsSz,
  1912. ESD* esd)
  1913. {
  1914. int ret = 0;
  1915. #if defined(HAVE_ECC) || \
  1916. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1917. int hashSz = 0;
  1918. #endif
  1919. #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
  1920. int hashOID;
  1921. #endif
  1922. word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
  1923. #ifdef WOLFSSL_SMALL_STACK
  1924. byte* digestInfo;
  1925. #else
  1926. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  1927. #endif
  1928. if (pkcs7 == NULL || esd == NULL)
  1929. return BAD_FUNC_ARG;
  1930. #ifdef WOLFSSL_SMALL_STACK
  1931. digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,
  1932. DYNAMIC_TYPE_TMP_BUFFER);
  1933. if (digestInfo == NULL) {
  1934. return MEMORY_E;
  1935. }
  1936. #endif
  1937. XMEMSET(digestInfo, 0, digestInfoSz);
  1938. ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
  1939. flatSignedAttribsSz, esd, digestInfo,
  1940. &digestInfoSz);
  1941. if (ret < 0) {
  1942. #ifdef WOLFSSL_SMALL_STACK
  1943. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1944. #endif
  1945. return ret;
  1946. }
  1947. #if defined(HAVE_ECC) || \
  1948. (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
  1949. /* get digest size from hash type */
  1950. hashSz = wc_HashGetDigestSize(esd->hashType);
  1951. if (hashSz < 0) {
  1952. #ifdef WOLFSSL_SMALL_STACK
  1953. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1954. #endif
  1955. return hashSz;
  1956. }
  1957. #endif
  1958. /* sign digestInfo */
  1959. switch (pkcs7->publicKeyOID) {
  1960. #ifndef NO_RSA
  1961. case RSAk:
  1962. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  1963. if (pkcs7->rsaSignRawDigestCb != NULL) {
  1964. /* get hash OID */
  1965. hashOID = wc_HashGetOID(esd->hashType);
  1966. /* user signing plain digest, build DigestInfo themselves */
  1967. ret = pkcs7->rsaSignRawDigestCb(pkcs7,
  1968. esd->contentAttribsDigest, hashSz,
  1969. esd->encContentDigest, sizeof(esd->encContentDigest),
  1970. pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
  1971. hashOID);
  1972. break;
  1973. }
  1974. #endif
  1975. ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
  1976. break;
  1977. #endif
  1978. #ifdef HAVE_ECC
  1979. case ECDSAk:
  1980. /* CMS with ECDSA does not sign DigestInfo structure
  1981. * like PKCS#7 with RSA does */
  1982. ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
  1983. hashSz, esd);
  1984. break;
  1985. #endif
  1986. default:
  1987. WOLFSSL_MSG("Unsupported public key type");
  1988. ret = BAD_FUNC_ARG;
  1989. }
  1990. #ifdef WOLFSSL_SMALL_STACK
  1991. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  1992. #endif
  1993. if (ret >= 0) {
  1994. esd->encContentDigestSz = (word32)ret;
  1995. }
  1996. return ret;
  1997. }
  1998. /* build PKCS#7 signedData content type */
  1999. /* To get the output size then set output = 0 and *outputSz = 0 */
  2000. static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
  2001. const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,
  2002. byte* output2, word32* output2Sz)
  2003. {
  2004. /* contentType OID (1.2.840.113549.1.9.3) */
  2005. static const byte contentTypeOid[] =
  2006. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  2007. 0x09, 0x03 };
  2008. /* messageDigest OID (1.2.840.113549.1.9.4) */
  2009. static const byte messageDigestOid[] =
  2010. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  2011. 0x09, 0x04 };
  2012. /* signingTime OID () */
  2013. static const byte signingTimeOid[] =
  2014. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  2015. 0x09, 0x05};
  2016. Pkcs7Cert* certPtr = NULL;
  2017. word32 certSetSz = 0;
  2018. word32 signerInfoSz = 0;
  2019. word32 totalSz, total2Sz;
  2020. int idx = 0, ret = 0;
  2021. int digEncAlgoId, digEncAlgoType;
  2022. byte* flatSignedAttribs = NULL;
  2023. word32 flatSignedAttribsSz = 0;
  2024. #ifdef WOLFSSL_SMALL_STACK
  2025. byte *signedDataOid = NULL;
  2026. #else
  2027. byte signedDataOid[MAX_OID_SZ];
  2028. #endif
  2029. word32 signedDataOidSz;
  2030. byte signingTime[MAX_TIME_STRING_SZ];
  2031. if (pkcs7 == NULL || pkcs7->hashOID == 0 ||
  2032. outputSz == NULL || hashSz == 0 ||
  2033. hashBuf == NULL) {
  2034. return BAD_FUNC_ARG;
  2035. }
  2036. #ifdef WOLFSSL_SMALL_STACK
  2037. signedDataOid = (byte *)XMALLOC(MAX_OID_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2038. if (signedDataOid == NULL) {
  2039. idx = MEMORY_E;
  2040. goto out;
  2041. }
  2042. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2043. if (esd == NULL) {
  2044. idx = MEMORY_E;
  2045. goto out;
  2046. }
  2047. #endif
  2048. XMEMSET(esd, 0, sizeof(ESD));
  2049. /* set content type based on contentOID, unless user has set custom one
  2050. with wc_PKCS7_SetContentType() */
  2051. if (pkcs7->contentTypeSz == 0) {
  2052. /* default to DATA content type if user has not set */
  2053. if (pkcs7->contentOID == 0) {
  2054. pkcs7->contentOID = DATA;
  2055. }
  2056. ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType,
  2057. sizeof(pkcs7->contentType));
  2058. if (ret < 0) {
  2059. idx = ret;
  2060. goto out;
  2061. }
  2062. pkcs7->contentTypeSz = ret;
  2063. }
  2064. /* set signedData outer content type */
  2065. ret = wc_SetContentType(SIGNED_DATA, signedDataOid, MAX_OID_SZ);
  2066. if (ret < 0) {
  2067. idx = ret;
  2068. goto out;
  2069. }
  2070. signedDataOidSz = ret;
  2071. if (pkcs7->sidType != DEGENERATE_SID) {
  2072. esd->hashType = wc_OidGetHash(pkcs7->hashOID);
  2073. if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
  2074. WOLFSSL_MSG("hashSz did not match hashOID");
  2075. idx = BUFFER_E;
  2076. goto out;
  2077. }
  2078. /* include hash */
  2079. esd->contentDigest[0] = ASN_OCTET_STRING;
  2080. esd->contentDigest[1] = (byte)hashSz;
  2081. XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
  2082. }
  2083. if (pkcs7->detached == 1) {
  2084. /* do not include content if generating detached signature */
  2085. esd->innerOctetsSz = 0;
  2086. esd->innerContSeqSz = 0;
  2087. esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz,
  2088. esd->contentInfoSeq);
  2089. } else {
  2090. esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
  2091. esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz +
  2092. pkcs7->contentSz, esd->innerContSeq);
  2093. esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz +
  2094. esd->innerOctetsSz + pkcs7->contentTypeSz +
  2095. esd->innerContSeqSz, esd->contentInfoSeq);
  2096. }
  2097. /* SignerIdentifier */
  2098. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  2099. /* IssuerAndSerialNumber */
  2100. esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
  2101. esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ);
  2102. signerInfoSz += esd->issuerSnSz;
  2103. esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
  2104. signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
  2105. esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
  2106. signerInfoSz += esd->issuerSnSeqSz;
  2107. if (pkcs7->version == 3) {
  2108. /* RFC 4108 version MUST be 3 for firmware package signer */
  2109. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  2110. }
  2111. else {
  2112. /* version MUST be 1 otherwise*/
  2113. esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
  2114. }
  2115. } else if (pkcs7->sidType == CMS_SKID) {
  2116. /* SubjectKeyIdentifier */
  2117. esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID);
  2118. esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE,
  2119. esd->issuerSKIDSeq);
  2120. signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz +
  2121. KEYID_SIZE);
  2122. /* version MUST be 3 */
  2123. esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
  2124. } else if (pkcs7->sidType == DEGENERATE_SID) {
  2125. /* no signer info added */
  2126. } else {
  2127. idx = SKID_E;
  2128. goto out;
  2129. }
  2130. if (pkcs7->sidType != DEGENERATE_SID) {
  2131. signerInfoSz += esd->signerVersionSz;
  2132. esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
  2133. oidHashType, 0);
  2134. signerInfoSz += esd->signerDigAlgoIdSz;
  2135. /* set signatureAlgorithm */
  2136. ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
  2137. &digEncAlgoType);
  2138. if (ret < 0) {
  2139. idx = ret;
  2140. goto out;
  2141. }
  2142. esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
  2143. digEncAlgoType, 0);
  2144. signerInfoSz += esd->digEncAlgoIdSz;
  2145. /* build up signed attributes, include contentType, signingTime, and
  2146. messageDigest by default */
  2147. ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType,
  2148. pkcs7->contentTypeSz,
  2149. contentTypeOid, sizeof(contentTypeOid),
  2150. messageDigestOid, sizeof(messageDigestOid),
  2151. signingTimeOid, sizeof(signingTimeOid),
  2152. signingTime, sizeof(signingTime));
  2153. if (ret < 0) {
  2154. idx = ret;
  2155. goto out;
  2156. }
  2157. if (esd->signedAttribsSz > 0) {
  2158. flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
  2159. DYNAMIC_TYPE_PKCS7);
  2160. if (flatSignedAttribs == NULL) {
  2161. idx = MEMORY_E;
  2162. goto out;
  2163. }
  2164. flatSignedAttribsSz = esd->signedAttribsSz;
  2165. FlattenAttributes(pkcs7, flatSignedAttribs,
  2166. esd->signedAttribs, esd->signedAttribsCount);
  2167. esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
  2168. esd->signedAttribSet);
  2169. } else {
  2170. esd->signedAttribSetSz = 0;
  2171. }
  2172. /* Calculate the final hash and encrypt it. */
  2173. ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
  2174. flatSignedAttribsSz, esd);
  2175. if (ret < 0) {
  2176. idx = ret;
  2177. goto out;
  2178. }
  2179. signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
  2180. esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
  2181. esd->signerDigest);
  2182. signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
  2183. esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
  2184. signerInfoSz += esd->signerInfoSeqSz;
  2185. }
  2186. esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
  2187. signerInfoSz += esd->signerInfoSetSz;
  2188. /* certificates [0] IMPLICIT CertificateSet */
  2189. /* get total certificates size */
  2190. certPtr = pkcs7->certList;
  2191. while (certPtr != NULL) {
  2192. certSetSz += certPtr->derSz;
  2193. certPtr = certPtr->next;
  2194. }
  2195. certPtr = NULL;
  2196. if (certSetSz > 0)
  2197. esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet);
  2198. if (pkcs7->sidType != DEGENERATE_SID) {
  2199. esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
  2200. oidHashType, 0);
  2201. }
  2202. esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
  2203. if (pkcs7->version == 3) {
  2204. /* RFC 4108 version MUST be 3 for firmware package signer */
  2205. esd->versionSz = SetMyVersion(3, esd->version, 0);
  2206. }
  2207. else {
  2208. esd->versionSz = SetMyVersion(1, esd->version, 0);
  2209. }
  2210. totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
  2211. esd->contentInfoSeqSz + pkcs7->contentTypeSz +
  2212. esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz;
  2213. total2Sz = esd->certsSetSz + certSetSz + signerInfoSz;
  2214. if (pkcs7->detached) {
  2215. totalSz -= pkcs7->contentSz;
  2216. }
  2217. esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
  2218. totalSz += esd->innerSeqSz;
  2219. esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
  2220. totalSz += esd->outerContentSz + signedDataOidSz;
  2221. esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
  2222. totalSz += esd->outerSeqSz;
  2223. /* if using header/footer, we are not returning the content */
  2224. if (output2 && output2Sz) {
  2225. if (total2Sz > *output2Sz) {
  2226. if (*outputSz == 0 && *output2Sz == 0) {
  2227. *outputSz = totalSz;
  2228. *output2Sz = total2Sz;
  2229. idx = 0;
  2230. goto out;
  2231. }
  2232. idx = BUFFER_E;
  2233. goto out;
  2234. }
  2235. if (!pkcs7->detached) {
  2236. totalSz -= pkcs7->contentSz;
  2237. }
  2238. }
  2239. else {
  2240. /* if using single output buffer include content and footer */
  2241. totalSz += total2Sz;
  2242. }
  2243. if (totalSz > *outputSz) {
  2244. if (*outputSz == 0) {
  2245. #ifdef HAVE_ECC
  2246. if (pkcs7->publicKeyOID == ECDSAk) {
  2247. totalSz += ECC_MAX_PAD_SZ; /* signatures size can vary */
  2248. }
  2249. #endif
  2250. *outputSz = totalSz;
  2251. idx = totalSz;
  2252. goto out;
  2253. }
  2254. idx = BUFFER_E;
  2255. goto out;
  2256. }
  2257. if (output == NULL) {
  2258. idx = BUFFER_E;
  2259. goto out;
  2260. }
  2261. idx = 0;
  2262. XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
  2263. idx += esd->outerSeqSz;
  2264. XMEMCPY(output + idx, signedDataOid, signedDataOidSz);
  2265. idx += signedDataOidSz;
  2266. XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
  2267. idx += esd->outerContentSz;
  2268. XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
  2269. idx += esd->innerSeqSz;
  2270. XMEMCPY(output + idx, esd->version, esd->versionSz);
  2271. idx += esd->versionSz;
  2272. XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
  2273. idx += esd->digAlgoIdSetSz;
  2274. XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
  2275. idx += esd->singleDigAlgoIdSz;
  2276. XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
  2277. idx += esd->contentInfoSeqSz;
  2278. XMEMCPY(output + idx, pkcs7->contentType, pkcs7->contentTypeSz);
  2279. idx += pkcs7->contentTypeSz;
  2280. XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
  2281. idx += esd->innerContSeqSz;
  2282. XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
  2283. idx += esd->innerOctetsSz;
  2284. /* support returning header and footer without content */
  2285. if (output2 && output2Sz) {
  2286. *outputSz = idx;
  2287. idx = 0;
  2288. }
  2289. else {
  2290. if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) {
  2291. XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
  2292. idx += pkcs7->contentSz;
  2293. }
  2294. output2 = output;
  2295. }
  2296. /* certificates */
  2297. XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);
  2298. idx += esd->certsSetSz;
  2299. certPtr = pkcs7->certList;
  2300. while (certPtr != NULL) {
  2301. XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz);
  2302. idx += certPtr->derSz;
  2303. certPtr = certPtr->next;
  2304. }
  2305. wc_PKCS7_FreeCertSet(pkcs7);
  2306. XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
  2307. idx += esd->signerInfoSetSz;
  2308. XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
  2309. idx += esd->signerInfoSeqSz;
  2310. XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
  2311. idx += esd->signerVersionSz;
  2312. /* SignerIdentifier */
  2313. if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  2314. /* IssuerAndSerialNumber */
  2315. XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
  2316. idx += esd->issuerSnSeqSz;
  2317. XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
  2318. idx += esd->issuerNameSz;
  2319. XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
  2320. idx += pkcs7->issuerSz;
  2321. XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
  2322. idx += esd->issuerSnSz;
  2323. } else if (pkcs7->sidType == CMS_SKID) {
  2324. /* SubjectKeyIdentifier */
  2325. XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz);
  2326. idx += esd->issuerSKIDSeqSz;
  2327. XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz);
  2328. idx += esd->issuerSKIDSz;
  2329. XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
  2330. idx += KEYID_SIZE;
  2331. } else if (pkcs7->sidType == DEGENERATE_SID) {
  2332. /* no signer infos in degenerate case */
  2333. } else {
  2334. idx = SKID_E;
  2335. goto out;
  2336. }
  2337. XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
  2338. idx += esd->signerDigAlgoIdSz;
  2339. /* SignerInfo:Attributes */
  2340. if (flatSignedAttribsSz > 0) {
  2341. XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
  2342. idx += esd->signedAttribSetSz;
  2343. XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
  2344. idx += flatSignedAttribsSz;
  2345. }
  2346. XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
  2347. idx += esd->digEncAlgoIdSz;
  2348. XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
  2349. idx += esd->signerDigestSz;
  2350. XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
  2351. idx += esd->encContentDigestSz;
  2352. if (output2Sz) {
  2353. *output2Sz = idx;
  2354. idx = 0; /* success */
  2355. }
  2356. else {
  2357. *outputSz = idx;
  2358. }
  2359. out:
  2360. if (flatSignedAttribs != NULL)
  2361. XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2362. #ifdef WOLFSSL_SMALL_STACK
  2363. if (esd)
  2364. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2365. if (signedDataOid)
  2366. XFREE(signedDataOid, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2367. #endif
  2368. return idx;
  2369. }
  2370. /* hashBuf: The computed digest for the pkcs7->content
  2371. * hashSz: The size of computed digest for the pkcs7->content based on hashOID
  2372. * outputHead: The PKCS7 header that goes on top of the raw data signed.
  2373. * outputFoot: The PKCS7 footer that goes at the end of the raw data signed.
  2374. * pkcs7->content: Not used
  2375. * pkcs7->contentSz: Must be provided as actual sign of raw data
  2376. * return codes: 0=success, negative=error
  2377. */
  2378. int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  2379. word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
  2380. word32* outputFootSz)
  2381. {
  2382. int ret;
  2383. #ifdef WOLFSSL_SMALL_STACK
  2384. ESD* esd;
  2385. #else
  2386. ESD esd[1];
  2387. #endif
  2388. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2389. if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {
  2390. return BAD_FUNC_ARG;
  2391. }
  2392. #ifdef WOLFSSL_SMALL_STACK
  2393. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2394. if (esd == NULL)
  2395. return MEMORY_E;
  2396. #endif
  2397. XMEMSET(esd, 0, sizeof(ESD));
  2398. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2399. outputHead, outputHeadSz, outputFoot, outputFootSz);
  2400. #ifdef WOLFSSL_SMALL_STACK
  2401. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2402. #endif
  2403. return ret;
  2404. }
  2405. /* Toggle detached signature mode on/off for PKCS#7/CMS SignedData content type.
  2406. * By default wolfCrypt includes the data to be signed in the SignedData
  2407. * bundle. This data can be omitted in the case when a detached signature is
  2408. * being created. To enable generation of detached signatures, set flag to "1",
  2409. * otherwise set to "0":
  2410. *
  2411. * flag 1 turns on support
  2412. * flag 0 turns off support
  2413. *
  2414. * pkcs7 - pointer to initialized PKCS7 structure
  2415. * flag - turn on/off detached signature generation (1 or 0)
  2416. *
  2417. * Returns 0 on success, negative upon error. */
  2418. int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag)
  2419. {
  2420. if (pkcs7 == NULL || (flag != 0 && flag != 1))
  2421. return BAD_FUNC_ARG;
  2422. pkcs7->detached = flag;
  2423. return 0;
  2424. }
  2425. /* By default, SignedData bundles have the following signed attributes attached:
  2426. * contentType (1.2.840.113549.1.9.3)
  2427. * signingTime (1.2.840.113549.1.9.5)
  2428. * messageDigest (1.2.840.113549.1.9.4)
  2429. *
  2430. * Calling this API before wc_PKCS7_EncodeSignedData() will disable the
  2431. * inclusion of those attributes.
  2432. *
  2433. * pkcs7 - pointer to initialized PKCS7 structure
  2434. *
  2435. * Returns 0 on success, negative upon error. */
  2436. int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7)
  2437. {
  2438. if (pkcs7 == NULL)
  2439. return BAD_FUNC_ARG;
  2440. pkcs7->skipDefaultSignedAttribs = 1;
  2441. return 0;
  2442. }
  2443. /* return codes: >0: Size of signed PKCS7 output buffer, negative: error */
  2444. int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  2445. {
  2446. int ret;
  2447. int hashSz;
  2448. enum wc_HashType hashType;
  2449. byte hashBuf[WC_MAX_DIGEST_SIZE];
  2450. #ifdef WOLFSSL_SMALL_STACK
  2451. ESD* esd;
  2452. #else
  2453. ESD esd[1];
  2454. #endif
  2455. /* other args checked in wc_PKCS7_EncodeSigned_ex */
  2456. if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL)) {
  2457. return BAD_FUNC_ARG;
  2458. }
  2459. /* get hash type and size, validate hashOID */
  2460. hashType = wc_OidGetHash(pkcs7->hashOID);
  2461. hashSz = wc_HashGetDigestSize(hashType);
  2462. if (hashSz < 0)
  2463. return hashSz;
  2464. #ifdef WOLFSSL_SMALL_STACK
  2465. esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2466. if (esd == NULL)
  2467. return MEMORY_E;
  2468. #endif
  2469. XMEMSET(esd, 0, sizeof(ESD));
  2470. esd->hashType = hashType;
  2471. /* calculate hash for content */
  2472. ret = wc_HashInit(&esd->hash, esd->hashType);
  2473. if (ret == 0) {
  2474. ret = wc_HashUpdate(&esd->hash, esd->hashType,
  2475. pkcs7->content, pkcs7->contentSz);
  2476. if (ret == 0) {
  2477. ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);
  2478. }
  2479. wc_HashFree(&esd->hash, esd->hashType);
  2480. }
  2481. if (ret == 0) {
  2482. ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
  2483. output, &outputSz, NULL, NULL);
  2484. }
  2485. #ifdef WOLFSSL_SMALL_STACK
  2486. XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2487. #endif
  2488. return ret;
  2489. }
  2490. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2491. * content of type FirmwarePkgData. Any recipient certificates should be
  2492. * loaded into the PKCS7 structure prior to calling this function, using
  2493. * wc_PKCS7_InitWithCert() and/or wc_PKCS7_AddCertificate().
  2494. *
  2495. * pkcs7 - pointer to initialized PKCS7 struct
  2496. * privateKey - private RSA/ECC key, used for signing SignedData
  2497. * privateKeySz - size of privateKey, octets
  2498. * signOID - public key algorithm OID, used for sign operation
  2499. * hashOID - hash algorithm OID, used for signature generation
  2500. * content - content to be encapsulated, of type FirmwarePkgData
  2501. * contentSz - size of content, octets
  2502. * signedAttribs - optional signed attributes
  2503. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2504. * output - output buffer for final bundle
  2505. * outputSz - size of output buffer, octets
  2506. *
  2507. * Returns length of generated bundle on success, negative upon error. */
  2508. int wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,
  2509. word32 privateKeySz, int signOID, int hashOID,
  2510. byte* content, word32 contentSz,
  2511. PKCS7Attrib* signedAttribs, word32 signedAttribsSz,
  2512. byte* output, word32 outputSz)
  2513. {
  2514. int ret = 0;
  2515. WC_RNG rng;
  2516. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2517. content == NULL || contentSz == 0 || output == NULL || outputSz == 0)
  2518. return BAD_FUNC_ARG;
  2519. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2520. if (ret != 0)
  2521. return ret;
  2522. pkcs7->rng = &rng;
  2523. pkcs7->content = content;
  2524. pkcs7->contentSz = contentSz;
  2525. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2526. pkcs7->hashOID = hashOID;
  2527. pkcs7->encryptOID = signOID;
  2528. pkcs7->privateKey = privateKey;
  2529. pkcs7->privateKeySz = privateKeySz;
  2530. pkcs7->signedAttribs = signedAttribs;
  2531. pkcs7->signedAttribsSz = signedAttribsSz;
  2532. pkcs7->version = 3;
  2533. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2534. if (ret <= 0) {
  2535. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2536. }
  2537. pkcs7->rng = NULL;
  2538. wc_FreeRng(&rng);
  2539. return ret;
  2540. }
  2541. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2542. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2543. * CMS EncryptedData bundle. Content of inner EncryptedData is set to that
  2544. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2545. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2546. * and/or wc_PKCS7_AddCertificate().
  2547. *
  2548. * pkcs7 - pointer to initialized PKCS7 struct
  2549. * encryptKey - encryption key used for encrypting EncryptedData
  2550. * encryptKeySz - size of encryptKey, octets
  2551. * privateKey - private RSA/ECC key, used for signing SignedData
  2552. * privateKeySz - size of privateKey, octets
  2553. * encryptOID - encryption algorithm OID, to be used as encryption
  2554. * algorithm for EncryptedData
  2555. * signOID - public key algorithm OID, to be used for sign
  2556. * operation in SignedData generation
  2557. * hashOID - hash algorithm OID, to be used for signature in
  2558. * SignedData generation
  2559. * content - content to be encapsulated
  2560. * contentSz - size of content, octets
  2561. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2562. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2563. * signedAttribs - optional signed attributes, for SignedData
  2564. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2565. * output - output buffer for final bundle
  2566. * outputSz - size of output buffer, octets
  2567. *
  2568. * Returns length of generated bundle on success, negative upon error. */
  2569. int wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, byte* encryptKey,
  2570. word32 encryptKeySz, byte* privateKey,
  2571. word32 privateKeySz, int encryptOID,
  2572. int signOID, int hashOID,
  2573. byte* content, word32 contentSz,
  2574. PKCS7Attrib* unprotectedAttribs,
  2575. word32 unprotectedAttribsSz,
  2576. PKCS7Attrib* signedAttribs,
  2577. word32 signedAttribsSz,
  2578. byte* output, word32 outputSz)
  2579. {
  2580. int ret = 0, encryptedSz = 0;
  2581. byte* encrypted = NULL;
  2582. WC_RNG rng;
  2583. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2584. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2585. contentSz == 0 || output == NULL || outputSz == 0) {
  2586. return BAD_FUNC_ARG;
  2587. }
  2588. /* 1: build up EncryptedData using FirmwarePkgData type, use output
  2589. * buffer as tmp for storage and to get size */
  2590. /* set struct elements, inner content type is FirmwarePkgData */
  2591. pkcs7->content = content;
  2592. pkcs7->contentSz = contentSz;
  2593. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2594. pkcs7->encryptOID = encryptOID;
  2595. pkcs7->encryptionKey = encryptKey;
  2596. pkcs7->encryptionKeySz = encryptKeySz;
  2597. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2598. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2599. pkcs7->version = 3;
  2600. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2601. if (encryptedSz < 0) {
  2602. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2603. return encryptedSz;
  2604. }
  2605. /* save encryptedData, reset output buffer and struct */
  2606. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2607. if (encrypted == NULL) {
  2608. ForceZero(output, outputSz);
  2609. return MEMORY_E;
  2610. }
  2611. XMEMCPY(encrypted, output, encryptedSz);
  2612. ForceZero(output, outputSz);
  2613. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2614. if (ret != 0) {
  2615. ForceZero(encrypted, encryptedSz);
  2616. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2617. return ret;
  2618. }
  2619. /* 2: build up SignedData, encapsulating EncryptedData */
  2620. pkcs7->rng = &rng;
  2621. pkcs7->content = encrypted;
  2622. pkcs7->contentSz = encryptedSz;
  2623. pkcs7->contentOID = ENCRYPTED_DATA;
  2624. pkcs7->hashOID = hashOID;
  2625. pkcs7->encryptOID = signOID;
  2626. pkcs7->privateKey = privateKey;
  2627. pkcs7->privateKeySz = privateKeySz;
  2628. pkcs7->signedAttribs = signedAttribs;
  2629. pkcs7->signedAttribsSz = signedAttribsSz;
  2630. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2631. if (ret <= 0) {
  2632. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2633. }
  2634. ForceZero(encrypted, encryptedSz);
  2635. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2636. pkcs7->rng = NULL;
  2637. wc_FreeRng(&rng);
  2638. return ret;
  2639. }
  2640. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  2641. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  2642. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2643. * CMS CompressedData bundle. Content of inner CompressedData is set to that
  2644. * of FirmwarePkgData. Any recipient certificates should be loaded into the
  2645. * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
  2646. * and/or wc_PKCS7_AddCertificate().
  2647. *
  2648. * pkcs7 - pointer to initialized PKCS7 struct
  2649. * privateKey - private RSA/ECC key, used for signing SignedData
  2650. * privateKeySz - size of privateKey, octets
  2651. * signOID - public key algorithm OID, to be used for sign
  2652. * operation in SignedData generation
  2653. * hashOID - hash algorithm OID, to be used for signature in
  2654. * SignedData generation
  2655. * content - content to be encapsulated
  2656. * contentSz - size of content, octets
  2657. * signedAttribs - optional signed attributes, for SignedData
  2658. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2659. * output - output buffer for final bundle
  2660. * outputSz - size of output buffer, octets
  2661. *
  2662. * Returns length of generated bundle on success, negative upon error. */
  2663. int wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, byte* privateKey,
  2664. word32 privateKeySz, int signOID,
  2665. int hashOID, byte* content,
  2666. word32 contentSz,
  2667. PKCS7Attrib* signedAttribs,
  2668. word32 signedAttribsSz, byte* output,
  2669. word32 outputSz)
  2670. {
  2671. int ret = 0, compressedSz = 0;
  2672. byte* compressed = NULL;
  2673. WC_RNG rng;
  2674. if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
  2675. content == NULL || contentSz == 0 || output == NULL || outputSz == 0) {
  2676. return BAD_FUNC_ARG;
  2677. }
  2678. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2679. * buffer as tmp for storage and to get size */
  2680. /* set struct elements, inner content type is FirmwarePkgData */
  2681. pkcs7->content = content;
  2682. pkcs7->contentSz = contentSz;
  2683. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2684. pkcs7->version = 3;
  2685. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2686. if (compressedSz < 0) {
  2687. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2688. return compressedSz;
  2689. }
  2690. /* save compressedData, reset output buffer and struct */
  2691. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2692. if (compressed == NULL) {
  2693. ForceZero(output, outputSz);
  2694. return MEMORY_E;
  2695. }
  2696. XMEMCPY(compressed, output, compressedSz);
  2697. ForceZero(output, outputSz);
  2698. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2699. if (ret != 0) {
  2700. ForceZero(compressed, compressedSz);
  2701. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2702. return ret;
  2703. }
  2704. /* 2: build up SignedData, encapsulating EncryptedData */
  2705. pkcs7->rng = &rng;
  2706. pkcs7->content = compressed;
  2707. pkcs7->contentSz = compressedSz;
  2708. pkcs7->contentOID = COMPRESSED_DATA;
  2709. pkcs7->hashOID = hashOID;
  2710. pkcs7->encryptOID = signOID;
  2711. pkcs7->privateKey = privateKey;
  2712. pkcs7->privateKeySz = privateKeySz;
  2713. pkcs7->signedAttribs = signedAttribs;
  2714. pkcs7->signedAttribsSz = signedAttribsSz;
  2715. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2716. if (ret <= 0) {
  2717. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2718. }
  2719. ForceZero(compressed, compressedSz);
  2720. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2721. pkcs7->rng = NULL;
  2722. wc_FreeRng(&rng);
  2723. return ret;
  2724. }
  2725. #ifndef NO_PKCS7_ENCRYPTED_DATA
  2726. /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
  2727. * CMS EncryptedData bundle, which then encapsulates a CMS CompressedData
  2728. * bundle. Content of inner CompressedData is set to that of FirmwarePkgData.
  2729. * Any recipient certificates should be loaded into the PKCS7 structure prior
  2730. * to calling this function, using wc_PKCS7_InitWithCert() and/or
  2731. * wc_PKCS7_AddCertificate().
  2732. *
  2733. * pkcs7 - pointer to initialized PKCS7 struct
  2734. * encryptKey - encryption key used for encrypting EncryptedData
  2735. * encryptKeySz - size of encryptKey, octets
  2736. * privateKey - private RSA/ECC key, used for signing SignedData
  2737. * privateKeySz - size of privateKey, octets
  2738. * encryptOID - encryption algorithm OID, to be used as encryption
  2739. * algorithm for EncryptedData
  2740. * signOID - public key algorithm OID, to be used for sign
  2741. * operation in SignedData generation
  2742. * hashOID - hash algorithm OID, to be used for signature in
  2743. * SignedData generation
  2744. * content - content to be encapsulated
  2745. * contentSz - size of content, octets
  2746. * unprotectedAttribs - optional unprotected attributes, for EncryptedData
  2747. * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
  2748. * signedAttribs - optional signed attributes, for SignedData
  2749. * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
  2750. * output - output buffer for final bundle
  2751. * outputSz - size of output buffer, octets
  2752. *
  2753. * Returns length of generated bundle on success, negative upon error. */
  2754. int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,
  2755. word32 encryptKeySz, byte* privateKey,
  2756. word32 privateKeySz, int encryptOID,
  2757. int signOID, int hashOID, byte* content,
  2758. word32 contentSz,
  2759. PKCS7Attrib* unprotectedAttribs,
  2760. word32 unprotectedAttribsSz,
  2761. PKCS7Attrib* signedAttribs,
  2762. word32 signedAttribsSz,
  2763. byte* output, word32 outputSz)
  2764. {
  2765. int ret = 0, compressedSz = 0, encryptedSz = 0;
  2766. byte* compressed = NULL;
  2767. byte* encrypted = NULL;
  2768. WC_RNG rng;
  2769. if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
  2770. privateKey == NULL || privateKeySz == 0 || content == NULL ||
  2771. contentSz == 0 || output == NULL || outputSz == 0) {
  2772. return BAD_FUNC_ARG;
  2773. }
  2774. /* 1: build up CompressedData using FirmwarePkgData type, use output
  2775. * buffer as tmp for storage and to get size */
  2776. pkcs7->content = content;
  2777. pkcs7->contentSz = contentSz;
  2778. pkcs7->contentOID = FIRMWARE_PKG_DATA;
  2779. pkcs7->version = 3;
  2780. compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
  2781. if (compressedSz < 0) {
  2782. WOLFSSL_MSG("Error encoding CMS CompressedData content type");
  2783. return compressedSz;
  2784. }
  2785. /* save compressedData, reset output buffer and struct */
  2786. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2787. if (compressed == NULL)
  2788. return MEMORY_E;
  2789. XMEMCPY(compressed, output, compressedSz);
  2790. ForceZero(output, outputSz);
  2791. /* 2: build up EncryptedData using CompressedData, use output
  2792. * buffer as tmp for storage and to get size */
  2793. pkcs7->content = compressed;
  2794. pkcs7->contentSz = compressedSz;
  2795. pkcs7->contentOID = COMPRESSED_DATA;
  2796. pkcs7->encryptOID = encryptOID;
  2797. pkcs7->encryptionKey = encryptKey;
  2798. pkcs7->encryptionKeySz = encryptKeySz;
  2799. pkcs7->unprotectedAttribs = unprotectedAttribs;
  2800. pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
  2801. encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
  2802. if (encryptedSz < 0) {
  2803. WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
  2804. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2805. return encryptedSz;
  2806. }
  2807. /* save encryptedData, reset output buffer and struct */
  2808. encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2809. if (encrypted == NULL) {
  2810. ForceZero(compressed, compressedSz);
  2811. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2812. return MEMORY_E;
  2813. }
  2814. XMEMCPY(encrypted, output, encryptedSz);
  2815. ForceZero(compressed, compressedSz);
  2816. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2817. ForceZero(output, outputSz);
  2818. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  2819. if (ret != 0) {
  2820. ForceZero(encrypted, encryptedSz);
  2821. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2822. return ret;
  2823. }
  2824. /* 3: build up SignedData, encapsulating EncryptedData */
  2825. pkcs7->rng = &rng;
  2826. pkcs7->content = encrypted;
  2827. pkcs7->contentSz = encryptedSz;
  2828. pkcs7->contentOID = ENCRYPTED_DATA;
  2829. pkcs7->hashOID = hashOID;
  2830. pkcs7->encryptOID = signOID;
  2831. pkcs7->privateKey = privateKey;
  2832. pkcs7->privateKeySz = privateKeySz;
  2833. pkcs7->signedAttribs = signedAttribs;
  2834. pkcs7->signedAttribsSz = signedAttribsSz;
  2835. ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
  2836. if (ret <= 0) {
  2837. WOLFSSL_MSG("Error encoding CMS SignedData content type");
  2838. }
  2839. ForceZero(encrypted, encryptedSz);
  2840. XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  2841. pkcs7->rng = NULL;
  2842. wc_FreeRng(&rng);
  2843. return ret;
  2844. }
  2845. #endif /* !NO_PKCS7_ENCRYPTED_DATA */
  2846. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  2847. #ifndef NO_RSA
  2848. #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
  2849. /* register raw RSA sign digest callback */
  2850. int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
  2851. {
  2852. if (pkcs7 == NULL || cb == NULL) {
  2853. return BAD_FUNC_ARG;
  2854. }
  2855. pkcs7->rsaSignRawDigestCb = cb;
  2856. return 0;
  2857. }
  2858. #endif
  2859. /* returns size of signature put into out, negative on error */
  2860. static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  2861. byte* hash, word32 hashSz)
  2862. {
  2863. int ret = 0, i;
  2864. word32 scratch = 0, verified = 0;
  2865. #ifdef WOLFSSL_SMALL_STACK
  2866. byte* digest;
  2867. RsaKey* key;
  2868. DecodedCert* dCert;
  2869. #else
  2870. byte digest[MAX_PKCS7_DIGEST_SZ];
  2871. RsaKey key[1];
  2872. DecodedCert stack_dCert;
  2873. DecodedCert* dCert = &stack_dCert;
  2874. #endif
  2875. if (pkcs7 == NULL || sig == NULL || hash == NULL) {
  2876. return BAD_FUNC_ARG;
  2877. }
  2878. #ifdef WOLFSSL_SMALL_STACK
  2879. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2880. DYNAMIC_TYPE_TMP_BUFFER);
  2881. if (digest == NULL)
  2882. return MEMORY_E;
  2883. key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2884. if (key == NULL) {
  2885. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2886. return MEMORY_E;
  2887. }
  2888. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  2889. DYNAMIC_TYPE_DCERT);
  2890. if (dCert == NULL) {
  2891. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2892. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2893. return MEMORY_E;
  2894. }
  2895. #endif
  2896. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  2897. /* loop over certs received in certificates set, try to find one
  2898. * that will validate signature */
  2899. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  2900. verified = 0;
  2901. scratch = 0;
  2902. if (pkcs7->certSz[i] == 0)
  2903. continue;
  2904. ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);
  2905. if (ret != 0) {
  2906. #ifdef WOLFSSL_SMALL_STACK
  2907. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2908. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2909. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2910. #endif
  2911. return ret;
  2912. }
  2913. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  2914. /* not verifying, only using this to extract public key */
  2915. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  2916. if (ret < 0) {
  2917. WOLFSSL_MSG("ASN RSA cert parse error");
  2918. FreeDecodedCert(dCert);
  2919. wc_FreeRsaKey(key);
  2920. continue;
  2921. }
  2922. if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key,
  2923. dCert->pubKeySize) < 0) {
  2924. WOLFSSL_MSG("ASN RSA key decode error");
  2925. FreeDecodedCert(dCert);
  2926. wc_FreeRsaKey(key);
  2927. continue;
  2928. }
  2929. #ifdef WOLFSSL_ASYNC_CRYPT
  2930. do {
  2931. ret = wc_AsyncWait(ret, &key->asyncDev,
  2932. WC_ASYNC_FLAG_CALL_AGAIN);
  2933. #endif
  2934. if (ret >= 0) {
  2935. ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,
  2936. key);
  2937. }
  2938. #ifdef WOLFSSL_ASYNC_CRYPT
  2939. } while (ret == WC_PENDING_E);
  2940. #endif
  2941. FreeDecodedCert(dCert);
  2942. wc_FreeRsaKey(key);
  2943. if ((ret > 0) && (hashSz == (word32)ret)) {
  2944. if (XMEMCMP(digest, hash, hashSz) == 0) {
  2945. /* found signer that successfully verified signature */
  2946. verified = 1;
  2947. pkcs7->verifyCert = pkcs7->cert[i];
  2948. pkcs7->verifyCertSz = pkcs7->certSz[i];
  2949. break;
  2950. }
  2951. }
  2952. }
  2953. if (verified == 0) {
  2954. ret = SIG_VERIFY_E;
  2955. }
  2956. #ifdef WOLFSSL_SMALL_STACK
  2957. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2958. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2959. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  2960. #endif
  2961. return ret;
  2962. }
  2963. #endif /* NO_RSA */
  2964. #ifdef HAVE_ECC
  2965. /* returns size of signature put into out, negative on error */
  2966. static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
  2967. byte* hash, word32 hashSz)
  2968. {
  2969. int ret = 0, i;
  2970. int res = 0;
  2971. int verified = 0;
  2972. #ifdef WOLFSSL_SMALL_STACK
  2973. byte* digest;
  2974. ecc_key* key;
  2975. DecodedCert* dCert;
  2976. #else
  2977. byte digest[MAX_PKCS7_DIGEST_SZ];
  2978. ecc_key key[1];
  2979. DecodedCert stack_dCert;
  2980. DecodedCert* dCert = &stack_dCert;
  2981. #endif
  2982. word32 idx = 0;
  2983. if (pkcs7 == NULL || sig == NULL)
  2984. return BAD_FUNC_ARG;
  2985. #ifdef WOLFSSL_SMALL_STACK
  2986. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  2987. DYNAMIC_TYPE_TMP_BUFFER);
  2988. if (digest == NULL)
  2989. return MEMORY_E;
  2990. key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  2991. DYNAMIC_TYPE_TMP_BUFFER);
  2992. if (key == NULL) {
  2993. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  2994. return MEMORY_E;
  2995. }
  2996. dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  2997. DYNAMIC_TYPE_DCERT);
  2998. if (dCert == NULL) {
  2999. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3000. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3001. return MEMORY_E;
  3002. }
  3003. #endif
  3004. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  3005. /* loop over certs received in certificates set, try to find one
  3006. * that will validate signature */
  3007. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  3008. verified = 0;
  3009. idx = 0;
  3010. if (pkcs7->certSz[i] == 0)
  3011. continue;
  3012. ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);
  3013. if (ret != 0) {
  3014. #ifdef WOLFSSL_SMALL_STACK
  3015. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3016. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3017. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  3018. #endif
  3019. return ret;
  3020. }
  3021. InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
  3022. /* not verifying, only using this to extract public key */
  3023. ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
  3024. if (ret < 0) {
  3025. WOLFSSL_MSG("ASN ECC cert parse error");
  3026. FreeDecodedCert(dCert);
  3027. wc_ecc_free(key);
  3028. continue;
  3029. }
  3030. if (wc_EccPublicKeyDecode(dCert->publicKey, &idx, key,
  3031. dCert->pubKeySize) < 0) {
  3032. WOLFSSL_MSG("ASN ECC key decode error");
  3033. FreeDecodedCert(dCert);
  3034. wc_ecc_free(key);
  3035. continue;
  3036. }
  3037. #ifdef WOLFSSL_ASYNC_CRYPT
  3038. do {
  3039. ret = wc_AsyncWait(ret, &key->asyncDev,
  3040. WC_ASYNC_FLAG_CALL_AGAIN);
  3041. #endif
  3042. if (ret >= 0) {
  3043. ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);
  3044. }
  3045. #ifdef WOLFSSL_ASYNC_CRYPT
  3046. } while (ret == WC_PENDING_E);
  3047. #endif
  3048. FreeDecodedCert(dCert);
  3049. wc_ecc_free(key);
  3050. if (ret == 0 && res == 1) {
  3051. /* found signer that successfully verified signature */
  3052. verified = 1;
  3053. pkcs7->verifyCert = pkcs7->cert[i];
  3054. pkcs7->verifyCertSz = pkcs7->certSz[i];
  3055. break;
  3056. }
  3057. }
  3058. if (verified == 0) {
  3059. ret = SIG_VERIFY_E;
  3060. }
  3061. #ifdef WOLFSSL_SMALL_STACK
  3062. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3063. XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3064. XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
  3065. #endif
  3066. return ret;
  3067. }
  3068. #endif /* HAVE_ECC */
  3069. /* build SignedData digest, both in PKCS#7 DigestInfo format and
  3070. * as plain digest for CMS.
  3071. *
  3072. * pkcs7 - pointer to initialized PKCS7 struct
  3073. * signedAttrib - signed attributes
  3074. * signedAttribSz - size of signedAttrib, octets
  3075. * pkcs7Digest - [OUT] PKCS#7 DigestInfo
  3076. * pkcs7DigestSz - [IN/OUT] size of pkcs7Digest
  3077. * plainDigest - [OUT] pointer to plain digest, offset into pkcs7Digest
  3078. * plainDigestSz - [OUT] size of digest at plainDigest
  3079. *
  3080. * returns 0 on success, negative on error */
  3081. static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
  3082. word32 signedAttribSz, byte* pkcs7Digest,
  3083. word32* pkcs7DigestSz, byte** plainDigest,
  3084. word32* plainDigestSz,
  3085. const byte* hashBuf, word32 hashBufSz)
  3086. {
  3087. int ret = 0, digIdx = 0;
  3088. word32 attribSetSz = 0, hashSz = 0;
  3089. byte attribSet[MAX_SET_SZ];
  3090. byte digest[WC_MAX_DIGEST_SIZE];
  3091. byte digestInfoSeq[MAX_SEQ_SZ];
  3092. byte digestStr[MAX_OCTET_STR_SZ];
  3093. byte algoId[MAX_ALGO_SZ];
  3094. word32 digestInfoSeqSz, digestStrSz, algoIdSz;
  3095. #ifdef WOLFSSL_SMALL_STACK
  3096. byte* digestInfo;
  3097. #else
  3098. byte digestInfo[MAX_PKCS7_DIGEST_SZ];
  3099. #endif
  3100. wc_HashAlg hash;
  3101. enum wc_HashType hashType;
  3102. /* check arguments */
  3103. if (pkcs7 == NULL || pkcs7Digest == NULL ||
  3104. pkcs7DigestSz == NULL || plainDigest == NULL) {
  3105. return BAD_FUNC_ARG;
  3106. }
  3107. hashType = wc_OidGetHash(pkcs7->hashOID);
  3108. ret = wc_HashGetDigestSize(hashType);
  3109. if (ret < 0)
  3110. return ret;
  3111. hashSz = ret;
  3112. if (signedAttribSz > 0) {
  3113. if (signedAttrib == NULL)
  3114. return BAD_FUNC_ARG;
  3115. }
  3116. else {
  3117. if (hashBuf && hashBufSz > 0) {
  3118. if (hashSz != hashBufSz)
  3119. return BAD_FUNC_ARG;
  3120. }
  3121. else if (pkcs7->content == NULL)
  3122. return BAD_FUNC_ARG;
  3123. }
  3124. #ifdef WOLFSSL_SMALL_STACK
  3125. digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3126. DYNAMIC_TYPE_TMP_BUFFER);
  3127. if (digestInfo == NULL)
  3128. return MEMORY_E;
  3129. #endif
  3130. XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);
  3131. XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE);
  3132. XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ);
  3133. /* calculate digest */
  3134. if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
  3135. XMEMCPY(digest, hashBuf, hashBufSz);
  3136. }
  3137. else {
  3138. ret = wc_HashInit(&hash, hashType);
  3139. if (ret < 0) {
  3140. #ifdef WOLFSSL_SMALL_STACK
  3141. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3142. #endif
  3143. return ret;
  3144. }
  3145. if (signedAttribSz > 0) {
  3146. attribSetSz = SetSet(signedAttribSz, attribSet);
  3147. /* calculate digest */
  3148. ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
  3149. if (ret == 0)
  3150. ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
  3151. if (ret == 0)
  3152. ret = wc_HashFinal(&hash, hashType, digest);
  3153. } else {
  3154. ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
  3155. if (ret == 0)
  3156. ret = wc_HashFinal(&hash, hashType, digest);
  3157. }
  3158. wc_HashFree(&hash, hashType);
  3159. if (ret < 0) {
  3160. #ifdef WOLFSSL_SMALL_STACK
  3161. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3162. #endif
  3163. return ret;
  3164. }
  3165. }
  3166. /* Set algoID, with NULL attributes */
  3167. algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
  3168. digestStrSz = SetOctetString(hashSz, digestStr);
  3169. digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
  3170. digestInfoSeq);
  3171. XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
  3172. digIdx += digestInfoSeqSz;
  3173. XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
  3174. digIdx += algoIdSz;
  3175. XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
  3176. digIdx += digestStrSz;
  3177. XMEMCPY(digestInfo + digIdx, digest, hashSz);
  3178. digIdx += hashSz;
  3179. XMEMCPY(pkcs7Digest, digestInfo, digIdx);
  3180. *pkcs7DigestSz = digIdx;
  3181. /* set plain digest pointer */
  3182. *plainDigest = pkcs7Digest + digIdx - hashSz;
  3183. *plainDigestSz = hashSz;
  3184. #ifdef WOLFSSL_SMALL_STACK
  3185. XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3186. #endif
  3187. return 0;
  3188. }
  3189. /* Verifies CMS/PKCS7 SignedData content digest matches that which is
  3190. * included in the messageDigest signed attribute. Only called when
  3191. * signed attributes are present, otherwise original signature verification
  3192. * is done over content.
  3193. *
  3194. * pkcs7 - pointer to initialized PKCS7 struct
  3195. * hashBuf - pointer to user-provided hash buffer, used with
  3196. * wc_PKCS7_VerifySignedData_ex()
  3197. * hashBufSz - size of hashBuf, octets
  3198. *
  3199. * return 0 on success, negative on error */
  3200. static int wc_PKCS7_VerifyContentMessageDigest(PKCS7* pkcs7,
  3201. const byte* hashBuf,
  3202. word32 hashSz)
  3203. {
  3204. int ret = 0, digestSz = 0, innerAttribSz = 0;
  3205. word32 idx = 0;
  3206. byte* digestBuf = NULL;
  3207. #ifdef WOLFSSL_SMALL_STACK
  3208. byte* digest = NULL;
  3209. #else
  3210. byte digest[MAX_PKCS7_DIGEST_SZ];
  3211. #endif
  3212. PKCS7DecodedAttrib* attrib;
  3213. enum wc_HashType hashType;
  3214. /* messageDigest OID (1.2.840.113549.1.9.4) */
  3215. const byte mdOid[] =
  3216. { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };
  3217. if (pkcs7 == NULL)
  3218. return BAD_FUNC_ARG;
  3219. if ((pkcs7->content == NULL || pkcs7->contentSz == 0) &&
  3220. (hashBuf == NULL || hashSz == 0)) {
  3221. WOLFSSL_MSG("SignedData bundle has no content or hash to verify");
  3222. return BAD_FUNC_ARG;
  3223. }
  3224. /* lookup messageDigest attribute */
  3225. attrib = findAttrib(pkcs7, mdOid, sizeof(mdOid));
  3226. if (attrib == NULL) {
  3227. WOLFSSL_MSG("messageDigest attribute not in bundle, must be when "
  3228. "signed attribs are present");
  3229. return ASN_PARSE_E;
  3230. }
  3231. /* advance past attrib->value ASN.1 header and length */
  3232. if (attrib->value == NULL || attrib->valueSz == 0)
  3233. return ASN_PARSE_E;
  3234. if (attrib->value[idx++] != ASN_OCTET_STRING)
  3235. return ASN_PARSE_E;
  3236. if (GetLength(attrib->value, &idx, &innerAttribSz, attrib->valueSz) < 0)
  3237. return ASN_PARSE_E;
  3238. /* get hash type and size */
  3239. hashType = wc_OidGetHash(pkcs7->hashOID);
  3240. if (hashType == WC_HASH_TYPE_NONE) {
  3241. WOLFSSL_MSG("Error getting hash type for PKCS7 content verification");
  3242. return BAD_FUNC_ARG;
  3243. }
  3244. /* build content hash if needed, or use existing hash value */
  3245. if (hashBuf == NULL) {
  3246. #ifdef WOLFSSL_SMALL_STACK
  3247. digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
  3248. DYNAMIC_TYPE_TMP_BUFFER);
  3249. if (digest == NULL)
  3250. return MEMORY_E;
  3251. #endif
  3252. XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
  3253. ret = wc_Hash(hashType, pkcs7->content, pkcs7->contentSz, digest,
  3254. MAX_PKCS7_DIGEST_SZ);
  3255. if (ret < 0) {
  3256. WOLFSSL_MSG("Error hashing PKCS7 content for verification");
  3257. #ifdef WOLFSSL_SMALL_STACK
  3258. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3259. #endif
  3260. return ret;
  3261. }
  3262. digestBuf = digest;
  3263. digestSz = wc_HashGetDigestSize(hashType);
  3264. if (digestSz < 0) {
  3265. WOLFSSL_MSG("Invalid hash type");
  3266. #ifdef WOLFSSL_SMALL_STACK
  3267. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3268. #endif
  3269. return digestSz;
  3270. }
  3271. } else {
  3272. /* user passed in pre-computed hash */
  3273. digestBuf = (byte*)hashBuf;
  3274. digestSz = (int)hashSz;
  3275. }
  3276. /* compare generated to hash in messageDigest attribute */
  3277. if ((innerAttribSz != digestSz) ||
  3278. (XMEMCMP(attrib->value + idx, digestBuf, (word32)digestSz) != 0)) {
  3279. WOLFSSL_MSG("Content digest does not match messageDigest attrib value");
  3280. #ifdef WOLFSSL_SMALL_STACK
  3281. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3282. #endif
  3283. return SIG_VERIFY_E;
  3284. }
  3285. if (hashBuf == NULL) {
  3286. #ifdef WOLFSSL_SMALL_STACK
  3287. XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3288. #endif
  3289. }
  3290. return 0;
  3291. }
  3292. /* verifies SignedData signature, over either PKCS#7 DigestInfo or
  3293. * content digest.
  3294. *
  3295. * pkcs7 - pointer to initialized PKCS7 struct
  3296. * sig - signature to verify
  3297. * sigSz - size of sig
  3298. * signedAttrib - signed attributes, or null if empty
  3299. * signedAttribSz - size of signedAttributes
  3300. *
  3301. * return 0 on success, negative on error */
  3302. static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
  3303. word32 sigSz, byte* signedAttrib,
  3304. word32 signedAttribSz,
  3305. const byte* hashBuf, word32 hashSz)
  3306. {
  3307. int ret = 0;
  3308. word32 plainDigestSz = 0, pkcs7DigestSz;
  3309. byte* plainDigest = NULL; /* offset into pkcs7Digest */
  3310. #ifdef WOLFSSL_SMALL_STACK
  3311. byte* pkcs7Digest;
  3312. #else
  3313. byte pkcs7Digest[MAX_PKCS7_DIGEST_SZ];
  3314. #endif
  3315. if (pkcs7 == NULL)
  3316. return BAD_FUNC_ARG;
  3317. /* allocate space to build hash */
  3318. pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;
  3319. #ifdef WOLFSSL_SMALL_STACK
  3320. pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3321. DYNAMIC_TYPE_TMP_BUFFER);
  3322. if (pkcs7Digest == NULL)
  3323. return MEMORY_E;
  3324. #endif
  3325. XMEMSET(pkcs7Digest, 0, pkcs7DigestSz);
  3326. /* verify signed attrib digest matches that of content */
  3327. if (signedAttrib != NULL) {
  3328. ret = wc_PKCS7_VerifyContentMessageDigest(pkcs7, hashBuf, hashSz);
  3329. if (ret != 0) {
  3330. #ifdef WOLFSSL_SMALL_STACK
  3331. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3332. #endif
  3333. return ret;
  3334. }
  3335. }
  3336. /* build hash to verify against */
  3337. ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
  3338. signedAttribSz, pkcs7Digest,
  3339. &pkcs7DigestSz, &plainDigest,
  3340. &plainDigestSz, hashBuf, hashSz);
  3341. if (ret < 0) {
  3342. #ifdef WOLFSSL_SMALL_STACK
  3343. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3344. #endif
  3345. return ret;
  3346. }
  3347. /* If no certificates are available then store the signature and hash for
  3348. * user to verify. Make sure that different return value than success is
  3349. * returned because the signature was not verified here. */
  3350. if (ret == 0) {
  3351. byte haveCert = 0;
  3352. int i;
  3353. for (i = 0; i < MAX_PKCS7_CERTS; i++) {
  3354. if (pkcs7->certSz[i] == 0)
  3355. continue;
  3356. haveCert = 1;
  3357. }
  3358. if (!haveCert) {
  3359. WOLFSSL_MSG("No certificates in bundle to verify signature");
  3360. /* store signature */
  3361. XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
  3362. pkcs7->signature = NULL;
  3363. pkcs7->signatureSz = 0;
  3364. pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap,
  3365. DYNAMIC_TYPE_SIGNATURE);
  3366. if (pkcs7->signature == NULL) {
  3367. #ifdef WOLFSSL_SMALL_STACK
  3368. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3369. #endif
  3370. return MEMORY_E;
  3371. }
  3372. XMEMCPY(pkcs7->signature, sig, sigSz);
  3373. pkcs7->signatureSz = sigSz;
  3374. /* store plain digest (CMS and ECC) */
  3375. XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3376. pkcs7->plainDigest = NULL;
  3377. pkcs7->plainDigestSz = 0;
  3378. pkcs7->plainDigest = (byte*)XMALLOC(plainDigestSz, pkcs7->heap,
  3379. DYNAMIC_TYPE_DIGEST);
  3380. if (pkcs7->plainDigest == NULL) {
  3381. #ifdef WOLFSSL_SMALL_STACK
  3382. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3383. #endif
  3384. return MEMORY_E;
  3385. }
  3386. XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz);
  3387. pkcs7->plainDigestSz = plainDigestSz;
  3388. /* store pkcs7 digest (default RSA) */
  3389. XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
  3390. pkcs7->pkcs7Digest = NULL;
  3391. pkcs7->pkcs7DigestSz = 0;
  3392. pkcs7->pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
  3393. DYNAMIC_TYPE_DIGEST);
  3394. if (pkcs7->pkcs7Digest == NULL) {
  3395. #ifdef WOLFSSL_SMALL_STACK
  3396. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3397. #endif
  3398. return MEMORY_E;
  3399. }
  3400. XMEMCPY(pkcs7->pkcs7Digest, pkcs7Digest, pkcs7DigestSz);
  3401. pkcs7->pkcs7DigestSz = pkcs7DigestSz;
  3402. #ifdef WOLFSSL_SMALL_STACK
  3403. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3404. #endif
  3405. return PKCS7_SIGNEEDS_CHECK;
  3406. }
  3407. }
  3408. switch (pkcs7->publicKeyOID) {
  3409. #ifndef NO_RSA
  3410. case RSAk:
  3411. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,
  3412. pkcs7DigestSz);
  3413. if (ret < 0) {
  3414. WOLFSSL_MSG("PKCS#7 verification failed, trying CMS");
  3415. ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,
  3416. plainDigestSz);
  3417. }
  3418. break;
  3419. #endif
  3420. #ifdef HAVE_ECC
  3421. case ECDSAk:
  3422. ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,
  3423. plainDigestSz);
  3424. break;
  3425. #endif
  3426. default:
  3427. WOLFSSL_MSG("Unsupported public key type");
  3428. ret = BAD_FUNC_ARG;
  3429. }
  3430. #ifdef WOLFSSL_SMALL_STACK
  3431. XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  3432. #endif
  3433. return ret;
  3434. }
  3435. /* set correct public key OID based on signature OID, stores in
  3436. * pkcs7->publicKeyOID and returns same value */
  3437. static int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)
  3438. {
  3439. if (pkcs7 == NULL)
  3440. return BAD_FUNC_ARG;
  3441. pkcs7->publicKeyOID = 0;
  3442. switch (sigOID) {
  3443. #ifndef NO_RSA
  3444. /* RSA signature types */
  3445. case CTC_MD2wRSA:
  3446. case CTC_MD5wRSA:
  3447. case CTC_SHAwRSA:
  3448. case CTC_SHA224wRSA:
  3449. case CTC_SHA256wRSA:
  3450. case CTC_SHA384wRSA:
  3451. case CTC_SHA512wRSA:
  3452. case CTC_SHA3_224wRSA:
  3453. case CTC_SHA3_256wRSA:
  3454. case CTC_SHA3_384wRSA:
  3455. case CTC_SHA3_512wRSA:
  3456. pkcs7->publicKeyOID = RSAk;
  3457. break;
  3458. /* if sigOID is already RSAk */
  3459. case RSAk:
  3460. pkcs7->publicKeyOID = sigOID;
  3461. break;
  3462. #endif
  3463. #ifndef NO_DSA
  3464. /* DSA signature types */
  3465. case CTC_SHAwDSA:
  3466. pkcs7->publicKeyOID = DSAk;
  3467. break;
  3468. /* if sigOID is already DSAk */
  3469. case DSAk:
  3470. pkcs7->publicKeyOID = sigOID;
  3471. break;
  3472. #endif
  3473. #ifdef HAVE_ECC
  3474. /* ECDSA signature types */
  3475. case CTC_SHAwECDSA:
  3476. case CTC_SHA224wECDSA:
  3477. case CTC_SHA256wECDSA:
  3478. case CTC_SHA384wECDSA:
  3479. case CTC_SHA512wECDSA:
  3480. case CTC_SHA3_224wECDSA:
  3481. case CTC_SHA3_256wECDSA:
  3482. case CTC_SHA3_384wECDSA:
  3483. case CTC_SHA3_512wECDSA:
  3484. pkcs7->publicKeyOID = ECDSAk;
  3485. break;
  3486. /* if sigOID is already ECDSAk */
  3487. case ECDSAk:
  3488. pkcs7->publicKeyOID = sigOID;
  3489. break;
  3490. #endif
  3491. default:
  3492. WOLFSSL_MSG("Unsupported public key algorithm");
  3493. return ASN_SIG_KEY_E;
  3494. }
  3495. return pkcs7->publicKeyOID;
  3496. }
  3497. /* Parses through the attributes and adds them to the PKCS7 structure
  3498. * Creates dynamic attribute structures that are free'd with calling
  3499. * wc_PKCS7_Free()
  3500. *
  3501. * NOTE: An attribute has the ASN1 format of
  3502. ** Sequence
  3503. ****** Object ID
  3504. ****** Set
  3505. ********** {PrintableString, UTCTime, OCTET STRING ...}
  3506. *
  3507. * pkcs7 the PKCS7 structure to put the parsed attributes into
  3508. * in buffer holding all attributes
  3509. * inSz size of in buffer
  3510. *
  3511. * returns the number of attributes parsed on success
  3512. */
  3513. static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
  3514. {
  3515. int found = 0;
  3516. word32 idx = 0;
  3517. word32 oid;
  3518. if (pkcs7 == NULL || in == NULL || inSz < 0) {
  3519. return BAD_FUNC_ARG;
  3520. }
  3521. while (idx < (word32)inSz) {
  3522. int length = 0;
  3523. int oidIdx;
  3524. PKCS7DecodedAttrib* attrib;
  3525. if (GetSequence(in, &idx, &length, inSz) < 0)
  3526. return ASN_PARSE_E;
  3527. attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),
  3528. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3529. if (attrib == NULL) {
  3530. return MEMORY_E;
  3531. }
  3532. XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));
  3533. oidIdx = idx;
  3534. if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)
  3535. < 0) {
  3536. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3537. return ASN_PARSE_E;
  3538. }
  3539. attrib->oidSz = idx - oidIdx;
  3540. attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,
  3541. DYNAMIC_TYPE_PKCS7);
  3542. if (attrib->oid == NULL) {
  3543. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3544. return MEMORY_E;
  3545. }
  3546. XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);
  3547. /* Get Set that contains the printable string value */
  3548. if (GetSet(in, &idx, &length, inSz) < 0) {
  3549. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3550. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3551. return ASN_PARSE_E;
  3552. }
  3553. if ((inSz - idx) < (word32)length) {
  3554. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3555. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3556. return ASN_PARSE_E;
  3557. }
  3558. attrib->valueSz = (word32)length;
  3559. attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,
  3560. DYNAMIC_TYPE_PKCS7);
  3561. if (attrib->value == NULL) {
  3562. XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3563. XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3564. return MEMORY_E;
  3565. }
  3566. XMEMCPY(attrib->value, in + idx, attrib->valueSz);
  3567. idx += length;
  3568. /* store attribute in linked list */
  3569. if (pkcs7->decodedAttrib != NULL) {
  3570. attrib->next = pkcs7->decodedAttrib;
  3571. pkcs7->decodedAttrib = attrib;
  3572. } else {
  3573. pkcs7->decodedAttrib = attrib;
  3574. }
  3575. found++;
  3576. }
  3577. return found;
  3578. }
  3579. /* option to turn off support for degenerate cases
  3580. * flag 0 turns off support
  3581. * flag 1 turns on support
  3582. *
  3583. * by default support for SignedData degenerate cases is on
  3584. */
  3585. void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
  3586. {
  3587. if (pkcs7) {
  3588. if (flag) { /* flag of 1 turns on support for degenerate */
  3589. pkcs7->noDegenerate = 0;
  3590. }
  3591. else { /* flag of 0 turns off support */
  3592. pkcs7->noDegenerate = 1;
  3593. }
  3594. }
  3595. }
  3596. /* Parses through a signerInfo set. Reads buffer "in" from "idxIn" to "idxIn" +
  3597. * length treating the current "idxIn" plus the length of set as max possible
  3598. * index.
  3599. *
  3600. * In the case that signed attributes are found "signedAttrib" gets set to point
  3601. * at their location in the buffer "in". Also in this case signedAttribSz gets
  3602. * set to the size of the signedAttrib buffer.
  3603. *
  3604. * returns 0 on success
  3605. */
  3606. static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
  3607. word32* idxIn, int degenerate, byte** signedAttrib, int* signedAttribSz)
  3608. {
  3609. int ret = 0;
  3610. int length;
  3611. int version;
  3612. word32 sigOID = 0, hashOID = 0;
  3613. word32 idx = *idxIn, localIdx;
  3614. byte tag;
  3615. WOLFSSL_ENTER("wc_PKCS7_ParseSignerInfo");
  3616. /* require a signer if degenerate case not allowed */
  3617. if (inSz == 0 && pkcs7->noDegenerate == 1) {
  3618. WOLFSSL_MSG("Set to not allow degenerate cases");
  3619. return PKCS7_NO_SIGNER_E;
  3620. }
  3621. if (inSz == 0 && degenerate == 0) {
  3622. WOLFSSL_MSG("PKCS7 signers expected");
  3623. return PKCS7_NO_SIGNER_E;
  3624. }
  3625. /* not a degenerate case and there is elements in the set */
  3626. if (inSz > 0 && degenerate == 0) {
  3627. ret = wc_PKCS7_SignerInfoNew(pkcs7);
  3628. /* Get the sequence of the first signerInfo */
  3629. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3630. ret = ASN_PARSE_E;
  3631. /* Get the version */
  3632. if (ret == 0 && GetMyVersion(in, &idx, &version, inSz) < 0)
  3633. ret = ASN_PARSE_E;
  3634. if (ret == 0) {
  3635. pkcs7->signerInfo->version = version;
  3636. }
  3637. if (ret == 0 && version == 1) {
  3638. /* Get the sequence of IssuerAndSerialNumber */
  3639. if (GetSequence(in, &idx, &length, inSz) < 0)
  3640. ret = ASN_PARSE_E;
  3641. if (ret == 0) {
  3642. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3643. idx += length;
  3644. }
  3645. } else if (ret == 0 && version == 3) {
  3646. /* Get the sequence of SubjectKeyIdentifier */
  3647. if (idx + 1 > inSz)
  3648. ret = BUFFER_E;
  3649. localIdx = idx;
  3650. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3651. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3652. idx++;
  3653. if (GetLength(in, &idx, &length, inSz) <= 0)
  3654. ret = ASN_PARSE_E;
  3655. if (ret == 0 && idx + 1 > inSz)
  3656. ret = BUFFER_E;
  3657. if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)
  3658. ret = ASN_PARSE_E;
  3659. if (ret == 0 && tag != ASN_OCTET_STRING)
  3660. ret = ASN_PARSE_E;
  3661. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3662. ret = ASN_PARSE_E;
  3663. }
  3664. else {
  3665. /* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version
  3666. * 3 try to get issuerAndSerial */
  3667. localIdx = idx;
  3668. if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3669. tag == ASN_CONTEXT_SPECIFIC) {
  3670. idx++;
  3671. if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
  3672. ret = ASN_PARSE_E;
  3673. }
  3674. else {
  3675. if (pkcs7->version != 3) {
  3676. WOLFSSL_MSG("Unexpected signer info found with version");
  3677. ret = ASN_PARSE_E;
  3678. }
  3679. if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
  3680. ret = ASN_PARSE_E;
  3681. }
  3682. }
  3683. if (ret == 0) {
  3684. if (length > (int)inSz - (int)idx)
  3685. ret = BUFFER_E;
  3686. }
  3687. if (ret == 0) {
  3688. ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
  3689. idx += length;
  3690. }
  3691. } else {
  3692. WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3");
  3693. ret = ASN_VERSION_E;
  3694. }
  3695. /* Get the sequence of digestAlgorithm */
  3696. if (ret == 0 && GetAlgoId(in, &idx, &hashOID, oidHashType, inSz) < 0) {
  3697. ret = ASN_PARSE_E;
  3698. }
  3699. pkcs7->hashOID = (int)hashOID;
  3700. /* Get the IMPLICIT[0] SET OF signedAttributes */
  3701. localIdx = idx;
  3702. if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
  3703. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  3704. idx++;
  3705. if (GetLength(in, &idx, &length, inSz) < 0)
  3706. ret = ASN_PARSE_E;
  3707. /* save pointer and length */
  3708. *signedAttrib = &in[idx];
  3709. *signedAttribSz = length;
  3710. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, *signedAttrib,
  3711. *signedAttribSz) < 0) {
  3712. WOLFSSL_MSG("Error parsing signed attributes");
  3713. ret = ASN_PARSE_E;
  3714. }
  3715. idx += length;
  3716. }
  3717. /* Get digestEncryptionAlgorithm - key type or signature type */
  3718. if (ret == 0 && GetAlgoId(in, &idx, &sigOID, oidIgnoreType, inSz) < 0) {
  3719. ret = ASN_PARSE_E;
  3720. }
  3721. /* store public key type based on digestEncryptionAlgorithm */
  3722. if (ret == 0) {
  3723. ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
  3724. if (ret < 0) {
  3725. WOLFSSL_MSG("Failed to set public key OID from signature");
  3726. }
  3727. else {
  3728. /* if previous return was positive then was success */
  3729. ret = 0;
  3730. }
  3731. }
  3732. }
  3733. /* update index on success */
  3734. if (ret == 0) {
  3735. *idxIn = idx;
  3736. }
  3737. return ret;
  3738. }
  3739. /* Finds the certificates in the message and saves it. By default allows
  3740. * degenerate cases which can have no signer.
  3741. *
  3742. * By default expects type SIGNED_DATA (SignedData) which can have any number of
  3743. * elements in signerInfos collection, including zero. (RFC2315 section 9.1)
  3744. * When adding support for the case of SignedAndEnvelopedData content types a
  3745. * signer is required. In this case the PKCS7 flag noDegenerate could be set.
  3746. */
  3747. static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
  3748. word32 hashSz, byte* in, word32 inSz,
  3749. byte* in2, word32 in2Sz)
  3750. {
  3751. word32 idx, maxIdx = inSz, outerContentType, contentTypeSz = 0, totalSz = 0;
  3752. int length = 0, version = 0, ret = 0;
  3753. byte* content = NULL;
  3754. byte* contentDynamic = NULL;
  3755. byte* sig = NULL;
  3756. byte* cert = NULL;
  3757. byte* signedAttrib = NULL;
  3758. byte* contentType = NULL;
  3759. int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
  3760. word32 localIdx, start;
  3761. byte degenerate = 0;
  3762. byte detached = 0;
  3763. byte tag = 0;
  3764. #ifdef ASN_BER_TO_DER
  3765. byte* der;
  3766. #endif
  3767. int multiPart = 0, keepContent;
  3768. int contentLen = 0;
  3769. byte* pkiMsg = in;
  3770. word32 pkiMsgSz = inSz;
  3771. #ifndef NO_PKCS7_STREAM
  3772. word32 stateIdx = 0;
  3773. #endif
  3774. byte* pkiMsg2 = in2;
  3775. word32 pkiMsg2Sz = in2Sz;
  3776. if (pkcs7 == NULL)
  3777. return BAD_FUNC_ARG;
  3778. #ifndef NO_PKCS7_STREAM
  3779. /* allow for 0 size inputs with stream mode */
  3780. if (pkiMsg == NULL && pkiMsgSz > 0)
  3781. return BAD_FUNC_ARG;
  3782. #else
  3783. if (pkiMsg == NULL || pkiMsgSz == 0)
  3784. return BAD_FUNC_ARG;
  3785. #endif
  3786. if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
  3787. return BAD_FUNC_ARG;
  3788. }
  3789. idx = 0;
  3790. #ifdef ASN_BER_TO_DER
  3791. if (pkcs7->derSz > 0 && pkcs7->der) {
  3792. pkiMsg = pkcs7->der;
  3793. }
  3794. #endif
  3795. #ifndef NO_PKCS7_STREAM
  3796. if (pkcs7->stream == NULL) {
  3797. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  3798. return ret;
  3799. }
  3800. }
  3801. #endif
  3802. switch (pkcs7->state) {
  3803. case WC_PKCS7_START:
  3804. #ifndef NO_PKCS7_STREAM
  3805. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  3806. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
  3807. ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
  3808. &pkiMsg, &idx)) != 0) {
  3809. break;
  3810. }
  3811. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  3812. break;
  3813. }
  3814. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  3815. inSz;
  3816. #endif
  3817. /* determine total message size */
  3818. totalSz = pkiMsgSz;
  3819. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3820. totalSz += pkiMsg2Sz + pkcs7->contentSz;
  3821. }
  3822. /* Get the contentInfo sequence */
  3823. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3824. NO_USER_CHECK) < 0)
  3825. ret = ASN_PARSE_E;
  3826. if (ret == 0 && length == 0 && pkiMsg[idx-1] == ASN_INDEF_LENGTH) {
  3827. #ifdef ASN_BER_TO_DER
  3828. word32 len = 0;
  3829. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  3830. if (ret != LENGTH_ONLY_E)
  3831. return ret;
  3832. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  3833. if (pkcs7->der == NULL)
  3834. return MEMORY_E;
  3835. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  3836. if (ret < 0)
  3837. return ret;
  3838. pkiMsg = in = pkcs7->der;
  3839. inSz = pkcs7->derSz = len;
  3840. idx = 0;
  3841. #ifdef NO_PKCS7_STREAM
  3842. pkiMsgSz = len;
  3843. #else
  3844. wc_PKCS7_ResetStream(pkcs7);
  3845. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  3846. MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_SEQ_SZ +
  3847. MAX_LENGTH_SZ + ASN_TAG_SZ + MAX_OID_SZ +
  3848. MAX_SEQ_SZ, &pkiMsg, &idx)) != 0) {
  3849. break;
  3850. }
  3851. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  3852. inSz;
  3853. totalSz = pkiMsgSz;
  3854. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3855. totalSz += pkiMsg2Sz + pkcs7->contentSz;
  3856. }
  3857. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, len)) != 0) {
  3858. break;
  3859. }
  3860. #endif
  3861. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  3862. NO_USER_CHECK) < 0)
  3863. return ASN_PARSE_E;
  3864. #else
  3865. ret = BER_INDEF_E;
  3866. #endif
  3867. }
  3868. /* Get the contentInfo contentType */
  3869. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,
  3870. pkiMsgSz) < 0)
  3871. ret = ASN_PARSE_E;
  3872. if (ret == 0 && outerContentType != SIGNED_DATA) {
  3873. WOLFSSL_MSG("PKCS#7 input not of type SignedData");
  3874. ret = PKCS7_OID_E;
  3875. }
  3876. /* get the ContentInfo content */
  3877. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)
  3878. ret = ASN_PARSE_E;
  3879. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  3880. ret = ASN_PARSE_E;
  3881. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,
  3882. NO_USER_CHECK) < 0)
  3883. ret = ASN_PARSE_E;
  3884. /* Get the signedData sequence */
  3885. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
  3886. NO_USER_CHECK) < 0)
  3887. ret = ASN_PARSE_E;
  3888. /* Get the version */
  3889. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  3890. ret = ASN_PARSE_E;
  3891. /* version 1 follows RFC 2315 */
  3892. /* version 3 follows RFC 4108 */
  3893. if (ret == 0 && (version != 1 && version != 3)) {
  3894. WOLFSSL_MSG("PKCS#7 signedData needs to be version 1 or 3");
  3895. ret = ASN_VERSION_E;
  3896. }
  3897. pkcs7->version = version;
  3898. /* Get the set of DigestAlgorithmIdentifiers */
  3899. if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  3900. ret = ASN_PARSE_E;
  3901. /* Skip the set. */
  3902. idx += length;
  3903. degenerate = (length == 0) ? 1 : 0;
  3904. if (pkcs7->noDegenerate == 1 && degenerate == 1) {
  3905. ret = PKCS7_NO_SIGNER_E;
  3906. }
  3907. if (ret != 0)
  3908. break;
  3909. #ifndef NO_PKCS7_STREAM
  3910. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  3911. break;
  3912. }
  3913. if (pkiMsg2 && pkiMsg2Sz > 0) {
  3914. pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz;
  3915. }
  3916. wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);
  3917. #endif
  3918. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);
  3919. FALL_THROUGH;
  3920. case WC_PKCS7_VERIFY_STAGE2:
  3921. #ifndef NO_PKCS7_STREAM
  3922. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  3923. MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ
  3924. + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  3925. break;
  3926. }
  3927. wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
  3928. if (pkcs7->stream->length > 0)
  3929. pkiMsgSz = pkcs7->stream->length;
  3930. #ifdef ASN_BER_TO_DER
  3931. else if (pkcs7->der)
  3932. pkiMsgSz = pkcs7->derSz;
  3933. #endif
  3934. else
  3935. pkiMsgSz = inSz;
  3936. #endif
  3937. /* Get the inner ContentInfo sequence */
  3938. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  3939. NO_USER_CHECK) < 0)
  3940. ret = ASN_PARSE_E;
  3941. /* Get the inner ContentInfo contentType */
  3942. if (ret == 0) {
  3943. int isIndef = 0;
  3944. word32 tmpIdx = idx;
  3945. if (length == 0 && pkiMsg[idx-1] == ASN_INDEF_LENGTH) {
  3946. isIndef = 1;
  3947. }
  3948. if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) == 0) {
  3949. contentType = pkiMsg + tmpIdx;
  3950. contentTypeSz = length + (idx - tmpIdx);
  3951. idx += length;
  3952. }
  3953. else {
  3954. ret = ASN_PARSE_E;
  3955. }
  3956. /* if indef, skip EOF */
  3957. if (isIndef) {
  3958. if (idx + 1 >= pkiMsgSz) {
  3959. ret = ASN_PARSE_E;
  3960. }
  3961. else if (pkiMsg[idx] == ASN_EOC && pkiMsg[idx+1] == 0) {
  3962. idx += 2; /* skip EOF + zero byte */
  3963. }
  3964. }
  3965. }
  3966. if (ret != 0)
  3967. break;
  3968. /* Check for content info, it could be omitted when degenerate */
  3969. localIdx = idx;
  3970. ret = 0;
  3971. if (localIdx + 1 > pkiMsgSz) {
  3972. ret = BUFFER_E;
  3973. break;
  3974. }
  3975. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)
  3976. ret = ASN_PARSE_E;
  3977. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  3978. ret = ASN_PARSE_E;
  3979. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
  3980. NO_USER_CHECK) <= 0)
  3981. ret = ASN_PARSE_E;
  3982. if (localIdx >= pkiMsgSz) {
  3983. ret = BUFFER_E;
  3984. }
  3985. /* get length of content in the case that there is multiple parts */
  3986. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  3987. ret = ASN_PARSE_E;
  3988. if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
  3989. multiPart = 1;
  3990. /* Get length of all OCTET_STRINGs. */
  3991. if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,
  3992. NO_USER_CHECK) < 0)
  3993. ret = ASN_PARSE_E;
  3994. /* Check whether there is one OCTET_STRING inside. */
  3995. start = localIdx;
  3996. if (localIdx >= pkiMsgSz) {
  3997. ret = BUFFER_E;
  3998. }
  3999. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)
  4000. != 0)
  4001. ret = ASN_PARSE_E;
  4002. if (ret == 0 && tag != ASN_OCTET_STRING)
  4003. ret = ASN_PARSE_E;
  4004. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length,
  4005. pkiMsgSz, NO_USER_CHECK) < 0)
  4006. ret = ASN_PARSE_E;
  4007. if (ret == 0) {
  4008. /* Use single OCTET_STRING directly, or reset length. */
  4009. if (localIdx - start + length == (word32)contentLen) {
  4010. multiPart = 0;
  4011. } else {
  4012. /* reset length to outer OCTET_STRING for bundle size
  4013. * check below */
  4014. length = contentLen;
  4015. }
  4016. localIdx = start;
  4017. }
  4018. if (ret != 0) {
  4019. /* failed ASN1 parsing during OCTET_STRING checks */
  4020. break;
  4021. }
  4022. }
  4023. /* get length of content in case of single part */
  4024. if (ret == 0 && !multiPart) {
  4025. if (tag != ASN_OCTET_STRING)
  4026. ret = ASN_PARSE_E;
  4027. if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
  4028. &length, pkiMsgSz, NO_USER_CHECK) < 0)
  4029. ret = ASN_PARSE_E;
  4030. }
  4031. /* update idx if successful */
  4032. if (ret == 0) {
  4033. /* support using header and footer without content */
  4034. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  4035. localIdx = 0;
  4036. } else if (pkiMsg2 == NULL && hashBuf == NULL) {
  4037. /* header/footer not separate, check content length is
  4038. * not larger than total bundle size */
  4039. if ((localIdx + length) > pkiMsgSz) {
  4040. WOLFSSL_MSG("Content length detected is larger than "
  4041. "total bundle size");
  4042. ret = BUFFER_E;
  4043. break;
  4044. }
  4045. }
  4046. idx = localIdx;
  4047. }
  4048. else {
  4049. /* If either pkcs7->content and pkcs7->contentSz are set
  4050. * (detached signature where user has set content explicitly
  4051. * into pkcs7->content/contentSz) OR pkcs7->hashBuf and
  4052. * pkcs7->hashSz are set (user has pre-computed content
  4053. * digest and passed in instead of content directly), try to
  4054. * process as a detached signature */
  4055. if (!degenerate &&
  4056. ((pkcs7->content != NULL && pkcs7->contentSz != 0) ||
  4057. (hashBuf != NULL && hashSz > 0)) ) {
  4058. WOLFSSL_MSG("Trying to process as detached signature");
  4059. detached = 1;
  4060. }
  4061. if (!degenerate && !detached && ret != 0)
  4062. break;
  4063. /* no content to read */
  4064. length = 0;
  4065. contentLen = 0;
  4066. pkiMsg2 = pkiMsg;
  4067. pkiMsg2Sz = pkiMsgSz;
  4068. }
  4069. #ifndef NO_PKCS7_STREAM
  4070. /* save detached flag value */
  4071. pkcs7->stream->detached = detached;
  4072. /* save contentType */
  4073. pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,
  4074. DYNAMIC_TYPE_PKCS7);
  4075. if (pkcs7->stream->nonce == NULL) {
  4076. ret = MEMORY_E;
  4077. break;
  4078. }
  4079. else {
  4080. pkcs7->stream->nonceSz = contentTypeSz;
  4081. XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);
  4082. }
  4083. /* content expected? */
  4084. if ((ret == 0 && length > 0) &&
  4085. !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
  4086. pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;
  4087. }
  4088. else {
  4089. pkcs7->stream->expected = ASN_TAG_SZ + MAX_LENGTH_SZ;
  4090. }
  4091. if (pkcs7->stream->expected > (pkcs7->stream->maxLen - idx)) {
  4092. pkcs7->stream->expected = pkcs7->stream->maxLen - idx;
  4093. }
  4094. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4095. break;
  4096. }
  4097. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);
  4098. /* content length is in multiple parts */
  4099. if (multiPart) {
  4100. pkcs7->stream->expected = contentLen + ASN_TAG_SZ;
  4101. }
  4102. pkcs7->stream->multi = multiPart;
  4103. #endif
  4104. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);
  4105. FALL_THROUGH;
  4106. case WC_PKCS7_VERIFY_STAGE3:
  4107. #ifndef NO_PKCS7_STREAM
  4108. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4109. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4110. break;
  4111. }
  4112. #ifdef ASN_BER_TO_DER
  4113. if (pkcs7->derSz != 0)
  4114. pkiMsgSz = pkcs7->derSz;
  4115. else
  4116. #endif
  4117. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  4118. inSz;
  4119. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);
  4120. if (pkcs7->stream->length > 0) {
  4121. localIdx = 0;
  4122. }
  4123. multiPart = pkcs7->stream->multi;
  4124. detached = pkcs7->stream->detached;
  4125. maxIdx = idx + pkcs7->stream->expected;
  4126. #endif
  4127. /* Break out before content because it can be optional in degenerate
  4128. * cases. */
  4129. if (ret != 0 && !degenerate)
  4130. break;
  4131. /* get parts of content */
  4132. if (ret == 0 && multiPart) {
  4133. int i = 0;
  4134. keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
  4135. if (keepContent) {
  4136. /* Create a buffer to hold content of OCTET_STRINGs. */
  4137. pkcs7->contentDynamic = (byte*)XMALLOC(contentLen, pkcs7->heap,
  4138. DYNAMIC_TYPE_PKCS7);
  4139. if (pkcs7->contentDynamic == NULL)
  4140. ret = MEMORY_E;
  4141. }
  4142. start = localIdx;
  4143. /* Use the data from each OCTET_STRING. */
  4144. while (ret == 0 && localIdx < start + contentLen) {
  4145. if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)
  4146. ret = ASN_PARSE_E;
  4147. if (ret == 0 && tag != ASN_OCTET_STRING)
  4148. ret = ASN_PARSE_E;
  4149. if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
  4150. ret = ASN_PARSE_E;
  4151. if (ret == 0 && length + localIdx > start + contentLen)
  4152. ret = ASN_PARSE_E;
  4153. if (ret == 0) {
  4154. if (keepContent) {
  4155. XMEMCPY(pkcs7->contentDynamic + i, pkiMsg + localIdx,
  4156. length);
  4157. }
  4158. i += length;
  4159. localIdx += length;
  4160. }
  4161. }
  4162. localIdx = start; /* reset for sanity check, increment later */
  4163. length = i;
  4164. }
  4165. /* Save the inner data as the content. */
  4166. if (ret == 0 && length > 0) {
  4167. contentSz = length;
  4168. /* support using header and footer without content */
  4169. if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
  4170. /* Content not provided, use provided pkiMsg2 footer */
  4171. content = NULL;
  4172. localIdx = 0;
  4173. if (contentSz != (int)pkcs7->contentSz) {
  4174. WOLFSSL_MSG("Data signed does not match contentSz provided");
  4175. ret = BUFFER_E;
  4176. }
  4177. }
  4178. else {
  4179. if ((word32)length > pkiMsgSz - localIdx) {
  4180. ret = BUFFER_E;
  4181. }
  4182. /* Content pointer for calculating hashes later */
  4183. if (ret == 0 && !multiPart) {
  4184. content = &pkiMsg[localIdx];
  4185. }
  4186. if (ret == 0 && multiPart) {
  4187. content = pkcs7->contentDynamic;
  4188. }
  4189. if (ret == 0) {
  4190. idx += length;
  4191. }
  4192. pkiMsg2 = pkiMsg;
  4193. pkiMsg2Sz = pkiMsgSz;
  4194. #ifndef NO_PKCS7_STREAM
  4195. pkiMsg2Sz = pkcs7->stream->maxLen;
  4196. pkcs7->stream->varOne = pkiMsg2Sz;
  4197. pkcs7->stream->flagOne = 1;
  4198. #endif
  4199. }
  4200. }
  4201. else {
  4202. pkiMsg2 = pkiMsg;
  4203. pkiMsg2Sz = pkiMsgSz;
  4204. #ifndef NO_PKCS7_STREAM
  4205. pkiMsg2Sz = pkcs7->stream->maxLen;
  4206. pkcs7->stream->varOne = pkiMsg2Sz;
  4207. pkcs7->stream->flagOne = 1;
  4208. #endif
  4209. }
  4210. /* If getting the content info failed with non degenerate then return the
  4211. * error case. Otherwise with a degenerate it is ok if the content
  4212. * info was omitted */
  4213. if (!degenerate && !detached && (ret != 0)) {
  4214. break;
  4215. }
  4216. else {
  4217. ret = 0; /* reset ret state on degenerate case */
  4218. }
  4219. #ifndef NO_PKCS7_STREAM
  4220. /* save content */
  4221. if (detached == 1) {
  4222. /* if detached, use content from user in pkcs7 struct */
  4223. content = pkcs7->content;
  4224. contentSz = pkcs7->contentSz;
  4225. }
  4226. if (content != NULL) {
  4227. XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4228. pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,
  4229. DYNAMIC_TYPE_PKCS7);
  4230. if (pkcs7->stream->content == NULL) {
  4231. ret = MEMORY_E;
  4232. break;
  4233. }
  4234. else {
  4235. XMEMCPY(pkcs7->stream->content, content, contentSz);
  4236. pkcs7->stream->contentSz = contentSz;
  4237. }
  4238. }
  4239. #endif /* !NO_PKCS7_STREAM */
  4240. /* Get the implicit[0] set of certificates */
  4241. if (ret == 0 && idx >= pkiMsg2Sz)
  4242. ret = BUFFER_E;
  4243. length = 0; /* set length to 0 to check if reading in any certs */
  4244. localIdx = idx;
  4245. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  4246. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  4247. idx++;
  4248. if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)
  4249. < 0)
  4250. ret = ASN_PARSE_E;
  4251. }
  4252. if (ret != 0) {
  4253. break;
  4254. }
  4255. #ifndef NO_PKCS7_STREAM
  4256. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  4257. stateIdx = idx; /* case where all data was read from in2 */
  4258. }
  4259. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4260. break;
  4261. }
  4262. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4263. if (length > 0) {
  4264. pkcs7->stream->expected = length;
  4265. }
  4266. else {
  4267. pkcs7->stream->expected = MAX_SEQ_SZ;
  4268. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  4269. pkcs7->stream->totalRd) + pkcs7->stream->length) {
  4270. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4271. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4272. }
  4273. }
  4274. #endif
  4275. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
  4276. FALL_THROUGH;
  4277. case WC_PKCS7_VERIFY_STAGE4:
  4278. #ifndef NO_PKCS7_STREAM
  4279. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4280. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4281. break;
  4282. }
  4283. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4284. if (pkcs7->stream->flagOne) {
  4285. pkiMsg2 = pkiMsg;
  4286. }
  4287. /* restore content */
  4288. content = pkcs7->stream->content;
  4289. contentSz = pkcs7->stream->contentSz;
  4290. /* restore detached flag */
  4291. detached = pkcs7->stream->detached;
  4292. /* store certificate if needed */
  4293. if (length > 0 && in2Sz == 0) {
  4294. /* free tmpCert if not NULL */
  4295. XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4296. pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
  4297. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4298. if ((pkiMsg2 == NULL) || (pkcs7->stream->tmpCert == NULL)) {
  4299. ret = MEMORY_E;
  4300. break;
  4301. }
  4302. XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
  4303. pkiMsg2 = pkcs7->stream->tmpCert;
  4304. pkiMsg2Sz = length;
  4305. idx = 0;
  4306. }
  4307. #endif
  4308. if (length > 0) {
  4309. /* At this point, idx is at the first certificate in
  4310. * a set of certificates. There may be more than one,
  4311. * or none, or they may be a PKCS 6 extended
  4312. * certificate. We want to save the first cert if it
  4313. * is X.509. */
  4314. word32 certIdx = idx;
  4315. if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)
  4316. ret = BUFFER_E;
  4317. if (ret == 0)
  4318. ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);
  4319. if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4320. if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
  4321. ret = ASN_PARSE_E;
  4322. cert = &pkiMsg2[idx];
  4323. certSz += (certIdx - idx);
  4324. if (certSz > length) {
  4325. ret = BUFFER_E;
  4326. break;
  4327. }
  4328. }
  4329. #ifdef ASN_BER_TO_DER
  4330. der = pkcs7->der;
  4331. pkcs7->der = NULL;
  4332. #endif
  4333. version = pkcs7->version;
  4334. if (ret == 0) {
  4335. byte isDynamic = (byte)pkcs7->isDynamic;
  4336. #ifndef NO_PKCS7_STREAM
  4337. PKCS7State* stream = pkcs7->stream;
  4338. pkcs7->stream = NULL;
  4339. #endif
  4340. /* Save dynamic content before freeing PKCS7 struct */
  4341. if (pkcs7->contentDynamic != NULL) {
  4342. contentDynamic = (byte*)XMALLOC(contentSz,
  4343. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4344. if (contentDynamic == NULL) {
  4345. ret = MEMORY_E;
  4346. break;
  4347. }
  4348. XMEMCPY(contentDynamic, pkcs7->contentDynamic,
  4349. contentSz);
  4350. }
  4351. /* Free pkcs7 resources but not the structure itself */
  4352. pkcs7->isDynamic = 0;
  4353. wc_PKCS7_Free(pkcs7);
  4354. pkcs7->isDynamic = isDynamic;
  4355. /* This will reset PKCS7 structure and then set the
  4356. * certificate */
  4357. ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
  4358. /* Restore pkcs7->contentDynamic from above, will be
  4359. * freed by application with wc_PKCS7_Free() */
  4360. if (contentDynamic != NULL) {
  4361. pkcs7->contentDynamic = contentDynamic;
  4362. contentDynamic = NULL;
  4363. }
  4364. #ifndef NO_PKCS7_STREAM
  4365. pkcs7->stream = stream;
  4366. #endif
  4367. }
  4368. pkcs7->version = version;
  4369. #ifdef ASN_BER_TO_DER
  4370. pkcs7->der = der;
  4371. #endif
  4372. if (ret != 0)
  4373. break;
  4374. /* iterate through any additional certificates */
  4375. if (ret == 0 && MAX_PKCS7_CERTS > 0) {
  4376. int sz = 0;
  4377. int i;
  4378. pkcs7->cert[0] = cert;
  4379. pkcs7->certSz[0] = certSz;
  4380. certIdx = idx + certSz;
  4381. for (i = 1; i < MAX_PKCS7_CERTS &&
  4382. certIdx + 1 < pkiMsg2Sz &&
  4383. certIdx + 1 < (word32)length; i++) {
  4384. localIdx = certIdx;
  4385. if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,
  4386. pkiMsg2Sz) < 0) {
  4387. ret = ASN_PARSE_E;
  4388. break;
  4389. }
  4390. if (ret == 0 &&
  4391. tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
  4392. if (GetLength(pkiMsg2, &certIdx, &sz,
  4393. pkiMsg2Sz) < 0) {
  4394. ret = ASN_PARSE_E;
  4395. break;
  4396. }
  4397. pkcs7->cert[i] = &pkiMsg2[localIdx];
  4398. pkcs7->certSz[i] = sz + (certIdx - localIdx);
  4399. certIdx += sz;
  4400. }
  4401. }
  4402. }
  4403. }
  4404. idx += length;
  4405. if (!detached) {
  4406. /* set content and size after init of PKCS7 structure */
  4407. pkcs7->content = content;
  4408. pkcs7->contentSz = contentSz;
  4409. }
  4410. #ifndef NO_PKCS7_STREAM
  4411. else {
  4412. /* save content if detached and using streaming API */
  4413. if (pkcs7->content != NULL) {
  4414. XFREE(pkcs7->stream->content, pkcs7->heap,
  4415. DYNAMIC_TYPE_PKCS7);
  4416. pkcs7->stream->content = (byte*)XMALLOC(pkcs7->contentSz,
  4417. pkcs7->heap,
  4418. DYNAMIC_TYPE_PKCS7);
  4419. if (pkcs7->stream->content == NULL) {
  4420. ret = MEMORY_E;
  4421. break;
  4422. }
  4423. else {
  4424. XMEMCPY(pkcs7->stream->content, pkcs7->content,
  4425. contentSz);
  4426. pkcs7->stream->contentSz = pkcs7->contentSz;
  4427. }
  4428. }
  4429. }
  4430. #endif
  4431. if (ret != 0) {
  4432. break;
  4433. }
  4434. #ifndef NO_PKCS7_STREAM
  4435. /* factor in that recent idx was in cert buffer. If in2 buffer was
  4436. * used then don't advance idx. */
  4437. if (length > 0 && pkcs7->stream->flagOne &&
  4438. pkcs7->stream->length == 0) {
  4439. idx = stateIdx + idx;
  4440. if (idx > inSz) {
  4441. /* index is more than input size */
  4442. ret = BUFFER_E;
  4443. break;
  4444. }
  4445. }
  4446. else {
  4447. stateIdx = idx; /* didn't read any from internal buffer */
  4448. }
  4449. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4450. break;
  4451. }
  4452. if (pkcs7->stream->flagOne && pkcs7->stream->length > 0) {
  4453. idx = stateIdx + idx;
  4454. }
  4455. pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +
  4456. MAX_SET_SZ;
  4457. if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
  4458. pkcs7->stream->totalRd) + pkcs7->stream->length)
  4459. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4460. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4461. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0);
  4462. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4463. #endif
  4464. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
  4465. FALL_THROUGH;
  4466. case WC_PKCS7_VERIFY_STAGE5:
  4467. #ifndef NO_PKCS7_STREAM
  4468. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4469. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4470. break;
  4471. }
  4472. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4473. if (pkcs7->stream->flagOne) {
  4474. pkiMsg2 = pkiMsg;
  4475. /* check if using internal stream buffer and should adjust sz */
  4476. if (pkiMsg != in && pkcs7->stream->length > 0) {
  4477. pkiMsg2Sz = pkcs7->stream->length;
  4478. }
  4479. }
  4480. /* restore content type */
  4481. contentType = pkcs7->stream->nonce;
  4482. contentTypeSz = pkcs7->stream->nonceSz;
  4483. maxIdx = idx + pkcs7->stream->expected;
  4484. if (maxIdx > pkiMsg2Sz) {
  4485. ret = BUFFER_E;
  4486. break;
  4487. }
  4488. stateIdx = idx;
  4489. #endif
  4490. /* set contentType and size after init of PKCS7 structure */
  4491. if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,
  4492. contentTypeSz) < 0)
  4493. ret = ASN_PARSE_E;
  4494. /* Get the implicit[1] set of crls */
  4495. if (ret == 0 && idx >= maxIdx)
  4496. ret = BUFFER_E;
  4497. localIdx = idx;
  4498. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
  4499. && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  4500. idx++;
  4501. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4502. ret = ASN_PARSE_E;
  4503. /* Skip the set */
  4504. idx += length;
  4505. }
  4506. /* Get the set of signerInfos */
  4507. if (ret == 0 && GetSet_ex(pkiMsg2, &idx, &length, maxIdx,
  4508. NO_USER_CHECK) < 0)
  4509. ret = ASN_PARSE_E;
  4510. if (ret != 0)
  4511. break;
  4512. #ifndef NO_PKCS7_STREAM
  4513. if (!pkcs7->stream->flagOne) {
  4514. stateIdx = idx; /* didn't read any from internal buffer */
  4515. }
  4516. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
  4517. break;
  4518. }
  4519. wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
  4520. if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
  4521. if (length > 0) {
  4522. pkcs7->stream->expected = length;
  4523. }
  4524. else {
  4525. pkcs7->stream->expected = 0;
  4526. }
  4527. }
  4528. else {
  4529. /* last state expect the rest of the buffer */
  4530. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  4531. pkcs7->stream->totalRd) + pkcs7->stream->length;
  4532. }
  4533. #endif
  4534. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);
  4535. FALL_THROUGH;
  4536. case WC_PKCS7_VERIFY_STAGE6:
  4537. #ifndef NO_PKCS7_STREAM
  4538. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
  4539. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  4540. break;
  4541. }
  4542. wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
  4543. if (pkcs7->stream->flagOne) {
  4544. pkiMsg2 = pkiMsg;
  4545. /* check if using internal stream buffer and should adjust sz */
  4546. if (pkiMsg != in && pkcs7->stream->length > 0) {
  4547. pkiMsg2Sz = pkcs7->stream->length;
  4548. }
  4549. else {
  4550. /* if pkiMsg2 is pkiMsg and not using an internal stream
  4551. * buffer then the size is limited by inSz */
  4552. pkiMsg2Sz = inSz;
  4553. }
  4554. }
  4555. /* restore content */
  4556. content = pkcs7->stream->content;
  4557. contentSz = pkcs7->stream->contentSz;
  4558. #endif
  4559. ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx,
  4560. degenerate, &signedAttrib, &signedAttribSz);
  4561. /* parse out the signature if present and verify it */
  4562. if (ret == 0 && length > 0 && degenerate == 0) {
  4563. WOLFSSL_MSG("Parsing signature and verifying");
  4564. if (idx >= pkiMsg2Sz)
  4565. ret = BUFFER_E;
  4566. /* Get the signature */
  4567. localIdx = idx;
  4568. if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,
  4569. pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {
  4570. idx++;
  4571. if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
  4572. ret = ASN_PARSE_E;
  4573. /* save pointer and length */
  4574. sig = &pkiMsg2[idx];
  4575. sigSz = length;
  4576. idx += length;
  4577. }
  4578. pkcs7->content = content;
  4579. pkcs7->contentSz = contentSz;
  4580. if (ret == 0) {
  4581. ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
  4582. signedAttrib, signedAttribSz,
  4583. hashBuf, hashSz);
  4584. }
  4585. }
  4586. if (ret < 0)
  4587. break;
  4588. ret = 0; /* success */
  4589. #ifndef NO_PKCS7_STREAM
  4590. wc_PKCS7_ResetStream(pkcs7);
  4591. #endif
  4592. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4593. break;
  4594. default:
  4595. WOLFSSL_MSG("PKCS7 Unknown verify state");
  4596. ret = BAD_FUNC_ARG;
  4597. }
  4598. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  4599. #ifndef NO_PKCS7_STREAM
  4600. wc_PKCS7_ResetStream(pkcs7);
  4601. #endif
  4602. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  4603. }
  4604. return ret;
  4605. }
  4606. /* Gets a copy of the SID parsed from signerInfo. This can be called after
  4607. * wc_PKCS7_VerifySignedData has been called. SID can be SKID in version 3 case
  4608. * or issuerAndSerialNumber.
  4609. *
  4610. * return 0 on success and LENGTH_ONLY_E if just setting "outSz" for buffer
  4611. * length needed.
  4612. */
  4613. int wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz)
  4614. {
  4615. if (outSz == NULL || pkcs7 == NULL) {
  4616. return BAD_FUNC_ARG;
  4617. }
  4618. if (pkcs7->signerInfo == NULL) {
  4619. WOLFSSL_MSG("Either the bundle had no signers or"
  4620. "wc_PKCS7_VerifySignedData needs called yet");
  4621. return PKCS7_NO_SIGNER_E;
  4622. }
  4623. if (pkcs7->signerInfo->sidSz == 0) {
  4624. WOLFSSL_MSG("Bundle had no signer SID set");
  4625. return PKCS7_NO_SIGNER_E;
  4626. }
  4627. if (out == NULL) {
  4628. *outSz = pkcs7->signerInfo->sidSz;
  4629. return LENGTH_ONLY_E;
  4630. }
  4631. if (*outSz < pkcs7->signerInfo->sidSz) {
  4632. WOLFSSL_MSG("Buffer being passed in is not large enough for SKID");
  4633. return BUFFER_E;
  4634. }
  4635. XMEMCPY(out, pkcs7->signerInfo->sid, pkcs7->signerInfo->sidSz);
  4636. *outSz = pkcs7->signerInfo->sidSz;
  4637. return 0;
  4638. }
  4639. /* SignedData verification function variant that allows pre-computed content
  4640. * message digest and optional PKCS7/CMS bundle content header/footer to be
  4641. * used for verification. Useful for large data signing.
  4642. *
  4643. * pkcs7 - pointer to initialized PKCS7 structure
  4644. * hashBuf - message digest of content
  4645. * hashSz - size of hashBuf, octets
  4646. * pkiMsgHead - PKCS7/CMS header that goes on top of the raw data signed,
  4647. * as output from wc_PKCS7_EncodeSignedData_ex (if also using
  4648. * pkiMsgFoot). Otherwise, PKCS7/CMS bundle with
  4649. * detached signature - will use hashBuf/hashSz to verify.
  4650. * pkiMsgHeadSz - size of pkiMsgHead, octets
  4651. * pkiMsgFoot - PKCS7/CMS footer that goes at the end of the raw data signed,
  4652. * as output from wc_PKCS7_EncodeSignedData_ex. Can be NULL
  4653. * if pkiMsgHead is a direct detached signature bundle to be used
  4654. * with hashBuf/hashSz.
  4655. * pkiMsgFootSz - size of pkiMsgFoot, octets. Should be 0 if pkiMsgFoot is NULL.
  4656. *
  4657. * Returns 0 on success, negative upon error.
  4658. *
  4659. */
  4660. int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
  4661. word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
  4662. word32 pkiMsgFootSz)
  4663. {
  4664. return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,
  4665. pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);
  4666. }
  4667. int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
  4668. {
  4669. return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);
  4670. }
  4671. /* Generate random content encryption key, store into pkcs7->cek and
  4672. * pkcs7->cekSz.
  4673. *
  4674. * pkcs7 - pointer to initialized PKCS7 structure
  4675. * len - length of key to be generated
  4676. *
  4677. * Returns 0 on success, negative upon error */
  4678. static int PKCS7_GenerateContentEncryptionKey(PKCS7* pkcs7, word32 len)
  4679. {
  4680. int ret;
  4681. WC_RNG rng;
  4682. byte* tmpKey;
  4683. if (pkcs7 == NULL || len == 0)
  4684. return BAD_FUNC_ARG;
  4685. /* if key already exists, don't need to re-generate */
  4686. if (pkcs7->cek != NULL && pkcs7->cekSz != 0) {
  4687. /* if key exists, but is different size, return error */
  4688. if (pkcs7->cekSz != len) {
  4689. WOLFSSL_MSG("Random content-encryption key size is inconsistent "
  4690. "between CMS recipients");
  4691. return WC_KEY_SIZE_E;
  4692. }
  4693. return 0;
  4694. }
  4695. /* allocate space for cek */
  4696. tmpKey = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4697. if (tmpKey == NULL)
  4698. return MEMORY_E;
  4699. XMEMSET(tmpKey, 0, len);
  4700. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  4701. if (ret != 0) {
  4702. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4703. return ret;
  4704. }
  4705. ret = wc_RNG_GenerateBlock(&rng, tmpKey, len);
  4706. if (ret != 0) {
  4707. wc_FreeRng(&rng);
  4708. XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4709. return ret;
  4710. }
  4711. /* store into PKCS7, memory freed during final cleanup */
  4712. pkcs7->cek = tmpKey;
  4713. pkcs7->cekSz = len;
  4714. wc_FreeRng(&rng);
  4715. return 0;
  4716. }
  4717. /* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */
  4718. static int wc_PKCS7_KeyWrap(byte* cek, word32 cekSz, byte* kek,
  4719. word32 kekSz, byte* out, word32 outSz,
  4720. int keyWrapAlgo, int direction)
  4721. {
  4722. int ret = 0;
  4723. if (cek == NULL || kek == NULL || out == NULL)
  4724. return BAD_FUNC_ARG;
  4725. switch (keyWrapAlgo) {
  4726. #ifndef NO_AES
  4727. #ifdef WOLFSSL_AES_128
  4728. case AES128_WRAP:
  4729. #endif
  4730. #ifdef WOLFSSL_AES_192
  4731. case AES192_WRAP:
  4732. #endif
  4733. #ifdef WOLFSSL_AES_256
  4734. case AES256_WRAP:
  4735. #endif
  4736. if (direction == AES_ENCRYPTION) {
  4737. ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,
  4738. out, outSz, NULL);
  4739. } else if (direction == AES_DECRYPTION) {
  4740. ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,
  4741. out, outSz, NULL);
  4742. } else {
  4743. WOLFSSL_MSG("Bad key un/wrap direction");
  4744. return BAD_FUNC_ARG;
  4745. }
  4746. if (ret <= 0)
  4747. return ret;
  4748. break;
  4749. #endif /* NO_AES */
  4750. default:
  4751. WOLFSSL_MSG("Unsupported key wrap algorithm");
  4752. return BAD_KEYWRAP_ALG_E;
  4753. };
  4754. (void)cekSz;
  4755. (void)kekSz;
  4756. (void)outSz;
  4757. (void)direction;
  4758. return ret;
  4759. }
  4760. #ifdef HAVE_ECC
  4761. /* KARI == KeyAgreeRecipientInfo (key agreement) */
  4762. typedef struct WC_PKCS7_KARI {
  4763. DecodedCert* decoded; /* decoded recip cert */
  4764. void* heap; /* user heap, points to PKCS7->heap */
  4765. int devId; /* device ID for HW based private key */
  4766. ecc_key* recipKey; /* recip key (pub | priv) */
  4767. ecc_key* senderKey; /* sender key (pub | priv) */
  4768. byte* senderKeyExport; /* sender ephemeral key DER */
  4769. byte* kek; /* key encryption key */
  4770. byte* ukm; /* OPTIONAL user keying material */
  4771. byte* sharedInfo; /* ECC-CMS-SharedInfo ASN.1 encoded blob */
  4772. word32 senderKeyExportSz; /* size of sender ephemeral key DER */
  4773. word32 kekSz; /* size of key encryption key */
  4774. word32 ukmSz; /* size of user keying material */
  4775. word32 sharedInfoSz; /* size of ECC-CMS-SharedInfo encoded */
  4776. byte ukmOwner; /* do we own ukm buffer? 1:yes, 0:no */
  4777. byte direction; /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */
  4778. byte decodedInit : 1; /* indicates decoded was initialized */
  4779. byte recipKeyInit : 1; /* indicates recipKey was initialized */
  4780. byte senderKeyInit : 1; /* indicates senderKey was initialized */
  4781. } WC_PKCS7_KARI;
  4782. /* allocate and create new WC_PKCS7_KARI struct,
  4783. * returns struct pointer on success, NULL on failure */
  4784. static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)
  4785. {
  4786. WC_PKCS7_KARI* kari = NULL;
  4787. if (pkcs7 == NULL)
  4788. return NULL;
  4789. kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,
  4790. DYNAMIC_TYPE_PKCS7);
  4791. if (kari == NULL) {
  4792. WOLFSSL_MSG("Failed to allocate WC_PKCS7_KARI");
  4793. return NULL;
  4794. }
  4795. kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  4796. DYNAMIC_TYPE_PKCS7);
  4797. if (kari->decoded == NULL) {
  4798. WOLFSSL_MSG("Failed to allocate DecodedCert");
  4799. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4800. return NULL;
  4801. }
  4802. kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4803. DYNAMIC_TYPE_PKCS7);
  4804. if (kari->recipKey == NULL) {
  4805. WOLFSSL_MSG("Failed to allocate recipient ecc_key");
  4806. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4807. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4808. return NULL;
  4809. }
  4810. kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
  4811. DYNAMIC_TYPE_PKCS7);
  4812. if (kari->senderKey == NULL) {
  4813. WOLFSSL_MSG("Failed to allocate sender ecc_key");
  4814. XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4815. XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4816. XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  4817. return NULL;
  4818. }
  4819. kari->senderKeyExport = NULL;
  4820. kari->senderKeyExportSz = 0;
  4821. kari->kek = NULL;
  4822. kari->kekSz = 0;
  4823. kari->ukm = NULL;
  4824. kari->ukmSz = 0;
  4825. kari->ukmOwner = 0;
  4826. kari->sharedInfo = NULL;
  4827. kari->sharedInfoSz = 0;
  4828. kari->direction = direction;
  4829. kari->decodedInit = 0;
  4830. kari->recipKeyInit = 0;
  4831. kari->senderKeyInit = 0;
  4832. kari->heap = pkcs7->heap;
  4833. kari->devId = pkcs7->devId;
  4834. return kari;
  4835. }
  4836. /* free WC_PKCS7_KARI struct, return 0 on success */
  4837. static int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)
  4838. {
  4839. void* heap;
  4840. if (kari) {
  4841. heap = kari->heap;
  4842. if (kari->decoded) {
  4843. if (kari->decodedInit)
  4844. FreeDecodedCert(kari->decoded);
  4845. XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);
  4846. }
  4847. if (kari->senderKey) {
  4848. if (kari->senderKeyInit)
  4849. wc_ecc_free(kari->senderKey);
  4850. XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);
  4851. }
  4852. if (kari->recipKey) {
  4853. if (kari->recipKeyInit)
  4854. wc_ecc_free(kari->recipKey);
  4855. XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);
  4856. }
  4857. if (kari->senderKeyExport) {
  4858. ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);
  4859. XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);
  4860. kari->senderKeyExportSz = 0;
  4861. }
  4862. if (kari->kek) {
  4863. ForceZero(kari->kek, kari->kekSz);
  4864. XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);
  4865. kari->kekSz = 0;
  4866. }
  4867. if (kari->ukm) {
  4868. if (kari->ukmOwner == 1) {
  4869. XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);
  4870. }
  4871. kari->ukmSz = 0;
  4872. }
  4873. if (kari->sharedInfo) {
  4874. ForceZero(kari->sharedInfo, kari->sharedInfoSz);
  4875. XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);
  4876. kari->sharedInfoSz = 0;
  4877. }
  4878. XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);
  4879. }
  4880. (void)heap;
  4881. return 0;
  4882. }
  4883. /* parse recipient cert/key, return 0 on success, negative on error
  4884. * key/keySz only needed during decoding (WC_PKCS7_DECODE) */
  4885. static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
  4886. word32 certSz, const byte* key,
  4887. word32 keySz)
  4888. {
  4889. int ret;
  4890. word32 idx;
  4891. if (kari == NULL || kari->decoded == NULL ||
  4892. cert == NULL || certSz == 0)
  4893. return BAD_FUNC_ARG;
  4894. /* decode certificate */
  4895. InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
  4896. kari->decodedInit = 1;
  4897. ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
  4898. if (ret < 0)
  4899. return ret;
  4900. /* only supports ECDSA for now */
  4901. if (kari->decoded->keyOID != ECDSAk) {
  4902. WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
  4903. return BAD_FUNC_ARG;
  4904. }
  4905. /* make sure subject key id was read from cert */
  4906. if (kari->decoded->extSubjKeyIdSet == 0) {
  4907. WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
  4908. return BAD_FUNC_ARG;
  4909. }
  4910. ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
  4911. if (ret != 0)
  4912. return ret;
  4913. kari->recipKeyInit = 1;
  4914. /* get recip public key */
  4915. if (kari->direction == WC_PKCS7_ENCODE) {
  4916. idx = 0;
  4917. ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
  4918. kari->recipKey, kari->decoded->pubKeySize);
  4919. if (ret != 0)
  4920. return ret;
  4921. }
  4922. /* get recip private key */
  4923. else if (kari->direction == WC_PKCS7_DECODE) {
  4924. if (key != NULL && keySz > 0) {
  4925. idx = 0;
  4926. ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);
  4927. }
  4928. else if (kari->devId == INVALID_DEVID) {
  4929. ret = BAD_FUNC_ARG;
  4930. }
  4931. if (ret != 0)
  4932. return ret;
  4933. } else {
  4934. /* bad direction */
  4935. return BAD_FUNC_ARG;
  4936. }
  4937. (void)idx;
  4938. return 0;
  4939. }
  4940. /* create ephemeral ECC key, places ecc_key in kari->senderKey,
  4941. * DER encoded in kari->senderKeyExport. return 0 on success,
  4942. * negative on error */
  4943. static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari)
  4944. {
  4945. int ret;
  4946. WC_RNG rng;
  4947. if (kari == NULL || kari->decoded == NULL ||
  4948. kari->recipKey == NULL || kari->recipKey->dp == NULL)
  4949. return BAD_FUNC_ARG;
  4950. kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,
  4951. kari->heap, DYNAMIC_TYPE_PKCS7);
  4952. if (kari->senderKeyExport == NULL)
  4953. return MEMORY_E;
  4954. kari->senderKeyExportSz = kari->decoded->pubKeySize;
  4955. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  4956. if (ret != 0) {
  4957. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4958. kari->senderKeyExportSz = 0;
  4959. kari->senderKeyExport = NULL;
  4960. return ret;
  4961. }
  4962. kari->senderKeyInit = 1;
  4963. ret = wc_InitRng_ex(&rng, kari->heap, kari->devId);
  4964. if (ret != 0) {
  4965. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4966. kari->senderKeyExportSz = 0;
  4967. kari->senderKeyExport = NULL;
  4968. return ret;
  4969. }
  4970. ret = wc_ecc_make_key_ex(&rng, kari->recipKey->dp->size,
  4971. kari->senderKey, kari->recipKey->dp->id);
  4972. if (ret != 0) {
  4973. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4974. kari->senderKeyExportSz = 0;
  4975. kari->senderKeyExport = NULL;
  4976. wc_FreeRng(&rng);
  4977. return ret;
  4978. }
  4979. wc_FreeRng(&rng);
  4980. /* dump generated key to X.963 DER for output in CMS bundle */
  4981. PRIVATE_KEY_UNLOCK();
  4982. ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,
  4983. &kari->senderKeyExportSz);
  4984. PRIVATE_KEY_LOCK();
  4985. if (ret != 0) {
  4986. XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
  4987. kari->senderKeyExportSz = 0;
  4988. kari->senderKeyExport = NULL;
  4989. return ret;
  4990. }
  4991. return 0;
  4992. }
  4993. /* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,
  4994. * place in kari->sharedInfo. returns 0 on success, negative on error */
  4995. static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)
  4996. {
  4997. int idx = 0;
  4998. int sharedInfoSeqSz = 0;
  4999. int keyInfoSz = 0;
  5000. int suppPubInfoSeqSz = 0;
  5001. int entityUInfoOctetSz = 0;
  5002. int entityUInfoExplicitSz = 0;
  5003. int kekOctetSz = 0;
  5004. int sharedInfoSz = 0;
  5005. word32 kekBitSz = 0;
  5006. byte sharedInfoSeq[MAX_SEQ_SZ];
  5007. byte keyInfo[MAX_ALGO_SZ];
  5008. byte suppPubInfoSeq[MAX_SEQ_SZ];
  5009. byte entityUInfoOctet[MAX_OCTET_STR_SZ];
  5010. byte entityUInfoExplicitSeq[MAX_SEQ_SZ];
  5011. byte kekOctet[MAX_OCTET_STR_SZ];
  5012. if (kari == NULL)
  5013. return BAD_FUNC_ARG;
  5014. if ((kari->ukmSz > 0) && (kari->ukm == NULL))
  5015. return BAD_FUNC_ARG;
  5016. /* kekOctet */
  5017. kekOctetSz = SetOctetString(sizeof(word32), kekOctet);
  5018. sharedInfoSz += (kekOctetSz + sizeof(word32));
  5019. /* suppPubInfo */
  5020. suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,
  5021. kekOctetSz + sizeof(word32),
  5022. suppPubInfoSeq);
  5023. sharedInfoSz += suppPubInfoSeqSz;
  5024. /* optional ukm/entityInfo */
  5025. if (kari->ukmSz > 0) {
  5026. entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);
  5027. sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);
  5028. entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +
  5029. kari->ukmSz,
  5030. entityUInfoExplicitSeq);
  5031. sharedInfoSz += entityUInfoExplicitSz;
  5032. }
  5033. /* keyInfo */
  5034. keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);
  5035. sharedInfoSz += keyInfoSz;
  5036. /* sharedInfo */
  5037. sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);
  5038. sharedInfoSz += sharedInfoSeqSz;
  5039. kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,
  5040. DYNAMIC_TYPE_PKCS7);
  5041. if (kari->sharedInfo == NULL)
  5042. return MEMORY_E;
  5043. kari->sharedInfoSz = sharedInfoSz;
  5044. XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);
  5045. idx += sharedInfoSeqSz;
  5046. XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);
  5047. idx += keyInfoSz;
  5048. if (kari->ukmSz > 0) {
  5049. XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,
  5050. entityUInfoExplicitSz);
  5051. idx += entityUInfoExplicitSz;
  5052. XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);
  5053. idx += entityUInfoOctetSz;
  5054. XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);
  5055. idx += kari->ukmSz;
  5056. }
  5057. XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);
  5058. idx += suppPubInfoSeqSz;
  5059. XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);
  5060. idx += kekOctetSz;
  5061. kekBitSz = (kari->kekSz) * 8; /* convert to bits */
  5062. #ifdef LITTLE_ENDIAN_ORDER
  5063. kekBitSz = ByteReverseWord32(kekBitSz); /* network byte order */
  5064. #endif
  5065. XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));
  5066. return 0;
  5067. }
  5068. /* create key encryption key (KEK) using key wrap algorithm and key encryption
  5069. * algorithm, place in kari->kek. return 0 on success, <0 on error. */
  5070. static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng,
  5071. int keyWrapOID, int keyEncOID)
  5072. {
  5073. int ret;
  5074. int kSz;
  5075. enum wc_HashType kdfType;
  5076. byte* secret;
  5077. word32 secretSz;
  5078. if (kari == NULL || kari->recipKey == NULL ||
  5079. kari->senderKey == NULL || kari->senderKey->dp == NULL)
  5080. return BAD_FUNC_ARG;
  5081. /* get KEK size, allocate buff */
  5082. kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);
  5083. if (kSz < 0)
  5084. return kSz;
  5085. kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  5086. if (kari->kek == NULL)
  5087. return MEMORY_E;
  5088. kari->kekSz = (word32)kSz;
  5089. /* generate ECC-CMS-SharedInfo */
  5090. ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);
  5091. if (ret != 0)
  5092. return ret;
  5093. /* generate shared secret */
  5094. secretSz = kari->senderKey->dp->size;
  5095. secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);
  5096. if (secret == NULL)
  5097. return MEMORY_E;
  5098. #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
  5099. (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
  5100. !defined(HAVE_SELFTEST)
  5101. ret = wc_ecc_set_rng(kari->senderKey, rng);
  5102. if (ret != 0)
  5103. return ret;
  5104. ret = wc_ecc_set_rng(kari->recipKey, rng);
  5105. if (ret != 0)
  5106. return ret;
  5107. #else
  5108. (void)rng;
  5109. #endif
  5110. if (kari->direction == WC_PKCS7_ENCODE) {
  5111. PRIVATE_KEY_UNLOCK();
  5112. ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,
  5113. secret, &secretSz);
  5114. PRIVATE_KEY_LOCK();
  5115. } else if (kari->direction == WC_PKCS7_DECODE) {
  5116. PRIVATE_KEY_UNLOCK();
  5117. ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,
  5118. secret, &secretSz);
  5119. PRIVATE_KEY_LOCK();
  5120. } else {
  5121. /* bad direction */
  5122. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5123. return BAD_FUNC_ARG;
  5124. }
  5125. if (ret != 0) {
  5126. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5127. return ret;
  5128. }
  5129. /* run through KDF */
  5130. switch (keyEncOID) {
  5131. #ifndef NO_SHA
  5132. case dhSinglePass_stdDH_sha1kdf_scheme:
  5133. kdfType = WC_HASH_TYPE_SHA;
  5134. break;
  5135. #endif
  5136. #ifndef WOLFSSL_SHA224
  5137. case dhSinglePass_stdDH_sha224kdf_scheme:
  5138. kdfType = WC_HASH_TYPE_SHA224;
  5139. break;
  5140. #endif
  5141. #ifndef NO_SHA256
  5142. case dhSinglePass_stdDH_sha256kdf_scheme:
  5143. kdfType = WC_HASH_TYPE_SHA256;
  5144. break;
  5145. #endif
  5146. #ifdef WOLFSSL_SHA384
  5147. case dhSinglePass_stdDH_sha384kdf_scheme:
  5148. kdfType = WC_HASH_TYPE_SHA384;
  5149. break;
  5150. #endif
  5151. #ifdef WOLFSSL_SHA512
  5152. case dhSinglePass_stdDH_sha512kdf_scheme:
  5153. kdfType = WC_HASH_TYPE_SHA512;
  5154. break;
  5155. #endif
  5156. default:
  5157. WOLFSSL_MSG("Unsupported key agreement algorithm");
  5158. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5159. return BAD_FUNC_ARG;
  5160. };
  5161. ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,
  5162. kari->sharedInfoSz, kari->kek, kari->kekSz);
  5163. if (ret != 0) {
  5164. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5165. return ret;
  5166. }
  5167. XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
  5168. return 0;
  5169. }
  5170. /* Encode and add CMS EnvelopedData KARI (KeyAgreeRecipientInfo) RecipientInfo
  5171. * to CMS/PKCS#7 EnvelopedData structure.
  5172. *
  5173. * Returns 0 on success, negative upon error */
  5174. int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  5175. int keyWrapOID, int keyAgreeOID, byte* ukm,
  5176. word32 ukmSz, int options)
  5177. {
  5178. Pkcs7EncodedRecip* recip;
  5179. Pkcs7EncodedRecip* lastRecip = NULL;
  5180. WC_PKCS7_KARI* kari = NULL;
  5181. word32 idx = 0;
  5182. word32 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  5183. int ret = 0;
  5184. int keySz, direction = 0;
  5185. int blockKeySz = 0;
  5186. /* ASN.1 layout */
  5187. int totalSz = 0;
  5188. int kariSeqSz = 0;
  5189. byte kariSeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  5190. int verSz = 0;
  5191. byte ver[MAX_VERSION_SZ];
  5192. int origIdOrKeySeqSz = 0;
  5193. byte origIdOrKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  5194. int origPubKeySeqSz = 0;
  5195. byte origPubKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
  5196. int origAlgIdSz = 0;
  5197. byte origAlgId[MAX_ALGO_SZ];
  5198. int origPubKeyStrSz = 0;
  5199. byte origPubKeyStr[MAX_OCTET_STR_SZ];
  5200. /* optional user keying material */
  5201. int ukmOctetSz = 0;
  5202. byte ukmOctetStr[MAX_OCTET_STR_SZ];
  5203. int ukmExplicitSz = 0;
  5204. byte ukmExplicitSeq[MAX_SEQ_SZ];
  5205. int keyEncryptAlgoIdSz = 0;
  5206. byte keyEncryptAlgoId[MAX_ALGO_SZ];
  5207. int keyWrapAlgSz = 0;
  5208. byte keyWrapAlg[MAX_ALGO_SZ];
  5209. int recipEncKeysSeqSz = 0;
  5210. byte recipEncKeysSeq[MAX_SEQ_SZ];
  5211. int recipEncKeySeqSz = 0;
  5212. byte recipEncKeySeq[MAX_SEQ_SZ];
  5213. int recipKeyIdSeqSz = 0;
  5214. byte recipKeyIdSeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
  5215. int subjKeyIdOctetSz = 0;
  5216. byte subjKeyIdOctet[MAX_OCTET_STR_SZ];
  5217. int encryptedKeyOctetSz = 0;
  5218. byte encryptedKeyOctet[MAX_OCTET_STR_SZ];
  5219. #ifdef WOLFSSL_SMALL_STACK
  5220. byte* encryptedKey;
  5221. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  5222. DYNAMIC_TYPE_TMP_BUFFER);
  5223. if (encryptedKey == NULL) {
  5224. return MEMORY_E;
  5225. }
  5226. #else
  5227. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  5228. #endif
  5229. /* allocate and init memory for recipient */
  5230. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  5231. DYNAMIC_TYPE_PKCS7);
  5232. if (recip == NULL) {
  5233. #ifdef WOLFSSL_SMALL_STACK
  5234. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5235. #endif
  5236. return MEMORY_E;
  5237. }
  5238. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5239. /* get key size for content-encryption key based on algorithm */
  5240. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5241. if (blockKeySz < 0) {
  5242. #ifdef WOLFSSL_SMALL_STACK
  5243. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5244. #endif
  5245. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5246. return blockKeySz;
  5247. }
  5248. /* generate random content encryption key, if needed */
  5249. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5250. if (ret < 0) {
  5251. #ifdef WOLFSSL_SMALL_STACK
  5252. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5253. #endif
  5254. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5255. return ret;
  5256. }
  5257. /* set direction based on keyWrapAlgo */
  5258. switch (keyWrapOID) {
  5259. #ifndef NO_AES
  5260. #ifdef WOLFSSL_AES_128
  5261. case AES128_WRAP:
  5262. #endif
  5263. #ifdef WOLFSSL_AES_192
  5264. case AES192_WRAP:
  5265. #endif
  5266. #ifdef WOLFSSL_AES_256
  5267. case AES256_WRAP:
  5268. #endif
  5269. direction = AES_ENCRYPTION;
  5270. break;
  5271. #endif
  5272. default:
  5273. WOLFSSL_MSG("Unsupported key wrap algorithm");
  5274. #ifdef WOLFSSL_SMALL_STACK
  5275. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5276. #endif
  5277. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5278. return BAD_KEYWRAP_ALG_E;
  5279. }
  5280. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);
  5281. if (kari == NULL) {
  5282. #ifdef WOLFSSL_SMALL_STACK
  5283. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5284. #endif
  5285. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5286. return MEMORY_E;
  5287. }
  5288. /* set user keying material if available */
  5289. if (ukmSz > 0 && ukm != NULL) {
  5290. kari->ukm = ukm;
  5291. kari->ukmSz = ukmSz;
  5292. kari->ukmOwner = 0;
  5293. }
  5294. /* parse recipient cert, get public key */
  5295. ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);
  5296. if (ret != 0) {
  5297. wc_PKCS7_KariFree(kari);
  5298. #ifdef WOLFSSL_SMALL_STACK
  5299. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5300. #endif
  5301. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5302. return ret;
  5303. }
  5304. /* generate sender ephemeral ECC key */
  5305. ret = wc_PKCS7_KariGenerateEphemeralKey(kari);
  5306. if (ret != 0) {
  5307. wc_PKCS7_KariFree(kari);
  5308. #ifdef WOLFSSL_SMALL_STACK
  5309. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5310. #endif
  5311. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5312. return ret;
  5313. }
  5314. /* generate KEK (key encryption key) */
  5315. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID, keyAgreeOID);
  5316. if (ret != 0) {
  5317. wc_PKCS7_KariFree(kari);
  5318. #ifdef WOLFSSL_SMALL_STACK
  5319. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5320. #endif
  5321. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5322. return ret;
  5323. }
  5324. /* encrypt CEK with KEK */
  5325. keySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kari->kek,
  5326. kari->kekSz, encryptedKey, encryptedKeySz,
  5327. keyWrapOID, direction);
  5328. if (keySz <= 0) {
  5329. wc_PKCS7_KariFree(kari);
  5330. #ifdef WOLFSSL_SMALL_STACK
  5331. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5332. #endif
  5333. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5334. return keySz;
  5335. }
  5336. encryptedKeySz = (word32)keySz;
  5337. /* Start of RecipientEncryptedKeys */
  5338. /* EncryptedKey */
  5339. encryptedKeyOctetSz = SetOctetString(encryptedKeySz, encryptedKeyOctet);
  5340. totalSz += (encryptedKeyOctetSz + encryptedKeySz);
  5341. /* SubjectKeyIdentifier */
  5342. subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet);
  5343. totalSz += (subjKeyIdOctetSz + KEYID_SIZE);
  5344. /* RecipientKeyIdentifier IMPLICIT [0] */
  5345. recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +
  5346. KEYID_SIZE, recipKeyIdSeq);
  5347. totalSz += recipKeyIdSeqSz;
  5348. /* RecipientEncryptedKey */
  5349. recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);
  5350. totalSz += recipEncKeySeqSz;
  5351. /* RecipientEncryptedKeys */
  5352. recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);
  5353. totalSz += recipEncKeysSeqSz;
  5354. /* Start of optional UserKeyingMaterial */
  5355. if (kari->ukmSz > 0) {
  5356. ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);
  5357. totalSz += (ukmOctetSz + kari->ukmSz);
  5358. ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,
  5359. ukmExplicitSeq);
  5360. totalSz += ukmExplicitSz;
  5361. }
  5362. /* Start of KeyEncryptionAlgorithmIdentifier */
  5363. /* KeyWrapAlgorithm */
  5364. keyWrapAlgSz = SetAlgoID(keyWrapOID, keyWrapAlg, oidKeyWrapType, 0);
  5365. totalSz += keyWrapAlgSz;
  5366. /* KeyEncryptionAlgorithmIdentifier */
  5367. keyEncryptAlgoIdSz = SetAlgoID(keyAgreeOID, keyEncryptAlgoId,
  5368. oidCmsKeyAgreeType, keyWrapAlgSz);
  5369. totalSz += keyEncryptAlgoIdSz;
  5370. /* Start of OriginatorIdentifierOrKey */
  5371. /* recipient ECPoint, public key */
  5372. XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */
  5373. origPubKeyStr[0] = ASN_BIT_STRING;
  5374. origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,
  5375. origPubKeyStr + 1) + 2;
  5376. totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);
  5377. /* Originator AlgorithmIdentifier, params set to NULL for interop
  5378. compatibility */
  5379. origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 2);
  5380. origAlgId[origAlgIdSz++] = ASN_TAG_NULL;
  5381. origAlgId[origAlgIdSz++] = 0;
  5382. totalSz += origAlgIdSz;
  5383. /* outer OriginatorPublicKey IMPLICIT [1] */
  5384. origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,
  5385. origAlgIdSz + origPubKeyStrSz +
  5386. kari->senderKeyExportSz, origPubKeySeq);
  5387. totalSz += origPubKeySeqSz;
  5388. /* outer OriginatorIdentifierOrKey IMPLICIT [0] */
  5389. origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,
  5390. origPubKeySeqSz + origAlgIdSz +
  5391. origPubKeyStrSz + kari->senderKeyExportSz,
  5392. origIdOrKeySeq);
  5393. totalSz += origIdOrKeySeqSz;
  5394. /* version, always 3 */
  5395. verSz = SetMyVersion(3, ver, 0);
  5396. totalSz += verSz;
  5397. recip->recipVersion = 3;
  5398. /* outer IMPLICIT [1] kari */
  5399. kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);
  5400. totalSz += kariSeqSz;
  5401. if (totalSz > MAX_RECIP_SZ) {
  5402. WOLFSSL_MSG("KeyAgreeRecipientInfo output buffer too small");
  5403. wc_PKCS7_KariFree(kari);
  5404. #ifdef WOLFSSL_SMALL_STACK
  5405. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5406. #endif
  5407. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5408. return BUFFER_E;
  5409. }
  5410. XMEMCPY(recip->recip + idx, kariSeq, kariSeqSz);
  5411. idx += kariSeqSz;
  5412. XMEMCPY(recip->recip + idx, ver, verSz);
  5413. idx += verSz;
  5414. XMEMCPY(recip->recip + idx, origIdOrKeySeq, origIdOrKeySeqSz);
  5415. idx += origIdOrKeySeqSz;
  5416. XMEMCPY(recip->recip + idx, origPubKeySeq, origPubKeySeqSz);
  5417. idx += origPubKeySeqSz;
  5418. /* AlgorithmIdentifier with NULL parameter */
  5419. XMEMCPY(recip->recip + idx, origAlgId, origAlgIdSz);
  5420. idx += origAlgIdSz;
  5421. XMEMCPY(recip->recip + idx, origPubKeyStr, origPubKeyStrSz);
  5422. idx += origPubKeyStrSz;
  5423. /* ephemeral public key */
  5424. XMEMCPY(recip->recip + idx, kari->senderKeyExport, kari->senderKeyExportSz);
  5425. idx += kari->senderKeyExportSz;
  5426. if (kari->ukmSz > 0) {
  5427. XMEMCPY(recip->recip + idx, ukmExplicitSeq, ukmExplicitSz);
  5428. idx += ukmExplicitSz;
  5429. XMEMCPY(recip->recip + idx, ukmOctetStr, ukmOctetSz);
  5430. idx += ukmOctetSz;
  5431. XMEMCPY(recip->recip + idx, kari->ukm, kari->ukmSz);
  5432. idx += kari->ukmSz;
  5433. }
  5434. XMEMCPY(recip->recip + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);
  5435. idx += keyEncryptAlgoIdSz;
  5436. XMEMCPY(recip->recip + idx, keyWrapAlg, keyWrapAlgSz);
  5437. idx += keyWrapAlgSz;
  5438. XMEMCPY(recip->recip + idx, recipEncKeysSeq, recipEncKeysSeqSz);
  5439. idx += recipEncKeysSeqSz;
  5440. XMEMCPY(recip->recip + idx, recipEncKeySeq, recipEncKeySeqSz);
  5441. idx += recipEncKeySeqSz;
  5442. XMEMCPY(recip->recip + idx, recipKeyIdSeq, recipKeyIdSeqSz);
  5443. idx += recipKeyIdSeqSz;
  5444. XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz);
  5445. idx += subjKeyIdOctetSz;
  5446. /* subject key id */
  5447. XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, KEYID_SIZE);
  5448. idx += KEYID_SIZE;
  5449. XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz);
  5450. idx += encryptedKeyOctetSz;
  5451. /* encrypted CEK */
  5452. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5453. idx += encryptedKeySz;
  5454. wc_PKCS7_KariFree(kari);
  5455. #ifdef WOLFSSL_SMALL_STACK
  5456. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5457. #endif
  5458. /* store recipient size */
  5459. recip->recipSz = idx;
  5460. recip->recipType = PKCS7_KARI;
  5461. /* add recipient to recip list */
  5462. if (pkcs7->recipList == NULL) {
  5463. pkcs7->recipList = recip;
  5464. } else {
  5465. lastRecip = pkcs7->recipList;
  5466. while (lastRecip->next != NULL) {
  5467. lastRecip = lastRecip->next;
  5468. }
  5469. lastRecip->next = recip;
  5470. }
  5471. (void)options;
  5472. return idx;
  5473. }
  5474. #endif /* HAVE_ECC */
  5475. #ifndef NO_RSA
  5476. /* Encode and add CMS EnvelopedData KTRI (KeyTransRecipientInfo) RecipientInfo
  5477. * to CMS/PKCS#7 EnvelopedData structure.
  5478. *
  5479. * Returns 0 on success, negative upon error */
  5480. int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz,
  5481. int options)
  5482. {
  5483. Pkcs7EncodedRecip* recip = NULL;
  5484. Pkcs7EncodedRecip* lastRecip = NULL;
  5485. WC_RNG rng;
  5486. word32 idx = 0;
  5487. word32 encryptedKeySz = 0;
  5488. int ret = 0, blockKeySz;
  5489. int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0;
  5490. int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0;
  5491. int encKeyOctetStrSz;
  5492. int sidType;
  5493. byte ver[MAX_VERSION_SZ];
  5494. byte issuerSerialSeq[MAX_SEQ_SZ];
  5495. byte recipSeq[MAX_SEQ_SZ];
  5496. byte issuerSeq[MAX_SEQ_SZ];
  5497. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  5498. byte issuerSKID[MAX_LENGTH_SZ];
  5499. word32 issuerSKIDSz = 0;
  5500. byte* encryptedKey;
  5501. #ifdef WOLFSSL_SMALL_STACK
  5502. byte* serial;
  5503. byte* keyAlgArray;
  5504. RsaKey* pubKey;
  5505. DecodedCert* decoded;
  5506. serial = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5507. keyAlgArray = (byte*)XMALLOC(MAX_ALGO_SZ, pkcs7->heap,
  5508. DYNAMIC_TYPE_TMP_BUFFER);
  5509. decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
  5510. DYNAMIC_TYPE_TMP_BUFFER);
  5511. if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
  5512. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5513. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5514. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5515. return MEMORY_E;
  5516. }
  5517. #else
  5518. byte serial[MAX_SN_SZ];
  5519. byte keyAlgArray[MAX_ALGO_SZ];
  5520. RsaKey pubKey[1];
  5521. DecodedCert decoded[1];
  5522. #endif
  5523. /* Always allocate to ensure aligned use with RSA */
  5524. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  5525. DYNAMIC_TYPE_WOLF_BIGINT);
  5526. if (encryptedKey == NULL) {
  5527. #ifdef WOLFSSL_SMALL_STACK
  5528. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5529. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5530. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5531. #endif
  5532. return MEMORY_E;
  5533. }
  5534. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  5535. XMEMSET(encryptedKey, 0, encryptedKeySz);
  5536. /* default to IssuerAndSerialNumber if not set */
  5537. if (pkcs7->sidType != 0) {
  5538. sidType = pkcs7->sidType;
  5539. } else {
  5540. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5541. }
  5542. /* allow options to override SubjectIdentifier type if set */
  5543. if (options & CMS_SKID) {
  5544. sidType = CMS_SKID;
  5545. } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) {
  5546. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  5547. }
  5548. /* allocate recipient struct */
  5549. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  5550. DYNAMIC_TYPE_PKCS7);
  5551. if (recip == NULL) {
  5552. #ifdef WOLFSSL_SMALL_STACK
  5553. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5554. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5555. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5556. #endif
  5557. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5558. return MEMORY_E;
  5559. }
  5560. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  5561. /* get key size for content-encryption key based on algorithm */
  5562. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  5563. if (blockKeySz < 0) {
  5564. #ifdef WOLFSSL_SMALL_STACK
  5565. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5566. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5567. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5568. #endif
  5569. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5570. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5571. return blockKeySz;
  5572. }
  5573. /* generate random content encryption key, if needed */
  5574. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  5575. if (ret < 0) {
  5576. #ifdef WOLFSSL_SMALL_STACK
  5577. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5578. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5579. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5580. #endif
  5581. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5582. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5583. return ret;
  5584. }
  5585. InitDecodedCert(decoded, (byte*)cert, certSz, pkcs7->heap);
  5586. ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
  5587. if (ret < 0) {
  5588. FreeDecodedCert(decoded);
  5589. #ifdef WOLFSSL_SMALL_STACK
  5590. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5591. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5592. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5593. #endif
  5594. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5595. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5596. return ret;
  5597. }
  5598. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5599. /* version, must be 0 for IssuerAndSerialNumber */
  5600. verSz = SetMyVersion(0, ver, 0);
  5601. recip->recipVersion = 0;
  5602. /* IssuerAndSerialNumber */
  5603. if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
  5604. WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
  5605. FreeDecodedCert(decoded);
  5606. #ifdef WOLFSSL_SMALL_STACK
  5607. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5608. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5609. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5610. #endif
  5611. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5612. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5613. return -1;
  5614. }
  5615. issuerSz = decoded->issuerRawLen;
  5616. issuerSeqSz = SetSequence(issuerSz, issuerSeq);
  5617. if (decoded->serialSz == 0) {
  5618. WOLFSSL_MSG("DecodedCert missing serial number");
  5619. FreeDecodedCert(decoded);
  5620. #ifdef WOLFSSL_SMALL_STACK
  5621. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5622. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5623. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5624. #endif
  5625. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5626. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5627. return -1;
  5628. }
  5629. snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial,
  5630. MAX_SN_SZ, MAX_SN_SZ);
  5631. if (snSz < 0) {
  5632. WOLFSSL_MSG("Error setting the serial number");
  5633. FreeDecodedCert(decoded);
  5634. #ifdef WOLFSSL_SMALL_STACK
  5635. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5636. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5637. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5638. #endif
  5639. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5640. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5641. return -1;
  5642. }
  5643. issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
  5644. issuerSerialSeq);
  5645. } else if (sidType == CMS_SKID) {
  5646. /* version, must be 2 for SubjectKeyIdentifier */
  5647. verSz = SetMyVersion(2, ver, 0);
  5648. recip->recipVersion = 2;
  5649. issuerSKIDSz = SetLength(KEYID_SIZE, issuerSKID);
  5650. } else {
  5651. FreeDecodedCert(decoded);
  5652. #ifdef WOLFSSL_SMALL_STACK
  5653. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5654. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5655. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5656. #endif
  5657. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5658. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5659. return PKCS7_RECIP_E;
  5660. }
  5661. pkcs7->publicKeyOID = decoded->keyOID;
  5662. /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
  5663. if (pkcs7->publicKeyOID != RSAk) {
  5664. FreeDecodedCert(decoded);
  5665. #ifdef WOLFSSL_SMALL_STACK
  5666. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5667. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5668. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5669. #endif
  5670. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5671. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5672. return ALGO_ID_E;
  5673. }
  5674. keyEncAlgSz = SetAlgoID(pkcs7->publicKeyOID, keyAlgArray, oidKeyType, 0);
  5675. if (keyEncAlgSz == 0) {
  5676. FreeDecodedCert(decoded);
  5677. #ifdef WOLFSSL_SMALL_STACK
  5678. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5679. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5680. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5681. #endif
  5682. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5683. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5684. return BAD_FUNC_ARG;
  5685. }
  5686. #ifdef WOLFSSL_SMALL_STACK
  5687. pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  5688. DYNAMIC_TYPE_TMP_BUFFER);
  5689. if (pubKey == NULL) {
  5690. FreeDecodedCert(decoded);
  5691. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5692. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5693. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5694. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5695. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5696. return MEMORY_E;
  5697. }
  5698. #endif
  5699. /* EncryptedKey */
  5700. ret = wc_InitRsaKey_ex(pubKey, pkcs7->heap, pkcs7->devId);
  5701. if (ret != 0) {
  5702. FreeDecodedCert(decoded);
  5703. #ifdef WOLFSSL_SMALL_STACK
  5704. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5705. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5706. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5707. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5708. #endif
  5709. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5710. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5711. return ret;
  5712. }
  5713. if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
  5714. decoded->pubKeySize) < 0) {
  5715. WOLFSSL_MSG("ASN RSA key decode error");
  5716. wc_FreeRsaKey(pubKey);
  5717. FreeDecodedCert(decoded);
  5718. #ifdef WOLFSSL_SMALL_STACK
  5719. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5720. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5721. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5722. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5723. #endif
  5724. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5725. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5726. return PUBLIC_KEY_E;
  5727. }
  5728. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  5729. if (ret != 0) {
  5730. wc_FreeRsaKey(pubKey);
  5731. FreeDecodedCert(decoded);
  5732. #ifdef WOLFSSL_SMALL_STACK
  5733. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5734. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5735. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5736. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5737. #endif
  5738. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5739. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5740. return MEMORY_E;
  5741. }
  5742. #ifdef WOLFSSL_ASYNC_CRYPT
  5743. /* Currently the call to RSA public encrypt here is blocking @TODO */
  5744. do {
  5745. ret = wc_AsyncWait(ret, &pubKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
  5746. if (ret >= 0)
  5747. #endif
  5748. {
  5749. ret = wc_RsaPublicEncrypt(pkcs7->cek, pkcs7->cekSz, encryptedKey,
  5750. encryptedKeySz, pubKey, &rng);
  5751. }
  5752. #ifdef WOLFSSL_ASYNC_CRYPT
  5753. } while (ret == WC_PENDING_E);
  5754. #endif
  5755. wc_FreeRsaKey(pubKey);
  5756. wc_FreeRng(&rng);
  5757. #ifdef WOLFSSL_SMALL_STACK
  5758. XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5759. #endif
  5760. if (ret < 0) {
  5761. WOLFSSL_MSG("RSA Public Encrypt failed");
  5762. FreeDecodedCert(decoded);
  5763. #ifdef WOLFSSL_SMALL_STACK
  5764. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5765. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5766. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5767. #endif
  5768. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5769. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5770. return ret;
  5771. }
  5772. encryptedKeySz = ret;
  5773. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  5774. /* RecipientInfo */
  5775. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5776. recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
  5777. issuerSz + snSz + keyEncAlgSz +
  5778. encKeyOctetStrSz + encryptedKeySz, recipSeq);
  5779. if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
  5780. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5781. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5782. FreeDecodedCert(decoded);
  5783. #ifdef WOLFSSL_SMALL_STACK
  5784. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5785. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5786. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5787. #endif
  5788. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5789. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5790. return BUFFER_E;
  5791. }
  5792. } else {
  5793. recipSeqSz = SetSequence(verSz + ASN_TAG_SZ + issuerSKIDSz +
  5794. KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz +
  5795. encryptedKeySz, recipSeq);
  5796. if (recipSeqSz + verSz + ASN_TAG_SZ + issuerSKIDSz + KEYID_SIZE +
  5797. keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
  5798. WOLFSSL_MSG("RecipientInfo output buffer too small");
  5799. FreeDecodedCert(decoded);
  5800. #ifdef WOLFSSL_SMALL_STACK
  5801. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5802. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5803. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5804. #endif
  5805. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5806. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  5807. return BUFFER_E;
  5808. }
  5809. }
  5810. idx = 0;
  5811. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  5812. idx += recipSeqSz;
  5813. XMEMCPY(recip->recip + idx, ver, verSz);
  5814. idx += verSz;
  5815. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  5816. XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz);
  5817. idx += issuerSerialSeqSz;
  5818. XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz);
  5819. idx += issuerSeqSz;
  5820. XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz);
  5821. idx += issuerSz;
  5822. XMEMCPY(recip->recip + idx, serial, snSz);
  5823. idx += snSz;
  5824. } else {
  5825. recip->recip[idx] = ASN_CONTEXT_SPECIFIC;
  5826. idx += ASN_TAG_SZ;
  5827. XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz);
  5828. idx += issuerSKIDSz;
  5829. XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
  5830. idx += KEYID_SIZE;
  5831. }
  5832. XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz);
  5833. idx += keyEncAlgSz;
  5834. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  5835. idx += encKeyOctetStrSz;
  5836. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  5837. idx += encryptedKeySz;
  5838. FreeDecodedCert(decoded);
  5839. #ifdef WOLFSSL_SMALL_STACK
  5840. XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5841. XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5842. XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  5843. #endif
  5844. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  5845. /* store recipient size */
  5846. recip->recipSz = idx;
  5847. recip->recipType = PKCS7_KTRI;
  5848. /* add recipient to recip list */
  5849. if (pkcs7->recipList == NULL) {
  5850. pkcs7->recipList = recip;
  5851. } else {
  5852. lastRecip = pkcs7->recipList;
  5853. while (lastRecip->next != NULL) {
  5854. lastRecip = lastRecip->next;
  5855. }
  5856. lastRecip->next = recip;
  5857. }
  5858. return idx;
  5859. }
  5860. #endif /* !NO_RSA */
  5861. /* encrypt content using encryptOID algo */
  5862. static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
  5863. byte* iv, int ivSz, byte* aad, word32 aadSz,
  5864. byte* authTag, word32 authTagSz, byte* in,
  5865. int inSz, byte* out)
  5866. {
  5867. int ret;
  5868. #ifndef NO_AES
  5869. #ifdef WOLFSSL_SMALL_STACK
  5870. Aes* aes;
  5871. #else
  5872. Aes aes[1];
  5873. #endif
  5874. #endif
  5875. #ifndef NO_DES3
  5876. Des des;
  5877. Des3 des3;
  5878. #endif
  5879. if (key == NULL || iv == NULL || in == NULL || out == NULL)
  5880. return BAD_FUNC_ARG;
  5881. switch (encryptOID) {
  5882. #ifndef NO_AES
  5883. #ifdef HAVE_AES_CBC
  5884. #ifdef WOLFSSL_AES_128
  5885. case AES128CBCb:
  5886. #endif
  5887. #ifdef WOLFSSL_AES_192
  5888. case AES192CBCb:
  5889. #endif
  5890. #ifdef WOLFSSL_AES_256
  5891. case AES256CBCb:
  5892. #endif
  5893. if (
  5894. #ifdef WOLFSSL_AES_128
  5895. (encryptOID == AES128CBCb && keySz != 16 ) ||
  5896. #endif
  5897. #ifdef WOLFSSL_AES_192
  5898. (encryptOID == AES192CBCb && keySz != 24 ) ||
  5899. #endif
  5900. #ifdef WOLFSSL_AES_256
  5901. (encryptOID == AES256CBCb && keySz != 32 ) ||
  5902. #endif
  5903. (ivSz != AES_BLOCK_SIZE) )
  5904. return BAD_FUNC_ARG;
  5905. #ifdef WOLFSSL_SMALL_STACK
  5906. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  5907. DYNAMIC_TYPE_AES)) == NULL)
  5908. return MEMORY_E;
  5909. #endif
  5910. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  5911. if (ret == 0) {
  5912. ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
  5913. if (ret == 0)
  5914. ret = wc_AesCbcEncrypt(aes, out, in, inSz);
  5915. wc_AesFree(aes);
  5916. }
  5917. #ifdef WOLFSSL_SMALL_STACK
  5918. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  5919. #endif
  5920. break;
  5921. #endif /* HAVE_AES_CBC */
  5922. #ifdef HAVE_AESGCM
  5923. #ifdef WOLFSSL_AES_128
  5924. case AES128GCMb:
  5925. #endif
  5926. #ifdef WOLFSSL_AES_192
  5927. case AES192GCMb:
  5928. #endif
  5929. #ifdef WOLFSSL_AES_256
  5930. case AES256GCMb:
  5931. #endif
  5932. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5933. defined(WOLFSSL_AES_256)
  5934. if (authTag == NULL)
  5935. return BAD_FUNC_ARG;
  5936. #ifdef WOLFSSL_SMALL_STACK
  5937. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  5938. DYNAMIC_TYPE_AES)) == NULL)
  5939. return MEMORY_E;
  5940. #endif
  5941. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  5942. if (ret == 0) {
  5943. ret = wc_AesGcmSetKey(aes, key, keySz);
  5944. if (ret == 0)
  5945. ret = wc_AesGcmEncrypt(aes, out, in, inSz, iv, ivSz,
  5946. authTag, authTagSz, aad, aadSz);
  5947. wc_AesFree(aes);
  5948. }
  5949. #ifdef WOLFSSL_SMALL_STACK
  5950. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  5951. #endif
  5952. break;
  5953. #endif
  5954. #endif /* HAVE_AESGCM */
  5955. #ifdef HAVE_AESCCM
  5956. #ifdef WOLFSSL_AES_128
  5957. case AES128CCMb:
  5958. #endif
  5959. #ifdef WOLFSSL_AES_192
  5960. case AES192CCMb:
  5961. #endif
  5962. #ifdef WOLFSSL_AES_256
  5963. case AES256CCMb:
  5964. #endif
  5965. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  5966. defined(WOLFSSL_AES_256)
  5967. if (authTag == NULL)
  5968. return BAD_FUNC_ARG;
  5969. #ifdef WOLFSSL_SMALL_STACK
  5970. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  5971. DYNAMIC_TYPE_AES)) == NULL)
  5972. return MEMORY_E;
  5973. #endif
  5974. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  5975. if (ret == 0) {
  5976. ret = wc_AesCcmSetKey(aes, key, keySz);
  5977. if (ret == 0)
  5978. ret = wc_AesCcmEncrypt(aes, out, in, inSz, iv, ivSz,
  5979. authTag, authTagSz, aad, aadSz);
  5980. wc_AesFree(aes);
  5981. }
  5982. #ifdef WOLFSSL_SMALL_STACK
  5983. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  5984. #endif
  5985. break;
  5986. #endif
  5987. #endif /* HAVE_AESCCM */
  5988. #endif /* !NO_AES */
  5989. #ifndef NO_DES3
  5990. case DESb:
  5991. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5992. return BAD_FUNC_ARG;
  5993. ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
  5994. if (ret == 0)
  5995. ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
  5996. break;
  5997. case DES3b:
  5998. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  5999. return BAD_FUNC_ARG;
  6000. ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
  6001. if (ret == 0) {
  6002. ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
  6003. if (ret == 0)
  6004. ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
  6005. wc_Des3Free(&des3);
  6006. }
  6007. break;
  6008. #endif /* !NO_DES3 */
  6009. default:
  6010. WOLFSSL_MSG("Unsupported content cipher type");
  6011. return ALGO_ID_E;
  6012. };
  6013. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  6014. (void)authTag;
  6015. (void)authTagSz;
  6016. (void)aad;
  6017. (void)aadSz;
  6018. #endif
  6019. return ret;
  6020. }
  6021. /* decrypt content using encryptOID algo
  6022. * returns 0 on success */
  6023. static int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,
  6024. int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,
  6025. word32 authTagSz, byte* in, int inSz, byte* out)
  6026. {
  6027. int ret;
  6028. #ifndef NO_AES
  6029. #ifdef WOLFSSL_SMALL_STACK
  6030. Aes *aes;
  6031. #else
  6032. Aes aes[1];
  6033. #endif
  6034. #endif
  6035. #ifndef NO_DES3
  6036. Des des;
  6037. Des3 des3;
  6038. #endif
  6039. if (iv == NULL || in == NULL || out == NULL)
  6040. return BAD_FUNC_ARG;
  6041. if (pkcs7->decryptionCb != NULL) {
  6042. return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,
  6043. aad, aadSz, authTag, authTagSz, in,
  6044. inSz, out, pkcs7->decryptionCtx);
  6045. }
  6046. if (key == NULL)
  6047. return BAD_FUNC_ARG;
  6048. switch (encryptOID) {
  6049. #ifndef NO_AES
  6050. #ifdef HAVE_AES_CBC
  6051. #ifdef WOLFSSL_AES_128
  6052. case AES128CBCb:
  6053. #endif
  6054. #ifdef WOLFSSL_AES_192
  6055. case AES192CBCb:
  6056. #endif
  6057. #ifdef WOLFSSL_AES_256
  6058. case AES256CBCb:
  6059. #endif
  6060. if (
  6061. #ifdef WOLFSSL_AES_128
  6062. (encryptOID == AES128CBCb && keySz != 16 ) ||
  6063. #endif
  6064. #ifdef WOLFSSL_AES_192
  6065. (encryptOID == AES192CBCb && keySz != 24 ) ||
  6066. #endif
  6067. #ifdef WOLFSSL_AES_256
  6068. (encryptOID == AES256CBCb && keySz != 32 ) ||
  6069. #endif
  6070. (ivSz != AES_BLOCK_SIZE) )
  6071. return BAD_FUNC_ARG;
  6072. #ifdef WOLFSSL_SMALL_STACK
  6073. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6074. DYNAMIC_TYPE_AES)) == NULL)
  6075. return MEMORY_E;
  6076. #endif
  6077. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  6078. if (ret == 0) {
  6079. ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
  6080. if (ret == 0)
  6081. ret = wc_AesCbcDecrypt(aes, out, in, inSz);
  6082. wc_AesFree(aes);
  6083. }
  6084. #ifdef WOLFSSL_SMALL_STACK
  6085. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6086. #endif
  6087. break;
  6088. #endif /* HAVE_AES_CBC */
  6089. #ifdef HAVE_AESGCM
  6090. #ifdef WOLFSSL_AES_128
  6091. case AES128GCMb:
  6092. #endif
  6093. #ifdef WOLFSSL_AES_192
  6094. case AES192GCMb:
  6095. #endif
  6096. #ifdef WOLFSSL_AES_256
  6097. case AES256GCMb:
  6098. #endif
  6099. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6100. defined(WOLFSSL_AES_256)
  6101. if (authTag == NULL)
  6102. return BAD_FUNC_ARG;
  6103. #ifdef WOLFSSL_SMALL_STACK
  6104. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6105. DYNAMIC_TYPE_AES)) == NULL)
  6106. return MEMORY_E;
  6107. #endif
  6108. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  6109. if (ret == 0) {
  6110. ret = wc_AesGcmSetKey(aes, key, keySz);
  6111. if (ret == 0)
  6112. ret = wc_AesGcmDecrypt(aes, out, in, inSz, iv, ivSz,
  6113. authTag, authTagSz, aad, aadSz);
  6114. wc_AesFree(aes);
  6115. }
  6116. #ifdef WOLFSSL_SMALL_STACK
  6117. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6118. #endif
  6119. break;
  6120. #endif
  6121. #endif /* HAVE_AESGCM */
  6122. #ifdef HAVE_AESCCM
  6123. #ifdef WOLFSSL_AES_128
  6124. case AES128CCMb:
  6125. #endif
  6126. #ifdef WOLFSSL_AES_192
  6127. case AES192CCMb:
  6128. #endif
  6129. #ifdef WOLFSSL_AES_256
  6130. case AES256CCMb:
  6131. #endif
  6132. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  6133. defined(WOLFSSL_AES_256)
  6134. if (authTag == NULL)
  6135. return BAD_FUNC_ARG;
  6136. #ifdef WOLFSSL_SMALL_STACK
  6137. if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
  6138. DYNAMIC_TYPE_AES)) == NULL)
  6139. return MEMORY_E;
  6140. #endif
  6141. ret = wc_AesInit(aes, NULL, INVALID_DEVID);
  6142. if (ret == 0) {
  6143. ret = wc_AesCcmSetKey(aes, key, keySz);
  6144. if (ret == 0)
  6145. ret = wc_AesCcmDecrypt(aes, out, in, inSz, iv, ivSz,
  6146. authTag, authTagSz, aad, aadSz);
  6147. wc_AesFree(aes);
  6148. }
  6149. #ifdef WOLFSSL_SMALL_STACK
  6150. XFREE(aes, NULL, DYNAMIC_TYPE_AES);
  6151. #endif
  6152. break;
  6153. #endif
  6154. #endif /* HAVE_AESCCM */
  6155. #endif /* !NO_AES */
  6156. #ifndef NO_DES3
  6157. case DESb:
  6158. if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6159. return BAD_FUNC_ARG;
  6160. ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
  6161. if (ret == 0)
  6162. ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
  6163. break;
  6164. case DES3b:
  6165. if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
  6166. return BAD_FUNC_ARG;
  6167. ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
  6168. if (ret == 0) {
  6169. ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
  6170. if (ret == 0)
  6171. ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
  6172. wc_Des3Free(&des3);
  6173. }
  6174. break;
  6175. #endif /* !NO_DES3 */
  6176. default:
  6177. WOLFSSL_MSG("Unsupported content cipher type");
  6178. return ALGO_ID_E;
  6179. };
  6180. #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
  6181. (void)authTag;
  6182. (void)authTagSz;
  6183. (void)aad;
  6184. (void)aadSz;
  6185. #endif
  6186. return ret;
  6187. }
  6188. /* Generate random block, place in out, return 0 on success negative on error.
  6189. * Used for generation of IV, nonce, etc */
  6190. static int wc_PKCS7_GenerateBlock(PKCS7* pkcs7, WC_RNG* rng, byte* out,
  6191. word32 outSz)
  6192. {
  6193. int ret;
  6194. WC_RNG* rnd = NULL;
  6195. if (out == NULL || outSz == 0)
  6196. return BAD_FUNC_ARG;
  6197. /* input RNG is optional, init local one if input rng is NULL */
  6198. if (rng == NULL) {
  6199. rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);
  6200. if (rnd == NULL)
  6201. return MEMORY_E;
  6202. ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);
  6203. if (ret != 0) {
  6204. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  6205. return ret;
  6206. }
  6207. } else {
  6208. rnd = rng;
  6209. }
  6210. ret = wc_RNG_GenerateBlock(rnd, out, outSz);
  6211. if (rng == NULL) {
  6212. wc_FreeRng(rnd);
  6213. XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
  6214. }
  6215. return ret;
  6216. }
  6217. /* Set default SignerIdentifier type to be used. Is either
  6218. * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using
  6219. * IssuerAndSerialNumber unless set with this function or explicitly
  6220. * overridden via options when adding RecipientInfo type.
  6221. *
  6222. * Using the type DEGENERATE_SID skips over signer information. In degenerate
  6223. * cases there are no signers.
  6224. *
  6225. * pkcs7 - pointer to initialized PKCS7 structure
  6226. * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID
  6227. *
  6228. * return 0 on success, negative upon error */
  6229. int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type)
  6230. {
  6231. if (pkcs7 == NULL)
  6232. return BAD_FUNC_ARG;
  6233. if (type != CMS_ISSUER_AND_SERIAL_NUMBER &&
  6234. type != CMS_SKID &&
  6235. type != DEGENERATE_SID) {
  6236. return BAD_FUNC_ARG;
  6237. }
  6238. pkcs7->sidType = type;
  6239. return 0;
  6240. }
  6241. /* Set custom contentType, currently supported with SignedData type
  6242. *
  6243. * pkcs7 - pointer to initialized PKCS7 structure
  6244. * contentType - pointer to array with ASN.1 encoded OID value
  6245. * sz - length of contentType array, octets
  6246. *
  6247. * return 0 on success, negative upon error */
  6248. int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, word32 sz)
  6249. {
  6250. if (pkcs7 == NULL || contentType == NULL || sz == 0)
  6251. return BAD_FUNC_ARG;
  6252. if (sz > MAX_OID_SZ) {
  6253. WOLFSSL_MSG("input array too large, bounded by MAX_OID_SZ");
  6254. return BAD_FUNC_ARG;
  6255. }
  6256. XMEMCPY(pkcs7->contentType, contentType, sz);
  6257. pkcs7->contentTypeSz = sz;
  6258. return 0;
  6259. }
  6260. /* return size of padded data, padded to blockSz chunks, or negative on error */
  6261. int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
  6262. {
  6263. int padSz;
  6264. if (blockSz == 0)
  6265. return BAD_FUNC_ARG;
  6266. padSz = blockSz - (inputSz % blockSz);
  6267. return padSz;
  6268. }
  6269. /* pad input data to blockSz chunk, place in outSz. out must be big enough
  6270. * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */
  6271. int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
  6272. word32 blockSz)
  6273. {
  6274. int i, padSz;
  6275. if (in == NULL || inSz == 0 ||
  6276. out == NULL || outSz == 0)
  6277. return BAD_FUNC_ARG;
  6278. padSz = wc_PKCS7_GetPadSize(inSz, blockSz);
  6279. if (outSz < (inSz + padSz))
  6280. return BAD_FUNC_ARG;
  6281. XMEMCPY(out, in, inSz);
  6282. for (i = 0; i < padSz; i++) {
  6283. out[inSz + i] = (byte)padSz;
  6284. }
  6285. return inSz + padSz;
  6286. }
  6287. /* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo
  6288. * to CMS/PKCS#7 EnvelopedData structure.
  6289. *
  6290. * Return 0 on success, negative upon error */
  6291. int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb,
  6292. int options)
  6293. {
  6294. int oriTypeLenSz, blockKeySz, ret;
  6295. word32 idx, recipSeqSz;
  6296. Pkcs7EncodedRecip* recip = NULL;
  6297. Pkcs7EncodedRecip* lastRecip = NULL;
  6298. byte recipSeq[MAX_SEQ_SZ];
  6299. byte oriTypeLen[MAX_LENGTH_SZ];
  6300. byte oriType[MAX_ORI_TYPE_SZ];
  6301. byte oriValue[MAX_ORI_VALUE_SZ];
  6302. word32 oriTypeSz = MAX_ORI_TYPE_SZ;
  6303. word32 oriValueSz = MAX_ORI_VALUE_SZ;
  6304. if (pkcs7 == NULL || oriEncryptCb == NULL) {
  6305. return BAD_FUNC_ARG;
  6306. }
  6307. /* allocate memory for RecipientInfo, KEK, encrypted key */
  6308. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  6309. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6310. if (recip == NULL)
  6311. return MEMORY_E;
  6312. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6313. /* get key size for content-encryption key based on algorithm */
  6314. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6315. if (blockKeySz < 0) {
  6316. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6317. return blockKeySz;
  6318. }
  6319. /* generate random content encryption key, if needed */
  6320. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  6321. if (ret < 0) {
  6322. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6323. return ret;
  6324. }
  6325. /* call user callback to encrypt CEK and get oriType and oriValue
  6326. values back */
  6327. ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz,
  6328. oriValue, &oriValueSz, pkcs7->oriEncryptCtx);
  6329. if (ret != 0) {
  6330. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6331. return ret;
  6332. }
  6333. oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen);
  6334. recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz +
  6335. oriValueSz, recipSeq);
  6336. idx = 0;
  6337. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6338. idx += recipSeqSz;
  6339. /* oriType */
  6340. recip->recip[idx] = ASN_OBJECT_ID;
  6341. idx += 1;
  6342. XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz);
  6343. idx += oriTypeLenSz;
  6344. XMEMCPY(recip->recip + idx, oriType, oriTypeSz);
  6345. idx += oriTypeSz;
  6346. /* oriValue, input MUST already be ASN.1 encoded */
  6347. XMEMCPY(recip->recip + idx, oriValue, oriValueSz);
  6348. idx += oriValueSz;
  6349. /* store recipient size */
  6350. recip->recipSz = idx;
  6351. recip->recipType = PKCS7_ORI;
  6352. recip->recipVersion = 4;
  6353. /* add recipient to recip list */
  6354. if (pkcs7->recipList == NULL) {
  6355. pkcs7->recipList = recip;
  6356. } else {
  6357. lastRecip = pkcs7->recipList;
  6358. while (lastRecip->next != NULL) {
  6359. lastRecip = lastRecip->next;
  6360. }
  6361. lastRecip->next = recip;
  6362. }
  6363. (void)options;
  6364. return idx;
  6365. }
  6366. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  6367. static int wc_PKCS7_GenerateKEK_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  6368. byte* salt, word32 saltSz, int kdfOID,
  6369. int prfOID, int iterations, byte* out,
  6370. word32 outSz)
  6371. {
  6372. int ret;
  6373. if (pkcs7 == NULL || passwd == NULL || salt == NULL || out == NULL)
  6374. return BAD_FUNC_ARG;
  6375. switch (kdfOID) {
  6376. case PBKDF2_OID:
  6377. ret = wc_PBKDF2(out, passwd, pLen, salt, saltSz, iterations,
  6378. outSz, prfOID);
  6379. if (ret != 0) {
  6380. return ret;
  6381. }
  6382. break;
  6383. default:
  6384. WOLFSSL_MSG("Unsupported KDF OID");
  6385. return PKCS7_OID_E;
  6386. }
  6387. return 0;
  6388. }
  6389. /* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK).
  6390. *
  6391. * Returns output size on success, negative upon error */
  6392. static int wc_PKCS7_PwriKek_KeyWrap(PKCS7* pkcs7, const byte* kek, word32 kekSz,
  6393. const byte* cek, word32 cekSz,
  6394. byte* out, word32 *outSz,
  6395. const byte* iv, word32 ivSz, int algID)
  6396. {
  6397. WC_RNG rng;
  6398. int blockSz, outLen, ret;
  6399. word32 padSz;
  6400. byte* lastBlock;
  6401. if (kek == NULL || cek == NULL || iv == NULL || outSz == NULL)
  6402. return BAD_FUNC_ARG;
  6403. /* get encryption algorithm block size */
  6404. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  6405. if (blockSz <= 0) {
  6406. if (blockSz < 0)
  6407. return blockSz;
  6408. else
  6409. return ALGO_ID_E;
  6410. }
  6411. /* get pad bytes needed to block boundary */
  6412. padSz = blockSz - ((4 + cekSz) % blockSz);
  6413. outLen = 4 + cekSz + padSz;
  6414. /* must be at least two blocks long */
  6415. if (outLen < 2 * blockSz)
  6416. padSz += blockSz;
  6417. /* if user set out to NULL, give back required length */
  6418. if (out == NULL) {
  6419. *outSz = outLen;
  6420. return LENGTH_ONLY_E;
  6421. }
  6422. /* verify output buffer is large enough */
  6423. if (*outSz < (word32)outLen)
  6424. return BUFFER_E;
  6425. out[0] = cekSz;
  6426. out[1] = ~cek[0];
  6427. out[2] = ~cek[1];
  6428. out[3] = ~cek[2];
  6429. XMEMCPY(out + 4, cek, cekSz);
  6430. /* random padding of size padSz */
  6431. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  6432. if (ret != 0)
  6433. return ret;
  6434. ret = wc_RNG_GenerateBlock(&rng, out + 4 + cekSz, padSz);
  6435. if (ret == 0) {
  6436. /* encrypt, normal */
  6437. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, (byte*)iv,
  6438. ivSz, NULL, 0, NULL, 0, out, outLen, out);
  6439. }
  6440. if (ret == 0) {
  6441. /* encrypt again, using last ciphertext block as IV */
  6442. lastBlock = out + (((outLen / blockSz) - 1) * blockSz);
  6443. ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, lastBlock,
  6444. blockSz, NULL, 0, NULL, 0, out,
  6445. outLen, out);
  6446. }
  6447. if (ret == 0) {
  6448. *outSz = outLen;
  6449. } else {
  6450. outLen = ret;
  6451. }
  6452. wc_FreeRng(&rng);
  6453. return outLen;
  6454. }
  6455. /* RFC3211 (Section 2.3.2) key unwrap algorithm (id-alg-PWRI-KEK).
  6456. *
  6457. * Returns cek size on success, negative upon error */
  6458. static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,
  6459. word32 kekSz, const byte* in, word32 inSz,
  6460. byte* out, word32 outSz, const byte* iv,
  6461. word32 ivSz, int algID)
  6462. {
  6463. int blockSz, cekLen, ret;
  6464. byte* tmpIv = NULL;
  6465. byte* lastBlock = NULL;
  6466. byte* outTmp = NULL;
  6467. if (pkcs7 == NULL || kek == NULL || in == NULL ||
  6468. out == NULL || iv == NULL) {
  6469. return BAD_FUNC_ARG;
  6470. }
  6471. outTmp = (byte*)XMALLOC(inSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6472. if (outTmp == NULL)
  6473. return MEMORY_E;
  6474. /* get encryption algorithm block size */
  6475. blockSz = wc_PKCS7_GetOIDBlockSize(algID);
  6476. if (blockSz <= 0) {
  6477. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6478. if (blockSz < 0)
  6479. return blockSz;
  6480. else
  6481. return ALGO_ID_E;
  6482. }
  6483. /* input needs to be blockSz multiple and at least 2 * blockSz */
  6484. if (((inSz % blockSz) != 0) || (inSz < (2 * (word32)blockSz))) {
  6485. WOLFSSL_MSG("PWRI-KEK unwrap input must of block size and >= 2 "
  6486. "times block size");
  6487. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6488. return BAD_FUNC_ARG;
  6489. }
  6490. /* use block out[n-1] as IV to decrypt block out[n] */
  6491. lastBlock = (byte*)in + inSz - blockSz;
  6492. tmpIv = lastBlock - blockSz;
  6493. /* decrypt last block */
  6494. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,
  6495. blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,
  6496. outTmp + inSz - blockSz);
  6497. if (ret == 0) {
  6498. /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
  6499. lastBlock = outTmp + inSz - blockSz;
  6500. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6501. lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,
  6502. outTmp);
  6503. }
  6504. if (ret == 0) {
  6505. /* decrypt using original kek and iv */
  6506. ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
  6507. (byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp);
  6508. }
  6509. if (ret != 0) {
  6510. ForceZero(outTmp, inSz);
  6511. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6512. return ret;
  6513. }
  6514. cekLen = outTmp[0];
  6515. /* verify length */
  6516. if ((word32)cekLen > inSz) {
  6517. ForceZero(outTmp, inSz);
  6518. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6519. return BAD_FUNC_ARG;
  6520. }
  6521. /* verify check bytes */
  6522. if ((outTmp[1] ^ outTmp[4]) != 0xFF ||
  6523. (outTmp[2] ^ outTmp[5]) != 0xFF ||
  6524. (outTmp[3] ^ outTmp[6]) != 0xFF) {
  6525. ForceZero(outTmp, inSz);
  6526. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6527. return BAD_FUNC_ARG;
  6528. }
  6529. if (outSz < (word32)cekLen) {
  6530. ForceZero(outTmp, inSz);
  6531. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6532. return BUFFER_E;
  6533. }
  6534. XMEMCPY(out, outTmp + 4, outTmp[0]);
  6535. ForceZero(outTmp, inSz);
  6536. XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  6537. return cekLen;
  6538. }
  6539. /* Encode and add CMS EnvelopedData PWRI (PasswordRecipientInfo) RecipientInfo
  6540. * to CMS/PKCS#7 EnvelopedData structure.
  6541. *
  6542. * Return 0 on success, negative upon error */
  6543. int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
  6544. byte* salt, word32 saltSz, int kdfOID,
  6545. int hashOID, int iterations, int kekEncryptOID,
  6546. int options)
  6547. {
  6548. Pkcs7EncodedRecip* recip = NULL;
  6549. Pkcs7EncodedRecip* lastRecip = NULL;
  6550. /* PasswordRecipientInfo */
  6551. byte recipSeq[MAX_SEQ_SZ];
  6552. byte ver[MAX_VERSION_SZ];
  6553. word32 recipSeqSz, verSz;
  6554. /* KeyDerivationAlgorithmIdentifier */
  6555. byte kdfAlgoIdSeq[MAX_SEQ_SZ];
  6556. byte kdfAlgoId[MAX_OID_SZ];
  6557. byte kdfParamsSeq[MAX_SEQ_SZ]; /* PBKDF2-params */
  6558. byte kdfSaltOctetStr[MAX_OCTET_STR_SZ]; /* salt OCTET STRING */
  6559. byte kdfIterations[MAX_VERSION_SZ];
  6560. word32 kdfAlgoIdSeqSz, kdfAlgoIdSz;
  6561. word32 kdfParamsSeqSz, kdfSaltOctetStrSz, kdfIterationsSz;
  6562. /* OPTIONAL: keyLength, not supported yet */
  6563. /* OPTIONAL: prf AlgorithmIdentifier, not supported yet */
  6564. /* KeyEncryptionAlgorithmIdentifier */
  6565. byte keyEncAlgoIdSeq[MAX_SEQ_SZ];
  6566. byte keyEncAlgoId[MAX_OID_SZ]; /* id-alg-PWRI-KEK */
  6567. byte pwriEncAlgoId[MAX_ALGO_SZ];
  6568. byte ivOctetString[MAX_OCTET_STR_SZ];
  6569. word32 keyEncAlgoIdSeqSz, keyEncAlgoIdSz;
  6570. word32 pwriEncAlgoIdSz, ivOctetStringSz;
  6571. /* EncryptedKey */
  6572. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6573. word32 encKeyOctetStrSz;
  6574. byte tmpIv[MAX_CONTENT_IV_SIZE];
  6575. byte* encryptedKey = NULL;
  6576. byte* kek = NULL;
  6577. int cekKeySz = 0, kekKeySz = 0, kekBlockSz = 0, ret = 0;
  6578. int encryptOID;
  6579. word32 idx, totalSz = 0, encryptedKeySz;
  6580. if (pkcs7 == NULL || passwd == NULL || pLen == 0 ||
  6581. salt == NULL || saltSz == 0) {
  6582. return BAD_FUNC_ARG;
  6583. }
  6584. /* allow user to use different KEK encryption algorithm than used for
  6585. * main content encryption algorithm, if passed in */
  6586. if (kekEncryptOID != 0) {
  6587. encryptOID = kekEncryptOID;
  6588. } else {
  6589. encryptOID = pkcs7->encryptOID;
  6590. }
  6591. /* get content-encryption key size, based on algorithm */
  6592. cekKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6593. if (cekKeySz < 0)
  6594. return cekKeySz;
  6595. /* get KEK encryption key size, based on algorithm */
  6596. if (encryptOID != pkcs7->encryptOID) {
  6597. kekKeySz = wc_PKCS7_GetOIDKeySize(encryptOID);
  6598. } else {
  6599. kekKeySz = cekKeySz;
  6600. }
  6601. /* get KEK encryption block size */
  6602. kekBlockSz = wc_PKCS7_GetOIDBlockSize(encryptOID);
  6603. if (kekBlockSz < 0)
  6604. return kekBlockSz;
  6605. /* generate random CEK */
  6606. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, cekKeySz);
  6607. if (ret < 0)
  6608. return ret;
  6609. /* generate random IV */
  6610. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, kekBlockSz);
  6611. if (ret != 0)
  6612. return ret;
  6613. /* allocate memory for RecipientInfo, KEK, encrypted key */
  6614. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
  6615. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6616. if (recip == NULL)
  6617. return MEMORY_E;
  6618. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6619. if (kek == NULL) {
  6620. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6621. return MEMORY_E;
  6622. }
  6623. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ,
  6624. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6625. if (encryptedKey == NULL) {
  6626. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6627. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6628. return MEMORY_E;
  6629. }
  6630. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  6631. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6632. XMEMSET(kek, 0, kekKeySz);
  6633. XMEMSET(encryptedKey, 0, encryptedKeySz);
  6634. /* generate KEK: expand password into KEK */
  6635. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, passwd, pLen, salt, saltSz,
  6636. kdfOID, hashOID, iterations, kek,
  6637. kekKeySz);
  6638. if (ret < 0) {
  6639. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6640. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6641. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6642. return ret;
  6643. }
  6644. /* generate encrypted key: encrypt CEK with KEK */
  6645. ret = wc_PKCS7_PwriKek_KeyWrap(pkcs7, kek, kekKeySz, pkcs7->cek,
  6646. pkcs7->cekSz, encryptedKey, &encryptedKeySz,
  6647. tmpIv, kekBlockSz, encryptOID);
  6648. if (ret < 0) {
  6649. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6650. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6651. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6652. return ret;
  6653. }
  6654. encryptedKeySz = ret;
  6655. /* put together encrypted key OCTET STRING */
  6656. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  6657. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  6658. /* put together IV OCTET STRING */
  6659. ivOctetStringSz = SetOctetString(kekBlockSz, ivOctetString);
  6660. totalSz += (ivOctetStringSz + kekBlockSz);
  6661. /* set PWRIAlgorithms AlgorithmIdentifier, adding (ivOctetStringSz +
  6662. blockKeySz) for IV OCTET STRING */
  6663. pwriEncAlgoIdSz = SetAlgoID(encryptOID, pwriEncAlgoId,
  6664. oidBlkType, ivOctetStringSz + kekBlockSz);
  6665. totalSz += pwriEncAlgoIdSz;
  6666. /* set KeyEncryptionAlgorithms OID */
  6667. ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId));
  6668. if (ret <= 0) {
  6669. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6670. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6671. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6672. return ret;
  6673. }
  6674. keyEncAlgoIdSz = ret;
  6675. totalSz += keyEncAlgoIdSz;
  6676. /* KeyEncryptionAlgorithm SEQ */
  6677. keyEncAlgoIdSeqSz = SetSequence(keyEncAlgoIdSz + pwriEncAlgoIdSz +
  6678. ivOctetStringSz + kekBlockSz,
  6679. keyEncAlgoIdSeq);
  6680. totalSz += keyEncAlgoIdSeqSz;
  6681. /* set KDF salt */
  6682. kdfSaltOctetStrSz = SetOctetString(saltSz, kdfSaltOctetStr);
  6683. totalSz += (kdfSaltOctetStrSz + saltSz);
  6684. /* set KDF iteration count */
  6685. kdfIterationsSz = SetMyVersion(iterations, kdfIterations, 0);
  6686. totalSz += kdfIterationsSz;
  6687. /* set KDF params SEQ */
  6688. kdfParamsSeqSz = SetSequence(kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6689. kdfParamsSeq);
  6690. totalSz += kdfParamsSeqSz;
  6691. /* set KDF algo OID */
  6692. ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId));
  6693. if (ret <= 0) {
  6694. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6695. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6696. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6697. return ret;
  6698. }
  6699. kdfAlgoIdSz = ret;
  6700. totalSz += kdfAlgoIdSz;
  6701. /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */
  6702. kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz +
  6703. kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
  6704. kdfAlgoIdSeq);
  6705. totalSz += kdfAlgoIdSeqSz;
  6706. /* set PasswordRecipientInfo CMSVersion, MUST be 0 */
  6707. verSz = SetMyVersion(0, ver, 0);
  6708. totalSz += verSz;
  6709. recip->recipVersion = 0;
  6710. /* set PasswordRecipientInfo SEQ */
  6711. recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq);
  6712. totalSz += recipSeqSz;
  6713. if (totalSz > MAX_RECIP_SZ) {
  6714. WOLFSSL_MSG("CMS Recipient output buffer too small");
  6715. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6716. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6717. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6718. return BUFFER_E;
  6719. }
  6720. idx = 0;
  6721. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6722. idx += recipSeqSz;
  6723. XMEMCPY(recip->recip + idx, ver, verSz);
  6724. idx += verSz;
  6725. XMEMCPY(recip->recip + idx, kdfAlgoIdSeq, kdfAlgoIdSeqSz);
  6726. idx += kdfAlgoIdSeqSz;
  6727. XMEMCPY(recip->recip + idx, kdfAlgoId, kdfAlgoIdSz);
  6728. idx += kdfAlgoIdSz;
  6729. XMEMCPY(recip->recip + idx, kdfParamsSeq, kdfParamsSeqSz);
  6730. idx += kdfParamsSeqSz;
  6731. XMEMCPY(recip->recip + idx, kdfSaltOctetStr, kdfSaltOctetStrSz);
  6732. idx += kdfSaltOctetStrSz;
  6733. XMEMCPY(recip->recip + idx, salt, saltSz);
  6734. idx += saltSz;
  6735. XMEMCPY(recip->recip + idx, kdfIterations, kdfIterationsSz);
  6736. idx += kdfIterationsSz;
  6737. XMEMCPY(recip->recip + idx, keyEncAlgoIdSeq, keyEncAlgoIdSeqSz);
  6738. idx += keyEncAlgoIdSeqSz;
  6739. XMEMCPY(recip->recip + idx, keyEncAlgoId, keyEncAlgoIdSz);
  6740. idx += keyEncAlgoIdSz;
  6741. XMEMCPY(recip->recip + idx, pwriEncAlgoId, pwriEncAlgoIdSz);
  6742. idx += pwriEncAlgoIdSz;
  6743. XMEMCPY(recip->recip + idx, ivOctetString, ivOctetStringSz);
  6744. idx += ivOctetStringSz;
  6745. XMEMCPY(recip->recip + idx, tmpIv, kekBlockSz);
  6746. idx += kekBlockSz;
  6747. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  6748. idx += encKeyOctetStrSz;
  6749. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  6750. idx += encryptedKeySz;
  6751. ForceZero(kek, kekBlockSz);
  6752. ForceZero(encryptedKey, encryptedKeySz);
  6753. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6754. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6755. /* store recipient size */
  6756. recip->recipSz = idx;
  6757. recip->recipType = PKCS7_PWRI;
  6758. /* add recipient to recip list */
  6759. if (pkcs7->recipList == NULL) {
  6760. pkcs7->recipList = recip;
  6761. } else {
  6762. lastRecip = pkcs7->recipList;
  6763. while (lastRecip->next != NULL) {
  6764. lastRecip = lastRecip->next;
  6765. }
  6766. lastRecip->next = recip;
  6767. }
  6768. (void)options;
  6769. return idx;
  6770. }
  6771. /* Import password and KDF settings into a PKCS7 structure. Used for setting
  6772. * the password info for decryption a EnvelopedData PWRI RecipientInfo.
  6773. *
  6774. * Returns 0 on success, negative upon error */
  6775. int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen)
  6776. {
  6777. if (pkcs7 == NULL || passwd == NULL || pLen == 0)
  6778. return BAD_FUNC_ARG;
  6779. pkcs7->pass = passwd;
  6780. pkcs7->passSz = pLen;
  6781. return 0;
  6782. }
  6783. #endif /* NO_PWDBASED */
  6784. /* Encode and add CMS EnvelopedData KEKRI (KEKRecipientInfo) RecipientInfo
  6785. * to CMS/PKCS#7 EnvelopedData structure.
  6786. *
  6787. * pkcs7 - pointer to initialized PKCS7 structure
  6788. * keyWrapOID - OID sum of key wrap algorithm identifier
  6789. * kek - key encryption key
  6790. * kekSz - size of kek, bytes
  6791. * keyID - key-encryption key identifier, pre-distributed to endpoints
  6792. * keyIDSz - size of keyID, bytes
  6793. * timePtr - pointer to "time_t", which is typically "long" (OPTIONAL)
  6794. * otherOID - ASN.1 encoded OID of other attribute (OPTIONAL)
  6795. * otherOIDSz - size of otherOID, bytes (OPTIONAL)
  6796. * other - other attribute (OPTIONAL)
  6797. * otherSz - size of other (OPTIONAL)
  6798. *
  6799. * Returns 0 on success, negative upon error */
  6800. int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek,
  6801. word32 kekSz, byte* keyId, word32 keyIdSz,
  6802. void* timePtr, byte* otherOID,
  6803. word32 otherOIDSz, byte* other, word32 otherSz,
  6804. int options)
  6805. {
  6806. Pkcs7EncodedRecip* recip = NULL;
  6807. Pkcs7EncodedRecip* lastRecip = NULL;
  6808. byte recipSeq[MAX_SEQ_SZ];
  6809. byte ver[MAX_VERSION_SZ];
  6810. byte kekIdSeq[MAX_SEQ_SZ];
  6811. byte kekIdOctetStr[MAX_OCTET_STR_SZ];
  6812. byte genTime[ASN_GENERALIZED_TIME_SIZE];
  6813. byte otherAttSeq[MAX_SEQ_SZ];
  6814. byte encAlgoId[MAX_ALGO_SZ];
  6815. byte encKeyOctetStr[MAX_OCTET_STR_SZ];
  6816. #ifdef WOLFSSL_SMALL_STACK
  6817. byte* encryptedKey;
  6818. #else
  6819. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  6820. #endif
  6821. int blockKeySz = 0, ret = 0, direction;
  6822. word32 idx = 0;
  6823. word32 totalSz = 0;
  6824. word32 recipSeqSz = 0, verSz = 0;
  6825. word32 kekIdSeqSz = 0, kekIdOctetStrSz = 0;
  6826. word32 otherAttSeqSz = 0, encAlgoIdSz = 0, encKeyOctetStrSz = 0;
  6827. int encryptedKeySz;
  6828. int timeSz = 0;
  6829. #ifndef NO_ASN_TIME
  6830. time_t* tm = NULL;
  6831. #endif
  6832. if (pkcs7 == NULL || kek == NULL || keyId == NULL)
  6833. return BAD_FUNC_ARG;
  6834. recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
  6835. DYNAMIC_TYPE_PKCS7);
  6836. if (recip == NULL)
  6837. return MEMORY_E;
  6838. XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
  6839. /* get key size for content-encryption key based on algorithm */
  6840. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  6841. if (blockKeySz < 0) {
  6842. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6843. return blockKeySz;
  6844. }
  6845. /* generate random content encryption key, if needed */
  6846. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  6847. if (ret < 0) {
  6848. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6849. return ret;
  6850. }
  6851. /* EncryptedKey */
  6852. #ifdef WOLFSSL_SMALL_STACK
  6853. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  6854. DYNAMIC_TYPE_PKCS7);
  6855. if (encryptedKey == NULL) {
  6856. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6857. return MEMORY_E;
  6858. }
  6859. #endif
  6860. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  6861. XMEMSET(encryptedKey, 0, encryptedKeySz);
  6862. #ifndef NO_AES
  6863. direction = AES_ENCRYPTION;
  6864. #else
  6865. direction = DES_ENCRYPTION;
  6866. #endif
  6867. encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz,
  6868. encryptedKey, encryptedKeySz, keyWrapOID,
  6869. direction);
  6870. if (encryptedKeySz < 0) {
  6871. #ifdef WOLFSSL_SMALL_STACK
  6872. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6873. #endif
  6874. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6875. return encryptedKeySz;
  6876. }
  6877. /* handle a zero size encKey case as WC_KEY_SIZE_E */
  6878. if (encryptedKeySz == 0 || encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  6879. #ifdef WOLFSSL_SMALL_STACK
  6880. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6881. #endif
  6882. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6883. return WC_KEY_SIZE_E;
  6884. }
  6885. encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
  6886. totalSz += (encKeyOctetStrSz + encryptedKeySz);
  6887. /* KeyEncryptionAlgorithmIdentifier */
  6888. encAlgoIdSz = SetAlgoID(keyWrapOID, encAlgoId, oidKeyWrapType, 0);
  6889. totalSz += encAlgoIdSz;
  6890. /* KEKIdentifier: keyIdentifier */
  6891. kekIdOctetStrSz = SetOctetString(keyIdSz, kekIdOctetStr);
  6892. totalSz += (kekIdOctetStrSz + keyIdSz);
  6893. /* KEKIdentifier: GeneralizedTime (OPTIONAL) */
  6894. #ifndef NO_ASN_TIME
  6895. if (timePtr != NULL) {
  6896. tm = (time_t*)timePtr;
  6897. timeSz = GetAsnTimeString(tm, genTime, sizeof(genTime));
  6898. if (timeSz < 0) {
  6899. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6900. #ifdef WOLFSSL_SMALL_STACK
  6901. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6902. #endif
  6903. return timeSz;
  6904. }
  6905. totalSz += timeSz;
  6906. }
  6907. #endif
  6908. /* KEKIdentifier: OtherKeyAttribute SEQ (OPTIONAL) */
  6909. if (other != NULL && otherSz > 0) {
  6910. otherAttSeqSz = SetSequence(otherOIDSz + otherSz, otherAttSeq);
  6911. totalSz += otherAttSeqSz + otherOIDSz + otherSz;
  6912. }
  6913. /* KEKIdentifier SEQ */
  6914. kekIdSeqSz = SetSequence(kekIdOctetStrSz + keyIdSz + timeSz +
  6915. otherAttSeqSz + otherOIDSz + otherSz, kekIdSeq);
  6916. totalSz += kekIdSeqSz;
  6917. /* version */
  6918. verSz = SetMyVersion(4, ver, 0);
  6919. totalSz += verSz;
  6920. recip->recipVersion = 4;
  6921. /* KEKRecipientInfo SEQ */
  6922. recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq);
  6923. totalSz += recipSeqSz;
  6924. if (totalSz > MAX_RECIP_SZ) {
  6925. WOLFSSL_MSG("CMS Recipient output buffer too small");
  6926. XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6927. #ifdef WOLFSSL_SMALL_STACK
  6928. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6929. #endif
  6930. return BUFFER_E;
  6931. }
  6932. XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
  6933. idx += recipSeqSz;
  6934. XMEMCPY(recip->recip + idx, ver, verSz);
  6935. idx += verSz;
  6936. XMEMCPY(recip->recip + idx, kekIdSeq, kekIdSeqSz);
  6937. idx += kekIdSeqSz;
  6938. XMEMCPY(recip->recip + idx, kekIdOctetStr, kekIdOctetStrSz);
  6939. idx += kekIdOctetStrSz;
  6940. XMEMCPY(recip->recip + idx, keyId, keyIdSz);
  6941. idx += keyIdSz;
  6942. if (timePtr != NULL) {
  6943. XMEMCPY(recip->recip + idx, genTime, timeSz);
  6944. idx += timeSz;
  6945. }
  6946. if (other != NULL && otherSz > 0) {
  6947. XMEMCPY(recip->recip + idx, otherAttSeq, otherAttSeqSz);
  6948. idx += otherAttSeqSz;
  6949. XMEMCPY(recip->recip + idx, otherOID, otherOIDSz);
  6950. idx += otherOIDSz;
  6951. XMEMCPY(recip->recip + idx, other, otherSz);
  6952. idx += otherSz;
  6953. }
  6954. XMEMCPY(recip->recip + idx, encAlgoId, encAlgoIdSz);
  6955. idx += encAlgoIdSz;
  6956. XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
  6957. idx += encKeyOctetStrSz;
  6958. XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
  6959. idx += encryptedKeySz;
  6960. #ifdef WOLFSSL_SMALL_STACK
  6961. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  6962. #endif
  6963. /* store recipient size */
  6964. recip->recipSz = idx;
  6965. recip->recipType = PKCS7_KEKRI;
  6966. /* add recipient to recip list */
  6967. if (pkcs7->recipList == NULL) {
  6968. pkcs7->recipList = recip;
  6969. } else {
  6970. lastRecip = pkcs7->recipList;
  6971. while(lastRecip->next != NULL) {
  6972. lastRecip = lastRecip->next;
  6973. }
  6974. lastRecip->next = recip;
  6975. }
  6976. (void)options;
  6977. return idx;
  6978. }
  6979. static int wc_PKCS7_GetCMSVersion(PKCS7* pkcs7, int cmsContentType)
  6980. {
  6981. int version = -1;
  6982. if (pkcs7 == NULL)
  6983. return BAD_FUNC_ARG;
  6984. switch (cmsContentType) {
  6985. case ENVELOPED_DATA:
  6986. /* NOTE: EnvelopedData does not currently support
  6987. originatorInfo or unprotectedAttributes. When either of these
  6988. are added, version checking below needs to be updated to match
  6989. Section 6.1 of RFC 5652 */
  6990. /* if RecipientInfos include pwri or ori, version is 3 */
  6991. if (wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_PWRI) ||
  6992. wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_ORI)) {
  6993. version = 3;
  6994. break;
  6995. }
  6996. /* if unprotectedAttrs is absent AND all RecipientInfo structs
  6997. are version 0, version is 0 */
  6998. if (wc_PKCS7_RecipientListVersionsAllZero(pkcs7)) {
  6999. version = 0;
  7000. break;
  7001. }
  7002. /* otherwise, version is 2 */
  7003. version = 2;
  7004. break;
  7005. default:
  7006. break;
  7007. }
  7008. return version;
  7009. }
  7010. /* build PKCS#7 envelopedData content type, return enveloped size */
  7011. int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  7012. {
  7013. int ret, idx = 0;
  7014. int totalSz, padSz, encryptedOutSz;
  7015. int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz;
  7016. byte contentInfoSeq[MAX_SEQ_SZ];
  7017. byte outerContentType[MAX_ALGO_SZ];
  7018. byte outerContent[MAX_SEQ_SZ];
  7019. int kariVersion;
  7020. int envDataSeqSz, verSz;
  7021. byte envDataSeq[MAX_SEQ_SZ];
  7022. byte ver[MAX_VERSION_SZ];
  7023. WC_RNG rng;
  7024. int blockSz, blockKeySz;
  7025. byte* plain;
  7026. byte* encryptedContent;
  7027. Pkcs7EncodedRecip* tmpRecip = NULL;
  7028. int recipSz, recipSetSz;
  7029. byte recipSet[MAX_SET_SZ];
  7030. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  7031. int contentEncAlgoSz, ivOctetStringSz;
  7032. byte encContentSeq[MAX_SEQ_SZ];
  7033. byte contentType[MAX_ALGO_SZ];
  7034. byte contentEncAlgo[MAX_ALGO_SZ];
  7035. byte tmpIv[MAX_CONTENT_IV_SIZE];
  7036. byte ivOctetString[MAX_OCTET_STR_SZ];
  7037. byte encContentOctet[MAX_OCTET_STR_SZ];
  7038. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  7039. return BAD_FUNC_ARG;
  7040. if (output == NULL || outputSz == 0)
  7041. return BAD_FUNC_ARG;
  7042. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  7043. if (blockKeySz < 0)
  7044. return blockKeySz;
  7045. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  7046. if (blockSz < 0)
  7047. return blockSz;
  7048. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7049. /* outer content type */
  7050. ret = wc_SetContentType(ENVELOPED_DATA, outerContentType,
  7051. sizeof(outerContentType));
  7052. if (ret < 0)
  7053. return ret;
  7054. outerContentTypeSz = ret;
  7055. }
  7056. /* generate random content encryption key */
  7057. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  7058. if (ret != 0) {
  7059. return ret;
  7060. }
  7061. /* build RecipientInfo, only if user manually set singleCert and size */
  7062. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  7063. switch (pkcs7->publicKeyOID) {
  7064. #ifndef NO_RSA
  7065. case RSAk:
  7066. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  7067. pkcs7->singleCertSz, 0);
  7068. break;
  7069. #endif
  7070. #ifdef HAVE_ECC
  7071. case ECDSAk:
  7072. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  7073. pkcs7->singleCertSz,
  7074. pkcs7->keyWrapOID,
  7075. pkcs7->keyAgreeOID, pkcs7->ukm,
  7076. pkcs7->ukmSz, 0);
  7077. break;
  7078. #endif
  7079. default:
  7080. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  7081. return BAD_FUNC_ARG;
  7082. };
  7083. if (ret < 0) {
  7084. WOLFSSL_MSG("Failed to create RecipientInfo");
  7085. return ret;
  7086. }
  7087. }
  7088. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  7089. if (recipSz < 0) {
  7090. return ret;
  7091. } else if (recipSz == 0) {
  7092. WOLFSSL_MSG("You must add at least one CMS recipient");
  7093. return PKCS7_RECIP_E;
  7094. }
  7095. recipSetSz = SetSet(recipSz, recipSet);
  7096. /* version, defined in Section 6.1 of RFC 5652 */
  7097. kariVersion = wc_PKCS7_GetCMSVersion(pkcs7, ENVELOPED_DATA);
  7098. if (kariVersion < 0) {
  7099. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7100. WOLFSSL_MSG("Failed to set CMS EnvelopedData version");
  7101. return PKCS7_RECIP_E;
  7102. }
  7103. verSz = SetMyVersion(kariVersion, ver, 0);
  7104. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  7105. if (ret != 0) {
  7106. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7107. return ret;
  7108. }
  7109. /* generate IV for block cipher */
  7110. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, tmpIv, blockSz);
  7111. wc_FreeRng(&rng);
  7112. if (ret != 0) {
  7113. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7114. return ret;
  7115. }
  7116. /* EncryptedContentInfo */
  7117. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  7118. sizeof(contentType));
  7119. if (ret < 0) {
  7120. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7121. return ret;
  7122. }
  7123. contentTypeSz = ret;
  7124. /* allocate encrypted content buffer and PKCS#7 padding */
  7125. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  7126. if (padSz < 0) {
  7127. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7128. return padSz;
  7129. }
  7130. encryptedOutSz = pkcs7->contentSz + padSz;
  7131. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7132. if (plain == NULL) {
  7133. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7134. return MEMORY_E;
  7135. }
  7136. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  7137. encryptedOutSz, blockSz);
  7138. if (ret < 0) {
  7139. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7140. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7141. return ret;
  7142. }
  7143. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  7144. DYNAMIC_TYPE_PKCS7);
  7145. if (encryptedContent == NULL) {
  7146. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7147. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7148. return MEMORY_E;
  7149. }
  7150. /* put together IV OCTET STRING */
  7151. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  7152. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  7153. * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  7154. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  7155. oidBlkType, ivOctetStringSz + blockSz);
  7156. if (contentEncAlgoSz == 0) {
  7157. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7158. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7159. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7160. return BAD_FUNC_ARG;
  7161. }
  7162. /* encrypt content */
  7163. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  7164. pkcs7->cekSz, tmpIv, blockSz, NULL, 0, NULL, 0, plain,
  7165. encryptedOutSz, encryptedContent);
  7166. if (ret != 0) {
  7167. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7168. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7169. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7170. return ret;
  7171. }
  7172. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  7173. encContentOctet);
  7174. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  7175. ivOctetStringSz + blockSz +
  7176. encContentOctetSz + encryptedOutSz,
  7177. encContentSeq);
  7178. /* keep track of sizes for outer wrapper layering */
  7179. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  7180. contentEncAlgoSz + ivOctetStringSz + blockSz +
  7181. encContentOctetSz + encryptedOutSz;
  7182. /* EnvelopedData */
  7183. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  7184. totalSz += envDataSeqSz;
  7185. /* outer content */
  7186. outerContentSz = SetExplicit(0, totalSz, outerContent);
  7187. totalSz += outerContentTypeSz;
  7188. totalSz += outerContentSz;
  7189. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7190. /* ContentInfo */
  7191. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  7192. totalSz += contentInfoSeqSz;
  7193. }
  7194. if (totalSz > (int)outputSz) {
  7195. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  7196. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7197. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7198. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7199. return BUFFER_E;
  7200. }
  7201. if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
  7202. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  7203. idx += contentInfoSeqSz;
  7204. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  7205. idx += outerContentTypeSz;
  7206. XMEMCPY(output + idx, outerContent, outerContentSz);
  7207. idx += outerContentSz;
  7208. }
  7209. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  7210. idx += envDataSeqSz;
  7211. XMEMCPY(output + idx, ver, verSz);
  7212. idx += verSz;
  7213. XMEMCPY(output + idx, recipSet, recipSetSz);
  7214. idx += recipSetSz;
  7215. /* copy in recipients from list */
  7216. tmpRecip = pkcs7->recipList;
  7217. while (tmpRecip != NULL) {
  7218. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  7219. idx += tmpRecip->recipSz;
  7220. tmpRecip = tmpRecip->next;
  7221. }
  7222. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  7223. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  7224. idx += encContentSeqSz;
  7225. XMEMCPY(output + idx, contentType, contentTypeSz);
  7226. idx += contentTypeSz;
  7227. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  7228. idx += contentEncAlgoSz;
  7229. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  7230. idx += ivOctetStringSz;
  7231. XMEMCPY(output + idx, tmpIv, blockSz);
  7232. idx += blockSz;
  7233. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  7234. idx += encContentOctetSz;
  7235. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  7236. idx += encryptedOutSz;
  7237. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7238. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  7239. return idx;
  7240. }
  7241. #ifndef NO_RSA
  7242. /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */
  7243. static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
  7244. word32* idx, byte* decryptedKey,
  7245. word32* decryptedKeySz, int* recipFound)
  7246. {
  7247. int length, encryptedKeySz = 0, ret = 0;
  7248. int keySz, version, sidType = 0;
  7249. word32 encOID = 0;
  7250. word32 keyIdx;
  7251. byte issuerHash[KEYID_SIZE];
  7252. byte* outKey = NULL;
  7253. byte* pkiMsg = in;
  7254. word32 pkiMsgSz = inSz;
  7255. byte tag;
  7256. #ifndef NO_PKCS7_STREAM
  7257. word32 tmpIdx = *idx;
  7258. #endif
  7259. #ifdef WC_RSA_BLINDING
  7260. WC_RNG rng;
  7261. #endif
  7262. byte* encryptedKey = NULL;
  7263. #ifdef WOLFSSL_SMALL_STACK
  7264. mp_int* serialNum = NULL;
  7265. RsaKey* privKey = NULL;
  7266. #else
  7267. mp_int serialNum[1];
  7268. RsaKey privKey[1];
  7269. #endif
  7270. switch (pkcs7->state) {
  7271. case WC_PKCS7_DECRYPT_KTRI:
  7272. #ifndef NO_PKCS7_STREAM
  7273. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_VERSION_SZ,
  7274. &pkiMsg, idx)) != 0) {
  7275. return ret;
  7276. }
  7277. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  7278. #endif
  7279. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  7280. return ASN_PARSE_E;
  7281. if (version == 0) {
  7282. sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
  7283. } else if (version == 2) {
  7284. sidType = CMS_SKID;
  7285. } else {
  7286. return ASN_VERSION_E;
  7287. }
  7288. #ifndef NO_PKCS7_STREAM
  7289. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7290. break;
  7291. }
  7292. wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version);
  7293. /* @TODO getting total amount left because of GetInt call later on
  7294. * this could be optimized to stream better */
  7295. if (pkcs7->stream->totalRd > pkcs7->stream->maxLen) {
  7296. WOLFSSL_MSG("PKCS7 read more than expected");
  7297. ret = BUFFER_E;
  7298. break;
  7299. }
  7300. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  7301. pkcs7->stream->totalRd) + pkcs7->stream->length;
  7302. #endif
  7303. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2);
  7304. FALL_THROUGH;
  7305. case WC_PKCS7_DECRYPT_KTRI_2:
  7306. #ifndef NO_PKCS7_STREAM
  7307. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7308. pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
  7309. return ret;
  7310. }
  7311. if (in != pkiMsg) {
  7312. pkiMsgSz = pkcs7->stream->length;
  7313. }
  7314. wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version);
  7315. /* @TODO get expected size for next part, does not account for
  7316. * GetInt call well */
  7317. if (pkcs7->stream->expected == MAX_SEQ_SZ) {
  7318. int sz;
  7319. word32 lidx;
  7320. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  7321. lidx = *idx;
  7322. ret = GetSequence(pkiMsg, &lidx, &sz, pkiMsgSz);
  7323. if (ret < 0)
  7324. return ret;
  7325. }
  7326. else {
  7327. lidx = *idx + ASN_TAG_SZ;
  7328. ret = GetLength(pkiMsg, &lidx, &sz, pkiMsgSz);
  7329. if (ret < 0)
  7330. return ret;
  7331. }
  7332. pkcs7->stream->expected = sz + MAX_ALGO_SZ + ASN_TAG_SZ +
  7333. MAX_LENGTH_SZ;
  7334. if (pkcs7->stream->length > 0 &&
  7335. pkcs7->stream->length < pkcs7->stream->expected) {
  7336. return WC_PKCS7_WANT_READ_E;
  7337. }
  7338. }
  7339. #endif /* !NO_PKCS7_STREAM */
  7340. if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
  7341. /* remove IssuerAndSerialNumber */
  7342. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7343. return ASN_PARSE_E;
  7344. if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
  7345. return ASN_PARSE_E;
  7346. /* if we found correct recipient, issuer hashes will match */
  7347. if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) {
  7348. *recipFound = 1;
  7349. }
  7350. #ifdef WOLFSSL_SMALL_STACK
  7351. serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,
  7352. DYNAMIC_TYPE_TMP_BUFFER);
  7353. if (serialNum == NULL)
  7354. return MEMORY_E;
  7355. #endif
  7356. if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {
  7357. #ifdef WOLFSSL_SMALL_STACK
  7358. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7359. #endif
  7360. return ASN_PARSE_E;
  7361. }
  7362. mp_clear(serialNum);
  7363. #ifdef WOLFSSL_SMALL_STACK
  7364. XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7365. #endif
  7366. } else {
  7367. /* parse SubjectKeyIdentifier
  7368. * RFC 5652 lists SubjectKeyIdentifier as [0] followed by
  7369. * simple type of octet string
  7370. *
  7371. * RecipientIdentifier ::= CHOICE {
  7372. * issuerAndSerialNumber IssuerAndSerialNumber,
  7373. * subjectKeyIdentifier [0] SubjectKeyIdentifier }
  7374. *
  7375. * The choice of subjectKeyIdentifier (where version was 2) is
  7376. * context specific with tag number 0 within the class.
  7377. */
  7378. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7379. return ASN_PARSE_E;
  7380. /* should be context specific and tag number 0: [0] (0x80) */
  7381. if (tag != ASN_CONTEXT_SPECIFIC) {
  7382. return ASN_PARSE_E;
  7383. }
  7384. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7385. return ASN_PARSE_E;
  7386. if (KEYID_SIZE > pkiMsgSz - (*idx))
  7387. return BUFFER_E;
  7388. /* if we found correct recipient, SKID will match */
  7389. if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId,
  7390. KEYID_SIZE) == 0) {
  7391. *recipFound = 1;
  7392. }
  7393. (*idx) += KEYID_SIZE;
  7394. }
  7395. if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)
  7396. return ASN_PARSE_E;
  7397. /* key encryption algorithm must be RSA for now */
  7398. if (encOID != RSAk
  7399. #ifndef WC_NO_RSA_OAEP
  7400. && encOID != RSAESOAEPk
  7401. #endif
  7402. )
  7403. return ALGO_ID_E;
  7404. #ifndef WC_NO_RSA_OAEP
  7405. if (encOID == RSAESOAEPk) {
  7406. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7407. return ASN_PARSE_E;
  7408. }
  7409. if (length > 0) {
  7410. WOLFSSL_MSG("only supported default OAEP");
  7411. WOLFSSL_ERROR(ALGO_ID_E);
  7412. return ALGO_ID_E;
  7413. }
  7414. }
  7415. #endif
  7416. /* read encryptedKey */
  7417. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7418. return ASN_PARSE_E;
  7419. if (tag != ASN_OCTET_STRING)
  7420. return ASN_PARSE_E;
  7421. if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
  7422. return ASN_PARSE_E;
  7423. }
  7424. if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
  7425. return BUFFER_E;
  7426. }
  7427. #ifndef NO_PKCS7_STREAM
  7428. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7429. break;
  7430. }
  7431. wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version);
  7432. pkcs7->stream->expected = encryptedKeySz;
  7433. #endif
  7434. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3);
  7435. FALL_THROUGH;
  7436. case WC_PKCS7_DECRYPT_KTRI_3:
  7437. #ifndef NO_PKCS7_STREAM
  7438. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7439. pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
  7440. return ret;
  7441. }
  7442. encryptedKeySz = pkcs7->stream->expected;
  7443. #endif
  7444. /* Always allocate to ensure aligned use with RSA */
  7445. encryptedKey = (byte*)XMALLOC(encryptedKeySz, pkcs7->heap,
  7446. DYNAMIC_TYPE_WOLF_BIGINT);
  7447. if (encryptedKey == NULL)
  7448. return MEMORY_E;
  7449. if (*recipFound == 1)
  7450. XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);
  7451. *idx += encryptedKeySz;
  7452. /* load private key */
  7453. #ifdef WOLFSSL_SMALL_STACK
  7454. privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
  7455. DYNAMIC_TYPE_TMP_BUFFER);
  7456. if (privKey == NULL) {
  7457. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7458. return MEMORY_E;
  7459. }
  7460. #endif
  7461. ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
  7462. if (ret != 0) {
  7463. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7464. #ifdef WOLFSSL_SMALL_STACK
  7465. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7466. #endif
  7467. return ret;
  7468. }
  7469. if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
  7470. keyIdx = 0;
  7471. ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx,
  7472. privKey, pkcs7->privateKeySz);
  7473. }
  7474. else if (pkcs7->devId == INVALID_DEVID) {
  7475. ret = BAD_FUNC_ARG;
  7476. }
  7477. if (ret != 0) {
  7478. WOLFSSL_MSG("Failed to decode RSA private key");
  7479. wc_FreeRsaKey(privKey);
  7480. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7481. #ifdef WOLFSSL_SMALL_STACK
  7482. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7483. #endif
  7484. return ret;
  7485. }
  7486. /* decrypt encryptedKey */
  7487. #ifdef WC_RSA_BLINDING
  7488. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  7489. if (ret == 0) {
  7490. ret = wc_RsaSetRNG(privKey, &rng);
  7491. }
  7492. #endif
  7493. if (ret == 0) {
  7494. #ifdef WOLFSSL_ASYNC_CRYPT
  7495. /* Currently the call to RSA decrypt here is blocking @TODO */
  7496. keySz = 0; /* set initial "ret" value to 0 */
  7497. do {
  7498. keySz = wc_AsyncWait(keySz, &privKey->asyncDev,
  7499. WC_ASYNC_FLAG_CALL_AGAIN);
  7500. if (keySz >= 0)
  7501. #endif
  7502. {
  7503. #ifndef WC_NO_RSA_OAEP
  7504. if (encOID != RSAESOAEPk) {
  7505. #endif
  7506. keySz = wc_RsaPrivateDecryptInline(encryptedKey,
  7507. encryptedKeySz, &outKey,
  7508. privKey);
  7509. #ifndef WC_NO_RSA_OAEP
  7510. }
  7511. else {
  7512. word32 outLen = wc_RsaEncryptSize(privKey);
  7513. outKey = (byte*)XMALLOC(outLen, pkcs7->heap,
  7514. DYNAMIC_TYPE_TMP_BUFFER);
  7515. if (!outKey) {
  7516. WOLFSSL_MSG("Failed to allocate out key buffer");
  7517. wc_FreeRsaKey(privKey);
  7518. XFREE(encryptedKey, pkcs7->heap,
  7519. DYNAMIC_TYPE_WOLF_BIGINT);
  7520. #ifdef WOLFSSL_SMALL_STACK
  7521. XFREE(privKey, pkcs7->heap,
  7522. DYNAMIC_TYPE_TMP_BUFFER);
  7523. #endif
  7524. WOLFSSL_ERROR_VERBOSE(MEMORY_E);
  7525. return MEMORY_E;
  7526. }
  7527. keySz = wc_RsaPrivateDecrypt_ex(encryptedKey,
  7528. encryptedKeySz, outKey, outLen, privKey,
  7529. WC_RSA_OAEP_PAD,
  7530. WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0);
  7531. }
  7532. #endif
  7533. }
  7534. #ifdef WOLFSSL_ASYNC_CRYPT
  7535. } while (keySz == WC_PENDING_E);
  7536. #endif
  7537. #ifdef WC_RSA_BLINDING
  7538. wc_FreeRng(&rng);
  7539. #endif
  7540. } else {
  7541. keySz = ret;
  7542. }
  7543. wc_FreeRsaKey(privKey);
  7544. if (keySz <= 0 || outKey == NULL) {
  7545. ForceZero(encryptedKey, encryptedKeySz);
  7546. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7547. #ifdef WOLFSSL_SMALL_STACK
  7548. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7549. #endif
  7550. #ifndef WC_NO_RSA_OAEP
  7551. if (encOID == RSAESOAEPk) {
  7552. if (!outKey) {
  7553. XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7554. }
  7555. }
  7556. #endif
  7557. return keySz;
  7558. } else {
  7559. *decryptedKeySz = keySz;
  7560. XMEMCPY(decryptedKey, outKey, keySz);
  7561. ForceZero(encryptedKey, encryptedKeySz);
  7562. }
  7563. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
  7564. #ifdef WOLFSSL_SMALL_STACK
  7565. XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7566. #endif
  7567. #ifndef WC_NO_RSA_OAEP
  7568. if (encOID == RSAESOAEPk) {
  7569. if (!outKey) {
  7570. XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7571. }
  7572. }
  7573. #endif
  7574. #ifndef NO_PKCS7_STREAM
  7575. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  7576. break;
  7577. }
  7578. #endif
  7579. ret = 0; /* success */
  7580. break;
  7581. default:
  7582. WOLFSSL_MSG("PKCS7 Unknown KTRI decrypt state");
  7583. ret = BAD_FUNC_ARG;
  7584. }
  7585. return ret;
  7586. }
  7587. #endif /* !NO_RSA */
  7588. #ifdef HAVE_ECC
  7589. /* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */
  7590. static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
  7591. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7592. {
  7593. int ret, length;
  7594. word32 keyOID, oidSum = 0;
  7595. int curve_id = ECC_CURVE_DEF;
  7596. byte tag;
  7597. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7598. return BAD_FUNC_ARG;
  7599. /* remove OriginatorIdentifierOrKey */
  7600. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7601. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7602. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7603. return ASN_PARSE_E;
  7604. } else {
  7605. return ASN_PARSE_E;
  7606. }
  7607. /* remove OriginatorPublicKey */
  7608. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
  7609. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7610. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7611. return ASN_PARSE_E;
  7612. } else {
  7613. return ASN_PARSE_E;
  7614. }
  7615. /* remove AlgorithmIdentifier */
  7616. if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)
  7617. return ASN_PARSE_E;
  7618. if (keyOID != ECDSAk)
  7619. return ASN_PARSE_E;
  7620. /* optional algorithm parameters */
  7621. ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);
  7622. if (ret == 0) {
  7623. /* get curve id */
  7624. curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
  7625. if (curve_id < 0)
  7626. return ECC_CURVE_OID_E;
  7627. }
  7628. /* remove ECPoint BIT STRING */
  7629. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7630. return ASN_PARSE_E;
  7631. if (tag != ASN_BIT_STRING)
  7632. return ASN_PARSE_E;
  7633. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7634. return ASN_PARSE_E;
  7635. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7636. return ASN_EXPECT_0_E;
  7637. if (tag != ASN_OTHER_TYPE)
  7638. return ASN_EXPECT_0_E;
  7639. /* get sender ephemeral public ECDSA key */
  7640. ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
  7641. if (ret != 0)
  7642. return ret;
  7643. kari->senderKeyInit = 1;
  7644. /* length-1 for unused bits counter */
  7645. ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,
  7646. curve_id);
  7647. if (ret != 0) {
  7648. ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
  7649. if (ret != 0)
  7650. return ret;
  7651. }
  7652. else {
  7653. (*idx) += length - 1;
  7654. }
  7655. return 0;
  7656. }
  7657. /* remove optional UserKeyingMaterial if available, return 0 on success,
  7658. * < 0 on error */
  7659. static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
  7660. byte* pkiMsg, word32 pkiMsgSz, word32* idx)
  7661. {
  7662. int length;
  7663. word32 savedIdx;
  7664. byte tag;
  7665. if (kari == NULL || pkiMsg == NULL || idx == NULL)
  7666. return BAD_FUNC_ARG;
  7667. savedIdx = *idx;
  7668. /* starts with EXPLICIT [1] */
  7669. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7670. *idx = savedIdx;
  7671. return 0;
  7672. }
  7673. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  7674. *idx = savedIdx;
  7675. return 0;
  7676. }
  7677. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7678. *idx = savedIdx;
  7679. return 0;
  7680. }
  7681. /* get OCTET STRING */
  7682. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7683. *idx = savedIdx;
  7684. return 0;
  7685. }
  7686. if (tag != ASN_OCTET_STRING) {
  7687. *idx = savedIdx;
  7688. return 0;
  7689. }
  7690. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  7691. *idx = savedIdx;
  7692. return 0;
  7693. }
  7694. kari->ukm = NULL;
  7695. if (length > 0) {
  7696. kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
  7697. if (kari->ukm == NULL)
  7698. return MEMORY_E;
  7699. XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
  7700. kari->ukmOwner = 1;
  7701. }
  7702. (*idx) += length;
  7703. kari->ukmSz = length;
  7704. return 0;
  7705. }
  7706. /* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,
  7707. * < 0 on error */
  7708. static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
  7709. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7710. word32* keyAgreeOID, word32* keyWrapOID)
  7711. {
  7712. int length = 0;
  7713. word32 localIdx;
  7714. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  7715. keyAgreeOID == NULL || keyWrapOID == NULL)
  7716. return BAD_FUNC_ARG;
  7717. localIdx = *idx;
  7718. /* remove KeyEncryptionAlgorithmIdentifier */
  7719. if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  7720. return ASN_PARSE_E;
  7721. localIdx = *idx;
  7722. if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,
  7723. pkiMsgSz) < 0) {
  7724. return ASN_PARSE_E;
  7725. }
  7726. if (localIdx < *idx + length) {
  7727. *idx = localIdx;
  7728. }
  7729. /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
  7730. if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  7731. return ASN_PARSE_E;
  7732. return 0;
  7733. }
  7734. /* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
  7735. * if subject key ID matches, recipFound is set to 1 */
  7736. static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
  7737. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7738. int* recipFound, byte* rid)
  7739. {
  7740. int length;
  7741. byte tag;
  7742. if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
  7743. rid == NULL)
  7744. return BAD_FUNC_ARG;
  7745. /* remove RecipientKeyIdentifier IMPLICIT [0] */
  7746. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7747. return ASN_PARSE_E;
  7748. }
  7749. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7750. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7751. return ASN_PARSE_E;
  7752. } else {
  7753. return ASN_PARSE_E;
  7754. }
  7755. /* remove SubjectKeyIdentifier */
  7756. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  7757. return ASN_PARSE_E;
  7758. }
  7759. if (tag != ASN_OCTET_STRING)
  7760. return ASN_PARSE_E;
  7761. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7762. return ASN_PARSE_E;
  7763. if (length != KEYID_SIZE)
  7764. return ASN_PARSE_E;
  7765. XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE);
  7766. (*idx) += length;
  7767. /* subject key id should match if recipient found */
  7768. if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {
  7769. *recipFound = 1;
  7770. }
  7771. return 0;
  7772. }
  7773. /* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
  7774. * if issuer and serial number match, recipFound is set to 1 */
  7775. static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
  7776. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7777. int* recipFound, byte* rid)
  7778. {
  7779. int length, ret;
  7780. #ifdef WOLFSSL_SMALL_STACK
  7781. mp_int* serial;
  7782. mp_int* recipSerial;
  7783. #else
  7784. mp_int serial[1];
  7785. mp_int recipSerial[1];
  7786. #endif
  7787. if (rid == NULL) {
  7788. return BAD_FUNC_ARG;
  7789. }
  7790. /* remove IssuerAndSerialNumber */
  7791. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7792. return ASN_PARSE_E;
  7793. if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0)
  7794. return ASN_PARSE_E;
  7795. /* if we found correct recipient, issuer hashes will match */
  7796. if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
  7797. *recipFound = 1;
  7798. }
  7799. #ifdef WOLFSSL_SMALL_STACK
  7800. serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  7801. DYNAMIC_TYPE_TMP_BUFFER);
  7802. if (serial == NULL)
  7803. return MEMORY_E;
  7804. recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
  7805. DYNAMIC_TYPE_TMP_BUFFER);
  7806. if (recipSerial == NULL) {
  7807. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7808. return MEMORY_E;
  7809. }
  7810. #endif
  7811. if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
  7812. #ifdef WOLFSSL_SMALL_STACK
  7813. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7814. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7815. #endif
  7816. return ASN_PARSE_E;
  7817. }
  7818. ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
  7819. kari->decoded->serialSz);
  7820. if (ret != MP_OKAY) {
  7821. mp_clear(serial);
  7822. WOLFSSL_MSG("Failed to parse CMS recipient serial number");
  7823. #ifdef WOLFSSL_SMALL_STACK
  7824. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7825. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7826. #endif
  7827. return ret;
  7828. }
  7829. if (mp_cmp(recipSerial, serial) != MP_EQ) {
  7830. mp_clear(serial);
  7831. mp_clear(recipSerial);
  7832. WOLFSSL_MSG("CMS serial number does not match recipient");
  7833. #ifdef WOLFSSL_SMALL_STACK
  7834. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7835. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7836. #endif
  7837. return PKCS7_RECIP_E;
  7838. }
  7839. mp_clear(serial);
  7840. mp_clear(recipSerial);
  7841. #ifdef WOLFSSL_SMALL_STACK
  7842. XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7843. XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
  7844. #endif
  7845. return 0;
  7846. }
  7847. /* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
  7848. static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
  7849. byte* pkiMsg, word32 pkiMsgSz, word32* idx,
  7850. int* recipFound, byte* encryptedKey,
  7851. int* encryptedKeySz, byte* rid)
  7852. {
  7853. int length;
  7854. int ret = 0;
  7855. byte tag;
  7856. word32 localIdx;
  7857. if (kari == NULL || pkiMsg == NULL || idx == NULL ||
  7858. recipFound == NULL || encryptedKey == NULL)
  7859. return BAD_FUNC_ARG;
  7860. /* remove RecipientEncryptedKeys */
  7861. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7862. return ASN_PARSE_E;
  7863. /* remove RecipientEncryptedKeys */
  7864. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7865. return ASN_PARSE_E;
  7866. /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
  7867. * or [0] IMPLICIT RecipientKeyIdentifier */
  7868. localIdx = *idx;
  7869. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  7870. return ASN_PARSE_E;
  7871. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
  7872. /* try to get RecipientKeyIdentifier */
  7873. ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
  7874. idx, recipFound, rid);
  7875. } else {
  7876. /* try to get IssuerAndSerialNumber */
  7877. ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
  7878. idx, recipFound, rid);
  7879. }
  7880. /* if we don't have either option, malformed CMS */
  7881. if (ret != 0)
  7882. return ret;
  7883. /* remove EncryptedKey */
  7884. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  7885. return ASN_PARSE_E;
  7886. if (tag != ASN_OCTET_STRING)
  7887. return ASN_PARSE_E;
  7888. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  7889. return ASN_PARSE_E;
  7890. /* put encrypted CEK in decryptedKey buffer for now, decrypt later */
  7891. if (length > *encryptedKeySz)
  7892. return BUFFER_E;
  7893. XMEMCPY(encryptedKey, pkiMsg + (*idx), length);
  7894. *encryptedKeySz = length;
  7895. (*idx) += length;
  7896. return 0;
  7897. }
  7898. #endif /* HAVE_ECC */
  7899. int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx)
  7900. {
  7901. if (pkcs7 == NULL)
  7902. return BAD_FUNC_ARG;
  7903. pkcs7->oriEncryptCtx = ctx;
  7904. return 0;
  7905. }
  7906. int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx)
  7907. {
  7908. if (pkcs7 == NULL)
  7909. return BAD_FUNC_ARG;
  7910. pkcs7->oriDecryptCtx = ctx;
  7911. return 0;
  7912. }
  7913. int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb)
  7914. {
  7915. if (pkcs7 == NULL)
  7916. return BAD_FUNC_ARG;
  7917. pkcs7->oriDecryptCb = cb;
  7918. return 0;
  7919. }
  7920. /* return 0 on success */
  7921. int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, CallbackWrapCEK cb)
  7922. {
  7923. if (pkcs7 == NULL)
  7924. return BAD_FUNC_ARG;
  7925. pkcs7->wrapCEKCb = cb;
  7926. return 0;
  7927. }
  7928. /* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by:
  7929. *
  7930. * OtherRecipientInfo ::= SEQUENCE {
  7931. * oriType OBJECT IDENTIFIER,
  7932. * oriValue ANY DEFINED BY oriType }
  7933. *
  7934. * pkcs7 - pointer to initialized PKCS7 structure
  7935. * pkiMsg - pointer to encoded CMS bundle
  7936. * pkiMsgSz - size of pkiMsg, bytes
  7937. * idx - [IN/OUT] pointer to index into pkiMsg
  7938. * decryptedKey - [OUT] output buf for decrypted content encryption key
  7939. * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key
  7940. * recipFound - [OUT] 1 if recipient has been found, 0 if not
  7941. *
  7942. * Return 0 on success, negative upon error.
  7943. */
  7944. static int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* in, word32 inSz,
  7945. word32* idx, byte* decryptedKey,
  7946. word32* decryptedKeySz, int* recipFound)
  7947. {
  7948. int ret, seqSz, oriOIDSz;
  7949. word32 oriValueSz, tmpIdx;
  7950. byte* oriValue;
  7951. byte oriOID[MAX_OID_SZ];
  7952. byte* pkiMsg = in;
  7953. word32 pkiMsgSz = inSz;
  7954. #ifndef NO_PKCS7_STREAM
  7955. word32 stateIdx = *idx;
  7956. #endif
  7957. if (pkcs7->oriDecryptCb == NULL) {
  7958. WOLFSSL_MSG("You must register an ORI Decrypt callback");
  7959. return BAD_FUNC_ARG;
  7960. }
  7961. switch (pkcs7->state) {
  7962. case WC_PKCS7_DECRYPT_ORI:
  7963. #ifndef NO_PKCS7_STREAM
  7964. /* @TODO for now just get full buffer, needs divided up */
  7965. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  7966. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  7967. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  7968. return ret;
  7969. }
  7970. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  7971. #endif
  7972. /* get OtherRecipientInfo sequence length */
  7973. if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0)
  7974. return ASN_PARSE_E;
  7975. tmpIdx = *idx;
  7976. /* remove and store oriType OBJECT IDENTIFIER */
  7977. if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0)
  7978. return ASN_PARSE_E;
  7979. XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz);
  7980. *idx += oriOIDSz;
  7981. /* get oriValue, increment idx */
  7982. oriValue = pkiMsg + *idx;
  7983. oriValueSz = seqSz - (*idx - tmpIdx);
  7984. *idx += oriValueSz;
  7985. /* pass oriOID and oriValue to user callback, expect back
  7986. decryptedKey and size */
  7987. ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue,
  7988. oriValueSz, decryptedKey, decryptedKeySz,
  7989. pkcs7->oriDecryptCtx);
  7990. if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) {
  7991. /* decrypt operation failed */
  7992. *recipFound = 0;
  7993. return PKCS7_RECIP_E;
  7994. }
  7995. /* mark recipFound, since we only support one RecipientInfo for now */
  7996. *recipFound = 1;
  7997. #ifndef NO_PKCS7_STREAM
  7998. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, idx)) != 0) {
  7999. break;
  8000. }
  8001. #endif
  8002. ret = 0; /* success */
  8003. break;
  8004. default:
  8005. WOLFSSL_MSG("PKCS7 ORI unknown state");
  8006. ret = BAD_FUNC_ARG;
  8007. }
  8008. return ret;
  8009. }
  8010. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8011. /* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success,
  8012. * < 0 on error */
  8013. static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
  8014. word32* idx, byte* decryptedKey,
  8015. word32* decryptedKeySz, int* recipFound)
  8016. {
  8017. byte* salt;
  8018. byte* cek;
  8019. byte* kek;
  8020. byte tmpIv[MAX_CONTENT_IV_SIZE];
  8021. int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
  8022. int hashOID = WC_SHA; /* default to SHA1 */
  8023. word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
  8024. byte* pkiMsg = in;
  8025. word32 pkiMsgSz = inSz;
  8026. byte tag;
  8027. #ifndef NO_PKCS7_STREAM
  8028. word32 tmpIdx = *idx;
  8029. #endif
  8030. switch (pkcs7->state) {
  8031. case WC_PKCS7_DECRYPT_PWRI:
  8032. #ifndef NO_PKCS7_STREAM
  8033. /*@TODO for now just get full buffer, needs divided up */
  8034. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8035. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8036. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8037. return ret;
  8038. }
  8039. #ifdef ASN_BER_TO_DER
  8040. /* check if pkcs7->der is being used after BER to DER */
  8041. if (pkcs7->derSz > 0) {
  8042. pkiMsgSz = pkcs7->derSz;
  8043. }
  8044. else
  8045. #endif
  8046. {
  8047. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  8048. inSz;
  8049. }
  8050. #endif
  8051. /* remove KeyDerivationAlgorithmIdentifier */
  8052. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8053. return ASN_PARSE_E;
  8054. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  8055. return ASN_PARSE_E;
  8056. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8057. return ASN_PARSE_E;
  8058. /* get KeyDerivationAlgorithmIdentifier */
  8059. if (wc_GetContentType(pkiMsg, idx, &kdfAlgoId, pkiMsgSz) < 0)
  8060. return ASN_PARSE_E;
  8061. /* get KDF params SEQ */
  8062. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8063. return ASN_PARSE_E;
  8064. /* get KDF salt OCTET STRING */
  8065. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8066. return ASN_PARSE_E;
  8067. if (tag != ASN_OCTET_STRING)
  8068. return ASN_PARSE_E;
  8069. if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)
  8070. return ASN_PARSE_E;
  8071. salt = (byte*)XMALLOC(saltSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8072. if (salt == NULL)
  8073. return MEMORY_E;
  8074. XMEMCPY(salt, pkiMsg + (*idx), saltSz);
  8075. *idx += saltSz;
  8076. /* get KDF iterations */
  8077. if (GetMyVersion(pkiMsg, idx, &iterations, pkiMsgSz) < 0) {
  8078. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8079. return ASN_PARSE_E;
  8080. }
  8081. /* get KeyEncAlgoId SEQ */
  8082. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8083. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8084. return ASN_PARSE_E;
  8085. }
  8086. /* get KeyEncAlgoId */
  8087. if (wc_GetContentType(pkiMsg, idx, &keyEncAlgoId, pkiMsgSz) < 0) {
  8088. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8089. return ASN_PARSE_E;
  8090. }
  8091. /* get pwriEncAlgoId */
  8092. if (GetAlgoId(pkiMsg, idx, &pwriEncAlgoId, oidBlkType, pkiMsgSz) < 0) {
  8093. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8094. return ASN_PARSE_E;
  8095. }
  8096. blockSz = wc_PKCS7_GetOIDBlockSize(pwriEncAlgoId);
  8097. if (blockSz < 0) {
  8098. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8099. return blockSz;
  8100. }
  8101. /* get content-encryption key size, based on algorithm */
  8102. kekKeySz = wc_PKCS7_GetOIDKeySize(pwriEncAlgoId);
  8103. if (kekKeySz < 0) {
  8104. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8105. return kekKeySz;
  8106. }
  8107. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  8108. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  8109. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8110. return ASN_PARSE_E;
  8111. }
  8112. if (tag != ASN_OCTET_STRING) {
  8113. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8114. return ASN_PARSE_E;
  8115. }
  8116. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8117. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8118. return ASN_PARSE_E;
  8119. }
  8120. if (length != blockSz) {
  8121. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  8122. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8123. return ASN_PARSE_E;
  8124. }
  8125. XMEMCPY(tmpIv, pkiMsg + (*idx), length);
  8126. *idx += length;
  8127. /* get EncryptedKey */
  8128. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
  8129. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8130. return ASN_PARSE_E;
  8131. }
  8132. if (tag != ASN_OCTET_STRING) {
  8133. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8134. return ASN_PARSE_E;
  8135. }
  8136. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
  8137. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8138. return ASN_PARSE_E;
  8139. }
  8140. /* allocate temporary space for decrypted key */
  8141. cekSz = length;
  8142. cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8143. if (cek == NULL) {
  8144. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8145. return MEMORY_E;
  8146. }
  8147. /* generate KEK */
  8148. kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8149. if (kek == NULL) {
  8150. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8151. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8152. return MEMORY_E;
  8153. }
  8154. ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, pkcs7->pass, pkcs7->passSz,
  8155. salt, saltSz, kdfAlgoId, hashOID,
  8156. iterations, kek, kekKeySz);
  8157. if (ret < 0) {
  8158. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8159. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8160. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8161. return ASN_PARSE_E;
  8162. }
  8163. /* decrypt CEK with KEK */
  8164. ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, kekKeySz,
  8165. pkiMsg + (*idx), length, cek,
  8166. cekSz, tmpIv, blockSz,
  8167. pwriEncAlgoId);
  8168. if (ret < 0) {
  8169. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8170. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8171. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8172. return ret;
  8173. }
  8174. cekSz = ret;
  8175. if (*decryptedKeySz < cekSz) {
  8176. WOLFSSL_MSG("Decrypted key buffer too small for CEK");
  8177. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8178. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8179. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8180. return BUFFER_E;
  8181. }
  8182. XMEMCPY(decryptedKey, cek, cekSz);
  8183. *decryptedKeySz = cekSz;
  8184. XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8185. XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8186. XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8187. /* mark recipFound, since we only support one RecipientInfo for now */
  8188. *recipFound = 1;
  8189. *idx += length;
  8190. #ifndef NO_PKCS7_STREAM
  8191. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8192. break;
  8193. }
  8194. #endif
  8195. ret = 0; /* success */
  8196. break;
  8197. default:
  8198. WOLFSSL_MSG("PKCS7 PWRI unknown state");
  8199. ret = BAD_FUNC_ARG;
  8200. }
  8201. return ret;
  8202. }
  8203. #endif /* NO_PWDBASED | NO_SHA */
  8204. /* decode ASN.1 KEKRecipientInfo (kekri), return 0 on success,
  8205. * < 0 on error */
  8206. static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
  8207. word32* idx, byte* decryptedKey,
  8208. word32* decryptedKeySz, int* recipFound)
  8209. {
  8210. int length, keySz, dateLen, direction;
  8211. byte* keyId = NULL;
  8212. const byte* datePtr = NULL;
  8213. byte dateFormat, tag;
  8214. word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;
  8215. int ret = 0;
  8216. byte* pkiMsg = in;
  8217. word32 pkiMsgSz = inSz;
  8218. #ifndef NO_PKCS7_STREAM
  8219. word32 tmpIdx = *idx;
  8220. #endif
  8221. WOLFSSL_ENTER("wc_PKCS7_DecryptKekri");
  8222. switch (pkcs7->state) {
  8223. case WC_PKCS7_DECRYPT_KEKRI:
  8224. #ifndef NO_PKCS7_STREAM
  8225. /* @TODO for now just get full buffer, needs divided up */
  8226. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8227. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8228. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8229. return ret;
  8230. }
  8231. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8232. #endif
  8233. /* remove KEKIdentifier */
  8234. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8235. return ASN_PARSE_E;
  8236. kekIdSz = length;
  8237. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8238. return ASN_PARSE_E;
  8239. if (tag != ASN_OCTET_STRING)
  8240. return ASN_PARSE_E;
  8241. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8242. return ASN_PARSE_E;
  8243. /* save keyIdentifier and length */
  8244. keyId = pkiMsg + *idx;
  8245. keyIdSz = length;
  8246. *idx += keyIdSz;
  8247. /* may have OPTIONAL GeneralizedTime */
  8248. localIdx = *idx;
  8249. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  8250. pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {
  8251. if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,
  8252. &dateLen) != 0) {
  8253. return ASN_PARSE_E;
  8254. }
  8255. *idx += (dateLen + 1);
  8256. }
  8257. /* may have OPTIONAL OtherKeyAttribute */
  8258. localIdx = *idx;
  8259. if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
  8260. pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |
  8261. ASN_CONSTRUCTED)) {
  8262. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8263. return ASN_PARSE_E;
  8264. /* skip it */
  8265. *idx += length;
  8266. }
  8267. /* get KeyEncryptionAlgorithmIdentifier */
  8268. if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
  8269. return ASN_PARSE_E;
  8270. /* get EncryptedKey */
  8271. if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
  8272. return ASN_PARSE_E;
  8273. if (tag != ASN_OCTET_STRING)
  8274. return ASN_PARSE_E;
  8275. if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8276. return ASN_PARSE_E;
  8277. #ifndef NO_AES
  8278. direction = AES_DECRYPTION;
  8279. #else
  8280. direction = DES_DECRYPTION;
  8281. #endif
  8282. /* decrypt CEK with KEK */
  8283. if (pkcs7->wrapCEKCb) {
  8284. keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,
  8285. keyIdSz, NULL, 0, decryptedKey,
  8286. *decryptedKeySz, keyWrapOID,
  8287. (int)PKCS7_KEKRI, direction);
  8288. }
  8289. else {
  8290. keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,
  8291. pkcs7->privateKeySz, decryptedKey, *decryptedKeySz,
  8292. keyWrapOID, direction);
  8293. }
  8294. if (keySz <= 0)
  8295. return keySz;
  8296. *decryptedKeySz = (word32)keySz;
  8297. /* mark recipFound, since we only support one RecipientInfo for now */
  8298. *recipFound = 1;
  8299. *idx += length;
  8300. #ifndef NO_PKCS7_STREAM
  8301. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8302. break;
  8303. }
  8304. #endif
  8305. ret = 0; /* success */
  8306. break;
  8307. default:
  8308. WOLFSSL_MSG("PKCS7 KEKRI unknown state");
  8309. ret = BAD_FUNC_ARG;
  8310. }
  8311. (void)keyId;
  8312. return ret;
  8313. }
  8314. /* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,
  8315. * < 0 on error */
  8316. static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
  8317. word32* idx, byte* decryptedKey,
  8318. word32* decryptedKeySz, int* recipFound)
  8319. {
  8320. #ifdef HAVE_ECC
  8321. int ret, keySz;
  8322. int encryptedKeySz;
  8323. int direction = 0;
  8324. word32 keyAgreeOID, keyWrapOID;
  8325. byte rid[KEYID_SIZE];
  8326. #ifdef WOLFSSL_SMALL_STACK
  8327. byte* encryptedKey;
  8328. #else
  8329. byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
  8330. #endif
  8331. byte* pkiMsg = in;
  8332. word32 pkiMsgSz = inSz;
  8333. #ifndef NO_PKCS7_STREAM
  8334. word32 tmpIdx = (idx) ? *idx : 0;
  8335. #endif
  8336. WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
  8337. if (pkcs7 == NULL || pkiMsg == NULL ||
  8338. ((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&
  8339. pkcs7->wrapCEKCb == NULL) ||
  8340. idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
  8341. return BAD_FUNC_ARG;
  8342. }
  8343. switch (pkcs7->state) {
  8344. case WC_PKCS7_DECRYPT_KARI: {
  8345. WC_PKCS7_KARI* kari;
  8346. #ifndef NO_PKCS7_STREAM
  8347. /* @TODO for now just get full buffer, needs divided up */
  8348. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8349. (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
  8350. pkcs7->stream->length, &pkiMsg, idx)) != 0) {
  8351. return ret;
  8352. }
  8353. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8354. #endif
  8355. kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);
  8356. if (kari == NULL)
  8357. return MEMORY_E;
  8358. #ifdef WOLFSSL_SMALL_STACK
  8359. encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  8360. DYNAMIC_TYPE_PKCS7);
  8361. if (encryptedKey == NULL) {
  8362. wc_PKCS7_KariFree(kari);
  8363. return MEMORY_E;
  8364. }
  8365. #endif
  8366. encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  8367. /* parse cert and key */
  8368. if (pkcs7->singleCert != NULL) {
  8369. ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
  8370. pkcs7->singleCertSz, pkcs7->privateKey,
  8371. pkcs7->privateKeySz);
  8372. if (ret != 0) {
  8373. wc_PKCS7_KariFree(kari);
  8374. #ifdef WOLFSSL_SMALL_STACK
  8375. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8376. #endif
  8377. return ret;
  8378. }
  8379. }
  8380. /* remove OriginatorIdentifierOrKey */
  8381. ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
  8382. pkiMsgSz, idx);
  8383. if (ret != 0) {
  8384. wc_PKCS7_KariFree(kari);
  8385. #ifdef WOLFSSL_SMALL_STACK
  8386. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8387. #endif
  8388. return ret;
  8389. }
  8390. /* try and remove optional UserKeyingMaterial */
  8391. ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);
  8392. if (ret != 0) {
  8393. wc_PKCS7_KariFree(kari);
  8394. #ifdef WOLFSSL_SMALL_STACK
  8395. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8396. #endif
  8397. return ret;
  8398. }
  8399. /* remove KeyEncryptionAlgorithmIdentifier */
  8400. ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,
  8401. pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);
  8402. if (ret != 0) {
  8403. wc_PKCS7_KariFree(kari);
  8404. #ifdef WOLFSSL_SMALL_STACK
  8405. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8406. #endif
  8407. return ret;
  8408. }
  8409. /* if user has not explicitly set keyAgreeOID, set from one in bundle */
  8410. if (pkcs7->keyAgreeOID == 0)
  8411. pkcs7->keyAgreeOID = keyAgreeOID;
  8412. /* set direction based on key wrap algorithm */
  8413. switch (keyWrapOID) {
  8414. #ifndef NO_AES
  8415. #ifdef WOLFSSL_AES_128
  8416. case AES128_WRAP:
  8417. #endif
  8418. #ifdef WOLFSSL_AES_192
  8419. case AES192_WRAP:
  8420. #endif
  8421. #ifdef WOLFSSL_AES_256
  8422. case AES256_WRAP:
  8423. #endif
  8424. direction = AES_DECRYPTION;
  8425. break;
  8426. #endif
  8427. default:
  8428. WOLFSSL_MSG("AES key wrap algorithm unsupported");
  8429. if (pkcs7->wrapCEKCb) {
  8430. WOLFSSL_MSG("Direction not set!");
  8431. break; /* if unwrapping callback is set then do not
  8432. * force restriction of supported wrap
  8433. * algorithms */
  8434. }
  8435. wc_PKCS7_KariFree(kari);
  8436. #ifdef WOLFSSL_SMALL_STACK
  8437. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8438. #endif
  8439. return BAD_KEYWRAP_ALG_E;
  8440. }
  8441. /* remove RecipientEncryptedKeys */
  8442. ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
  8443. idx, recipFound, encryptedKey, &encryptedKeySz, rid);
  8444. if (ret != 0) {
  8445. wc_PKCS7_KariFree(kari);
  8446. #ifdef WOLFSSL_SMALL_STACK
  8447. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8448. #endif
  8449. return ret;
  8450. }
  8451. /* decrypt CEK with KEK */
  8452. if (pkcs7->wrapCEKCb) {
  8453. word32 tmpKeySz = 0;
  8454. byte* tmpKeyDer = NULL;
  8455. PRIVATE_KEY_UNLOCK();
  8456. ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);
  8457. PRIVATE_KEY_LOCK();
  8458. if (ret != LENGTH_ONLY_E) {
  8459. return ret;
  8460. }
  8461. /* buffer space for algorithm/curve */
  8462. tmpKeySz += MAX_SEQ_SZ;
  8463. tmpKeySz += 2 * MAX_ALGO_SZ;
  8464. /* buffer space for public key sequence */
  8465. tmpKeySz += MAX_SEQ_SZ;
  8466. tmpKeySz += TRAILING_ZERO;
  8467. tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,
  8468. DYNAMIC_TYPE_TMP_BUFFER);
  8469. if (tmpKeyDer == NULL) {
  8470. return MEMORY_E;
  8471. }
  8472. ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,
  8473. tmpKeySz, 1);
  8474. if (ret < 0) {
  8475. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8476. return ret;
  8477. }
  8478. tmpKeySz = (word32)ret;
  8479. keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,
  8480. rid, KEYID_SIZE, tmpKeyDer, tmpKeySz,
  8481. decryptedKey, *decryptedKeySz,
  8482. keyWrapOID, (int)PKCS7_KARI, direction);
  8483. XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  8484. if (keySz > 0) {
  8485. /* If unwrapping was successful then consider recipient
  8486. * found. Checking for NULL singleCert to confirm previous
  8487. * SID check was not done */
  8488. if (pkcs7->singleCert == NULL)
  8489. *recipFound = 1;
  8490. }
  8491. }
  8492. else {
  8493. /* create KEK */
  8494. ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, keyWrapOID,
  8495. pkcs7->keyAgreeOID);
  8496. if (ret != 0) {
  8497. wc_PKCS7_KariFree(kari);
  8498. #ifdef WOLFSSL_SMALL_STACK
  8499. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8500. #endif
  8501. return ret;
  8502. }
  8503. /* decrypt CEK with KEK */
  8504. keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,
  8505. kari->kekSz, decryptedKey, *decryptedKeySz,
  8506. keyWrapOID, direction);
  8507. }
  8508. if (keySz <= 0) {
  8509. wc_PKCS7_KariFree(kari);
  8510. #ifdef WOLFSSL_SMALL_STACK
  8511. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8512. #endif
  8513. return keySz;
  8514. }
  8515. *decryptedKeySz = (word32)keySz;
  8516. wc_PKCS7_KariFree(kari);
  8517. #ifdef WOLFSSL_SMALL_STACK
  8518. XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8519. #endif
  8520. #ifndef NO_PKCS7_STREAM
  8521. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8522. break;
  8523. }
  8524. #endif
  8525. ret = 0; /* success */
  8526. }
  8527. break;
  8528. default:
  8529. WOLFSSL_MSG("PKCS7 kari unknown state");
  8530. ret = BAD_FUNC_ARG;
  8531. }
  8532. (void)pkiMsg;
  8533. (void)pkiMsgSz;
  8534. return ret;
  8535. #else
  8536. (void)in;
  8537. (void)inSz;
  8538. (void)pkcs7;
  8539. (void)idx;
  8540. (void)decryptedKey;
  8541. (void)decryptedKeySz;
  8542. (void)recipFound;
  8543. return NOT_COMPILED_IN;
  8544. #endif /* HAVE_ECC */
  8545. }
  8546. /* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */
  8547. static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
  8548. word32 inSz, word32* idx, byte* decryptedKey,
  8549. word32* decryptedKeySz, int* recipFound)
  8550. {
  8551. word32 savedIdx;
  8552. int version, ret = 0, length;
  8553. byte* pkiMsg = in;
  8554. word32 pkiMsgSz = inSz;
  8555. byte tag;
  8556. #ifndef NO_PKCS7_STREAM
  8557. word32 tmpIdx;
  8558. #endif
  8559. if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||
  8560. decryptedKey == NULL || decryptedKeySz == NULL ||
  8561. recipFound == NULL) {
  8562. return BAD_FUNC_ARG;
  8563. }
  8564. WOLFSSL_ENTER("wc_PKCS7_DecryptRecipientInfos");
  8565. #ifndef NO_PKCS7_STREAM
  8566. tmpIdx = *idx;
  8567. #endif
  8568. /* check if in the process of decrypting */
  8569. switch (pkcs7->state) {
  8570. case WC_PKCS7_DECRYPT_KTRI:
  8571. case WC_PKCS7_DECRYPT_KTRI_2:
  8572. case WC_PKCS7_DECRYPT_KTRI_3:
  8573. #ifndef NO_RSA
  8574. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8575. decryptedKey, decryptedKeySz, recipFound);
  8576. #else
  8577. return NOT_COMPILED_IN;
  8578. #endif
  8579. break;
  8580. case WC_PKCS7_DECRYPT_KARI:
  8581. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8582. decryptedKey, decryptedKeySz, recipFound);
  8583. break;
  8584. case WC_PKCS7_DECRYPT_KEKRI:
  8585. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8586. decryptedKey, decryptedKeySz, recipFound);
  8587. break;
  8588. case WC_PKCS7_DECRYPT_PWRI:
  8589. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8590. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8591. decryptedKey, decryptedKeySz, recipFound);
  8592. #else
  8593. return NOT_COMPILED_IN;
  8594. #endif
  8595. break;
  8596. case WC_PKCS7_DECRYPT_ORI:
  8597. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8598. decryptedKey, decryptedKeySz, recipFound);
  8599. break;
  8600. default:
  8601. /* not in decrypting state */
  8602. break;
  8603. }
  8604. if (ret < 0) {
  8605. return ret;
  8606. }
  8607. savedIdx = *idx;
  8608. #ifndef NO_PKCS7_STREAM
  8609. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8610. if (pkcs7->stream->length > 0)
  8611. pkiMsg = pkcs7->stream->buffer;
  8612. #endif
  8613. /* when looking for next recipient, use first sequence and version to
  8614. * indicate there is another, if not, move on */
  8615. while(*recipFound == 0) {
  8616. /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
  8617. * last good saved one */
  8618. if (GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz, NO_USER_CHECK) > 0) {
  8619. #ifndef NO_RSA
  8620. /* found ktri */
  8621. #ifndef NO_PKCS7_STREAM
  8622. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8623. break;
  8624. }
  8625. #endif
  8626. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI);
  8627. ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
  8628. decryptedKey, decryptedKeySz,
  8629. recipFound);
  8630. if (ret != 0)
  8631. return ret;
  8632. #else
  8633. return NOT_COMPILED_IN;
  8634. #endif
  8635. }
  8636. else {
  8637. word32 localIdx;
  8638. /* kari is IMPLICIT[1] */
  8639. *idx = savedIdx;
  8640. localIdx = *idx;
  8641. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {
  8642. /* no room for recipient info */
  8643. break;
  8644. }
  8645. if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  8646. (*idx)++;
  8647. if (GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
  8648. NO_USER_CHECK) < 0)
  8649. return ASN_PARSE_E;
  8650. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8651. *idx = savedIdx;
  8652. break;
  8653. }
  8654. if (version != 3)
  8655. return ASN_VERSION_E;
  8656. /* found kari */
  8657. #ifndef NO_PKCS7_STREAM
  8658. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8659. break;
  8660. }
  8661. #endif
  8662. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KARI);
  8663. ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
  8664. decryptedKey, decryptedKeySz,
  8665. recipFound);
  8666. if (ret != 0)
  8667. return ret;
  8668. /* kekri is IMPLICIT[2] */
  8669. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {
  8670. (*idx)++;
  8671. if (GetLength_ex(pkiMsg, idx, &version, pkiMsgSz,
  8672. NO_USER_CHECK) < 0)
  8673. return ASN_PARSE_E;
  8674. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8675. *idx = savedIdx;
  8676. break;
  8677. }
  8678. if (version != 4)
  8679. return ASN_VERSION_E;
  8680. /* found kekri */
  8681. #ifndef NO_PKCS7_STREAM
  8682. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8683. break;
  8684. }
  8685. #endif
  8686. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KEKRI);
  8687. ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
  8688. decryptedKey, decryptedKeySz,
  8689. recipFound);
  8690. if (ret != 0)
  8691. return ret;
  8692. /* pwri is IMPLICIT[3] */
  8693. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {
  8694. #if !defined(NO_PWDBASED) && !defined(NO_SHA)
  8695. (*idx)++;
  8696. if (GetLength_ex(pkiMsg, idx, &version, pkiMsgSz,
  8697. NO_USER_CHECK) < 0)
  8698. return ASN_PARSE_E;
  8699. if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
  8700. *idx = savedIdx;
  8701. break;
  8702. }
  8703. if (version != 0)
  8704. return ASN_VERSION_E;
  8705. /* found pwri */
  8706. #ifndef NO_PKCS7_STREAM
  8707. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8708. break;
  8709. }
  8710. #endif
  8711. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_PWRI);
  8712. ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
  8713. decryptedKey, decryptedKeySz,
  8714. recipFound);
  8715. if (ret != 0)
  8716. return ret;
  8717. #else
  8718. return NOT_COMPILED_IN;
  8719. #endif
  8720. /* ori is IMPLICIT[4] */
  8721. } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {
  8722. (*idx)++;
  8723. /* found ori */
  8724. #ifndef NO_PKCS7_STREAM
  8725. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8726. break;
  8727. }
  8728. #endif
  8729. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_ORI);
  8730. ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
  8731. decryptedKey, decryptedKeySz,
  8732. recipFound);
  8733. if (ret != 0)
  8734. return ret;
  8735. } else {
  8736. /* failed to find RecipientInfo, restore idx and continue */
  8737. *idx = savedIdx;
  8738. break;
  8739. }
  8740. }
  8741. /* update good idx */
  8742. savedIdx = *idx;
  8743. }
  8744. return ret;
  8745. }
  8746. /* Parse encoded EnvelopedData bundle up to RecipientInfo set.
  8747. *
  8748. * return size of RecipientInfo SET on success, negative upon error */
  8749. static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
  8750. word32 inSz, word32* idx,
  8751. int type)
  8752. {
  8753. int version = 0, length, ret = 0;
  8754. word32 contentType;
  8755. byte* pkiMsg = in;
  8756. word32 pkiMsgSz = inSz;
  8757. byte tag;
  8758. #ifndef NO_PKCS7_STREAM
  8759. word32 tmpIdx = 0;
  8760. #endif
  8761. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 || idx == NULL)
  8762. return BAD_FUNC_ARG;
  8763. if ((type != ENVELOPED_DATA) && (type != AUTH_ENVELOPED_DATA) &&
  8764. pkcs7->contentOID != FIRMWARE_PKG_DATA
  8765. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  8766. && pkcs7->contentOID != COMPRESSED_DATA
  8767. #endif
  8768. )
  8769. return BAD_FUNC_ARG;
  8770. #ifndef NO_PKCS7_STREAM
  8771. if (pkcs7->stream == NULL) {
  8772. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  8773. return ret;
  8774. }
  8775. }
  8776. #endif
  8777. switch (pkcs7->state) {
  8778. case WC_PKCS7_INFOSET_START:
  8779. case WC_PKCS7_INFOSET_BER:
  8780. case WC_PKCS7_INFOSET_STAGE1:
  8781. case WC_PKCS7_INFOSET_STAGE2:
  8782. case WC_PKCS7_INFOSET_END:
  8783. break;
  8784. default:
  8785. WOLFSSL_MSG("Warning, setting PKCS7 info state to start");
  8786. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_START);
  8787. }
  8788. switch (pkcs7->state) {
  8789. case WC_PKCS7_INFOSET_START:
  8790. #ifndef NO_PKCS7_STREAM
  8791. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  8792. ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  8793. return ret;
  8794. }
  8795. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  8796. break;
  8797. }
  8798. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8799. #endif
  8800. /* read past ContentInfo, verify type is envelopedData */
  8801. if (ret == 0 && GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz,
  8802. NO_USER_CHECK) < 0)
  8803. {
  8804. ret = ASN_PARSE_E;
  8805. }
  8806. if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) {
  8807. #ifdef ASN_BER_TO_DER
  8808. word32 len;
  8809. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER);
  8810. FALL_THROUGH;
  8811. /* full buffer is needed for conversion */
  8812. case WC_PKCS7_INFOSET_BER:
  8813. #ifndef NO_PKCS7_STREAM
  8814. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8815. pkcs7->stream->maxLen - pkcs7->stream->length,
  8816. &pkiMsg, idx)) != 0) {
  8817. return ret;
  8818. }
  8819. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
  8820. inSz;
  8821. #endif
  8822. len = 0;
  8823. ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
  8824. if (ret != LENGTH_ONLY_E)
  8825. return ret;
  8826. pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8827. if (pkcs7->der == NULL)
  8828. return MEMORY_E;
  8829. ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
  8830. if (ret < 0)
  8831. return ret;
  8832. pkiMsg = in = pkcs7->der;
  8833. pkiMsgSz = pkcs7->derSz = inSz = len;
  8834. *idx = 0;
  8835. if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
  8836. return ASN_PARSE_E;
  8837. #else
  8838. return BER_INDEF_E;
  8839. #endif
  8840. }
  8841. #ifndef NO_PKCS7_STREAM
  8842. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8843. break;
  8844. }
  8845. #endif
  8846. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE1);
  8847. FALL_THROUGH;
  8848. case WC_PKCS7_INFOSET_STAGE1:
  8849. #ifndef NO_PKCS7_STREAM
  8850. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +
  8851. MAX_LENGTH_SZ + ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
  8852. return ret;
  8853. }
  8854. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
  8855. #endif
  8856. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  8857. type == AUTH_ENVELOPED_DATA) {
  8858. if (ret == 0 && wc_GetContentType(pkiMsg, idx, &contentType,
  8859. pkiMsgSz) < 0)
  8860. ret = ASN_PARSE_E;
  8861. if (ret == 0) {
  8862. if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) {
  8863. WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
  8864. ret = PKCS7_OID_E;
  8865. } else if (type == AUTH_ENVELOPED_DATA &&
  8866. contentType != AUTH_ENVELOPED_DATA) {
  8867. WOLFSSL_MSG("PKCS#7 input not of type AuthEnvelopedData");
  8868. ret = PKCS7_OID_E;
  8869. }
  8870. }
  8871. if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)
  8872. ret = ASN_PARSE_E;
  8873. if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
  8874. | 0))
  8875. ret = ASN_PARSE_E;
  8876. if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
  8877. NO_USER_CHECK) < 0)
  8878. ret = ASN_PARSE_E;
  8879. }
  8880. if (ret < 0)
  8881. break;
  8882. #ifndef NO_PKCS7_STREAM
  8883. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8884. break;
  8885. }
  8886. #endif
  8887. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE2);
  8888. FALL_THROUGH;
  8889. case WC_PKCS7_INFOSET_STAGE2:
  8890. #ifndef NO_PKCS7_STREAM
  8891. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  8892. MAX_VERSION_SZ, &pkiMsg, idx)) != 0) {
  8893. return ret;
  8894. }
  8895. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8896. #endif
  8897. /* remove EnvelopedData and version */
  8898. if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
  8899. type == AUTH_ENVELOPED_DATA) {
  8900. if (ret == 0 && GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz,
  8901. NO_USER_CHECK) < 0)
  8902. ret = ASN_PARSE_E;
  8903. }
  8904. if (ret == 0 && GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
  8905. ret = ASN_PARSE_E;
  8906. if (ret < 0)
  8907. break;
  8908. #ifndef NO_PKCS7_STREAM
  8909. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8910. break;
  8911. }
  8912. pkcs7->stream->varOne = version;
  8913. #endif
  8914. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_END);
  8915. FALL_THROUGH;
  8916. case WC_PKCS7_INFOSET_END:
  8917. #ifndef NO_PKCS7_STREAM
  8918. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  8919. MAX_SET_SZ, &pkiMsg, idx)) != 0) {
  8920. return ret;
  8921. }
  8922. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  8923. version = pkcs7->stream->varOne;
  8924. #endif
  8925. if (type == ENVELOPED_DATA) {
  8926. /* TODO :: make this more accurate */
  8927. if ((pkcs7->publicKeyOID == RSAk &&
  8928. (version != 0 && version != 2))
  8929. #ifdef HAVE_ECC
  8930. || (pkcs7->publicKeyOID == ECDSAk &&
  8931. (version != 0 && version != 2 && version != 3))
  8932. #endif
  8933. ) {
  8934. WOLFSSL_MSG("PKCS#7 envelopedData version incorrect");
  8935. ret = ASN_VERSION_E;
  8936. }
  8937. } else {
  8938. /* AuthEnvelopedData version MUST be 0 */
  8939. if (version != 0) {
  8940. WOLFSSL_MSG("PKCS#7 AuthEnvelopedData needs to be of version 0");
  8941. ret = ASN_VERSION_E;
  8942. }
  8943. }
  8944. /* remove RecipientInfo set, get length of set */
  8945. if (ret == 0 && GetSet_ex(pkiMsg, idx, &length, pkiMsgSz,
  8946. NO_USER_CHECK) < 0)
  8947. ret = ASN_PARSE_E;
  8948. if (ret < 0)
  8949. break;
  8950. #ifndef NO_PKCS7_STREAM
  8951. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
  8952. break;
  8953. }
  8954. #endif
  8955. if (ret == 0)
  8956. ret = length;
  8957. break;
  8958. default:
  8959. WOLFSSL_MSG("Bad PKCS7 info set state");
  8960. ret = BAD_FUNC_ARG;
  8961. break;
  8962. }
  8963. return ret;
  8964. }
  8965. /* Import secret/private key into a PKCS7 structure. Used for setting
  8966. * the secret key for decryption a EnvelopedData KEKRI RecipientInfo.
  8967. *
  8968. * Returns 0 on success, negative upon error */
  8969. WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz)
  8970. {
  8971. if (pkcs7 == NULL || key == NULL || keySz == 0)
  8972. return BAD_FUNC_ARG;
  8973. pkcs7->privateKey = key;
  8974. pkcs7->privateKeySz = keySz;
  8975. return 0;
  8976. }
  8977. /* append data to encrypted content cache in PKCS7 structure
  8978. * return 0 on success, negative on error */
  8979. static int PKCS7_CacheEncryptedContent(PKCS7* pkcs7, byte* in, word32 inSz)
  8980. {
  8981. byte* oldCache;
  8982. word32 oldCacheSz;
  8983. if (pkcs7 == NULL || in == NULL)
  8984. return BAD_FUNC_ARG;
  8985. /* save pointer to old cache */
  8986. oldCache = pkcs7->cachedEncryptedContent;
  8987. oldCacheSz = pkcs7->cachedEncryptedContentSz;
  8988. /* re-allocate new buffer to fit appended data */
  8989. pkcs7->cachedEncryptedContent = (byte*)XMALLOC(oldCacheSz + inSz,
  8990. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8991. if (pkcs7->cachedEncryptedContent == NULL) {
  8992. pkcs7->cachedEncryptedContentSz = 0;
  8993. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  8994. return MEMORY_E;
  8995. }
  8996. if (oldCache != NULL) {
  8997. XMEMCPY(pkcs7->cachedEncryptedContent, oldCache, oldCacheSz);
  8998. }
  8999. XMEMCPY(pkcs7->cachedEncryptedContent + oldCacheSz, in, inSz);
  9000. pkcs7->cachedEncryptedContentSz += inSz;
  9001. XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9002. return 0;
  9003. }
  9004. /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
  9005. WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
  9006. word32 inSz, byte* output,
  9007. word32 outputSz)
  9008. {
  9009. int recipFound = 0;
  9010. int ret, length = 0;
  9011. word32 idx = 0;
  9012. #ifndef NO_PKCS7_STREAM
  9013. word32 tmpIdx = 0;
  9014. #endif
  9015. word32 contentType = 0, encOID = 0;
  9016. word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9017. int expBlockSz = 0, blockKeySz = 0;
  9018. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  9019. byte* tmpIv = tmpIvBuf;
  9020. byte* pkiMsg = in;
  9021. word32 pkiMsgSz = inSz;
  9022. byte* decryptedKey = NULL;
  9023. int encryptedContentTotalSz = 0;
  9024. int encryptedContentSz = 0;
  9025. byte padLen;
  9026. byte* encryptedContent = NULL;
  9027. int explicitOctet = 0;
  9028. word32 localIdx;
  9029. byte tag;
  9030. if (pkcs7 == NULL)
  9031. return BAD_FUNC_ARG;
  9032. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  9033. output == NULL || outputSz == 0)
  9034. return BAD_FUNC_ARG;
  9035. #ifndef NO_PKCS7_STREAM
  9036. (void)tmpIv; /* help out static analysis */
  9037. if (pkcs7->stream == NULL) {
  9038. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  9039. return ret;
  9040. }
  9041. }
  9042. #endif
  9043. switch (pkcs7->state) {
  9044. case WC_PKCS7_START:
  9045. case WC_PKCS7_INFOSET_START:
  9046. case WC_PKCS7_INFOSET_BER:
  9047. case WC_PKCS7_INFOSET_STAGE1:
  9048. case WC_PKCS7_INFOSET_STAGE2:
  9049. case WC_PKCS7_INFOSET_END:
  9050. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  9051. &idx, ENVELOPED_DATA);
  9052. if (ret < 0) {
  9053. break;
  9054. }
  9055. #ifdef ASN_BER_TO_DER
  9056. /* check if content was BER and has been converted to DER */
  9057. if (pkcs7->derSz > 0) {
  9058. pkiMsg = in = pkcs7->der;
  9059. inSz = pkcs7->derSz;
  9060. #ifdef NO_PKCS7_STREAM
  9061. pkiMsgSz = pkcs7->derSz;
  9062. #endif
  9063. }
  9064. #endif
  9065. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  9066. DYNAMIC_TYPE_PKCS7);
  9067. if (decryptedKey == NULL)
  9068. return MEMORY_E;
  9069. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);
  9070. #ifndef NO_PKCS7_STREAM
  9071. tmpIdx = idx;
  9072. pkcs7->stream->aad = decryptedKey;
  9073. #endif
  9074. FALL_THROUGH;
  9075. case WC_PKCS7_ENV_2:
  9076. #ifndef NO_PKCS7_STREAM
  9077. /* store up enough buffer for initial info set decode */
  9078. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9079. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  9080. return ret;
  9081. }
  9082. #endif
  9083. FALL_THROUGH;
  9084. case WC_PKCS7_DECRYPT_KTRI:
  9085. case WC_PKCS7_DECRYPT_KTRI_2:
  9086. case WC_PKCS7_DECRYPT_KTRI_3:
  9087. case WC_PKCS7_DECRYPT_KARI:
  9088. case WC_PKCS7_DECRYPT_KEKRI:
  9089. case WC_PKCS7_DECRYPT_PWRI:
  9090. case WC_PKCS7_DECRYPT_ORI:
  9091. #ifndef NO_PKCS7_STREAM
  9092. decryptedKey = pkcs7->stream->aad;
  9093. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9094. #endif
  9095. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  9096. decryptedKey, &decryptedKeySz,
  9097. &recipFound);
  9098. if (ret == 0 && recipFound == 0) {
  9099. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  9100. ret = PKCS7_RECIP_E;
  9101. }
  9102. if (ret != 0)
  9103. break;
  9104. #ifndef NO_PKCS7_STREAM
  9105. tmpIdx = idx;
  9106. pkcs7->stream->aadSz = decryptedKeySz;
  9107. #endif
  9108. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
  9109. FALL_THROUGH;
  9110. case WC_PKCS7_ENV_3:
  9111. #ifndef NO_PKCS7_STREAM
  9112. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9113. MAX_VERSION_SZ + ASN_TAG_SZ +
  9114. MAX_LENGTH_SZ, &pkiMsg, &idx))
  9115. != 0) {
  9116. return ret;
  9117. }
  9118. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9119. #else
  9120. ret = 0;
  9121. #endif
  9122. /* remove EncryptedContentInfo */
  9123. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  9124. NO_USER_CHECK) < 0) {
  9125. ret = ASN_PARSE_E;
  9126. }
  9127. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  9128. pkiMsgSz) < 0) {
  9129. ret = ASN_PARSE_E;
  9130. }
  9131. if (ret == 0) {
  9132. pkcs7->contentOID = contentType;
  9133. }
  9134. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  9135. pkiMsgSz) < 0) {
  9136. ret = ASN_PARSE_E;
  9137. }
  9138. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  9139. if (ret == 0 && blockKeySz < 0) {
  9140. ret = blockKeySz;
  9141. }
  9142. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  9143. if (ret == 0 && expBlockSz < 0) {
  9144. ret = expBlockSz;
  9145. }
  9146. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  9147. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {
  9148. ret = ASN_PARSE_E;
  9149. }
  9150. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9151. ret = ASN_PARSE_E;
  9152. }
  9153. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz,
  9154. NO_USER_CHECK) < 0) {
  9155. ret = ASN_PARSE_E;
  9156. }
  9157. if (ret == 0 && length != expBlockSz) {
  9158. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  9159. ret = ASN_PARSE_E;
  9160. }
  9161. if (ret != 0)
  9162. break;
  9163. #ifndef NO_PKCS7_STREAM
  9164. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9165. break;
  9166. }
  9167. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length);
  9168. pkcs7->stream->contentSz = blockKeySz;
  9169. pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ +
  9170. ASN_TAG_SZ + ASN_TAG_SZ;
  9171. #endif
  9172. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4);
  9173. FALL_THROUGH;
  9174. case WC_PKCS7_ENV_4:
  9175. #ifndef NO_PKCS7_STREAM
  9176. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9177. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9178. return ret;
  9179. }
  9180. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9181. wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length);
  9182. tmpIv = pkcs7->stream->tmpIv;
  9183. if (tmpIv == NULL) {
  9184. /* check added to help out static analysis tool */
  9185. ret = MEMORY_E;
  9186. break;
  9187. }
  9188. #else
  9189. ret = 0;
  9190. #endif
  9191. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  9192. idx += length;
  9193. explicitOctet = 0;
  9194. localIdx = idx;
  9195. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  9196. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9197. explicitOctet = 1;
  9198. }
  9199. /* read encryptedContent, cont[0] */
  9200. if (tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  9201. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9202. ret = ASN_PARSE_E;
  9203. }
  9204. idx++;
  9205. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz,
  9206. pkiMsgSz) <= 0) {
  9207. ret = ASN_PARSE_E;
  9208. }
  9209. if (ret != 0)
  9210. break;
  9211. #ifndef NO_PKCS7_STREAM
  9212. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9213. break;
  9214. }
  9215. pkcs7->stream->expected = encryptedContentTotalSz;
  9216. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0);
  9217. wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet);
  9218. #endif
  9219. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5);
  9220. FALL_THROUGH;
  9221. case WC_PKCS7_ENV_5:
  9222. #ifndef NO_PKCS7_STREAM
  9223. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  9224. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  9225. return ret;
  9226. }
  9227. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet);
  9228. tmpIv = pkcs7->stream->tmpIv;
  9229. encryptedContentTotalSz = pkcs7->stream->expected;
  9230. /* restore decrypted key */
  9231. decryptedKey = pkcs7->stream->aad;
  9232. decryptedKeySz = pkcs7->stream->aadSz;
  9233. blockKeySz = pkcs7->stream->contentSz;
  9234. #else
  9235. ret = 0;
  9236. #endif
  9237. if (explicitOctet) {
  9238. /* encrypted content may be fragmented into multiple
  9239. * consecutive OCTET STRINGs, if so loop through
  9240. * collecting and caching encrypted content bytes */
  9241. localIdx = idx;
  9242. while (idx < (localIdx + encryptedContentTotalSz)) {
  9243. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9244. ret = ASN_PARSE_E;
  9245. }
  9246. if (ret == 0 && (tag != ASN_OCTET_STRING)) {
  9247. ret = ASN_PARSE_E;
  9248. }
  9249. if (ret == 0 && GetLength(pkiMsg, &idx,
  9250. &encryptedContentSz, pkiMsgSz) <= 0) {
  9251. ret = ASN_PARSE_E;
  9252. }
  9253. if (ret == 0) {
  9254. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  9255. encryptedContentSz);
  9256. }
  9257. if (ret != 0) {
  9258. break;
  9259. }
  9260. /* advance idx past encrypted content */
  9261. idx += encryptedContentSz;
  9262. }
  9263. if (ret != 0) {
  9264. break;
  9265. }
  9266. } else {
  9267. /* cache encrypted content, no OCTET STRING */
  9268. ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
  9269. encryptedContentTotalSz);
  9270. if (ret != 0) {
  9271. break;
  9272. }
  9273. idx += encryptedContentTotalSz;
  9274. }
  9275. /* use cached content */
  9276. encryptedContent = pkcs7->cachedEncryptedContent;
  9277. encryptedContentSz = pkcs7->cachedEncryptedContentSz;
  9278. /* decrypt encryptedContent */
  9279. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  9280. blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,
  9281. encryptedContent, encryptedContentSz, encryptedContent);
  9282. if (ret != 0) {
  9283. break;
  9284. }
  9285. padLen = encryptedContent[encryptedContentSz-1];
  9286. /* copy plaintext to output */
  9287. if (padLen > encryptedContentSz ||
  9288. (word32)(encryptedContentSz - padLen) > outputSz) {
  9289. ret = BUFFER_E;
  9290. break;
  9291. }
  9292. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  9293. /* free memory, zero out keys */
  9294. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9295. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9296. if (pkcs7->cachedEncryptedContent != NULL) {
  9297. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  9298. DYNAMIC_TYPE_PKCS7);
  9299. pkcs7->cachedEncryptedContent = NULL;
  9300. pkcs7->cachedEncryptedContentSz = 0;
  9301. }
  9302. ret = encryptedContentSz - padLen;
  9303. #ifndef NO_PKCS7_STREAM
  9304. pkcs7->stream->aad = NULL;
  9305. pkcs7->stream->aadSz = 0;
  9306. wc_PKCS7_ResetStream(pkcs7);
  9307. #endif
  9308. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  9309. break;
  9310. default:
  9311. WOLFSSL_MSG("PKCS#7 unknown decode enveloped state");
  9312. ret = BAD_FUNC_ARG;
  9313. }
  9314. #ifndef NO_PKCS7_STREAM
  9315. if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {
  9316. wc_PKCS7_ResetStream(pkcs7);
  9317. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  9318. if (pkcs7->cachedEncryptedContent != NULL) {
  9319. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
  9320. DYNAMIC_TYPE_PKCS7);
  9321. pkcs7->cachedEncryptedContent = NULL;
  9322. pkcs7->cachedEncryptedContentSz = 0;
  9323. }
  9324. }
  9325. #else
  9326. if (decryptedKey != NULL && ret < 0) {
  9327. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  9328. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9329. }
  9330. if (pkcs7->cachedEncryptedContent != NULL && ret < 0) {
  9331. XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9332. pkcs7->cachedEncryptedContent = NULL;
  9333. pkcs7->cachedEncryptedContentSz = 0;
  9334. }
  9335. #endif
  9336. return ret;
  9337. }
  9338. /* build PKCS#7 authEnvelopedData content type, return enveloped size */
  9339. int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
  9340. word32 outputSz)
  9341. {
  9342. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  9343. int ret, idx = 0;
  9344. int totalSz, encryptedOutSz;
  9345. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  9346. byte contentInfoSeq[MAX_SEQ_SZ];
  9347. byte outerContentType[MAX_ALGO_SZ];
  9348. byte outerContent[MAX_SEQ_SZ];
  9349. int envDataSeqSz, verSz;
  9350. byte envDataSeq[MAX_SEQ_SZ];
  9351. byte ver[MAX_VERSION_SZ];
  9352. WC_RNG rng;
  9353. int blockSz, blockKeySz;
  9354. byte* encryptedContent;
  9355. Pkcs7EncodedRecip* tmpRecip = NULL;
  9356. int recipSz, recipSetSz;
  9357. byte recipSet[MAX_SET_SZ];
  9358. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  9359. int contentEncAlgoSz, nonceOctetStringSz, macOctetStringSz;
  9360. byte encContentSeq[MAX_SEQ_SZ];
  9361. byte contentType[MAX_ALGO_SZ];
  9362. byte contentEncAlgo[MAX_ALGO_SZ];
  9363. byte nonceOctetString[MAX_OCTET_STR_SZ];
  9364. byte encContentOctet[MAX_OCTET_STR_SZ];
  9365. byte macOctetString[MAX_OCTET_STR_SZ];
  9366. byte authTag[AES_BLOCK_SIZE];
  9367. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  9368. byte macInt[MAX_VERSION_SZ];
  9369. word32 nonceSz = 0, macIntSz = 0;
  9370. /* authAttribs */
  9371. byte* flatAuthAttribs = NULL;
  9372. byte authAttribSet[MAX_SET_SZ];
  9373. EncodedAttrib authAttribs[MAX_AUTH_ATTRIBS_SZ];
  9374. word32 authAttribsSz = 0, authAttribsCount = 0;
  9375. word32 authAttribsSetSz = 0;
  9376. byte* aadBuffer = NULL;
  9377. word32 aadBufferSz = 0;
  9378. byte authAttribAadSet[MAX_SET_SZ];
  9379. word32 authAttribsAadSetSz = 0;
  9380. /* unauthAttribs */
  9381. byte* flatUnauthAttribs = NULL;
  9382. byte unauthAttribSet[MAX_SET_SZ];
  9383. EncodedAttrib unauthAttribs[MAX_UNAUTH_ATTRIBS_SZ];
  9384. word32 unauthAttribsSz = 0, unauthAttribsCount = 0;
  9385. word32 unauthAttribsSetSz = 0;
  9386. PKCS7Attrib contentTypeAttrib;
  9387. byte contentTypeValue[MAX_OID_SZ];
  9388. /* contentType OID (1.2.840.113549.1.9.3) */
  9389. const byte contentTypeOid[] =
  9390. { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
  9391. 0x09, 0x03 };
  9392. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
  9393. return BAD_FUNC_ARG;
  9394. if (output == NULL || outputSz == 0)
  9395. return BAD_FUNC_ARG;
  9396. switch (pkcs7->encryptOID) {
  9397. #ifdef HAVE_AESGCM
  9398. #ifdef WOLFSSL_AES_128
  9399. case AES128GCMb:
  9400. break;
  9401. #endif
  9402. #ifdef WOLFSSL_AES_192
  9403. case AES192GCMb:
  9404. break;
  9405. #endif
  9406. #ifdef WOLFSSL_AES_256
  9407. case AES256GCMb:
  9408. break;
  9409. #endif
  9410. #endif
  9411. #ifdef HAVE_AESCCM
  9412. #ifdef WOLFSSL_AES_128
  9413. case AES128CCMb:
  9414. break;
  9415. #endif
  9416. #ifdef WOLFSSL_AES_192
  9417. case AES192CCMb:
  9418. break;
  9419. #endif
  9420. #ifdef WOLFSSL_AES_256
  9421. case AES256CCMb:
  9422. break;
  9423. #endif
  9424. #endif
  9425. default:
  9426. WOLFSSL_MSG("CMS AuthEnvelopedData must use AES-GCM or AES-CCM");
  9427. return BAD_FUNC_ARG;
  9428. }
  9429. blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
  9430. if (blockKeySz < 0)
  9431. return blockKeySz;
  9432. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  9433. if (blockSz < 0)
  9434. return blockSz;
  9435. /* outer content type */
  9436. ret = wc_SetContentType(AUTH_ENVELOPED_DATA, outerContentType,
  9437. sizeof(outerContentType));
  9438. if (ret < 0)
  9439. return ret;
  9440. outerContentTypeSz = ret;
  9441. /* version, defined as 0 in RFC 5083 */
  9442. verSz = SetMyVersion(0, ver, 0);
  9443. /* generate random content encryption key */
  9444. ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
  9445. if (ret != 0) {
  9446. return ret;
  9447. }
  9448. /* build RecipientInfo, only if user manually set singleCert and size */
  9449. if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
  9450. switch (pkcs7->publicKeyOID) {
  9451. #ifndef NO_RSA
  9452. case RSAk:
  9453. ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
  9454. pkcs7->singleCertSz, 0);
  9455. break;
  9456. #endif
  9457. #ifdef HAVE_ECC
  9458. case ECDSAk:
  9459. ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
  9460. pkcs7->singleCertSz,
  9461. pkcs7->keyWrapOID,
  9462. pkcs7->keyAgreeOID, pkcs7->ukm,
  9463. pkcs7->ukmSz, 0);
  9464. break;
  9465. #endif
  9466. default:
  9467. WOLFSSL_MSG("Unsupported RecipientInfo public key type");
  9468. return BAD_FUNC_ARG;
  9469. };
  9470. if (ret < 0) {
  9471. WOLFSSL_MSG("Failed to create RecipientInfo");
  9472. return ret;
  9473. }
  9474. }
  9475. recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
  9476. if (recipSz < 0) {
  9477. return ret;
  9478. } else if (recipSz == 0) {
  9479. WOLFSSL_MSG("You must add at least one CMS recipient");
  9480. return PKCS7_RECIP_E;
  9481. }
  9482. recipSetSz = SetSet(recipSz, recipSet);
  9483. /* generate random nonce and IV for encryption */
  9484. switch (pkcs7->encryptOID) {
  9485. #ifdef HAVE_AESGCM
  9486. #ifdef WOLFSSL_AES_128
  9487. case AES128GCMb:
  9488. FALL_THROUGH;
  9489. #endif
  9490. #ifdef WOLFSSL_AES_192
  9491. case AES192GCMb:
  9492. FALL_THROUGH;
  9493. #endif
  9494. #ifdef WOLFSSL_AES_256
  9495. case AES256GCMb:
  9496. #endif
  9497. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  9498. defined(WOLFSSL_AES_256)
  9499. /* GCM nonce is GCM_NONCE_MID_SZ (12) */
  9500. nonceSz = GCM_NONCE_MID_SZ;
  9501. break;
  9502. #endif
  9503. #endif /* HAVE_AESGCM */
  9504. #ifdef HAVE_AESCCM
  9505. #ifdef WOLFSSL_AES_128
  9506. case AES128CCMb:
  9507. FALL_THROUGH;
  9508. #endif
  9509. #ifdef WOLFSSL_AES_192
  9510. case AES192CCMb:
  9511. FALL_THROUGH;
  9512. #endif
  9513. #ifdef WOLFSSL_AES_256
  9514. case AES256CCMb:
  9515. #endif
  9516. #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
  9517. defined(WOLFSSL_AES_256)
  9518. /* CCM nonce is CCM_NONCE_MIN_SZ (7) */
  9519. nonceSz = CCM_NONCE_MIN_SZ;
  9520. break;
  9521. #endif
  9522. #endif /* HAVE_AESCCM */
  9523. }
  9524. ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
  9525. if (ret != 0) {
  9526. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9527. return ret;
  9528. }
  9529. ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, nonce, nonceSz);
  9530. wc_FreeRng(&rng);
  9531. if (ret != 0) {
  9532. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9533. return ret;
  9534. }
  9535. /* authAttribs: add contentType attrib if needed */
  9536. if (pkcs7->contentOID != DATA) {
  9537. XMEMSET(&contentTypeAttrib, 0, sizeof contentTypeAttrib);
  9538. /* if type is not id-data, contentType attribute MUST be added */
  9539. contentTypeAttrib.oid = contentTypeOid;
  9540. contentTypeAttrib.oidSz = sizeof(contentTypeOid);
  9541. /* try to set from contentOID first, known types */
  9542. ret = wc_SetContentType(pkcs7->contentOID, contentTypeValue,
  9543. sizeof(contentTypeValue));
  9544. if (ret > 0) {
  9545. contentTypeAttrib.value = contentTypeValue;
  9546. contentTypeAttrib.valueSz = ret;
  9547. /* otherwise, try to set from custom content type */
  9548. } else {
  9549. if (pkcs7->contentTypeSz == 0) {
  9550. WOLFSSL_MSG("CMS pkcs7->contentType must be set if "
  9551. "contentOID is not");
  9552. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9553. return BAD_FUNC_ARG;
  9554. }
  9555. contentTypeAttrib.value = pkcs7->contentType;
  9556. contentTypeAttrib.valueSz = pkcs7->contentTypeSz;
  9557. }
  9558. authAttribsSz += EncodeAttributes(authAttribs, 1,
  9559. &contentTypeAttrib, 1);
  9560. authAttribsCount += 1;
  9561. }
  9562. /* authAttribs: add in user authenticated attributes */
  9563. if (pkcs7->authAttribs != NULL && pkcs7->authAttribsSz > 0) {
  9564. authAttribsSz += EncodeAttributes(authAttribs + authAttribsCount,
  9565. MAX_AUTH_ATTRIBS_SZ - authAttribsCount,
  9566. pkcs7->authAttribs,
  9567. pkcs7->authAttribsSz);
  9568. authAttribsCount += pkcs7->authAttribsSz;
  9569. }
  9570. /* authAttribs: flatten authAttribs */
  9571. if (authAttribsSz > 0 && authAttribsCount > 0) {
  9572. flatAuthAttribs = (byte*)XMALLOC(authAttribsSz, pkcs7->heap,
  9573. DYNAMIC_TYPE_PKCS7);
  9574. if (flatAuthAttribs == NULL) {
  9575. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9576. return MEMORY_E;
  9577. }
  9578. FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,
  9579. authAttribsCount);
  9580. authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,
  9581. authAttribSet);
  9582. /* From RFC5083, "For the purpose of constructing the AAD, the
  9583. * IMPLICIT [1] tag in the authAttrs field is not used for the
  9584. * DER encoding: rather a universal SET OF tag is used. */
  9585. authAttribsAadSetSz = SetSet(authAttribsSz, authAttribAadSet);
  9586. /* allocate temp buffer to hold alternate attrib encoding for aad */
  9587. aadBuffer = (byte*)XMALLOC(authAttribsSz + authAttribsAadSetSz,
  9588. pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9589. if (aadBuffer == NULL) {
  9590. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9591. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9592. return MEMORY_E;
  9593. }
  9594. /* build up alternate attrib encoding for aad */
  9595. aadBufferSz = 0;
  9596. XMEMCPY(aadBuffer + aadBufferSz, authAttribAadSet, authAttribsAadSetSz);
  9597. aadBufferSz += authAttribsAadSetSz;
  9598. XMEMCPY(aadBuffer + aadBufferSz, flatAuthAttribs, authAttribsSz);
  9599. aadBufferSz += authAttribsSz;
  9600. }
  9601. /* build up unauthenticated attributes (unauthAttrs) */
  9602. if (pkcs7->unauthAttribsSz > 0) {
  9603. unauthAttribsSz = EncodeAttributes(unauthAttribs + unauthAttribsCount,
  9604. MAX_UNAUTH_ATTRIBS_SZ - unauthAttribsCount,
  9605. pkcs7->unauthAttribs,
  9606. pkcs7->unauthAttribsSz);
  9607. unauthAttribsCount = pkcs7->unauthAttribsSz;
  9608. flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap,
  9609. DYNAMIC_TYPE_PKCS7);
  9610. if (flatUnauthAttribs == NULL) {
  9611. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9612. if (aadBuffer)
  9613. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9614. if (flatAuthAttribs)
  9615. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9616. return MEMORY_E;
  9617. }
  9618. FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,
  9619. unauthAttribsCount);
  9620. unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,
  9621. unauthAttribSet);
  9622. }
  9623. /* allocate encrypted content buffer */
  9624. encryptedOutSz = pkcs7->contentSz;
  9625. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  9626. DYNAMIC_TYPE_PKCS7);
  9627. if (encryptedContent == NULL) {
  9628. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9629. if (aadBuffer)
  9630. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9631. if (flatUnauthAttribs)
  9632. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9633. if (flatAuthAttribs)
  9634. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9635. return MEMORY_E;
  9636. }
  9637. /* encrypt content */
  9638. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
  9639. pkcs7->cekSz, nonce, nonceSz, aadBuffer, aadBufferSz, authTag,
  9640. sizeof(authTag), pkcs7->content, encryptedOutSz, encryptedContent);
  9641. if (aadBuffer) {
  9642. XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
  9643. aadBuffer = NULL;
  9644. }
  9645. if (ret != 0) {
  9646. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9647. if (flatUnauthAttribs)
  9648. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9649. if (flatAuthAttribs)
  9650. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9651. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9652. return ret;
  9653. }
  9654. /* EncryptedContentInfo */
  9655. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  9656. sizeof(contentType));
  9657. if (ret < 0) {
  9658. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9659. if (flatUnauthAttribs)
  9660. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9661. if (flatAuthAttribs)
  9662. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9663. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9664. return ret;
  9665. }
  9666. contentTypeSz = ret;
  9667. /* put together nonce OCTET STRING */
  9668. nonceOctetStringSz = SetOctetString(nonceSz, nonceOctetString);
  9669. /* put together aes-ICVlen INTEGER */
  9670. macIntSz = SetMyVersion(sizeof(authTag), macInt, 0);
  9671. /* build up our ContentEncryptionAlgorithmIdentifier sequence,
  9672. * adding (nonceOctetStringSz + blockSz + macIntSz) for nonce OCTET STRING
  9673. * and tag size */
  9674. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  9675. oidBlkType, nonceOctetStringSz + nonceSz +
  9676. macIntSz);
  9677. if (contentEncAlgoSz == 0) {
  9678. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9679. if (flatUnauthAttribs)
  9680. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9681. if (flatAuthAttribs)
  9682. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9683. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9684. return BAD_FUNC_ARG;
  9685. }
  9686. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
  9687. encContentOctet);
  9688. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  9689. nonceOctetStringSz + nonceSz + macIntSz +
  9690. encContentOctetSz + encryptedOutSz,
  9691. encContentSeq);
  9692. macOctetStringSz = SetOctetString(sizeof(authTag), macOctetString);
  9693. /* keep track of sizes for outer wrapper layering */
  9694. totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
  9695. contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz +
  9696. encContentOctetSz + encryptedOutSz + authAttribsSz +
  9697. authAttribsSetSz + macOctetStringSz + sizeof(authTag) +
  9698. unauthAttribsSz + unauthAttribsSetSz;
  9699. /* EnvelopedData */
  9700. envDataSeqSz = SetSequence(totalSz, envDataSeq);
  9701. totalSz += envDataSeqSz;
  9702. /* outer content */
  9703. outerContentSz = SetExplicit(0, totalSz, outerContent);
  9704. totalSz += outerContentTypeSz;
  9705. totalSz += outerContentSz;
  9706. /* ContentInfo */
  9707. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  9708. totalSz += contentInfoSeqSz;
  9709. if (totalSz > (int)outputSz) {
  9710. WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
  9711. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9712. if (flatUnauthAttribs)
  9713. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9714. if (flatAuthAttribs)
  9715. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9716. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9717. return BUFFER_E;
  9718. }
  9719. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  9720. idx += contentInfoSeqSz;
  9721. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  9722. idx += outerContentTypeSz;
  9723. XMEMCPY(output + idx, outerContent, outerContentSz);
  9724. idx += outerContentSz;
  9725. XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
  9726. idx += envDataSeqSz;
  9727. XMEMCPY(output + idx, ver, verSz);
  9728. idx += verSz;
  9729. XMEMCPY(output + idx, recipSet, recipSetSz);
  9730. idx += recipSetSz;
  9731. /* copy in recipients from list */
  9732. tmpRecip = pkcs7->recipList;
  9733. while (tmpRecip != NULL) {
  9734. XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
  9735. idx += tmpRecip->recipSz;
  9736. tmpRecip = tmpRecip->next;
  9737. }
  9738. wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
  9739. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  9740. idx += encContentSeqSz;
  9741. XMEMCPY(output + idx, contentType, contentTypeSz);
  9742. idx += contentTypeSz;
  9743. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  9744. idx += contentEncAlgoSz;
  9745. XMEMCPY(output + idx, nonceOctetString, nonceOctetStringSz);
  9746. idx += nonceOctetStringSz;
  9747. XMEMCPY(output + idx, nonce, nonceSz);
  9748. idx += nonceSz;
  9749. XMEMCPY(output + idx, macInt, macIntSz);
  9750. idx += macIntSz;
  9751. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  9752. idx += encContentOctetSz;
  9753. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  9754. idx += encryptedOutSz;
  9755. /* authenticated attributes */
  9756. if (flatAuthAttribs && authAttribsSz > 0) {
  9757. XMEMCPY(output + idx, authAttribSet, authAttribsSetSz);
  9758. idx += authAttribsSetSz;
  9759. XMEMCPY(output + idx, flatAuthAttribs, authAttribsSz);
  9760. idx += authAttribsSz;
  9761. XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9762. }
  9763. XMEMCPY(output + idx, macOctetString, macOctetStringSz);
  9764. idx += macOctetStringSz;
  9765. XMEMCPY(output + idx, authTag, sizeof(authTag));
  9766. idx += sizeof(authTag);
  9767. /* unauthenticated attributes */
  9768. if (unauthAttribsSz > 0) {
  9769. XMEMCPY(output + idx, unauthAttribSet, unauthAttribsSetSz);
  9770. idx += unauthAttribsSetSz;
  9771. XMEMCPY(output + idx, flatUnauthAttribs, unauthAttribsSz);
  9772. idx += unauthAttribsSz;
  9773. }
  9774. if (flatUnauthAttribs != NULL) {
  9775. XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9776. }
  9777. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  9778. return idx;
  9779. #else
  9780. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  9781. (void)pkcs7;
  9782. (void)output;
  9783. (void)outputSz;
  9784. return NOT_COMPILED_IN;
  9785. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  9786. }
  9787. /* unwrap and decrypt PKCS#7 AuthEnvelopedData object, return decoded size */
  9788. WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
  9789. word32 inSz, byte* output,
  9790. word32 outputSz)
  9791. {
  9792. #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  9793. int recipFound = 0;
  9794. int ret = 0, length;
  9795. word32 idx = 0;
  9796. #ifndef NO_PKCS7_STREAM
  9797. word32 tmpIdx = 0;
  9798. #endif
  9799. word32 contentType = 0, encOID = 0;
  9800. word32 decryptedKeySz = 0;
  9801. byte* pkiMsg = in;
  9802. word32 pkiMsgSz = inSz;
  9803. int expBlockSz = 0, blockKeySz = 0;
  9804. byte authTag[AES_BLOCK_SIZE];
  9805. byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
  9806. int nonceSz = 0, authTagSz = 0, macSz = 0;
  9807. #ifdef WOLFSSL_SMALL_STACK
  9808. byte* decryptedKey = NULL;
  9809. #else
  9810. byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
  9811. #endif
  9812. int encryptedContentSz = 0;
  9813. byte* encryptedContent = NULL;
  9814. int explicitOctet = 0;
  9815. byte authAttribSetByte = 0;
  9816. byte* encodedAttribs = NULL;
  9817. word32 encodedAttribIdx = 0, encodedAttribSz = 0;
  9818. byte* authAttrib = NULL;
  9819. int authAttribSz = 0;
  9820. word32 localIdx;
  9821. byte tag;
  9822. if (pkcs7 == NULL)
  9823. return BAD_FUNC_ARG;
  9824. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  9825. output == NULL || outputSz == 0)
  9826. return BAD_FUNC_ARG;
  9827. #ifndef NO_PKCS7_STREAM
  9828. if (pkcs7->stream == NULL) {
  9829. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  9830. return ret;
  9831. }
  9832. }
  9833. #endif
  9834. switch (pkcs7->state) {
  9835. case WC_PKCS7_START:
  9836. case WC_PKCS7_INFOSET_START:
  9837. case WC_PKCS7_INFOSET_STAGE1:
  9838. case WC_PKCS7_INFOSET_STAGE2:
  9839. case WC_PKCS7_INFOSET_END:
  9840. ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
  9841. &idx, AUTH_ENVELOPED_DATA);
  9842. if (ret < 0)
  9843. break;
  9844. #ifndef NO_PKCS7_STREAM
  9845. tmpIdx = idx;
  9846. #endif
  9847. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_2);
  9848. FALL_THROUGH;
  9849. case WC_PKCS7_AUTHENV_2:
  9850. #ifndef NO_PKCS7_STREAM
  9851. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9852. MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  9853. break;
  9854. }
  9855. #endif
  9856. #ifdef WOLFSSL_SMALL_STACK
  9857. decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
  9858. DYNAMIC_TYPE_PKCS7);
  9859. if (decryptedKey == NULL) {
  9860. ret = MEMORY_E;
  9861. break;
  9862. }
  9863. #ifndef NO_PKCS7_STREAM
  9864. pkcs7->stream->key = decryptedKey;
  9865. #endif
  9866. #endif
  9867. FALL_THROUGH;
  9868. case WC_PKCS7_DECRYPT_KTRI:
  9869. case WC_PKCS7_DECRYPT_KTRI_2:
  9870. case WC_PKCS7_DECRYPT_KTRI_3:
  9871. case WC_PKCS7_DECRYPT_KARI:
  9872. case WC_PKCS7_DECRYPT_KEKRI:
  9873. case WC_PKCS7_DECRYPT_PWRI:
  9874. case WC_PKCS7_DECRYPT_ORI:
  9875. decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
  9876. #ifdef WOLFSSL_SMALL_STACK
  9877. #ifndef NO_PKCS7_STREAM
  9878. decryptedKey = pkcs7->stream->key;
  9879. #endif
  9880. #endif
  9881. ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
  9882. decryptedKey, &decryptedKeySz,
  9883. &recipFound);
  9884. if (ret != 0) {
  9885. break;
  9886. }
  9887. if (recipFound == 0) {
  9888. WOLFSSL_MSG("No recipient found in envelopedData that matches input");
  9889. ret = PKCS7_RECIP_E;
  9890. break;
  9891. }
  9892. #ifndef NO_PKCS7_STREAM
  9893. tmpIdx = idx;
  9894. #endif
  9895. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3);
  9896. FALL_THROUGH;
  9897. case WC_PKCS7_AUTHENV_3:
  9898. #ifndef NO_PKCS7_STREAM
  9899. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  9900. MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ,
  9901. &pkiMsg, &idx)) != 0) {
  9902. break;
  9903. }
  9904. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9905. #endif
  9906. /* remove EncryptedContentInfo */
  9907. if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
  9908. ret = ASN_PARSE_E;
  9909. }
  9910. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  9911. pkiMsgSz) < 0) {
  9912. ret = ASN_PARSE_E;
  9913. }
  9914. if (ret == 0) {
  9915. pkcs7->contentOID = contentType;
  9916. }
  9917. if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  9918. pkiMsgSz) < 0) {
  9919. ret = ASN_PARSE_E;
  9920. }
  9921. blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
  9922. if (ret == 0 && blockKeySz < 0) {
  9923. ret = blockKeySz;
  9924. }
  9925. expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
  9926. if (ret == 0 && expBlockSz < 0) {
  9927. ret = expBlockSz;
  9928. }
  9929. /* get nonce, stored in OPTIONAL parameter of AlgoID */
  9930. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9931. ret = ASN_PARSE_E;
  9932. }
  9933. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9934. ret = ASN_PARSE_E;
  9935. }
  9936. if (ret < 0)
  9937. break;
  9938. #ifndef NO_PKCS7_STREAM
  9939. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  9940. break;
  9941. }
  9942. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0);
  9943. #endif
  9944. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4);
  9945. FALL_THROUGH;
  9946. case WC_PKCS7_AUTHENV_4:
  9947. #ifndef NO_PKCS7_STREAM
  9948. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  9949. MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ,
  9950. &pkiMsg, &idx)) != 0) {
  9951. break;
  9952. }
  9953. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  9954. #endif
  9955. if (ret == 0 && GetLength(pkiMsg, &idx, &nonceSz, pkiMsgSz) < 0) {
  9956. ret = ASN_PARSE_E;
  9957. }
  9958. if (ret == 0 && nonceSz > (int)sizeof(nonce)) {
  9959. WOLFSSL_MSG("AuthEnvelopedData nonce too large for buffer");
  9960. ret = ASN_PARSE_E;
  9961. }
  9962. if (ret == 0) {
  9963. XMEMCPY(nonce, &pkiMsg[idx], nonceSz);
  9964. idx += nonceSz;
  9965. }
  9966. /* get mac size, also stored in OPTIONAL parameter of AlgoID */
  9967. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &macSz, pkiMsgSz) < 0) {
  9968. ret = ASN_PARSE_E;
  9969. }
  9970. if (ret == 0) {
  9971. explicitOctet = 0;
  9972. localIdx = idx;
  9973. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  9974. tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
  9975. explicitOctet = 1;
  9976. /* read encryptedContent, cont[0] */
  9977. ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);
  9978. }
  9979. if (ret == 0 &&
  9980. tag != (ASN_CONTEXT_SPECIFIC | 0) &&
  9981. tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
  9982. ret = ASN_PARSE_E;
  9983. }
  9984. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  9985. pkiMsgSz) <= 0) {
  9986. ret = ASN_PARSE_E;
  9987. }
  9988. if (explicitOctet) {
  9989. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  9990. ret = ASN_PARSE_E;
  9991. }
  9992. if (ret == 0 && tag != ASN_OCTET_STRING) {
  9993. ret = ASN_PARSE_E;
  9994. }
  9995. if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
  9996. pkiMsgSz) <= 0) {
  9997. ret = ASN_PARSE_E;
  9998. }
  9999. }
  10000. if (ret < 0)
  10001. break;
  10002. #ifndef NO_PKCS7_STREAM
  10003. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10004. break;
  10005. }
  10006. /* store nonce for later */
  10007. if (nonceSz > 0) {
  10008. pkcs7->stream->nonceSz = nonceSz;
  10009. pkcs7->stream->nonce = (byte*)XMALLOC(nonceSz, pkcs7->heap,
  10010. DYNAMIC_TYPE_PKCS7);
  10011. if (pkcs7->stream->nonce == NULL) {
  10012. ret = MEMORY_E;
  10013. break;
  10014. }
  10015. else {
  10016. XMEMCPY(pkcs7->stream->nonce, nonce, nonceSz);
  10017. }
  10018. }
  10019. pkcs7->stream->expected = encryptedContentSz;
  10020. wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz,
  10021. encryptedContentSz);
  10022. #endif
  10023. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5);
  10024. FALL_THROUGH;
  10025. case WC_PKCS7_AUTHENV_5:
  10026. #ifndef NO_PKCS7_STREAM
  10027. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10028. ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected,
  10029. &pkiMsg, &idx)) != 0) {
  10030. break;
  10031. }
  10032. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10033. encryptedContentSz = pkcs7->stream->expected;
  10034. #endif
  10035. encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
  10036. DYNAMIC_TYPE_PKCS7);
  10037. if (ret == 0 && encryptedContent == NULL) {
  10038. ret = MEMORY_E;
  10039. }
  10040. if (ret == 0) {
  10041. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  10042. idx += encryptedContentSz;
  10043. }
  10044. #ifndef NO_PKCS7_STREAM
  10045. pkcs7->stream->bufferPt = encryptedContent;
  10046. #endif
  10047. /* may have IMPLICIT [1] authenticatedAttributes */
  10048. localIdx = idx;
  10049. if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
  10050. tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
  10051. encodedAttribIdx = idx;
  10052. encodedAttribs = pkiMsg + idx;
  10053. idx++;
  10054. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10055. ret = ASN_PARSE_E;
  10056. #ifndef NO_PKCS7_STREAM
  10057. pkcs7->stream->expected = length;
  10058. #endif
  10059. encodedAttribSz = length + (idx - encodedAttribIdx);
  10060. if (ret != 0)
  10061. break;
  10062. #ifndef NO_PKCS7_STREAM
  10063. if (encodedAttribSz > 0) {
  10064. pkcs7->stream->aadSz = encodedAttribSz;
  10065. pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz,
  10066. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10067. if (pkcs7->stream->aad == NULL) {
  10068. ret = MEMORY_E;
  10069. break;
  10070. }
  10071. else {
  10072. XMEMCPY(pkcs7->stream->aad, encodedAttribs,
  10073. (idx - encodedAttribIdx));
  10074. }
  10075. }
  10076. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10077. break;
  10078. }
  10079. #endif
  10080. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRB);
  10081. }
  10082. else {
  10083. #ifndef NO_PKCS7_STREAM
  10084. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10085. break;
  10086. }
  10087. #endif
  10088. goto authenv_atrbend; /* jump over attribute cases */
  10089. }
  10090. FALL_THROUGH;
  10091. case WC_PKCS7_AUTHENV_ATRB:
  10092. #ifndef NO_PKCS7_STREAM
  10093. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10094. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10095. return ret;
  10096. }
  10097. length = pkcs7->stream->expected;
  10098. encodedAttribs = pkcs7->stream->aad;
  10099. #else
  10100. length = 0;
  10101. #endif
  10102. /* save pointer and length */
  10103. authAttrib = &pkiMsg[idx];
  10104. authAttribSz = length;
  10105. if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) {
  10106. WOLFSSL_MSG("Error parsing authenticated attributes");
  10107. ret = ASN_PARSE_E;
  10108. break;
  10109. }
  10110. idx += length;
  10111. #ifndef NO_PKCS7_STREAM
  10112. if (encodedAttribSz > 0) {
  10113. XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - length),
  10114. authAttrib, authAttribSz);
  10115. }
  10116. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10117. break;
  10118. }
  10119. #endif
  10120. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND);
  10121. FALL_THROUGH;
  10122. case WC_PKCS7_AUTHENV_ATRBEND:
  10123. authenv_atrbend:
  10124. #ifndef NO_PKCS7_STREAM
  10125. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
  10126. ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
  10127. return ret;
  10128. }
  10129. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10130. if (pkcs7->stream->aadSz > 0) {
  10131. encodedAttribSz = pkcs7->stream->aadSz;
  10132. encodedAttribs = pkcs7->stream->aad;
  10133. }
  10134. #endif
  10135. /* get authTag OCTET STRING */
  10136. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
  10137. ret = ASN_PARSE_E;
  10138. }
  10139. if (ret == 0 && tag != ASN_OCTET_STRING) {
  10140. ret = ASN_PARSE_E;
  10141. }
  10142. if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) {
  10143. ret = ASN_PARSE_E;
  10144. }
  10145. if (ret == 0 && authTagSz > (int)sizeof(authTag)) {
  10146. WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer");
  10147. ret = ASN_PARSE_E;
  10148. }
  10149. if (ret == 0) {
  10150. XMEMCPY(authTag, &pkiMsg[idx], authTagSz);
  10151. idx += authTagSz;
  10152. }
  10153. if (ret == 0 && authAttrib != NULL) {
  10154. /* temporarily swap authAttribs byte[0] to SET OF instead of
  10155. * IMPLICIT [1], for aad calculation */
  10156. authAttribSetByte = encodedAttribs[0];
  10157. encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED;
  10158. }
  10159. if (ret < 0)
  10160. break;
  10161. #ifndef NO_PKCS7_STREAM
  10162. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10163. break;
  10164. }
  10165. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  10166. pkcs7->stream->totalRd) + pkcs7->stream->length;
  10167. /* store tag for later */
  10168. if (authTagSz > 0) {
  10169. pkcs7->stream->tagSz = authTagSz;
  10170. pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap,
  10171. DYNAMIC_TYPE_PKCS7);
  10172. if (pkcs7->stream->tag == NULL) {
  10173. ret = MEMORY_E;
  10174. break;
  10175. }
  10176. else {
  10177. XMEMCPY(pkcs7->stream->tag, authTag, authTagSz);
  10178. }
  10179. }
  10180. #endif
  10181. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_6);
  10182. FALL_THROUGH;
  10183. case WC_PKCS7_AUTHENV_6:
  10184. #ifndef NO_PKCS7_STREAM
  10185. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10186. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10187. break;
  10188. }
  10189. /* restore all variables needed */
  10190. if (pkcs7->stream->nonceSz > 0) {
  10191. nonceSz = pkcs7->stream->nonceSz;
  10192. if (nonceSz > GCM_NONCE_MID_SZ) {
  10193. WOLFSSL_MSG("PKCS7 saved nonce is too large");
  10194. ret = BUFFER_E;
  10195. break;
  10196. }
  10197. else {
  10198. XMEMCPY(nonce, pkcs7->stream->nonce, nonceSz);
  10199. }
  10200. }
  10201. if (pkcs7->stream->tagSz > 0) {
  10202. authTagSz = pkcs7->stream->tagSz;
  10203. if (authTagSz > AES_BLOCK_SIZE) {
  10204. WOLFSSL_MSG("PKCS7 saved tag is too large");
  10205. ret = BUFFER_E;
  10206. break;
  10207. }
  10208. else {
  10209. XMEMCPY(authTag, pkcs7->stream->tag, authTagSz);
  10210. }
  10211. }
  10212. if (pkcs7->stream->aadSz > 0) {
  10213. encodedAttribSz = pkcs7->stream->aadSz;
  10214. encodedAttribs = pkcs7->stream->aad;
  10215. }
  10216. wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz,
  10217. &encryptedContentSz);
  10218. encryptedContent = pkcs7->stream->bufferPt;
  10219. #ifdef WOLFSSL_SMALL_STACK
  10220. decryptedKey = pkcs7->stream->key;
  10221. #endif
  10222. #endif
  10223. /* decrypt encryptedContent */
  10224. ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
  10225. blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,
  10226. authTag, authTagSz, encryptedContent, encryptedContentSz,
  10227. encryptedContent);
  10228. if (ret != 0) {
  10229. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10230. return ret;
  10231. }
  10232. if (authAttrib != NULL) {
  10233. /* restore authAttrib IMPLICIT [1] */
  10234. encodedAttribs[0] = authAttribSetByte;
  10235. }
  10236. /* copy plaintext to output */
  10237. XMEMCPY(output, encryptedContent, encryptedContentSz);
  10238. /* free memory, zero out keys */
  10239. ForceZero(encryptedContent, encryptedContentSz);
  10240. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10241. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  10242. #ifdef WOLFSSL_SMALL_STACK
  10243. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10244. decryptedKey = NULL;
  10245. #ifndef NO_PKCS7_STREAM
  10246. pkcs7->stream->key = NULL;
  10247. #endif
  10248. #endif
  10249. ret = encryptedContentSz;
  10250. #ifndef NO_PKCS7_STREAM
  10251. wc_PKCS7_ResetStream(pkcs7);
  10252. #endif
  10253. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10254. break;
  10255. default:
  10256. WOLFSSL_MSG("Unknown PKCS7 state");
  10257. ret = BAD_FUNC_ARG;
  10258. }
  10259. #ifdef WOLFSSL_SMALL_STACK
  10260. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  10261. if (decryptedKey != NULL) {
  10262. ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
  10263. }
  10264. XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10265. }
  10266. #endif
  10267. #ifndef NO_PKCS7_STREAM
  10268. if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
  10269. wc_PKCS7_ResetStream(pkcs7);
  10270. }
  10271. #endif
  10272. return ret;
  10273. #else
  10274. WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
  10275. (void)pkcs7;
  10276. (void)in;
  10277. (void)inSz;
  10278. (void)output;
  10279. (void)outputSz;
  10280. return NOT_COMPILED_IN;
  10281. #endif /* HAVE_AESGCM | HAVE_AESCCM */
  10282. }
  10283. #ifndef NO_PKCS7_ENCRYPTED_DATA
  10284. /* build PKCS#7 encryptedData content type, return encrypted size */
  10285. int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  10286. {
  10287. int ret, idx = 0;
  10288. int totalSz, padSz, encryptedOutSz;
  10289. int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
  10290. byte contentInfoSeq[MAX_SEQ_SZ];
  10291. byte outerContentType[MAX_ALGO_SZ];
  10292. byte outerContent[MAX_SEQ_SZ];
  10293. int encDataSeqSz, verSz, blockSz;
  10294. byte encDataSeq[MAX_SEQ_SZ];
  10295. byte ver[MAX_VERSION_SZ];
  10296. byte* plain = NULL;
  10297. byte* encryptedContent = NULL;
  10298. int encContentOctetSz, encContentSeqSz, contentTypeSz;
  10299. int contentEncAlgoSz, ivOctetStringSz;
  10300. byte encContentSeq[MAX_SEQ_SZ];
  10301. byte contentType[MAX_OID_SZ];
  10302. byte contentEncAlgo[MAX_ALGO_SZ];
  10303. byte tmpIv[MAX_CONTENT_IV_SIZE];
  10304. byte ivOctetString[MAX_OCTET_STR_SZ];
  10305. byte encContentOctet[MAX_OCTET_STR_SZ];
  10306. byte attribSet[MAX_SET_SZ];
  10307. EncodedAttrib* attribs = NULL;
  10308. word32 attribsSz;
  10309. word32 attribsCount;
  10310. word32 attribsSetSz;
  10311. byte* flatAttribs = NULL;
  10312. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  10313. pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
  10314. pkcs7->encryptionKeySz == 0)
  10315. return BAD_FUNC_ARG;
  10316. if (output == NULL || outputSz == 0)
  10317. return BAD_FUNC_ARG;
  10318. if (pkcs7->version == 3) {
  10319. verSz = SetMyVersion(0, ver, 0);
  10320. outerContentTypeSz = 0;
  10321. }
  10322. else {
  10323. /* outer content type */
  10324. ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType,
  10325. sizeof(outerContentType));
  10326. if (ret < 0)
  10327. return ret;
  10328. outerContentTypeSz = ret;
  10329. /* version, 2 if unprotectedAttrs present, 0 if absent */
  10330. if (pkcs7->unprotectedAttribsSz > 0) {
  10331. verSz = SetMyVersion(2, ver, 0);
  10332. } else {
  10333. verSz = SetMyVersion(0, ver, 0);
  10334. }
  10335. }
  10336. /* EncryptedContentInfo */
  10337. ret = wc_SetContentType(pkcs7->contentOID, contentType,
  10338. sizeof(contentType));
  10339. if (ret < 0)
  10340. return ret;
  10341. contentTypeSz = ret;
  10342. /* allocate encrypted content buffer, do PKCS#7 padding */
  10343. blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
  10344. if (blockSz < 0)
  10345. return blockSz;
  10346. padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
  10347. if (padSz < 0)
  10348. return padSz;
  10349. encryptedOutSz = pkcs7->contentSz + padSz;
  10350. plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  10351. DYNAMIC_TYPE_PKCS7);
  10352. if (plain == NULL)
  10353. return MEMORY_E;
  10354. ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
  10355. encryptedOutSz, blockSz);
  10356. if (ret < 0) {
  10357. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10358. return ret;
  10359. }
  10360. encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
  10361. DYNAMIC_TYPE_PKCS7);
  10362. if (encryptedContent == NULL) {
  10363. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10364. return MEMORY_E;
  10365. }
  10366. /* put together IV OCTET STRING */
  10367. ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
  10368. /* build up ContentEncryptionAlgorithmIdentifier sequence,
  10369. adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
  10370. contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
  10371. oidBlkType, ivOctetStringSz + blockSz);
  10372. if (contentEncAlgoSz == 0) {
  10373. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10374. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10375. return BAD_FUNC_ARG;
  10376. }
  10377. /* encrypt content */
  10378. WOLFSSL_MSG("Encrypting the content");
  10379. ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, blockSz);
  10380. if (ret != 0) {
  10381. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10382. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10383. return ret;
  10384. }
  10385. ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
  10386. pkcs7->encryptionKeySz, tmpIv, blockSz, NULL, 0, NULL, 0,
  10387. plain, encryptedOutSz, encryptedContent);
  10388. if (ret != 0) {
  10389. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10390. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10391. return ret;
  10392. }
  10393. encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
  10394. encryptedOutSz, encContentOctet);
  10395. encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
  10396. ivOctetStringSz + blockSz +
  10397. encContentOctetSz + encryptedOutSz,
  10398. encContentSeq);
  10399. /* optional UnprotectedAttributes */
  10400. if (pkcs7->unprotectedAttribsSz != 0) {
  10401. if (pkcs7->unprotectedAttribs == NULL) {
  10402. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10403. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10404. return BAD_FUNC_ARG;
  10405. }
  10406. attribs = (EncodedAttrib*)XMALLOC(
  10407. sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,
  10408. pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10409. if (attribs == NULL) {
  10410. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10411. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10412. return MEMORY_E;
  10413. }
  10414. attribsCount = pkcs7->unprotectedAttribsSz;
  10415. attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,
  10416. pkcs7->unprotectedAttribs,
  10417. pkcs7->unprotectedAttribsSz);
  10418. flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10419. if (flatAttribs == NULL) {
  10420. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10421. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10422. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10423. return MEMORY_E;
  10424. }
  10425. FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);
  10426. attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
  10427. } else {
  10428. attribsSz = 0;
  10429. attribsSetSz = 0;
  10430. }
  10431. /* keep track of sizes for outer wrapper layering */
  10432. totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
  10433. ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +
  10434. attribsSz + attribsSetSz;
  10435. /* EncryptedData */
  10436. encDataSeqSz = SetSequence(totalSz, encDataSeq);
  10437. totalSz += encDataSeqSz;
  10438. if (pkcs7->version != 3) {
  10439. /* outer content */
  10440. outerContentSz = SetExplicit(0, totalSz, outerContent);
  10441. totalSz += outerContentTypeSz;
  10442. totalSz += outerContentSz;
  10443. /* ContentInfo */
  10444. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  10445. totalSz += contentInfoSeqSz;
  10446. } else {
  10447. contentInfoSeqSz = 0;
  10448. outerContentSz = 0;
  10449. }
  10450. if (totalSz > (int)outputSz) {
  10451. WOLFSSL_MSG("PKCS#7 output buffer too small");
  10452. if (attribs != NULL)
  10453. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10454. if (flatAttribs != NULL)
  10455. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10456. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10457. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10458. return BUFFER_E;
  10459. }
  10460. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  10461. idx += contentInfoSeqSz;
  10462. XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
  10463. idx += outerContentTypeSz;
  10464. XMEMCPY(output + idx, outerContent, outerContentSz);
  10465. idx += outerContentSz;
  10466. XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
  10467. idx += encDataSeqSz;
  10468. XMEMCPY(output + idx, ver, verSz);
  10469. idx += verSz;
  10470. XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
  10471. idx += encContentSeqSz;
  10472. XMEMCPY(output + idx, contentType, contentTypeSz);
  10473. idx += contentTypeSz;
  10474. XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
  10475. idx += contentEncAlgoSz;
  10476. XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
  10477. idx += ivOctetStringSz;
  10478. XMEMCPY(output + idx, tmpIv, blockSz);
  10479. idx += blockSz;
  10480. XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
  10481. idx += encContentOctetSz;
  10482. XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
  10483. idx += encryptedOutSz;
  10484. if (pkcs7->unprotectedAttribsSz != 0) {
  10485. XMEMCPY(output + idx, attribSet, attribsSetSz);
  10486. idx += attribsSetSz;
  10487. XMEMCPY(output + idx, flatAttribs, attribsSz);
  10488. idx += attribsSz;
  10489. }
  10490. if (attribs != NULL)
  10491. XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10492. if (flatAttribs != NULL)
  10493. XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10494. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10495. XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10496. return idx;
  10497. }
  10498. /* decode and store unprotected attributes in PKCS7->decodedAttrib. Return
  10499. * 0 on success, negative on error. User must call wc_PKCS7_Free(). */
  10500. static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
  10501. word32 pkiMsgSz, word32* inOutIdx)
  10502. {
  10503. int ret, attribLen;
  10504. word32 idx;
  10505. byte tag;
  10506. if (pkcs7 == NULL || pkiMsg == NULL ||
  10507. pkiMsgSz == 0 || inOutIdx == NULL)
  10508. return BAD_FUNC_ARG;
  10509. idx = *inOutIdx;
  10510. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10511. return ASN_PARSE_E;
  10512. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
  10513. return ASN_PARSE_E;
  10514. if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
  10515. return ASN_PARSE_E;
  10516. /* loop through attributes */
  10517. if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {
  10518. return ret;
  10519. }
  10520. *inOutIdx = idx;
  10521. return 0;
  10522. }
  10523. /* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */
  10524. int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
  10525. byte* output, word32 outputSz)
  10526. {
  10527. int ret = 0, version, length = 0, haveAttribs = 0;
  10528. word32 idx = 0;
  10529. #ifndef NO_PKCS7_STREAM
  10530. word32 tmpIdx = 0;
  10531. #endif
  10532. word32 contentType = 0, encOID;
  10533. int expBlockSz = 0;
  10534. byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
  10535. byte *tmpIv = tmpIvBuf;
  10536. int encryptedContentSz = 0;
  10537. byte padLen = 0;
  10538. byte* encryptedContent = NULL;
  10539. byte* pkiMsg = in;
  10540. word32 pkiMsgSz = inSz;
  10541. byte tag;
  10542. if (pkcs7 == NULL ||
  10543. ((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
  10544. pkcs7->decryptionCb == NULL))
  10545. return BAD_FUNC_ARG;
  10546. if (pkiMsg == NULL || pkiMsgSz == 0 ||
  10547. output == NULL || outputSz == 0)
  10548. return BAD_FUNC_ARG;
  10549. #ifndef NO_PKCS7_STREAM
  10550. (void)tmpIv; /* help out static analysis */
  10551. if (pkcs7->stream == NULL) {
  10552. if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
  10553. return ret;
  10554. }
  10555. }
  10556. #endif
  10557. switch (pkcs7->state) {
  10558. case WC_PKCS7_START:
  10559. #ifndef NO_PKCS7_STREAM
  10560. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
  10561. MAX_ALGO_SZ, &pkiMsg, &idx)) != 0) {
  10562. return ret;
  10563. }
  10564. if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) {
  10565. return ret;
  10566. }
  10567. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10568. #endif
  10569. if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10570. NO_USER_CHECK) < 0)
  10571. ret = ASN_PARSE_E;
  10572. if (pkcs7->version != 3) { /* ContentInfo not in firmware bundles */
  10573. /* read past ContentInfo, verify type is encrypted-data */
  10574. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10575. pkiMsgSz) < 0)
  10576. ret = ASN_PARSE_E;
  10577. if (ret == 0 && contentType != ENCRYPTED_DATA) {
  10578. WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
  10579. ret = PKCS7_OID_E;
  10580. }
  10581. }
  10582. if (ret != 0) break;
  10583. #ifndef NO_PKCS7_STREAM
  10584. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10585. break;
  10586. }
  10587. #endif
  10588. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE2);
  10589. FALL_THROUGH;
  10590. /* end of stage 1 */
  10591. case WC_PKCS7_STAGE2:
  10592. #ifndef NO_PKCS7_STREAM
  10593. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10594. MAX_LENGTH_SZ + MAX_SEQ_SZ + ASN_TAG_SZ, &pkiMsg,
  10595. &idx)) != 0) {
  10596. return ret;
  10597. }
  10598. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10599. #endif
  10600. if (pkcs7->version != 3) {
  10601. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10602. ret = ASN_PARSE_E;
  10603. if (ret == 0 && tag !=
  10604. (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  10605. ret = ASN_PARSE_E;
  10606. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10607. NO_USER_CHECK) < 0)
  10608. ret = ASN_PARSE_E;
  10609. /* remove EncryptedData and version */
  10610. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10611. NO_USER_CHECK) < 0)
  10612. ret = ASN_PARSE_E;
  10613. }
  10614. if (ret != 0) break;
  10615. #ifndef NO_PKCS7_STREAM
  10616. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10617. break;
  10618. }
  10619. #endif
  10620. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE3);
  10621. FALL_THROUGH;
  10622. /* end of stage 2 */
  10623. case WC_PKCS7_STAGE3:
  10624. #ifndef NO_PKCS7_STREAM
  10625. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10626. MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ * 2,
  10627. &pkiMsg, &idx)) != 0) {
  10628. return ret;
  10629. }
  10630. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10631. #endif
  10632. /* get version, check later */
  10633. haveAttribs = 0;
  10634. if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  10635. ret = ASN_PARSE_E;
  10636. /* remove EncryptedContentInfo */
  10637. if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
  10638. NO_USER_CHECK) < 0)
  10639. ret = ASN_PARSE_E;
  10640. if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
  10641. pkiMsgSz) < 0)
  10642. ret = ASN_PARSE_E;
  10643. if (ret == 0) {
  10644. pkcs7->contentOID = contentType;
  10645. }
  10646. if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
  10647. pkiMsgSz)) < 0)
  10648. ret = ASN_PARSE_E;
  10649. if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID)) < 0)
  10650. ret = expBlockSz;
  10651. if (ret != 0) break;
  10652. #ifndef NO_PKCS7_STREAM
  10653. /* store expBlockSz for later */
  10654. pkcs7->stream->varOne = expBlockSz;
  10655. pkcs7->stream->varTwo = encOID;
  10656. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10657. break;
  10658. }
  10659. /* store version for later */
  10660. pkcs7->stream->vers = version;
  10661. #endif
  10662. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE4);
  10663. FALL_THROUGH;
  10664. /* end of stage 3 */
  10665. /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
  10666. case WC_PKCS7_STAGE4:
  10667. #ifndef NO_PKCS7_STREAM
  10668. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10669. ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  10670. return ret;
  10671. }
  10672. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10673. /* restore saved variables */
  10674. expBlockSz = pkcs7->stream->varOne;
  10675. #endif
  10676. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10677. ret = ASN_PARSE_E;
  10678. if (ret == 0 && tag != ASN_OCTET_STRING)
  10679. ret = ASN_PARSE_E;
  10680. if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  10681. ret = ASN_PARSE_E;
  10682. if (ret == 0 && length != expBlockSz) {
  10683. WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
  10684. ret = ASN_PARSE_E;
  10685. }
  10686. if (ret != 0) break;
  10687. #ifndef NO_PKCS7_STREAM
  10688. /* next chunk of data expected should have the IV */
  10689. pkcs7->stream->expected = length;
  10690. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10691. break;
  10692. }
  10693. #endif
  10694. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE5);
  10695. FALL_THROUGH;
  10696. /* end of stage 4 */
  10697. case WC_PKCS7_STAGE5:
  10698. #ifndef NO_PKCS7_STREAM
  10699. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10700. pkcs7->stream->expected + ASN_TAG_SZ +
  10701. MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
  10702. return ret;
  10703. }
  10704. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10705. /* use IV buffer from stream structure */
  10706. tmpIv = pkcs7->stream->tmpIv;
  10707. length = pkcs7->stream->expected;
  10708. #endif
  10709. XMEMCPY(tmpIv, &pkiMsg[idx], length);
  10710. idx += length;
  10711. /* read encryptedContent, cont[0] */
  10712. if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  10713. ret = ASN_PARSE_E;
  10714. if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))
  10715. ret = ASN_PARSE_E;
  10716. if (ret == 0 && GetLength_ex(pkiMsg, &idx, &encryptedContentSz,
  10717. pkiMsgSz, NO_USER_CHECK) <= 0)
  10718. ret = ASN_PARSE_E;
  10719. if (ret < 0)
  10720. break;
  10721. #ifndef NO_PKCS7_STREAM
  10722. /* next chunk of data should contain encrypted content */
  10723. pkcs7->stream->varThree = encryptedContentSz;
  10724. if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
  10725. break;
  10726. }
  10727. if (pkcs7->stream->totalRd + encryptedContentSz <
  10728. pkcs7->stream->maxLen) {
  10729. pkcs7->stream->flagOne = 1;
  10730. }
  10731. pkcs7->stream->expected = (pkcs7->stream->maxLen -
  10732. pkcs7->stream->totalRd) + pkcs7->stream->length;
  10733. #endif
  10734. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE6);
  10735. FALL_THROUGH;
  10736. /* end of stage 5 */
  10737. case WC_PKCS7_STAGE6:
  10738. #ifndef NO_PKCS7_STREAM
  10739. if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
  10740. pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
  10741. return ret;
  10742. }
  10743. pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz;
  10744. /* restore saved variables */
  10745. expBlockSz = pkcs7->stream->varOne;
  10746. encOID = pkcs7->stream->varTwo;
  10747. encryptedContentSz = pkcs7->stream->varThree;
  10748. version = pkcs7->stream->vers;
  10749. tmpIv = pkcs7->stream->tmpIv;
  10750. #else
  10751. encOID = 0;
  10752. #endif
  10753. if (ret == 0 && (encryptedContent = (byte*)XMALLOC(
  10754. encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) {
  10755. ret = MEMORY_E;
  10756. break;
  10757. }
  10758. if (ret == 0) {
  10759. XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
  10760. idx += encryptedContentSz;
  10761. /* decrypt encryptedContent */
  10762. ret = wc_PKCS7_DecryptContent(pkcs7, encOID,
  10763. pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,
  10764. expBlockSz, NULL, 0, NULL, 0, encryptedContent,
  10765. encryptedContentSz, encryptedContent);
  10766. if (ret != 0) {
  10767. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10768. }
  10769. }
  10770. if (ret == 0) {
  10771. padLen = encryptedContent[encryptedContentSz-1];
  10772. if (padLen > encryptedContentSz) {
  10773. WOLFSSL_MSG("Bad padding size found");
  10774. ret = BUFFER_E;
  10775. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10776. break;
  10777. }
  10778. /* copy plaintext to output */
  10779. XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
  10780. /* get implicit[1] unprotected attributes, optional */
  10781. wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
  10782. pkcs7->decodedAttrib = NULL;
  10783. #ifndef NO_PKCS7_STREAM
  10784. if (pkcs7->stream->flagOne)
  10785. #else
  10786. if (idx < pkiMsgSz)
  10787. #endif
  10788. {
  10789. haveAttribs = 1;
  10790. ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
  10791. pkiMsgSz, &idx);
  10792. if (ret != 0) {
  10793. ForceZero(encryptedContent, encryptedContentSz);
  10794. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10795. ret = ASN_PARSE_E;
  10796. }
  10797. }
  10798. }
  10799. if (ret == 0) {
  10800. ForceZero(encryptedContent, encryptedContentSz);
  10801. XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10802. /* go back and check the version now that attribs have been processed */
  10803. if (pkcs7->version == 3 && version != 0) {
  10804. WOLFSSL_MSG("Wrong PKCS#7 FirmwareEncryptedData version");
  10805. return ASN_VERSION_E;
  10806. }
  10807. if (pkcs7->version != 3 &&
  10808. ((haveAttribs == 0 && version != 0) ||
  10809. (haveAttribs == 1 && version != 2))) {
  10810. WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version");
  10811. return ASN_VERSION_E;
  10812. }
  10813. ret = encryptedContentSz - padLen;
  10814. }
  10815. if (ret != 0) break;
  10816. #ifndef NO_PKCS7_STREAM
  10817. wc_PKCS7_ResetStream(pkcs7);
  10818. #endif
  10819. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10820. break;
  10821. default:
  10822. WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
  10823. return BAD_STATE_E;
  10824. }
  10825. if (ret != 0) {
  10826. #ifndef NO_PKCS7_STREAM
  10827. /* restart in error case */
  10828. wc_PKCS7_ResetStream(pkcs7);
  10829. #endif
  10830. wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
  10831. }
  10832. return ret;
  10833. }
  10834. /* Function to set callback during decryption, this overrides the default
  10835. * decryption function and can be used for choosing a key at run time based
  10836. * on the parsed bundle so far.
  10837. * returns 0 on success
  10838. */
  10839. int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,
  10840. CallbackDecryptContent decryptionCb)
  10841. {
  10842. if (pkcs7 != NULL) {
  10843. pkcs7->decryptionCb = decryptionCb;
  10844. }
  10845. return 0;
  10846. }
  10847. /* Set an optional user context that gets passed to callback
  10848. * returns 0 on success
  10849. */
  10850. int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx)
  10851. {
  10852. if (pkcs7 != NULL) {
  10853. pkcs7->decryptionCtx = ctx;
  10854. }
  10855. return 0;
  10856. }
  10857. #endif /* NO_PKCS7_ENCRYPTED_DATA */
  10858. #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
  10859. /* build PKCS#7 compressedData content type, return encrypted size */
  10860. int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz)
  10861. {
  10862. byte contentInfoSeq[MAX_SEQ_SZ];
  10863. byte contentInfoTypeOid[MAX_OID_SZ];
  10864. byte contentInfoContentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  10865. byte compressedDataSeq[MAX_SEQ_SZ];
  10866. byte cmsVersion[MAX_VERSION_SZ];
  10867. byte compressAlgId[MAX_ALGO_SZ];
  10868. byte encapContentInfoSeq[MAX_SEQ_SZ];
  10869. byte contentTypeOid[MAX_OID_SZ];
  10870. byte contentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
  10871. byte contentOctetStr[MAX_OCTET_STR_SZ];
  10872. int ret;
  10873. word32 totalSz, idx;
  10874. word32 contentInfoSeqSz, contentInfoContentSeqSz, contentInfoTypeOidSz;
  10875. word32 compressedDataSeqSz, cmsVersionSz, compressAlgIdSz;
  10876. word32 encapContentInfoSeqSz, contentTypeOidSz, contentSeqSz;
  10877. word32 contentOctetStrSz;
  10878. byte* compressed;
  10879. word32 compressedSz;
  10880. if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
  10881. output == NULL || outputSz == 0) {
  10882. return BAD_FUNC_ARG;
  10883. }
  10884. /* allocate space for compressed content. The libz code says the compressed
  10885. * buffer should be srcSz + 0.1% + 12. */
  10886. compressedSz = (pkcs7->contentSz + (word32)(pkcs7->contentSz * 0.001) + 12);
  10887. compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10888. if (compressed == NULL) {
  10889. WOLFSSL_MSG("Error allocating memory for CMS compressed content");
  10890. return MEMORY_E;
  10891. }
  10892. /* compress content */
  10893. ret = wc_Compress(compressed, compressedSz, pkcs7->content,
  10894. pkcs7->contentSz, 0);
  10895. if (ret < 0) {
  10896. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10897. return ret;
  10898. }
  10899. compressedSz = (word32)ret;
  10900. /* eContent OCTET STRING, working backwards */
  10901. contentOctetStrSz = SetOctetString(compressedSz, contentOctetStr);
  10902. totalSz = contentOctetStrSz + compressedSz;
  10903. /* EXPLICIT [0] eContentType */
  10904. contentSeqSz = SetExplicit(0, totalSz, contentSeq);
  10905. totalSz += contentSeqSz;
  10906. /* eContentType OBJECT IDENTIFIER */
  10907. ret = wc_SetContentType(pkcs7->contentOID, contentTypeOid,
  10908. sizeof(contentTypeOid));
  10909. if (ret < 0) {
  10910. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10911. return ret;
  10912. }
  10913. contentTypeOidSz = ret;
  10914. totalSz += contentTypeOidSz;
  10915. /* EncapsulatedContentInfo SEQUENCE */
  10916. encapContentInfoSeqSz = SetSequence(totalSz, encapContentInfoSeq);
  10917. totalSz += encapContentInfoSeqSz;
  10918. /* compressionAlgorithm AlgorithmIdentifier */
  10919. /* Only supports zlib for compression currently:
  10920. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  10921. compressAlgIdSz = SetAlgoID(ZLIBc, compressAlgId, oidCompressType, 0);
  10922. totalSz += compressAlgIdSz;
  10923. /* version */
  10924. cmsVersionSz = SetMyVersion(0, cmsVersion, 0);
  10925. totalSz += cmsVersionSz;
  10926. /* CompressedData SEQUENCE */
  10927. compressedDataSeqSz = SetSequence(totalSz, compressedDataSeq);
  10928. totalSz += compressedDataSeqSz;
  10929. if (pkcs7->version == 3) {
  10930. /* RFC 4108 section 2
  10931. * When the SignedData is version 3 and eContent is compressedData then
  10932. * the encoding is :
  10933. * CompressedData {
  10934. * version
  10935. * compressionAlgorithm
  10936. * encapContentInfo
  10937. * }
  10938. */
  10939. contentInfoSeqSz = 0;
  10940. contentInfoTypeOidSz = 0;
  10941. contentInfoContentSeqSz = 0;
  10942. }
  10943. else {
  10944. /* EncryptedData eContent type is encoded with:
  10945. * EncryptedData {
  10946. * version
  10947. * EncryptedContentInfo {
  10948. * contentType (i.e id-ct-compressedData)
  10949. * contentEncryptionAlgorithm
  10950. * octet string of CompressedData or FirmwarePkgData
  10951. * }
  10952. * attributes
  10953. * }
  10954. */
  10955. /* ContentInfo content EXPLICIT SEQUENCE */
  10956. contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq);
  10957. totalSz += contentInfoContentSeqSz;
  10958. ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid,
  10959. sizeof(contentInfoTypeOid));
  10960. if (ret < 0) {
  10961. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10962. return ret;
  10963. }
  10964. contentInfoTypeOidSz = ret;
  10965. totalSz += contentInfoTypeOidSz;
  10966. /* ContentInfo SEQUENCE */
  10967. contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
  10968. totalSz += contentInfoSeqSz;
  10969. }
  10970. if (outputSz < totalSz) {
  10971. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  10972. return BUFFER_E;
  10973. }
  10974. idx = 0;
  10975. if (contentInfoSeqSz > 0) {
  10976. XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
  10977. idx += contentInfoSeqSz;
  10978. }
  10979. if (contentInfoTypeOidSz > 0) {
  10980. XMEMCPY(output + idx, contentInfoTypeOid, contentInfoTypeOidSz);
  10981. idx += contentInfoTypeOidSz;
  10982. }
  10983. if (contentInfoContentSeqSz > 0) {
  10984. XMEMCPY(output + idx, contentInfoContentSeq, contentInfoContentSeqSz);
  10985. idx += contentInfoContentSeqSz;
  10986. }
  10987. XMEMCPY(output + idx, compressedDataSeq, compressedDataSeqSz);
  10988. idx += compressedDataSeqSz;
  10989. XMEMCPY(output + idx, cmsVersion, cmsVersionSz);
  10990. idx += cmsVersionSz;
  10991. XMEMCPY(output + idx, compressAlgId, compressAlgIdSz);
  10992. idx += compressAlgIdSz;
  10993. XMEMCPY(output + idx, encapContentInfoSeq, encapContentInfoSeqSz);
  10994. idx += encapContentInfoSeqSz;
  10995. XMEMCPY(output + idx, contentTypeOid, contentTypeOidSz);
  10996. idx += contentTypeOidSz;
  10997. XMEMCPY(output + idx, contentSeq, contentSeqSz);
  10998. idx += contentSeqSz;
  10999. XMEMCPY(output + idx, contentOctetStr, contentOctetStrSz);
  11000. idx += contentOctetStrSz;
  11001. XMEMCPY(output + idx, compressed, compressedSz);
  11002. idx += compressedSz;
  11003. XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11004. return idx;
  11005. }
  11006. /* unwrap and decompress PKCS#7/CMS compressedData object,
  11007. * Handles content wrapped compressed data and raw compressed data packet
  11008. * returned decoded size */
  11009. int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
  11010. byte* output, word32 outputSz)
  11011. {
  11012. int length, version, ret;
  11013. word32 idx = 0, algOID, contentType;
  11014. byte tag;
  11015. byte* decompressed;
  11016. word32 decompressedSz;
  11017. if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 ||
  11018. output == NULL || outputSz == 0) {
  11019. return BAD_FUNC_ARG;
  11020. }
  11021. /* unwarp content surrounding if found */
  11022. {
  11023. word32 localIdx = idx;
  11024. int err = 0;
  11025. /* get ContentInfo SEQUENCE */
  11026. if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  11027. err = ASN_PARSE_E;
  11028. if (err == 0 && pkcs7->version != 3) {
  11029. /* get ContentInfo contentType */
  11030. if (wc_GetContentType(pkiMsg, &localIdx, &contentType, pkiMsgSz)
  11031. < 0)
  11032. err = ASN_PARSE_E;
  11033. if (err == 0 && contentType != COMPRESSED_DATA)
  11034. err = ASN_PARSE_E;
  11035. }
  11036. /* get ContentInfo content EXPLICIT SEQUENCE */
  11037. if (err == 0) {
  11038. if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
  11039. err = ASN_PARSE_E;
  11040. }
  11041. if (err == 0) {
  11042. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  11043. err = ASN_PARSE_E;
  11044. }
  11045. if (err == 0) {
  11046. if (GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
  11047. err = ASN_PARSE_E;
  11048. }
  11049. /* successful content unwrap, update index */
  11050. if (err == 0) {
  11051. idx = localIdx;
  11052. }
  11053. }
  11054. /* get CompressedData SEQUENCE */
  11055. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11056. return ASN_PARSE_E;
  11057. /* get version */
  11058. if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
  11059. return ASN_PARSE_E;
  11060. if (version != 0) {
  11061. WOLFSSL_MSG("CMS CompressedData version MUST be 0, but is not");
  11062. return ASN_PARSE_E;
  11063. }
  11064. /* get CompressionAlgorithmIdentifier */
  11065. if (GetAlgoId(pkiMsg, &idx, &algOID, oidIgnoreType, pkiMsgSz) < 0)
  11066. return ASN_PARSE_E;
  11067. /* Only supports zlib for compression currently:
  11068. * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
  11069. if (algOID != ZLIBc) {
  11070. WOLFSSL_MSG("CMS CompressedData only supports zlib algorithm");
  11071. return ASN_PARSE_E;
  11072. }
  11073. /* get EncapsulatedContentInfo SEQUENCE */
  11074. if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11075. return ASN_PARSE_E;
  11076. /* get ContentType OID */
  11077. if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
  11078. return ASN_PARSE_E;
  11079. pkcs7->contentOID = contentType;
  11080. /* get eContent EXPLICIT SEQUENCE */
  11081. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  11082. return ASN_PARSE_E;
  11083. if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
  11084. return ASN_PARSE_E;
  11085. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11086. return ASN_PARSE_E;
  11087. /* get content OCTET STRING */
  11088. if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
  11089. return ASN_PARSE_E;
  11090. if (tag != ASN_OCTET_STRING)
  11091. return ASN_PARSE_E;
  11092. if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
  11093. return ASN_PARSE_E;
  11094. /* decompress content */
  11095. ret = wc_DeCompressDynamic(&decompressed, WOLFSSL_PKCS7_MAX_DECOMPRESSION,
  11096. DYNAMIC_TYPE_PKCS7, &pkiMsg[idx], length, 0, pkcs7->heap);
  11097. if (ret < 0) {
  11098. return ret;
  11099. }
  11100. decompressedSz = (word32)ret;
  11101. /* get content */
  11102. if (outputSz < decompressedSz) {
  11103. WOLFSSL_MSG("CMS output buffer too small to hold decompressed data");
  11104. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11105. return BUFFER_E;
  11106. }
  11107. XMEMCPY(output, decompressed, decompressedSz);
  11108. XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
  11109. return decompressedSz;
  11110. }
  11111. #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
  11112. #else /* HAVE_PKCS7 */
  11113. #ifdef _MSC_VER
  11114. /* 4206 warning for blank file */
  11115. #pragma warning(disable: 4206)
  11116. #endif
  11117. #endif /* HAVE_PKCS7 */