ClpAsn1Objects.pas 247 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489
  1. { *********************************************************************************** }
  2. { * CryptoLib Library * }
  3. { * Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe * }
  4. { * Github Repository <https://github.com/Xor-el> * }
  5. { * Distributed under the MIT software license, see the accompanying file LICENSE * }
  6. { * or visit http://www.opensource.org/licenses/mit-license.php. * }
  7. { * Acknowledgements: * }
  8. { * * }
  9. { * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
  10. { * development of this library * }
  11. { * ******************************************************************************* * }
  12. (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
  13. unit ClpAsn1Objects;
  14. {$I ..\Include\CryptoLib.inc}
  15. interface
  16. uses
  17. Classes,
  18. Math,
  19. SyncObjs,
  20. StrUtils,
  21. SysUtils,
  22. Generics.Collections,
  23. ClpEncoders,
  24. ClpBits,
  25. ClpBigInteger,
  26. ClpArrayUtils,
  27. ClpStringUtils,
  28. ClpCryptoLibTypes,
  29. ClpConverters,
  30. ClpIAsn1Objects,
  31. ClpOidTokenizer,
  32. ClpIOidTokenizer;
  33. resourcestring
  34. SDataOverflow = 'Data Overflow';
  35. SCorruptedStreamInvalidTag =
  36. 'Corrupted Stream - Invalid High Tag Number Found';
  37. SEOFFound = 'EOF Found Inside Tag Value';
  38. SInvalidEnd = 'EOF Found When Length Expected';
  39. SInvalidDerLength = 'DER Length More Than 4 Bytes: %d';
  40. SEndOfStream = 'EOF Found Reading Length';
  41. SNegativeLength = 'Corrupted Stream - Negative Length Found';
  42. SOutOfBoundsLength = 'Corrupted stream - Out of Bounds Length Found';
  43. SUnknownTag = 'Unknown Tag " %d " Encountered';
  44. SEndOfContent = 'Unexpected End-of-Contents Marker';
  45. SIndefiniteLength = 'Indefinite Length Primitive Encoding Encountered';
  46. SUnknownBerObject = 'Unknown BER Object Encountered';
  47. SCorruptedStream = 'Corrupted Stream Detected: %s';
  48. SInvalidLength = 'Negative Lengths not Allowed", "Length"';
  49. SEndOfStreamTwo = 'DEF Length %d " TObject truncated by " %d';
  50. SInvalidBufferLength = 'Buffer Length Not Right For Data';
  51. SMalformedContent = 'Malformed End-of-Contents Marker';
  52. SExtraData = 'Extra Data Found After Object';
  53. SUnRecognizedObjectStream = 'Cannot Recognise Object in Stream';
  54. SUnRecognizedObjectByteArray = 'Cannot Recognise Object in ByteArray';
  55. SIllegalObject = 'Illegal Object in GetInstance: %s, "obj"';
  56. SStrNil = '"Str" Cannot be Nil';
  57. SProcessingError = 'Error Processing Object : "%s"';
  58. SInvalidObject = 'Object Implicit - Explicit Expected.';
  59. SUnknownObject = 'Unknown object in GetInstance: %s, "obj"';
  60. SInvalidSequence = 'Failed to Construct Sequence from byte array: "%s"';
  61. SImplicitObject = 'Implicitly Tagged Object';
  62. SImplicitTag = 'Implicit Tagging for Tag: %d';
  63. SUnknownObjectBER = 'Unknown BER Object Encountered: $%x';
  64. SImplicitTagging = 'Implicit Tagging not Implemented';
  65. SUnConstructedEncoding =
  66. 'Sequences Must Use Constructed Encoding (see X.690 8.9.1/8.10.1)';
  67. SUnConstructedEncoding2 =
  68. 'Sets Must Use Constructed Encoding (see X.690 8.11.1/8.12.1)';
  69. SMalformedObject = 'Malformed Object %s';
  70. SUnSupportedTag = 'Unsupported Tag Number';
  71. SConvertError = 'EIOCryptoLibException Converting Stream to Byte Array: %s';
  72. SEncodingError = 'Encoding Error in GetInstance: %s "obj"';
  73. SDataNil = '"data"';
  74. SInvalidRange = 'Must be in the Range 0 to 7", "padBits"';
  75. SPadBitError = 'If "data" is Empty, "padBits" Must be 0';
  76. SUnalignedData = 'Attempt to Get non-octet Aligned Data from BIT STRING"';
  77. STruncatedBitString = 'Truncated BIT STRING Detected", "octets"';
  78. SNotImplemented = 'Not Implemented %s';
  79. SUnConstructedTag = 'Explicit Tags Must be Constructed (see X.690 8.14.2)';
  80. SParsingError = '%s';
  81. SEmptyInput = 'Input Cannot be Empty "astr"';
  82. SInvalidValue = 'Byte Value Should Have 1 Byte in it'', "val"';
  83. SInvalidBooleanValue = 'BOOLEAN Value Should Have 1 Byte in it", "Value"';
  84. SMalformedEnumerated = 'Malformed Enumerated';
  85. SZeroLength = 'Enumerated has Zero Length, "enc"';
  86. SInvalidEncoding = 'Invalid Encoding Value: %d';
  87. SFewObject = 'Too Few Objects in Input Vector, "v"';
  88. SVectorTooLarge = 'Input Vector too Large", "vector"';
  89. SNoTaggedObjectFound =
  90. 'No Tagged Object Found in Vector. Structure Doesn ''t Seem to be of Type External, "Vector"';
  91. SInvalidEncodingValue = 'Invalid Encoding Value';
  92. SObjectNil = ' "obj" Can''t be Nil';
  93. SValueNil = ' "value" Can''t be Nil';
  94. SMalformedInteger = 'Malformed Integer';
  95. SIdentifierNil = 'Identifier Cannot be Empty';
  96. SInvalidOID = '"String " %s is " not an OID"';
  97. SInvalidBranchId = '"String " %s " not a valid OID branch", "branchID"';
  98. SIllegalCharacters = 'String Contains Illegal Characters "str"';
  99. SObjectEncodeError = 'Cannot Encode Object added to SET';
  100. SIndexOutOfRange = '%d >= %d';
  101. SInitialCapacityNegative = 'InitialCapacity must not be Negative';
  102. SElementNil = 'element cannot be Nil';
  103. SOtherNil = 'other cannot be Nil';
  104. SOtherElementsNil = 'other elements cannot be Nil';
  105. SElementsNil = '"elements" cannot be null, or contain null';
  106. SElementVectorNil = 'elementVector cannot be Nil';
  107. SASN1IntegerPositiveOutOfRangeError =
  108. 'ASN.1 Integer out of positive int range';
  109. SASN1IntegerOutOfRangeError = 'ASN.1 Integer out of int range';
  110. SEnumeratedNegative = 'enumerated must be non-negative';
  111. // ** Start Stream Operations ** //
  112. type
  113. TStreamHelper = class helper for TStream
  114. public
  115. function ReadByte(): Int32;
  116. procedure WriteByte(b: Byte); inline;
  117. end;
  118. type
  119. TStreamSorter = class sealed(TObject)
  120. public
  121. class function Read(input: TStream; var buffer: TCryptoLibByteArray;
  122. offset, count: Int32): Int32; static;
  123. class function ReadByte(input: TStream): Int32; static;
  124. end;
  125. type
  126. TStreamUtils = class sealed(TObject)
  127. strict private
  128. const
  129. BufferSize = Int32(512);
  130. public
  131. class procedure Drain(const inStr: TStream); static;
  132. class function ReadAll(const inStr: TStream): TCryptoLibByteArray;
  133. static; inline;
  134. class function ReadAllLimited(const inStr: TStream; limit: Int32)
  135. : TCryptoLibByteArray; static; inline;
  136. class function ReadFully(const inStr: TStream; var buf: TCryptoLibByteArray)
  137. : Int32; overload; static; inline;
  138. class function ReadFully(const inStr: TStream; var buf: TCryptoLibByteArray;
  139. off, len: Int32): Int32; overload; static;
  140. class procedure PipeAll(const inStr, outStr: TStream); static;
  141. /// <summary>
  142. /// Pipe all bytes from <c>inStr</c> to <c>outStr</c>, throwing <c>
  143. /// EStreamOverflowCryptoLibException</c> if greater than <c>limit</c> bytes in <c>
  144. /// inStr</c>.
  145. /// </summary>
  146. /// <param name="inStr">
  147. /// Input Stream
  148. /// </param>
  149. /// <param name="limit">
  150. /// Limit
  151. /// </param>
  152. /// <param name="outStr">
  153. /// Output Stream
  154. /// </param>
  155. /// <returns>
  156. /// The number of bytes actually transferred, if not greater than <c>
  157. /// limit</c>
  158. /// </returns>
  159. /// <exception cref="EStreamOverflowCryptoLibException" />
  160. class function PipeAllLimited(const inStr: TStream; limit: Int64;
  161. const outStr: TStream): Int64; static;
  162. class procedure WriteBufTo(const buf: TMemoryStream; const output: TStream);
  163. overload; static; inline;
  164. class function WriteBufTo(const buf: TMemoryStream;
  165. const output: TCryptoLibByteArray; offset: Int32): Int32; overload;
  166. static; inline;
  167. class procedure WriteZeroes(const outStr: TStream; count: Int64); static;
  168. end;
  169. type
  170. TBaseInputStream = class abstract(TStream)
  171. {$IFDEF DELPHI}
  172. private
  173. function GetPosition: Int64; inline;
  174. procedure SetPosition(const Pos: Int64); inline;
  175. procedure SetSize64(const NewSize: Int64); inline;
  176. {$ENDIF DELPHI}
  177. protected
  178. {$IFDEF FPC}
  179. function GetPosition: Int64; override;
  180. procedure SetPosition(const Pos: Int64); override;
  181. procedure SetSize64(const NewSize: Int64); override;
  182. {$ENDIF FPC}
  183. function GetSize: Int64; override;
  184. procedure SetSize(NewSize: LongInt); overload; override;
  185. procedure SetSize(const NewSize: Int64); overload; override;
  186. public
  187. function ReadByte: Int32; virtual;
  188. function Read(var buffer; count: LongInt): LongInt; overload; override;
  189. function Write(const buffer; count: LongInt): LongInt; overload; override;
  190. function Read(buffer: TCryptoLibByteArray; offset, count: LongInt)
  191. : LongInt; overload;
  192. {$IFDEF SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD} override {$ELSE} virtual
  193. {$ENDIF SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD};
  194. function Write(const buffer: TCryptoLibByteArray; offset, count: LongInt)
  195. : LongInt; overload; {$IFDEF SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD} override {$ELSE} virtual
  196. {$ENDIF SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD};
  197. function Seek(offset: LongInt; Origin: Word): LongInt; overload; override;
  198. function Seek(const offset: Int64; Origin: TSeekOrigin): Int64;
  199. overload; override;
  200. {$IFNDEF _FIXINSIGHT_}
  201. property Size: Int64 read GetSize write SetSize64;
  202. {$ENDIF}
  203. property Position: Int64 read GetPosition write SetPosition;
  204. end;
  205. type
  206. TFilterStream = class(TStream)
  207. protected
  208. var
  209. Fs: TStream;
  210. function GetPosition: Int64; {$IFDEF FPC} override; {$ENDIF FPC}
  211. procedure SetPosition(const Value: Int64); {$IFDEF FPC} override;
  212. {$ENDIF FPC}
  213. function GetSize: Int64; override;
  214. public
  215. constructor Create(const s: TStream);
  216. property Size: Int64 read GetSize;
  217. property Position: Int64 read GetPosition write SetPosition;
  218. function Seek(const offset: Int64; Origin: TSeekOrigin): Int64; override;
  219. function Read(var buffer; count: LongInt): LongInt; override;
  220. function Write(const buffer; count: LongInt): LongInt; override;
  221. function ReadByte(): Int32;
  222. procedure WriteByte(Value: Byte);
  223. end;
  224. type
  225. TLimitedInputStream = class abstract(TBaseInputStream)
  226. strict private
  227. var
  228. F_limit: Int32;
  229. strict protected
  230. var
  231. F_in: TStream;
  232. procedure SetParentEofDetect(&on: Boolean);
  233. public
  234. constructor Create(inStream: TStream; limit: Int32);
  235. function GetRemaining(): Int32; virtual;
  236. end;
  237. type
  238. TDefiniteLengthInputStream = class(TLimitedInputStream)
  239. strict private
  240. var
  241. F_originalLength, F_remaining: Int32;
  242. function GetRemaining: Int32; reintroduce; inline;
  243. class function GetEmptyBytes: TCryptoLibByteArray; static; inline;
  244. public
  245. constructor Create(inStream: TStream; length: Int32);
  246. function ReadByte(): Int32; override;
  247. function Read(buf: TCryptoLibByteArray; off, len: LongInt)
  248. : LongInt; override;
  249. procedure ReadAllIntoByteArray(var buf: TCryptoLibByteArray);
  250. function ToArray: TCryptoLibByteArray;
  251. property Remaining: Int32 read GetRemaining;
  252. class property EmptyBytes: TCryptoLibByteArray read GetEmptyBytes;
  253. end;
  254. type
  255. /// <summary>
  256. /// a general purpose ASN.1 decoder - note: this class differs from the <br />
  257. /// others in that it returns null after it has read the last object in <br />
  258. /// the stream. If an ASN.1 Null is encountered a DerBER Null object is <br />
  259. /// returned. <br />
  260. /// </summary>
  261. TAsn1InputStream = class(TFilterStream)
  262. strict private
  263. var
  264. Flimit: Int32;
  265. FtmpBuffers: TCryptoLibMatrixByteArray;
  266. FStream: TStream;
  267. /// <summary>
  268. /// build an object given its tag and the number of bytes to construct it
  269. /// from.
  270. /// </summary>
  271. function BuildObject(tag, tagNo, length: Int32): IAsn1Object;
  272. public
  273. constructor Create(const inputStream: TStream); overload;
  274. /// <summary>
  275. /// Create an ASN1InputStream where no DER object will be longer than
  276. /// limit.
  277. /// </summary>
  278. /// <param name="inputStream">
  279. /// stream containing ASN.1 encoded data.
  280. /// </param>
  281. /// <param name="limit">
  282. /// maximum size of a DER encoded object.
  283. /// </param>
  284. constructor Create(const inputStream: TStream; limit: Int32); overload;
  285. destructor Destroy(); override;
  286. /// <summary>
  287. /// the stream is automatically limited to the length of the input array.
  288. /// </summary>
  289. /// <param name="input">
  290. /// array containing ASN.1 encoded data.
  291. /// </param>
  292. constructor Create(const input: TCryptoLibByteArray); overload;
  293. function ReadObject(): IAsn1Object;
  294. function ReadVector(const dIn: TDefiniteLengthInputStream)
  295. : IAsn1EncodableVector; virtual;
  296. function CreateDerSequence(const dIn: TDefiniteLengthInputStream)
  297. : IDerSequence; virtual;
  298. function CreateDerSet(const dIn: TDefiniteLengthInputStream)
  299. : IDerSet; virtual;
  300. class function FindLimit(const input: TStream): Int32; static;
  301. class function ReadTagNumber(const s: TStream; tag: Int32): Int32; static;
  302. class function ReadLength(const s: TStream; limit: Int32): Int32; static;
  303. class function GetBuffer(const defIn: TDefiniteLengthInputStream;
  304. const tmpBuffers: TCryptoLibMatrixByteArray): TCryptoLibByteArray;
  305. static; inline;
  306. class function CreatePrimitiveDerObject(tagNo: Int32;
  307. const defIn: TDefiniteLengthInputStream;
  308. const tmpBuffers: TCryptoLibMatrixByteArray): IAsn1Object; static;
  309. end;
  310. type
  311. TDerOutputStream = class(TFilterStream)
  312. strict private
  313. procedure WriteLength(length: Int32);
  314. strict protected
  315. procedure WriteNull();
  316. public
  317. constructor Create(const os: TStream);
  318. procedure WriteEncoded(tag: Int32;
  319. const bytes: TCryptoLibByteArray); overload;
  320. procedure WriteEncoded(tag: Int32; first: Byte;
  321. const bytes: TCryptoLibByteArray); overload;
  322. procedure WriteEncoded(tag: Int32; const bytes: TCryptoLibByteArray;
  323. offset, length: Int32); overload;
  324. procedure WriteEncoded(flags, tagNo: Int32;
  325. const bytes: TCryptoLibByteArray); overload;
  326. procedure WriteTag(flags, tagNo: Int32);
  327. procedure WriteObject(const obj: IAsn1Encodable); overload; virtual;
  328. procedure WriteObject(const obj: IAsn1Object); overload; virtual;
  329. end;
  330. type
  331. TAsn1OutputStream = class sealed(TDerOutputStream)
  332. public
  333. constructor Create(os: TStream);
  334. end;
  335. type
  336. // TODO Make Obsolete in favour of Asn1OutputStream?
  337. TBerOutputStream = class sealed(TDerOutputStream)
  338. public
  339. constructor Create(os: TStream);
  340. end;
  341. type
  342. TConstructedOctetStream = class(TBaseInputStream)
  343. strict private
  344. var
  345. F_parser: IAsn1StreamParser;
  346. F_first: Boolean;
  347. F_currentStream: TStream;
  348. public
  349. constructor Create(const parser: IAsn1StreamParser);
  350. function Read(buffer: TCryptoLibByteArray; offset, count: LongInt)
  351. : LongInt; override;
  352. function ReadByte(): Int32; override;
  353. end;
  354. type
  355. TIndefiniteLengthInputStream = class(TLimitedInputStream)
  356. strict private
  357. var
  358. F_lookAhead: Int32;
  359. F_eofOn00: Boolean;
  360. function CheckForEof(): Boolean; inline;
  361. function RequireByte(): Int32; inline;
  362. public
  363. constructor Create(inStream: TStream; limit: Int32);
  364. procedure SetEofOn00(eofOn00: Boolean);
  365. function Read(buffer: TCryptoLibByteArray; offset, count: LongInt)
  366. : LongInt; override;
  367. function ReadByte(): Int32; override;
  368. end;
  369. // ** End Stream Operations ** //
  370. type
  371. TCollectionUtilities = class sealed(TObject)
  372. public
  373. class function ToStructuredString(c: TCryptoLibGenericArray<IAsn1Encodable>)
  374. : String; static;
  375. end;
  376. type
  377. TAsn1Encodable = class abstract(TInterfacedObject, IAsn1Encodable,
  378. IAsn1Convertible)
  379. public
  380. const
  381. Der: String = 'DER';
  382. Ber: String = 'BER';
  383. function GetEncoded(): TCryptoLibByteArray; overload;
  384. function GetEncoded(const encoding: String): TCryptoLibByteArray; overload;
  385. /// <summary>
  386. /// Return the DER encoding of the object, null if the DER encoding can
  387. /// not be made.
  388. /// </summary>
  389. /// <returns>
  390. /// return a DER byte array, null otherwise.
  391. /// </returns>
  392. function GetDerEncoded(): TCryptoLibByteArray; overload;
  393. function Equals(const other: IAsn1Convertible): Boolean; reintroduce;
  394. function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
  395. {$ENDIF DELPHI}override;
  396. function ToAsn1Object(): IAsn1Object; virtual; abstract;
  397. class function IsNullOrContainsNull(const data
  398. : TCryptoLibGenericArray<IAsn1Encodable>): Boolean; static;
  399. class function OpenArrayToDynamicArray(const data: array of IAsn1Encodable)
  400. : TCryptoLibGenericArray<IAsn1Encodable>; static;
  401. end;
  402. type
  403. TAsn1Object = class abstract(TAsn1Encodable, IAsn1Object)
  404. strict protected
  405. function Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  406. virtual; abstract;
  407. function Asn1GetHashCode(): Int32; virtual; abstract;
  408. public
  409. /// <summary>Create a base ASN.1 object from a byte array.</summary>
  410. /// <param name="data">The byte array to parse.</param>
  411. /// <returns>The base ASN.1 object represented by the byte array.</returns>
  412. /// <exception cref="IOException">
  413. /// If there is a problem parsing the data, or parsing an object did not exhaust the available data.
  414. /// </exception>
  415. class function FromByteArray(const data: TCryptoLibByteArray)
  416. : IAsn1Object; static;
  417. /// <summary>Read a base ASN.1 object from a stream.</summary>
  418. /// <param name="inStr">The stream to parse.</param>
  419. /// <returns>The base ASN.1 object represented by the byte array.</returns>
  420. /// <exception cref="IOException">If there is a problem parsing the data.</exception>
  421. class function FromStream(const inStr: TStream): IAsn1Object; static;
  422. function ToAsn1Object(): IAsn1Object; override;
  423. procedure Encode(const derOut: TStream); virtual; abstract;
  424. function CallAsn1Equals(const obj: IAsn1Object): Boolean;
  425. function CallAsn1GetHashCode(): Int32;
  426. end;
  427. type
  428. TDerObjectIdentifier = class(TAsn1Object, IDerObjectIdentifier)
  429. strict private
  430. const
  431. LONG_LIMIT = Int64((Int64($7FFFFFFFFFFFFFFF) shr 7) - $7F);
  432. class var
  433. FLock: TCriticalSection;
  434. Fcache: array [0 .. 1023] of IDerObjectIdentifier;
  435. var
  436. Fidentifier: String;
  437. Fbody: TCryptoLibByteArray;
  438. class procedure Boot(); static;
  439. class constructor CreateDerObjectIdentifier();
  440. class destructor DestroyDerObjectIdentifier();
  441. constructor Create(const oid: IDerObjectIdentifier;
  442. const branchID: String); overload;
  443. constructor Create(const bytes: TCryptoLibByteArray); overload;
  444. function GetID: String; inline;
  445. procedure WriteField(const outputStream: TStream;
  446. fieldValue: Int64); overload;
  447. procedure WriteField(const outputStream: TStream;
  448. const fieldValue: TBigInteger); overload;
  449. procedure DoOutput(const bOut: TMemoryStream); overload;
  450. function GetBody(): TCryptoLibByteArray;
  451. class function IsValidBranchID(const branchID: String; start: Int32)
  452. : Boolean; static;
  453. class function IsValidIdentifier(const identifier: String): Boolean; static;
  454. class function MakeOidStringFromBytes(const bytes: TCryptoLibByteArray)
  455. : String; static;
  456. strict protected
  457. function Asn1GetHashCode(): Int32; override;
  458. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  459. public
  460. // /**
  461. // * return an Oid from the passed in object
  462. // *
  463. // * @exception ArgumentException if the object cannot be converted.
  464. // */
  465. class function GetInstance(const obj: TObject): IDerObjectIdentifier;
  466. overload; static;
  467. // /**
  468. // * return an Oid from the passed in byte array
  469. // */
  470. class function GetInstance(const obj: TCryptoLibByteArray)
  471. : IDerObjectIdentifier; overload; static; inline;
  472. // /**
  473. // * return an object Identifier from a tagged object.
  474. // *
  475. // * @param obj the tagged object holding the object we want
  476. // * @param explicitly true if the object is meant to be explicitly
  477. // * tagged false otherwise.
  478. // * @exception ArgumentException if the tagged object cannot
  479. // * be converted.
  480. // */
  481. class function GetInstance(const obj: IAsn1TaggedObject;
  482. explicitly: Boolean): IDerObjectIdentifier; overload; static; inline;
  483. class function FromOctetString(const enc: TCryptoLibByteArray)
  484. : IDerObjectIdentifier; static;
  485. constructor Create(const identifier: String); overload;
  486. property ID: String read GetID;
  487. function Branch(const branchID: String): IDerObjectIdentifier; virtual;
  488. // /**
  489. // * Return true if this oid is an extension of the passed in branch, stem.
  490. // * @param stem the arc or branch that is a possible parent.
  491. // * @return true if the branch is on the passed in stem, false otherwise.
  492. // */
  493. function &on(const stem: IDerObjectIdentifier): Boolean; virtual;
  494. procedure Encode(const derOut: TStream); override;
  495. function ToString(): String; override;
  496. end;
  497. type
  498. /// <summary>
  499. /// Mutable class for building ASN.1 constructed objects such as SETs or
  500. /// SEQUENCEs.
  501. /// </summary>
  502. TAsn1EncodableVector = class sealed(TInterfacedObject, IAsn1EncodableVector)
  503. strict private
  504. const
  505. DefaultCapacity = Int32(10);
  506. var
  507. FElements: TCryptoLibGenericArray<IAsn1Encodable>;
  508. FElementCount: Int32;
  509. FCopyOnWrite: Boolean;
  510. function GetCount: Int32;
  511. function GetSelf(Index: Int32): IAsn1Encodable;
  512. procedure Reallocate(minCapacity: Int32);
  513. class function GetEmptyElements: TCryptoLibGenericArray<IAsn1Encodable>;
  514. static; inline;
  515. public
  516. class function FromEnumerable(const e: TList<IAsn1Encodable>)
  517. : IAsn1EncodableVector; static;
  518. constructor Create(); overload;
  519. constructor Create(initialCapacity: Int32); overload;
  520. constructor Create(const v: array of IAsn1Encodable); overload;
  521. destructor Destroy(); override;
  522. procedure Add(const objs: array of IAsn1Encodable); overload;
  523. procedure Add(const element: IAsn1Encodable); overload;
  524. procedure AddAll(const other: IAsn1EncodableVector);
  525. procedure AddOptional(const objs: array of IAsn1Encodable);
  526. procedure AddOptionalTagged(isExplicit: Boolean; tagNo: Int32;
  527. const obj: IAsn1Encodable);
  528. property Self[Index: Int32]: IAsn1Encodable read GetSelf; default;
  529. property count: Int32 read GetCount;
  530. function GetEnumerable: TCryptoLibGenericArray<IAsn1Encodable>; virtual;
  531. function CopyElements(): TCryptoLibGenericArray<IAsn1Encodable>;
  532. function TakeElements(): TCryptoLibGenericArray<IAsn1Encodable>;
  533. class function CloneElements(const elements
  534. : TCryptoLibGenericArray<IAsn1Encodable>)
  535. : TCryptoLibGenericArray<IAsn1Encodable>; static;
  536. class property EmptyElements: TCryptoLibGenericArray<IAsn1Encodable>
  537. read GetEmptyElements;
  538. end;
  539. type
  540. TAsn1Generator = class abstract(TInterfacedObject, IAsn1Generator)
  541. strict private
  542. var
  543. F_out: TStream;
  544. strict protected
  545. constructor Create(outStream: TStream);
  546. function GetOut: TStream; inline;
  547. property &Out: TStream read GetOut;
  548. public
  549. procedure AddObject(const obj: IAsn1Encodable); virtual; abstract;
  550. function GetRawOutputStream(): TStream; virtual; abstract;
  551. procedure Close(); virtual; abstract;
  552. end;
  553. type
  554. /// <summary>
  555. /// A Null object.
  556. /// </summary>
  557. TAsn1Null = class abstract(TAsn1Object, IAsn1Null)
  558. public
  559. function ToString(): String; override;
  560. end;
  561. type
  562. TAsn1OctetString = class abstract(TAsn1Object, IAsn1OctetString,
  563. IAsn1OctetStringParser)
  564. strict private
  565. var
  566. FStr: TCryptoLibByteArray;
  567. strict protected
  568. function GetStr: TCryptoLibByteArray; inline;
  569. function GetParser: IAsn1OctetStringParser; inline;
  570. function Asn1GetHashCode(): Int32; override;
  571. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  572. public
  573. property Str: TCryptoLibByteArray read GetStr;
  574. property parser: IAsn1OctetStringParser read GetParser;
  575. /// <summary>
  576. /// return an Octet string from a tagged object.
  577. /// </summary>
  578. /// <param name="obj">
  579. /// the tagged object holding the object we want.
  580. /// </param>
  581. /// <param name="isExplicit">
  582. /// explicitly true if the object is meant to be explicitly tagged false
  583. /// otherwise.
  584. /// </param>
  585. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  586. /// if the tagged object cannot be converted.
  587. /// </exception>
  588. class function GetInstance(const obj: IAsn1TaggedObject;
  589. isExplicit: Boolean): IAsn1OctetString; overload; static;
  590. /// <summary>
  591. /// return an Octet string from the given object.
  592. /// </summary>
  593. /// <param name="obj">
  594. /// the object we want converted.
  595. /// </param>
  596. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  597. /// if the object cannot be converted.
  598. /// </exception>
  599. class function GetInstance(const obj: TObject): IAsn1OctetString;
  600. overload; static;
  601. /// <param name="Str">
  602. /// the octets making up the octet string.
  603. /// </param>
  604. constructor Create(const Str: TCryptoLibByteArray); overload;
  605. constructor Create(const obj: IAsn1Encodable); overload;
  606. function GetOctetStream(): TStream;
  607. function GetOctets(): TCryptoLibByteArray; virtual;
  608. function ToString(): String; override;
  609. end;
  610. type
  611. /// <summary>
  612. /// return an Asn1Sequence from the given object.
  613. /// </summary>
  614. TAsn1Sequence = class abstract(TAsn1Object, IAsn1Sequence)
  615. strict private
  616. var
  617. FElements: TCryptoLibGenericArray<IAsn1Encodable>;
  618. type
  619. TAsn1SequenceParserImpl = class sealed(TInterfacedObject,
  620. IAsn1SequenceParserImpl, IAsn1SequenceParser)
  621. strict private
  622. var
  623. Fouter: IAsn1Sequence;
  624. Fmax, Findex: Int32;
  625. public
  626. constructor Create(const outer: IAsn1Sequence);
  627. function ReadObject(): IAsn1Convertible;
  628. function ToAsn1Object(): IAsn1Object;
  629. end;
  630. strict protected
  631. function GetCount: Int32; virtual;
  632. function GetParser: IAsn1SequenceParser; virtual;
  633. function GetSelf(Index: Int32): IAsn1Encodable; virtual;
  634. function Asn1GetHashCode(): Int32; override;
  635. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  636. function GetElements: TCryptoLibGenericArray<IAsn1Encodable>; inline;
  637. constructor Create(); overload;
  638. constructor Create(const element: IAsn1Encodable); overload;
  639. constructor Create(const elements: array of IAsn1Encodable); overload;
  640. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  641. public
  642. destructor Destroy(); override;
  643. function ToString(): String; override;
  644. function GetEnumerable: TCryptoLibGenericArray<IAsn1Encodable>; virtual;
  645. function ToArray(): TCryptoLibGenericArray<IAsn1Encodable>; virtual;
  646. // /**
  647. // * return the object at the sequence position indicated by index.
  648. // *
  649. // * @param index the sequence number (starting at zero) of the object
  650. // * @return the object at the sequence position indicated by index.
  651. // */
  652. property Self[Index: Int32]: IAsn1Encodable read GetSelf; default;
  653. /// <summary>
  654. /// return an Asn1Sequence from the given object.
  655. /// </summary>
  656. /// <param name="obj">
  657. /// the object we want converted.
  658. /// </param>
  659. /// <exception cref="EArgumentCryptoLibException">
  660. /// if the object cannot be converted.
  661. /// </exception>
  662. class function GetInstance(const obj: TObject): IAsn1Sequence;
  663. overload; static;
  664. /// <summary>
  665. /// return an Asn1Sequence from the given object.
  666. /// </summary>
  667. /// <param name="obj">
  668. /// the byte array we want converted.
  669. /// </param>
  670. /// <exception cref="EArgumentCryptoLibException">
  671. /// if the object cannot be converted.
  672. /// </exception>
  673. class function GetInstance(const obj: TCryptoLibByteArray): IAsn1Sequence;
  674. overload; static;
  675. // /**
  676. // * Return an ASN1 sequence from a tagged object. There is a special
  677. // * case here, if an object appears to have been explicitly tagged on
  678. // * reading but we were expecting it to be implicitly tagged in the
  679. // * normal course of events it indicates that we lost the surrounding
  680. // * sequence - so we need to add it back (this will happen if the tagged
  681. // * object is a sequence that contains other sequences). If you are
  682. // * dealing with implicitly tagged sequences you really <b>should</b>
  683. // * be using this method.
  684. // *
  685. // * @param obj the tagged object.
  686. // * @param explicitly true if the object is meant to be explicitly tagged,
  687. // * false otherwise.
  688. // * @exception ArgumentException if the tagged object cannot
  689. // * be converted.
  690. // */
  691. class function GetInstance(const obj: IAsn1TaggedObject;
  692. explicitly: Boolean): IAsn1Sequence; overload; static;
  693. property parser: IAsn1SequenceParser read GetParser;
  694. property count: Int32 read GetCount;
  695. property elements: TCryptoLibGenericArray<IAsn1Encodable> read GetElements;
  696. end;
  697. type
  698. TDerOctetString = class(TAsn1OctetString, IDerOctetString)
  699. public
  700. /// <param name="str">The octets making up the octet string.</param>
  701. constructor Create(const Str: TCryptoLibByteArray); overload;
  702. constructor Create(const obj: IAsn1Encodable); overload;
  703. destructor Destroy(); override;
  704. procedure Encode(const derOut: TStream); overload; override;
  705. class procedure Encode(const derOut: TDerOutputStream;
  706. const bytes: TCryptoLibByteArray; offset, length: Int32); reintroduce;
  707. overload; static; inline;
  708. end;
  709. type
  710. TBerOctetString = class(TDerOctetString, IBerOctetString)
  711. strict private
  712. const
  713. MaxLength = Int32(1000);
  714. var
  715. Focts: TList<IDerOctetString>;
  716. function GenerateOcts(): TList<IDerOctetString>;
  717. class function ToBytes(octs: TList<IDerOctetString>)
  718. : TCryptoLibByteArray; static;
  719. public
  720. /// <inheritdoc />
  721. /// <param name="str">The octets making up the octet string.</param>
  722. constructor Create(const Str: TCryptoLibByteArray); overload;
  723. constructor Create(const octets: TList<IDerOctetString>); overload;
  724. constructor Create(const obj: IAsn1Object); overload;
  725. constructor Create(const obj: IAsn1Encodable); overload;
  726. destructor Destroy(); override;
  727. function GetOctets(): TCryptoLibByteArray; override;
  728. /// <summary>
  729. /// return the DER octets that make up this string.
  730. /// </summary>
  731. function GetEnumerable: TCryptoLibGenericArray<IDerOctetString>; virtual;
  732. procedure Encode(const derOut: TStream); override;
  733. class function FromSequence(const seq: IAsn1Sequence)
  734. : IBerOctetString; static;
  735. end;
  736. type
  737. /// <summary>
  738. /// A Null object.
  739. /// </summary>
  740. TDerNull = class(TAsn1Null, IDerNull)
  741. strict private
  742. class function GetInstance: IDerNull; static; inline;
  743. const
  744. ZeroBytes: TCryptoLibByteArray = Nil;
  745. strict protected
  746. constructor Create(dummy: Int32);
  747. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  748. function Asn1GetHashCode(): Int32; override;
  749. public
  750. procedure Encode(const derOut: TStream); override;
  751. class property Instance: IDerNull read GetInstance;
  752. end;
  753. type
  754. TDerSequence = class(TAsn1Sequence, IDerSequence)
  755. strict private
  756. class function GetEmpty: IDerSequence; static; inline;
  757. public
  758. class function FromVector(const elementVector: IAsn1EncodableVector)
  759. : IDerSequence; static;
  760. /// <summary>
  761. /// create an empty sequence
  762. /// </summary>
  763. constructor Create(); overload;
  764. /// <summary>
  765. /// create a sequence containing one object
  766. /// </summary>
  767. constructor Create(const element: IAsn1Encodable); overload;
  768. constructor Create(const elements: array of IAsn1Encodable); overload;
  769. /// <summary>
  770. /// create a sequence containing a vector of objects.
  771. /// </summary>
  772. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  773. destructor Destroy(); override;
  774. /// <summary>
  775. /// A note on the implementation: <br />As Der requires the constructed,
  776. /// definite-length model to <br />be used for structured types, this
  777. /// varies slightly from the <br />ASN.1 descriptions given. Rather than
  778. /// just outputing Sequence, <br />we also have to specify Constructed,
  779. /// and the objects length. <br />
  780. /// </summary>
  781. procedure Encode(const derOut: TStream); override;
  782. class property Empty: IDerSequence read GetEmpty;
  783. end;
  784. type
  785. TBerSequence = class(TDerSequence, IBerSequence)
  786. strict private
  787. class function GetEmpty: IBerSequence; static; inline;
  788. public
  789. class function FromVector(const elementVector: IAsn1EncodableVector)
  790. : IBerSequence; static;
  791. /// <summary>
  792. /// create an empty sequence
  793. /// </summary>
  794. constructor Create(); overload;
  795. /// <summary>
  796. /// create a sequence containing one object
  797. /// </summary>
  798. constructor Create(const element: IAsn1Encodable); overload;
  799. constructor Create(const elements: array of IAsn1Encodable); overload;
  800. /// <summary>
  801. /// create a sequence containing a vector of objects.
  802. /// </summary>
  803. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  804. destructor Destroy(); override;
  805. /// <summary>
  806. /// A note on the implementation: <br />As Der requires the constructed,
  807. /// definite-length model to <br />be used for structured types, this
  808. /// varies slightly from the <br />ASN.1 descriptions given. Rather than
  809. /// just outputing Sequence, <br />we also have to specify Constructed,
  810. /// and the objects length. <br />
  811. /// </summary>
  812. procedure Encode(const derOut: TStream); override;
  813. class property Empty: IBerSequence read GetEmpty;
  814. end;
  815. type
  816. /// **
  817. // * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
  818. // * a [n] where n is some number - these are assumed to follow the construction
  819. // * rules (as with sequences).
  820. // */
  821. TAsn1TaggedObject = class abstract(TAsn1Object, IAsn1TaggedObject,
  822. IAsn1TaggedObjectParser)
  823. strict private
  824. FtagNo: Int32;
  825. Fexplicitly: Boolean;
  826. Fobj: IAsn1Encodable;
  827. strict protected
  828. // /**
  829. // * @param tagNo the tag number for this object.
  830. // * @param obj the tagged object.
  831. // */
  832. constructor Create(tagNo: Int32; const obj: IAsn1Encodable); overload;
  833. // /**
  834. // * @param explicitly true if the object is explicitly tagged.
  835. // * @param tagNo the tag number for this object.
  836. // * @param obj the tagged object.
  837. // */
  838. constructor Create(explicitly: Boolean; tagNo: Int32;
  839. const obj: IAsn1Encodable); overload;
  840. function GetTagNo: Int32; inline;
  841. function Getexplicitly: Boolean; inline;
  842. function Getobj: IAsn1Encodable; inline;
  843. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  844. function Asn1GetHashCode(): Int32; override;
  845. public
  846. class function IsConstructed(isExplicit: Boolean; const obj: IAsn1Object)
  847. : Boolean; static;
  848. class function GetInstance(const obj: IAsn1TaggedObject;
  849. explicitly: Boolean): IAsn1TaggedObject; overload; static; inline;
  850. class function GetInstance(obj: TObject): IAsn1TaggedObject; overload;
  851. static; inline;
  852. property tagNo: Int32 read GetTagNo;
  853. property explicitly: Boolean read Getexplicitly;
  854. property obj: IAsn1Encodable read Getobj;
  855. // /**
  856. // * return whether or not the object may be explicitly tagged.
  857. // * <p>
  858. // * Note: if the object has been read from an input stream, the only
  859. // * time you can be sure if isExplicit is returning the true state of
  860. // * affairs is if it returns false. An implicitly tagged object may appear
  861. // * to be explicitly tagged, so you need to understand the context under
  862. // * which the reading was done as well, see GetObject below.</p>
  863. // */
  864. function isExplicit(): Boolean; inline;
  865. function IsEmpty(): Boolean; inline;
  866. // /**
  867. // * return whatever was following the tag.
  868. // * <p>
  869. // * Note: tagged objects are generally context dependent if you're
  870. // * trying to extract a tagged object you should be going via the
  871. // * appropriate GetInstance method.</p>
  872. // */
  873. function GetObject(): IAsn1Object; inline;
  874. // /**
  875. // * Return the object held in this tagged object as a parser assuming it has
  876. // * the type of the passed in tag. If the object doesn't have a parser
  877. // * associated with it, the base object is returned.
  878. // */
  879. function GetObjectParser(tag: Int32; isExplicit: Boolean): IAsn1Convertible;
  880. function ToString(): String; override;
  881. end;
  882. type
  883. TAsn1Tags = class sealed(TObject)
  884. public
  885. const
  886. &Boolean = Int32($01);
  887. &Integer = Int32($02);
  888. BitString = Int32($03);
  889. OctetString = Int32($04);
  890. Null = Int32($05);
  891. ObjectIdentifier = Int32($06);
  892. &External = Int32($08);
  893. Enumerated = Int32($0A);
  894. Sequence = Int32($10);
  895. SequenceOf = Int32($10); // for completeness
  896. &Set = Int32($11);
  897. SetOf = Int32($11); // for completeness
  898. NumericString = Int32($12);
  899. PrintableString = Int32($13);
  900. T61String = Int32($14);
  901. VideotexString = Int32($15);
  902. IA5String = Int32($16);
  903. UtcTime = Int32($17);
  904. GeneralizedTime = Int32($18);
  905. GraphicString = Int32($19);
  906. VisibleString = Int32($1A);
  907. GeneralString = Int32($1B);
  908. UniversalString = Int32($1C);
  909. BmpString = Int32($1E);
  910. Utf8String = Int32($0C);
  911. Constructed = Int32($20);
  912. Application = Int32($40);
  913. Tagged = Int32($80);
  914. end;
  915. type
  916. /// <summary>
  917. /// return an Asn1Set from the given object.
  918. /// </summary>
  919. TAsn1Set = class abstract(TAsn1Object, IAsn1Set)
  920. strict private
  921. var
  922. FElements: TCryptoLibGenericArray<IAsn1Encodable>;
  923. function GetDerEncoded(const obj: IAsn1Encodable)
  924. : TCryptoLibByteArray; overload;
  925. /// <summary>
  926. /// return true if a &lt;= b (arrays are assumed padded with zeros).
  927. /// </summary>
  928. class function LessThanOrEqual(const a, b: TCryptoLibByteArray)
  929. : Boolean; static;
  930. type
  931. TAsn1SetParserImpl = class sealed(TInterfacedObject, IAsn1SetParserImpl,
  932. IAsn1SetParser)
  933. strict private
  934. Fouter: IAsn1Set;
  935. Fmax, Findex: Int32;
  936. public
  937. constructor Create(const outer: IAsn1Set);
  938. function ReadObject(): IAsn1Convertible;
  939. function ToAsn1Object(): IAsn1Object;
  940. end;
  941. strict protected
  942. function GetCount: Int32; virtual;
  943. function GetParser: IAsn1SetParser; inline;
  944. function GetSelf(Index: Int32): IAsn1Encodable; virtual;
  945. function Asn1GetHashCode(): Int32; override;
  946. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  947. function GetElements: TCryptoLibGenericArray<IAsn1Encodable>; inline;
  948. procedure Sort();
  949. constructor Create(); overload;
  950. constructor Create(const element: IAsn1Encodable); overload;
  951. constructor Create(const elements: array of IAsn1Encodable); overload;
  952. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  953. public
  954. destructor Destroy(); override;
  955. function ToString(): String; override;
  956. function ToArray(): TCryptoLibGenericArray<IAsn1Encodable>; virtual;
  957. function GetEnumerable: TCryptoLibGenericArray<IAsn1Encodable>; virtual;
  958. // /**
  959. // * return the object at the sequence position indicated by index.
  960. // *
  961. // * @param index the sequence number (starting at zero) of the object
  962. // * @return the object at the sequence position indicated by index.
  963. // */
  964. property Self[Index: Int32]: IAsn1Encodable read GetSelf; default;
  965. /// <summary>
  966. /// return an ASN1Set from the given object.
  967. /// </summary>
  968. /// <param name="obj">
  969. /// the object we want converted.
  970. /// </param>
  971. /// <exception cref="EArgumentCryptoLibException">
  972. /// if the object cannot be converted.
  973. /// </exception>
  974. class function GetInstance(const obj: TObject): IAsn1Set; overload; static;
  975. /// <summary>
  976. /// return an Asn1Set from the given object.
  977. /// </summary>
  978. /// <param name="obj">
  979. /// the byte array we want converted.
  980. /// </param>
  981. /// <exception cref="EArgumentCryptoLibException">
  982. /// if the object cannot be converted.
  983. /// </exception>
  984. class function GetInstance(const obj: TCryptoLibByteArray): IAsn1Set;
  985. overload; static;
  986. // /**
  987. // * Return an ASN1 sequence from a tagged object. There is a special
  988. // * case here, if an object appears to have been explicitly tagged on
  989. // * reading but we were expecting it to be implicitly tagged in the
  990. // * normal course of events it indicates that we lost the surrounding
  991. // * sequence - so we need to add it back (this will happen if the tagged
  992. // * object is a sequence that contains other sequences). If you are
  993. // * dealing with implicitly tagged sequences you really <b>should</b>
  994. // * be using this method.
  995. // *
  996. // * @param obj the tagged object.
  997. // * @param explicitly true if the object is meant to be explicitly tagged,
  998. // * false otherwise.
  999. // * @exception ArgumentException if the tagged object cannot
  1000. // * be converted.
  1001. // */
  1002. class function GetInstance(const obj: IAsn1TaggedObject;
  1003. explicitly: Boolean): IAsn1Set; overload; static;
  1004. property parser: IAsn1SetParser read GetParser;
  1005. property count: Int32 read GetCount;
  1006. property elements: TCryptoLibGenericArray<IAsn1Encodable> read GetElements;
  1007. end;
  1008. type
  1009. /// <summary>
  1010. /// A Der encoded set object
  1011. /// </summary>
  1012. TDerSet = class(TAsn1Set, IDerSet)
  1013. strict private
  1014. class function GetEmpty: IDerSet; static; inline;
  1015. public
  1016. class function FromVector(const elementVector: IAsn1EncodableVector)
  1017. : IDerSet; overload; static;
  1018. class function FromVector(const elementVector: IAsn1EncodableVector;
  1019. needsSorting: Boolean): IDerSet; overload; static;
  1020. /// <summary>
  1021. /// create an empty set
  1022. /// </summary>
  1023. constructor Create(); overload;
  1024. /// <param name="element">
  1025. /// a single object that makes up the set.
  1026. /// </param>
  1027. constructor Create(const element: IAsn1Encodable); overload;
  1028. constructor Create(const elements: array of IAsn1Encodable); overload;
  1029. /// <param name="elementVector">
  1030. /// a vector of objects making up the set.
  1031. /// </param>
  1032. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  1033. constructor Create(const elementVector: IAsn1EncodableVector;
  1034. needsSorting: Boolean); overload;
  1035. destructor Destroy(); override;
  1036. /// <summary>
  1037. /// A note on the implementation: <br />As Der requires the constructed,
  1038. /// definite-length model to <br />be used for structured types, this
  1039. /// varies slightly from the <br />ASN.1 descriptions given. Rather than
  1040. /// just outputing Set, <br />we also have to specify Constructed, and
  1041. /// the objects length. <br />
  1042. /// </summary>
  1043. procedure Encode(const derOut: TStream); override;
  1044. class property Empty: IDerSet read GetEmpty;
  1045. end;
  1046. type
  1047. TAsn1StreamParser = class(TInterfacedObject, IAsn1StreamParser)
  1048. strict private
  1049. var
  1050. F_in: TStream;
  1051. F_limit: Int32;
  1052. FtmpBuffers: TCryptoLibMatrixByteArray;
  1053. procedure Set00Check(enabled: Boolean); inline;
  1054. public
  1055. constructor Create(const inStream: TStream); overload;
  1056. constructor Create(const inStream: TStream; limit: Int32); overload;
  1057. constructor Create(const encoding: TCryptoLibByteArray); overload;
  1058. destructor Destroy; override;
  1059. function ReadIndef(tagValue: Int32): IAsn1Convertible;
  1060. function ReadImplicit(Constructed: Boolean; tag: Int32): IAsn1Convertible;
  1061. function ReadTaggedObject(Constructed: Boolean; tag: Int32): IAsn1Object;
  1062. function ReadObject(): IAsn1Convertible; virtual;
  1063. function ReadVector(): IAsn1EncodableVector; inline;
  1064. end;
  1065. type
  1066. TDerSetParser = class(TInterfacedObject, IAsn1SetParser, IAsn1Convertible,
  1067. IDerSetParser)
  1068. strict private
  1069. var
  1070. F_parser: IAsn1StreamParser;
  1071. public
  1072. constructor Create(const parser: IAsn1StreamParser);
  1073. function ReadObject(): IAsn1Convertible; inline;
  1074. function ToAsn1Object(): IAsn1Object; inline;
  1075. end;
  1076. type
  1077. TDerSequenceParser = class(TInterfacedObject, IAsn1SequenceParser,
  1078. IAsn1Convertible, IDerSequenceParser)
  1079. strict private
  1080. var
  1081. F_parser: IAsn1StreamParser;
  1082. public
  1083. constructor Create(const parser: IAsn1StreamParser);
  1084. function ReadObject(): IAsn1Convertible; inline;
  1085. function ToAsn1Object(): IAsn1Object; inline;
  1086. end;
  1087. type
  1088. /// <summary>
  1089. /// Base class for an application specific object
  1090. /// </summary>
  1091. TDerApplicationSpecific = class(TAsn1Object, IDerApplicationSpecific)
  1092. strict private
  1093. var
  1094. FisConstructed: Boolean;
  1095. Ftag: Int32;
  1096. Foctets: TCryptoLibByteArray;
  1097. class function ReplaceTagNumber(newTag: Int32;
  1098. const input: TCryptoLibByteArray): TCryptoLibByteArray; static;
  1099. strict protected
  1100. function GetApplicationTag: Int32; inline;
  1101. function GetLengthOfHeader(const data: TCryptoLibByteArray): Int32; inline;
  1102. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1103. function Asn1GetHashCode(): Int32; override;
  1104. public
  1105. constructor Create(IsConstructed: Boolean; tag: Int32;
  1106. const octets: TCryptoLibByteArray); overload;
  1107. constructor Create(tag: Int32; const octets: TCryptoLibByteArray); overload;
  1108. constructor Create(tag: Int32; const obj: IAsn1Encodable); overload;
  1109. constructor Create(isExplicit: Boolean; tag: Int32;
  1110. const obj: IAsn1Encodable); overload;
  1111. constructor Create(tagNo: Int32; const vec: IAsn1EncodableVector); overload;
  1112. function IsConstructed(): Boolean; inline;
  1113. function GetContents(): TCryptoLibByteArray; inline;
  1114. /// <summary>
  1115. /// Return the enclosed object assuming explicit tagging.
  1116. /// </summary>
  1117. /// <returns>
  1118. /// the resulting object
  1119. /// </returns>
  1120. /// <exception cref="ClpCryptoLibTypes|EIOCryptoLibException">
  1121. /// if reconstruction fails.
  1122. /// </exception>
  1123. function GetObject(): IAsn1Object; overload; inline;
  1124. /// <summary>
  1125. /// Return the enclosed object assuming implicit tagging.
  1126. /// </summary>
  1127. /// <param name="derTagNo">
  1128. /// the type tag that should be applied to the object's contents.
  1129. /// </param>
  1130. /// <returns>
  1131. /// the resulting object
  1132. /// </returns>
  1133. /// <exception cref="ClpCryptoLibTypes|EIOCryptoLibException">
  1134. /// if reconstruction fails.
  1135. /// </exception>
  1136. function GetObject(derTagNo: Int32): IAsn1Object; overload; inline;
  1137. procedure Encode(const derOut: TStream); override;
  1138. property ApplicationTag: Int32 read GetApplicationTag;
  1139. end;
  1140. type
  1141. TBerApplicationSpecific = class(TDerApplicationSpecific,
  1142. IBerApplicationSpecific)
  1143. public
  1144. constructor Create(tagNo: Int32; const vec: IAsn1EncodableVector);
  1145. end;
  1146. type
  1147. TBerOctetStringParser = class(TInterfacedObject, IAsn1OctetStringParser,
  1148. IAsn1Convertible, IBerOctetStringParser)
  1149. strict private
  1150. var
  1151. F_parser: IAsn1StreamParser;
  1152. public
  1153. constructor Create(const parser: IAsn1StreamParser);
  1154. function GetOctetStream(): TStream; inline;
  1155. function ToAsn1Object(): IAsn1Object;
  1156. end;
  1157. type
  1158. TBerApplicationSpecificParser = class(TInterfacedObject,
  1159. IAsn1ApplicationSpecificParser, IAsn1Convertible,
  1160. IBerApplicationSpecificParser)
  1161. strict private
  1162. var
  1163. F_tag: Int32;
  1164. F_parser: IAsn1StreamParser;
  1165. public
  1166. constructor Create(tag: Int32; const parser: IAsn1StreamParser);
  1167. function ReadObject(): IAsn1Convertible; inline;
  1168. function ToAsn1Object(): IAsn1Object; inline;
  1169. end;
  1170. type
  1171. TDerStringBase = class abstract(TAsn1Object, IAsn1String, IDerStringBase)
  1172. strict protected
  1173. constructor Create();
  1174. function Asn1GetHashCode(): Int32; override;
  1175. public
  1176. function GetString(): String; virtual; abstract;
  1177. function ToString(): String; override;
  1178. end;
  1179. type
  1180. /// <summary>
  1181. /// Der Bit string object.
  1182. /// </summary>
  1183. TDerBitString = class(TDerStringBase, IDerBitString)
  1184. strict private
  1185. const
  1186. FTable: array [0 .. 15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7',
  1187. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
  1188. strict protected
  1189. var
  1190. FmData: TCryptoLibByteArray;
  1191. FmPadBits: Int32;
  1192. function GetmPadBits: Int32; inline;
  1193. function GetmData: TCryptoLibByteArray; inline;
  1194. function Asn1GetHashCode(): Int32; override;
  1195. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1196. property mPadBits: Int32 read GetmPadBits;
  1197. property mData: TCryptoLibByteArray read GetmData;
  1198. public
  1199. constructor Create(const data: TCryptoLibByteArray;
  1200. padBits: Int32); overload;
  1201. constructor Create(const data: TCryptoLibByteArray); overload;
  1202. constructor Create(namedBits: Int32); overload;
  1203. constructor Create(const obj: IAsn1Encodable); overload;
  1204. function GetString(): String; override;
  1205. function GetOctets(): TCryptoLibByteArray; virtual;
  1206. function GetBytes(): TCryptoLibByteArray; virtual;
  1207. procedure Encode(const derOut: TStream); override;
  1208. function GetInt32Value: Int32; virtual;
  1209. property Int32Value: Int32 read GetInt32Value;
  1210. /// <summary>
  1211. /// return a Der Bit string from the passed in object
  1212. /// </summary>
  1213. /// <param name="obj">
  1214. /// a Bit string or an object that can be converted into one.
  1215. /// </param>
  1216. /// <returns>
  1217. /// return a Der Bit string instance, or null.
  1218. /// </returns>
  1219. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1220. /// if the object cannot be converted.
  1221. /// </exception>
  1222. class function GetInstance(const obj: TObject): IDerBitString; overload;
  1223. static; inline;
  1224. class function GetInstance(const obj: TCryptoLibByteArray): IDerBitString;
  1225. overload; static;
  1226. /// <summary>
  1227. /// return a Der Bit string from a tagged object.
  1228. /// </summary>
  1229. /// <param name="obj">
  1230. /// the tagged object holding the object we want
  1231. /// </param>
  1232. /// <param name="isExplicit">
  1233. /// true if the object is meant to be explicitly tagged false otherwise.
  1234. /// </param>
  1235. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1236. /// if the tagged object cannot be converted.
  1237. /// </exception>
  1238. class function GetInstance(const obj: IAsn1TaggedObject;
  1239. isExplicit: Boolean): IDerBitString; overload; static; inline;
  1240. class function FromAsn1Octets(const octets: TCryptoLibByteArray)
  1241. : IDerBitString; static;
  1242. end;
  1243. type
  1244. TBerBitString = class(TDerBitString, IBerBitString)
  1245. public
  1246. constructor Create(const data: TCryptoLibByteArray;
  1247. padBits: Int32); overload;
  1248. constructor Create(const data: TCryptoLibByteArray); overload;
  1249. constructor Create(namedBits: Int32); overload;
  1250. constructor Create(const obj: IAsn1Encodable); overload;
  1251. procedure Encode(const derOut: TStream); override;
  1252. end;
  1253. type
  1254. TBerGenerator = class abstract(TAsn1Generator, IBerGenerator)
  1255. strict private
  1256. var
  1257. F_tagged, F_isExplicit: Boolean;
  1258. F_tagNo: Int32;
  1259. strict protected
  1260. constructor Create(outStream: TStream); overload;
  1261. constructor Create(outStream: TStream; tagNo: Int32;
  1262. isExplicit: Boolean); overload;
  1263. procedure WriteHdr(tag: Int32);
  1264. procedure WriteBerHeader(tag: Int32);
  1265. procedure WriteBerBody(contentStream: TStream);
  1266. procedure WriteBerEnd();
  1267. public
  1268. procedure AddObject(const obj: IAsn1Encodable); override;
  1269. function GetRawOutputStream(): TStream; override;
  1270. procedure Close(); override;
  1271. end;
  1272. type
  1273. /// <summary>
  1274. /// A BER Null object.
  1275. /// </summary>
  1276. TBerNull = class sealed(TDerNull, IBerNull)
  1277. strict private
  1278. class function GetInstance: IBerNull; static; inline;
  1279. constructor Create(dummy: Int32);
  1280. public
  1281. procedure Encode(const derOut: TStream); override;
  1282. class property Instance: IBerNull read GetInstance;
  1283. end;
  1284. type
  1285. TBerSequenceGenerator = class(TBerGenerator, IBerSequenceGenerator)
  1286. public
  1287. constructor Create(outStream: TStream); overload;
  1288. constructor Create(outStream: TStream; tagNo: Int32;
  1289. isExplicit: Boolean); overload;
  1290. end;
  1291. type
  1292. TBerSequenceParser = class(TInterfacedObject, IAsn1SequenceParser,
  1293. IAsn1Convertible, IBerSequenceParser)
  1294. strict private
  1295. var
  1296. F_parser: IAsn1StreamParser;
  1297. public
  1298. constructor Create(const parser: IAsn1StreamParser);
  1299. function ReadObject(): IAsn1Convertible; inline;
  1300. function ToAsn1Object(): IAsn1Object; inline;
  1301. end;
  1302. type
  1303. /// <summary>
  1304. /// A Ber encoded set object
  1305. /// </summary>
  1306. TBerSet = class sealed(TDerSet, IBerSet)
  1307. strict private
  1308. class function GetEmpty: IBerSet; static; inline;
  1309. public
  1310. class function FromVector(const elementVector: IAsn1EncodableVector)
  1311. : IBerSet; overload; static;
  1312. class function FromVector(const elementVector: IAsn1EncodableVector;
  1313. needsSorting: Boolean): IBerSet; overload; static;
  1314. /// <summary>
  1315. /// create an empty set
  1316. /// </summary>
  1317. constructor Create(); overload;
  1318. /// <param name="element">
  1319. /// a single object that makes up the set.
  1320. /// </param>
  1321. constructor Create(const element: IAsn1Encodable); overload;
  1322. /// <param name="elementVector">
  1323. /// a vector of objects making up the set.
  1324. /// </param>
  1325. constructor Create(const elementVector: IAsn1EncodableVector); overload;
  1326. constructor Create(const v: IAsn1EncodableVector;
  1327. needsSorting: Boolean); overload;
  1328. destructor Destroy(); override;
  1329. /// <summary>
  1330. /// A note on the implementation: <br />As Ber requires the constructed,
  1331. /// definite-length model to <br />be used for structured types, this
  1332. /// varies slightly from the <br />ASN.1 descriptions given. Rather than
  1333. /// just outputing Set, <br />we also have to specify Constructed, and
  1334. /// the objects length. <br />
  1335. /// </summary>
  1336. procedure Encode(const derOut: TStream); override;
  1337. class property Empty: IBerSet read GetEmpty;
  1338. end;
  1339. type
  1340. TBerSetParser = class(TInterfacedObject, IAsn1SetParser, IAsn1Convertible,
  1341. IBerSetParser)
  1342. strict private
  1343. var
  1344. F_parser: IAsn1StreamParser;
  1345. public
  1346. constructor Create(const parser: IAsn1StreamParser);
  1347. function ReadObject(): IAsn1Convertible; inline;
  1348. function ToAsn1Object(): IAsn1Object; inline;
  1349. end;
  1350. type
  1351. /// <summary>
  1352. /// DER TaggedObject - in ASN.1 notation this is any object preceded by <br />
  1353. /// a [n] where n is some number - these are assumed to follow the
  1354. /// construction <br />rules (as with sequences). <br />
  1355. /// </summary>
  1356. TDerTaggedObject = class(TAsn1TaggedObject, IDerTaggedObject)
  1357. public
  1358. /// <param name="tagNo">
  1359. /// the tag number for this object.
  1360. /// </param>
  1361. /// <param name="obj">
  1362. /// the tagged object.
  1363. /// </param>
  1364. constructor Create(tagNo: Int32; const obj: IAsn1Encodable); overload;
  1365. /// <param name="explicitly">
  1366. /// true if an explicitly tagged object.
  1367. /// </param>
  1368. /// <param name="tagNo">
  1369. /// the tag number for this object.
  1370. /// </param>
  1371. /// <param name="obj">
  1372. /// the tagged object.
  1373. /// </param>
  1374. constructor Create(explicitly: Boolean; tagNo: Int32;
  1375. const obj: IAsn1Encodable); overload;
  1376. /// <summary>
  1377. /// create an implicitly tagged object that contains a zero length
  1378. /// sequence.
  1379. /// </summary>
  1380. /// <param name="tagNo">
  1381. /// the tag number for this object.
  1382. /// </param>
  1383. constructor Create(tagNo: Int32); overload;
  1384. procedure Encode(const derOut: TStream); override;
  1385. end;
  1386. type
  1387. /// <summary>
  1388. /// BER TaggedObject - in ASN.1 notation this is any object preceded by <br />
  1389. /// a [n] where n is some number - these are assumed to follow the
  1390. /// construction <br />rules (as with sequences). <br />
  1391. /// </summary>
  1392. TBerTaggedObject = class(TDerTaggedObject, IBerTaggedObject)
  1393. public
  1394. /// <param name="tagNo">
  1395. /// the tag number for this object.
  1396. /// </param>
  1397. /// <param name="obj">
  1398. /// the tagged object.
  1399. /// </param>
  1400. constructor Create(tagNo: Int32; const obj: IAsn1Encodable); overload;
  1401. /// <param name="explicitly">
  1402. /// true if an explicitly tagged object.
  1403. /// </param>
  1404. /// <param name="tagNo">
  1405. /// the tag number for this object.
  1406. /// </param>
  1407. /// <param name="obj">
  1408. /// the tagged object.
  1409. /// </param>
  1410. constructor Create(explicitly: Boolean; tagNo: Int32;
  1411. const obj: IAsn1Encodable); overload;
  1412. /// <summary>
  1413. /// create an implicitly tagged object that contains a zero length
  1414. /// sequence.
  1415. /// </summary>
  1416. /// <param name="tagNo">
  1417. /// the tag number for this object.
  1418. /// </param>
  1419. constructor Create(tagNo: Int32); overload;
  1420. procedure Encode(const derOut: TStream); override;
  1421. end;
  1422. type
  1423. TBerTaggedObjectParser = class(TInterfacedObject, IAsn1TaggedObjectParser,
  1424. IAsn1Convertible, IBerTaggedObjectParser)
  1425. strict private
  1426. var
  1427. F_constructed: Boolean;
  1428. F_tagNumber: Int32;
  1429. F_parser: IAsn1StreamParser;
  1430. function GetIsConstructed: Boolean; inline;
  1431. function GetTagNo: Int32; inline;
  1432. public
  1433. constructor Create(Constructed: Boolean; tagNumber: Int32;
  1434. const parser: IAsn1StreamParser);
  1435. destructor Destroy; override;
  1436. function GetObjectParser(tag: Int32; isExplicit: Boolean)
  1437. : IAsn1Convertible; inline;
  1438. function ToAsn1Object(): IAsn1Object;
  1439. property IsConstructed: Boolean read GetIsConstructed;
  1440. property tagNo: Int32 read GetTagNo;
  1441. end;
  1442. type
  1443. TDerBmpString = class(TDerStringBase, IDerBmpString)
  1444. strict private
  1445. var
  1446. FStr: String;
  1447. function GetStr: String; inline;
  1448. strict protected
  1449. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1450. public
  1451. property Str: String read GetStr;
  1452. /// <summary>
  1453. /// basic constructor - byte encoded string.
  1454. /// </summary>
  1455. constructor Create(const astr: TCryptoLibByteArray); overload;
  1456. /// <summary>
  1457. /// basic constructor
  1458. /// </summary>
  1459. constructor Create(const astr: String); overload;
  1460. function GetString(): String; override;
  1461. procedure Encode(const derOut: TStream); override;
  1462. /// <summary>
  1463. /// return a BMP string from the given object.
  1464. /// </summary>
  1465. /// <param name="obj">
  1466. /// the object we want converted.
  1467. /// </param>
  1468. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1469. /// if the object cannot be converted.
  1470. /// </exception>
  1471. class function GetInstance(const obj: TObject): IDerBmpString; overload;
  1472. static; inline;
  1473. /// <summary>
  1474. /// return a BMP string from a tagged object.
  1475. /// </summary>
  1476. /// <param name="obj">
  1477. /// the tagged object holding the object we want
  1478. /// </param>
  1479. /// <param name="isExplicit">
  1480. /// true if the object is meant to be explicitly tagged false otherwise.
  1481. /// </param>
  1482. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1483. /// if the tagged object cannot be converted.
  1484. /// </exception>
  1485. class function GetInstance(const obj: IAsn1TaggedObject;
  1486. isExplicit: Boolean): IDerBmpString; overload; static; inline;
  1487. end;
  1488. type
  1489. TDerBoolean = class(TAsn1Object, IDerBoolean)
  1490. strict private
  1491. var
  1492. Fvalue: Byte;
  1493. function GetIsTrue: Boolean; inline;
  1494. constructor Create(Value: Boolean); overload;
  1495. class function GetFalse: IDerBoolean; static; inline;
  1496. class function GetTrue: IDerBoolean; static; inline;
  1497. strict protected
  1498. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1499. function Asn1GetHashCode(): Int32; override;
  1500. public
  1501. constructor Create(const val: TCryptoLibByteArray); overload;
  1502. procedure Encode(const derOut: TStream); override;
  1503. function ToString(): String; override;
  1504. property IsTrue: Boolean read GetIsTrue;
  1505. class property True: IDerBoolean read GetTrue;
  1506. class property False: IDerBoolean read GetFalse;
  1507. /// <summary>
  1508. /// return a DerBoolean from the passed in object.
  1509. /// </summary>
  1510. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1511. /// if the object cannot be converted.
  1512. /// </exception>
  1513. class function GetInstance(const obj: TObject): IDerBoolean; overload;
  1514. static; inline;
  1515. /// <summary>
  1516. /// return a DerBoolean from the passed in boolean.
  1517. /// </summary>
  1518. class function GetInstance(Value: Boolean): IDerBoolean; overload;
  1519. static; inline;
  1520. /// <summary>
  1521. /// return a Boolean from a tagged object.
  1522. /// </summary>
  1523. /// <param name="obj">
  1524. /// the tagged object holding the object we want
  1525. /// </param>
  1526. /// <param name="isExplicit">
  1527. /// explicitly true if the object is meant to be explicitly tagged false
  1528. /// otherwise.
  1529. /// </param>
  1530. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1531. /// if the tagged object cannot be converted.
  1532. /// </exception>
  1533. class function GetInstance(const obj: IAsn1TaggedObject;
  1534. isExplicit: Boolean): IDerBoolean; overload; static; inline;
  1535. class function FromOctetString(const Value: TCryptoLibByteArray)
  1536. : IDerBoolean; static;
  1537. end;
  1538. type
  1539. TDerEnumerated = class(TAsn1Object, IDerEnumerated)
  1540. strict private
  1541. class var
  1542. Fcache: array [0 .. 11] of IDerEnumerated;
  1543. var
  1544. Fbytes: TCryptoLibByteArray;
  1545. FStart: Int32;
  1546. function GetValue: TBigInteger; inline;
  1547. function GetBytes: TCryptoLibByteArray; inline;
  1548. function GetIntValueExact: Int32; inline;
  1549. strict protected
  1550. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1551. function Asn1GetHashCode(): Int32; override;
  1552. public
  1553. constructor Create(val: Int32); overload;
  1554. constructor Create(val: Int64); overload;
  1555. constructor Create(const val: TBigInteger); overload;
  1556. constructor Create(const bytes: TCryptoLibByteArray); overload;
  1557. procedure Encode(const derOut: TStream); override;
  1558. property Value: TBigInteger read GetValue;
  1559. property bytes: TCryptoLibByteArray read GetBytes;
  1560. property IntValueExact: Int32 read GetIntValueExact;
  1561. function HasValue(const x: TBigInteger): Boolean;
  1562. /// <summary>
  1563. /// return an integer from the passed in object
  1564. /// </summary>
  1565. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1566. /// if the object cannot be converted.
  1567. /// </exception>
  1568. class function GetInstance(const obj: TObject): IDerEnumerated; overload;
  1569. static; inline;
  1570. /// <summary>
  1571. /// return an Enumerated from a tagged object.
  1572. /// </summary>
  1573. /// <param name="obj">
  1574. /// the tagged object holding the object we want
  1575. /// </param>
  1576. /// <param name="isExplicit">
  1577. /// true if the object is meant to be explicitly tagged false otherwise.
  1578. /// </param>
  1579. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1580. /// if the tagged object cannot be converted.
  1581. /// </exception>
  1582. class function GetInstance(const obj: IAsn1TaggedObject;
  1583. isExplicit: Boolean): IDerEnumerated; overload; static; inline;
  1584. class function FromOctetString(const enc: TCryptoLibByteArray)
  1585. : IDerEnumerated; static;
  1586. end;
  1587. type
  1588. TDerGraphicString = class(TDerStringBase, IDerGraphicString)
  1589. strict private
  1590. var
  1591. FmString: TCryptoLibByteArray;
  1592. function GetmString: TCryptoLibByteArray; inline;
  1593. protected
  1594. function Asn1GetHashCode(): Int32; override;
  1595. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1596. public
  1597. property mString: TCryptoLibByteArray read GetmString;
  1598. /// <summary>
  1599. /// basic constructor - with bytes.
  1600. /// </summary>
  1601. /// <param name="encoding">
  1602. /// the byte encoding of the characters making up the string.
  1603. /// </param>
  1604. constructor Create(const encoding: TCryptoLibByteArray);
  1605. function GetString(): String; override;
  1606. function GetOctets(): TCryptoLibByteArray; inline;
  1607. procedure Encode(const derOut: TStream); override;
  1608. /// <summary>
  1609. /// return a Graphic String from the passed in object
  1610. /// </summary>
  1611. /// <param name="obj">
  1612. /// a DerGraphicString or an object that can be converted into one.
  1613. /// </param>
  1614. /// <returns>
  1615. /// return a DerGraphicString instance, or null.
  1616. /// </returns>
  1617. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1618. /// if the object cannot be converted.
  1619. /// </exception>
  1620. class function GetInstance(const obj: TObject): IDerGraphicString; overload;
  1621. static; inline;
  1622. class function GetInstance(const obj: TCryptoLibByteArray)
  1623. : IDerGraphicString; overload; static;
  1624. /// <summary>
  1625. /// return a Graphic string from a tagged object.
  1626. /// </summary>
  1627. /// <param name="obj">
  1628. /// the tagged object holding the object we want
  1629. /// </param>
  1630. /// <param name="isExplicit">
  1631. /// true if the object is meant to be explicitly tagged false otherwise.
  1632. /// </param>
  1633. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1634. /// if the tagged object cannot be converted.
  1635. /// </exception>
  1636. class function GetInstance(const obj: IAsn1TaggedObject;
  1637. isExplicit: Boolean): IDerGraphicString; overload; static; inline;
  1638. end;
  1639. type
  1640. /// <summary>
  1641. /// Class representing the DER-type External
  1642. /// </summary>
  1643. TDerExternal = class(TAsn1Object, IDerExternal)
  1644. strict private
  1645. var
  1646. FdirectReference: IDerObjectIdentifier;
  1647. FindirectReference: IDerInteger;
  1648. FdataValueDescriptor, FexternalContent: IAsn1Object;
  1649. Fencoding: Int32;
  1650. function GetDataValueDescriptor: IAsn1Object;
  1651. function GetDirectReference: IDerObjectIdentifier;
  1652. /// <summary>
  1653. /// <para>
  1654. /// The encoding of the content. Valid values are
  1655. /// </para>
  1656. /// <para>
  1657. /// &lt;ul&gt; <br />&lt;li&gt;&lt;code&gt;0&lt;/code&gt;
  1658. /// single-ASN1-type&lt;/li&gt; <br />
  1659. /// &lt;li&gt;&lt;code&gt;1&lt;/code&gt; OCTET STRING&lt;/li&gt; <br />
  1660. /// &lt;li&gt;&lt;code&gt;2&lt;/code&gt; BIT STRING&lt;/li&gt; <br />
  1661. /// &lt;/ul&gt;
  1662. /// </para>
  1663. /// </summary>
  1664. function GetEncoding: Int32;
  1665. function GetExternalContent: IAsn1Object;
  1666. function GetIndirectReference: IDerInteger;
  1667. procedure SetDataValueDescriptor(const Value: IAsn1Object);
  1668. procedure SetDirectReference(const Value: IDerObjectIdentifier);
  1669. procedure SetEncoding(const Value: Int32);
  1670. procedure SetExternalContent(const Value: IAsn1Object);
  1671. procedure SetIndirectReference(const Value: IDerInteger);
  1672. class function GetObjFromVector(const v: IAsn1EncodableVector; Index: Int32)
  1673. : IAsn1Object; static; inline;
  1674. class procedure WriteEncodable(ms: TMemoryStream; const e: IAsn1Encodable);
  1675. static; inline;
  1676. strict protected
  1677. function Asn1GetHashCode(): Int32; override;
  1678. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1679. public
  1680. constructor Create(const vector: IAsn1EncodableVector); overload;
  1681. /// <summary>
  1682. /// Creates a new instance of DerExternal <br />See X.690 for more
  1683. /// informations about the meaning of these parameters
  1684. /// </summary>
  1685. /// <param name="directReference">
  1686. /// The direct reference or &lt;code&gt;null&lt;/code&gt; if not set.
  1687. /// </param>
  1688. /// <param name="indirectReference">
  1689. /// The indirect reference or &lt;code&gt;null&lt;/code&gt; if not set.
  1690. /// </param>
  1691. /// <param name="dataValueDescriptor">
  1692. /// The data value descriptor or &lt;code&gt;null&lt;/code&gt; if not
  1693. /// set.
  1694. /// </param>
  1695. /// <param name="externalData">
  1696. /// The external data in its encoded form.
  1697. /// </param>
  1698. constructor Create(const directReference: IDerObjectIdentifier;
  1699. const indirectReference: IDerInteger;
  1700. const dataValueDescriptor: IAsn1Object;
  1701. const externalData: IDerTaggedObject); overload;
  1702. constructor Create(const directReference: IDerObjectIdentifier;
  1703. const indirectReference: IDerInteger;
  1704. const dataValueDescriptor: IAsn1Object; encoding: Int32;
  1705. const externalData: IAsn1Object); overload;
  1706. procedure Encode(const derOut: TStream); override;
  1707. property dataValueDescriptor: IAsn1Object read GetDataValueDescriptor
  1708. write SetDataValueDescriptor;
  1709. property directReference: IDerObjectIdentifier read GetDirectReference
  1710. write SetDirectReference;
  1711. property encoding: Int32 read GetEncoding write SetEncoding;
  1712. property ExternalContent: IAsn1Object read GetExternalContent
  1713. write SetExternalContent;
  1714. property indirectReference: IDerInteger read GetIndirectReference
  1715. write SetIndirectReference;
  1716. end;
  1717. type
  1718. TDerInteger = class sealed(TAsn1Object, IDerInteger)
  1719. strict private
  1720. class var
  1721. FAllowUnsafeInteger: Boolean;
  1722. class constructor CreateDerInteger();
  1723. var
  1724. Fbytes: TCryptoLibByteArray;
  1725. FStart: Int32;
  1726. function GetBytes: TCryptoLibByteArray; inline;
  1727. function GetPositiveValue: TBigInteger; inline;
  1728. function GetValue: TBigInteger; inline;
  1729. function GetIntPositiveValueExact: Int32; inline;
  1730. function GetIntValueExact: Int32; inline;
  1731. class function GetAllowUnsafeInteger: Boolean; static; inline;
  1732. class procedure SetAllowUnsafeInteger(const Value: Boolean); static; inline;
  1733. strict protected
  1734. function Asn1GetHashCode(): Int32; override;
  1735. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1736. public
  1737. const
  1738. SignExtSigned = Int32(-1);
  1739. SignExtUnsigned = Int32($FF);
  1740. constructor Create(Value: Int32); overload;
  1741. constructor Create(Value: Int64); overload;
  1742. constructor Create(const Value: TBigInteger); overload;
  1743. constructor Create(const bytes: TCryptoLibByteArray); overload;
  1744. constructor Create(const bytes: TCryptoLibByteArray;
  1745. clone: Boolean); overload;
  1746. property Value: TBigInteger read GetValue;
  1747. property PositiveValue: TBigInteger read GetPositiveValue;
  1748. property IntPositiveValueExact: Int32 read GetIntPositiveValueExact;
  1749. property IntValueExact: Int32 read GetIntValueExact;
  1750. property bytes: TCryptoLibByteArray read GetBytes;
  1751. procedure Encode(const derOut: TStream); override;
  1752. function HasValue(const x: TBigInteger): Boolean;
  1753. function ToString(): String; override;
  1754. // /**
  1755. // * return an integer from the passed in object
  1756. // *
  1757. // * @exception ArgumentException if the object cannot be converted.
  1758. // */
  1759. class function GetInstance(const obj: TObject): IDerInteger;
  1760. overload; static;
  1761. // /**
  1762. // * return an Integer from a tagged object.
  1763. // *
  1764. // * @param obj the tagged object holding the object we want
  1765. // * @param isExplicit true if the object is meant to be explicitly
  1766. // * tagged false otherwise.
  1767. // * @exception ArgumentException if the tagged object cannot
  1768. // * be converted.
  1769. // */
  1770. class function GetInstance(const obj: IAsn1TaggedObject;
  1771. isExplicit: Boolean): IDerInteger; overload; static; inline;
  1772. /// <summary>
  1773. /// Apply the correct validation for an INTEGER primitive following the
  1774. /// BER rules.
  1775. /// </summary>
  1776. /// <param name="bytes">
  1777. /// The raw encoding of the integer.
  1778. /// </param>
  1779. /// <returns>
  1780. /// if the (in)put fails this validation.
  1781. /// </returns>
  1782. class function IsMalformed(const bytes: TCryptoLibByteArray)
  1783. : Boolean; static;
  1784. class function SignBytesToSkip(const bytes: TCryptoLibByteArray)
  1785. : Int32; static;
  1786. class function IntValue(const bytes: TCryptoLibByteArray;
  1787. start, signExt: Int32): Int32; static;
  1788. class property AllowUnsafeInteger: Boolean read GetAllowUnsafeInteger
  1789. write SetAllowUnsafeInteger;
  1790. end;
  1791. type
  1792. TDerExternalParser = class(TAsn1Encodable, IDerExternalParser)
  1793. strict private
  1794. var
  1795. F_parser: IAsn1StreamParser;
  1796. public
  1797. constructor Create(const parser: IAsn1StreamParser);
  1798. function ReadObject(): IAsn1Convertible; inline;
  1799. function ToAsn1Object(): IAsn1Object; override;
  1800. end;
  1801. type
  1802. TDerOctetStringParser = class(TInterfacedObject, IAsn1OctetStringParser,
  1803. IAsn1Convertible, IDerOctetStringParser)
  1804. strict private
  1805. var
  1806. FStream: TStream;
  1807. public
  1808. constructor Create(stream: TStream);
  1809. destructor Destroy(); override;
  1810. function GetOctetStream(): TStream; inline;
  1811. function ToAsn1Object(): IAsn1Object;
  1812. end;
  1813. type
  1814. TDerGeneralString = class(TDerStringBase, IDerGeneralString)
  1815. strict private
  1816. var
  1817. FStr: String;
  1818. function GetStr: String; inline;
  1819. property Str: String read GetStr;
  1820. strict protected
  1821. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1822. public
  1823. constructor Create(const Str: TCryptoLibByteArray); overload;
  1824. constructor Create(const Str: String); overload;
  1825. function GetString(): String; override;
  1826. function GetOctets(): TCryptoLibByteArray; inline;
  1827. procedure Encode(const derOut: TStream); override;
  1828. class function GetInstance(const obj: TObject): IDerGeneralString; overload;
  1829. static; inline;
  1830. class function GetInstance(const obj: IAsn1TaggedObject;
  1831. isExplicit: Boolean): IDerGeneralString; overload; static; inline;
  1832. end;
  1833. type
  1834. TDerGenerator = class abstract(TAsn1Generator, IDerGenerator)
  1835. strict private
  1836. var
  1837. F_tagged, F_isExplicit: Boolean;
  1838. F_tagNo: Int32;
  1839. class procedure WriteLength(const outStr: TStream; length: Int32); static;
  1840. strict protected
  1841. constructor Create(const outStream: TStream); overload;
  1842. constructor Create(const outStream: TStream; tagNo: Int32;
  1843. isExplicit: Boolean); overload;
  1844. public
  1845. procedure WriteDerEncoded(tag: Int32;
  1846. const bytes: TCryptoLibByteArray); overload;
  1847. class procedure WriteDerEncoded(const outStream: TStream; tag: Int32;
  1848. const bytes: TCryptoLibByteArray); overload; static;
  1849. class procedure WriteDerEncoded(const outStr: TStream; tag: Int32;
  1850. const inStr: TStream); overload; static;
  1851. end;
  1852. type
  1853. /// <summary>
  1854. /// Der IA5String object - this is an ascii string.
  1855. /// </summary>
  1856. TDerIA5String = class(TDerStringBase, IDerIA5String)
  1857. strict private
  1858. var
  1859. FStr: String;
  1860. function GetStr: String; inline;
  1861. property Str: String read GetStr;
  1862. strict protected
  1863. function Asn1GetHashCode(): Int32; override;
  1864. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1865. public
  1866. /// <summary>
  1867. /// basic constructor - with bytes.
  1868. /// </summary>
  1869. constructor Create(const Str: TCryptoLibByteArray); overload;
  1870. /// <summary>
  1871. /// basic constructor - without validation.
  1872. /// </summary>
  1873. constructor Create(const Str: String); overload;
  1874. /// <summary>
  1875. /// Constructor with optional validation.
  1876. /// </summary>
  1877. /// <param name="Str">
  1878. /// the base string to wrap.
  1879. /// </param>
  1880. /// <param name="validate">
  1881. /// whether or not to check the string.
  1882. /// </param>
  1883. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1884. /// if validate is true and the string contains characters that should
  1885. /// not be in an IA5String.
  1886. /// </exception>
  1887. constructor Create(const Str: String; validate: Boolean); overload;
  1888. function GetString(): String; override;
  1889. function GetOctets(): TCryptoLibByteArray; inline;
  1890. procedure Encode(const derOut: TStream); override;
  1891. /// <summary>
  1892. /// return a DerIA5String from the passed in object
  1893. /// </summary>
  1894. /// <param name="obj">
  1895. /// a DerIA5String or an object that can be converted into one.
  1896. /// </param>
  1897. /// <returns>
  1898. /// return a DerIA5String instance, or null.
  1899. /// </returns>
  1900. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1901. /// if the object cannot be converted.
  1902. /// </exception>
  1903. class function GetInstance(const obj: TObject): IDerIA5String; overload;
  1904. static; inline;
  1905. /// <summary>
  1906. /// return a DerIA5String from a tagged object.
  1907. /// </summary>
  1908. /// <param name="obj">
  1909. /// the tagged object holding the object we want
  1910. /// </param>
  1911. /// <param name="isExplicit">
  1912. /// true if the object is meant to be explicitly tagged false otherwise.
  1913. /// </param>
  1914. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1915. /// if the tagged object cannot be converted.
  1916. /// </exception>
  1917. class function GetInstance(const obj: IAsn1TaggedObject;
  1918. isExplicit: Boolean): IDerIA5String; overload; static; inline;
  1919. /// <summary>
  1920. /// return true if the passed in String can be represented without loss
  1921. /// as an IA5String, false otherwise.
  1922. /// </summary>
  1923. /// <param name="Str">
  1924. /// true if in printable set, false otherwise.
  1925. /// </param>
  1926. class function IsIA5String(const Str: String): Boolean; static; inline;
  1927. end;
  1928. type
  1929. /// <summary>
  1930. /// Der NumericString object - this is an ascii string of characters
  1931. /// {0,1,2,3,4,5,6,7,8,9, }.
  1932. /// </summary>
  1933. TDerNumericString = class(TDerStringBase, IDerNumericString)
  1934. strict private
  1935. var
  1936. FStr: String;
  1937. function GetStr: String; inline;
  1938. property Str: String read GetStr;
  1939. strict protected
  1940. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  1941. public
  1942. /// <summary>
  1943. /// basic constructor - with bytes.
  1944. /// </summary>
  1945. constructor Create(const Str: TCryptoLibByteArray); overload;
  1946. /// <summary>
  1947. /// basic constructor - without validation.
  1948. /// </summary>
  1949. constructor Create(const Str: String); overload;
  1950. /// <summary>
  1951. /// Constructor with optional validation.
  1952. /// </summary>
  1953. /// <param name="Str">
  1954. /// the base string to wrap.
  1955. /// </param>
  1956. /// <param name="validate">
  1957. /// whether or not to check the string.
  1958. /// </param>
  1959. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1960. /// if validate is true and the string contains characters that should
  1961. /// not be in an IA5String.
  1962. /// </exception>
  1963. constructor Create(const Str: String; validate: Boolean); overload;
  1964. function GetString(): String; override;
  1965. function GetOctets(): TCryptoLibByteArray; inline;
  1966. procedure Encode(const derOut: TStream); override;
  1967. /// <summary>
  1968. /// return a Numeric string from the passed in object
  1969. /// </summary>
  1970. /// <param name="obj">
  1971. /// a DerNumericString or an object that can be converted into one.
  1972. /// </param>
  1973. /// <returns>
  1974. /// return a DerNumericString instance, or null.
  1975. /// </returns>
  1976. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1977. /// if the object cannot be converted.
  1978. /// </exception>
  1979. class function GetInstance(const obj: TObject): IDerNumericString; overload;
  1980. static; inline;
  1981. /// <summary>
  1982. /// return a Numeric String from a tagged object.
  1983. /// </summary>
  1984. /// <param name="obj">
  1985. /// the tagged object holding the object we want
  1986. /// </param>
  1987. /// <param name="isExplicit">
  1988. /// true if the object is meant to be explicitly tagged false otherwise.
  1989. /// </param>
  1990. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  1991. /// if the tagged object cannot be converted.
  1992. /// </exception>
  1993. class function GetInstance(const obj: IAsn1TaggedObject;
  1994. isExplicit: Boolean): IDerNumericString; overload; static; inline;
  1995. /// <summary>
  1996. /// Return true if the string can be represented as a NumericString
  1997. /// ('0'..'9', ' ')
  1998. /// </summary>
  1999. /// <param name="Str">
  2000. /// string to validate.
  2001. /// </param>
  2002. /// <returns>
  2003. /// true if numeric, false otherwise.
  2004. /// </returns>
  2005. class function IsNumericString(const Str: String): Boolean; static; inline;
  2006. end;
  2007. type
  2008. /// <summary>
  2009. /// Der PrintableString object.
  2010. /// </summary>
  2011. TDerPrintableString = class(TDerStringBase, IDerPrintableString)
  2012. strict private
  2013. var
  2014. FStr: String;
  2015. function GetStr: String; inline;
  2016. strict protected
  2017. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2018. public
  2019. /// <summary>
  2020. /// basic constructor - with bytes.
  2021. /// </summary>
  2022. constructor Create(const Str: TCryptoLibByteArray); overload;
  2023. /// <summary>
  2024. /// basic constructor - without validation.
  2025. /// </summary>
  2026. constructor Create(const Str: String); overload;
  2027. /// <summary>
  2028. /// Constructor with optional validation.
  2029. /// </summary>
  2030. /// <param name="Str">
  2031. /// the base string to wrap.
  2032. /// </param>
  2033. /// <param name="validate">
  2034. /// whether or not to check the string.
  2035. /// </param>
  2036. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2037. /// if validate is true and the string contains characters that should
  2038. /// not be in an PrintableString.
  2039. /// </exception>
  2040. constructor Create(const Str: String; validate: Boolean); overload;
  2041. function GetString(): String; override;
  2042. function GetOctets(): TCryptoLibByteArray; inline;
  2043. procedure Encode(const derOut: TStream); override;
  2044. property Str: String read GetStr;
  2045. /// <summary>
  2046. /// return a printable string from the passed in object.
  2047. /// </summary>
  2048. /// <param name="obj">
  2049. /// a DerPrintableString or an object that can be converted into one.
  2050. /// </param>
  2051. /// <returns>
  2052. /// return a DerPrintableString instance, or null.
  2053. /// </returns>
  2054. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2055. /// if the object cannot be converted.
  2056. /// </exception>
  2057. class function GetInstance(const obj: TObject): IDerPrintableString;
  2058. overload; static; inline;
  2059. /// <summary>
  2060. /// return a Printable string from a tagged object.
  2061. /// </summary>
  2062. /// <param name="obj">
  2063. /// the tagged object holding the object we want
  2064. /// </param>
  2065. /// <param name="isExplicit">
  2066. /// true if the object is meant to be explicitly tagged false otherwise.
  2067. /// </param>
  2068. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2069. /// if the tagged object cannot be converted.
  2070. /// </exception>
  2071. class function GetInstance(const obj: IAsn1TaggedObject;
  2072. isExplicit: Boolean): IDerPrintableString; overload; static; inline;
  2073. /// <summary>
  2074. /// return true if the passed in String can be represented without loss
  2075. /// as a PrintableString, false otherwise.
  2076. /// </summary>
  2077. /// <param name="Str">
  2078. /// string to validate.
  2079. /// </param>
  2080. /// <returns>
  2081. /// return true if in printable set, false otherwise.
  2082. /// </returns>
  2083. class function IsPrintableString(const Str: String): Boolean;
  2084. static; inline;
  2085. end;
  2086. type
  2087. TDerSequenceGenerator = class(TDerGenerator, IDerSequenceGenerator)
  2088. strict private
  2089. var
  2090. F_bOut: TMemoryStream;
  2091. public
  2092. constructor Create(outStream: TStream); overload;
  2093. constructor Create(outStream: TStream; tagNo: Int32;
  2094. isExplicit: Boolean); overload;
  2095. destructor Destroy(); override;
  2096. procedure AddObject(const obj: IAsn1Encodable); override;
  2097. function GetRawOutputStream(): TStream; override;
  2098. procedure Close(); override;
  2099. end;
  2100. type
  2101. /// <summary>
  2102. /// Der T61String (also the teletex string) - 8-bit characters
  2103. /// </summary>
  2104. TDerT61String = class(TDerStringBase, IDerT61String)
  2105. strict private
  2106. var
  2107. FStr: String;
  2108. function GetStr: String; inline;
  2109. property Str: String read GetStr;
  2110. class function GetEncoding: TEncoding; static; inline;
  2111. strict protected
  2112. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2113. public
  2114. /// <summary>
  2115. /// basic constructor - with bytes.
  2116. /// </summary>
  2117. constructor Create(const Str: TCryptoLibByteArray); overload;
  2118. /// <summary>
  2119. /// basic constructor
  2120. /// </summary>
  2121. constructor Create(const Str: String); overload;
  2122. function GetString(): String; override;
  2123. function GetOctets(): TCryptoLibByteArray; inline;
  2124. procedure Encode(const derOut: TStream); override;
  2125. /// <summary>
  2126. /// return a T61 string from the passed in object.
  2127. /// </summary>
  2128. /// <param name="obj">
  2129. /// a Der T61 string or an object that can be converted into one.
  2130. /// </param>
  2131. /// <returns>
  2132. /// return a Der T61 string instance, or null.
  2133. /// </returns>
  2134. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2135. /// if the object cannot be converted.
  2136. /// </exception>
  2137. class function GetInstance(const obj: TObject): IDerT61String; overload;
  2138. static; inline;
  2139. /// <summary>
  2140. /// return a Der T61 string from a tagged object.
  2141. /// </summary>
  2142. /// <param name="obj">
  2143. /// the tagged object holding the object we want
  2144. /// </param>
  2145. /// <param name="isExplicit">
  2146. /// true if the object is meant to be explicitly tagged false otherwise.
  2147. /// </param>
  2148. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2149. /// if the tagged object cannot be converted.
  2150. /// </exception>
  2151. class function GetInstance(const obj: IAsn1TaggedObject;
  2152. isExplicit: Boolean): IDerT61String; overload; static; inline;
  2153. end;
  2154. type
  2155. /// <summary>
  2156. /// Der UniversalString object.
  2157. /// </summary>
  2158. TDerUniversalString = class(TDerStringBase, IDerUniversalString)
  2159. strict private
  2160. var
  2161. FStr: TCryptoLibByteArray;
  2162. const
  2163. FTable: array [0 .. 15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7',
  2164. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
  2165. function GetStr: TCryptoLibByteArray; inline;
  2166. property Str: TCryptoLibByteArray read GetStr;
  2167. strict protected
  2168. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2169. public
  2170. /// <summary>
  2171. /// basic constructor - byte encoded string.
  2172. /// </summary>
  2173. constructor Create(const Str: TCryptoLibByteArray); overload;
  2174. function GetString(): String; override;
  2175. function GetOctets(): TCryptoLibByteArray; inline;
  2176. procedure Encode(const derOut: TStream); override;
  2177. /// <summary>
  2178. /// return a Universal String from the passed in object.
  2179. /// </summary>
  2180. /// <param name="obj">
  2181. /// a Der T61 string or an object that can be converted into one.
  2182. /// </param>
  2183. /// <returns>
  2184. /// return a Der UniversalString instance, or null.
  2185. /// </returns>
  2186. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2187. /// if the object cannot be converted.
  2188. /// </exception>
  2189. class function GetInstance(const obj: TObject): IDerUniversalString;
  2190. overload; static; inline;
  2191. /// <summary>
  2192. /// return a Der UniversalString from a tagged object.
  2193. /// </summary>
  2194. /// <param name="obj">
  2195. /// the tagged object holding the object we want
  2196. /// </param>
  2197. /// <param name="isExplicit">
  2198. /// true if the object is meant to be explicitly tagged false otherwise.
  2199. /// </param>
  2200. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2201. /// if the tagged object cannot be converted.
  2202. /// </exception>
  2203. class function GetInstance(const obj: IAsn1TaggedObject;
  2204. isExplicit: Boolean): IDerUniversalString; overload; static; inline;
  2205. end;
  2206. type
  2207. /// <summary>
  2208. /// Der UTF8String object.
  2209. /// </summary>
  2210. TDerUtf8String = class(TDerStringBase, IDerUtf8String)
  2211. strict private
  2212. var
  2213. FStr: String;
  2214. function GetStr: String; inline;
  2215. property Str: String read GetStr;
  2216. strict protected
  2217. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2218. public
  2219. /// <summary>
  2220. /// basic constructor - with bytes.
  2221. /// </summary>
  2222. constructor Create(const Str: TCryptoLibByteArray); overload;
  2223. /// <summary>
  2224. /// basic constructor
  2225. /// </summary>
  2226. constructor Create(const Str: String); overload;
  2227. function GetString(): String; override;
  2228. procedure Encode(const derOut: TStream); override;
  2229. /// <summary>
  2230. /// return an UTF8 string from the passed in object.
  2231. /// </summary>
  2232. /// <param name="obj">
  2233. /// a Der UTF8String or an object that can be converted into one.
  2234. /// </param>
  2235. /// <returns>
  2236. /// return a Der UTF8String instance, or null.
  2237. /// </returns>
  2238. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2239. /// if the object cannot be converted.
  2240. /// </exception>
  2241. class function GetInstance(const obj: TObject): IDerUtf8String; overload;
  2242. static; inline;
  2243. /// <summary>
  2244. /// return a Der UTF8String from a tagged object.
  2245. /// </summary>
  2246. /// <param name="obj">
  2247. /// the tagged object holding the object we want
  2248. /// </param>
  2249. /// <param name="isExplicit">
  2250. /// true if the object is meant to be explicitly tagged false otherwise.
  2251. /// </param>
  2252. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2253. /// if the tagged object cannot be converted.
  2254. /// </exception>
  2255. class function GetInstance(const obj: IAsn1TaggedObject;
  2256. isExplicit: Boolean): IDerUtf8String; overload; static; inline;
  2257. end;
  2258. type
  2259. TDerVideotexString = class(TDerStringBase, IDerVideotexString)
  2260. strict private
  2261. var
  2262. FmString: TCryptoLibByteArray;
  2263. function GetmString: TCryptoLibByteArray; inline;
  2264. protected
  2265. function Asn1GetHashCode(): Int32; override;
  2266. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2267. public
  2268. property mString: TCryptoLibByteArray read GetmString;
  2269. /// <summary>
  2270. /// basic constructor - with bytes.
  2271. /// </summary>
  2272. /// <param name="encoding">
  2273. /// the byte encoding of the characters making up the string.
  2274. /// </param>
  2275. constructor Create(const encoding: TCryptoLibByteArray);
  2276. function GetString(): String; override;
  2277. function GetOctets(): TCryptoLibByteArray; inline;
  2278. procedure Encode(const derOut: TStream); override;
  2279. /// <summary>
  2280. /// return a Videotex String from the passed in object
  2281. /// </summary>
  2282. /// <param name="obj">
  2283. /// a DerVideotexString or an object that can be converted into one.
  2284. /// </param>
  2285. /// <returns>
  2286. /// return a DerVideotexString instance, or null.
  2287. /// </returns>
  2288. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2289. /// if the object cannot be converted.
  2290. /// </exception>
  2291. class function GetInstance(const obj: TObject): IDerVideotexString;
  2292. overload; static; inline;
  2293. class function GetInstance(const obj: TCryptoLibByteArray)
  2294. : IDerVideotexString; overload; static;
  2295. /// <summary>
  2296. /// return a Videotex string from a tagged object.
  2297. /// </summary>
  2298. /// <param name="obj">
  2299. /// the tagged object holding the object we want
  2300. /// </param>
  2301. /// <param name="isExplicit">
  2302. /// true if the object is meant to be explicitly tagged false otherwise.
  2303. /// </param>
  2304. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2305. /// if the tagged object cannot be converted.
  2306. /// </exception>
  2307. class function GetInstance(const obj: IAsn1TaggedObject;
  2308. isExplicit: Boolean): IDerVideotexString; overload; static; inline;
  2309. end;
  2310. type
  2311. /// <summary>
  2312. /// Der VisibleString object.
  2313. /// </summary>
  2314. TDerVisibleString = class(TDerStringBase, IDerVisibleString)
  2315. strict private
  2316. var
  2317. FStr: String;
  2318. function GetStr: String; inline;
  2319. property Str: String read GetStr;
  2320. strict protected
  2321. function Asn1GetHashCode(): Int32; override;
  2322. function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
  2323. public
  2324. /// <summary>
  2325. /// basic constructor - byte encoded string.
  2326. /// </summary>
  2327. constructor Create(const Str: TCryptoLibByteArray); overload;
  2328. /// <summary>
  2329. /// basic constructor
  2330. /// </summary>
  2331. constructor Create(const Str: String); overload;
  2332. function GetString(): String; override;
  2333. function GetOctets(): TCryptoLibByteArray; inline;
  2334. procedure Encode(const derOut: TStream); override;
  2335. /// <summary>
  2336. /// return a DerVisibleString from the passed in object
  2337. /// </summary>
  2338. /// <param name="obj">
  2339. /// a DerVisibleString or an object that can be converted into one.
  2340. /// </param>
  2341. /// <returns>
  2342. /// return a DerVisibleString instance, or null.
  2343. /// </returns>
  2344. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2345. /// if the object cannot be converted.
  2346. /// </exception>
  2347. class function GetInstance(const obj: TObject): IDerVisibleString; overload;
  2348. static; inline;
  2349. /// <summary>
  2350. /// return a DerVisibleString from a tagged object.
  2351. /// </summary>
  2352. /// <param name="obj">
  2353. /// the tagged object holding the object we want
  2354. /// </param>
  2355. /// <param name="isExplicit">
  2356. /// true if the object is meant to be explicitly tagged false otherwise.
  2357. /// </param>
  2358. /// <exception cref="ClpCryptoLibTypes|EArgumentCryptoLibException">
  2359. /// if the tagged object cannot be converted.
  2360. /// </exception>
  2361. class function GetInstance(const obj: IAsn1TaggedObject;
  2362. isExplicit: Boolean): IDerVisibleString; overload; static; inline;
  2363. end;
  2364. implementation
  2365. { TStreamHelper }
  2366. function TStreamHelper.ReadByte: Int32;
  2367. var
  2368. buffer: TCryptoLibByteArray;
  2369. begin
  2370. System.SetLength(buffer, 1);
  2371. if (TStreamSorter.Read(Self, buffer, 0, 1) = 0) then
  2372. begin
  2373. result := -1;
  2374. end
  2375. else
  2376. begin
  2377. result := Int32(buffer[0]);
  2378. end;
  2379. end;
  2380. procedure TStreamHelper.WriteByte(b: Byte);
  2381. var
  2382. oneByteArray: TCryptoLibByteArray;
  2383. begin
  2384. System.SetLength(oneByteArray, 1);
  2385. oneByteArray[0] := b;
  2386. // Self.Write(oneByteArray, 0, 1);
  2387. Self.Write(oneByteArray[0], 1);
  2388. end;
  2389. { TStreamSorter }
  2390. class function TStreamSorter.Read(input: TStream;
  2391. var buffer: TCryptoLibByteArray; offset, count: Int32): Int32;
  2392. begin
  2393. if input is TIndefiniteLengthInputStream then
  2394. begin
  2395. result := (input as TIndefiniteLengthInputStream).
  2396. Read(buffer, offset, count);
  2397. end
  2398. else if input is TDefiniteLengthInputStream then
  2399. begin
  2400. result := (input as TDefiniteLengthInputStream).Read(buffer, offset, count);
  2401. end
  2402. else if input is TConstructedOctetStream then
  2403. begin
  2404. result := (input as TConstructedOctetStream).Read(buffer, offset, count);
  2405. end
  2406. else
  2407. begin
  2408. result := input.Read(buffer[offset], count);
  2409. end;
  2410. end;
  2411. class function TStreamSorter.ReadByte(input: TStream): Int32;
  2412. begin
  2413. if input is TIndefiniteLengthInputStream then
  2414. begin
  2415. result := (input as TIndefiniteLengthInputStream).ReadByte();
  2416. end
  2417. else if input is TDefiniteLengthInputStream then
  2418. begin
  2419. result := (input as TDefiniteLengthInputStream).ReadByte();
  2420. end
  2421. else if input is TConstructedOctetStream then
  2422. begin
  2423. result := (input as TConstructedOctetStream).ReadByte();
  2424. end
  2425. else
  2426. begin
  2427. result := input.ReadByte();
  2428. end;
  2429. end;
  2430. { TStreamUtils }
  2431. class procedure TStreamUtils.Drain(const inStr: TStream);
  2432. var
  2433. bs: TCryptoLibByteArray;
  2434. begin
  2435. System.SetLength(bs, BufferSize);
  2436. while (TStreamSorter.Read(inStr, bs, 0, System.length(bs)) > 0) do
  2437. begin
  2438. // do nothing
  2439. end;
  2440. end;
  2441. class procedure TStreamUtils.PipeAll(const inStr, outStr: TStream);
  2442. var
  2443. numRead: Int32;
  2444. bs: TCryptoLibByteArray;
  2445. begin
  2446. System.SetLength(bs, BufferSize);
  2447. numRead := TStreamSorter.Read(inStr, bs, 0, System.length(bs));
  2448. while ((numRead) > 0) do
  2449. begin
  2450. outStr.Write(bs[0], numRead);
  2451. numRead := TStreamSorter.Read(inStr, bs, 0, System.length(bs));
  2452. end;
  2453. end;
  2454. class function TStreamUtils.PipeAllLimited(const inStr: TStream; limit: Int64;
  2455. const outStr: TStream): Int64;
  2456. var
  2457. bs: TCryptoLibByteArray;
  2458. numRead: Int32;
  2459. total: Int64;
  2460. begin
  2461. System.SetLength(bs, BufferSize);
  2462. total := 0;
  2463. numRead := TStreamSorter.Read(inStr, bs, 0, System.length(bs));
  2464. while ((numRead) > 0) do
  2465. begin
  2466. if ((limit - total) < numRead) then
  2467. begin
  2468. raise EStreamOverflowCryptoLibException.CreateRes(@SDataOverflow);
  2469. end;
  2470. total := total + numRead;
  2471. outStr.Write(bs[0], numRead);
  2472. numRead := TStreamSorter.Read(inStr, bs, 0, System.length(bs));
  2473. end;
  2474. result := total;
  2475. end;
  2476. class function TStreamUtils.ReadAll(const inStr: TStream): TCryptoLibByteArray;
  2477. var
  2478. buf: TMemoryStream;
  2479. begin
  2480. buf := TMemoryStream.Create();
  2481. try
  2482. PipeAll(inStr, buf);
  2483. System.SetLength(result, buf.Size);
  2484. buf.Position := 0;
  2485. buf.Read(result[0], buf.Size);
  2486. finally
  2487. buf.Free;
  2488. end;
  2489. end;
  2490. class function TStreamUtils.ReadAllLimited(const inStr: TStream; limit: Int32)
  2491. : TCryptoLibByteArray;
  2492. var
  2493. buf: TMemoryStream;
  2494. begin
  2495. buf := TMemoryStream.Create();
  2496. try
  2497. PipeAllLimited(inStr, limit, buf);
  2498. System.SetLength(result, buf.Size);
  2499. buf.Position := 0;
  2500. buf.Read(result[0], buf.Size);
  2501. finally
  2502. buf.Free;
  2503. end;
  2504. end;
  2505. class function TStreamUtils.ReadFully(const inStr: TStream;
  2506. var buf: TCryptoLibByteArray; off, len: Int32): Int32;
  2507. var
  2508. totalRead, numRead: Int32;
  2509. begin
  2510. totalRead := 0;
  2511. while (totalRead < len) do
  2512. begin
  2513. numRead := TStreamSorter.Read(inStr, buf, off + totalRead, len - totalRead);
  2514. if (numRead < 1) then
  2515. begin
  2516. break;
  2517. end;
  2518. totalRead := totalRead + numRead;
  2519. end;
  2520. result := totalRead;
  2521. end;
  2522. class function TStreamUtils.WriteBufTo(const buf: TMemoryStream;
  2523. const output: TCryptoLibByteArray; offset: Int32): Int32;
  2524. var
  2525. bytes: TCryptoLibByteArray;
  2526. begin
  2527. buf.Position := 0;
  2528. System.SetLength(bytes, buf.Size);
  2529. buf.Read(bytes[0], buf.Size);
  2530. System.Move(bytes[0], output[offset], System.length(bytes) *
  2531. System.SizeOf(Byte));
  2532. result := System.length(bytes);
  2533. end;
  2534. class procedure TStreamUtils.WriteZeroes(const outStr: TStream; count: Int64);
  2535. var
  2536. zeroes: TCryptoLibByteArray;
  2537. begin
  2538. System.SetLength(zeroes, BufferSize);
  2539. while (count > BufferSize) do
  2540. begin
  2541. outStr.Write(zeroes[0], BufferSize);
  2542. count := count - BufferSize;
  2543. end;
  2544. outStr.Write(zeroes[0], Int32(count));
  2545. end;
  2546. class function TStreamUtils.ReadFully(const inStr: TStream;
  2547. var buf: TCryptoLibByteArray): Int32;
  2548. begin
  2549. result := ReadFully(inStr, buf, 0, System.length(buf));
  2550. end;
  2551. class procedure TStreamUtils.WriteBufTo(const buf: TMemoryStream;
  2552. const output: TStream);
  2553. begin
  2554. output.CopyFrom(buf, buf.Size);
  2555. end;
  2556. { TBaseInputStream }
  2557. function TBaseInputStream.GetPosition: Int64;
  2558. begin
  2559. raise ENotSupportedCryptoLibException.Create('');
  2560. end;
  2561. function TBaseInputStream.GetSize: Int64;
  2562. begin
  2563. raise ENotSupportedCryptoLibException.Create('');
  2564. end;
  2565. {$IFNDEF _FIXINSIGHT_}
  2566. function TBaseInputStream.Read(var buffer; count: LongInt): LongInt;
  2567. begin
  2568. raise ENotSupportedCryptoLibException.Create('');
  2569. end;
  2570. function TBaseInputStream.Write(const buffer; count: LongInt): LongInt;
  2571. begin
  2572. raise ENotSupportedCryptoLibException.Create('');
  2573. end;
  2574. {$ENDIF}
  2575. function TBaseInputStream.ReadByte: Int32;
  2576. var
  2577. buffer: TCryptoLibByteArray;
  2578. begin
  2579. System.SetLength(buffer, 1);
  2580. // if (Read(Buffer, 0, 1) = 0) then
  2581. if (TStreamSorter.Read(Self, buffer, 0, 1) = 0) then
  2582. begin
  2583. result := -1;
  2584. end
  2585. else
  2586. begin
  2587. result := Int32(buffer[0]);
  2588. end;
  2589. end;
  2590. function TBaseInputStream.Seek(offset: LongInt; Origin: Word): LongInt;
  2591. begin
  2592. result := Seek(Int64(offset), TSeekOrigin(Origin));
  2593. end;
  2594. {$IFNDEF _FIXINSIGHT_}
  2595. function TBaseInputStream.Seek(const offset: Int64; Origin: TSeekOrigin): Int64;
  2596. begin
  2597. raise ENotSupportedCryptoLibException.Create('');
  2598. end;
  2599. procedure TBaseInputStream.SetPosition(const Pos: Int64);
  2600. begin
  2601. raise ENotSupportedCryptoLibException.Create('');
  2602. end;
  2603. {$ENDIF}
  2604. procedure TBaseInputStream.SetSize(const NewSize: Int64);
  2605. begin
  2606. SetSize(LongInt(NewSize));
  2607. end;
  2608. procedure TBaseInputStream.SetSize(NewSize: LongInt);
  2609. begin
  2610. raise ENotSupportedCryptoLibException.Create('');
  2611. end;
  2612. procedure TBaseInputStream.SetSize64(const NewSize: Int64);
  2613. begin
  2614. SetSize(NewSize);
  2615. end;
  2616. function TBaseInputStream.Read(buffer: TCryptoLibByteArray;
  2617. offset, count: LongInt): LongInt;
  2618. var
  2619. &pos, endPoint, b: Int32;
  2620. begin
  2621. Pos := offset;
  2622. try
  2623. endPoint := offset + count;
  2624. while (Pos < endPoint) do
  2625. begin
  2626. b := ReadByte();
  2627. if (b = -1) then
  2628. begin
  2629. break;
  2630. end;
  2631. buffer[Pos] := Byte(b);
  2632. System.Inc(Pos);
  2633. end;
  2634. except
  2635. on e: EIOCryptoLibException do
  2636. begin
  2637. if (Pos = offset) then
  2638. raise;
  2639. end;
  2640. end;
  2641. result := Pos - offset;
  2642. end;
  2643. {$IFNDEF _FIXINSIGHT_}
  2644. function TBaseInputStream.Write(const buffer: TCryptoLibByteArray;
  2645. offset, count: LongInt): LongInt;
  2646. begin
  2647. raise ENotSupportedCryptoLibException.Create('');
  2648. end;
  2649. {$ENDIF}
  2650. { TFilterStream }
  2651. constructor TFilterStream.Create(const s: TStream);
  2652. begin
  2653. inherited Create();
  2654. Fs := s;
  2655. end;
  2656. function TFilterStream.GetPosition: Int64;
  2657. begin
  2658. result := Fs.Position;
  2659. end;
  2660. procedure TFilterStream.SetPosition(const Value: Int64);
  2661. begin
  2662. Fs.Position := Value;
  2663. end;
  2664. function TFilterStream.Write(const buffer; count: LongInt): LongInt;
  2665. begin
  2666. result := Fs.Write(PByte(buffer), count);
  2667. end;
  2668. procedure TFilterStream.WriteByte(Value: Byte);
  2669. begin
  2670. Fs.WriteByte(Value);
  2671. end;
  2672. function TFilterStream.GetSize: Int64;
  2673. begin
  2674. result := Fs.Size;
  2675. end;
  2676. function TFilterStream.Read(var buffer; count: LongInt): LongInt;
  2677. begin
  2678. result := Fs.Read(PByte(buffer), count);
  2679. end;
  2680. function TFilterStream.ReadByte: Int32;
  2681. begin
  2682. result := TStreamSorter.ReadByte(Fs);
  2683. end;
  2684. function TFilterStream.Seek(const offset: Int64; Origin: TSeekOrigin): Int64;
  2685. begin
  2686. result := Fs.Seek(offset, Origin);
  2687. end;
  2688. { TLimitedInputStream }
  2689. constructor TLimitedInputStream.Create(inStream: TStream; limit: Int32);
  2690. begin
  2691. Inherited Create();
  2692. F_in := inStream;
  2693. F_limit := limit;
  2694. end;
  2695. function TLimitedInputStream.GetRemaining: Int32;
  2696. begin
  2697. // TODO: maybe one day this can become more accurate
  2698. result := F_limit;
  2699. end;
  2700. procedure TLimitedInputStream.SetParentEofDetect(&on: Boolean);
  2701. var
  2702. indefiniteLengthInputStream: TIndefiniteLengthInputStream;
  2703. begin
  2704. if F_in is TIndefiniteLengthInputStream then
  2705. begin
  2706. indefiniteLengthInputStream := F_in as TIndefiniteLengthInputStream;
  2707. indefiniteLengthInputStream.SetEofOn00(&on);
  2708. end;
  2709. end;
  2710. { TDefiniteLengthInputStream }
  2711. constructor TDefiniteLengthInputStream.Create(inStream: TStream; length: Int32);
  2712. begin
  2713. Inherited Create(inStream, length);
  2714. if (length < 0) then
  2715. begin
  2716. raise EArgumentCryptoLibException.CreateRes(@SInvalidLength);
  2717. end;
  2718. F_originalLength := length;
  2719. F_remaining := length;
  2720. if (length = 0) then
  2721. begin
  2722. SetParentEofDetect(True);
  2723. end;
  2724. end;
  2725. class function TDefiniteLengthInputStream.GetEmptyBytes: TCryptoLibByteArray;
  2726. begin
  2727. result := Nil;
  2728. end;
  2729. function TDefiniteLengthInputStream.GetRemaining: Int32;
  2730. begin
  2731. result := F_remaining;
  2732. end;
  2733. function TDefiniteLengthInputStream.Read(buf: TCryptoLibByteArray;
  2734. off, len: LongInt): LongInt;
  2735. var
  2736. toRead, numRead: Int32;
  2737. begin
  2738. if (F_remaining = 0) then
  2739. begin
  2740. result := 0;
  2741. Exit;
  2742. end;
  2743. toRead := Min(len, F_remaining);
  2744. numRead := TStreamSorter.Read(F_in, buf, off, toRead);
  2745. if (numRead < 1) then
  2746. begin
  2747. raise EEndOfStreamCryptoLibException.CreateResFmt(@SEndOfStreamTwo,
  2748. [F_originalLength, F_remaining]);
  2749. end;
  2750. F_remaining := F_remaining - numRead;
  2751. if (F_remaining = 0) then
  2752. begin
  2753. SetParentEofDetect(True);
  2754. end;
  2755. result := numRead;
  2756. end;
  2757. procedure TDefiniteLengthInputStream.ReadAllIntoByteArray
  2758. (var buf: TCryptoLibByteArray);
  2759. begin
  2760. if (F_remaining <> System.length(buf)) then
  2761. begin
  2762. raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
  2763. end;
  2764. F_remaining := F_remaining - TStreamUtils.ReadFully(F_in, buf);
  2765. if ((F_remaining <> 0)) then
  2766. begin
  2767. raise EEndOfStreamCryptoLibException.CreateResFmt(@SEndOfStreamTwo,
  2768. [F_originalLength, F_remaining]);
  2769. end;
  2770. SetParentEofDetect(True);
  2771. end;
  2772. function TDefiniteLengthInputStream.ReadByte: Int32;
  2773. begin
  2774. if (F_remaining = 0) then
  2775. begin
  2776. result := -1;
  2777. Exit;
  2778. end;
  2779. // result := F_in.ReadByte();
  2780. result := TStreamSorter.ReadByte(F_in);
  2781. if (result < 0) then
  2782. begin
  2783. raise EEndOfStreamCryptoLibException.CreateResFmt(@SEndOfStreamTwo,
  2784. [F_originalLength, F_remaining]);
  2785. end;
  2786. System.Dec(F_remaining);
  2787. if (F_remaining = 0) then
  2788. begin
  2789. SetParentEofDetect(True);
  2790. end;
  2791. end;
  2792. function TDefiniteLengthInputStream.ToArray: TCryptoLibByteArray;
  2793. var
  2794. bytes: TCryptoLibByteArray;
  2795. begin
  2796. if (F_remaining = 0) then
  2797. begin
  2798. result := EmptyBytes;
  2799. Exit;
  2800. end;
  2801. System.SetLength(bytes, F_remaining);
  2802. F_remaining := F_remaining - TStreamUtils.ReadFully(F_in, bytes);
  2803. if (F_remaining <> 0) then
  2804. begin
  2805. raise EEndOfStreamCryptoLibException.CreateResFmt(@SEndOfStreamTwo,
  2806. [F_originalLength, F_remaining]);
  2807. end;
  2808. SetParentEofDetect(True);
  2809. result := bytes;
  2810. end;
  2811. { TAsn1InputStream }
  2812. class function TAsn1InputStream.FindLimit(const input: TStream): Int32;
  2813. var
  2814. limitedInputStream: TLimitedInputStream;
  2815. mem: TMemoryStream;
  2816. begin
  2817. limitedInputStream := input as TLimitedInputStream;
  2818. if (limitedInputStream <> Nil) then
  2819. begin
  2820. result := limitedInputStream.GetRemaining();
  2821. Exit;
  2822. end
  2823. else if (input is TMemoryStream) then
  2824. begin
  2825. mem := input as TMemoryStream;
  2826. result := Int32(mem.Size - mem.Position);
  2827. Exit;
  2828. end;
  2829. result := System.High(Int32);
  2830. end;
  2831. class function TAsn1InputStream.GetBuffer(const defIn
  2832. : TDefiniteLengthInputStream; const tmpBuffers: TCryptoLibMatrixByteArray)
  2833. : TCryptoLibByteArray;
  2834. var
  2835. len: Int32;
  2836. buf, temp: TCryptoLibByteArray;
  2837. begin
  2838. len := defIn.GetRemaining();
  2839. if (len >= System.length(tmpBuffers)) then
  2840. begin
  2841. result := defIn.ToArray();
  2842. Exit;
  2843. end;
  2844. buf := tmpBuffers[len];
  2845. if (buf = Nil) then
  2846. begin
  2847. System.SetLength(temp, len);
  2848. tmpBuffers[len] := temp;
  2849. buf := tmpBuffers[len];
  2850. end;
  2851. defIn.ReadAllIntoByteArray(buf);
  2852. result := buf;
  2853. end;
  2854. class function TAsn1InputStream.CreatePrimitiveDerObject(tagNo: Int32;
  2855. const defIn: TDefiniteLengthInputStream;
  2856. const tmpBuffers: TCryptoLibMatrixByteArray): IAsn1Object;
  2857. var
  2858. bytes: TCryptoLibByteArray;
  2859. begin
  2860. case tagNo of
  2861. TAsn1Tags.Boolean:
  2862. begin
  2863. result := TDerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers));
  2864. Exit;
  2865. end;
  2866. TAsn1Tags.Enumerated:
  2867. begin
  2868. result := TDerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers));
  2869. Exit;
  2870. end;
  2871. TAsn1Tags.ObjectIdentifier:
  2872. begin
  2873. result := TDerObjectIdentifier.FromOctetString
  2874. (GetBuffer(defIn, tmpBuffers));
  2875. Exit;
  2876. end;
  2877. end;
  2878. bytes := defIn.ToArray();
  2879. case tagNo of
  2880. TAsn1Tags.BitString:
  2881. begin
  2882. result := TDerBitString.FromAsn1Octets(bytes);
  2883. Exit;
  2884. end;
  2885. TAsn1Tags.BmpString:
  2886. begin
  2887. result := TDerBmpString.Create(bytes);
  2888. Exit;
  2889. end;
  2890. // TAsn1Tags.GeneralizedTime:
  2891. // begin
  2892. // result := TDerGeneralizedTime.Create(bytes);
  2893. // Exit;
  2894. // end;
  2895. TAsn1Tags.GeneralString:
  2896. begin
  2897. result := TDerGeneralString.Create(bytes);
  2898. Exit;
  2899. end;
  2900. TAsn1Tags.GraphicString:
  2901. begin
  2902. result := TDerGraphicString.Create(bytes);
  2903. Exit;
  2904. end;
  2905. TAsn1Tags.IA5String:
  2906. begin
  2907. result := TDerIA5String.Create(bytes);
  2908. Exit;
  2909. end;
  2910. TAsn1Tags.Integer:
  2911. begin
  2912. result := TDerInteger.Create(bytes);
  2913. Exit;
  2914. end;
  2915. TAsn1Tags.Null:
  2916. begin
  2917. // actual content is ignored (enforce 0 length?)
  2918. result := TDerNull.Instance;
  2919. Exit;
  2920. end;
  2921. TAsn1Tags.NumericString:
  2922. begin
  2923. result := TDerNumericString.Create(bytes);
  2924. Exit;
  2925. end;
  2926. TAsn1Tags.OctetString:
  2927. begin
  2928. result := TDerOctetString.Create(bytes);
  2929. Exit;
  2930. end;
  2931. TAsn1Tags.PrintableString:
  2932. begin
  2933. result := TDerPrintableString.Create(bytes);
  2934. Exit;
  2935. end;
  2936. TAsn1Tags.T61String:
  2937. begin
  2938. result := TDerT61String.Create(bytes);
  2939. Exit;
  2940. end;
  2941. TAsn1Tags.UniversalString:
  2942. begin
  2943. result := TDerUniversalString.Create(bytes);
  2944. Exit;
  2945. end;
  2946. // TAsn1Tags.UtcTime:
  2947. // begin
  2948. // result := TDerUtcTime.Create(bytes);
  2949. // Exit;
  2950. // end;
  2951. TAsn1Tags.Utf8String:
  2952. begin
  2953. result := TDerUtf8String.Create(bytes);
  2954. Exit;
  2955. end;
  2956. TAsn1Tags.VideotexString:
  2957. begin
  2958. result := TDerVideotexString.Create(bytes);
  2959. Exit;
  2960. end;
  2961. TAsn1Tags.VisibleString:
  2962. begin
  2963. result := TDerVisibleString.Create(bytes);
  2964. Exit;
  2965. end;
  2966. else
  2967. begin
  2968. raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
  2969. end;
  2970. end;
  2971. end;
  2972. destructor TAsn1InputStream.Destroy;
  2973. begin
  2974. FStream.Free;
  2975. inherited Destroy;
  2976. end;
  2977. constructor TAsn1InputStream.Create(const inputStream: TStream; limit: Int32);
  2978. begin
  2979. Inherited Create(inputStream);
  2980. Flimit := limit;
  2981. System.SetLength(FtmpBuffers, 16);
  2982. end;
  2983. constructor TAsn1InputStream.Create(const inputStream: TStream);
  2984. begin
  2985. Create(inputStream, FindLimit(inputStream));
  2986. end;
  2987. constructor TAsn1InputStream.Create(const input: TCryptoLibByteArray);
  2988. begin
  2989. // used TBytesStream here for one pass creation and population with byte array :)
  2990. FStream := TBytesStream.Create(input);
  2991. Create(FStream, System.length(input));
  2992. end;
  2993. class function TAsn1InputStream.ReadLength(const s: TStream;
  2994. limit: Int32): Int32;
  2995. var
  2996. &length, Size, next, I: Int32;
  2997. begin
  2998. length := TStreamSorter.ReadByte(s);
  2999. if (length < 0) then
  3000. begin
  3001. raise EEndOfStreamCryptoLibException.CreateRes(@SInvalidEnd);
  3002. end;
  3003. if (length = $80) then
  3004. begin
  3005. result := -1; // indefinite-length encoding
  3006. Exit;
  3007. end;
  3008. if (length > 127) then
  3009. begin
  3010. Size := length and $7F;
  3011. // Note: The invalid long form "$ff" (see X.690 8.1.3.5c) will be caught here
  3012. if (Size > 4) then
  3013. begin
  3014. raise EIOCryptoLibException.CreateResFmt(@SInvalidDerLength, [Size]);
  3015. end;
  3016. length := 0;
  3017. I := 0;
  3018. while I < Size do
  3019. begin
  3020. next := TStreamSorter.ReadByte(s);
  3021. if (next < 0) then
  3022. begin
  3023. raise EEndOfStreamCryptoLibException.CreateRes(@SEndOfStream);
  3024. end;
  3025. length := (length shl 8) + next;
  3026. System.Inc(I);
  3027. end;
  3028. if (length < 0) then
  3029. begin
  3030. raise EIOCryptoLibException.CreateRes(@SNegativeLength);
  3031. end;
  3032. if (length >= limit) then // after all we must have read at least 1 byte
  3033. begin
  3034. raise EIOCryptoLibException.CreateRes(@SOutOfBoundsLength);
  3035. end;
  3036. end;
  3037. result := length;
  3038. end;
  3039. function TAsn1InputStream.ReadObject: IAsn1Object;
  3040. var
  3041. tag, tagNo, &length: Int32;
  3042. IsConstructed: Boolean;
  3043. indIn: TIndefiniteLengthInputStream;
  3044. sp: IAsn1StreamParser;
  3045. begin
  3046. tag := ReadByte();
  3047. if (tag <= 0) then
  3048. begin
  3049. if (tag = 0) then
  3050. begin
  3051. raise EIOCryptoLibException.CreateRes(@SEndOfContent);
  3052. end;
  3053. result := Nil;
  3054. Exit;
  3055. end;
  3056. //
  3057. // calculate tag number
  3058. //
  3059. tagNo := ReadTagNumber(Fs, tag);
  3060. IsConstructed := (tag and TAsn1Tags.Constructed) <> 0;
  3061. //
  3062. // calculate length
  3063. //
  3064. length := ReadLength(Fs, Flimit);
  3065. if (length < 0) then // indefinite length method
  3066. begin
  3067. if (not IsConstructed) then
  3068. begin
  3069. raise EIOCryptoLibException.CreateRes(@SIndefiniteLength);
  3070. end;
  3071. indIn := TIndefiniteLengthInputStream.Create(Fs, Flimit);
  3072. sp := TAsn1StreamParser.Create(indIn, Flimit);
  3073. if ((tag and TAsn1Tags.Application) <> 0) then
  3074. begin
  3075. result := (TBerApplicationSpecificParser.Create(tagNo, sp)
  3076. as IBerApplicationSpecificParser).ToAsn1Object();
  3077. Exit;
  3078. end;
  3079. if ((tag and TAsn1Tags.Tagged) <> 0) then
  3080. begin
  3081. result := (TBerTaggedObjectParser.Create(True, tagNo, sp)
  3082. as IBerTaggedObjectParser).ToAsn1Object();
  3083. Exit;
  3084. end;
  3085. // TODO There are other tags that may be constructed (e.g. BitString)
  3086. case tagNo of
  3087. TAsn1Tags.OctetString:
  3088. begin
  3089. result := (TBerOctetStringParser.Create(sp) as IBerOctetStringParser)
  3090. .ToAsn1Object();
  3091. Exit;
  3092. end;
  3093. TAsn1Tags.Sequence:
  3094. begin
  3095. result := (TBerSequenceParser.Create(sp) as IBerSequenceParser)
  3096. .ToAsn1Object();
  3097. Exit;
  3098. end;
  3099. TAsn1Tags.&Set:
  3100. begin
  3101. result := (TBerSetParser.Create(sp) as IBerSetParser).ToAsn1Object();
  3102. Exit;
  3103. end;
  3104. TAsn1Tags.External:
  3105. begin
  3106. result := (TDerExternalParser.Create(sp) as IDerExternalParser)
  3107. .ToAsn1Object();
  3108. Exit;
  3109. end;
  3110. else
  3111. begin
  3112. raise EIOCryptoLibException.CreateRes(@SUnknownBerObject);
  3113. end;
  3114. end;
  3115. end
  3116. else
  3117. begin
  3118. try
  3119. result := BuildObject(tag, tagNo, length);
  3120. except
  3121. on e: EArgumentCryptoLibException do
  3122. begin
  3123. raise EAsn1CryptoLibException.CreateResFmt(@SCorruptedStream,
  3124. [e.Message]);
  3125. end;
  3126. end;
  3127. end;
  3128. end;
  3129. function TAsn1InputStream.ReadVector(const dIn: TDefiniteLengthInputStream)
  3130. : IAsn1EncodableVector;
  3131. var
  3132. v: IAsn1EncodableVector;
  3133. o: IAsn1Object;
  3134. subStream: TAsn1InputStream;
  3135. begin
  3136. if (dIn.Remaining < 1) then
  3137. begin
  3138. result := TAsn1EncodableVector.Create(0) as IAsn1EncodableVector;
  3139. Exit;
  3140. end;
  3141. subStream := TAsn1InputStream.Create(dIn);
  3142. try
  3143. v := TAsn1EncodableVector.Create();
  3144. o := subStream.ReadObject();
  3145. while (o <> Nil) do
  3146. begin
  3147. v.Add([o]);
  3148. o := subStream.ReadObject();
  3149. end;
  3150. finally
  3151. subStream.Free;
  3152. end;
  3153. result := v;
  3154. end;
  3155. function TAsn1InputStream.BuildObject(tag, tagNo, length: Int32): IAsn1Object;
  3156. var
  3157. IsConstructed: Boolean;
  3158. defIn: TDefiniteLengthInputStream;
  3159. v: IAsn1EncodableVector;
  3160. strings: TList<IDerOctetString>;
  3161. I: Int32;
  3162. begin
  3163. IsConstructed := (tag and TAsn1Tags.Constructed) <> 0;
  3164. defIn := TDefiniteLengthInputStream.Create(Fs, length);
  3165. if ((tag and TAsn1Tags.Application) <> 0) then
  3166. begin
  3167. try
  3168. result := TDerApplicationSpecific.Create(IsConstructed, tagNo,
  3169. defIn.ToArray());
  3170. Exit;
  3171. finally
  3172. defIn.Free;
  3173. end;
  3174. end;
  3175. if ((tag and TAsn1Tags.Tagged) <> 0) then
  3176. begin
  3177. result := (TAsn1StreamParser.Create(defIn) as IAsn1StreamParser)
  3178. .ReadTaggedObject(IsConstructed, tagNo);
  3179. Exit;
  3180. end;
  3181. if (IsConstructed) then
  3182. begin
  3183. // TODO There are other tags that may be constructed (e.g. BitString)
  3184. case (tagNo) of
  3185. TAsn1Tags.OctetString:
  3186. //
  3187. // yes, people actually do this...
  3188. //
  3189. begin
  3190. try
  3191. v := ReadVector(defIn);
  3192. strings := TList<IDerOctetString>.Create;
  3193. strings.capacity := v.count;
  3194. I := 0;
  3195. while (I <> v.count) do
  3196. begin
  3197. strings.Add(v[I] as IDerOctetString);
  3198. end;
  3199. result := TBerOctetString.Create(strings);
  3200. Exit;
  3201. finally
  3202. defIn.Free;
  3203. end;
  3204. end;
  3205. TAsn1Tags.Sequence:
  3206. begin
  3207. try
  3208. result := CreateDerSequence(defIn);
  3209. Exit;
  3210. finally
  3211. defIn.Free;
  3212. end;
  3213. end;
  3214. TAsn1Tags.&Set:
  3215. begin
  3216. try
  3217. result := CreateDerSet(defIn);
  3218. Exit;
  3219. finally
  3220. defIn.Free;
  3221. end;
  3222. end;
  3223. TAsn1Tags.External:
  3224. begin
  3225. try
  3226. result := TDerExternal.Create(ReadVector(defIn));
  3227. Exit;
  3228. finally
  3229. defIn.Free;
  3230. end;
  3231. end;
  3232. else
  3233. begin
  3234. defIn.Free; // free the stream incase an unsupported tag is encountered.
  3235. raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
  3236. end;
  3237. end;
  3238. end;
  3239. try
  3240. result := CreatePrimitiveDerObject(tagNo, defIn, FtmpBuffers);
  3241. finally
  3242. defIn.Free;
  3243. end;
  3244. end;
  3245. function TAsn1InputStream.CreateDerSequence
  3246. (const dIn: TDefiniteLengthInputStream): IDerSequence;
  3247. begin
  3248. result := TDerSequence.FromVector(ReadVector(dIn));
  3249. end;
  3250. function TAsn1InputStream.CreateDerSet(const dIn
  3251. : TDefiniteLengthInputStream): IDerSet;
  3252. begin
  3253. result := TDerSet.FromVector(ReadVector(dIn), False);
  3254. end;
  3255. class function TAsn1InputStream.ReadTagNumber(const s: TStream;
  3256. tag: Int32): Int32;
  3257. var
  3258. tagNo, b: Int32;
  3259. begin
  3260. tagNo := tag and $1F;
  3261. //
  3262. // with tagged object tag number is bottom 5 bits, or stored at the start of the content
  3263. //
  3264. if (tagNo = $1F) then
  3265. begin
  3266. tagNo := 0;
  3267. b := TStreamSorter.ReadByte(s);
  3268. // X.690-0207 8.1.2.4.2
  3269. // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
  3270. if ((b and $7F) = 0) then // Note: -1 will pass
  3271. begin
  3272. raise EIOCryptoLibException.CreateRes(@SCorruptedStreamInvalidTag);
  3273. end;
  3274. while ((b >= 0) and ((b and $80) <> 0)) do
  3275. begin
  3276. tagNo := tagNo or (b and $7F);
  3277. tagNo := tagNo shl 7;
  3278. b := TStreamSorter.ReadByte(s);
  3279. end;
  3280. if (b < 0) then
  3281. begin
  3282. raise EEndOfStreamCryptoLibException.CreateRes(@SEOFFound);
  3283. end;
  3284. tagNo := tagNo or (b and $7F);
  3285. end;
  3286. result := tagNo;
  3287. end;
  3288. { TDerOutputStream }
  3289. constructor TDerOutputStream.Create(const os: TStream);
  3290. begin
  3291. Inherited Create(os);
  3292. end;
  3293. procedure TDerOutputStream.WriteEncoded(tag: Int32; first: Byte;
  3294. const bytes: TCryptoLibByteArray);
  3295. begin
  3296. WriteByte(Byte(tag));
  3297. WriteLength(System.length(bytes) + 1);
  3298. WriteByte(first);
  3299. Write(bytes[0], System.length(bytes));
  3300. end;
  3301. procedure TDerOutputStream.WriteEncoded(tag: Int32;
  3302. const bytes: TCryptoLibByteArray);
  3303. begin
  3304. WriteByte(Byte(tag));
  3305. WriteLength(System.length(bytes));
  3306. if bytes <> Nil then
  3307. begin
  3308. Write(bytes[0], System.length(bytes));
  3309. end;
  3310. end;
  3311. procedure TDerOutputStream.WriteEncoded(flags, tagNo: Int32;
  3312. const bytes: TCryptoLibByteArray);
  3313. begin
  3314. WriteTag(flags, tagNo);
  3315. WriteLength(System.length(bytes));
  3316. Write(bytes[0], System.length(bytes));
  3317. end;
  3318. procedure TDerOutputStream.WriteEncoded(tag: Int32;
  3319. const bytes: TCryptoLibByteArray; offset, length: Int32);
  3320. begin
  3321. WriteByte(Byte(tag));
  3322. WriteLength(length);
  3323. Write(bytes[offset], length);
  3324. end;
  3325. procedure TDerOutputStream.WriteLength(length: Int32);
  3326. var
  3327. Size, I: Int32;
  3328. val: UInt32;
  3329. begin
  3330. if (length > 127) then
  3331. begin
  3332. Size := 1;
  3333. val := UInt32(length);
  3334. val := val shr 8;
  3335. while (val <> 0) do
  3336. begin
  3337. System.Inc(Size);
  3338. val := val shr 8;
  3339. end;
  3340. WriteByte(Byte(Size or $80));
  3341. I := (Size - 1) * 8;
  3342. while I >= 0 do
  3343. begin
  3344. WriteByte(Byte(TBits.Asr32(length, I)));
  3345. System.Dec(I, 8);
  3346. end;
  3347. end
  3348. else
  3349. begin
  3350. WriteByte(Byte(length));
  3351. end;
  3352. end;
  3353. procedure TDerOutputStream.WriteNull;
  3354. begin
  3355. WriteByte(TAsn1Tags.Null);
  3356. WriteByte($00);
  3357. end;
  3358. procedure TDerOutputStream.WriteObject(const obj: IAsn1Encodable);
  3359. var
  3360. asn1: IAsn1Object;
  3361. begin
  3362. if (obj = Nil) then
  3363. begin
  3364. WriteNull();
  3365. end
  3366. else
  3367. begin
  3368. asn1 := obj.ToAsn1Object();
  3369. asn1.Encode(Self);
  3370. end;
  3371. end;
  3372. procedure TDerOutputStream.WriteObject(const obj: IAsn1Object);
  3373. begin
  3374. if (obj = Nil) then
  3375. begin
  3376. WriteNull();
  3377. end
  3378. else
  3379. begin
  3380. obj.Encode(Self);
  3381. end;
  3382. end;
  3383. procedure TDerOutputStream.WriteTag(flags, tagNo: Int32);
  3384. var
  3385. stack: TCryptoLibByteArray;
  3386. Pos: Int32;
  3387. begin
  3388. if (tagNo < 31) then
  3389. begin
  3390. WriteByte(Byte(flags or tagNo));
  3391. end
  3392. else
  3393. begin
  3394. WriteByte(Byte(flags or $1F));
  3395. if (tagNo < 128) then
  3396. begin
  3397. WriteByte(Byte(tagNo));
  3398. end
  3399. else
  3400. begin
  3401. System.SetLength(stack, 5);
  3402. Pos := System.length(stack);
  3403. System.Dec(Pos);
  3404. stack[Pos] := Byte(tagNo and $7F);
  3405. repeat
  3406. tagNo := TBits.Asr32(tagNo, 7);
  3407. System.Dec(Pos);
  3408. stack[Pos] := Byte(tagNo and $7F or $80);
  3409. until (not(tagNo > 127));
  3410. Write(stack[Pos], System.length(stack) - Pos);
  3411. end;
  3412. end;
  3413. end;
  3414. { TAsn1OutputStream }
  3415. constructor TAsn1OutputStream.Create(os: TStream);
  3416. begin
  3417. Inherited Create(os);
  3418. end;
  3419. { TBerOutputStream }
  3420. constructor TBerOutputStream.Create(os: TStream);
  3421. begin
  3422. Inherited Create(os);
  3423. end;
  3424. { TConstructedOctetStream }
  3425. constructor TConstructedOctetStream.Create(const parser: IAsn1StreamParser);
  3426. begin
  3427. Inherited Create();
  3428. F_parser := parser;
  3429. F_first := True;
  3430. end;
  3431. function TConstructedOctetStream.Read(buffer: TCryptoLibByteArray;
  3432. offset, count: LongInt): LongInt;
  3433. var
  3434. s, aos: IAsn1OctetStringParser;
  3435. totalRead, numRead: Int32;
  3436. begin
  3437. if (F_currentStream = Nil) then
  3438. begin
  3439. if (not F_first) then
  3440. begin
  3441. result := 0;
  3442. Exit;
  3443. end;
  3444. if (not Supports(F_parser.ReadObject(), IAsn1OctetStringParser, s)) then
  3445. begin
  3446. result := 0;
  3447. Exit;
  3448. end;
  3449. F_first := False;
  3450. F_currentStream := s.GetOctetStream();
  3451. end;
  3452. totalRead := 0;
  3453. while True do
  3454. begin
  3455. numRead := TStreamSorter.Read(F_currentStream, buffer, offset + totalRead,
  3456. count - totalRead);
  3457. if (numRead > 0) then
  3458. begin
  3459. totalRead := totalRead + numRead;
  3460. if (totalRead = count) then
  3461. begin
  3462. result := totalRead;
  3463. Exit;
  3464. end;
  3465. end
  3466. else
  3467. begin
  3468. if (not Supports(F_parser.ReadObject(), IAsn1OctetStringParser, aos)) then
  3469. begin
  3470. F_currentStream := Nil;
  3471. result := totalRead;
  3472. Exit;
  3473. end;
  3474. F_currentStream := aos.GetOctetStream();
  3475. end
  3476. end;
  3477. result := 0;
  3478. end;
  3479. function TConstructedOctetStream.ReadByte: Int32;
  3480. var
  3481. s, aos: IAsn1OctetStringParser;
  3482. b: Int32;
  3483. begin
  3484. if (F_currentStream = Nil) then
  3485. begin
  3486. if (not F_first) then
  3487. begin
  3488. result := 0;
  3489. Exit;
  3490. end;
  3491. if (not Supports(F_parser.ReadObject(), IAsn1OctetStringParser, s)) then
  3492. begin
  3493. result := 0;
  3494. Exit;
  3495. end;
  3496. F_first := False;
  3497. F_currentStream := s.GetOctetStream();
  3498. end;
  3499. while True do
  3500. begin
  3501. // b := F_currentStream.ReadByte();
  3502. b := TStreamSorter.ReadByte(F_currentStream);
  3503. if (b >= 0) then
  3504. begin
  3505. result := b;
  3506. Exit;
  3507. end;
  3508. if (not Supports(F_parser.ReadObject(), IAsn1OctetStringParser, aos)) then
  3509. begin
  3510. F_currentStream := Nil;
  3511. result := -1;
  3512. Exit;
  3513. end;
  3514. F_currentStream := aos.GetOctetStream();
  3515. end;
  3516. result := 0;
  3517. end;
  3518. { TIndefiniteLengthInputStream }
  3519. function TIndefiniteLengthInputStream.RequireByte: Int32;
  3520. begin
  3521. // result := F_in.ReadByte();
  3522. result := TStreamSorter.ReadByte(F_in);
  3523. if (result < 0) then
  3524. begin
  3525. // Corrupted stream
  3526. raise EEndOfStreamCryptoLibException.Create('');
  3527. end;
  3528. end;
  3529. function TIndefiniteLengthInputStream.CheckForEof: Boolean;
  3530. var
  3531. extra: Int32;
  3532. begin
  3533. if (F_lookAhead = $00) then
  3534. begin
  3535. extra := RequireByte();
  3536. if (extra <> 0) then
  3537. begin
  3538. raise EIOCryptoLibException.CreateRes(@SMalformedContent);
  3539. end;
  3540. F_lookAhead := -1;
  3541. SetParentEofDetect(True);
  3542. result := True;
  3543. Exit;
  3544. end;
  3545. result := F_lookAhead < 0;
  3546. end;
  3547. constructor TIndefiniteLengthInputStream.Create(inStream: TStream;
  3548. limit: Int32);
  3549. begin
  3550. Inherited Create(inStream, limit);
  3551. F_lookAhead := RequireByte();
  3552. CheckForEof();
  3553. end;
  3554. function TIndefiniteLengthInputStream.Read(buffer: TCryptoLibByteArray;
  3555. offset, count: LongInt): LongInt;
  3556. var
  3557. numRead: Int32;
  3558. begin
  3559. // Only use this optimisation if we aren't checking for 00
  3560. if ((F_eofOn00) or (count <= 1)) then
  3561. begin
  3562. result := (Inherited Read(buffer, offset, count));
  3563. Exit;
  3564. end;
  3565. if (F_lookAhead < 0) then
  3566. begin
  3567. result := 0;
  3568. Exit;
  3569. end;
  3570. numRead := TStreamSorter.Read(F_in, buffer, offset + 1, count - 1);
  3571. if (numRead <= 0) then
  3572. begin
  3573. // Corrupted stream
  3574. raise EEndOfStreamCryptoLibException.Create('');
  3575. end;
  3576. buffer[offset] := Byte(F_lookAhead);
  3577. F_lookAhead := RequireByte();
  3578. result := numRead + 1;
  3579. end;
  3580. function TIndefiniteLengthInputStream.ReadByte: Int32;
  3581. begin
  3582. if (F_eofOn00 and CheckForEof()) then
  3583. begin
  3584. result := -1;
  3585. Exit;
  3586. end;
  3587. result := F_lookAhead;
  3588. F_lookAhead := RequireByte();
  3589. end;
  3590. procedure TIndefiniteLengthInputStream.SetEofOn00(eofOn00: Boolean);
  3591. begin
  3592. F_eofOn00 := eofOn00;
  3593. if (F_eofOn00) then
  3594. begin
  3595. CheckForEof();
  3596. end;
  3597. end;
  3598. { TCollectionUtilities }
  3599. class function TCollectionUtilities.ToStructuredString
  3600. (c: TCryptoLibGenericArray<IAsn1Encodable>): String;
  3601. var
  3602. sl: TStringList;
  3603. idx: Int32;
  3604. begin
  3605. if (c = Nil) then
  3606. begin
  3607. result := '[]';
  3608. Exit;
  3609. end;
  3610. sl := TStringList.Create();
  3611. sl.LineBreak := '';
  3612. try
  3613. sl.Add('[');
  3614. sl.Add((c[0] as TAsn1Encodable).ClassName);
  3615. if System.length(c) > 1 then
  3616. begin
  3617. for idx := 1 to System.length(c) - 2 do
  3618. begin
  3619. sl.Add(', ');
  3620. sl.Add((c[idx] as TAsn1Encodable).ClassName);
  3621. end;
  3622. end;
  3623. sl.Add(']');
  3624. result := sl.Text;
  3625. finally
  3626. sl.Free;
  3627. end;
  3628. end;
  3629. { TAsn1Encodable }
  3630. function TAsn1Encodable.Equals(const other: IAsn1Convertible): Boolean;
  3631. var
  3632. o1, o2: IAsn1Object;
  3633. begin
  3634. if (other = Self as IAsn1Convertible) then
  3635. begin
  3636. result := True;
  3637. Exit;
  3638. end;
  3639. if (other = Nil) then
  3640. begin
  3641. result := False;
  3642. Exit;
  3643. end;
  3644. o1 := ToAsn1Object();
  3645. o2 := other.ToAsn1Object();
  3646. result := ((o1 = o2) or ((o2 <> Nil) and (o1.CallAsn1Equals(o2))));
  3647. end;
  3648. function TAsn1Encodable.GetDerEncoded: TCryptoLibByteArray;
  3649. begin
  3650. try
  3651. result := GetEncoded(Der);
  3652. except
  3653. on e: EIOCryptoLibException do
  3654. begin
  3655. result := Nil;
  3656. end;
  3657. end;
  3658. end;
  3659. function TAsn1Encodable.GetEncoded: TCryptoLibByteArray;
  3660. var
  3661. bOut: TMemoryStream;
  3662. aOut: TAsn1OutputStream;
  3663. begin
  3664. bOut := TMemoryStream.Create();
  3665. aOut := TAsn1OutputStream.Create(bOut);
  3666. try
  3667. aOut.WriteObject(Self as IAsn1Encodable);
  3668. System.SetLength(result, bOut.Size);
  3669. bOut.Position := 0;
  3670. bOut.Read(result[0], System.length(result));
  3671. finally
  3672. bOut.Free;
  3673. aOut.Free;
  3674. end;
  3675. end;
  3676. function TAsn1Encodable.GetEncoded(const encoding: String): TCryptoLibByteArray;
  3677. var
  3678. bOut: TMemoryStream;
  3679. dOut: TDerOutputStream;
  3680. begin
  3681. if (encoding = Der) then
  3682. begin
  3683. bOut := TMemoryStream.Create();
  3684. dOut := TDerOutputStream.Create(bOut);
  3685. try
  3686. dOut.WriteObject(Self as IAsn1Encodable);
  3687. System.SetLength(result, bOut.Size);
  3688. bOut.Position := 0;
  3689. bOut.Read(result[0], System.length(result));
  3690. finally
  3691. bOut.Free;
  3692. dOut.Free;
  3693. end;
  3694. Exit;
  3695. end;
  3696. result := GetEncoded();
  3697. end;
  3698. function TAsn1Encodable.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
  3699. {$ENDIF DELPHI}
  3700. begin
  3701. result := ToAsn1Object().CallAsn1GetHashCode();
  3702. end;
  3703. class function TAsn1Encodable.IsNullOrContainsNull
  3704. (const data: TCryptoLibGenericArray<IAsn1Encodable>): Boolean;
  3705. var
  3706. count, I: Int32;
  3707. begin
  3708. if (data = Nil) then
  3709. begin
  3710. result := True;
  3711. Exit;
  3712. end;
  3713. count := System.length(data);
  3714. for I := 0 to System.Pred(count) do
  3715. begin
  3716. if (data[I] = Nil) then
  3717. begin
  3718. result := True;
  3719. Exit;
  3720. end;
  3721. end;
  3722. result := False;
  3723. end;
  3724. class function TAsn1Encodable.OpenArrayToDynamicArray
  3725. (const data: array of IAsn1Encodable): TCryptoLibGenericArray<IAsn1Encodable>;
  3726. var
  3727. LDataLength, LIdx: Int32;
  3728. begin
  3729. LDataLength := System.length(data);
  3730. System.SetLength(result, LDataLength);
  3731. for LIdx := 0 to System.Pred(LDataLength) do
  3732. begin
  3733. result[LIdx] := data[LIdx];
  3734. end;
  3735. end;
  3736. { TAsn1Object }
  3737. function TAsn1Object.CallAsn1Equals(const obj: IAsn1Object): Boolean;
  3738. begin
  3739. result := Asn1Equals(obj);
  3740. end;
  3741. function TAsn1Object.CallAsn1GetHashCode: Int32;
  3742. begin
  3743. result := Asn1GetHashCode();
  3744. end;
  3745. class function TAsn1Object.FromByteArray(const data: TCryptoLibByteArray)
  3746. : IAsn1Object;
  3747. var
  3748. asn1: TAsn1InputStream;
  3749. input: TBytesStream;
  3750. begin
  3751. try
  3752. // used TBytesStream here for one pass creation and population with byte array :)
  3753. input := TBytesStream.Create(data);
  3754. try
  3755. asn1 := TAsn1InputStream.Create(input, System.length(data));
  3756. try
  3757. result := asn1.ReadObject();
  3758. finally
  3759. asn1.Free;
  3760. end;
  3761. if (input.Position <> input.Size) then
  3762. begin
  3763. raise EIOCryptoLibException.CreateRes(@SExtraData);
  3764. end;
  3765. finally
  3766. input.Free;
  3767. end;
  3768. except
  3769. on e: EInvalidCastCryptoLibException do
  3770. begin
  3771. raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectByteArray);
  3772. end;
  3773. end;
  3774. end;
  3775. class function TAsn1Object.FromStream(const inStr: TStream): IAsn1Object;
  3776. var
  3777. asn1Stream: TAsn1InputStream;
  3778. begin
  3779. asn1Stream := TAsn1InputStream.Create(inStr);
  3780. try
  3781. try
  3782. result := asn1Stream.ReadObject();
  3783. except
  3784. on e: EInvalidCastCryptoLibException do
  3785. begin
  3786. raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectStream);
  3787. end;
  3788. end;
  3789. finally
  3790. asn1Stream.Free;
  3791. end;
  3792. end;
  3793. function TAsn1Object.ToAsn1Object: IAsn1Object;
  3794. begin
  3795. result := Self as IAsn1Object;
  3796. end;
  3797. { TDerObjectIdentifier }
  3798. function TDerObjectIdentifier.GetID: String;
  3799. begin
  3800. result := Fidentifier;
  3801. end;
  3802. function TDerObjectIdentifier.Asn1Equals(const asn1Object: IAsn1Object)
  3803. : Boolean;
  3804. var
  3805. other: IDerObjectIdentifier;
  3806. begin
  3807. if (not Supports(asn1Object, IDerObjectIdentifier, other)) then
  3808. begin
  3809. result := False;
  3810. Exit;
  3811. end;
  3812. result := ID = other.ID;
  3813. end;
  3814. function TDerObjectIdentifier.Asn1GetHashCode: Int32;
  3815. begin
  3816. result := TStringUtils.GetStringHashCode(Fidentifier);
  3817. end;
  3818. class procedure TDerObjectIdentifier.Boot;
  3819. begin
  3820. if FLock = Nil then
  3821. begin
  3822. FLock := TCriticalSection.Create;
  3823. end;
  3824. end;
  3825. function TDerObjectIdentifier.Branch(const branchID: String)
  3826. : IDerObjectIdentifier;
  3827. begin
  3828. result := TDerObjectIdentifier.Create(Self as IDerObjectIdentifier, branchID);
  3829. end;
  3830. constructor TDerObjectIdentifier.Create(const oid: IDerObjectIdentifier;
  3831. const branchID: String);
  3832. begin
  3833. Inherited Create();
  3834. if (not(IsValidBranchID(branchID, 1))) then
  3835. begin
  3836. raise EArgumentCryptoLibException.CreateResFmt(@SInvalidBranchId,
  3837. [branchID]);
  3838. end;
  3839. Fidentifier := oid.ID + '.' + branchID;
  3840. end;
  3841. constructor TDerObjectIdentifier.Create(const identifier: String);
  3842. begin
  3843. Inherited Create();
  3844. if (identifier = '') then
  3845. begin
  3846. raise EArgumentNilCryptoLibException.CreateRes(@SIdentifierNil);
  3847. end;
  3848. if (not(IsValidIdentifier(identifier))) then
  3849. begin
  3850. raise EFormatCryptoLibException.CreateResFmt(@SInvalidOID, [identifier]);
  3851. end;
  3852. Fidentifier := identifier;
  3853. end;
  3854. constructor TDerObjectIdentifier.Create(const bytes: TCryptoLibByteArray);
  3855. begin
  3856. Inherited Create();
  3857. Fidentifier := MakeOidStringFromBytes(bytes);
  3858. Fbody := System.Copy(bytes);
  3859. end;
  3860. function TDerObjectIdentifier.&on(const stem: IDerObjectIdentifier): Boolean;
  3861. var
  3862. LocalId, stemId: String;
  3863. begin
  3864. LocalId := ID;
  3865. stemId := stem.ID;
  3866. result := (System.length(LocalId) > System.length(stemId)) and
  3867. (LocalId[System.length(stemId) + 1] = '.') and
  3868. (AnsiStartsStr(stemId, LocalId));
  3869. end;
  3870. class constructor TDerObjectIdentifier.CreateDerObjectIdentifier;
  3871. begin
  3872. TDerObjectIdentifier.Boot;
  3873. end;
  3874. class destructor TDerObjectIdentifier.DestroyDerObjectIdentifier;
  3875. begin
  3876. FLock.Free;
  3877. end;
  3878. procedure TDerObjectIdentifier.DoOutput(const bOut: TMemoryStream);
  3879. var
  3880. tok: IOidTokenizer;
  3881. token: String;
  3882. first: Int32;
  3883. begin
  3884. tok := TOidTokenizer.Create(Fidentifier);
  3885. token := tok.NextToken();
  3886. first := StrToInt(token) * 40;
  3887. token := tok.NextToken();
  3888. if (System.length(token) <= 18) then
  3889. begin
  3890. WriteField(bOut, Int64(first + StrToInt64(token)));
  3891. end
  3892. else
  3893. begin
  3894. WriteField(bOut, TBigInteger.Create(token).Add(TBigInteger.ValueOf(first)));
  3895. end;
  3896. while (tok.HasMoreTokens) do
  3897. begin
  3898. token := tok.NextToken();
  3899. if (System.length(token) <= 18) then
  3900. begin
  3901. WriteField(bOut, StrToInt64(token));
  3902. end
  3903. else
  3904. begin
  3905. WriteField(bOut, TBigInteger.Create(token));
  3906. end;
  3907. end;
  3908. end;
  3909. procedure TDerObjectIdentifier.Encode(const derOut: TStream);
  3910. begin
  3911. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.ObjectIdentifier,
  3912. GetBody());
  3913. end;
  3914. class function TDerObjectIdentifier.FromOctetString
  3915. (const enc: TCryptoLibByteArray): IDerObjectIdentifier;
  3916. var
  3917. HashCode, first: Int32;
  3918. entry: IDerObjectIdentifier;
  3919. begin
  3920. HashCode := TArrayUtils.GetArrayHashCode(enc);
  3921. first := HashCode and 1023;
  3922. FLock.Acquire;
  3923. try
  3924. entry := Fcache[first];
  3925. if ((entry <> Nil) and (TArrayUtils.AreEqual(enc, entry.GetBody()))) then
  3926. begin
  3927. result := entry;
  3928. Exit;
  3929. end;
  3930. Fcache[first] := TDerObjectIdentifier.Create(enc);
  3931. result := Fcache[first];
  3932. finally
  3933. FLock.Release;
  3934. end;
  3935. end;
  3936. function TDerObjectIdentifier.GetBody: TCryptoLibByteArray;
  3937. var
  3938. bOut: TMemoryStream;
  3939. begin
  3940. FLock.Acquire;
  3941. try
  3942. if (Fbody = Nil) then
  3943. begin
  3944. bOut := TMemoryStream.Create();
  3945. try
  3946. DoOutput(bOut);
  3947. System.SetLength(Fbody, bOut.Size);
  3948. bOut.Position := 0;
  3949. bOut.Read(Fbody[0], System.length(Fbody));
  3950. finally
  3951. bOut.Free;
  3952. end;
  3953. end;
  3954. finally
  3955. FLock.Release;
  3956. end;
  3957. result := Fbody;
  3958. end;
  3959. class function TDerObjectIdentifier.GetInstance(const obj: IAsn1TaggedObject;
  3960. explicitly: Boolean): IDerObjectIdentifier;
  3961. var
  3962. o: IAsn1Object;
  3963. begin
  3964. o := obj.GetObject();
  3965. if ((explicitly) or (Supports(o, IDerObjectIdentifier))) then
  3966. begin
  3967. result := GetInstance(o as TAsn1Object);
  3968. Exit;
  3969. end;
  3970. result := FromOctetString(TAsn1OctetString.GetInstance(o as TAsn1Object)
  3971. .GetOctets());
  3972. end;
  3973. class function TDerObjectIdentifier.GetInstance(const obj: TObject)
  3974. : IDerObjectIdentifier;
  3975. begin
  3976. if ((obj = Nil) or (obj is TDerObjectIdentifier)) then
  3977. begin
  3978. result := obj as TDerObjectIdentifier;
  3979. Exit;
  3980. end;
  3981. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  3982. [obj.ClassName]);
  3983. end;
  3984. class function TDerObjectIdentifier.GetInstance(const obj: TCryptoLibByteArray)
  3985. : IDerObjectIdentifier;
  3986. begin
  3987. result := FromOctetString(obj);
  3988. end;
  3989. class function TDerObjectIdentifier.IsValidBranchID(const branchID: String;
  3990. start: Int32): Boolean;
  3991. var
  3992. digitCount, Pos: Int32;
  3993. ch: Char;
  3994. begin
  3995. digitCount := 0;
  3996. Pos := System.length(branchID) + 1;
  3997. System.Dec(Pos);
  3998. while (Pos >= start) do
  3999. begin
  4000. ch := branchID[Pos];
  4001. if (ch = '.') then
  4002. begin
  4003. if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0')))
  4004. then
  4005. begin
  4006. result := False;
  4007. Exit;
  4008. end;
  4009. digitCount := 0;
  4010. end
  4011. else if (CharInSet(ch, ['0' .. '9'])) then
  4012. begin
  4013. System.Inc(digitCount);
  4014. end
  4015. else
  4016. begin
  4017. result := False;
  4018. Exit;
  4019. end;
  4020. System.Dec(Pos);
  4021. end;
  4022. if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0'))) then
  4023. begin
  4024. result := False;
  4025. Exit;
  4026. end;
  4027. result := True;
  4028. end;
  4029. class function TDerObjectIdentifier.IsValidIdentifier(const identifier
  4030. : String): Boolean;
  4031. var
  4032. first: Char;
  4033. begin
  4034. if ((System.length(identifier) < 3) or (identifier[2] <> '.')) then
  4035. begin
  4036. result := False;
  4037. Exit;
  4038. end;
  4039. first := identifier[1];
  4040. if (not CharInSet(first, ['0' .. '2'])) then
  4041. begin
  4042. result := False;
  4043. Exit;
  4044. end;
  4045. result := IsValidBranchID(identifier, 3);
  4046. end;
  4047. class function TDerObjectIdentifier.MakeOidStringFromBytes
  4048. (const bytes: TCryptoLibByteArray): String;
  4049. var
  4050. objId: TStringList;
  4051. Value: Int64;
  4052. bigValue: TBigInteger;
  4053. first: Boolean;
  4054. I, b: Int32;
  4055. begin
  4056. Value := 0;
  4057. bigValue := Default (TBigInteger);
  4058. first := True;
  4059. objId := TStringList.Create();
  4060. objId.LineBreak := '';
  4061. try
  4062. I := 0;
  4063. while I <> System.length(bytes) do
  4064. begin
  4065. b := Int32(bytes[I]);
  4066. if (Value <= LONG_LIMIT) then
  4067. begin
  4068. Value := Value + (b and $7F);
  4069. if ((b and $80) = 0) then // end of number reached
  4070. begin
  4071. if (first) then
  4072. begin
  4073. if (Value < 40) then
  4074. begin
  4075. objId.Add('0');
  4076. end
  4077. else if (Value < 80) then
  4078. begin
  4079. objId.Add('1');
  4080. Value := Value - 40;
  4081. end
  4082. else
  4083. begin
  4084. objId.Add('2');
  4085. Value := Value - 80;
  4086. end;
  4087. first := False;
  4088. end;
  4089. objId.Add('.');
  4090. objId.Add(IntToStr(Value));
  4091. Value := 0;
  4092. end
  4093. else
  4094. begin
  4095. Value := Value shl 7;
  4096. end;
  4097. end
  4098. else
  4099. begin
  4100. if (not bigValue.IsInitialized) then
  4101. begin
  4102. bigValue := TBigInteger.ValueOf(Value);
  4103. end;
  4104. bigValue := bigValue.&Or(TBigInteger.ValueOf(b and $7F));
  4105. if ((b and $80) = 0) then
  4106. begin
  4107. if (first) then
  4108. begin
  4109. objId.Add('2');
  4110. bigValue := bigValue.Subtract(TBigInteger.ValueOf(80));
  4111. first := False;
  4112. end;
  4113. objId.Add('.');
  4114. objId.Add(bigValue.ToString());
  4115. bigValue := Default (TBigInteger);
  4116. Value := 0;
  4117. end
  4118. else
  4119. begin
  4120. bigValue := bigValue.ShiftLeft(7);
  4121. end
  4122. end;
  4123. System.Inc(I);
  4124. end;
  4125. result := objId.Text;
  4126. finally
  4127. objId.Free;
  4128. end;
  4129. end;
  4130. function TDerObjectIdentifier.ToString: String;
  4131. begin
  4132. result := ID;
  4133. end;
  4134. procedure TDerObjectIdentifier.WriteField(const outputStream: TStream;
  4135. const fieldValue: TBigInteger);
  4136. var
  4137. byteCount, I: Int32;
  4138. tmpValue: TBigInteger;
  4139. tmp: TCryptoLibByteArray;
  4140. begin
  4141. byteCount := (fieldValue.BitLength + 6) div 7;
  4142. if (byteCount = 0) then
  4143. begin
  4144. outputStream.WriteByte(0);
  4145. end
  4146. else
  4147. begin
  4148. tmpValue := fieldValue;
  4149. System.SetLength(tmp, byteCount);
  4150. I := byteCount - 1;
  4151. while I >= 0 do
  4152. begin
  4153. tmp[I] := Byte((tmpValue.Int32Value and $7F) or $80);
  4154. tmpValue := tmpValue.ShiftRight(7);
  4155. System.Dec(I);
  4156. end;
  4157. tmp[byteCount - 1] := tmp[byteCount - 1] and $7F;
  4158. outputStream.Write(tmp[0], System.length(tmp));
  4159. end;
  4160. end;
  4161. procedure TDerObjectIdentifier.WriteField(const outputStream: TStream;
  4162. fieldValue: Int64);
  4163. var
  4164. tempRes: TCryptoLibByteArray;
  4165. Pos: Int32;
  4166. begin
  4167. System.SetLength(tempRes, 9);
  4168. Pos := 8;
  4169. tempRes[Pos] := Byte(fieldValue and $7F);
  4170. while (fieldValue >= (Int64(1) shl 7)) do
  4171. begin
  4172. fieldValue := TBits.Asr64(fieldValue, 7);
  4173. System.Dec(Pos);
  4174. tempRes[Pos] := Byte((fieldValue and $7F) or $80);
  4175. end;
  4176. outputStream.Write(tempRes[Pos], 9 - Pos);
  4177. end;
  4178. { TAsn1EncodableVector }
  4179. procedure TAsn1EncodableVector.Add(const objs: array of IAsn1Encodable);
  4180. var
  4181. obj: IAsn1Encodable;
  4182. begin
  4183. for obj in objs do
  4184. begin
  4185. Add(obj);
  4186. end;
  4187. end;
  4188. procedure TAsn1EncodableVector.Add(const element: IAsn1Encodable);
  4189. var
  4190. capacity, minCapacity: Int32;
  4191. begin
  4192. if (element = Nil) then
  4193. begin
  4194. raise EArgumentNilCryptoLibException.CreateRes(@SElementNil);
  4195. end;
  4196. capacity := System.length(FElements);
  4197. minCapacity := FElementCount + 1;
  4198. if ((minCapacity > capacity) or FCopyOnWrite) then
  4199. begin
  4200. Reallocate(minCapacity);
  4201. end;
  4202. FElements[FElementCount] := element;
  4203. FElementCount := minCapacity;
  4204. end;
  4205. procedure TAsn1EncodableVector.AddAll(const other: IAsn1EncodableVector);
  4206. var
  4207. otherElementCount, capacity, minCapacity, I: Int32;
  4208. otherElement: IAsn1Encodable;
  4209. begin
  4210. if (other = Nil) then
  4211. begin
  4212. raise EArgumentNilCryptoLibException.CreateRes(@SOtherNil);
  4213. end;
  4214. otherElementCount := other.count;
  4215. if (otherElementCount < 1) then
  4216. begin
  4217. Exit;
  4218. end;
  4219. capacity := System.length(FElements);
  4220. minCapacity := FElementCount + otherElementCount;
  4221. if ((minCapacity > capacity) or FCopyOnWrite) then
  4222. begin
  4223. Reallocate(minCapacity);
  4224. end;
  4225. I := 0;
  4226. repeat
  4227. otherElement := other[I];
  4228. if (otherElement = Nil) then
  4229. begin
  4230. raise ENullReferenceCryptoLibException.CreateRes(@SOtherElementsNil);
  4231. end;
  4232. FElements[FElementCount + I] := otherElement;
  4233. System.Inc(I);
  4234. until not(I < otherElementCount);
  4235. FElementCount := minCapacity;
  4236. end;
  4237. procedure TAsn1EncodableVector.AddOptional(const objs: array of IAsn1Encodable);
  4238. var
  4239. obj: IAsn1Encodable;
  4240. begin
  4241. if (System.length(objs) <> 0) then
  4242. begin
  4243. for obj in objs do
  4244. begin
  4245. if (obj <> Nil) then
  4246. begin
  4247. Add(obj);
  4248. end;
  4249. end;
  4250. end;
  4251. end;
  4252. procedure TAsn1EncodableVector.AddOptionalTagged(isExplicit: Boolean;
  4253. tagNo: Int32; const obj: IAsn1Encodable);
  4254. begin
  4255. if (obj <> Nil) then
  4256. begin
  4257. Add(TDerTaggedObject.Create(isExplicit, tagNo, obj) as IDerTaggedObject);
  4258. end;
  4259. end;
  4260. function TAsn1EncodableVector.CopyElements
  4261. : TCryptoLibGenericArray<IAsn1Encodable>;
  4262. begin
  4263. if (FElementCount = 0) then
  4264. begin
  4265. result := EmptyElements;
  4266. Exit;
  4267. end;
  4268. result := System.Copy(FElements, 0, FElementCount);
  4269. System.SetLength(result, FElementCount);
  4270. end;
  4271. constructor TAsn1EncodableVector.Create(const v: array of IAsn1Encodable);
  4272. begin
  4273. inherited Create();
  4274. Add(v);
  4275. end;
  4276. constructor TAsn1EncodableVector.Create(initialCapacity: Int32);
  4277. begin
  4278. Inherited Create();
  4279. if (initialCapacity < 0) then
  4280. begin
  4281. raise EArgumentCryptoLibException.CreateRes(@SInitialCapacityNegative);
  4282. end;
  4283. if (initialCapacity = 0) then
  4284. begin
  4285. FElements := EmptyElements;
  4286. end
  4287. else
  4288. begin
  4289. System.SetLength(FElements, initialCapacity);
  4290. end;
  4291. FElementCount := 0;
  4292. FCopyOnWrite := False;
  4293. end;
  4294. constructor TAsn1EncodableVector.Create();
  4295. begin
  4296. Create(DefaultCapacity);
  4297. end;
  4298. destructor TAsn1EncodableVector.Destroy;
  4299. begin
  4300. inherited Destroy;
  4301. end;
  4302. class function TAsn1EncodableVector.FromEnumerable
  4303. (const e: TList<IAsn1Encodable>): IAsn1EncodableVector;
  4304. var
  4305. v: IAsn1EncodableVector;
  4306. obj: IAsn1Encodable;
  4307. begin
  4308. v := TAsn1EncodableVector.Create();
  4309. for obj in e do
  4310. begin
  4311. v.Add(obj);
  4312. end;
  4313. result := v;
  4314. end;
  4315. function TAsn1EncodableVector.GetCount: Int32;
  4316. begin
  4317. result := FElementCount;
  4318. end;
  4319. class function TAsn1EncodableVector.GetEmptyElements
  4320. : TCryptoLibGenericArray<IAsn1Encodable>;
  4321. begin
  4322. result := Nil;
  4323. end;
  4324. function TAsn1EncodableVector.GetEnumerable
  4325. : TCryptoLibGenericArray<IAsn1Encodable>;
  4326. begin
  4327. result := CopyElements();
  4328. end;
  4329. function TAsn1EncodableVector.GetSelf(Index: Int32): IAsn1Encodable;
  4330. begin
  4331. if (Index >= FElementCount) then
  4332. begin
  4333. raise EIndexOutOfRangeCryptoLibException.CreateResFmt(@SIndexOutOfRange,
  4334. [Index, FElementCount]);
  4335. end;
  4336. result := FElements[Index];
  4337. end;
  4338. procedure TAsn1EncodableVector.Reallocate(minCapacity: Int32);
  4339. var
  4340. oldCapacity, newCapacity: Int32;
  4341. LocalCopy: TCryptoLibGenericArray<IAsn1Encodable>;
  4342. begin
  4343. oldCapacity := System.length(FElements);
  4344. newCapacity := Max(oldCapacity, minCapacity + (TBits.Asr32(minCapacity, 1)));
  4345. LocalCopy := System.Copy(FElements, 0, FElementCount);
  4346. System.SetLength(LocalCopy, newCapacity);
  4347. FElements := LocalCopy;
  4348. FCopyOnWrite := False;
  4349. end;
  4350. function TAsn1EncodableVector.TakeElements
  4351. : TCryptoLibGenericArray<IAsn1Encodable>;
  4352. begin
  4353. if (FElementCount = 0) then
  4354. begin
  4355. result := EmptyElements;
  4356. Exit;
  4357. end;
  4358. if (System.length(FElements) = FElementCount) then
  4359. begin
  4360. FCopyOnWrite := True;
  4361. result := FElements;
  4362. Exit;
  4363. end;
  4364. result := System.Copy(FElements, 0, FElementCount);
  4365. System.SetLength(result, FElementCount);
  4366. end;
  4367. class function TAsn1EncodableVector.CloneElements(const elements
  4368. : TCryptoLibGenericArray<IAsn1Encodable>)
  4369. : TCryptoLibGenericArray<IAsn1Encodable>;
  4370. begin
  4371. if System.length(elements) < 1 then
  4372. begin
  4373. result := EmptyElements;
  4374. end
  4375. else
  4376. begin
  4377. result := System.Copy(elements);
  4378. end;
  4379. end;
  4380. { TAsn1Generator }
  4381. constructor TAsn1Generator.Create(outStream: TStream);
  4382. begin
  4383. F_out := outStream;
  4384. end;
  4385. function TAsn1Generator.GetOut: TStream;
  4386. begin
  4387. result := F_out;
  4388. end;
  4389. { TAsn1Null }
  4390. function TAsn1Null.ToString: String;
  4391. begin
  4392. result := 'NULL';
  4393. end;
  4394. { TAsn1OctetString }
  4395. function TAsn1OctetString.GetStr: TCryptoLibByteArray;
  4396. begin
  4397. result := FStr;
  4398. end;
  4399. function TAsn1OctetString.GetParser: IAsn1OctetStringParser;
  4400. begin
  4401. result := Self as IAsn1OctetStringParser;
  4402. end;
  4403. constructor TAsn1OctetString.Create(const Str: TCryptoLibByteArray);
  4404. begin
  4405. Inherited Create();
  4406. if (Str = Nil) then
  4407. begin
  4408. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  4409. end;
  4410. FStr := Str;
  4411. end;
  4412. function TAsn1OctetString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  4413. var
  4414. other: IDerOctetString;
  4415. begin
  4416. if (not Supports(asn1Object, IDerOctetString, other)) then
  4417. begin
  4418. result := False;
  4419. Exit;
  4420. end;
  4421. result := TArrayUtils.AreEqual(GetOctets(), other.GetOctets());
  4422. end;
  4423. function TAsn1OctetString.Asn1GetHashCode: Int32;
  4424. begin
  4425. result := TArrayUtils.GetArrayHashCode(GetOctets());
  4426. end;
  4427. constructor TAsn1OctetString.Create(const obj: IAsn1Encodable);
  4428. begin
  4429. Inherited Create();
  4430. try
  4431. FStr := obj.GetEncoded(TAsn1Encodable.Der);
  4432. except
  4433. on e: EIOCryptoLibException do
  4434. begin
  4435. raise EArgumentCryptoLibException.CreateResFmt(@SProcessingError,
  4436. [e.Message]);
  4437. end;
  4438. end;
  4439. end;
  4440. class function TAsn1OctetString.GetInstance(const obj: IAsn1TaggedObject;
  4441. isExplicit: Boolean): IAsn1OctetString;
  4442. var
  4443. o: IAsn1Object;
  4444. begin
  4445. o := obj.GetObject();
  4446. if ((isExplicit) or (Supports(o, IAsn1OctetString))) then
  4447. begin
  4448. result := GetInstance(o as TAsn1Object);
  4449. Exit;
  4450. end;
  4451. result := TBerOctetString.FromSequence
  4452. (TAsn1Sequence.GetInstance(o as TAsn1Object));
  4453. end;
  4454. class function TAsn1OctetString.GetInstance(const obj: TObject)
  4455. : IAsn1OctetString;
  4456. var
  4457. asn1TaggedObject: IAsn1TaggedObject;
  4458. begin
  4459. if ((obj = Nil) or (obj is TAsn1OctetString)) then
  4460. begin
  4461. result := obj as TAsn1OctetString;
  4462. Exit;
  4463. end;
  4464. // TODO: this needs to be deleted in V2
  4465. if Supports(obj, IAsn1TaggedObject, asn1TaggedObject) then
  4466. begin
  4467. result := GetInstance(asn1TaggedObject.GetObject() as TAsn1Object);
  4468. Exit;
  4469. end;
  4470. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  4471. [obj.ClassName]);
  4472. end;
  4473. function TAsn1OctetString.GetOctets: TCryptoLibByteArray;
  4474. begin
  4475. result := Str;
  4476. end;
  4477. function TAsn1OctetString.GetOctetStream: TStream;
  4478. begin
  4479. // used TBytesStream here for one pass creation and population with byte array :)
  4480. result := TBytesStream.Create(Str);
  4481. end;
  4482. function TAsn1OctetString.ToString: String;
  4483. begin
  4484. result := '#' + THex.Encode(Str);
  4485. end;
  4486. { TAsn1Sequence }
  4487. function TAsn1Sequence.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  4488. var
  4489. that: IAsn1Sequence;
  4490. o1, o2: IAsn1Object;
  4491. I, LCount: Int32;
  4492. begin
  4493. that := asn1Object as IAsn1Sequence;
  4494. if (that = Nil) then
  4495. begin
  4496. result := False;
  4497. Exit;
  4498. end;
  4499. LCount := count;
  4500. if (that.count <> LCount) then
  4501. begin
  4502. result := False;
  4503. Exit;
  4504. end;
  4505. for I := 0 to System.Pred(LCount) do
  4506. begin
  4507. o1 := FElements[I].ToAsn1Object();
  4508. o2 := that.elements[I].ToAsn1Object();
  4509. if ((o1 <> o2) and (not o1.CallAsn1Equals(o2))) then
  4510. begin
  4511. result := False;
  4512. Exit;
  4513. end;
  4514. end;
  4515. result := True;
  4516. end;
  4517. function TAsn1Sequence.Asn1GetHashCode: Int32;
  4518. var
  4519. hc, I: Int32;
  4520. begin
  4521. I := System.length(FElements);
  4522. hc := I + 1;
  4523. System.Dec(I);
  4524. while (I >= 0) do
  4525. begin
  4526. hc := hc * 257;
  4527. hc := hc xor (FElements[I].ToAsn1Object().CallAsn1GetHashCode());
  4528. System.Dec(I);
  4529. end;
  4530. result := hc;
  4531. end;
  4532. constructor TAsn1Sequence.Create();
  4533. begin
  4534. inherited Create();
  4535. FElements := TAsn1EncodableVector.EmptyElements;
  4536. end;
  4537. constructor TAsn1Sequence.Create(const element: IAsn1Encodable);
  4538. begin
  4539. Inherited Create();
  4540. if (element = Nil) then
  4541. begin
  4542. raise EArgumentNilCryptoLibException.CreateRes(@SElementNil);
  4543. end;
  4544. FElements := TCryptoLibGenericArray<IAsn1Encodable>.Create(element);
  4545. end;
  4546. constructor TAsn1Sequence.Create(const elementVector: IAsn1EncodableVector);
  4547. begin
  4548. Inherited Create();
  4549. if (elementVector = Nil) then
  4550. begin
  4551. raise EArgumentNilCryptoLibException.CreateRes(@SElementVectorNil);
  4552. end;
  4553. FElements := elementVector.TakeElements();
  4554. end;
  4555. constructor TAsn1Sequence.Create(const elements: array of IAsn1Encodable);
  4556. var
  4557. LElementsCopy: TCryptoLibGenericArray<IAsn1Encodable>;
  4558. begin
  4559. Inherited Create();
  4560. LElementsCopy := OpenArrayToDynamicArray(elements);
  4561. if (TAsn1Encodable.IsNullOrContainsNull(LElementsCopy)) then
  4562. begin
  4563. raise ENullReferenceCryptoLibException.CreateRes(@SElementsNil);
  4564. end;
  4565. FElements := TAsn1EncodableVector.CloneElements(LElementsCopy);
  4566. end;
  4567. destructor TAsn1Sequence.Destroy;
  4568. begin
  4569. inherited Destroy;
  4570. end;
  4571. function TAsn1Sequence.GetCount: Int32;
  4572. begin
  4573. result := System.length(FElements);
  4574. end;
  4575. function TAsn1Sequence.GetElements: TCryptoLibGenericArray<IAsn1Encodable>;
  4576. begin
  4577. result := FElements;
  4578. end;
  4579. function TAsn1Sequence.GetEnumerable: TCryptoLibGenericArray<IAsn1Encodable>;
  4580. begin
  4581. result := FElements;
  4582. end;
  4583. class function TAsn1Sequence.GetInstance(const obj: TObject): IAsn1Sequence;
  4584. var
  4585. primitive: IAsn1Object;
  4586. Sequence: IAsn1Sequence;
  4587. res: IAsn1SequenceParser;
  4588. begin
  4589. if ((obj = Nil) or (obj is TAsn1Sequence)) then
  4590. begin
  4591. result := obj as TAsn1Sequence;
  4592. Exit;
  4593. end;
  4594. if (Supports(obj, IAsn1SequenceParser, res)) then
  4595. begin
  4596. result := TAsn1Sequence.GetInstance(res.ToAsn1Object() as TAsn1Object);
  4597. Exit;
  4598. end;
  4599. if (obj is TAsn1Encodable) then
  4600. begin
  4601. primitive := (obj as TAsn1Encodable).ToAsn1Object();
  4602. if (Supports(primitive, IAsn1Sequence, Sequence)) then
  4603. begin
  4604. result := Sequence;
  4605. Exit;
  4606. end;
  4607. end;
  4608. raise EArgumentCryptoLibException.CreateResFmt(@SUnknownObject,
  4609. [obj.ClassName]);
  4610. end;
  4611. class function TAsn1Sequence.GetInstance(const obj: TCryptoLibByteArray)
  4612. : IAsn1Sequence;
  4613. begin
  4614. try
  4615. result := TAsn1Sequence.GetInstance(FromByteArray(obj) as TAsn1Object);
  4616. except
  4617. on e: EIOCryptoLibException do
  4618. begin
  4619. raise EArgumentCryptoLibException.CreateResFmt(@SInvalidSequence,
  4620. [e.Message]);
  4621. end;
  4622. end;
  4623. end;
  4624. class function TAsn1Sequence.GetInstance(const obj: IAsn1TaggedObject;
  4625. explicitly: Boolean): IAsn1Sequence;
  4626. var
  4627. inner: IAsn1Object;
  4628. Sequence: IAsn1Sequence;
  4629. begin
  4630. inner := obj.GetObject();
  4631. if (explicitly) then
  4632. begin
  4633. if (not(obj.isExplicit())) then
  4634. raise EArgumentCryptoLibException.CreateRes(@SInvalidObject);
  4635. result := inner as IAsn1Sequence;
  4636. Exit;
  4637. end;
  4638. //
  4639. // constructed object which appears to be explicitly tagged
  4640. // when it should be implicit means we have to add the
  4641. // surrounding sequence.
  4642. //
  4643. if (obj.isExplicit()) then
  4644. begin
  4645. if (Supports(obj, IBerTaggedObject)) then
  4646. begin
  4647. result := TBerSequence.Create(inner);
  4648. Exit;
  4649. end;
  4650. result := TDerSequence.Create(inner);
  4651. Exit;
  4652. end;
  4653. if (Supports(inner, IAsn1Sequence, Sequence)) then
  4654. begin
  4655. result := Sequence;
  4656. Exit;
  4657. end;
  4658. raise EArgumentCryptoLibException.CreateResFmt(@SUnknownObject,
  4659. [(obj as TAsn1TaggedObject).ClassName]);
  4660. end;
  4661. function TAsn1Sequence.GetParser: IAsn1SequenceParser;
  4662. begin
  4663. result := TAsn1SequenceParserImpl.Create(Self as IAsn1Sequence);
  4664. end;
  4665. function TAsn1Sequence.GetSelf(Index: Int32): IAsn1Encodable;
  4666. begin
  4667. result := FElements[Index];
  4668. end;
  4669. function TAsn1Sequence.ToArray: TCryptoLibGenericArray<IAsn1Encodable>;
  4670. begin
  4671. result := TAsn1EncodableVector.CloneElements(FElements);
  4672. end;
  4673. function TAsn1Sequence.ToString: String;
  4674. begin
  4675. result := TCollectionUtilities.ToStructuredString(FElements);
  4676. end;
  4677. { TAsn1Sequence.TAsn1SequenceParserImpl }
  4678. constructor TAsn1Sequence.TAsn1SequenceParserImpl.Create
  4679. (const outer: IAsn1Sequence);
  4680. begin
  4681. inherited Create();
  4682. Fouter := outer;
  4683. Fmax := outer.count;
  4684. end;
  4685. function TAsn1Sequence.TAsn1SequenceParserImpl.ReadObject: IAsn1Convertible;
  4686. var
  4687. obj: IAsn1Encodable;
  4688. Sequence: IAsn1Sequence;
  4689. asn1Set: IAsn1Set;
  4690. begin
  4691. if (Findex = Fmax) then
  4692. begin
  4693. result := Nil;
  4694. Exit;
  4695. end;
  4696. obj := Fouter[Findex];
  4697. System.Inc(Findex);
  4698. if (Supports(obj, IAsn1Sequence, Sequence)) then
  4699. begin
  4700. result := Sequence.parser;
  4701. Exit;
  4702. end;
  4703. if (Supports(obj, IAsn1Set, asn1Set)) then
  4704. begin
  4705. result := asn1Set.parser;
  4706. Exit;
  4707. end;
  4708. // NB: Asn1OctetString implements Asn1OctetStringParser directly
  4709. // if (obj is Asn1OctetString)
  4710. // return ((Asn1OctetString)obj).Parser;
  4711. result := obj;
  4712. end;
  4713. function TAsn1Sequence.TAsn1SequenceParserImpl.ToAsn1Object: IAsn1Object;
  4714. begin
  4715. result := Fouter;
  4716. end;
  4717. { TDerOctetString }
  4718. constructor TDerOctetString.Create(const Str: TCryptoLibByteArray);
  4719. begin
  4720. Inherited Create(Str);
  4721. end;
  4722. constructor TDerOctetString.Create(const obj: IAsn1Encodable);
  4723. begin
  4724. Inherited Create(obj);
  4725. end;
  4726. destructor TDerOctetString.Destroy;
  4727. begin
  4728. inherited Destroy;
  4729. end;
  4730. procedure TDerOctetString.Encode(const derOut: TStream);
  4731. begin
  4732. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.OctetString, Str);
  4733. end;
  4734. class procedure TDerOctetString.Encode(const derOut: TDerOutputStream;
  4735. const bytes: TCryptoLibByteArray; offset, length: Int32);
  4736. begin
  4737. derOut.WriteEncoded(TAsn1Tags.OctetString, bytes, offset, length);
  4738. end;
  4739. { TBerOctetString }
  4740. constructor TBerOctetString.Create(const octets: TList<IDerOctetString>);
  4741. begin
  4742. Inherited Create(ToBytes(octets));
  4743. Focts := octets;
  4744. end;
  4745. constructor TBerOctetString.Create(const Str: TCryptoLibByteArray);
  4746. begin
  4747. Inherited Create(Str);
  4748. end;
  4749. constructor TBerOctetString.Create(const obj: IAsn1Encodable);
  4750. begin
  4751. Inherited Create(obj.ToAsn1Object());
  4752. end;
  4753. destructor TBerOctetString.Destroy;
  4754. begin
  4755. Focts.Free;
  4756. inherited Destroy;
  4757. end;
  4758. constructor TBerOctetString.Create(const obj: IAsn1Object);
  4759. begin
  4760. Inherited Create(obj);
  4761. end;
  4762. procedure TBerOctetString.Encode(const derOut: TStream);
  4763. var
  4764. oct: IDerOctetString;
  4765. LListIDerOctetString: TCryptoLibGenericArray<IDerOctetString>;
  4766. begin
  4767. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  4768. begin
  4769. (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Constructed or
  4770. TAsn1Tags.OctetString);
  4771. (derOut as TDerOutputStream).WriteByte($80);
  4772. //
  4773. // write out the octet array
  4774. //
  4775. LListIDerOctetString := Self.GetEnumerable;
  4776. for oct in LListIDerOctetString do
  4777. begin
  4778. (derOut as TDerOutputStream).WriteObject(oct);
  4779. end;
  4780. (derOut as TDerOutputStream).WriteByte($00);
  4781. (derOut as TDerOutputStream).WriteByte($00);
  4782. end
  4783. else
  4784. begin
  4785. (Inherited Encode(derOut));
  4786. end;
  4787. end;
  4788. class function TBerOctetString.FromSequence(const seq: IAsn1Sequence)
  4789. : IBerOctetString;
  4790. var
  4791. v: TList<IDerOctetString>;
  4792. obj: IAsn1Encodable;
  4793. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  4794. begin
  4795. v := TList<IDerOctetString>.Create();
  4796. LListAsn1Encodable := seq.GetEnumerable;
  4797. for obj in LListAsn1Encodable do
  4798. begin
  4799. v.Add(obj as IDerOctetString);
  4800. end;
  4801. result := TBerOctetString.Create(v);
  4802. end;
  4803. function TBerOctetString.GenerateOcts: TList<IDerOctetString>;
  4804. var
  4805. I, endPoint: Int32;
  4806. nStr: TCryptoLibByteArray;
  4807. begin
  4808. result := TList<IDerOctetString>.Create();
  4809. I := 0;
  4810. while I < System.length(Str) do
  4811. begin
  4812. endPoint := Min(System.length(Str), I + MaxLength);
  4813. System.SetLength(nStr, endPoint - I);
  4814. System.Move(Str[I], nStr[0], System.length(nStr) * System.SizeOf(Byte));
  4815. result.Add(TDerOctetString.Create(nStr) as IDerOctetString);
  4816. System.Inc(I, MaxLength);
  4817. end;
  4818. end;
  4819. function TBerOctetString.GetEnumerable: TCryptoLibGenericArray<IDerOctetString>;
  4820. var
  4821. LList: TList<IDerOctetString>;
  4822. begin
  4823. if (Focts = Nil) then
  4824. begin
  4825. LList := GenerateOcts();
  4826. try
  4827. result := LList.ToArray;
  4828. Exit;
  4829. finally
  4830. LList.Free;
  4831. end;
  4832. end;
  4833. result := Focts.ToArray;
  4834. end;
  4835. function TBerOctetString.GetOctets: TCryptoLibByteArray;
  4836. begin
  4837. result := Str;
  4838. end;
  4839. class function TBerOctetString.ToBytes(octs: TList<IDerOctetString>)
  4840. : TCryptoLibByteArray;
  4841. var
  4842. bOut: TMemoryStream;
  4843. o: IDerOctetString;
  4844. octets: TCryptoLibByteArray;
  4845. begin
  4846. bOut := TMemoryStream.Create();
  4847. try
  4848. for o in octs do
  4849. begin
  4850. octets := o.GetOctets();
  4851. bOut.Write(octets[0], System.length(octets));
  4852. end;
  4853. System.SetLength(result, bOut.Size);
  4854. bOut.Position := 0;
  4855. bOut.Read(result[0], bOut.Size);
  4856. finally
  4857. bOut.Free;
  4858. end;
  4859. end;
  4860. { TDerNull }
  4861. function TDerNull.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  4862. begin
  4863. result := Supports(asn1Object, IDerNull);
  4864. end;
  4865. function TDerNull.Asn1GetHashCode: Int32;
  4866. begin
  4867. result := -1;
  4868. end;
  4869. {$IFNDEF _FIXINSIGHT_}
  4870. constructor TDerNull.Create(dummy: Int32);
  4871. begin
  4872. Inherited Create();
  4873. end;
  4874. {$ENDIF}
  4875. procedure TDerNull.Encode(const derOut: TStream);
  4876. begin
  4877. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Null, ZeroBytes);
  4878. end;
  4879. class function TDerNull.GetInstance: IDerNull;
  4880. begin
  4881. result := TDerNull.Create(0);
  4882. end;
  4883. { TDerSequence }
  4884. class function TDerSequence.GetEmpty: IDerSequence;
  4885. begin
  4886. result := TDerSequence.Create();
  4887. end;
  4888. constructor TDerSequence.Create(const element: IAsn1Encodable);
  4889. begin
  4890. Inherited Create(element);
  4891. end;
  4892. constructor TDerSequence.Create;
  4893. begin
  4894. Inherited Create();
  4895. end;
  4896. constructor TDerSequence.Create(const elementVector: IAsn1EncodableVector);
  4897. begin
  4898. Inherited Create(elementVector);
  4899. end;
  4900. constructor TDerSequence.Create(const elements: array of IAsn1Encodable);
  4901. begin
  4902. Inherited Create(elements);
  4903. end;
  4904. destructor TDerSequence.Destroy;
  4905. begin
  4906. inherited Destroy;
  4907. end;
  4908. procedure TDerSequence.Encode(const derOut: TStream);
  4909. var
  4910. bOut: TMemoryStream;
  4911. dOut: TDerOutputStream;
  4912. obj: IAsn1Encodable;
  4913. bytes: TCryptoLibByteArray;
  4914. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  4915. begin
  4916. // TODO Intermediate buffer could be avoided if we could calculate expected length
  4917. bOut := TMemoryStream.Create();
  4918. dOut := TDerOutputStream.Create(bOut);
  4919. try
  4920. LListAsn1Encodable := Self.GetEnumerable;
  4921. for obj in LListAsn1Encodable do
  4922. begin
  4923. dOut.WriteObject(obj);
  4924. end;
  4925. System.SetLength(bytes, bOut.Size);
  4926. bOut.Position := 0;
  4927. bOut.Read(bytes[0], bOut.Size);
  4928. finally
  4929. bOut.Free;
  4930. dOut.Free;
  4931. end;
  4932. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Sequence or
  4933. TAsn1Tags.Constructed, bytes);
  4934. end;
  4935. class function TDerSequence.FromVector(const elementVector
  4936. : IAsn1EncodableVector): IDerSequence;
  4937. begin
  4938. if elementVector.count < 1 then
  4939. begin
  4940. result := Empty;
  4941. end
  4942. else
  4943. begin
  4944. result := TDerSequence.Create(elementVector);
  4945. end;
  4946. end;
  4947. { TBerSequence }
  4948. class function TBerSequence.GetEmpty: IBerSequence;
  4949. begin
  4950. result := TBerSequence.Create();
  4951. end;
  4952. constructor TBerSequence.Create(const element: IAsn1Encodable);
  4953. begin
  4954. Inherited Create(element);
  4955. end;
  4956. constructor TBerSequence.Create;
  4957. begin
  4958. Inherited Create();
  4959. end;
  4960. constructor TBerSequence.Create(const elementVector: IAsn1EncodableVector);
  4961. begin
  4962. Inherited Create(elementVector);
  4963. end;
  4964. destructor TBerSequence.Destroy;
  4965. begin
  4966. inherited Destroy;
  4967. end;
  4968. constructor TBerSequence.Create(const elements: array of IAsn1Encodable);
  4969. begin
  4970. Inherited Create(elements);
  4971. end;
  4972. procedure TBerSequence.Encode(const derOut: TStream);
  4973. var
  4974. o: IAsn1Encodable;
  4975. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  4976. begin
  4977. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  4978. begin
  4979. (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Sequence or
  4980. TAsn1Tags.Constructed);
  4981. (derOut as TDerOutputStream).WriteByte($80);
  4982. LListAsn1Encodable := Self.GetEnumerable;
  4983. for o in LListAsn1Encodable do
  4984. begin
  4985. (derOut as TDerOutputStream).WriteObject(o);
  4986. end;
  4987. (derOut as TDerOutputStream).WriteByte($00);
  4988. (derOut as TDerOutputStream).WriteByte($00);
  4989. end
  4990. else
  4991. begin
  4992. (Inherited Encode(derOut));
  4993. end;
  4994. end;
  4995. class function TBerSequence.FromVector(const elementVector
  4996. : IAsn1EncodableVector): IBerSequence;
  4997. begin
  4998. if elementVector.count < 1 then
  4999. begin
  5000. result := Empty;
  5001. end
  5002. else
  5003. begin
  5004. result := TBerSequence.Create(elementVector);
  5005. end;
  5006. end;
  5007. { TAsn1TaggedObject }
  5008. function TAsn1TaggedObject.GetObject: IAsn1Object;
  5009. begin
  5010. if (Fobj <> Nil) then
  5011. begin
  5012. result := Fobj.ToAsn1Object();
  5013. Exit;
  5014. end;
  5015. result := Nil;
  5016. end;
  5017. function TAsn1TaggedObject.GetTagNo: Int32;
  5018. begin
  5019. result := FtagNo;
  5020. end;
  5021. function TAsn1TaggedObject.Getexplicitly: Boolean;
  5022. begin
  5023. result := Fexplicitly;
  5024. end;
  5025. function TAsn1TaggedObject.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  5026. var
  5027. other: IAsn1TaggedObject;
  5028. begin
  5029. if (not Supports(asn1Object, IAsn1TaggedObject, other)) then
  5030. begin
  5031. result := False;
  5032. Exit;
  5033. end;
  5034. result := ((tagNo = other.tagNo) and
  5035. // TODO Should this be part of equality?
  5036. (explicitly = other.explicitly)) and
  5037. (GetObject().Equals(other.GetObject()));
  5038. end;
  5039. function TAsn1TaggedObject.Asn1GetHashCode: Int32;
  5040. var
  5041. code: Int32;
  5042. begin
  5043. code := Abs(tagNo);
  5044. // TODO: actually this is wrong - the problem is that a re-encoded
  5045. // object may end up with a different hashCode due to implicit
  5046. // tagging. As implicit tagging is ambiguous if a sequence is involved
  5047. // it seems the only correct method for both equals and hashCode is to
  5048. // compare the encodings...
  5049. // code := code xor explicitly.GetHashCode();
  5050. if (Fobj <> Nil) then
  5051. begin
  5052. code := code xor Fobj.GetHashCode();
  5053. end;
  5054. result := code;
  5055. end;
  5056. constructor TAsn1TaggedObject.Create(tagNo: Int32; const obj: IAsn1Encodable);
  5057. begin
  5058. Inherited Create();
  5059. Fexplicitly := True;
  5060. FtagNo := tagNo;
  5061. Fobj := obj;
  5062. end;
  5063. constructor TAsn1TaggedObject.Create(explicitly: Boolean; tagNo: Int32;
  5064. const obj: IAsn1Encodable);
  5065. begin
  5066. Inherited Create();
  5067. // IAsn1Choice marker interface 'insists' on explicit tagging
  5068. Fexplicitly := explicitly or (Supports(obj, IAsn1Choice));
  5069. FtagNo := tagNo;
  5070. Fobj := obj;
  5071. end;
  5072. class function TAsn1TaggedObject.GetInstance(obj: TObject): IAsn1TaggedObject;
  5073. begin
  5074. if ((obj = Nil) or (obj is TAsn1TaggedObject)) then
  5075. begin
  5076. result := obj as TAsn1TaggedObject;
  5077. Exit;
  5078. end;
  5079. raise EArgumentCryptoLibException.CreateResFmt(@SUnknownObject,
  5080. [obj.ClassName]);
  5081. end;
  5082. function TAsn1TaggedObject.Getobj: IAsn1Encodable;
  5083. begin
  5084. result := Fobj;
  5085. end;
  5086. class function TAsn1TaggedObject.GetInstance(const obj: IAsn1TaggedObject;
  5087. explicitly: Boolean): IAsn1TaggedObject;
  5088. begin
  5089. if (explicitly) then
  5090. begin
  5091. result := GetInstance(obj.GetObject() as TAsn1Object);
  5092. Exit;
  5093. end;
  5094. raise EArgumentCryptoLibException.CreateRes(@SImplicitObject);
  5095. end;
  5096. function TAsn1TaggedObject.GetObjectParser(tag: Int32; isExplicit: Boolean)
  5097. : IAsn1Convertible;
  5098. begin
  5099. case tag of
  5100. TAsn1Tags.&Set:
  5101. begin
  5102. result := TAsn1Set.GetInstance(Self as IAsn1TaggedObject,
  5103. isExplicit).parser;
  5104. Exit;
  5105. end;
  5106. TAsn1Tags.Sequence:
  5107. begin
  5108. result := TAsn1Sequence.GetInstance(Self as IAsn1TaggedObject,
  5109. isExplicit).parser;
  5110. Exit;
  5111. end;
  5112. TAsn1Tags.OctetString:
  5113. begin
  5114. result := TAsn1OctetString.GetInstance(Self as IAsn1TaggedObject,
  5115. isExplicit).parser;
  5116. Exit;
  5117. end;
  5118. end;
  5119. if (isExplicit) then
  5120. begin
  5121. result := GetObject();
  5122. Exit;
  5123. end;
  5124. raise ENotImplementedCryptoLibException.CreateResFmt(@SImplicitTag, [tag]);
  5125. end;
  5126. class function TAsn1TaggedObject.IsConstructed(isExplicit: Boolean;
  5127. const obj: IAsn1Object): Boolean;
  5128. var
  5129. Tagged: IAsn1TaggedObject;
  5130. begin
  5131. if ((isExplicit) or (Supports(obj, IAsn1Sequence)) or
  5132. (Supports(obj, IAsn1Set))) then
  5133. begin
  5134. result := True;
  5135. Exit;
  5136. end;
  5137. if (not Supports(obj, IAsn1TaggedObject, Tagged)) then
  5138. begin
  5139. result := False;
  5140. Exit;
  5141. end;
  5142. result := IsConstructed(Tagged.isExplicit(), Tagged.GetObject());
  5143. end;
  5144. function TAsn1TaggedObject.IsEmpty: Boolean;
  5145. begin
  5146. result := False; // empty;
  5147. end;
  5148. function TAsn1TaggedObject.isExplicit: Boolean;
  5149. begin
  5150. result := Fexplicitly;
  5151. end;
  5152. function TAsn1TaggedObject.ToString: String;
  5153. begin
  5154. result := '[' + IntToStr(tagNo) + ']' + (Fobj as TAsn1Encodable).ClassName;
  5155. end;
  5156. { TAsn1Set }
  5157. function TAsn1Set.GetDerEncoded(const obj: IAsn1Encodable): TCryptoLibByteArray;
  5158. begin
  5159. try
  5160. result := obj.GetEncoded(Der);
  5161. except
  5162. on e: EIOCryptoLibException do
  5163. begin
  5164. raise EInvalidArgumentCryptoLibException.CreateRes(@SObjectEncodeError);
  5165. end;
  5166. end;
  5167. end;
  5168. function TAsn1Set.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  5169. var
  5170. that: IAsn1Set;
  5171. o1, o2: IAsn1Object;
  5172. idx, LCount: Int32;
  5173. begin
  5174. if (not Supports(asn1Object, IAsn1Set, that)) then
  5175. begin
  5176. result := False;
  5177. Exit;
  5178. end;
  5179. LCount := count;
  5180. if (that.count <> LCount) then
  5181. begin
  5182. result := False;
  5183. Exit;
  5184. end;
  5185. for idx := 0 to System.Pred(LCount) do
  5186. begin
  5187. o1 := FElements[idx].ToAsn1Object();
  5188. o2 := that.elements[idx].ToAsn1Object();
  5189. if ((o1 <> o2) and (not o1.CallAsn1Equals(o2))) then
  5190. begin
  5191. result := False;
  5192. Exit;
  5193. end;
  5194. end;
  5195. result := True;
  5196. end;
  5197. function TAsn1Set.Asn1GetHashCode: Int32;
  5198. var
  5199. hc, I: Int32;
  5200. begin
  5201. I := System.length(FElements);
  5202. hc := I + 1;
  5203. System.Dec(I);
  5204. while (I >= 0) do
  5205. begin
  5206. hc := hc * 257;
  5207. hc := hc xor FElements[I].ToAsn1Object().CallAsn1GetHashCode();
  5208. System.Dec(I);
  5209. end;
  5210. result := hc;
  5211. end;
  5212. constructor TAsn1Set.Create();
  5213. begin
  5214. Inherited Create();
  5215. FElements := TAsn1EncodableVector.EmptyElements;
  5216. end;
  5217. constructor TAsn1Set.Create(const element: IAsn1Encodable);
  5218. begin
  5219. Inherited Create();
  5220. if (element = Nil) then
  5221. begin
  5222. raise EArgumentNilCryptoLibException.CreateRes(@SElementNil);
  5223. end;
  5224. FElements := TCryptoLibGenericArray<IAsn1Encodable>.Create(element);
  5225. end;
  5226. constructor TAsn1Set.Create(const elementVector: IAsn1EncodableVector);
  5227. begin
  5228. Inherited Create();
  5229. if (elementVector = Nil) then
  5230. begin
  5231. raise EArgumentNilCryptoLibException.CreateRes(@SElementVectorNil);
  5232. end;
  5233. FElements := elementVector.TakeElements();
  5234. end;
  5235. constructor TAsn1Set.Create(const elements: array of IAsn1Encodable);
  5236. var
  5237. LElementsCopy: TCryptoLibGenericArray<IAsn1Encodable>;
  5238. begin
  5239. Inherited Create();
  5240. LElementsCopy := OpenArrayToDynamicArray(elements);
  5241. if (TAsn1Encodable.IsNullOrContainsNull(LElementsCopy)) then
  5242. begin
  5243. raise ENullReferenceCryptoLibException.CreateRes(@SElementsNil);
  5244. end;
  5245. FElements := TAsn1EncodableVector.CloneElements(LElementsCopy);
  5246. end;
  5247. destructor TAsn1Set.Destroy;
  5248. begin
  5249. inherited Destroy;
  5250. end;
  5251. function TAsn1Set.GetCount: Int32;
  5252. begin
  5253. result := System.length(FElements);
  5254. end;
  5255. function TAsn1Set.GetElements: TCryptoLibGenericArray<IAsn1Encodable>;
  5256. begin
  5257. result := FElements;
  5258. end;
  5259. function TAsn1Set.GetEnumerable: TCryptoLibGenericArray<IAsn1Encodable>;
  5260. begin
  5261. result := FElements;
  5262. end;
  5263. class function TAsn1Set.GetInstance(const obj: TCryptoLibByteArray): IAsn1Set;
  5264. begin
  5265. try
  5266. result := TAsn1Set.GetInstance(FromByteArray(obj) as TAsn1Object);
  5267. except
  5268. on e: EIOCryptoLibException do
  5269. begin
  5270. raise EArgumentCryptoLibException.CreateResFmt(@SInvalidSequence,
  5271. [e.Message]);
  5272. end;
  5273. end;
  5274. end;
  5275. class function TAsn1Set.GetInstance(const obj: IAsn1TaggedObject;
  5276. explicitly: Boolean): IAsn1Set;
  5277. var
  5278. inner: IAsn1Object;
  5279. asn1Set: IAsn1Set;
  5280. asn1Sequence: IAsn1Sequence;
  5281. v: IAsn1EncodableVector;
  5282. ae: IAsn1Encodable;
  5283. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  5284. begin
  5285. inner := obj.GetObject();
  5286. if (explicitly) then
  5287. begin
  5288. if (not(obj.isExplicit())) then
  5289. raise EArgumentCryptoLibException.CreateRes(@SInvalidObject);
  5290. result := inner as IAsn1Set;
  5291. Exit;
  5292. end;
  5293. //
  5294. // constructed object which appears to be explicitly tagged
  5295. // when it should be implicit means we have to add the
  5296. // surrounding sequence.
  5297. //
  5298. if (obj.isExplicit()) then
  5299. begin
  5300. result := TDerSet.Create(inner);
  5301. Exit;
  5302. end;
  5303. if (Supports(inner, IAsn1Set, asn1Set)) then
  5304. begin
  5305. result := asn1Set;
  5306. Exit;
  5307. end;
  5308. //
  5309. // in this case the parser returns a sequence, convert it
  5310. // into a set.
  5311. //
  5312. if (Supports(inner, IAsn1Sequence, asn1Sequence)) then
  5313. begin
  5314. v := TAsn1EncodableVector.Create();
  5315. LListAsn1Encodable := asn1Sequence.GetEnumerable;
  5316. for ae in LListAsn1Encodable do
  5317. begin
  5318. v.Add(ae);
  5319. end;
  5320. // TODO Should be able to construct set directly from sequence?
  5321. result := TDerSet.Create(v, False);
  5322. Exit;
  5323. end;
  5324. raise EArgumentCryptoLibException.CreateResFmt(@SUnknownObject,
  5325. [(obj as TAsn1TaggedObject).ClassName]);
  5326. end;
  5327. class function TAsn1Set.GetInstance(const obj: TObject): IAsn1Set;
  5328. var
  5329. primitive: IAsn1Object;
  5330. asn1Set: IAsn1Set;
  5331. res: IAsn1SetParser;
  5332. begin
  5333. if ((obj = Nil) or (obj is TAsn1Set)) then
  5334. begin
  5335. result := obj as TAsn1Set;
  5336. Exit;
  5337. end;
  5338. if (Supports(obj, IAsn1SetParser, res)) then
  5339. begin
  5340. result := TAsn1Set.GetInstance(res.ToAsn1Object() as TAsn1Object);
  5341. Exit;
  5342. end;
  5343. if (obj is TAsn1Encodable) then
  5344. begin
  5345. primitive := (obj as TAsn1Encodable).ToAsn1Object();
  5346. if (Supports(primitive, IAsn1Set, asn1Set)) then
  5347. begin
  5348. result := asn1Set;
  5349. Exit;
  5350. end;
  5351. end;
  5352. raise EArgumentCryptoLibException.CreateResFmt(@SUnknownObject,
  5353. [obj.ClassName]);
  5354. end;
  5355. function TAsn1Set.GetParser: IAsn1SetParser;
  5356. begin
  5357. result := TAsn1SetParserImpl.Create(Self as IAsn1Set);
  5358. end;
  5359. function TAsn1Set.GetSelf(Index: Int32): IAsn1Encodable;
  5360. begin
  5361. result := FElements[Index];
  5362. end;
  5363. class function TAsn1Set.LessThanOrEqual(const a,
  5364. b: TCryptoLibByteArray): Boolean;
  5365. var
  5366. last, I, a0, b0: Int32;
  5367. begin
  5368. {$IFDEF DEBUG}
  5369. System.Assert((System.length(a) >= 2) and (System.length(b) >= 2));
  5370. {$ENDIF DEBUG}
  5371. (*
  5372. * NOTE: Set elements in DER encodings are ordered first according to their tags (class and
  5373. * number); the CONSTRUCTED bit is not part of the tag.
  5374. *
  5375. * For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
  5376. * either all be in constructed form or all in primitive form, according to that tag. The
  5377. * elements are effectively ordered according to their content octets.
  5378. *
  5379. * For SET, the elements will have distinct tags, and each will be in constructed or
  5380. * primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
  5381. * ordering inversions.
  5382. *)
  5383. a0 := a[0] and (not TAsn1Tags.Constructed);
  5384. b0 := b[0] and (not TAsn1Tags.Constructed);
  5385. if (a0 <> b0) then
  5386. begin
  5387. result := a0 < b0;
  5388. Exit;
  5389. end;
  5390. last := Math.Min(System.length(a), System.length(b)) - 1;
  5391. I := 1;
  5392. while I < last do
  5393. begin
  5394. if (a[I] <> b[I]) then
  5395. begin
  5396. result := (a[I]) < (b[I]);
  5397. Exit;
  5398. end;
  5399. System.Inc(I);
  5400. end;
  5401. result := (a[last]) <= (b[last]);
  5402. end;
  5403. procedure TAsn1Set.Sort;
  5404. var
  5405. count, I, j: Int32;
  5406. eh, ei, et, e2, e1: IAsn1Encodable;
  5407. bh, bi, bt, b2, b1: TCryptoLibByteArray;
  5408. begin
  5409. count := System.length(FElements);
  5410. if (count < 2) then
  5411. begin
  5412. Exit;
  5413. end;
  5414. eh := FElements[0];
  5415. ei := FElements[1];
  5416. bh := GetDerEncoded(eh);
  5417. bi := GetDerEncoded(ei);
  5418. if (LessThanOrEqual(bi, bh)) then
  5419. begin
  5420. et := ei;
  5421. ei := eh;
  5422. eh := et;
  5423. bt := bi;
  5424. bi := bh;
  5425. bh := bt;
  5426. end;
  5427. for I := 2 to System.Pred(count) do
  5428. begin
  5429. e2 := FElements[I];
  5430. b2 := GetDerEncoded(e2);
  5431. if (LessThanOrEqual(bi, b2)) then
  5432. begin
  5433. FElements[I - 2] := eh;
  5434. eh := ei;
  5435. bh := bi;
  5436. ei := e2;
  5437. bi := b2;
  5438. continue;
  5439. end;
  5440. if (LessThanOrEqual(bh, b2)) then
  5441. begin
  5442. FElements[I - 2] := eh;
  5443. eh := e2;
  5444. bh := b2;
  5445. continue;
  5446. end;
  5447. j := I - 1;
  5448. System.Dec(j);
  5449. while (j > 0) do
  5450. begin
  5451. e1 := FElements[j - 1];
  5452. b1 := GetDerEncoded(e1);
  5453. if (LessThanOrEqual(b1, b2)) then
  5454. begin
  5455. break;
  5456. end;
  5457. FElements[j] := e1;
  5458. System.Dec(j);
  5459. end;
  5460. FElements[j] := e2;
  5461. end;
  5462. FElements[count - 2] := eh;
  5463. FElements[count - 1] := ei;
  5464. end;
  5465. function TAsn1Set.ToArray: TCryptoLibGenericArray<IAsn1Encodable>;
  5466. begin
  5467. result := TAsn1EncodableVector.CloneElements(FElements);
  5468. end;
  5469. function TAsn1Set.ToString: String;
  5470. begin
  5471. result := TCollectionUtilities.ToStructuredString(FElements);
  5472. end;
  5473. { TAsn1Set.TAsn1SetParserImpl }
  5474. constructor TAsn1Set.TAsn1SetParserImpl.Create(const outer: IAsn1Set);
  5475. begin
  5476. Inherited Create();
  5477. Fouter := outer;
  5478. Fmax := outer.count;
  5479. end;
  5480. function TAsn1Set.TAsn1SetParserImpl.ReadObject: IAsn1Convertible;
  5481. var
  5482. obj: IAsn1Encodable;
  5483. Sequence: IAsn1Sequence;
  5484. asn1Set: IAsn1Set;
  5485. begin
  5486. if (Findex = Fmax) then
  5487. begin
  5488. result := Nil;
  5489. Exit;
  5490. end;
  5491. obj := Fouter[Findex];
  5492. System.Inc(Findex);
  5493. if (Supports(obj, IAsn1Sequence, Sequence)) then
  5494. begin
  5495. result := Sequence.parser;
  5496. Exit;
  5497. end;
  5498. if (Supports(obj, IAsn1Set, asn1Set)) then
  5499. begin
  5500. result := asn1Set.parser;
  5501. Exit;
  5502. end;
  5503. // NB: Asn1OctetString implements Asn1OctetStringParser directly
  5504. // if (obj is Asn1OctetString)
  5505. // return ((Asn1OctetString)obj).Parser;
  5506. result := obj;
  5507. end;
  5508. function TAsn1Set.TAsn1SetParserImpl.ToAsn1Object: IAsn1Object;
  5509. begin
  5510. result := Fouter;
  5511. end;
  5512. { TDerSet }
  5513. class function TDerSet.GetEmpty: IDerSet;
  5514. begin
  5515. result := TDerSet.Create();
  5516. end;
  5517. constructor TDerSet.Create(const elements: array of IAsn1Encodable);
  5518. begin
  5519. Inherited Create(elements);
  5520. Sort();
  5521. end;
  5522. constructor TDerSet.Create;
  5523. begin
  5524. Inherited Create();
  5525. end;
  5526. constructor TDerSet.Create(const element: IAsn1Encodable);
  5527. begin
  5528. Inherited Create(element);
  5529. end;
  5530. constructor TDerSet.Create(const elementVector: IAsn1EncodableVector);
  5531. begin
  5532. Create(elementVector, True);
  5533. end;
  5534. constructor TDerSet.Create(const elementVector: IAsn1EncodableVector;
  5535. needsSorting: Boolean);
  5536. begin
  5537. Inherited Create(elementVector);
  5538. if (needsSorting) then
  5539. begin
  5540. Sort();
  5541. end;
  5542. end;
  5543. destructor TDerSet.Destroy;
  5544. begin
  5545. inherited Destroy;
  5546. end;
  5547. procedure TDerSet.Encode(const derOut: TStream);
  5548. var
  5549. bOut: TMemoryStream;
  5550. dOut: TDerOutputStream;
  5551. obj: IAsn1Encodable;
  5552. bytes: TCryptoLibByteArray;
  5553. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  5554. begin
  5555. // TODO Intermediate buffer could be avoided if we could calculate expected length
  5556. bOut := TMemoryStream.Create();
  5557. dOut := TDerOutputStream.Create(bOut);
  5558. try
  5559. LListAsn1Encodable := Self.GetEnumerable;
  5560. for obj in LListAsn1Encodable do
  5561. begin
  5562. dOut.WriteObject(obj);
  5563. end;
  5564. System.SetLength(bytes, bOut.Size);
  5565. bOut.Position := 0;
  5566. bOut.Read(bytes[0], bOut.Size);
  5567. finally
  5568. bOut.Free;
  5569. dOut.Free;
  5570. end;
  5571. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.&Set or
  5572. TAsn1Tags.Constructed, bytes);
  5573. end;
  5574. class function TDerSet.FromVector(const elementVector: IAsn1EncodableVector;
  5575. needsSorting: Boolean): IDerSet;
  5576. begin
  5577. if elementVector.count < 1 then
  5578. begin
  5579. result := Empty;
  5580. end
  5581. else
  5582. begin
  5583. result := TDerSet.Create(elementVector, needsSorting);
  5584. end;
  5585. end;
  5586. class function TDerSet.FromVector(const elementVector
  5587. : IAsn1EncodableVector): IDerSet;
  5588. begin
  5589. if elementVector.count < 1 then
  5590. begin
  5591. result := Empty;
  5592. end
  5593. else
  5594. begin
  5595. result := TDerSet.Create(elementVector);
  5596. end;
  5597. end;
  5598. { TAsn1StreamParser }
  5599. procedure TAsn1StreamParser.Set00Check(enabled: Boolean);
  5600. var
  5601. indefiniteLengthInputStream: TIndefiniteLengthInputStream;
  5602. begin
  5603. if (F_in is TIndefiniteLengthInputStream) then
  5604. begin
  5605. indefiniteLengthInputStream := F_in as TIndefiniteLengthInputStream;
  5606. indefiniteLengthInputStream.SetEofOn00(enabled);
  5607. end;
  5608. end;
  5609. constructor TAsn1StreamParser.Create(const inStream: TStream);
  5610. begin
  5611. Create(inStream, TAsn1InputStream.FindLimit(inStream));
  5612. end;
  5613. constructor TAsn1StreamParser.Create(const inStream: TStream; limit: Int32);
  5614. begin
  5615. Inherited Create();
  5616. F_in := inStream;
  5617. F_limit := limit;
  5618. System.SetLength(FtmpBuffers, 16);
  5619. end;
  5620. constructor TAsn1StreamParser.Create(const encoding: TCryptoLibByteArray);
  5621. begin
  5622. // used TBytesStream here for one pass creation and population with byte array :)
  5623. Create(TBytesStream.Create(encoding), System.length(encoding));
  5624. end;
  5625. destructor TAsn1StreamParser.Destroy;
  5626. begin
  5627. F_in.Free;
  5628. inherited Destroy;
  5629. end;
  5630. function TAsn1StreamParser.ReadVector: IAsn1EncodableVector;
  5631. var
  5632. obj: IAsn1Convertible;
  5633. begin
  5634. obj := ReadObject();
  5635. if obj = Nil then
  5636. begin
  5637. result := TAsn1EncodableVector.Create(0);
  5638. Exit;
  5639. end;
  5640. result := TAsn1EncodableVector.Create();
  5641. repeat
  5642. result.Add([obj.ToAsn1Object()]);
  5643. obj := ReadObject();
  5644. until not(obj <> Nil);
  5645. end;
  5646. function TAsn1StreamParser.ReadImplicit(Constructed: Boolean; tag: Int32)
  5647. : IAsn1Convertible;
  5648. begin
  5649. if (F_in is TIndefiniteLengthInputStream) then
  5650. begin
  5651. if (not Constructed) then
  5652. begin
  5653. raise EIOCryptoLibException.CreateRes(@SIndefiniteLength);
  5654. end;
  5655. result := ReadIndef(tag);
  5656. Exit;
  5657. end;
  5658. if (Constructed) then
  5659. begin
  5660. case tag of
  5661. TAsn1Tags.&Set:
  5662. begin
  5663. result := TDerSetParser.Create(Self as IAsn1StreamParser);
  5664. Exit;
  5665. end;
  5666. TAsn1Tags.Sequence:
  5667. begin
  5668. result := TDerSequenceParser.Create(Self as IAsn1StreamParser);
  5669. Exit;
  5670. end;
  5671. TAsn1Tags.OctetString:
  5672. begin
  5673. result := TBerOctetStringParser.Create(Self as IAsn1StreamParser);
  5674. Exit;
  5675. end;
  5676. end;
  5677. end
  5678. else
  5679. begin
  5680. case tag of
  5681. TAsn1Tags.&Set:
  5682. begin
  5683. raise EAsn1CryptoLibException.CreateRes(@SUnConstructedEncoding);
  5684. end;
  5685. TAsn1Tags.Sequence:
  5686. begin
  5687. raise EAsn1CryptoLibException.CreateRes(@SUnConstructedEncoding2);
  5688. end;
  5689. TAsn1Tags.OctetString:
  5690. begin
  5691. result := TDerOctetStringParser.Create
  5692. (F_in as TDefiniteLengthInputStream);
  5693. Exit;
  5694. end;
  5695. end;
  5696. end;
  5697. raise EAsn1CryptoLibException.CreateRes(@SImplicitTagging);
  5698. end;
  5699. function TAsn1StreamParser.ReadIndef(tagValue: Int32): IAsn1Convertible;
  5700. begin
  5701. // Note: INDEF => CONSTRUCTED
  5702. // TODO There are other tags that may be constructed (e.g. BIT_STRING)
  5703. case tagValue of
  5704. TAsn1Tags.External:
  5705. begin
  5706. result := TDerExternalParser.Create(Self as IAsn1StreamParser);
  5707. Exit;
  5708. end;
  5709. TAsn1Tags.OctetString:
  5710. begin
  5711. result := TBerOctetStringParser.Create(Self as IAsn1StreamParser);
  5712. Exit;
  5713. end;
  5714. TAsn1Tags.Sequence:
  5715. begin
  5716. result := TBerSequenceParser.Create(Self as IAsn1StreamParser);
  5717. Exit;
  5718. end;
  5719. TAsn1Tags.&Set:
  5720. begin
  5721. result := TBerSetParser.Create(Self as IAsn1StreamParser);
  5722. Exit;
  5723. end;
  5724. else
  5725. begin
  5726. raise EAsn1CryptoLibException.CreateResFmt(@SUnknownObjectBER,
  5727. [tagValue]);
  5728. end;
  5729. end;
  5730. end;
  5731. function TAsn1StreamParser.ReadObject: IAsn1Convertible;
  5732. var
  5733. tag, tagNo, &length: Int32;
  5734. IsConstructed: Boolean;
  5735. indIn: TIndefiniteLengthInputStream;
  5736. sp: IAsn1StreamParser;
  5737. defIn: TDefiniteLengthInputStream;
  5738. begin
  5739. tag := TStreamSorter.ReadByte(F_in);
  5740. if (tag = -1) then
  5741. begin
  5742. result := Nil;
  5743. Exit;
  5744. end;
  5745. // turn off looking for "00" while we resolve the tag
  5746. Set00Check(False);
  5747. //
  5748. // calculate tag number
  5749. //
  5750. tagNo := TAsn1InputStream.ReadTagNumber(F_in, tag);
  5751. IsConstructed := (tag and TAsn1Tags.Constructed) <> 0;
  5752. //
  5753. // calculate length
  5754. //
  5755. length := TAsn1InputStream.ReadLength(F_in, F_limit);
  5756. if (length < 0) then // indefinite length method
  5757. begin
  5758. if (not IsConstructed) then
  5759. begin
  5760. raise EIOCryptoLibException.CreateRes(@SIndefiniteLength);
  5761. end;
  5762. indIn := TIndefiniteLengthInputStream.Create(F_in, F_limit);
  5763. sp := TAsn1StreamParser.Create(indIn, F_limit);
  5764. if ((tag and TAsn1Tags.Application) <> 0) then
  5765. begin
  5766. result := TBerApplicationSpecificParser.Create(tagNo, sp);
  5767. Exit;
  5768. end;
  5769. if ((tag and TAsn1Tags.Tagged) <> 0) then
  5770. begin
  5771. result := TBerTaggedObjectParser.Create(True, tagNo, sp);
  5772. Exit;
  5773. end;
  5774. result := sp.ReadIndef(tagNo);
  5775. Exit;
  5776. end;
  5777. defIn := TDefiniteLengthInputStream.Create(F_in, length);
  5778. if ((tag and TAsn1Tags.Application) <> 0) then
  5779. begin
  5780. try
  5781. result := TDerApplicationSpecific.Create(IsConstructed, tagNo,
  5782. defIn.ToArray());
  5783. Exit;
  5784. finally
  5785. defIn.Free;
  5786. end;
  5787. end;
  5788. if ((tag and TAsn1Tags.Tagged) <> 0) then
  5789. begin
  5790. result := TBerTaggedObjectParser.Create(IsConstructed, tagNo,
  5791. TAsn1StreamParser.Create(defIn) as IAsn1StreamParser);
  5792. Exit;
  5793. end;
  5794. if (IsConstructed) then
  5795. begin
  5796. // TODO There are other tags that may be constructed (e.g. BitString)
  5797. case tagNo of
  5798. TAsn1Tags.OctetString:
  5799. begin
  5800. //
  5801. // yes, people actually do this...
  5802. //
  5803. result := TBerOctetStringParser.Create(TAsn1StreamParser.Create(defIn)
  5804. as IAsn1StreamParser);
  5805. Exit;
  5806. end;
  5807. TAsn1Tags.Sequence:
  5808. begin
  5809. result := TDerSequenceParser.Create(TAsn1StreamParser.Create(defIn)
  5810. as IAsn1StreamParser);
  5811. Exit;
  5812. end;
  5813. TAsn1Tags.&Set:
  5814. begin
  5815. result := TDerSetParser.Create(TAsn1StreamParser.Create(defIn)
  5816. as IAsn1StreamParser);
  5817. Exit;
  5818. end;
  5819. TAsn1Tags.External:
  5820. begin
  5821. result := TDerExternalParser.Create(TAsn1StreamParser.Create(defIn)
  5822. as IAsn1StreamParser);
  5823. Exit;
  5824. end;
  5825. else
  5826. begin
  5827. defIn.Free; // free the stream incase an unsupported tag is encountered.
  5828. raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
  5829. end;
  5830. end;
  5831. end;
  5832. // Some primitive encodings can be handled by parsers too...
  5833. case tagNo of
  5834. TAsn1Tags.OctetString:
  5835. begin
  5836. result := TDerOctetStringParser.Create(defIn);
  5837. Exit;
  5838. end;
  5839. end;
  5840. try
  5841. try
  5842. result := TAsn1InputStream.CreatePrimitiveDerObject(tagNo, defIn,
  5843. FtmpBuffers);
  5844. Exit;
  5845. except
  5846. on e: EArgumentCryptoLibException do
  5847. begin
  5848. raise EAsn1CryptoLibException.CreateResFmt(@SCorruptedStream,
  5849. [e.Message]);
  5850. end;
  5851. end;
  5852. finally
  5853. defIn.Free;
  5854. end;
  5855. end;
  5856. function TAsn1StreamParser.ReadTaggedObject(Constructed: Boolean; tag: Int32)
  5857. : IAsn1Object;
  5858. var
  5859. defIn: TDefiniteLengthInputStream;
  5860. v: IAsn1EncodableVector;
  5861. begin
  5862. if (not Constructed) then
  5863. begin
  5864. // Note: !CONSTRUCTED => IMPLICIT
  5865. defIn := F_in as TDefiniteLengthInputStream;
  5866. result := TDerTaggedObject.Create(False, tag,
  5867. TDerOctetString.Create(defIn.ToArray()));
  5868. Exit;
  5869. end;
  5870. v := ReadVector();
  5871. if (F_in is TIndefiniteLengthInputStream) then
  5872. begin
  5873. if v.count = 1 then
  5874. begin
  5875. result := TBerTaggedObject.Create(True, tag, v[0]);
  5876. Exit;
  5877. end
  5878. else
  5879. begin
  5880. result := TBerTaggedObject.Create(False, tag, TBerSequence.FromVector(v));
  5881. Exit;
  5882. end;
  5883. end;
  5884. if v.count = 1 then
  5885. begin
  5886. result := TDerTaggedObject.Create(True, tag, v[0]);
  5887. Exit;
  5888. end
  5889. else
  5890. begin
  5891. result := TDerTaggedObject.Create(False, tag, TDerSequence.FromVector(v));
  5892. Exit;
  5893. end;
  5894. end;
  5895. { TDerSetParser }
  5896. constructor TDerSetParser.Create(const parser: IAsn1StreamParser);
  5897. begin
  5898. F_parser := parser;
  5899. end;
  5900. function TDerSetParser.ReadObject: IAsn1Convertible;
  5901. begin
  5902. result := F_parser.ReadObject();
  5903. end;
  5904. function TDerSetParser.ToAsn1Object: IAsn1Object;
  5905. begin
  5906. result := TDerSet.Create(F_parser.ReadVector(), False);
  5907. end;
  5908. { TDerSequenceParser }
  5909. constructor TDerSequenceParser.Create(const parser: IAsn1StreamParser);
  5910. begin
  5911. F_parser := parser;
  5912. end;
  5913. function TDerSequenceParser.ReadObject: IAsn1Convertible;
  5914. begin
  5915. result := F_parser.ReadObject();
  5916. end;
  5917. function TDerSequenceParser.ToAsn1Object: IAsn1Object;
  5918. begin
  5919. result := TDerSequence.Create(F_parser.ReadVector());
  5920. end;
  5921. { TDerApplicationSpecific }
  5922. function TDerApplicationSpecific.GetApplicationTag: Int32;
  5923. begin
  5924. result := Ftag;
  5925. end;
  5926. function TDerApplicationSpecific.GetContents: TCryptoLibByteArray;
  5927. begin
  5928. result := Foctets;
  5929. end;
  5930. function TDerApplicationSpecific.IsConstructed: Boolean;
  5931. begin
  5932. result := FisConstructed;
  5933. end;
  5934. function TDerApplicationSpecific.GetLengthOfHeader
  5935. (const data: TCryptoLibByteArray): Int32;
  5936. var
  5937. &length, Size: Int32;
  5938. begin
  5939. length := data[1]; // TODO: assumes 1 byte tag
  5940. if (length = $80) then
  5941. begin
  5942. result := 2; // indefinite-length encoding
  5943. Exit;
  5944. end;
  5945. if (length > 127) then
  5946. begin
  5947. Size := length and $7F;
  5948. // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
  5949. if (Size > 4) then
  5950. begin
  5951. raise EInvalidOperationCryptoLibException.CreateResFmt
  5952. (@SInvalidDerLength, [Size]);
  5953. end;
  5954. result := Size + 2;
  5955. Exit;
  5956. end;
  5957. result := 2;
  5958. end;
  5959. constructor TDerApplicationSpecific.Create(tag: Int32;
  5960. const obj: IAsn1Encodable);
  5961. begin
  5962. Create(True, tag, obj);
  5963. end;
  5964. constructor TDerApplicationSpecific.Create(tag: Int32;
  5965. const octets: TCryptoLibByteArray);
  5966. begin
  5967. Create(False, tag, octets);
  5968. end;
  5969. constructor TDerApplicationSpecific.Create(IsConstructed: Boolean; tag: Int32;
  5970. const octets: TCryptoLibByteArray);
  5971. begin
  5972. Inherited Create();
  5973. FisConstructed := IsConstructed;
  5974. Ftag := tag;
  5975. Foctets := octets;
  5976. end;
  5977. function TDerApplicationSpecific.Asn1Equals(const asn1Object
  5978. : IAsn1Object): Boolean;
  5979. var
  5980. other: IDerApplicationSpecific;
  5981. begin
  5982. if (not Supports(asn1Object, IDerApplicationSpecific, other)) then
  5983. begin
  5984. result := False;
  5985. Exit;
  5986. end;
  5987. result := (IsConstructed = other.IsConstructed) and
  5988. (ApplicationTag = other.ApplicationTag) and
  5989. TArrayUtils.AreEqual(GetContents, other.GetContents);
  5990. end;
  5991. function TDerApplicationSpecific.Asn1GetHashCode: Int32;
  5992. var
  5993. HashCode: Int32;
  5994. begin
  5995. case IsConstructed of
  5996. True:
  5997. HashCode := 1;
  5998. False:
  5999. HashCode := 0;
  6000. end;
  6001. result := HashCode xor Ftag xor TArrayUtils.GetArrayHashCode(Foctets);
  6002. end;
  6003. constructor TDerApplicationSpecific.Create(tagNo: Int32;
  6004. const vec: IAsn1EncodableVector);
  6005. var
  6006. bOut: TMemoryStream;
  6007. bs: TCryptoLibByteArray;
  6008. I: Int32;
  6009. val: IAsn1Encodable;
  6010. begin
  6011. Inherited Create();
  6012. Ftag := tagNo;
  6013. FisConstructed := True;
  6014. bOut := TMemoryStream.Create();
  6015. try
  6016. I := 0;
  6017. while I <> vec.count do
  6018. begin
  6019. try
  6020. val := vec[I];
  6021. bs := val.GetDerEncoded();
  6022. bOut.Write(bs[0], System.length(bs));
  6023. except
  6024. on e: EIOCryptoLibException do
  6025. begin
  6026. raise EInvalidOperationCryptoLibException.CreateResFmt
  6027. (@SMalformedObject, [e.Message]);
  6028. end;
  6029. end;
  6030. System.Inc(I);
  6031. end;
  6032. System.SetLength(Foctets, bOut.Size);
  6033. bOut.Position := 0;
  6034. bOut.Read(Foctets[0], bOut.Size);
  6035. finally
  6036. bOut.Free;
  6037. end;
  6038. end;
  6039. procedure TDerApplicationSpecific.Encode(const derOut: TStream);
  6040. var
  6041. classBits: Int32;
  6042. begin
  6043. classBits := TAsn1Tags.Application;
  6044. if (IsConstructed) then
  6045. begin
  6046. classBits := classBits or TAsn1Tags.Constructed;
  6047. end;
  6048. (derOut as TDerOutputStream).WriteEncoded(classBits, Ftag, Foctets);
  6049. end;
  6050. constructor TDerApplicationSpecific.Create(isExplicit: Boolean; tag: Int32;
  6051. const obj: IAsn1Encodable);
  6052. var
  6053. asn1Obj: IAsn1Object;
  6054. data, tmp: TCryptoLibByteArray;
  6055. lenBytes: Int32;
  6056. begin
  6057. Inherited Create();
  6058. asn1Obj := obj.ToAsn1Object();
  6059. data := asn1Obj.GetDerEncoded();
  6060. FisConstructed := TAsn1TaggedObject.IsConstructed(isExplicit, asn1Obj);
  6061. Ftag := tag;
  6062. if (isExplicit) then
  6063. begin
  6064. Foctets := data;
  6065. end
  6066. else
  6067. begin
  6068. lenBytes := GetLengthOfHeader(data);
  6069. System.SetLength(tmp, System.length(data) - lenBytes);
  6070. System.Move(data[lenBytes], tmp[0], System.length(tmp) *
  6071. System.SizeOf(Byte));
  6072. Foctets := tmp;
  6073. end;
  6074. end;
  6075. function TDerApplicationSpecific.GetObject: IAsn1Object;
  6076. begin
  6077. result := FromByteArray(GetContents());
  6078. end;
  6079. function TDerApplicationSpecific.GetObject(derTagNo: Int32): IAsn1Object;
  6080. var
  6081. orig, tmp: TCryptoLibByteArray;
  6082. begin
  6083. if (derTagNo >= $1F) then
  6084. begin
  6085. raise EIOCryptoLibException.CreateRes(@SUnSupportedTag);
  6086. end;
  6087. orig := GetEncoded();
  6088. tmp := ReplaceTagNumber(derTagNo, orig);
  6089. if ((orig[0] and TAsn1Tags.Constructed) <> 0) then
  6090. begin
  6091. tmp[0] := tmp[0] or TAsn1Tags.Constructed;
  6092. end;
  6093. result := FromByteArray(tmp);
  6094. end;
  6095. class function TDerApplicationSpecific.ReplaceTagNumber(newTag: Int32;
  6096. const input: TCryptoLibByteArray): TCryptoLibByteArray;
  6097. var
  6098. tagNo, Index, b, Remaining: Int32;
  6099. tmp: TCryptoLibByteArray;
  6100. begin
  6101. tagNo := input[0] and $1F;
  6102. index := 1;
  6103. //
  6104. // with tagged object tag number is bottom 5 bits, or stored at the start of the content
  6105. //
  6106. if (tagNo = $1F) then
  6107. begin
  6108. b := input[index];
  6109. System.Inc(index);
  6110. // X.690-0207 8.1.2.4.2
  6111. // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
  6112. if ((b and $7F) = 0) then // Note: -1 will pass
  6113. begin
  6114. raise EIOCryptoLibException.CreateRes(@SCorruptedStreamInvalidTag);
  6115. end;
  6116. while ((b and $80) <> 0) do
  6117. begin
  6118. b := input[index];
  6119. System.Inc(index);
  6120. end;
  6121. end;
  6122. Remaining := System.length(input) - index;
  6123. System.SetLength(tmp, 1 + Remaining);
  6124. tmp[0] := Byte(newTag);
  6125. System.Move(input[index], tmp[1], Remaining * System.SizeOf(Byte));
  6126. result := tmp;
  6127. end;
  6128. { TBerApplicationSpecific }
  6129. constructor TBerApplicationSpecific.Create(tagNo: Int32;
  6130. const vec: IAsn1EncodableVector);
  6131. begin
  6132. inherited Create(tagNo, vec);
  6133. end;
  6134. { TBerOctetStringParser }
  6135. constructor TBerOctetStringParser.Create(const parser: IAsn1StreamParser);
  6136. begin
  6137. Inherited Create();
  6138. F_parser := parser;
  6139. end;
  6140. function TBerOctetStringParser.GetOctetStream: TStream;
  6141. begin
  6142. result := TConstructedOctetStream.Create(F_parser);
  6143. end;
  6144. function TBerOctetStringParser.ToAsn1Object: IAsn1Object;
  6145. var
  6146. LStream: TStream;
  6147. begin
  6148. try
  6149. LStream := GetOctetStream();
  6150. try
  6151. result := TBerOctetString.Create(TStreamUtils.ReadAll(LStream));
  6152. finally
  6153. LStream.Free;
  6154. end;
  6155. except
  6156. on e: EIOCryptoLibException do
  6157. begin
  6158. raise EAsn1ParsingCryptoLibException.CreateResFmt(@SConvertError,
  6159. [e.Message]);
  6160. end;
  6161. end;
  6162. end;
  6163. { TBerApplicationSpecificParser }
  6164. constructor TBerApplicationSpecificParser.Create(tag: Int32;
  6165. const parser: IAsn1StreamParser);
  6166. begin
  6167. F_tag := tag;
  6168. F_parser := parser;
  6169. end;
  6170. function TBerApplicationSpecificParser.ReadObject: IAsn1Convertible;
  6171. begin
  6172. result := F_parser.ReadObject();
  6173. end;
  6174. function TBerApplicationSpecificParser.ToAsn1Object: IAsn1Object;
  6175. begin
  6176. result := TBerApplicationSpecific.Create(F_tag, F_parser.ReadVector());
  6177. end;
  6178. { TDerStringBase }
  6179. function TDerStringBase.Asn1GetHashCode: Int32;
  6180. begin
  6181. result := TStringUtils.GetStringHashCode(GetString());
  6182. end;
  6183. constructor TDerStringBase.Create;
  6184. begin
  6185. Inherited Create();
  6186. end;
  6187. function TDerStringBase.ToString: String;
  6188. begin
  6189. result := GetString();
  6190. end;
  6191. { TDerBitString }
  6192. class function TDerBitString.GetInstance(const obj: TCryptoLibByteArray)
  6193. : IDerBitString;
  6194. begin
  6195. try
  6196. result := FromByteArray(obj) as IDerBitString;
  6197. except
  6198. on e: Exception do
  6199. begin
  6200. raise EArgumentCryptoLibException.CreateResFmt(@SEncodingError,
  6201. [e.Message]);
  6202. end;
  6203. end;
  6204. end;
  6205. function TDerBitString.GetmData: TCryptoLibByteArray;
  6206. begin
  6207. result := FmData;
  6208. end;
  6209. function TDerBitString.GetmPadBits: Int32;
  6210. begin
  6211. result := FmPadBits;
  6212. end;
  6213. function TDerBitString.GetOctets: TCryptoLibByteArray;
  6214. begin
  6215. if (mPadBits <> 0) then
  6216. begin
  6217. raise EInvalidOperationCryptoLibException.CreateRes(@SUnalignedData);
  6218. end;
  6219. result := System.Copy(mData);
  6220. end;
  6221. function TDerBitString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  6222. var
  6223. other: IDerBitString;
  6224. begin
  6225. if (not Supports(asn1Object, IDerBitString, other)) then
  6226. begin
  6227. result := False;
  6228. Exit;
  6229. end;
  6230. result := (mPadBits = other.mPadBits) and
  6231. (TArrayUtils.AreEqual(mData, other.mData));
  6232. end;
  6233. constructor TDerBitString.Create(const data: TCryptoLibByteArray;
  6234. padBits: Int32);
  6235. begin
  6236. Inherited Create();
  6237. if (data = Nil) then
  6238. begin
  6239. raise EArgumentNilCryptoLibException.CreateRes(@SDataNil);
  6240. end;
  6241. if ((padBits < 0) or (padBits > 7)) then
  6242. begin
  6243. raise EArgumentCryptoLibException.CreateRes(@SInvalidRange);
  6244. end;
  6245. if ((System.length(data) = 0) and (padBits <> 0)) then
  6246. begin
  6247. raise EArgumentCryptoLibException.CreateRes(@SPadBitError);
  6248. end;
  6249. FmData := System.Copy(data);
  6250. FmPadBits := padBits;
  6251. end;
  6252. constructor TDerBitString.Create(const data: TCryptoLibByteArray);
  6253. begin
  6254. Create(data, 0);
  6255. end;
  6256. constructor TDerBitString.Create(namedBits: Int32);
  6257. var
  6258. bits, bytes, I, padBits: Int32;
  6259. data: TCryptoLibByteArray;
  6260. begin
  6261. Inherited Create();
  6262. if (namedBits = 0) then
  6263. begin
  6264. System.SetLength(FmData, 0);
  6265. FmPadBits := 0;
  6266. Exit;
  6267. end;
  6268. bits := TBigInteger.BitLen(namedBits);
  6269. bytes := (bits + 7) div 8;
  6270. {$IFDEF DEBUG}
  6271. System.Assert((0 < bytes) and (bytes <= 4));
  6272. {$ENDIF DEBUG}
  6273. System.SetLength(data, bytes);
  6274. System.Dec(bytes);
  6275. for I := 0 to System.Pred(bytes) do
  6276. begin
  6277. data[I] := Byte(namedBits);
  6278. namedBits := TBits.Asr32(namedBits, 8);
  6279. end;
  6280. {$IFDEF DEBUG}
  6281. System.Assert((namedBits and $FF) <> 0);
  6282. {$ENDIF DEBUG}
  6283. data[bytes] := Byte(namedBits);
  6284. padBits := 0;
  6285. while ((namedBits and (1 shl padBits)) = 0) do
  6286. begin
  6287. System.Inc(padBits);
  6288. end;
  6289. {$IFDEF DEBUG}
  6290. System.Assert(padBits < 8);
  6291. {$ENDIF DEBUG}
  6292. FmData := data;
  6293. FmPadBits := padBits;
  6294. end;
  6295. procedure TDerBitString.Encode(const derOut: TStream);
  6296. var
  6297. last, mask, unusedBits: Int32;
  6298. contents: TCryptoLibByteArray;
  6299. begin
  6300. if (mPadBits > 0) then
  6301. begin
  6302. last := mData[System.length(mData) - 1];
  6303. mask := (1 shl mPadBits) - 1;
  6304. unusedBits := last and mask;
  6305. if (unusedBits <> 0) then
  6306. begin
  6307. contents := TArrayUtils.Prepend(mData, Byte(mPadBits));
  6308. // /*
  6309. // * X.690-0207 11.2.1: Each unused bit in the final octet of the encoding of a bit string value shall be set to zero.
  6310. // */
  6311. contents[System.length(contents) - 1] := Byte(last xor unusedBits);
  6312. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString, contents);
  6313. Exit;
  6314. end;
  6315. end;
  6316. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString,
  6317. Byte(mPadBits), mData);
  6318. end;
  6319. class function TDerBitString.FromAsn1Octets(const octets: TCryptoLibByteArray)
  6320. : IDerBitString;
  6321. var
  6322. padBits, last, mask: Int32;
  6323. data: TCryptoLibByteArray;
  6324. begin
  6325. if (System.length(octets) < 1) then
  6326. begin
  6327. raise EArgumentCryptoLibException.CreateRes(@STruncatedBitString);
  6328. end;
  6329. padBits := octets[0];
  6330. data := TArrayUtils.CopyOfRange(octets, 1, System.length(octets));
  6331. if ((padBits > 0) and (padBits < 8) and (System.length(data) > 0)) then
  6332. begin
  6333. last := data[System.length(data) - 1];
  6334. mask := (1 shl padBits) - 1;
  6335. if ((last and mask) <> 0) then
  6336. begin
  6337. result := TBerBitString.Create(data, padBits);
  6338. Exit;
  6339. end;
  6340. end;
  6341. result := TDerBitString.Create(data, padBits);
  6342. end;
  6343. function TDerBitString.GetBytes: TCryptoLibByteArray;
  6344. begin
  6345. result := System.Copy(mData);
  6346. // DER requires pad bits be zero
  6347. if (mPadBits > 0) then
  6348. begin
  6349. result[System.length(result) - 1] := result[System.length(result) - 1] and
  6350. Byte($FF shl mPadBits);
  6351. end;
  6352. end;
  6353. class function TDerBitString.GetInstance(const obj: TObject): IDerBitString;
  6354. begin
  6355. if ((obj = Nil) or (obj is TDerBitString)) then
  6356. begin
  6357. result := obj as TDerBitString;
  6358. Exit;
  6359. end;
  6360. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  6361. [obj.ClassName]);
  6362. end;
  6363. class function TDerBitString.GetInstance(const obj: IAsn1TaggedObject;
  6364. isExplicit: Boolean): IDerBitString;
  6365. var
  6366. o: IAsn1Object;
  6367. begin
  6368. o := obj.GetObject();
  6369. if ((isExplicit) or (Supports(o, IDerBitString))) then
  6370. begin
  6371. result := GetInstance(o as TAsn1Object);
  6372. Exit;
  6373. end;
  6374. result := FromAsn1Octets((o as IAsn1OctetString).GetOctets());
  6375. end;
  6376. function TDerBitString.GetInt32Value: Int32;
  6377. var
  6378. Value, &length, I, mask: Int32;
  6379. begin
  6380. Value := 0;
  6381. length := Min(4, System.length(mData));
  6382. for I := 0 to System.Pred(length) do
  6383. begin
  6384. Value := Value or (Int32(mData[I]) shl (8 * I));
  6385. end;
  6386. if ((mPadBits > 0) and (length = System.length(mData))) then
  6387. begin
  6388. mask := (1 shl mPadBits) - 1;
  6389. Value := Value and (not(mask shl (8 * (length - 1))));
  6390. end;
  6391. result := Value;
  6392. end;
  6393. function TDerBitString.GetString: String;
  6394. var
  6395. buffer: TStringList;
  6396. I: Int32;
  6397. Str: TCryptoLibByteArray;
  6398. ubyte: UInt32;
  6399. begin
  6400. buffer := TStringList.Create();
  6401. buffer.LineBreak := '';
  6402. Str := GetDerEncoded();
  6403. buffer.Add('#');
  6404. I := 0;
  6405. try
  6406. while I <> System.length(Str) do
  6407. begin
  6408. ubyte := Str[I];
  6409. buffer.Add(FTable[(ubyte shr 4) and $F]);
  6410. buffer.Add(FTable[Str[I] and $F]);
  6411. System.Inc(I);
  6412. end;
  6413. result := buffer.Text;
  6414. finally
  6415. buffer.Free;
  6416. end;
  6417. end;
  6418. function TDerBitString.Asn1GetHashCode: Int32;
  6419. begin
  6420. result := mPadBits xor TArrayUtils.GetArrayHashCode(mData);
  6421. end;
  6422. constructor TDerBitString.Create(const obj: IAsn1Encodable);
  6423. begin
  6424. Create(obj.GetDerEncoded());
  6425. end;
  6426. { TBerBitString }
  6427. constructor TBerBitString.Create(const data: TCryptoLibByteArray);
  6428. begin
  6429. Inherited Create(data);
  6430. end;
  6431. constructor TBerBitString.Create(const data: TCryptoLibByteArray;
  6432. padBits: Int32);
  6433. begin
  6434. Inherited Create(data, padBits);
  6435. end;
  6436. constructor TBerBitString.Create(const obj: IAsn1Encodable);
  6437. begin
  6438. Inherited Create(obj);
  6439. end;
  6440. constructor TBerBitString.Create(namedBits: Int32);
  6441. begin
  6442. Inherited Create(namedBits);
  6443. end;
  6444. procedure TBerBitString.Encode(const derOut: TStream);
  6445. begin
  6446. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  6447. begin
  6448. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString,
  6449. Byte(mPadBits), mData);
  6450. end
  6451. else
  6452. begin
  6453. Inherited Encode(derOut);
  6454. end;
  6455. end;
  6456. { TBerGenerator }
  6457. constructor TBerGenerator.Create(outStream: TStream);
  6458. begin
  6459. Inherited Create(outStream);
  6460. end;
  6461. procedure TBerGenerator.AddObject(const obj: IAsn1Encodable);
  6462. var
  6463. temp: TBerOutputStream;
  6464. begin
  6465. temp := TBerOutputStream.Create(&Out);
  6466. try
  6467. temp.WriteObject(obj);
  6468. finally
  6469. temp.Free;
  6470. end;
  6471. end;
  6472. procedure TBerGenerator.Close;
  6473. begin
  6474. WriteBerEnd();
  6475. end;
  6476. constructor TBerGenerator.Create(outStream: TStream; tagNo: Int32;
  6477. isExplicit: Boolean);
  6478. begin
  6479. Inherited Create(outStream);
  6480. F_tagged := True;
  6481. F_isExplicit := isExplicit;
  6482. F_tagNo := tagNo;
  6483. end;
  6484. function TBerGenerator.GetRawOutputStream: TStream;
  6485. begin
  6486. result := &Out;
  6487. end;
  6488. procedure TBerGenerator.WriteBerBody(contentStream: TStream);
  6489. begin
  6490. TStreamUtils.PipeAll(contentStream, &Out);
  6491. end;
  6492. procedure TBerGenerator.WriteBerEnd;
  6493. begin
  6494. &Out.WriteByte($00);
  6495. &Out.WriteByte($00);
  6496. if (F_tagged and F_isExplicit) then // write extra end for tag header
  6497. begin
  6498. &Out.WriteByte($00);
  6499. &Out.WriteByte($00);
  6500. end;
  6501. end;
  6502. procedure TBerGenerator.WriteBerHeader(tag: Int32);
  6503. var
  6504. tagNum: Int32;
  6505. begin
  6506. if (F_tagged) then
  6507. begin
  6508. tagNum := F_tagNo or TAsn1Tags.Tagged;
  6509. if (F_isExplicit) then
  6510. begin
  6511. WriteHdr(tagNum or TAsn1Tags.Constructed);
  6512. WriteHdr(tag);
  6513. end
  6514. else
  6515. begin
  6516. if ((tag and TAsn1Tags.Constructed) <> 0) then
  6517. begin
  6518. WriteHdr(tagNum or TAsn1Tags.Constructed);
  6519. end
  6520. else
  6521. begin
  6522. WriteHdr(tagNum);
  6523. end;
  6524. end
  6525. end
  6526. else
  6527. begin
  6528. WriteHdr(tag);
  6529. end;
  6530. end;
  6531. procedure TBerGenerator.WriteHdr(tag: Int32);
  6532. begin
  6533. &Out.WriteByte(Byte(tag));
  6534. &Out.WriteByte($80);
  6535. end;
  6536. { TBerNull }
  6537. constructor TBerNull.Create(dummy: Int32);
  6538. begin
  6539. Inherited Create(dummy);
  6540. end;
  6541. procedure TBerNull.Encode(const derOut: TStream);
  6542. begin
  6543. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  6544. begin
  6545. (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Null);
  6546. end
  6547. else
  6548. begin
  6549. Inherited Encode(derOut);
  6550. end;
  6551. end;
  6552. class function TBerNull.GetInstance: IBerNull;
  6553. begin
  6554. result := TBerNull.Create(0);
  6555. end;
  6556. { TBerSequenceGenerator }
  6557. constructor TBerSequenceGenerator.Create(outStream: TStream);
  6558. begin
  6559. Inherited Create(outStream);
  6560. WriteBerHeader(TAsn1Tags.Constructed or TAsn1Tags.Sequence);
  6561. end;
  6562. constructor TBerSequenceGenerator.Create(outStream: TStream; tagNo: Int32;
  6563. isExplicit: Boolean);
  6564. begin
  6565. Inherited Create(outStream, tagNo, isExplicit);
  6566. WriteBerHeader(TAsn1Tags.Constructed or TAsn1Tags.Sequence);
  6567. end;
  6568. { TBerSequenceParser }
  6569. constructor TBerSequenceParser.Create(const parser: IAsn1StreamParser);
  6570. begin
  6571. F_parser := parser;
  6572. end;
  6573. function TBerSequenceParser.ReadObject: IAsn1Convertible;
  6574. begin
  6575. result := F_parser.ReadObject();
  6576. end;
  6577. function TBerSequenceParser.ToAsn1Object: IAsn1Object;
  6578. begin
  6579. result := TBerSequence.Create(F_parser.ReadVector());
  6580. end;
  6581. { TBerSet }
  6582. class function TBerSet.GetEmpty: IBerSet;
  6583. begin
  6584. result := TBerSet.Create();
  6585. end;
  6586. constructor TBerSet.Create;
  6587. begin
  6588. Inherited Create();
  6589. end;
  6590. constructor TBerSet.Create(const v: IAsn1EncodableVector;
  6591. needsSorting: Boolean);
  6592. begin
  6593. Inherited Create(v, needsSorting);
  6594. end;
  6595. destructor TBerSet.Destroy;
  6596. begin
  6597. inherited Destroy;
  6598. end;
  6599. constructor TBerSet.Create(const element: IAsn1Encodable);
  6600. begin
  6601. Inherited Create(element);
  6602. end;
  6603. constructor TBerSet.Create(const elementVector: IAsn1EncodableVector);
  6604. begin
  6605. Inherited Create(elementVector, False);
  6606. end;
  6607. procedure TBerSet.Encode(const derOut: TStream);
  6608. var
  6609. o: IAsn1Encodable;
  6610. LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  6611. begin
  6612. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  6613. begin
  6614. (derOut as TDerOutputStream).WriteByte(TAsn1Tags.&Set or
  6615. TAsn1Tags.Constructed);
  6616. (derOut as TDerOutputStream).WriteByte($80);
  6617. LListAsn1Encodable := Self.GetEnumerable;
  6618. for o in LListAsn1Encodable do
  6619. begin
  6620. (derOut as TDerOutputStream).WriteObject(o);
  6621. end;
  6622. (derOut as TDerOutputStream).WriteByte($00);
  6623. (derOut as TDerOutputStream).WriteByte($00);
  6624. end
  6625. else
  6626. begin
  6627. (Inherited Encode(derOut));
  6628. end;
  6629. end;
  6630. class function TBerSet.FromVector(const elementVector: IAsn1EncodableVector;
  6631. needsSorting: Boolean): IBerSet;
  6632. begin
  6633. if elementVector.count < 1 then
  6634. begin
  6635. result := Empty;
  6636. end
  6637. else
  6638. begin
  6639. result := TBerSet.Create(elementVector, needsSorting);
  6640. end;
  6641. end;
  6642. class function TBerSet.FromVector(const elementVector
  6643. : IAsn1EncodableVector): IBerSet;
  6644. begin
  6645. if elementVector.count < 1 then
  6646. begin
  6647. result := Empty;
  6648. end
  6649. else
  6650. begin
  6651. result := TBerSet.Create(elementVector);
  6652. end;
  6653. end;
  6654. { TBerSetParser }
  6655. constructor TBerSetParser.Create(const parser: IAsn1StreamParser);
  6656. begin
  6657. F_parser := parser;
  6658. end;
  6659. function TBerSetParser.ReadObject: IAsn1Convertible;
  6660. begin
  6661. result := F_parser.ReadObject();
  6662. end;
  6663. function TBerSetParser.ToAsn1Object: IAsn1Object;
  6664. begin
  6665. result := TBerSet.Create(F_parser.ReadVector(), False);
  6666. end;
  6667. { TDerTaggedObject }
  6668. constructor TDerTaggedObject.Create(tagNo: Int32; const obj: IAsn1Encodable);
  6669. begin
  6670. Inherited Create(tagNo, obj);
  6671. end;
  6672. constructor TDerTaggedObject.Create(explicitly: Boolean; tagNo: Int32;
  6673. const obj: IAsn1Encodable);
  6674. begin
  6675. Inherited Create(explicitly, tagNo, obj)
  6676. end;
  6677. constructor TDerTaggedObject.Create(tagNo: Int32);
  6678. begin
  6679. Inherited Create(False, tagNo, TDerSequence.Empty)
  6680. end;
  6681. procedure TDerTaggedObject.Encode(const derOut: TStream);
  6682. var
  6683. bytes: TCryptoLibByteArray;
  6684. flags: Int32;
  6685. begin
  6686. if (not IsEmpty()) then
  6687. begin
  6688. bytes := obj.GetDerEncoded();
  6689. if (explicitly) then
  6690. begin
  6691. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed or
  6692. TAsn1Tags.Tagged, tagNo, bytes);
  6693. end
  6694. else
  6695. begin
  6696. //
  6697. // need to mark constructed types... (preserve Constructed tag)
  6698. //
  6699. flags := (bytes[0] and TAsn1Tags.Constructed) or TAsn1Tags.Tagged;
  6700. (derOut as TDerOutputStream).WriteTag(flags, tagNo);
  6701. derOut.Write(bytes[1], System.length(bytes) - 1);
  6702. end
  6703. end
  6704. else
  6705. begin
  6706. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed or
  6707. TAsn1Tags.Tagged, tagNo, Nil);
  6708. end;
  6709. end;
  6710. { TBerTaggedObject }
  6711. constructor TBerTaggedObject.Create(tagNo: Int32; const obj: IAsn1Encodable);
  6712. begin
  6713. Inherited Create(tagNo, obj);
  6714. end;
  6715. constructor TBerTaggedObject.Create(explicitly: Boolean; tagNo: Int32;
  6716. const obj: IAsn1Encodable);
  6717. begin
  6718. Inherited Create(explicitly, tagNo, obj)
  6719. end;
  6720. constructor TBerTaggedObject.Create(tagNo: Int32);
  6721. begin
  6722. Inherited Create(False, tagNo, TBerSequence.Empty)
  6723. end;
  6724. procedure TBerTaggedObject.Encode(const derOut: TStream);
  6725. var
  6726. eObj: TList<IAsn1Encodable>;
  6727. LListIDerOctetString: TCryptoLibGenericArray<IDerOctetString>;
  6728. LListIAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
  6729. asn1OctetString: IAsn1OctetString;
  6730. berOctetString: IBerOctetString;
  6731. derOctetString: IDerOctetString;
  6732. asn1Sequence: IAsn1Sequence;
  6733. asn1Set: IAsn1Set;
  6734. o: IAsn1Encodable;
  6735. begin
  6736. eObj := TList<IAsn1Encodable>.Create();
  6737. try
  6738. if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
  6739. begin
  6740. (derOut as TDerOutputStream)
  6741. .WriteTag(Byte(TAsn1Tags.Constructed or TAsn1Tags.Tagged), tagNo);
  6742. (derOut as TDerOutputStream).WriteByte($80);
  6743. if (not IsEmpty()) then
  6744. begin
  6745. if (not explicitly) then
  6746. begin
  6747. if (Supports(obj, IAsn1OctetString, asn1OctetString)) then
  6748. begin
  6749. if (Supports(asn1OctetString, IBerOctetString, berOctetString)) then
  6750. begin
  6751. LListIDerOctetString := berOctetString.GetEnumerable;
  6752. for derOctetString in LListIDerOctetString do
  6753. begin
  6754. eObj.Add(derOctetString as IAsn1Encodable);
  6755. end;
  6756. end
  6757. else
  6758. begin
  6759. berOctetString := TBerOctetString.Create
  6760. (asn1OctetString.GetOctets());
  6761. LListIDerOctetString := berOctetString.GetEnumerable;
  6762. for derOctetString in LListIDerOctetString do
  6763. begin
  6764. eObj.Add(derOctetString as IAsn1Encodable);
  6765. end;
  6766. end
  6767. end
  6768. else if Supports(obj, IAsn1Sequence, asn1Sequence) then
  6769. begin
  6770. LListIAsn1Encodable := asn1Sequence.GetEnumerable;
  6771. for o in LListIAsn1Encodable do
  6772. begin
  6773. eObj.Add(o);
  6774. end;
  6775. end
  6776. else if Supports(obj, IAsn1Set, asn1Set) then
  6777. begin
  6778. LListIAsn1Encodable := asn1Set.GetEnumerable;
  6779. for o in LListIAsn1Encodable do
  6780. begin
  6781. eObj.Add(o);
  6782. end;
  6783. end
  6784. else
  6785. begin
  6786. raise ENotImplementedCryptoLibException.CreateResFmt
  6787. (@SNotImplemented, [(obj as TAsn1Encodable).ClassName]);
  6788. end;
  6789. for o in eObj do
  6790. begin
  6791. (derOut as TDerOutputStream).WriteObject(o);
  6792. end;
  6793. end
  6794. else
  6795. begin
  6796. (derOut as TDerOutputStream).WriteObject(obj);
  6797. end;
  6798. end;
  6799. (derOut as TDerOutputStream).WriteByte($00);
  6800. (derOut as TDerOutputStream).WriteByte($00);
  6801. end
  6802. else
  6803. begin
  6804. (Inherited Encode(derOut));
  6805. end
  6806. finally
  6807. eObj.Free;
  6808. end;
  6809. end;
  6810. { TBerTaggedObjectParser }
  6811. constructor TBerTaggedObjectParser.Create(Constructed: Boolean;
  6812. tagNumber: Int32; const parser: IAsn1StreamParser);
  6813. begin
  6814. F_constructed := Constructed;
  6815. F_tagNumber := tagNumber;
  6816. F_parser := parser;
  6817. end;
  6818. destructor TBerTaggedObjectParser.Destroy;
  6819. begin
  6820. F_parser := Nil;
  6821. inherited Destroy;
  6822. end;
  6823. function TBerTaggedObjectParser.GetIsConstructed: Boolean;
  6824. begin
  6825. result := F_constructed;
  6826. end;
  6827. function TBerTaggedObjectParser.GetObjectParser(tag: Int32; isExplicit: Boolean)
  6828. : IAsn1Convertible;
  6829. begin
  6830. if (isExplicit) then
  6831. begin
  6832. if (not F_constructed) then
  6833. begin
  6834. raise EIOCryptoLibException.CreateRes(@SUnConstructedTag);
  6835. end;
  6836. result := F_parser.ReadObject();
  6837. Exit;
  6838. end;
  6839. result := F_parser.ReadImplicit(F_constructed, tag);
  6840. end;
  6841. function TBerTaggedObjectParser.GetTagNo: Int32;
  6842. begin
  6843. result := F_tagNumber;
  6844. end;
  6845. function TBerTaggedObjectParser.ToAsn1Object: IAsn1Object;
  6846. begin
  6847. try
  6848. result := F_parser.ReadTaggedObject(F_constructed, F_tagNumber);
  6849. except
  6850. on e: EIOCryptoLibException do
  6851. begin
  6852. raise EAsn1ParsingCryptoLibException.CreateResFmt(@SParsingError,
  6853. [e.Message]);
  6854. end;
  6855. end;
  6856. end;
  6857. { TDerBmpString }
  6858. function TDerBmpString.GetStr: String;
  6859. begin
  6860. result := FStr;
  6861. end;
  6862. function TDerBmpString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  6863. var
  6864. other: IDerBmpString;
  6865. begin
  6866. if (not Supports(asn1Object, IDerBmpString, other)) then
  6867. begin
  6868. result := False;
  6869. Exit;
  6870. end;
  6871. result := Str = other.Str;
  6872. end;
  6873. constructor TDerBmpString.Create(const astr: TCryptoLibByteArray);
  6874. var
  6875. cs: TCryptoLibCharArray;
  6876. I: Int32;
  6877. begin
  6878. Inherited Create();
  6879. if (astr = Nil) then
  6880. begin
  6881. raise EArgumentNilCryptoLibException.CreateRes(@SEmptyInput);
  6882. end;
  6883. System.SetLength(cs, System.length(astr) shr 1);
  6884. I := 0;
  6885. while I <> System.length(cs) do
  6886. begin
  6887. cs[I] := Char((astr[2 * I] shl 8) or (astr[2 * I + 1] and $FF));
  6888. System.Inc(I);
  6889. end;
  6890. System.SetString(FStr, PChar(@cs[0]), System.length(cs));
  6891. end;
  6892. constructor TDerBmpString.Create(const astr: String);
  6893. begin
  6894. Inherited Create();
  6895. if (astr = '') then
  6896. begin
  6897. raise EArgumentNilCryptoLibException.CreateRes(@SEmptyInput);
  6898. end;
  6899. FStr := astr;
  6900. end;
  6901. procedure TDerBmpString.Encode(const derOut: TStream);
  6902. var
  6903. c: TCryptoLibCharArray;
  6904. b: TCryptoLibByteArray;
  6905. I: Int32;
  6906. begin
  6907. c := TStringUtils.StringToCharArray(Str);
  6908. System.SetLength(b, System.length(c) * 2);
  6909. I := 0;
  6910. while I <> System.length(c) do
  6911. begin
  6912. b[2 * I] := Byte(Ord(c[I]) shr 8);
  6913. b[2 * I + 1] := Byte(c[I]);
  6914. System.Inc(I);
  6915. end;
  6916. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BmpString, b);
  6917. end;
  6918. class function TDerBmpString.GetInstance(const obj: TObject): IDerBmpString;
  6919. begin
  6920. if ((obj = Nil) or (obj is TDerBmpString)) then
  6921. begin
  6922. result := obj as TDerBmpString;
  6923. Exit;
  6924. end;
  6925. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  6926. [obj.ClassName]);
  6927. end;
  6928. class function TDerBmpString.GetInstance(const obj: IAsn1TaggedObject;
  6929. isExplicit: Boolean): IDerBmpString;
  6930. var
  6931. o: IAsn1Object;
  6932. begin
  6933. o := obj.GetObject();
  6934. if ((isExplicit) or (Supports(o, IDerBmpString))) then
  6935. begin
  6936. result := GetInstance(o as TAsn1Object);
  6937. Exit;
  6938. end;
  6939. result := TDerBmpString.Create(TAsn1OctetString.GetInstance(o as TAsn1Object)
  6940. .GetOctets());
  6941. end;
  6942. function TDerBmpString.GetString: String;
  6943. begin
  6944. result := FStr;
  6945. end;
  6946. { TDerBoolean }
  6947. function TDerBoolean.GetIsTrue: Boolean;
  6948. begin
  6949. result := Fvalue <> 0;
  6950. end;
  6951. function TDerBoolean.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  6952. var
  6953. other: IDerBoolean;
  6954. begin
  6955. if (not Supports(asn1Object, IDerBoolean, other)) then
  6956. begin
  6957. result := System.False;
  6958. Exit;
  6959. end;
  6960. result := IsTrue = other.IsTrue;
  6961. end;
  6962. function TDerBoolean.Asn1GetHashCode: Int32;
  6963. begin
  6964. result := Ord(IsTrue);
  6965. end;
  6966. constructor TDerBoolean.Create(const val: TCryptoLibByteArray);
  6967. begin
  6968. Inherited Create();
  6969. if (System.length(val) <> 1) then
  6970. begin
  6971. raise EArgumentCryptoLibException.CreateRes(@SInvalidValue);
  6972. end;
  6973. // TODO Are there any constraints on the possible byte values?
  6974. Fvalue := val[0];
  6975. end;
  6976. constructor TDerBoolean.Create(Value: Boolean);
  6977. begin
  6978. Inherited Create();
  6979. if Value then
  6980. begin
  6981. Fvalue := Byte($FF)
  6982. end
  6983. else
  6984. begin
  6985. Fvalue := Byte(0)
  6986. end;
  6987. end;
  6988. procedure TDerBoolean.Encode(const derOut: TStream);
  6989. begin
  6990. // TODO Should we make sure the byte value is one of '0' or '0xff' here?
  6991. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Boolean,
  6992. TCryptoLibByteArray.Create(Fvalue));
  6993. end;
  6994. class function TDerBoolean.FromOctetString(const Value: TCryptoLibByteArray)
  6995. : IDerBoolean;
  6996. var
  6997. b: Byte;
  6998. begin
  6999. if (System.length(Value) <> 1) then
  7000. begin
  7001. raise EArgumentCryptoLibException.CreateRes(@SInvalidBooleanValue);
  7002. end;
  7003. b := Value[0];
  7004. case b of
  7005. 0:
  7006. result := TDerBoolean.False;
  7007. $FF:
  7008. result := TDerBoolean.True
  7009. else
  7010. begin
  7011. result := TDerBoolean.Create(Value);
  7012. end;
  7013. end;
  7014. end;
  7015. class function TDerBoolean.GetInstance(Value: Boolean): IDerBoolean;
  7016. begin
  7017. if Value then
  7018. begin
  7019. result := TDerBoolean.True;
  7020. end
  7021. else
  7022. begin
  7023. result := TDerBoolean.False;
  7024. end;
  7025. end;
  7026. class function TDerBoolean.GetInstance(const obj: TObject): IDerBoolean;
  7027. begin
  7028. if ((obj = Nil) or (obj is TDerBoolean)) then
  7029. begin
  7030. Supports(obj, IDerBoolean, result);
  7031. Exit;
  7032. end;
  7033. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7034. [obj.ClassName]);
  7035. end;
  7036. class function TDerBoolean.GetFalse: IDerBoolean;
  7037. begin
  7038. result := TDerBoolean.Create(System.False);
  7039. end;
  7040. class function TDerBoolean.GetInstance(const obj: IAsn1TaggedObject;
  7041. isExplicit: Boolean): IDerBoolean;
  7042. var
  7043. o: IAsn1Object;
  7044. begin
  7045. o := obj.GetObject();
  7046. if ((isExplicit) or (Supports(o, IDerBoolean))) then
  7047. begin
  7048. result := GetInstance(o as TAsn1Object);
  7049. Exit;
  7050. end;
  7051. result := FromOctetString((o as IAsn1OctetString).GetOctets());
  7052. end;
  7053. class function TDerBoolean.GetTrue: IDerBoolean;
  7054. begin
  7055. result := TDerBoolean.Create(System.True);
  7056. end;
  7057. function TDerBoolean.ToString: String;
  7058. begin
  7059. result := BoolToStr(IsTrue, System.True);
  7060. end;
  7061. { TDerEnumerated }
  7062. function TDerEnumerated.GetBytes: TCryptoLibByteArray;
  7063. begin
  7064. result := Fbytes;
  7065. end;
  7066. function TDerEnumerated.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7067. var
  7068. other: IDerEnumerated;
  7069. begin
  7070. if (not Supports(asn1Object, IDerEnumerated, other)) then
  7071. begin
  7072. result := False;
  7073. Exit;
  7074. end;
  7075. result := TArrayUtils.AreEqual(bytes, other.bytes);
  7076. end;
  7077. function TDerEnumerated.Asn1GetHashCode: Int32;
  7078. begin
  7079. result := TArrayUtils.GetArrayHashCode(bytes);
  7080. end;
  7081. constructor TDerEnumerated.Create(val: Int32);
  7082. begin
  7083. Inherited Create();
  7084. if (val < 0) then
  7085. begin
  7086. raise EArgumentCryptoLibException.CreateRes(@SEnumeratedNegative);
  7087. end;
  7088. Fbytes := TBigInteger.ValueOf(val).ToByteArray();
  7089. FStart := 0;
  7090. end;
  7091. constructor TDerEnumerated.Create(val: Int64);
  7092. begin
  7093. Inherited Create();
  7094. if (val < 0) then
  7095. begin
  7096. raise EArgumentCryptoLibException.CreateRes(@SEnumeratedNegative);
  7097. end;
  7098. Fbytes := TBigInteger.ValueOf(val).ToByteArray();
  7099. FStart := 0;
  7100. end;
  7101. constructor TDerEnumerated.Create(const val: TBigInteger);
  7102. begin
  7103. Inherited Create();
  7104. if (val.SignValue < 0) then
  7105. begin
  7106. raise EArgumentCryptoLibException.CreateRes(@SEnumeratedNegative);
  7107. end;
  7108. Fbytes := val.ToByteArray();
  7109. FStart := 0;
  7110. end;
  7111. constructor TDerEnumerated.Create(const bytes: TCryptoLibByteArray);
  7112. begin
  7113. Inherited Create();
  7114. if (TDerInteger.IsMalformed(bytes)) then
  7115. begin
  7116. raise EArgumentCryptoLibException.CreateRes(@SMalformedEnumerated);
  7117. end;
  7118. if (0 <> (bytes[0] and $80)) then
  7119. begin
  7120. raise EArgumentCryptoLibException.CreateRes(@SEnumeratedNegative);
  7121. end;
  7122. Fbytes := System.Copy(bytes);
  7123. FStart := TDerInteger.SignBytesToSkip(bytes);
  7124. end;
  7125. procedure TDerEnumerated.Encode(const derOut: TStream);
  7126. begin
  7127. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Enumerated, Fbytes);
  7128. end;
  7129. class function TDerEnumerated.FromOctetString(const enc: TCryptoLibByteArray)
  7130. : IDerEnumerated;
  7131. var
  7132. LValue: Int32;
  7133. possibleMatch: IDerEnumerated;
  7134. begin
  7135. if (System.length(enc) > 1) then
  7136. begin
  7137. result := TDerEnumerated.Create(enc);
  7138. Exit;
  7139. end;
  7140. if (System.length(enc) = 0) then
  7141. begin
  7142. raise EArgumentCryptoLibException.CreateRes(@SZeroLength);
  7143. end;
  7144. LValue := enc[0];
  7145. if (LValue >= System.length(Fcache)) then
  7146. begin
  7147. result := TDerEnumerated.Create(enc);
  7148. Exit;
  7149. end;
  7150. possibleMatch := Fcache[LValue];
  7151. if (possibleMatch = Nil) then
  7152. begin
  7153. possibleMatch := TDerEnumerated.Create(enc);
  7154. Fcache[LValue] := possibleMatch;
  7155. end;
  7156. result := possibleMatch;
  7157. end;
  7158. class function TDerEnumerated.GetInstance(const obj: TObject): IDerEnumerated;
  7159. begin
  7160. if ((obj = Nil) or (obj is TDerEnumerated)) then
  7161. begin
  7162. result := obj as TDerEnumerated;
  7163. Exit;
  7164. end;
  7165. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7166. [obj.ClassName]);
  7167. end;
  7168. class function TDerEnumerated.GetInstance(const obj: IAsn1TaggedObject;
  7169. isExplicit: Boolean): IDerEnumerated;
  7170. var
  7171. o: IAsn1Object;
  7172. begin
  7173. o := obj.GetObject();
  7174. if (isExplicit or (Supports(o, IDerEnumerated))) then
  7175. begin
  7176. result := GetInstance(o as TObject);
  7177. Exit;
  7178. end;
  7179. result := FromOctetString((o as IAsn1OctetString).GetOctets());
  7180. end;
  7181. function TDerEnumerated.GetIntValueExact: Int32;
  7182. var
  7183. count: Int32;
  7184. begin
  7185. count := System.length(Fbytes) - FStart;
  7186. if (count > 4) then
  7187. begin
  7188. raise EArithmeticCryptoLibException.CreateRes(@SASN1IntegerOutOfRangeError);
  7189. end;
  7190. result := TDerInteger.IntValue(Fbytes, FStart, TDerInteger.SignExtSigned);
  7191. end;
  7192. function TDerEnumerated.GetValue: TBigInteger;
  7193. begin
  7194. result := TBigInteger.Create(Fbytes);
  7195. end;
  7196. function TDerEnumerated.HasValue(const x: TBigInteger): Boolean;
  7197. begin
  7198. result := (x.IsInitialized)
  7199. // Fast check to avoid allocation
  7200. and (TDerInteger.IntValue(Fbytes, FStart, TDerInteger.SignExtSigned)
  7201. = x.Int32Value) and (Value.Equals(x));
  7202. end;
  7203. { TDerGraphicString }
  7204. function TDerGraphicString.GetmString: TCryptoLibByteArray;
  7205. begin
  7206. result := FmString;
  7207. end;
  7208. function TDerGraphicString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7209. var
  7210. other: IDerGraphicString;
  7211. begin
  7212. if (not Supports(asn1Object, IDerGraphicString, other)) then
  7213. begin
  7214. result := False;
  7215. Exit;
  7216. end;
  7217. result := TArrayUtils.AreEqual(mString, other.mString);
  7218. end;
  7219. function TDerGraphicString.Asn1GetHashCode: Int32;
  7220. begin
  7221. result := TArrayUtils.GetArrayHashCode(mString);
  7222. end;
  7223. constructor TDerGraphicString.Create(const encoding: TCryptoLibByteArray);
  7224. begin
  7225. Inherited Create();
  7226. FmString := System.Copy(encoding);
  7227. end;
  7228. procedure TDerGraphicString.Encode(const derOut: TStream);
  7229. begin
  7230. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.GraphicString, mString);
  7231. end;
  7232. class function TDerGraphicString.GetInstance(const obj: TObject)
  7233. : IDerGraphicString;
  7234. begin
  7235. if ((obj = Nil) or (obj is TDerGraphicString)) then
  7236. begin
  7237. result := obj as TDerGraphicString;
  7238. Exit;
  7239. end;
  7240. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7241. [obj.ClassName]);
  7242. end;
  7243. class function TDerGraphicString.GetInstance(const obj: IAsn1TaggedObject;
  7244. isExplicit: Boolean): IDerGraphicString;
  7245. var
  7246. o: IAsn1Object;
  7247. begin
  7248. o := obj.GetObject();
  7249. if ((isExplicit) or (Supports(o, IDerGraphicString))) then
  7250. begin
  7251. result := GetInstance(o as TAsn1Object);
  7252. Exit;
  7253. end;
  7254. result := TDerGraphicString.Create
  7255. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  7256. end;
  7257. class function TDerGraphicString.GetInstance(const obj: TCryptoLibByteArray)
  7258. : IDerGraphicString;
  7259. begin
  7260. try
  7261. result := FromByteArray(obj) as IDerGraphicString;
  7262. except
  7263. on e: Exception do
  7264. begin
  7265. raise EArgumentCryptoLibException.CreateResFmt(@SEncodingError,
  7266. [e.Message]);
  7267. end;
  7268. end;
  7269. end;
  7270. function TDerGraphicString.GetOctets: TCryptoLibByteArray;
  7271. begin
  7272. result := System.Copy(mString);
  7273. end;
  7274. function TDerGraphicString.GetString: String;
  7275. begin
  7276. result := TConverters.ConvertBytesToString(mString, TEncoding.ANSI);
  7277. end;
  7278. { TDerExternal }
  7279. class function TDerExternal.GetObjFromVector(const v: IAsn1EncodableVector;
  7280. Index: Int32): IAsn1Object;
  7281. var
  7282. val: IAsn1Encodable;
  7283. begin
  7284. if (v.count <= index) then
  7285. begin
  7286. raise EArgumentCryptoLibException.CreateRes(@SFewObject);
  7287. end;
  7288. val := v[index];
  7289. result := val.ToAsn1Object();
  7290. end;
  7291. class procedure TDerExternal.WriteEncodable(ms: TMemoryStream;
  7292. const e: IAsn1Encodable);
  7293. var
  7294. bs: TCryptoLibByteArray;
  7295. begin
  7296. if (e <> Nil) then
  7297. begin
  7298. bs := e.GetDerEncoded();
  7299. ms.Write(bs[0], System.length(bs));
  7300. end;
  7301. end;
  7302. function TDerExternal.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7303. var
  7304. other: IDerExternal;
  7305. begin
  7306. if (Self.Equals(asn1Object)) then
  7307. begin
  7308. result := True;
  7309. Exit;
  7310. end;
  7311. if (not Supports(asn1Object, IDerExternal, other)) then
  7312. begin
  7313. result := False;
  7314. Exit;
  7315. end;
  7316. result := directReference.Equals(other.directReference) and
  7317. indirectReference.Equals(other.indirectReference) and
  7318. dataValueDescriptor.Equals(other.dataValueDescriptor) and
  7319. ExternalContent.Equals(other.ExternalContent);
  7320. end;
  7321. function TDerExternal.Asn1GetHashCode: Int32;
  7322. var
  7323. ret: Int32;
  7324. begin
  7325. ret := ExternalContent.GetHashCode();
  7326. if (directReference <> Nil) then
  7327. begin
  7328. ret := ret xor directReference.GetHashCode();
  7329. end;
  7330. if (indirectReference <> Nil) then
  7331. begin
  7332. ret := ret xor indirectReference.GetHashCode();
  7333. end;
  7334. if (dataValueDescriptor <> Nil) then
  7335. begin
  7336. ret := ret xor dataValueDescriptor.GetHashCode();
  7337. end;
  7338. result := ret;
  7339. end;
  7340. constructor TDerExternal.Create(const directReference: IDerObjectIdentifier;
  7341. const indirectReference: IDerInteger; const dataValueDescriptor: IAsn1Object;
  7342. encoding: Int32; const externalData: IAsn1Object);
  7343. begin
  7344. Inherited Create();
  7345. FdirectReference := directReference;
  7346. FindirectReference := indirectReference;
  7347. FdataValueDescriptor := dataValueDescriptor;
  7348. Fencoding := encoding;
  7349. FexternalContent := externalData.ToAsn1Object();
  7350. end;
  7351. constructor TDerExternal.Create(const vector: IAsn1EncodableVector);
  7352. var
  7353. offset: Int32;
  7354. enc: IAsn1Object;
  7355. derObjectIdentifier: IDerObjectIdentifier;
  7356. derInteger: IDerInteger;
  7357. obj: IAsn1TaggedObject;
  7358. begin
  7359. Inherited Create();
  7360. offset := 0;
  7361. enc := GetObjFromVector(vector, offset);
  7362. if (Supports(enc, IDerObjectIdentifier, derObjectIdentifier)) then
  7363. begin
  7364. directReference := derObjectIdentifier;
  7365. System.Inc(offset);
  7366. enc := GetObjFromVector(vector, offset);
  7367. end;
  7368. if (Supports(enc, IDerInteger, derInteger)) then
  7369. begin
  7370. indirectReference := derInteger;
  7371. System.Inc(offset);
  7372. enc := GetObjFromVector(vector, offset);
  7373. end;
  7374. if (not(Supports(enc, IAsn1TaggedObject))) then
  7375. begin
  7376. dataValueDescriptor := enc;
  7377. System.Inc(offset);
  7378. enc := GetObjFromVector(vector, offset);
  7379. end;
  7380. if (vector.count <> (offset + 1)) then
  7381. begin
  7382. raise EArgumentCryptoLibException.CreateRes(@SVectorTooLarge);
  7383. end;
  7384. if (not(Supports(enc, IAsn1TaggedObject, obj))) then
  7385. begin
  7386. raise EArgumentCryptoLibException.CreateRes(@SNoTaggedObjectFound);
  7387. end;
  7388. // Use property accessor to include check on value
  7389. encoding := obj.tagNo;
  7390. if ((Fencoding < 0) or (Fencoding > 2)) then
  7391. begin
  7392. raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidEncodingValue);
  7393. end;
  7394. FexternalContent := obj.GetObject();
  7395. end;
  7396. constructor TDerExternal.Create(const directReference: IDerObjectIdentifier;
  7397. const indirectReference: IDerInteger; const dataValueDescriptor: IAsn1Object;
  7398. const externalData: IDerTaggedObject);
  7399. begin
  7400. Create(directReference, indirectReference, dataValueDescriptor,
  7401. externalData.tagNo, externalData.ToAsn1Object());
  7402. end;
  7403. procedure TDerExternal.Encode(const derOut: TStream);
  7404. var
  7405. ms: TMemoryStream;
  7406. buffer: TCryptoLibByteArray;
  7407. begin
  7408. ms := TMemoryStream.Create();
  7409. try
  7410. WriteEncodable(ms, directReference);
  7411. WriteEncodable(ms, indirectReference);
  7412. WriteEncodable(ms, dataValueDescriptor);
  7413. WriteEncodable(ms, TDerTaggedObject.Create(TAsn1Tags.External,
  7414. ExternalContent));
  7415. System.SetLength(buffer, ms.Size);
  7416. ms.Position := 0;
  7417. ms.Read(buffer[0], ms.Size);
  7418. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed,
  7419. TAsn1Tags.External, buffer);
  7420. finally
  7421. ms.Free;
  7422. end;
  7423. end;
  7424. function TDerExternal.GetDataValueDescriptor: IAsn1Object;
  7425. begin
  7426. result := FdataValueDescriptor;
  7427. end;
  7428. function TDerExternal.GetDirectReference: IDerObjectIdentifier;
  7429. begin
  7430. result := FdirectReference;
  7431. end;
  7432. function TDerExternal.GetEncoding: Int32;
  7433. begin
  7434. result := Fencoding;
  7435. end;
  7436. function TDerExternal.GetExternalContent: IAsn1Object;
  7437. begin
  7438. result := FexternalContent;
  7439. end;
  7440. function TDerExternal.GetIndirectReference: IDerInteger;
  7441. begin
  7442. result := FindirectReference;
  7443. end;
  7444. procedure TDerExternal.SetDataValueDescriptor(const Value: IAsn1Object);
  7445. begin
  7446. FdataValueDescriptor := Value;
  7447. end;
  7448. procedure TDerExternal.SetDirectReference(const Value: IDerObjectIdentifier);
  7449. begin
  7450. FdirectReference := Value;
  7451. end;
  7452. procedure TDerExternal.SetEncoding(const Value: Int32);
  7453. begin
  7454. if ((Fencoding < 0) or (Fencoding > 2)) then
  7455. begin
  7456. raise EInvalidOperationCryptoLibException.CreateResFmt
  7457. (@SInvalidEncoding, [Value]);
  7458. end;
  7459. Fencoding := Value;
  7460. end;
  7461. procedure TDerExternal.SetExternalContent(const Value: IAsn1Object);
  7462. begin
  7463. FexternalContent := Value;
  7464. end;
  7465. procedure TDerExternal.SetIndirectReference(const Value: IDerInteger);
  7466. begin
  7467. FindirectReference := Value;
  7468. end;
  7469. { TDerInteger }
  7470. class function TDerInteger.GetAllowUnsafeInteger: Boolean;
  7471. begin
  7472. result := FAllowUnsafeInteger;
  7473. end;
  7474. class procedure TDerInteger.SetAllowUnsafeInteger(const Value: Boolean);
  7475. begin
  7476. FAllowUnsafeInteger := Value;
  7477. end;
  7478. function TDerInteger.GetBytes: TCryptoLibByteArray;
  7479. begin
  7480. result := Fbytes;
  7481. end;
  7482. class function TDerInteger.GetInstance(const obj: TObject): IDerInteger;
  7483. begin
  7484. if ((obj = Nil) or (obj is TDerInteger)) then
  7485. begin
  7486. result := obj as TDerInteger;
  7487. Exit;
  7488. end;
  7489. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7490. [obj.ClassName]);
  7491. end;
  7492. function TDerInteger.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7493. var
  7494. other: IDerInteger;
  7495. begin
  7496. if (not Supports(asn1Object, IDerInteger, other)) then
  7497. begin
  7498. result := False;
  7499. Exit;
  7500. end;
  7501. result := TArrayUtils.AreEqual(bytes, other.bytes);
  7502. end;
  7503. function TDerInteger.Asn1GetHashCode: Int32;
  7504. begin
  7505. result := TArrayUtils.GetArrayHashCode(Fbytes);
  7506. end;
  7507. constructor TDerInteger.Create(const Value: TBigInteger);
  7508. begin
  7509. inherited Create();
  7510. if (not Value.IsInitialized) then
  7511. begin
  7512. raise EArgumentNilCryptoLibException.CreateRes(@SValueNil);
  7513. end;
  7514. Fbytes := Value.ToByteArray();
  7515. FStart := 0;
  7516. end;
  7517. constructor TDerInteger.Create(Value: Int32);
  7518. begin
  7519. inherited Create();
  7520. Fbytes := TBigInteger.ValueOf(Value).ToByteArray();
  7521. FStart := 0;
  7522. end;
  7523. constructor TDerInteger.Create(Value: Int64);
  7524. begin
  7525. inherited Create();
  7526. Fbytes := TBigInteger.ValueOf(Value).ToByteArray();
  7527. FStart := 0;
  7528. end;
  7529. constructor TDerInteger.Create(const bytes: TCryptoLibByteArray);
  7530. begin
  7531. Create(bytes, True);
  7532. end;
  7533. constructor TDerInteger.Create(const bytes: TCryptoLibByteArray;
  7534. clone: Boolean);
  7535. begin
  7536. Inherited Create();
  7537. if (IsMalformed(bytes)) then
  7538. begin
  7539. raise EArgumentCryptoLibException.CreateRes(@SMalformedInteger);
  7540. end;
  7541. if clone then
  7542. begin
  7543. Fbytes := System.Copy(bytes);
  7544. end
  7545. else
  7546. begin
  7547. Fbytes := bytes;
  7548. end;
  7549. FStart := SignBytesToSkip(bytes);
  7550. end;
  7551. class constructor TDerInteger.CreateDerInteger;
  7552. begin
  7553. FAllowUnsafeInteger := False;
  7554. end;
  7555. procedure TDerInteger.Encode(const derOut: TStream);
  7556. begin
  7557. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Integer, Fbytes);
  7558. end;
  7559. class function TDerInteger.GetInstance(const obj: IAsn1TaggedObject;
  7560. isExplicit: Boolean): IDerInteger;
  7561. var
  7562. o: IAsn1Object;
  7563. begin
  7564. if (obj = Nil) then
  7565. raise EArgumentNilCryptoLibException.CreateRes(@SObjectNil);
  7566. o := obj.GetObject();
  7567. if ((isExplicit) or (Supports(o, IDerInteger))) then
  7568. begin
  7569. result := GetInstance(o as TAsn1Object);
  7570. Exit;
  7571. end;
  7572. result := TDerInteger.Create(TAsn1OctetString.GetInstance(o as TAsn1Object)
  7573. .GetOctets());
  7574. end;
  7575. function TDerInteger.GetIntPositiveValueExact: Int32;
  7576. var
  7577. count: Int32;
  7578. begin
  7579. count := System.length(Fbytes) - FStart;
  7580. if ((count > 4) or ((count = 4) and (0 <> (bytes[FStart] and $80)))) then
  7581. begin
  7582. raise EArithmeticCryptoLibException.CreateRes
  7583. (@SASN1IntegerPositiveOutOfRangeError);
  7584. end;
  7585. result := IntValue(Fbytes, FStart, SignExtUnsigned);
  7586. end;
  7587. function TDerInteger.GetIntValueExact: Int32;
  7588. var
  7589. count: Int32;
  7590. begin
  7591. count := System.length(Fbytes) - FStart;
  7592. if (count > 4) then
  7593. begin
  7594. raise EArithmeticCryptoLibException.CreateRes(@SASN1IntegerOutOfRangeError);
  7595. end;
  7596. result := IntValue(Fbytes, FStart, SignExtSigned);
  7597. end;
  7598. function TDerInteger.GetPositiveValue: TBigInteger;
  7599. begin
  7600. result := TBigInteger.Create(1, Fbytes);
  7601. end;
  7602. function TDerInteger.GetValue: TBigInteger;
  7603. begin
  7604. result := TBigInteger.Create(Fbytes);
  7605. end;
  7606. function TDerInteger.HasValue(const x: TBigInteger): Boolean;
  7607. begin
  7608. result := (x.IsInitialized)
  7609. // Fast check to avoid allocation
  7610. and (IntValue(Fbytes, FStart, SignExtSigned) = x.Int32Value) and
  7611. (Value.Equals(x));
  7612. end;
  7613. class function TDerInteger.IntValue(const bytes: TCryptoLibByteArray;
  7614. start, signExt: Int32): Int32;
  7615. var
  7616. LLength, LPos, LVal: Int32;
  7617. begin
  7618. LLength := System.length(bytes);
  7619. LPos := Max(start, LLength - 4);
  7620. LVal := ShortInt(bytes[LPos]) and signExt;
  7621. System.Inc(LPos);
  7622. while (LPos < LLength) do
  7623. begin
  7624. LVal := (LVal shl 8) or bytes[LPos];
  7625. System.Inc(LPos);
  7626. end;
  7627. result := LVal;
  7628. end;
  7629. class function TDerInteger.IsMalformed(const bytes
  7630. : TCryptoLibByteArray): Boolean;
  7631. begin
  7632. case System.length(bytes) of
  7633. 0:
  7634. begin
  7635. result := True;
  7636. end;
  7637. 1:
  7638. begin
  7639. result := False;
  7640. end
  7641. else
  7642. begin
  7643. result := (ShortInt(bytes[0]) = (TBits.Asr32(ShortInt(bytes[1]), 7))) and
  7644. (not AllowUnsafeInteger);
  7645. end;
  7646. end;
  7647. end;
  7648. class function TDerInteger.SignBytesToSkip(const bytes
  7649. : TCryptoLibByteArray): Int32;
  7650. var
  7651. LPos, LLast: Int32;
  7652. begin
  7653. LPos := 0;
  7654. LLast := System.length(bytes) - 1;
  7655. while ((LPos < LLast) and (ShortInt(bytes[LPos])
  7656. = TBits.Asr32(ShortInt(bytes[LPos + 1]), 7))) do
  7657. begin
  7658. System.Inc(LPos);
  7659. end;
  7660. result := LPos;
  7661. end;
  7662. function TDerInteger.ToString: String;
  7663. begin
  7664. result := Value.ToString();
  7665. end;
  7666. { TDerExternalParser }
  7667. constructor TDerExternalParser.Create(const parser: IAsn1StreamParser);
  7668. begin
  7669. Inherited Create();
  7670. F_parser := parser;
  7671. end;
  7672. function TDerExternalParser.ReadObject: IAsn1Convertible;
  7673. begin
  7674. result := F_parser.ReadObject();
  7675. end;
  7676. function TDerExternalParser.ToAsn1Object: IAsn1Object;
  7677. begin
  7678. result := TDerExternal.Create(F_parser.ReadVector());
  7679. end;
  7680. { TDerOctetStringParser }
  7681. constructor TDerOctetStringParser.Create(stream: TStream);
  7682. begin
  7683. FStream := stream;
  7684. end;
  7685. destructor TDerOctetStringParser.Destroy;
  7686. begin
  7687. FStream.Free;
  7688. inherited Destroy;
  7689. end;
  7690. function TDerOctetStringParser.GetOctetStream: TStream;
  7691. begin
  7692. result := FStream;
  7693. end;
  7694. function TDerOctetStringParser.ToAsn1Object: IAsn1Object;
  7695. begin
  7696. try
  7697. result := TDerOctetString.Create((FStream as TDefiniteLengthInputStream)
  7698. .ToArray());
  7699. except
  7700. on e: EIOCryptoLibException do
  7701. begin
  7702. raise EInvalidOperationCryptoLibException.CreateResFmt(@SConvertError,
  7703. [e.Message]);
  7704. end;
  7705. end;
  7706. end;
  7707. { TDerGeneralString }
  7708. function TDerGeneralString.GetStr: String;
  7709. begin
  7710. result := FStr;
  7711. end;
  7712. function TDerGeneralString.GetOctets: TCryptoLibByteArray;
  7713. begin
  7714. result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
  7715. end;
  7716. function TDerGeneralString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7717. var
  7718. other: IDerGeneralString;
  7719. begin
  7720. if (not Supports(asn1Object, IDerGeneralString, other)) then
  7721. begin
  7722. result := False;
  7723. Exit;
  7724. end;
  7725. result := Str = other.Str;
  7726. end;
  7727. constructor TDerGeneralString.Create(const Str: TCryptoLibByteArray);
  7728. begin
  7729. Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII));
  7730. end;
  7731. constructor TDerGeneralString.Create(const Str: String);
  7732. begin
  7733. Inherited Create();
  7734. if (Str = '') then
  7735. begin
  7736. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  7737. end;
  7738. FStr := Str;
  7739. end;
  7740. procedure TDerGeneralString.Encode(const derOut: TStream);
  7741. begin
  7742. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.GeneralString,
  7743. GetOctets());
  7744. end;
  7745. class function TDerGeneralString.GetInstance(const obj: TObject)
  7746. : IDerGeneralString;
  7747. begin
  7748. if ((obj = Nil) or (obj is TDerGeneralString)) then
  7749. begin
  7750. result := obj as TDerGeneralString;
  7751. Exit;
  7752. end;
  7753. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7754. [obj.ClassName]);
  7755. end;
  7756. class function TDerGeneralString.GetInstance(const obj: IAsn1TaggedObject;
  7757. isExplicit: Boolean): IDerGeneralString;
  7758. var
  7759. o: IAsn1Object;
  7760. begin
  7761. o := obj.GetObject();
  7762. if ((isExplicit) or (Supports(o, IDerGeneralString))) then
  7763. begin
  7764. result := GetInstance(o as TAsn1Object);
  7765. Exit;
  7766. end;
  7767. result := TDerGeneralString.Create
  7768. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  7769. end;
  7770. function TDerGeneralString.GetString: String;
  7771. begin
  7772. result := Str;
  7773. end;
  7774. { TDerGenerator }
  7775. constructor TDerGenerator.Create(const outStream: TStream);
  7776. begin
  7777. Inherited Create(outStream);
  7778. end;
  7779. constructor TDerGenerator.Create(const outStream: TStream; tagNo: Int32;
  7780. isExplicit: Boolean);
  7781. begin
  7782. Inherited Create(outStream);
  7783. F_tagged := True;
  7784. F_isExplicit := isExplicit;
  7785. F_tagNo := tagNo;
  7786. end;
  7787. class procedure TDerGenerator.WriteDerEncoded(const outStream: TStream;
  7788. tag: Int32; const bytes: TCryptoLibByteArray);
  7789. begin
  7790. outStream.WriteByte(Byte(tag));
  7791. WriteLength(outStream, System.length(bytes));
  7792. outStream.Write(bytes[0], System.length(bytes));
  7793. end;
  7794. procedure TDerGenerator.WriteDerEncoded(tag: Int32;
  7795. const bytes: TCryptoLibByteArray);
  7796. var
  7797. tagNum, newTag: Int32;
  7798. bOut: TMemoryStream;
  7799. temp: TCryptoLibByteArray;
  7800. begin
  7801. if (F_tagged) then
  7802. begin
  7803. tagNum := F_tagNo or TAsn1Tags.Tagged;
  7804. if (F_isExplicit) then
  7805. begin
  7806. newTag := F_tagNo or TAsn1Tags.Constructed or TAsn1Tags.Tagged;
  7807. bOut := TMemoryStream.Create();
  7808. try
  7809. WriteDerEncoded(bOut, tag, bytes);
  7810. bOut.Position := 0;
  7811. System.SetLength(temp, bOut.Size);
  7812. bOut.Read(temp[0], bOut.Size);
  7813. WriteDerEncoded(&Out, newTag, temp);
  7814. finally
  7815. bOut.Free;
  7816. end;
  7817. end
  7818. else
  7819. begin
  7820. if ((tag and TAsn1Tags.Constructed) <> 0) then
  7821. begin
  7822. tagNum := tagNum or TAsn1Tags.Constructed;
  7823. end;
  7824. WriteDerEncoded(&Out, tagNum, bytes);
  7825. end;
  7826. end
  7827. else
  7828. begin
  7829. WriteDerEncoded(&Out, tag, bytes);
  7830. end;
  7831. end;
  7832. class procedure TDerGenerator.WriteDerEncoded(const outStr: TStream; tag: Int32;
  7833. const inStr: TStream);
  7834. begin
  7835. WriteDerEncoded(outStr, tag, TStreamUtils.ReadAll(inStr));
  7836. end;
  7837. class procedure TDerGenerator.WriteLength(const outStr: TStream; length: Int32);
  7838. var
  7839. Size, val, I: Int32;
  7840. begin
  7841. if (length > 127) then
  7842. begin
  7843. Size := 1;
  7844. val := length;
  7845. val := TBits.Asr32(val, 8);
  7846. while (val <> 0) do
  7847. begin
  7848. System.Inc(Size);
  7849. val := TBits.Asr32(val, 8);
  7850. end;
  7851. outStr.WriteByte(Byte(Size or $80));
  7852. I := (Size - 1) * 8;
  7853. while I >= 0 do
  7854. begin
  7855. outStr.WriteByte(Byte(TBits.Asr32(length, I)));
  7856. System.Dec(I, 8);
  7857. end;
  7858. end
  7859. else
  7860. begin
  7861. outStr.WriteByte(Byte(length));
  7862. end;
  7863. end;
  7864. { TDerIA5String }
  7865. function TDerIA5String.GetStr: String;
  7866. begin
  7867. result := FStr;
  7868. end;
  7869. function TDerIA5String.GetOctets: TCryptoLibByteArray;
  7870. begin
  7871. result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
  7872. end;
  7873. class function TDerIA5String.IsIA5String(const Str: String): Boolean;
  7874. var
  7875. ch: Char;
  7876. begin
  7877. for ch in Str do
  7878. begin
  7879. if (Ord(ch) > $007F) then
  7880. begin
  7881. result := False;
  7882. Exit;
  7883. end;
  7884. end;
  7885. result := True;
  7886. end;
  7887. function TDerIA5String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7888. var
  7889. other: IDerIA5String;
  7890. begin
  7891. if (not Supports(asn1Object, IDerIA5String, other)) then
  7892. begin
  7893. result := False;
  7894. Exit;
  7895. end;
  7896. result := Str = other.Str;
  7897. end;
  7898. function TDerIA5String.Asn1GetHashCode: Int32;
  7899. begin
  7900. result := TStringUtils.GetStringHashCode(FStr);
  7901. end;
  7902. constructor TDerIA5String.Create(const Str: TCryptoLibByteArray);
  7903. begin
  7904. Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII), False);
  7905. end;
  7906. constructor TDerIA5String.Create(const Str: String);
  7907. begin
  7908. Create(Str, False);
  7909. end;
  7910. constructor TDerIA5String.Create(const Str: String; validate: Boolean);
  7911. begin
  7912. Inherited Create();
  7913. if (Str = '') then
  7914. begin
  7915. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  7916. end;
  7917. if (validate and (not IsIA5String(Str))) then
  7918. begin
  7919. raise EArgumentCryptoLibException.CreateRes(@SIllegalCharacters);
  7920. end;
  7921. FStr := Str;
  7922. end;
  7923. procedure TDerIA5String.Encode(const derOut: TStream);
  7924. begin
  7925. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.IA5String, GetOctets());
  7926. end;
  7927. class function TDerIA5String.GetInstance(const obj: TObject): IDerIA5String;
  7928. begin
  7929. if ((obj = Nil) or (obj is TDerIA5String)) then
  7930. begin
  7931. result := obj as TDerIA5String;
  7932. Exit;
  7933. end;
  7934. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  7935. [obj.ClassName]);
  7936. end;
  7937. class function TDerIA5String.GetInstance(const obj: IAsn1TaggedObject;
  7938. isExplicit: Boolean): IDerIA5String;
  7939. var
  7940. o: IAsn1Object;
  7941. begin
  7942. o := obj.GetObject();
  7943. if ((isExplicit) or (Supports(o, IDerIA5String))) then
  7944. begin
  7945. result := GetInstance(o as TAsn1Object);
  7946. Exit;
  7947. end;
  7948. result := TDerIA5String.Create(TAsn1OctetString.GetInstance(o as TAsn1Object)
  7949. .GetOctets());
  7950. end;
  7951. function TDerIA5String.GetString: String;
  7952. begin
  7953. result := Str;
  7954. end;
  7955. { TDerNumericString }
  7956. function TDerNumericString.GetStr: String;
  7957. begin
  7958. result := FStr;
  7959. end;
  7960. function TDerNumericString.GetOctets: TCryptoLibByteArray;
  7961. begin
  7962. result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
  7963. end;
  7964. class function TDerNumericString.IsNumericString(const Str: String): Boolean;
  7965. var
  7966. ch: Char;
  7967. begin
  7968. for ch in Str do
  7969. begin
  7970. // char.IsDigit(ch)
  7971. if ((Ord(ch) > $007F) or ((ch <> ' ') and (not CharInSet(ch, ['0' .. '9']))))
  7972. then
  7973. begin
  7974. result := False;
  7975. Exit;
  7976. end;
  7977. end;
  7978. result := True;
  7979. end;
  7980. function TDerNumericString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  7981. var
  7982. other: IDerNumericString;
  7983. begin
  7984. if (not Supports(asn1Object, IDerNumericString, other)) then
  7985. begin
  7986. result := False;
  7987. Exit;
  7988. end;
  7989. result := Str = other.Str;
  7990. end;
  7991. constructor TDerNumericString.Create(const Str: TCryptoLibByteArray);
  7992. begin
  7993. Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII), False);
  7994. end;
  7995. constructor TDerNumericString.Create(const Str: String);
  7996. begin
  7997. Create(Str, False);
  7998. end;
  7999. constructor TDerNumericString.Create(const Str: String; validate: Boolean);
  8000. begin
  8001. Inherited Create();
  8002. if (Str = '') then
  8003. begin
  8004. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8005. end;
  8006. if (validate and (not IsNumericString(Str))) then
  8007. begin
  8008. raise EArgumentCryptoLibException.CreateRes(@SIllegalCharacters);
  8009. end;
  8010. FStr := Str;
  8011. end;
  8012. procedure TDerNumericString.Encode(const derOut: TStream);
  8013. begin
  8014. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.NumericString,
  8015. GetOctets());
  8016. end;
  8017. class function TDerNumericString.GetInstance(const obj: TObject)
  8018. : IDerNumericString;
  8019. begin
  8020. if ((obj = Nil) or (obj is TDerNumericString)) then
  8021. begin
  8022. result := obj as TDerNumericString;
  8023. Exit;
  8024. end;
  8025. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8026. [obj.ClassName]);
  8027. end;
  8028. class function TDerNumericString.GetInstance(const obj: IAsn1TaggedObject;
  8029. isExplicit: Boolean): IDerNumericString;
  8030. var
  8031. o: IAsn1Object;
  8032. begin
  8033. o := obj.GetObject();
  8034. if ((isExplicit) or (Supports(o, IDerNumericString))) then
  8035. begin
  8036. result := GetInstance(o as TAsn1Object);
  8037. Exit;
  8038. end;
  8039. result := TDerNumericString.Create
  8040. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  8041. end;
  8042. function TDerNumericString.GetString: String;
  8043. begin
  8044. result := Str;
  8045. end;
  8046. { TDerPrintableString }
  8047. function TDerPrintableString.GetStr: String;
  8048. begin
  8049. result := FStr;
  8050. end;
  8051. function TDerPrintableString.GetString: String;
  8052. begin
  8053. result := Str;
  8054. end;
  8055. function TDerPrintableString.GetOctets: TCryptoLibByteArray;
  8056. begin
  8057. result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
  8058. end;
  8059. class function TDerPrintableString.IsPrintableString(const Str: String)
  8060. : Boolean;
  8061. var
  8062. ch: Char;
  8063. begin
  8064. for ch in Str do
  8065. begin
  8066. if ((Ord(ch) > $007F)) then
  8067. begin
  8068. result := False;
  8069. Exit;
  8070. end;
  8071. // if (char.IsLetterOrDigit(ch))
  8072. if CharInSet(ch, ['a' .. 'z', 'A' .. 'Z', '0' .. '9']) then
  8073. begin
  8074. continue;
  8075. end;
  8076. case IndexStr(UnicodeString(ch), [''' ''', '\', '(', ')', '+', '-', '.',
  8077. ':', '=', '?', '/', ',']) of
  8078. 0 .. 11:
  8079. begin
  8080. continue;
  8081. end;
  8082. end;
  8083. result := False;
  8084. Exit;
  8085. end;
  8086. result := True;
  8087. end;
  8088. function TDerPrintableString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8089. var
  8090. other: IDerPrintableString;
  8091. begin
  8092. if (not Supports(asn1Object, IDerPrintableString, other)) then
  8093. begin
  8094. result := False;
  8095. Exit;
  8096. end;
  8097. result := Str = other.Str;
  8098. end;
  8099. constructor TDerPrintableString.Create(const Str: TCryptoLibByteArray);
  8100. begin
  8101. Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII), False);
  8102. end;
  8103. constructor TDerPrintableString.Create(const Str: String);
  8104. begin
  8105. Create(Str, False);
  8106. end;
  8107. constructor TDerPrintableString.Create(const Str: String; validate: Boolean);
  8108. begin
  8109. Inherited Create();
  8110. if (Str = '') then
  8111. begin
  8112. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8113. end;
  8114. if (validate and (not IsPrintableString(Str))) then
  8115. begin
  8116. raise EArgumentCryptoLibException.CreateRes(@SIllegalCharacters);
  8117. end;
  8118. FStr := Str;
  8119. end;
  8120. procedure TDerPrintableString.Encode(const derOut: TStream);
  8121. begin
  8122. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.PrintableString,
  8123. GetOctets());
  8124. end;
  8125. class function TDerPrintableString.GetInstance(const obj: TObject)
  8126. : IDerPrintableString;
  8127. begin
  8128. if ((obj = Nil) or (obj is TDerPrintableString)) then
  8129. begin
  8130. result := obj as TDerPrintableString;
  8131. Exit;
  8132. end;
  8133. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8134. [obj.ClassName]);
  8135. end;
  8136. class function TDerPrintableString.GetInstance(const obj: IAsn1TaggedObject;
  8137. isExplicit: Boolean): IDerPrintableString;
  8138. var
  8139. o: IAsn1Object;
  8140. begin
  8141. o := obj.GetObject();
  8142. if ((isExplicit) or (Supports(o, IDerPrintableString))) then
  8143. begin
  8144. result := GetInstance(o as TAsn1Object);
  8145. Exit;
  8146. end;
  8147. result := TDerPrintableString.Create
  8148. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  8149. end;
  8150. { TDerSequenceGenerator }
  8151. procedure TDerSequenceGenerator.AddObject(const obj: IAsn1Encodable);
  8152. var
  8153. temp: TDerOutputStream;
  8154. begin
  8155. temp := TDerOutputStream.Create(F_bOut);
  8156. try
  8157. temp.WriteObject(obj);
  8158. finally
  8159. temp.Free;
  8160. end;
  8161. end;
  8162. procedure TDerSequenceGenerator.Close;
  8163. var
  8164. temp: TCryptoLibByteArray;
  8165. begin
  8166. F_bOut.Position := 0;
  8167. System.SetLength(temp, F_bOut.Size);
  8168. F_bOut.Read(temp[0], F_bOut.Size);
  8169. WriteDerEncoded(TAsn1Tags.Constructed or TAsn1Tags.Sequence, temp);
  8170. end;
  8171. constructor TDerSequenceGenerator.Create(outStream: TStream);
  8172. begin
  8173. Inherited Create(outStream);
  8174. F_bOut := TMemoryStream.Create();
  8175. end;
  8176. constructor TDerSequenceGenerator.Create(outStream: TStream; tagNo: Int32;
  8177. isExplicit: Boolean);
  8178. begin
  8179. Inherited Create(outStream, tagNo, isExplicit);
  8180. F_bOut := TMemoryStream.Create();
  8181. end;
  8182. destructor TDerSequenceGenerator.Destroy;
  8183. begin
  8184. F_bOut.Free;
  8185. inherited Destroy;
  8186. end;
  8187. function TDerSequenceGenerator.GetRawOutputStream: TStream;
  8188. begin
  8189. result := F_bOut;
  8190. end;
  8191. { TDerT61String }
  8192. class function TDerT61String.GetEncoding: TEncoding;
  8193. begin
  8194. result := TEncoding.GetEncoding('iso-8859-1');
  8195. end;
  8196. function TDerT61String.GetStr: String;
  8197. begin
  8198. result := FStr;
  8199. end;
  8200. function TDerT61String.GetOctets: TCryptoLibByteArray;
  8201. var
  8202. LEncoding: TEncoding;
  8203. begin
  8204. LEncoding := TDerT61String.GetEncoding();
  8205. try
  8206. result := TConverters.ConvertStringToBytes(Str, LEncoding);
  8207. finally
  8208. LEncoding.Free;
  8209. end;
  8210. end;
  8211. function TDerT61String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8212. var
  8213. other: IDerT61String;
  8214. begin
  8215. if (not Supports(asn1Object, IDerT61String, other)) then
  8216. begin
  8217. result := False;
  8218. Exit;
  8219. end;
  8220. result := Str = other.Str;
  8221. end;
  8222. constructor TDerT61String.Create(const Str: TCryptoLibByteArray);
  8223. var
  8224. LEncoding: TEncoding;
  8225. begin
  8226. Inherited Create();
  8227. LEncoding := TDerT61String.GetEncoding();
  8228. try
  8229. Create(TConverters.ConvertBytesToString(Str, LEncoding));
  8230. finally
  8231. LEncoding.Free;
  8232. end;
  8233. end;
  8234. constructor TDerT61String.Create(const Str: String);
  8235. begin
  8236. Inherited Create();
  8237. if (Str = '') then
  8238. begin
  8239. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8240. end;
  8241. FStr := Str;
  8242. end;
  8243. procedure TDerT61String.Encode(const derOut: TStream);
  8244. begin
  8245. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.T61String, GetOctets());
  8246. end;
  8247. class function TDerT61String.GetInstance(const obj: TObject): IDerT61String;
  8248. begin
  8249. if ((obj = Nil) or (obj is TDerT61String)) then
  8250. begin
  8251. result := obj as TDerT61String;
  8252. Exit;
  8253. end;
  8254. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8255. [obj.ClassName]);
  8256. end;
  8257. class function TDerT61String.GetInstance(const obj: IAsn1TaggedObject;
  8258. isExplicit: Boolean): IDerT61String;
  8259. var
  8260. o: IAsn1Object;
  8261. begin
  8262. o := obj.GetObject();
  8263. if ((isExplicit) or (Supports(o, IDerT61String))) then
  8264. begin
  8265. result := GetInstance(o as TAsn1Object);
  8266. Exit;
  8267. end;
  8268. result := TDerT61String.Create(TAsn1OctetString.GetInstance(o as TAsn1Object)
  8269. .GetOctets());
  8270. end;
  8271. function TDerT61String.GetString: String;
  8272. begin
  8273. result := Str;
  8274. end;
  8275. { TDerUniversalString }
  8276. function TDerUniversalString.GetStr: TCryptoLibByteArray;
  8277. begin
  8278. result := FStr;
  8279. end;
  8280. function TDerUniversalString.GetOctets: TCryptoLibByteArray;
  8281. begin
  8282. result := System.Copy(Str);
  8283. end;
  8284. function TDerUniversalString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8285. var
  8286. other: IDerUniversalString;
  8287. begin
  8288. if (not Supports(asn1Object, IDerUniversalString, other)) then
  8289. begin
  8290. result := False;
  8291. Exit;
  8292. end;
  8293. result := TArrayUtils.AreEqual(Str, other.Str);
  8294. end;
  8295. constructor TDerUniversalString.Create(const Str: TCryptoLibByteArray);
  8296. begin
  8297. Inherited Create();
  8298. if (Str = Nil) then
  8299. begin
  8300. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8301. end;
  8302. FStr := Str;
  8303. end;
  8304. procedure TDerUniversalString.Encode(const derOut: TStream);
  8305. begin
  8306. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.UniversalString, Str);
  8307. end;
  8308. class function TDerUniversalString.GetInstance(const obj: TObject)
  8309. : IDerUniversalString;
  8310. begin
  8311. if ((obj = Nil) or (obj is TDerUniversalString)) then
  8312. begin
  8313. result := obj as TDerUniversalString;
  8314. Exit;
  8315. end;
  8316. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8317. [obj.ClassName]);
  8318. end;
  8319. class function TDerUniversalString.GetInstance(const obj: IAsn1TaggedObject;
  8320. isExplicit: Boolean): IDerUniversalString;
  8321. var
  8322. o: IAsn1Object;
  8323. begin
  8324. o := obj.GetObject();
  8325. if ((isExplicit) or (Supports(o, IDerUniversalString))) then
  8326. begin
  8327. result := GetInstance(o as TAsn1Object);
  8328. Exit;
  8329. end;
  8330. result := TDerUniversalString.Create
  8331. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  8332. end;
  8333. function TDerUniversalString.GetString: String;
  8334. var
  8335. buffer: TStringList;
  8336. I: Int32;
  8337. enc: TCryptoLibByteArray;
  8338. ubyte: UInt32;
  8339. begin
  8340. buffer := TStringList.Create();
  8341. buffer.LineBreak := '';
  8342. enc := GetDerEncoded();
  8343. buffer.Add('#');
  8344. I := 0;
  8345. try
  8346. while I <> System.length(enc) do
  8347. begin
  8348. ubyte := enc[I];
  8349. buffer.Add(FTable[(ubyte shr 4) and $F]);
  8350. buffer.Add(FTable[enc[I] and $F]);
  8351. System.Inc(I);
  8352. end;
  8353. result := buffer.Text;
  8354. finally
  8355. buffer.Free;
  8356. end;
  8357. end;
  8358. { TDerUtf8String }
  8359. function TDerUtf8String.GetStr: String;
  8360. begin
  8361. result := FStr;
  8362. end;
  8363. function TDerUtf8String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8364. var
  8365. other: IDerUtf8String;
  8366. begin
  8367. if (not Supports(asn1Object, IDerUtf8String, other)) then
  8368. begin
  8369. result := False;
  8370. Exit;
  8371. end;
  8372. result := Str = other.Str;
  8373. end;
  8374. constructor TDerUtf8String.Create(const Str: TCryptoLibByteArray);
  8375. begin
  8376. Create(TConverters.ConvertBytesToString(Str, TEncoding.UTF8));
  8377. end;
  8378. constructor TDerUtf8String.Create(const Str: String);
  8379. begin
  8380. Inherited Create();
  8381. if (Str = '') then
  8382. begin
  8383. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8384. end;
  8385. FStr := Str;
  8386. end;
  8387. procedure TDerUtf8String.Encode(const derOut: TStream);
  8388. begin
  8389. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Utf8String,
  8390. TConverters.ConvertStringToBytes(Str, TEncoding.UTF8));
  8391. end;
  8392. class function TDerUtf8String.GetInstance(const obj: TObject): IDerUtf8String;
  8393. begin
  8394. if ((obj = Nil) or (obj is TDerUtf8String)) then
  8395. begin
  8396. result := obj as TDerUtf8String;
  8397. Exit;
  8398. end;
  8399. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8400. [obj.ClassName]);
  8401. end;
  8402. class function TDerUtf8String.GetInstance(const obj: IAsn1TaggedObject;
  8403. isExplicit: Boolean): IDerUtf8String;
  8404. var
  8405. o: IAsn1Object;
  8406. begin
  8407. o := obj.GetObject();
  8408. if ((isExplicit) or (Supports(o, IDerUtf8String))) then
  8409. begin
  8410. result := GetInstance(o as TAsn1Object);
  8411. Exit;
  8412. end;
  8413. result := TDerUtf8String.Create(TAsn1OctetString.GetInstance(o as TAsn1Object)
  8414. .GetOctets());
  8415. end;
  8416. function TDerUtf8String.GetString: String;
  8417. begin
  8418. result := Str;
  8419. end;
  8420. { TDerVideotexString }
  8421. function TDerVideotexString.GetmString: TCryptoLibByteArray;
  8422. begin
  8423. result := FmString;
  8424. end;
  8425. function TDerVideotexString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8426. var
  8427. other: IDerVideotexString;
  8428. begin
  8429. if (not Supports(asn1Object, IDerVideotexString, other)) then
  8430. begin
  8431. result := False;
  8432. Exit;
  8433. end;
  8434. result := TArrayUtils.AreEqual(mString, other.mString);
  8435. end;
  8436. function TDerVideotexString.Asn1GetHashCode: Int32;
  8437. begin
  8438. result := TArrayUtils.GetArrayHashCode(mString);
  8439. end;
  8440. constructor TDerVideotexString.Create(const encoding: TCryptoLibByteArray);
  8441. begin
  8442. Inherited Create();
  8443. FmString := System.Copy(encoding);
  8444. end;
  8445. procedure TDerVideotexString.Encode(const derOut: TStream);
  8446. begin
  8447. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.VideotexString, mString);
  8448. end;
  8449. class function TDerVideotexString.GetInstance(const obj: TObject)
  8450. : IDerVideotexString;
  8451. begin
  8452. if ((obj = Nil) or (obj is TDerVideotexString)) then
  8453. begin
  8454. result := obj as TDerVideotexString;
  8455. Exit;
  8456. end;
  8457. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8458. [obj.ClassName]);
  8459. end;
  8460. class function TDerVideotexString.GetInstance(const obj: IAsn1TaggedObject;
  8461. isExplicit: Boolean): IDerVideotexString;
  8462. var
  8463. o: IAsn1Object;
  8464. begin
  8465. o := obj.GetObject();
  8466. if ((isExplicit) or (Supports(o, IDerVideotexString))) then
  8467. begin
  8468. result := GetInstance(o as TAsn1Object);
  8469. Exit;
  8470. end;
  8471. result := TDerVideotexString.Create
  8472. (TAsn1OctetString.GetInstance(o as TAsn1Object).GetOctets());
  8473. end;
  8474. class function TDerVideotexString.GetInstance(const obj: TCryptoLibByteArray)
  8475. : IDerVideotexString;
  8476. begin
  8477. try
  8478. result := FromByteArray(obj) as IDerVideotexString;
  8479. except
  8480. on e: Exception do
  8481. begin
  8482. raise EArgumentCryptoLibException.CreateResFmt(@SEncodingError,
  8483. [e.Message]);
  8484. end;
  8485. end;
  8486. end;
  8487. function TDerVideotexString.GetOctets: TCryptoLibByteArray;
  8488. begin
  8489. result := System.Copy(mString);
  8490. end;
  8491. function TDerVideotexString.GetString: String;
  8492. begin
  8493. result := TConverters.ConvertBytesToString(mString, TEncoding.ANSI)
  8494. end;
  8495. { TDerVisibleString }
  8496. function TDerVisibleString.GetStr: String;
  8497. begin
  8498. result := FStr;
  8499. end;
  8500. function TDerVisibleString.GetOctets: TCryptoLibByteArray;
  8501. begin
  8502. result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
  8503. end;
  8504. function TDerVisibleString.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
  8505. var
  8506. other: IDerVisibleString;
  8507. begin
  8508. if (not Supports(asn1Object, IDerVisibleString, other)) then
  8509. begin
  8510. result := False;
  8511. Exit;
  8512. end;
  8513. result := Str = other.Str;
  8514. end;
  8515. function TDerVisibleString.Asn1GetHashCode: Int32;
  8516. begin
  8517. result := TStringUtils.GetStringHashCode(FStr);
  8518. end;
  8519. constructor TDerVisibleString.Create(const Str: TCryptoLibByteArray);
  8520. begin
  8521. Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII));
  8522. end;
  8523. constructor TDerVisibleString.Create(const Str: String);
  8524. begin
  8525. Inherited Create();
  8526. if (Str = '') then
  8527. begin
  8528. raise EArgumentNilCryptoLibException.CreateRes(@SStrNil);
  8529. end;
  8530. FStr := Str;
  8531. end;
  8532. procedure TDerVisibleString.Encode(const derOut: TStream);
  8533. begin
  8534. (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.VisibleString,
  8535. GetOctets());
  8536. end;
  8537. class function TDerVisibleString.GetInstance(const obj: TObject)
  8538. : IDerVisibleString;
  8539. var
  8540. asn1OctetString: IAsn1OctetString;
  8541. asn1TaggedObject: IAsn1TaggedObject;
  8542. begin
  8543. if ((obj = Nil) or (obj is TDerVisibleString)) then
  8544. begin
  8545. result := obj as TDerVisibleString;
  8546. Exit;
  8547. end;
  8548. if Supports(obj, IAsn1OctetString, asn1OctetString) then
  8549. begin
  8550. result := TDerVisibleString.Create(asn1OctetString.GetOctets());
  8551. Exit;
  8552. end;
  8553. if Supports(obj, IAsn1TaggedObject, asn1TaggedObject) then
  8554. begin
  8555. result := GetInstance(asn1TaggedObject.GetObject() as TAsn1Object);
  8556. Exit;
  8557. end;
  8558. raise EArgumentCryptoLibException.CreateResFmt(@SIllegalObject,
  8559. [obj.ClassName]);
  8560. end;
  8561. {$IFNDEF _FIXINSIGHT_}
  8562. class function TDerVisibleString.GetInstance(const obj: IAsn1TaggedObject;
  8563. isExplicit: Boolean): IDerVisibleString;
  8564. begin
  8565. result := GetInstance(obj.GetObject() as TAsn1Object);
  8566. end;
  8567. {$ENDIF}
  8568. function TDerVisibleString.GetString: String;
  8569. begin
  8570. result := Str;
  8571. end;
  8572. end.