core.py 147 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099
  1. # coding: utf-8
  2. """
  3. ASN.1 type classes for universal types. Exports the following items:
  4. - load()
  5. - Any()
  6. - Asn1Value()
  7. - BitString()
  8. - BMPString()
  9. - Boolean()
  10. - CharacterString()
  11. - Choice()
  12. - EmbeddedPdv()
  13. - Enumerated()
  14. - GeneralizedTime()
  15. - GeneralString()
  16. - GraphicString()
  17. - IA5String()
  18. - InstanceOf()
  19. - Integer()
  20. - IntegerBitString()
  21. - IntegerOctetString()
  22. - Null()
  23. - NumericString()
  24. - ObjectDescriptor()
  25. - ObjectIdentifier()
  26. - OctetBitString()
  27. - OctetString()
  28. - PrintableString()
  29. - Real()
  30. - RelativeOid()
  31. - Sequence()
  32. - SequenceOf()
  33. - Set()
  34. - SetOf()
  35. - TeletexString()
  36. - UniversalString()
  37. - UTCTime()
  38. - UTF8String()
  39. - VideotexString()
  40. - VisibleString()
  41. - VOID
  42. - Void()
  43. Other type classes are defined that help compose the types listed above.
  44. """
  45. from __future__ import unicode_literals, division, absolute_import, print_function
  46. from datetime import datetime, timedelta
  47. import binascii
  48. import copy
  49. import math
  50. import re
  51. import sys
  52. from . import _teletex_codec
  53. from ._errors import unwrap
  54. from ._ordereddict import OrderedDict
  55. from ._types import type_name, str_cls, byte_cls, int_types, chr_cls
  56. from .parser import _parse, _dump_header
  57. from .util import int_to_bytes, int_from_bytes, timezone, extended_datetime
  58. if sys.version_info <= (3,):
  59. from cStringIO import StringIO as BytesIO
  60. range = xrange # noqa
  61. _PY2 = True
  62. else:
  63. from io import BytesIO
  64. _PY2 = False
  65. _teletex_codec.register()
  66. CLASS_NUM_TO_NAME_MAP = {
  67. 0: 'universal',
  68. 1: 'application',
  69. 2: 'context',
  70. 3: 'private',
  71. }
  72. CLASS_NAME_TO_NUM_MAP = {
  73. 'universal': 0,
  74. 'application': 1,
  75. 'context': 2,
  76. 'private': 3,
  77. 0: 0,
  78. 1: 1,
  79. 2: 2,
  80. 3: 3,
  81. }
  82. METHOD_NUM_TO_NAME_MAP = {
  83. 0: 'primitive',
  84. 1: 'constructed',
  85. }
  86. _OID_RE = re.compile('^\d+(\.\d+)*$')
  87. # A global tracker to ensure that _setup() is called for every class, even
  88. # if is has been called for a parent class. This allows different _fields
  89. # definitions for child classes. Without such a construct, the child classes
  90. # would just see the parent class attributes and would use them.
  91. _SETUP_CLASSES = {}
  92. def load(encoded_data, strict=False):
  93. """
  94. Loads a BER/DER-encoded byte string and construct a universal object based
  95. on the tag value:
  96. - 1: Boolean
  97. - 2: Integer
  98. - 3: BitString
  99. - 4: OctetString
  100. - 5: Null
  101. - 6: ObjectIdentifier
  102. - 7: ObjectDescriptor
  103. - 8: InstanceOf
  104. - 9: Real
  105. - 10: Enumerated
  106. - 11: EmbeddedPdv
  107. - 12: UTF8String
  108. - 13: RelativeOid
  109. - 16: Sequence,
  110. - 17: Set
  111. - 18: NumericString
  112. - 19: PrintableString
  113. - 20: TeletexString
  114. - 21: VideotexString
  115. - 22: IA5String
  116. - 23: UTCTime
  117. - 24: GeneralizedTime
  118. - 25: GraphicString
  119. - 26: VisibleString
  120. - 27: GeneralString
  121. - 28: UniversalString
  122. - 29: CharacterString
  123. - 30: BMPString
  124. :param encoded_data:
  125. A byte string of BER or DER-encoded data
  126. :param strict:
  127. A boolean indicating if trailing data should be forbidden - if so, a
  128. ValueError will be raised when trailing data exists
  129. :raises:
  130. ValueError - when strict is True and trailing data is present
  131. ValueError - when the encoded value tag a tag other than listed above
  132. ValueError - when the ASN.1 header length is longer than the data
  133. TypeError - when encoded_data is not a byte string
  134. :return:
  135. An instance of the one of the universal classes
  136. """
  137. return Asn1Value.load(encoded_data, strict=strict)
  138. class Asn1Value(object):
  139. """
  140. The basis of all ASN.1 values
  141. """
  142. # The integer 0 for primitive, 1 for constructed
  143. method = None
  144. # An integer 0 through 3 - see CLASS_NUM_TO_NAME_MAP for value
  145. class_ = None
  146. # An integer 1 or greater indicating the tag number
  147. tag = None
  148. # An alternate tag allowed for this type - used for handling broken
  149. # structures where a string value is encoded using an incorrect tag
  150. _bad_tag = None
  151. # A unicode string or None - "explicit" or "implicit" for
  152. # tagged values, None for normal
  153. tag_type = None
  154. # If "explicit"ly tagged, the class and tag for the wrapped header
  155. explicit_class = None
  156. explicit_tag = None
  157. # The BER/DER header bytes
  158. _header = None
  159. # Raw encoded value bytes not including class, method, tag, length header
  160. contents = None
  161. # The BER/DER trailer bytes
  162. _trailer = b''
  163. # The native python representation of the value - this is not used by
  164. # some classes since they utilize _bytes or _unicode
  165. _native = None
  166. @classmethod
  167. def load(cls, encoded_data, strict=False, **kwargs):
  168. """
  169. Loads a BER/DER-encoded byte string using the current class as the spec
  170. :param encoded_data:
  171. A byte string of BER or DER-encoded data
  172. :param strict:
  173. A boolean indicating if trailing data should be forbidden - if so, a
  174. ValueError will be raised when trailing data exists
  175. :return:
  176. An instance of the current class
  177. """
  178. if not isinstance(encoded_data, byte_cls):
  179. raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
  180. spec = None
  181. if cls.tag is not None:
  182. spec = cls
  183. value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict)
  184. return value
  185. def __init__(self, tag_type=None, class_=None, tag=None, optional=None, default=None, contents=None):
  186. """
  187. The optional parameter is not used, but rather included so we don't
  188. have to delete it from the parameter dictionary when passing as keyword
  189. args
  190. :param tag_type:
  191. None for normal values, or one of "implicit", "explicit" for tagged
  192. values
  193. :param class_:
  194. The class for the value - defaults to "universal" if tag_type is
  195. None, otherwise defaults to "context". Valid values include:
  196. - "universal"
  197. - "application"
  198. - "context"
  199. - "private"
  200. :param tag:
  201. The integer tag to override - usually this is used with tag_type or
  202. class_
  203. :param optional:
  204. Dummy parameter that allows "optional" key in spec param dicts
  205. :param default:
  206. The default value to use if the value is currently None
  207. :param contents:
  208. A byte string of the encoded contents of the value
  209. :raises:
  210. ValueError - when tag_type, class_ or tag are invalid values
  211. """
  212. try:
  213. if self.__class__ not in _SETUP_CLASSES:
  214. cls = self.__class__
  215. if hasattr(cls, '_setup'):
  216. self._setup()
  217. _SETUP_CLASSES[cls] = True
  218. if tag_type is not None:
  219. if tag_type not in ('implicit', 'explicit'):
  220. raise ValueError(unwrap(
  221. '''
  222. tag_type must be one of "implicit", "explicit", not %s
  223. ''',
  224. repr(tag_type)
  225. ))
  226. self.tag_type = tag_type
  227. if class_ is None:
  228. class_ = 'context'
  229. if class_ not in CLASS_NAME_TO_NUM_MAP:
  230. raise ValueError(unwrap(
  231. '''
  232. class_ must be one of "universal", "application",
  233. "context", "private", not %s
  234. ''',
  235. repr(class_)
  236. ))
  237. class_ = CLASS_NAME_TO_NUM_MAP[class_]
  238. if tag is not None:
  239. if not isinstance(tag, int_types):
  240. raise TypeError(unwrap(
  241. '''
  242. tag must be an integer, not %s
  243. ''',
  244. type_name(tag)
  245. ))
  246. if tag_type == 'implicit':
  247. self.class_ = class_
  248. self.tag = tag
  249. else:
  250. self.explicit_class = class_
  251. self.explicit_tag = tag
  252. else:
  253. if class_ is not None:
  254. if class_ not in CLASS_NUM_TO_NAME_MAP:
  255. raise ValueError(unwrap(
  256. '''
  257. class_ must be one of "universal", "application",
  258. "context", "private", not %s
  259. ''',
  260. repr(class_)
  261. ))
  262. self.class_ = CLASS_NAME_TO_NUM_MAP[class_]
  263. if tag is not None:
  264. self.tag = tag
  265. if contents is not None:
  266. self.contents = contents
  267. elif default is not None:
  268. self.set(default)
  269. except (ValueError, TypeError) as e:
  270. args = e.args[1:]
  271. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  272. raise e
  273. def __str__(self):
  274. """
  275. Since str is differnt in Python 2 and 3, this calls the appropriate
  276. method, __unicode__() or __bytes__()
  277. :return:
  278. A unicode string
  279. """
  280. if _PY2:
  281. return self.__bytes__()
  282. else:
  283. return self.__unicode__()
  284. def __repr__(self):
  285. """
  286. :return:
  287. A unicode string
  288. """
  289. if _PY2:
  290. return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump()))
  291. else:
  292. return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
  293. def __bytes__(self):
  294. """
  295. A fall-back method for print() in Python 2
  296. :return:
  297. A byte string of the output of repr()
  298. """
  299. return self.__repr__().encode('utf-8')
  300. def __unicode__(self):
  301. """
  302. A fall-back method for print() in Python 3
  303. :return:
  304. A unicode string of the output of repr()
  305. """
  306. return self.__repr__()
  307. def _new_instance(self):
  308. """
  309. Constructs a new copy of the current object, preserving any tagging
  310. :return:
  311. An Asn1Value object
  312. """
  313. new_obj = self.__class__()
  314. new_obj.tag_type = self.tag_type
  315. new_obj.class_ = self.class_
  316. new_obj.tag = self.tag
  317. new_obj.explicit_class = self.explicit_class
  318. new_obj.explicit_tag = self.explicit_tag
  319. return new_obj
  320. def __copy__(self):
  321. """
  322. Implements the copy.copy() interface
  323. :return:
  324. A new shallow copy of the current Asn1Value object
  325. """
  326. new_obj = self._new_instance()
  327. new_obj._copy(self, copy.copy)
  328. return new_obj
  329. def __deepcopy__(self, memo):
  330. """
  331. Implements the copy.deepcopy() interface
  332. :param memo:
  333. A dict for memoization
  334. :return:
  335. A new deep copy of the current Asn1Value object
  336. """
  337. new_obj = self._new_instance()
  338. memo[id(self)] = new_obj
  339. new_obj._copy(self, copy.deepcopy)
  340. return new_obj
  341. def copy(self):
  342. """
  343. Copies the object, preserving any special tagging from it
  344. :return:
  345. An Asn1Value object
  346. """
  347. return copy.deepcopy(self)
  348. def retag(self, tag_type, tag):
  349. """
  350. Copies the object, applying a new tagging to it
  351. :param tag_type:
  352. A unicode string of "implicit" or "explicit"
  353. :param tag:
  354. A integer tag number
  355. :return:
  356. An Asn1Value object
  357. """
  358. new_obj = self.__class__(tag_type=tag_type, tag=tag)
  359. new_obj._copy(self, copy.deepcopy)
  360. return new_obj
  361. def untag(self):
  362. """
  363. Copies the object, removing any special tagging from it
  364. :return:
  365. An Asn1Value object
  366. """
  367. new_obj = self.__class__()
  368. new_obj._copy(self, copy.deepcopy)
  369. return new_obj
  370. def _copy(self, other, copy_func):
  371. """
  372. Copies the contents of another Asn1Value object to itself
  373. :param object:
  374. Another instance of the same class
  375. :param copy_func:
  376. An reference of copy.copy() or copy.deepcopy() to use when copying
  377. lists, dicts and objects
  378. """
  379. if self.__class__ != other.__class__:
  380. raise TypeError(unwrap(
  381. '''
  382. Can not copy values from %s object to %s object
  383. ''',
  384. type_name(other),
  385. type_name(self)
  386. ))
  387. self.contents = other.contents
  388. self._native = copy_func(other._native)
  389. def debug(self, nest_level=1):
  390. """
  391. Show the binary data and parsed data in a tree structure
  392. """
  393. prefix = ' ' * nest_level
  394. # This interacts with Any and moves the tag, tag_type, _header, contents, _footer
  395. # to the parsed value so duplicate data isn't present
  396. has_parsed = hasattr(self, 'parsed')
  397. _basic_debug(prefix, self)
  398. if has_parsed:
  399. self.parsed.debug(nest_level + 2)
  400. elif hasattr(self, 'chosen'):
  401. self.chosen.debug(nest_level + 2)
  402. else:
  403. if _PY2 and isinstance(self.native, byte_cls):
  404. print('%s Native: b%s' % (prefix, repr(self.native)))
  405. else:
  406. print('%s Native: %s' % (prefix, self.native))
  407. def dump(self, force=False):
  408. """
  409. Encodes the value using DER
  410. :param force:
  411. If the encoded contents already exist, clear them and regenerate
  412. to ensure they are in DER format instead of BER format
  413. :return:
  414. A byte string of the DER-encoded value
  415. """
  416. contents = self.contents
  417. if self._header is None or force:
  418. if isinstance(self, Constructable) and self._indefinite:
  419. self.method = 0
  420. header = _dump_header(self.class_, self.method, self.tag, self.contents)
  421. trailer = b''
  422. if self.tag_type == 'explicit':
  423. container = Asn1Value()
  424. container.method = 1
  425. container.class_ = self.explicit_class
  426. container.tag = self.explicit_tag
  427. container.contents = header + self.contents + trailer
  428. # Force the container to generate the header and footer
  429. container.dump()
  430. header = container._header + header
  431. trailer += container._trailer
  432. self._header = header
  433. self._trailer = trailer
  434. return self._header + contents + self._trailer
  435. class ValueMap():
  436. """
  437. Basic functionality that allows for mapping values from ints or OIDs to
  438. python unicode strings
  439. """
  440. # A dict from primitive value (int or OID) to unicode string. This needs
  441. # to be defined in the source code
  442. _map = None
  443. # A dict from unicode string to int/OID. This is automatically generated
  444. # from _map the first time it is needed
  445. _reverse_map = None
  446. def _setup(self):
  447. """
  448. Generates _reverse_map from _map
  449. """
  450. cls = self.__class__
  451. if cls._map is None or cls._reverse_map is not None:
  452. return
  453. cls._reverse_map = {}
  454. for key, value in cls._map.items():
  455. cls._reverse_map[value] = key
  456. class Castable(object):
  457. """
  458. A mixin to handle converting an object between different classes that
  459. represent the same encoded value, but with different rules for converting
  460. to and from native Python values
  461. """
  462. def cast(self, other_class):
  463. """
  464. Converts the current object into an object of a different class. The
  465. new class must use the ASN.1 encoding for the value.
  466. :param other_class:
  467. The class to instantiate the new object from
  468. :return:
  469. An instance of the type other_class
  470. """
  471. if other_class.tag != self.__class__.tag:
  472. raise TypeError(unwrap(
  473. '''
  474. Can not covert a value from %s object to %s object since they
  475. use different tags: %d versus %d
  476. ''',
  477. type_name(other_class),
  478. type_name(self),
  479. other_class.tag,
  480. self.__class__.tag
  481. ))
  482. new_obj = other_class()
  483. new_obj.tag_type = self.tag_type
  484. new_obj.class_ = self.class_
  485. new_obj.explicit_class = self.explicit_class
  486. new_obj.explicit_tag = self.explicit_tag
  487. new_obj._header = self._header
  488. new_obj.contents = self.contents
  489. new_obj._trailer = self._trailer
  490. if isinstance(self, Constructable):
  491. new_obj.method = self.method
  492. new_obj._indefinite = self._indefinite
  493. return new_obj
  494. class Constructable(object):
  495. """
  496. A mixin to handle string types that may be constructed from chunks
  497. contained within an indefinite length BER-encoded container
  498. """
  499. # Instance attribute indicating if an object was indefinite
  500. # length when parsed – affects parsing and dumping
  501. _indefinite = False
  502. # Class attribute that indicates the offset into self.contents
  503. # that contains the chunks of data to merge
  504. _chunks_offset = 0
  505. def _merge_chunks(self):
  506. """
  507. :return:
  508. A concatenation of the native values of the contained chunks
  509. """
  510. if not self._indefinite:
  511. return self._as_chunk()
  512. pointer = self._chunks_offset
  513. contents_len = len(self.contents)
  514. output = None
  515. while pointer < contents_len:
  516. # We pass the current class as the spec so content semantics are preserved
  517. sub_value, pointer = _parse_build(self.contents, pointer, spec=self.__class__)
  518. if output is None:
  519. output = sub_value._merge_chunks()
  520. else:
  521. output += sub_value._merge_chunks()
  522. if output is None:
  523. return self._as_chunk()
  524. return output
  525. def _as_chunk(self):
  526. """
  527. A method to return a chunk of data that can be combined for
  528. constructed method values
  529. :return:
  530. A native Python value that can be added together. Examples include
  531. byte strings, unicode strings or tuples.
  532. """
  533. if self._chunks_offset == 0:
  534. return self.contents
  535. return self.contents[self._chunks_offset:]
  536. def _copy(self, other, copy_func):
  537. """
  538. Copies the contents of another Constructable object to itself
  539. :param object:
  540. Another instance of the same class
  541. :param copy_func:
  542. An reference of copy.copy() or copy.deepcopy() to use when copying
  543. lists, dicts and objects
  544. """
  545. super(Constructable, self)._copy(other, copy_func)
  546. self.method = other.method
  547. self._indefinite = other._indefinite
  548. class Void(Asn1Value):
  549. """
  550. A representation of an optional value that is not present. Has .native
  551. property and .dump() method to be compatible with other value classes.
  552. """
  553. contents = b''
  554. def __eq__(self, other):
  555. """
  556. :param other:
  557. The other Primitive to compare to
  558. :return:
  559. A boolean
  560. """
  561. return other.__class__ == self.__class__
  562. def __nonzero__(self):
  563. return False
  564. def __len__(self):
  565. return 0
  566. def __iter__(self):
  567. return iter(())
  568. @property
  569. def native(self):
  570. """
  571. The a native Python datatype representation of this value
  572. :return:
  573. None
  574. """
  575. return None
  576. def dump(self, force=False):
  577. """
  578. Encodes the value using DER
  579. :param force:
  580. If the encoded contents already exist, clear them and regenerate
  581. to ensure they are in DER format instead of BER format
  582. :return:
  583. A byte string of the DER-encoded value
  584. """
  585. return b''
  586. VOID = Void()
  587. class Any(Asn1Value):
  588. """
  589. A value class that can contain any value, and allows for easy parsing of
  590. the underlying encoded value using a spec. This is normally contained in
  591. a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs
  592. defined.
  593. """
  594. # The parsed value object
  595. _parsed = None
  596. def __init__(self, value=None, **kwargs):
  597. """
  598. Sets the value of the object before passing to Asn1Value.__init__()
  599. :param value:
  600. An Asn1Value object that will be set as the parsed value
  601. """
  602. Asn1Value.__init__(self, **kwargs)
  603. try:
  604. if value is not None:
  605. if not isinstance(value, Asn1Value):
  606. raise TypeError(unwrap(
  607. '''
  608. value must be an instance of Ans1Value, not %s
  609. ''',
  610. type_name(value)
  611. ))
  612. self._parsed = (value, value.__class__, None)
  613. self.contents = value.dump()
  614. except (ValueError, TypeError) as e:
  615. args = e.args[1:]
  616. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  617. raise e
  618. @property
  619. def native(self):
  620. """
  621. The a native Python datatype representation of this value
  622. :return:
  623. The .native value from the parsed value object
  624. """
  625. if self._parsed is None:
  626. self.parse()
  627. return self._parsed[0].native
  628. @property
  629. def parsed(self):
  630. """
  631. Returns the parsed object from .parse()
  632. :return:
  633. The object returned by .parse()
  634. """
  635. if self._parsed is None:
  636. self.parse()
  637. return self._parsed[0]
  638. def parse(self, spec=None, spec_params=None):
  639. """
  640. Parses the contents generically, or using a spec with optional params
  641. :param spec:
  642. A class derived from Asn1Value that defines what class_ and tag the
  643. value should have, and the semantics of the encoded value. The
  644. return value will be of this type. If omitted, the encoded value
  645. will be decoded using the standard universal tag based on the
  646. encoded tag number.
  647. :param spec_params:
  648. A dict of params to pass to the spec object
  649. :return:
  650. An object of the type spec, or if not present, a child of Asn1Value
  651. """
  652. if self._parsed is None or self._parsed[1:3] != (spec, spec_params):
  653. try:
  654. passed_params = spec_params
  655. if self.tag_type == 'explicit':
  656. passed_params = {} if not spec_params else spec_params.copy()
  657. passed_params['tag_type'] = self.tag_type
  658. passed_params['tag'] = self.explicit_tag
  659. contents = self._header + self.contents + self._trailer
  660. parsed_value, _ = _parse_build(
  661. contents,
  662. spec=spec,
  663. spec_params=passed_params
  664. )
  665. self._parsed = (parsed_value, spec, spec_params)
  666. # Once we've parsed the Any value, clear any attributes from this object
  667. # since they are now duplicate
  668. self.tag_type = None
  669. self.tag = None
  670. self._header = b''
  671. self.contents = contents
  672. self._trailer = b''
  673. except (ValueError, TypeError) as e:
  674. args = e.args[1:]
  675. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  676. raise e
  677. return self._parsed[0]
  678. def _copy(self, other, copy_func):
  679. """
  680. Copies the contents of another Any object to itself
  681. :param object:
  682. Another instance of the same class
  683. :param copy_func:
  684. An reference of copy.copy() or copy.deepcopy() to use when copying
  685. lists, dicts and objects
  686. """
  687. super(Any, self)._copy(other, copy_func)
  688. self._parsed = copy_func(other._parsed)
  689. def dump(self, force=False):
  690. """
  691. Encodes the value using DER
  692. :param force:
  693. If the encoded contents already exist, clear them and regenerate
  694. to ensure they are in DER format instead of BER format
  695. :return:
  696. A byte string of the DER-encoded value
  697. """
  698. if self._parsed is None:
  699. self.parse()
  700. return self._parsed[0].dump(force=force)
  701. class Choice(Asn1Value):
  702. """
  703. A class to handle when a value may be one of several options
  704. """
  705. # The index in _alternatives of the validated alternative
  706. _choice = None
  707. # The name of the chosen alternative
  708. _name = None
  709. # The Asn1Value object for the chosen alternative
  710. _parsed = None
  711. # A list of tuples in one of the following forms.
  712. #
  713. # Option 1, a unicode string field name and a value class
  714. #
  715. # ("name", Asn1ValueClass)
  716. #
  717. # Option 2, same as Option 1, but with a dict of class params
  718. #
  719. # ("name", Asn1ValueClass, {'tag_type': 'explicit', 'tag': 5})
  720. _alternatives = None
  721. # A dict that maps tuples of (class_, tag) to an index in _alternatives
  722. _id_map = None
  723. # A dict that maps alternative names to an index in _alternatives
  724. _name_map = None
  725. @classmethod
  726. def load(cls, encoded_data, strict=False, **kwargs):
  727. """
  728. Loads a BER/DER-encoded byte string using the current class as the spec
  729. :param encoded_data:
  730. A byte string of BER or DER encoded data
  731. :param strict:
  732. A boolean indicating if trailing data should be forbidden - if so, a
  733. ValueError will be raised when trailing data exists
  734. :return:
  735. A instance of the current class
  736. """
  737. if not isinstance(encoded_data, byte_cls):
  738. raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
  739. value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict)
  740. return value
  741. def _setup(self):
  742. """
  743. Generates _id_map from _alternatives to allow validating contents
  744. """
  745. cls = self.__class__
  746. cls._id_map = {}
  747. cls._name_map = {}
  748. for index, info in enumerate(cls._alternatives):
  749. if len(info) < 3:
  750. info = info + ({},)
  751. cls._alternatives[index] = info
  752. id_ = _build_id_tuple(info[2], info[1])
  753. cls._id_map[id_] = index
  754. cls._name_map[info[0]] = index
  755. def __init__(self, name=None, value=None, tag_type=None, **kwargs):
  756. """
  757. Checks to ensure implicit tagging is not being used since it is
  758. incompatible with Choice, then forwards on to Asn1Value.__init__()
  759. :param name:
  760. The name of the alternative to be set - used with value.
  761. Alternatively this may be a dict with a single key being the name
  762. and the value being the value, or a two-element tuple of the the
  763. name and the value.
  764. :param value:
  765. The alternative value to set - used with name
  766. :param tag_type:
  767. The tag_type of the value - None, "implicit" or "explicit"
  768. :raises:
  769. ValueError - when tag_type is "implicit"
  770. """
  771. kwargs['tag_type'] = tag_type
  772. Asn1Value.__init__(self, **kwargs)
  773. try:
  774. if tag_type == 'implicit':
  775. raise ValueError(unwrap(
  776. '''
  777. The Choice type can not be implicitly tagged even if in an
  778. implicit module - due to its nature any tagging must be
  779. explicit
  780. '''
  781. ))
  782. if name is not None:
  783. if isinstance(name, dict):
  784. if len(name) != 1:
  785. raise ValueError(unwrap(
  786. '''
  787. When passing a dict as the "name" argument to %s,
  788. it must have a single key/value - however %d were
  789. present
  790. ''',
  791. type_name(self),
  792. len(name)
  793. ))
  794. name, value = list(name.items())[0]
  795. if isinstance(name, tuple):
  796. if len(name) != 2:
  797. raise ValueError(unwrap(
  798. '''
  799. When passing a tuple as the "name" argument to %s,
  800. it must have two elements, the name and value -
  801. however %d were present
  802. ''',
  803. type_name(self),
  804. len(name)
  805. ))
  806. value = name[1]
  807. name = name[0]
  808. if name not in self._name_map:
  809. raise ValueError(unwrap(
  810. '''
  811. The name specified, "%s", is not a valid alternative
  812. for %s
  813. ''',
  814. name,
  815. type_name(self)
  816. ))
  817. self._choice = self._name_map[name]
  818. _, spec, params = self._alternatives[self._choice]
  819. if not isinstance(value, spec):
  820. value = spec(value, **params)
  821. else:
  822. value = _fix_tagging(value, params)
  823. self._parsed = value
  824. except (ValueError, TypeError) as e:
  825. args = e.args[1:]
  826. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  827. raise e
  828. @property
  829. def name(self):
  830. """
  831. :return:
  832. A unicode string of the field name of the chosen alternative
  833. """
  834. if not self._name:
  835. self._name = self._alternatives[self._choice][0]
  836. return self._name
  837. def parse(self):
  838. """
  839. Parses the detected alternative
  840. :return:
  841. An Asn1Value object of the chosen alternative
  842. """
  843. if self._parsed is not None:
  844. return self._parsed
  845. try:
  846. _, spec, params = self._alternatives[self._choice]
  847. self._parsed, _ = _parse_build(self.contents, spec=spec, spec_params=params)
  848. except (ValueError, TypeError) as e:
  849. args = e.args[1:]
  850. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  851. raise e
  852. @property
  853. def chosen(self):
  854. """
  855. :return:
  856. An Asn1Value object of the chosen alternative
  857. """
  858. return self.parse()
  859. @property
  860. def native(self):
  861. """
  862. The a native Python datatype representation of this value
  863. :return:
  864. The .native value from the contained value object
  865. """
  866. return self.chosen.native
  867. def validate(self, class_, tag, contents):
  868. """
  869. Ensures that the class and tag specified exist as an alternative
  870. :param class_:
  871. The integer class_ from the encoded value header
  872. :param tag:
  873. The integer tag from the encoded value header
  874. :param contents:
  875. A byte string of the contents of the value - used when the object
  876. is explicitly tagged
  877. :raises:
  878. ValueError - when value is not a valid alternative
  879. """
  880. id_ = (class_, tag)
  881. if self.tag_type == 'explicit':
  882. if (self.explicit_class, self.explicit_tag) != id_:
  883. raise ValueError(unwrap(
  884. '''
  885. %s was explicitly tagged, but the value provided does not
  886. match the class and tag
  887. ''',
  888. type_name(self)
  889. ))
  890. ((class_, _, tag, _, _, _), _) = _parse(contents, len(contents))
  891. id_ = (class_, tag)
  892. if id_ in self._id_map:
  893. self._choice = self._id_map[id_]
  894. return
  895. # This means the Choice was implicitly tagged
  896. if self.class_ is not None and self.tag is not None:
  897. if len(self._alternatives) > 1:
  898. raise ValueError(unwrap(
  899. '''
  900. %s was implicitly tagged, but more than one alternative
  901. exists
  902. ''',
  903. type_name(self)
  904. ))
  905. if id_ == (self.class_, self.tag):
  906. self._choice = 0
  907. return
  908. asn1 = self._format_class_tag(class_, tag)
  909. asn1s = [self._format_class_tag(pair[0], pair[1]) for pair in self._id_map]
  910. raise ValueError(unwrap(
  911. '''
  912. Value %s did not match the class and tag of any of the alternatives
  913. in %s: %s
  914. ''',
  915. asn1,
  916. type_name(self),
  917. ', '.join(asn1s)
  918. ))
  919. def _format_class_tag(self, class_, tag):
  920. """
  921. :return:
  922. A unicode string of a human-friendly representation of the class and tag
  923. """
  924. return '[%s %s]' % (CLASS_NUM_TO_NAME_MAP[class_].upper(), tag)
  925. def _copy(self, other, copy_func):
  926. """
  927. Copies the contents of another Choice object to itself
  928. :param object:
  929. Another instance of the same class
  930. :param copy_func:
  931. An reference of copy.copy() or copy.deepcopy() to use when copying
  932. lists, dicts and objects
  933. """
  934. super(Choice, self)._copy(other, copy_func)
  935. self._choice = other._choice
  936. self._name = other._name
  937. self._parsed = copy_func(other._parsed)
  938. def dump(self, force=False):
  939. """
  940. Encodes the value using DER
  941. :param force:
  942. If the encoded contents already exist, clear them and regenerate
  943. to ensure they are in DER format instead of BER format
  944. :return:
  945. A byte string of the DER-encoded value
  946. """
  947. self.contents = self.chosen.dump(force=force)
  948. if self._header is None or force:
  949. if self.tag_type == 'explicit':
  950. self._header = _dump_header(self.explicit_class, 1, self.explicit_tag, self.contents)
  951. else:
  952. self._header = b''
  953. return self._header + self.contents
  954. class Concat(object):
  955. """
  956. A class that contains two or more encoded child values concatentated
  957. together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle
  958. the x509.TrustedCertificate() class for OpenSSL certificates containing
  959. extra information.
  960. """
  961. # A list of the specs of the concatenated values
  962. _child_specs = None
  963. _children = None
  964. @classmethod
  965. def load(cls, encoded_data, strict=False):
  966. """
  967. Loads a BER/DER-encoded byte string using the current class as the spec
  968. :param encoded_data:
  969. A byte string of BER or DER encoded data
  970. :param strict:
  971. A boolean indicating if trailing data should be forbidden - if so, a
  972. ValueError will be raised when trailing data exists
  973. :return:
  974. A Concat object
  975. """
  976. return cls(contents=encoded_data, strict=strict)
  977. def __init__(self, value=None, contents=None, strict=False):
  978. """
  979. :param value:
  980. A native Python datatype to initialize the object value with
  981. :param contents:
  982. A byte string of the encoded contents of the value
  983. :param strict:
  984. A boolean indicating if trailing data should be forbidden - if so, a
  985. ValueError will be raised when trailing data exists in contents
  986. :raises:
  987. ValueError - when an error occurs with one of the children
  988. TypeError - when an error occurs with one of the children
  989. """
  990. if contents is not None:
  991. try:
  992. contents_len = len(contents)
  993. self._children = []
  994. offset = 0
  995. for spec in self._child_specs:
  996. if offset < contents_len:
  997. child_value, offset = _parse_build(contents, pointer=offset, spec=spec)
  998. else:
  999. child_value = spec()
  1000. self._children.append(child_value)
  1001. if strict and offset != contents_len:
  1002. extra_bytes = contents_len - offset
  1003. raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)
  1004. except (ValueError, TypeError) as e:
  1005. args = e.args[1:]
  1006. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  1007. raise e
  1008. if value is not None:
  1009. if self._children is None:
  1010. self._children = [None] * len(self._child_specs)
  1011. for index, data in enumerate(value):
  1012. self.__setitem__(index, data)
  1013. def __str__(self):
  1014. """
  1015. Since str is differnt in Python 2 and 3, this calls the appropriate
  1016. method, __unicode__() or __bytes__()
  1017. :return:
  1018. A unicode string
  1019. """
  1020. if _PY2:
  1021. return self.__bytes__()
  1022. else:
  1023. return self.__unicode__()
  1024. def __bytes__(self):
  1025. """
  1026. A byte string of the DER-encoded contents
  1027. """
  1028. return self.dump()
  1029. def __unicode__(self):
  1030. """
  1031. :return:
  1032. A unicode string
  1033. """
  1034. return repr(self)
  1035. def __repr__(self):
  1036. """
  1037. :return:
  1038. A unicode string
  1039. """
  1040. return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
  1041. def __copy__(self):
  1042. """
  1043. Implements the copy.copy() interface
  1044. :return:
  1045. A new shallow copy of the Concat object
  1046. """
  1047. new_obj = self.__class__()
  1048. new_obj._copy(self, copy.copy)
  1049. return new_obj
  1050. def __deepcopy__(self, memo):
  1051. """
  1052. Implements the copy.deepcopy() interface
  1053. :param memo:
  1054. A dict for memoization
  1055. :return:
  1056. A new deep copy of the Concat object and all child objects
  1057. """
  1058. new_obj = self.__class__()
  1059. memo[id(self)] = new_obj
  1060. new_obj._copy(self, copy.deepcopy)
  1061. return new_obj
  1062. def copy(self):
  1063. """
  1064. Copies the object
  1065. :return:
  1066. A Concat object
  1067. """
  1068. return copy.deepcopy(self)
  1069. def _copy(self, other, copy_func):
  1070. """
  1071. Copies the contents of another Concat object to itself
  1072. :param object:
  1073. Another instance of the same class
  1074. :param copy_func:
  1075. An reference of copy.copy() or copy.deepcopy() to use when copying
  1076. lists, dicts and objects
  1077. """
  1078. if self.__class__ != other.__class__:
  1079. raise TypeError(unwrap(
  1080. '''
  1081. Can not copy values from %s object to %s object
  1082. ''',
  1083. type_name(other),
  1084. type_name(self)
  1085. ))
  1086. self._children = copy_func(other._children)
  1087. def debug(self, nest_level=1):
  1088. """
  1089. Show the binary data and parsed data in a tree structure
  1090. """
  1091. prefix = ' ' * nest_level
  1092. print('%s%s Object #%s' % (prefix, type_name(self), id(self)))
  1093. print('%s Children:' % (prefix,))
  1094. for child in self._children:
  1095. child.debug(nest_level + 2)
  1096. def dump(self, force=False):
  1097. """
  1098. Encodes the value using DER
  1099. :param force:
  1100. If the encoded contents already exist, clear them and regenerate
  1101. to ensure they are in DER format instead of BER format
  1102. :return:
  1103. A byte string of the DER-encoded value
  1104. """
  1105. contents = b''
  1106. for child in self._children:
  1107. contents += child.dump(force=force)
  1108. return contents
  1109. @property
  1110. def contents(self):
  1111. """
  1112. :return:
  1113. A byte string of the DER-encoded contents of the children
  1114. """
  1115. return self.dump()
  1116. def __len__(self):
  1117. """
  1118. :return:
  1119. Integer
  1120. """
  1121. return len(self._children)
  1122. def __getitem__(self, key):
  1123. """
  1124. Allows accessing children by index
  1125. :param key:
  1126. An integer of the child index
  1127. :raises:
  1128. KeyError - when an index is invalid
  1129. :return:
  1130. The Asn1Value object of the child specified
  1131. """
  1132. if key > len(self._child_specs) - 1 or key < 0:
  1133. raise KeyError(unwrap(
  1134. '''
  1135. No child is definition for position %d of %s
  1136. ''',
  1137. key,
  1138. type_name(self)
  1139. ))
  1140. return self._children[key]
  1141. def __setitem__(self, key, value):
  1142. """
  1143. Allows settings children by index
  1144. :param key:
  1145. An integer of the child index
  1146. :param value:
  1147. An Asn1Value object to set the child to
  1148. :raises:
  1149. KeyError - when an index is invalid
  1150. ValueError - when the value is not an instance of Asn1Value
  1151. """
  1152. if key > len(self._child_specs) - 1 or key < 0:
  1153. raise KeyError(unwrap(
  1154. '''
  1155. No child is defined for position %d of %s
  1156. ''',
  1157. key,
  1158. type_name(self)
  1159. ))
  1160. if not isinstance(value, Asn1Value):
  1161. raise ValueError(unwrap(
  1162. '''
  1163. Value for child %s of %s is not an instance of
  1164. asn1crypto.core.Asn1Value
  1165. ''',
  1166. key,
  1167. type_name(self)
  1168. ))
  1169. self._children[key] = value
  1170. def __iter__(self):
  1171. """
  1172. :return:
  1173. An iterator of child values
  1174. """
  1175. return iter(self._children)
  1176. class Primitive(Asn1Value):
  1177. """
  1178. Sets the class_ and method attributes for primitive, universal values
  1179. """
  1180. class_ = 0
  1181. method = 0
  1182. def __init__(self, value=None, default=None, contents=None, **kwargs):
  1183. """
  1184. Sets the value of the object before passing to Asn1Value.__init__()
  1185. :param value:
  1186. A native Python datatype to initialize the object value with
  1187. :param default:
  1188. The default value if no value is specified
  1189. :param contents:
  1190. A byte string of the encoded contents of the value
  1191. """
  1192. Asn1Value.__init__(self, **kwargs)
  1193. try:
  1194. if contents is not None:
  1195. self.contents = contents
  1196. elif value is not None:
  1197. self.set(value)
  1198. elif default is not None:
  1199. self.set(default)
  1200. except (ValueError, TypeError) as e:
  1201. args = e.args[1:]
  1202. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  1203. raise e
  1204. def set(self, value):
  1205. """
  1206. Sets the value of the object
  1207. :param value:
  1208. A byte string
  1209. """
  1210. if not isinstance(value, byte_cls):
  1211. raise TypeError(unwrap(
  1212. '''
  1213. %s value must be a byte string, not %s
  1214. ''',
  1215. type_name(self),
  1216. type_name(value)
  1217. ))
  1218. self._native = value
  1219. self.contents = value
  1220. self._header = None
  1221. if self._trailer != b'':
  1222. self._trailer = b''
  1223. def dump(self, force=False):
  1224. """
  1225. Encodes the value using DER
  1226. :param force:
  1227. If the encoded contents already exist, clear them and regenerate
  1228. to ensure they are in DER format instead of BER format
  1229. :return:
  1230. A byte string of the DER-encoded value
  1231. """
  1232. if force:
  1233. native = self.native
  1234. self.contents = None
  1235. self.set(native)
  1236. return Asn1Value.dump(self)
  1237. def __ne__(self, other):
  1238. return not self == other
  1239. def __eq__(self, other):
  1240. """
  1241. :param other:
  1242. The other Primitive to compare to
  1243. :return:
  1244. A boolean
  1245. """
  1246. if not isinstance(other, Primitive):
  1247. return False
  1248. if self.contents != other.contents:
  1249. return False
  1250. # We compare class tag numbers since object tag numbers could be
  1251. # different due to implicit or explicit tagging
  1252. if self.__class__.tag != other.__class__.tag:
  1253. return False
  1254. if self.__class__ == other.__class__ and self.contents == other.contents:
  1255. return True
  1256. # If the objects share a common base class that is not too low-level
  1257. # then we can compare the contents
  1258. self_bases = (set(self.__class__.__bases__) | set([self.__class__])) - set([Asn1Value, Primitive, ValueMap])
  1259. other_bases = (set(other.__class__.__bases__) | set([other.__class__])) - set([Asn1Value, Primitive, ValueMap])
  1260. if self_bases | other_bases:
  1261. return self.contents == other.contents
  1262. # When tagging is going on, do the extra work of constructing new
  1263. # objects to see if the dumped representation are the same
  1264. if self.tag_type is not None or other.tag_type is not None:
  1265. return self.untag().dump() == other.untag().dump()
  1266. return self.dump() == other.dump()
  1267. class AbstractString(Constructable, Primitive):
  1268. """
  1269. A base class for all strings that have a known encoding. In general, we do
  1270. not worry ourselves with confirming that the decoded values match a specific
  1271. set of characters, only that they are decoded into a Python unicode string
  1272. """
  1273. # The Python encoding name to use when decoding or encoded the contents
  1274. _encoding = 'latin1'
  1275. # Instance attribute of (possibly-merged) unicode string
  1276. _unicode = None
  1277. def set(self, value):
  1278. """
  1279. Sets the value of the string
  1280. :param value:
  1281. A unicode string
  1282. """
  1283. if not isinstance(value, str_cls):
  1284. raise TypeError(unwrap(
  1285. '''
  1286. %s value must be a unicode string, not %s
  1287. ''',
  1288. type_name(self),
  1289. type_name(value)
  1290. ))
  1291. self._unicode = value
  1292. self.contents = value.encode(self._encoding)
  1293. self._header = None
  1294. if self._indefinite:
  1295. self._indefinite = False
  1296. self.method = 0
  1297. if self._trailer != b'':
  1298. self._trailer = b''
  1299. def __unicode__(self):
  1300. """
  1301. :return:
  1302. A unicode string
  1303. """
  1304. if self.contents is None:
  1305. return ''
  1306. if self._unicode is None:
  1307. self._unicode = self._merge_chunks().decode(self._encoding)
  1308. return self._unicode
  1309. def _copy(self, other, copy_func):
  1310. """
  1311. Copies the contents of another AbstractString object to itself
  1312. :param object:
  1313. Another instance of the same class
  1314. :param copy_func:
  1315. An reference of copy.copy() or copy.deepcopy() to use when copying
  1316. lists, dicts and objects
  1317. """
  1318. super(AbstractString, self)._copy(other, copy_func)
  1319. self._unicode = other._unicode
  1320. @property
  1321. def native(self):
  1322. """
  1323. The a native Python datatype representation of this value
  1324. :return:
  1325. A unicode string or None
  1326. """
  1327. if self.contents is None:
  1328. return None
  1329. return self.__unicode__()
  1330. class Boolean(Primitive):
  1331. """
  1332. Represents a boolean in both ASN.1 and Python
  1333. """
  1334. tag = 1
  1335. def set(self, value):
  1336. """
  1337. Sets the value of the object
  1338. :param value:
  1339. True, False or another value that works with bool()
  1340. """
  1341. self._native = bool(value)
  1342. self.contents = b'\x00' if not value else b'\xff'
  1343. self._header = None
  1344. if self._trailer != b'':
  1345. self._trailer = b''
  1346. # Python 2
  1347. def __nonzero__(self):
  1348. """
  1349. :return:
  1350. True or False
  1351. """
  1352. return self.__bool__()
  1353. def __bool__(self):
  1354. """
  1355. :return:
  1356. True or False
  1357. """
  1358. return self.contents != b'\x00'
  1359. @property
  1360. def native(self):
  1361. """
  1362. The a native Python datatype representation of this value
  1363. :return:
  1364. True, False or None
  1365. """
  1366. if self.contents is None:
  1367. return None
  1368. if self._native is None:
  1369. self._native = self.__bool__()
  1370. return self._native
  1371. class Integer(Primitive, ValueMap):
  1372. """
  1373. Represents an integer in both ASN.1 and Python
  1374. """
  1375. tag = 2
  1376. def set(self, value):
  1377. """
  1378. Sets the value of the object
  1379. :param value:
  1380. An integer, or a unicode string if _map is set
  1381. :raises:
  1382. ValueError - when an invalid value is passed
  1383. """
  1384. if isinstance(value, str_cls):
  1385. if self._map is None:
  1386. raise ValueError(unwrap(
  1387. '''
  1388. %s value is a unicode string, but no _map provided
  1389. ''',
  1390. type_name(self)
  1391. ))
  1392. if value not in self._reverse_map:
  1393. raise ValueError(unwrap(
  1394. '''
  1395. %s value, %s, is not present in the _map
  1396. ''',
  1397. type_name(self),
  1398. value
  1399. ))
  1400. value = self._reverse_map[value]
  1401. elif not isinstance(value, int_types):
  1402. raise TypeError(unwrap(
  1403. '''
  1404. %s value must be an integer or unicode string when a name_map
  1405. is provided, not %s
  1406. ''',
  1407. type_name(self),
  1408. type_name(value)
  1409. ))
  1410. self._native = self._map[value] if self._map and value in self._map else value
  1411. self.contents = int_to_bytes(value, signed=True)
  1412. self._header = None
  1413. if self._trailer != b'':
  1414. self._trailer = b''
  1415. def __int__(self):
  1416. """
  1417. :return:
  1418. An integer
  1419. """
  1420. return int_from_bytes(self.contents, signed=True)
  1421. @property
  1422. def native(self):
  1423. """
  1424. The a native Python datatype representation of this value
  1425. :return:
  1426. An integer or None
  1427. """
  1428. if self.contents is None:
  1429. return None
  1430. if self._native is None:
  1431. self._native = self.__int__()
  1432. if self._map is not None and self._native in self._map:
  1433. self._native = self._map[self._native]
  1434. return self._native
  1435. class BitString(Constructable, Castable, Primitive, ValueMap, object):
  1436. """
  1437. Represents a bit string from ASN.1 as a Python tuple of 1s and 0s
  1438. """
  1439. tag = 3
  1440. _size = None
  1441. # Used with _as_chunk() from Constructable
  1442. _chunk = None
  1443. _chunks_offset = 1
  1444. def _setup(self):
  1445. """
  1446. Generates _reverse_map from _map
  1447. """
  1448. ValueMap._setup(self)
  1449. cls = self.__class__
  1450. if cls._map is not None:
  1451. cls._size = max(self._map.keys()) + 1
  1452. def set(self, value):
  1453. """
  1454. Sets the value of the object
  1455. :param value:
  1456. An integer or a tuple of integers 0 and 1
  1457. :raises:
  1458. ValueError - when an invalid value is passed
  1459. """
  1460. if isinstance(value, set):
  1461. if self._map is None:
  1462. raise ValueError(unwrap(
  1463. '''
  1464. %s._map has not been defined
  1465. ''',
  1466. type_name(self)
  1467. ))
  1468. bits = [0] * self._size
  1469. self._native = value
  1470. for index in range(0, self._size):
  1471. key = self._map.get(index)
  1472. if key is None:
  1473. continue
  1474. if key in value:
  1475. bits[index] = 1
  1476. value = ''.join(map(str_cls, bits))
  1477. elif value.__class__ == tuple:
  1478. if self._map is None:
  1479. self._native = value
  1480. else:
  1481. self._native = set()
  1482. for index, bit in enumerate(value):
  1483. if bit:
  1484. name = self._map.get(index, index)
  1485. self._native.add(name)
  1486. value = ''.join(map(str_cls, value))
  1487. else:
  1488. raise TypeError(unwrap(
  1489. '''
  1490. %s value must be a tuple of ones and zeros or a set of unicode
  1491. strings, not %s
  1492. ''',
  1493. type_name(self),
  1494. type_name(value)
  1495. ))
  1496. self._chunk = None
  1497. if self._map is not None:
  1498. if len(value) > self._size:
  1499. raise ValueError(unwrap(
  1500. '''
  1501. %s value must be at most %s bits long, specified was %s long
  1502. ''',
  1503. type_name(self),
  1504. self._size,
  1505. len(value)
  1506. ))
  1507. # A NamedBitList must have trailing zero bit truncated. See
  1508. # https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  1509. # section 11.2,
  1510. # https://tools.ietf.org/html/rfc5280#page-134 and
  1511. # https://www.ietf.org/mail-archive/web/pkix/current/msg10443.html
  1512. value = value.rstrip('0')
  1513. size = len(value)
  1514. size_mod = size % 8
  1515. extra_bits = 0
  1516. if size_mod != 0:
  1517. extra_bits = 8 - size_mod
  1518. value += '0' * extra_bits
  1519. size_in_bytes = int(math.ceil(size / 8))
  1520. if extra_bits:
  1521. extra_bits_byte = int_to_bytes(extra_bits)
  1522. else:
  1523. extra_bits_byte = b'\x00'
  1524. if value == '':
  1525. value_bytes = b''
  1526. else:
  1527. value_bytes = int_to_bytes(int(value, 2))
  1528. if len(value_bytes) != size_in_bytes:
  1529. value_bytes = (b'\x00' * (size_in_bytes - len(value_bytes))) + value_bytes
  1530. self.contents = extra_bits_byte + value_bytes
  1531. self._header = None
  1532. if self._indefinite:
  1533. self._indefinite = False
  1534. self.method = 0
  1535. if self._trailer != b'':
  1536. self._trailer = b''
  1537. def __getitem__(self, key):
  1538. """
  1539. Retrieves a boolean version of one of the bits based on a name from the
  1540. _map
  1541. :param key:
  1542. The unicode string of one of the bit names
  1543. :raises:
  1544. ValueError - when _map is not set or the key name is invalid
  1545. :return:
  1546. A boolean if the bit is set
  1547. """
  1548. is_int = isinstance(key, int_types)
  1549. if not is_int:
  1550. if not isinstance(self._map, dict):
  1551. raise ValueError(unwrap(
  1552. '''
  1553. %s._map has not been defined
  1554. ''',
  1555. type_name(self)
  1556. ))
  1557. if key not in self._reverse_map:
  1558. raise ValueError(unwrap(
  1559. '''
  1560. %s._map does not contain an entry for "%s"
  1561. ''',
  1562. type_name(self),
  1563. key
  1564. ))
  1565. if self._native is None:
  1566. self.native
  1567. if self._map is None:
  1568. if len(self._native) >= key + 1:
  1569. return bool(self._native[key])
  1570. return False
  1571. if is_int:
  1572. key = self._map.get(key, key)
  1573. return key in self._native
  1574. def __setitem__(self, key, value):
  1575. """
  1576. Sets one of the bits based on a name from the _map
  1577. :param key:
  1578. The unicode string of one of the bit names
  1579. :param value:
  1580. A boolean value
  1581. :raises:
  1582. ValueError - when _map is not set or the key name is invalid
  1583. """
  1584. is_int = isinstance(key, int_types)
  1585. if not is_int:
  1586. if self._map is None:
  1587. raise ValueError(unwrap(
  1588. '''
  1589. %s._map has not been defined
  1590. ''',
  1591. type_name(self)
  1592. ))
  1593. if key not in self._reverse_map:
  1594. raise ValueError(unwrap(
  1595. '''
  1596. %s._map does not contain an entry for "%s"
  1597. ''',
  1598. type_name(self),
  1599. key
  1600. ))
  1601. if self._native is None:
  1602. self.native
  1603. if self._map is None:
  1604. new_native = list(self._native)
  1605. max_key = len(new_native) - 1
  1606. if key > max_key:
  1607. new_native.extend([0] * (key - max_key))
  1608. new_native[key] = 1 if value else 0
  1609. self._native = tuple(new_native)
  1610. else:
  1611. if is_int:
  1612. key = self._map.get(key, key)
  1613. if value:
  1614. if key not in self._native:
  1615. self._native.add(key)
  1616. else:
  1617. if key in self._native:
  1618. self._native.remove(key)
  1619. self.set(self._native)
  1620. def _as_chunk(self):
  1621. """
  1622. Allows reconstructing indefinite length values
  1623. :return:
  1624. A tuple of integers
  1625. """
  1626. extra_bits = int_from_bytes(self.contents[0:1])
  1627. bit_string = '{0:b}'.format(int_from_bytes(self.contents[1:]))
  1628. byte_len = len(self.contents[1:])
  1629. bit_len = len(bit_string)
  1630. # Left-pad the bit string to a byte multiple to ensure we didn't
  1631. # lose any zero bits on the left
  1632. mod_bit_len = bit_len % 8
  1633. if mod_bit_len != 0:
  1634. bit_string = ('0' * (8 - mod_bit_len)) + bit_string
  1635. bit_len = len(bit_string)
  1636. if bit_len // 8 < byte_len:
  1637. missing_bytes = byte_len - (bit_len // 8)
  1638. bit_string = ('0' * (8 * missing_bytes)) + bit_string
  1639. # Trim off the extra bits on the right used to fill the last byte
  1640. if extra_bits > 0:
  1641. bit_string = bit_string[0:0 - extra_bits]
  1642. return tuple(map(int, tuple(bit_string)))
  1643. @property
  1644. def native(self):
  1645. """
  1646. The a native Python datatype representation of this value
  1647. :return:
  1648. If a _map is set, a set of names, or if no _map is set, a tuple of
  1649. integers 1 and 0. None if no value.
  1650. """
  1651. # For BitString we default the value to be all zeros
  1652. if self.contents is None:
  1653. if self._map is None:
  1654. self.set(())
  1655. else:
  1656. self.set(set())
  1657. if self._native is None:
  1658. bits = self._merge_chunks()
  1659. if self._map:
  1660. self._native = set()
  1661. for index, bit in enumerate(bits):
  1662. if bit:
  1663. name = self._map.get(index, index)
  1664. self._native.add(name)
  1665. else:
  1666. self._native = bits
  1667. return self._native
  1668. class OctetBitString(Constructable, Castable, Primitive):
  1669. """
  1670. Represents a bit string in ASN.1 as a Python byte string
  1671. """
  1672. tag = 3
  1673. # Whenever dealing with octet-based bit strings, we really want the
  1674. # bytes, so we just ignore the unused bits portion since it isn't
  1675. # applicable to the current use case
  1676. # unused_bits = struct.unpack('>B', self.contents[0:1])[0]
  1677. _chunks_offset = 1
  1678. # Instance attribute of (possibly-merged) byte string
  1679. _bytes = None
  1680. def set(self, value):
  1681. """
  1682. Sets the value of the object
  1683. :param value:
  1684. A byte string
  1685. :raises:
  1686. ValueError - when an invalid value is passed
  1687. """
  1688. if not isinstance(value, byte_cls):
  1689. raise TypeError(unwrap(
  1690. '''
  1691. %s value must be a byte string, not %s
  1692. ''',
  1693. type_name(self),
  1694. type_name(value)
  1695. ))
  1696. self._bytes = value
  1697. # Set the unused bits to 0
  1698. self.contents = b'\x00' + value
  1699. self._header = None
  1700. if self._indefinite:
  1701. self._indefinite = False
  1702. self.method = 0
  1703. if self._trailer != b'':
  1704. self._trailer = b''
  1705. def __bytes__(self):
  1706. """
  1707. :return:
  1708. A byte string
  1709. """
  1710. if self.contents is None:
  1711. return b''
  1712. if self._bytes is None:
  1713. self._bytes = self._merge_chunks()
  1714. return self._bytes
  1715. def _copy(self, other, copy_func):
  1716. """
  1717. Copies the contents of another OctetBitString object to itself
  1718. :param object:
  1719. Another instance of the same class
  1720. :param copy_func:
  1721. An reference of copy.copy() or copy.deepcopy() to use when copying
  1722. lists, dicts and objects
  1723. """
  1724. super(OctetBitString, self)._copy(other, copy_func)
  1725. self._bytes = other._bytes
  1726. @property
  1727. def native(self):
  1728. """
  1729. The a native Python datatype representation of this value
  1730. :return:
  1731. A byte string or None
  1732. """
  1733. if self.contents is None:
  1734. return None
  1735. return self.__bytes__()
  1736. class IntegerBitString(Constructable, Castable, Primitive):
  1737. """
  1738. Represents a bit string in ASN.1 as a Python integer
  1739. """
  1740. tag = 3
  1741. _chunks_offset = 1
  1742. def set(self, value):
  1743. """
  1744. Sets the value of the object
  1745. :param value:
  1746. An integer
  1747. :raises:
  1748. ValueError - when an invalid value is passed
  1749. """
  1750. if not isinstance(value, int_types):
  1751. raise TypeError(unwrap(
  1752. '''
  1753. %s value must be an integer, not %s
  1754. ''',
  1755. type_name(self),
  1756. type_name(value)
  1757. ))
  1758. self._native = value
  1759. # Set the unused bits to 0
  1760. self.contents = b'\x00' + int_to_bytes(value, signed=True)
  1761. self._header = None
  1762. if self._indefinite:
  1763. self._indefinite = False
  1764. self.method = 0
  1765. if self._trailer != b'':
  1766. self._trailer = b''
  1767. def _as_chunk(self):
  1768. """
  1769. Allows reconstructing indefinite length values
  1770. :return:
  1771. A unicode string of bits – 1s and 0s
  1772. """
  1773. extra_bits = int_from_bytes(self.contents[0:1])
  1774. bit_string = '{0:b}'.format(int_from_bytes(self.contents[1:]))
  1775. # Ensure we have leading zeros since these chunks may be concatenated together
  1776. mod_bit_len = len(bit_string) % 8
  1777. if mod_bit_len != 0:
  1778. bit_string = ('0' * (8 - mod_bit_len)) + bit_string
  1779. if extra_bits > 0:
  1780. return bit_string[0:0 - extra_bits]
  1781. return bit_string
  1782. @property
  1783. def native(self):
  1784. """
  1785. The a native Python datatype representation of this value
  1786. :return:
  1787. An integer or None
  1788. """
  1789. if self.contents is None:
  1790. return None
  1791. if self._native is None:
  1792. extra_bits = int_from_bytes(self.contents[0:1])
  1793. # Fast path
  1794. if not self._indefinite and extra_bits == 0:
  1795. self._native = int_from_bytes(self.contents[1:])
  1796. else:
  1797. if self._indefinite and extra_bits > 0:
  1798. raise ValueError('Constructed bit string has extra bits on indefinite container')
  1799. self._native = int(self._merge_chunks(), 2)
  1800. return self._native
  1801. class OctetString(Constructable, Castable, Primitive):
  1802. """
  1803. Represents a byte string in both ASN.1 and Python
  1804. """
  1805. tag = 4
  1806. # Instance attribute of (possibly-merged) byte string
  1807. _bytes = None
  1808. def set(self, value):
  1809. """
  1810. Sets the value of the object
  1811. :param value:
  1812. A byte string
  1813. """
  1814. if not isinstance(value, byte_cls):
  1815. raise TypeError(unwrap(
  1816. '''
  1817. %s value must be a byte string, not %s
  1818. ''',
  1819. type_name(self),
  1820. type_name(value)
  1821. ))
  1822. self._bytes = value
  1823. self.contents = value
  1824. self._header = None
  1825. if self._indefinite:
  1826. self._indefinite = False
  1827. self.method = 0
  1828. if self._trailer != b'':
  1829. self._trailer = b''
  1830. def __bytes__(self):
  1831. """
  1832. :return:
  1833. A byte string
  1834. """
  1835. if self.contents is None:
  1836. return b''
  1837. if self._bytes is None:
  1838. self._bytes = self._merge_chunks()
  1839. return self._bytes
  1840. def _copy(self, other, copy_func):
  1841. """
  1842. Copies the contents of another OctetString object to itself
  1843. :param object:
  1844. Another instance of the same class
  1845. :param copy_func:
  1846. An reference of copy.copy() or copy.deepcopy() to use when copying
  1847. lists, dicts and objects
  1848. """
  1849. super(OctetString, self)._copy(other, copy_func)
  1850. self._bytes = other._bytes
  1851. @property
  1852. def native(self):
  1853. """
  1854. The a native Python datatype representation of this value
  1855. :return:
  1856. A byte string or None
  1857. """
  1858. if self.contents is None:
  1859. return None
  1860. return self.__bytes__()
  1861. class IntegerOctetString(Constructable, Castable, Primitive):
  1862. """
  1863. Represents a byte string in ASN.1 as a Python integer
  1864. """
  1865. tag = 4
  1866. def set(self, value):
  1867. """
  1868. Sets the value of the object
  1869. :param value:
  1870. An integer
  1871. :raises:
  1872. ValueError - when an invalid value is passed
  1873. """
  1874. if not isinstance(value, int_types):
  1875. raise TypeError(unwrap(
  1876. '''
  1877. %s value must be an integer, not %s
  1878. ''',
  1879. type_name(self),
  1880. type_name(value)
  1881. ))
  1882. self._native = value
  1883. self.contents = int_to_bytes(value, signed=False)
  1884. self._header = None
  1885. if self._indefinite:
  1886. self._indefinite = False
  1887. self.method = 0
  1888. if self._trailer != b'':
  1889. self._trailer = b''
  1890. @property
  1891. def native(self):
  1892. """
  1893. The a native Python datatype representation of this value
  1894. :return:
  1895. An integer or None
  1896. """
  1897. if self.contents is None:
  1898. return None
  1899. if self._native is None:
  1900. self._native = int_from_bytes(self._merge_chunks())
  1901. return self._native
  1902. class ParsableOctetString(Constructable, Castable, Primitive):
  1903. tag = 4
  1904. _parsed = None
  1905. # Instance attribute of (possibly-merged) byte string
  1906. _bytes = None
  1907. def __init__(self, value=None, parsed=None, **kwargs):
  1908. """
  1909. Allows providing a parsed object that will be serialized to get the
  1910. byte string value
  1911. :param value:
  1912. A native Python datatype to initialize the object value with
  1913. :param parsed:
  1914. If value is None and this is an Asn1Value object, this will be
  1915. set as the parsed value, and the value will be obtained by calling
  1916. .dump() on this object.
  1917. """
  1918. set_parsed = False
  1919. if value is None and parsed is not None and isinstance(parsed, Asn1Value):
  1920. value = parsed.dump()
  1921. set_parsed = True
  1922. Primitive.__init__(self, value=value, **kwargs)
  1923. if set_parsed:
  1924. self._parsed = (parsed, parsed.__class__, None)
  1925. def set(self, value):
  1926. """
  1927. Sets the value of the object
  1928. :param value:
  1929. A byte string
  1930. """
  1931. if not isinstance(value, byte_cls):
  1932. raise TypeError(unwrap(
  1933. '''
  1934. %s value must be a byte string, not %s
  1935. ''',
  1936. type_name(self),
  1937. type_name(value)
  1938. ))
  1939. self._bytes = value
  1940. self.contents = value
  1941. self._header = None
  1942. if self._indefinite:
  1943. self._indefinite = False
  1944. self.method = 0
  1945. if self._trailer != b'':
  1946. self._trailer = b''
  1947. def parse(self, spec=None, spec_params=None):
  1948. """
  1949. Parses the contents generically, or using a spec with optional params
  1950. :param spec:
  1951. A class derived from Asn1Value that defines what class_ and tag the
  1952. value should have, and the semantics of the encoded value. The
  1953. return value will be of this type. If omitted, the encoded value
  1954. will be decoded using the standard universal tag based on the
  1955. encoded tag number.
  1956. :param spec_params:
  1957. A dict of params to pass to the spec object
  1958. :return:
  1959. An object of the type spec, or if not present, a child of Asn1Value
  1960. """
  1961. if self._parsed is None or self._parsed[1:3] != (spec, spec_params):
  1962. parsed_value, _ = _parse_build(self.__bytes__(), spec=spec, spec_params=spec_params)
  1963. self._parsed = (parsed_value, spec, spec_params)
  1964. return self._parsed[0]
  1965. def __bytes__(self):
  1966. """
  1967. :return:
  1968. A byte string
  1969. """
  1970. if self.contents is None:
  1971. return b''
  1972. if self._bytes is None:
  1973. self._bytes = self._merge_chunks()
  1974. return self._bytes
  1975. def _copy(self, other, copy_func):
  1976. """
  1977. Copies the contents of another ParsableOctetString object to itself
  1978. :param object:
  1979. Another instance of the same class
  1980. :param copy_func:
  1981. An reference of copy.copy() or copy.deepcopy() to use when copying
  1982. lists, dicts and objects
  1983. """
  1984. super(ParsableOctetString, self)._copy(other, copy_func)
  1985. self._bytes = other._bytes
  1986. self._parsed = copy_func(other._parsed)
  1987. @property
  1988. def native(self):
  1989. """
  1990. The a native Python datatype representation of this value
  1991. :return:
  1992. A byte string or None
  1993. """
  1994. if self.contents is None:
  1995. return None
  1996. if self._parsed is not None:
  1997. return self._parsed[0].native
  1998. else:
  1999. return self.__bytes__()
  2000. @property
  2001. def parsed(self):
  2002. """
  2003. Returns the parsed object from .parse()
  2004. :return:
  2005. The object returned by .parse()
  2006. """
  2007. if self._parsed is None:
  2008. self.parse()
  2009. return self._parsed[0]
  2010. def dump(self, force=False):
  2011. """
  2012. Encodes the value using DER
  2013. :param force:
  2014. If the encoded contents already exist, clear them and regenerate
  2015. to ensure they are in DER format instead of BER format
  2016. :return:
  2017. A byte string of the DER-encoded value
  2018. """
  2019. if force:
  2020. if self._parsed is not None:
  2021. native = self.parsed.dump(force=force)
  2022. else:
  2023. native = self.native
  2024. self.contents = None
  2025. self.set(native)
  2026. return Asn1Value.dump(self)
  2027. class ParsableOctetBitString(ParsableOctetString):
  2028. tag = 3
  2029. # Whenever dealing with octet-based bit strings, we really want the
  2030. # bytes, so we just ignore the unused bits portion since it isn't
  2031. # applicable to the current use case
  2032. # unused_bits = struct.unpack('>B', self.contents[0:1])[0]
  2033. _chunks_offset = 1
  2034. def set(self, value):
  2035. """
  2036. Sets the value of the object
  2037. :param value:
  2038. A byte string
  2039. :raises:
  2040. ValueError - when an invalid value is passed
  2041. """
  2042. if not isinstance(value, byte_cls):
  2043. raise TypeError(unwrap(
  2044. '''
  2045. %s value must be a byte string, not %s
  2046. ''',
  2047. type_name(self),
  2048. type_name(value)
  2049. ))
  2050. self._bytes = value
  2051. # Set the unused bits to 0
  2052. self.contents = b'\x00' + value
  2053. self._header = None
  2054. if self._indefinite:
  2055. self._indefinite = False
  2056. self.method = 0
  2057. if self._trailer != b'':
  2058. self._trailer = b''
  2059. class Null(Primitive):
  2060. """
  2061. Represents a null value in ASN.1 as None in Python
  2062. """
  2063. tag = 5
  2064. contents = b''
  2065. def set(self, value):
  2066. """
  2067. Sets the value of the object
  2068. :param value:
  2069. None
  2070. """
  2071. self.contents = b''
  2072. @property
  2073. def native(self):
  2074. """
  2075. The a native Python datatype representation of this value
  2076. :return:
  2077. None
  2078. """
  2079. return None
  2080. class ObjectIdentifier(Primitive, ValueMap):
  2081. """
  2082. Represents an object identifier in ASN.1 as a Python unicode dotted
  2083. integer string
  2084. """
  2085. tag = 6
  2086. # A unicode string of the dotted form of the object identifier
  2087. _dotted = None
  2088. @classmethod
  2089. def map(cls, value):
  2090. """
  2091. Converts a dotted unicode string OID into a mapped unicode string
  2092. :param value:
  2093. A dotted unicode string OID
  2094. :raises:
  2095. ValueError - when no _map dict has been defined on the class
  2096. TypeError - when value is not a unicode string
  2097. :return:
  2098. A mapped unicode string
  2099. """
  2100. if cls._map is None:
  2101. raise ValueError(unwrap(
  2102. '''
  2103. %s._map has not been defined
  2104. ''',
  2105. type_name(cls)
  2106. ))
  2107. if not isinstance(value, str_cls):
  2108. raise TypeError(unwrap(
  2109. '''
  2110. value must be a unicode string, not %s
  2111. ''',
  2112. type_name(value)
  2113. ))
  2114. return cls._map.get(value, value)
  2115. @classmethod
  2116. def unmap(cls, value):
  2117. """
  2118. Converts a mapped unicode string value into a dotted unicode string OID
  2119. :param value:
  2120. A mapped unicode string OR dotted unicode string OID
  2121. :raises:
  2122. ValueError - when no _map dict has been defined on the class or the value can't be unmapped
  2123. TypeError - when value is not a unicode string
  2124. :return:
  2125. A dotted unicode string OID
  2126. """
  2127. if cls not in _SETUP_CLASSES:
  2128. cls()._setup()
  2129. _SETUP_CLASSES[cls] = True
  2130. if cls._map is None:
  2131. raise ValueError(unwrap(
  2132. '''
  2133. %s._map has not been defined
  2134. ''',
  2135. type_name(cls)
  2136. ))
  2137. if not isinstance(value, str_cls):
  2138. raise TypeError(unwrap(
  2139. '''
  2140. value must be a unicode string, not %s
  2141. ''',
  2142. type_name(value)
  2143. ))
  2144. if value in cls._reverse_map:
  2145. return cls._reverse_map[value]
  2146. if not _OID_RE.match(value):
  2147. raise ValueError(unwrap(
  2148. '''
  2149. %s._map does not contain an entry for "%s"
  2150. ''',
  2151. type_name(cls),
  2152. value
  2153. ))
  2154. return value
  2155. def set(self, value):
  2156. """
  2157. Sets the value of the object
  2158. :param value:
  2159. A unicode string. May be a dotted integer string, or if _map is
  2160. provided, one of the mapped values.
  2161. :raises:
  2162. ValueError - when an invalid value is passed
  2163. """
  2164. if not isinstance(value, str_cls):
  2165. raise TypeError(unwrap(
  2166. '''
  2167. %s value must be a unicode string, not %s
  2168. ''',
  2169. type_name(self),
  2170. type_name(value)
  2171. ))
  2172. self._native = value
  2173. if self._map is not None:
  2174. if value in self._reverse_map:
  2175. value = self._reverse_map[value]
  2176. self.contents = b''
  2177. first = None
  2178. for index, part in enumerate(value.split('.')):
  2179. part = int(part)
  2180. # The first two parts are merged into a single byte
  2181. if index == 0:
  2182. first = part
  2183. continue
  2184. elif index == 1:
  2185. part = (first * 40) + part
  2186. encoded_part = chr_cls(0x7F & part)
  2187. part = part >> 7
  2188. while part > 0:
  2189. encoded_part = chr_cls(0x80 | (0x7F & part)) + encoded_part
  2190. part = part >> 7
  2191. self.contents += encoded_part
  2192. self._header = None
  2193. if self._trailer != b'':
  2194. self._trailer = b''
  2195. def __unicode__(self):
  2196. """
  2197. :return:
  2198. A unicode string
  2199. """
  2200. return self.dotted
  2201. @property
  2202. def dotted(self):
  2203. """
  2204. :return:
  2205. A unicode string of the object identifier in dotted notation, thus
  2206. ignoring any mapped value
  2207. """
  2208. if self._dotted is None:
  2209. output = []
  2210. part = 0
  2211. for byte in self.contents:
  2212. if _PY2:
  2213. byte = ord(byte)
  2214. part = part * 128
  2215. part += byte & 127
  2216. # Last byte in subidentifier has the eighth bit set to 0
  2217. if byte & 0x80 == 0:
  2218. if len(output) == 0:
  2219. output.append(str_cls(part // 40))
  2220. output.append(str_cls(part % 40))
  2221. else:
  2222. output.append(str_cls(part))
  2223. part = 0
  2224. self._dotted = '.'.join(output)
  2225. return self._dotted
  2226. @property
  2227. def native(self):
  2228. """
  2229. The a native Python datatype representation of this value
  2230. :return:
  2231. A unicode string or None. If _map is not defined, the unicode string
  2232. is a string of dotted integers. If _map is defined and the dotted
  2233. string is present in the _map, the mapped value is returned.
  2234. """
  2235. if self.contents is None:
  2236. return None
  2237. if self._native is None:
  2238. self._native = self.dotted
  2239. if self._map is not None and self._native in self._map:
  2240. self._native = self._map[self._native]
  2241. return self._native
  2242. class ObjectDescriptor(Primitive):
  2243. """
  2244. Represents an object descriptor from ASN.1 - no Python implementation
  2245. """
  2246. tag = 7
  2247. class InstanceOf(Primitive):
  2248. """
  2249. Represents an instance from ASN.1 - no Python implementation
  2250. """
  2251. tag = 8
  2252. class Real(Primitive):
  2253. """
  2254. Represents a real number from ASN.1 - no Python implementation
  2255. """
  2256. tag = 9
  2257. class Enumerated(Integer):
  2258. """
  2259. Represents a enumerated list of integers from ASN.1 as a Python
  2260. unicode string
  2261. """
  2262. tag = 10
  2263. def set(self, value):
  2264. """
  2265. Sets the value of the object
  2266. :param value:
  2267. An integer or a unicode string from _map
  2268. :raises:
  2269. ValueError - when an invalid value is passed
  2270. """
  2271. if not isinstance(value, int_types) and not isinstance(value, str_cls):
  2272. raise TypeError(unwrap(
  2273. '''
  2274. %s value must be an integer or a unicode string, not %s
  2275. ''',
  2276. type_name(self),
  2277. type_name(value)
  2278. ))
  2279. if isinstance(value, str_cls):
  2280. if value not in self._reverse_map:
  2281. raise ValueError(unwrap(
  2282. '''
  2283. %s value "%s" is not a valid value
  2284. ''',
  2285. type_name(self),
  2286. value
  2287. ))
  2288. value = self._reverse_map[value]
  2289. elif value not in self._map:
  2290. raise ValueError(unwrap(
  2291. '''
  2292. %s value %s is not a valid value
  2293. ''',
  2294. type_name(self),
  2295. value
  2296. ))
  2297. Integer.set(self, value)
  2298. @property
  2299. def native(self):
  2300. """
  2301. The a native Python datatype representation of this value
  2302. :return:
  2303. A unicode string or None
  2304. """
  2305. if self.contents is None:
  2306. return None
  2307. if self._native is None:
  2308. self._native = self._map[self.__int__()]
  2309. return self._native
  2310. class UTF8String(AbstractString):
  2311. """
  2312. Represents a UTF-8 string from ASN.1 as a Python unicode string
  2313. """
  2314. tag = 12
  2315. _encoding = 'utf-8'
  2316. class RelativeOid(ObjectIdentifier):
  2317. """
  2318. Represents an object identifier in ASN.1 as a Python unicode dotted
  2319. integer string
  2320. """
  2321. tag = 13
  2322. class Sequence(Asn1Value):
  2323. """
  2324. Represents a sequence of fields from ASN.1 as a Python object with a
  2325. dict-like interface
  2326. """
  2327. tag = 16
  2328. class_ = 0
  2329. method = 1
  2330. # A list of child objects, in order of _fields
  2331. children = None
  2332. # Sequence overrides .contents to be a property so that the mutated state
  2333. # of child objects can be checked to ensure everything is up-to-date
  2334. _contents = None
  2335. # Variable to track if the object has been mutated
  2336. _mutated = False
  2337. # A list of tuples in one of the following forms.
  2338. #
  2339. # Option 1, a unicode string field name and a value class
  2340. #
  2341. # ("name", Asn1ValueClass)
  2342. #
  2343. # Option 2, same as Option 1, but with a dict of class params
  2344. #
  2345. # ("name", Asn1ValueClass, {'tag_type': 'explicit', 'tag': 5})
  2346. _fields = []
  2347. # A dict with keys being the name of a field and the value being a unicode
  2348. # string of the method name on self to call to get the spec for that field
  2349. _spec_callbacks = None
  2350. # A dict that maps unicode string field names to an index in _fields
  2351. _field_map = None
  2352. # A list in the same order as _fields that has tuples in the form (class_, tag)
  2353. _field_ids = None
  2354. # An optional 2-element tuple that defines the field names of an OID field
  2355. # and the field that the OID should be used to help decode. Works with the
  2356. # _oid_specs attribute.
  2357. _oid_pair = None
  2358. # A dict with keys that are unicode string OID values and values that are
  2359. # Asn1Value classes to use for decoding a variable-type field.
  2360. _oid_specs = None
  2361. # A 2-element tuple of the indexes in _fields of the OID and value fields
  2362. _oid_nums = None
  2363. # Predetermined field specs to optimize away calls to _determine_spec()
  2364. _precomputed_specs = None
  2365. def __init__(self, value=None, default=None, **kwargs):
  2366. """
  2367. Allows setting field values before passing everything else along to
  2368. Asn1Value.__init__()
  2369. :param value:
  2370. A native Python datatype to initialize the object value with
  2371. :param default:
  2372. The default value if no value is specified
  2373. """
  2374. Asn1Value.__init__(self, **kwargs)
  2375. check_existing = False
  2376. if value is None and default is not None:
  2377. check_existing = True
  2378. if self.children is None:
  2379. if self.contents is None:
  2380. check_existing = False
  2381. else:
  2382. self._parse_children()
  2383. value = default
  2384. if value is not None:
  2385. try:
  2386. # Fields are iterated in definition order to allow things like
  2387. # OID-based specs. Otherwise sometimes the value would be processed
  2388. # before the OID field, resulting in invalid value object creation.
  2389. if self._fields:
  2390. keys = [info[0] for info in self._fields]
  2391. unused_keys = set(value.keys())
  2392. else:
  2393. keys = value.keys()
  2394. unused_keys = set(keys)
  2395. for key in keys:
  2396. # If we are setting defaults, but a real value has already
  2397. # been set for the field, then skip it
  2398. if check_existing:
  2399. index = self._field_map[key]
  2400. if index < len(self.children) and self.children[index] is not VOID:
  2401. if key in unused_keys:
  2402. unused_keys.remove(key)
  2403. continue
  2404. if key in value:
  2405. self.__setitem__(key, value[key])
  2406. unused_keys.remove(key)
  2407. if len(unused_keys):
  2408. raise ValueError(unwrap(
  2409. '''
  2410. One or more unknown fields was passed to the constructor
  2411. of %s: %s
  2412. ''',
  2413. type_name(self),
  2414. ', '.join(sorted(list(unused_keys)))
  2415. ))
  2416. except (ValueError, TypeError) as e:
  2417. args = e.args[1:]
  2418. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  2419. raise e
  2420. @property
  2421. def contents(self):
  2422. """
  2423. :return:
  2424. A byte string of the DER-encoded contents of the sequence
  2425. """
  2426. if self.children is None:
  2427. return self._contents
  2428. if self._is_mutated():
  2429. self._set_contents()
  2430. return self._contents
  2431. @contents.setter
  2432. def contents(self, value):
  2433. """
  2434. :param value:
  2435. A byte string of the DER-encoded contents of the sequence
  2436. """
  2437. self._contents = value
  2438. def _is_mutated(self):
  2439. """
  2440. :return:
  2441. A boolean - if the sequence or any children (recursively) have been
  2442. mutated
  2443. """
  2444. mutated = self._mutated
  2445. if self.children is not None:
  2446. for child in self.children:
  2447. if isinstance(child, Sequence) or isinstance(child, SequenceOf):
  2448. mutated = mutated or child._is_mutated()
  2449. return mutated
  2450. def _lazy_child(self, index):
  2451. """
  2452. Builds a child object if the child has only been parsed into a tuple so far
  2453. """
  2454. child = self.children[index]
  2455. if child.__class__ == tuple:
  2456. child = self.children[index] = _build(*child)
  2457. return child
  2458. def __len__(self):
  2459. """
  2460. :return:
  2461. Integer
  2462. """
  2463. # We inline this check to prevent method invocation each time
  2464. if self.children is None:
  2465. self._parse_children()
  2466. return len(self.children)
  2467. def __getitem__(self, key):
  2468. """
  2469. Allows accessing fields by name or index
  2470. :param key:
  2471. A unicode string of the field name, or an integer of the field index
  2472. :raises:
  2473. KeyError - when a field name or index is invalid
  2474. :return:
  2475. The Asn1Value object of the field specified
  2476. """
  2477. # We inline this check to prevent method invocation each time
  2478. if self.children is None:
  2479. self._parse_children()
  2480. if not isinstance(key, int_types):
  2481. if key not in self._field_map:
  2482. raise KeyError(unwrap(
  2483. '''
  2484. No field named "%s" defined for %s
  2485. ''',
  2486. key,
  2487. type_name(self)
  2488. ))
  2489. key = self._field_map[key]
  2490. if key >= len(self.children):
  2491. raise KeyError(unwrap(
  2492. '''
  2493. No field numbered %s is present in this %s
  2494. ''',
  2495. key,
  2496. type_name(self)
  2497. ))
  2498. try:
  2499. return self._lazy_child(key)
  2500. except (ValueError, TypeError) as e:
  2501. args = e.args[1:]
  2502. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  2503. raise e
  2504. def __setitem__(self, key, value):
  2505. """
  2506. Allows settings fields by name or index
  2507. :param key:
  2508. A unicode string of the field name, or an integer of the field index
  2509. :param value:
  2510. A native Python datatype to set the field value to. This method will
  2511. construct the appropriate Asn1Value object from _fields.
  2512. :raises:
  2513. ValueError - when a field name or index is invalid
  2514. """
  2515. # We inline this check to prevent method invocation each time
  2516. if self.children is None:
  2517. self._parse_children()
  2518. if not isinstance(key, int_types):
  2519. if key not in self._field_map:
  2520. raise KeyError(unwrap(
  2521. '''
  2522. No field named "%s" defined for %s
  2523. ''',
  2524. key,
  2525. type_name(self)
  2526. ))
  2527. key = self._field_map[key]
  2528. field_name, field_spec, value_spec, field_params, _ = self._determine_spec(key)
  2529. new_value = self._make_value(field_name, field_spec, value_spec, field_params, value)
  2530. invalid_value = False
  2531. if isinstance(new_value, Any):
  2532. invalid_value = new_value.parsed is None
  2533. elif isinstance(new_value, Choice):
  2534. invalid_value = new_value.chosen.contents is None
  2535. else:
  2536. invalid_value = new_value.contents is None
  2537. if invalid_value:
  2538. raise ValueError(unwrap(
  2539. '''
  2540. Value for field "%s" of %s is not set
  2541. ''',
  2542. field_name,
  2543. type_name(self)
  2544. ))
  2545. self.children[key] = new_value
  2546. if self._native is not None:
  2547. self._native[self._fields[key][0]] = self.children[key].native
  2548. self._mutated = True
  2549. def __delitem__(self, key):
  2550. """
  2551. Allows deleting optional or default fields by name or index
  2552. :param key:
  2553. A unicode string of the field name, or an integer of the field index
  2554. :raises:
  2555. ValueError - when a field name or index is invalid, or the field is not optional or defaulted
  2556. """
  2557. # We inline this check to prevent method invocation each time
  2558. if self.children is None:
  2559. self._parse_children()
  2560. if not isinstance(key, int_types):
  2561. if key not in self._field_map:
  2562. raise KeyError(unwrap(
  2563. '''
  2564. No field named "%s" defined for %s
  2565. ''',
  2566. key,
  2567. type_name(self)
  2568. ))
  2569. key = self._field_map[key]
  2570. name, _, params = self._fields[key]
  2571. if not params or ('default' not in params and 'optional' not in params):
  2572. raise ValueError(unwrap(
  2573. '''
  2574. Can not delete the value for the field "%s" of %s since it is
  2575. not optional or defaulted
  2576. ''',
  2577. name,
  2578. type_name(self)
  2579. ))
  2580. if 'optional' in params:
  2581. self.children[key] = VOID
  2582. if self._native is not None:
  2583. self._native[name] = None
  2584. else:
  2585. self.__setitem__(key, None)
  2586. self._mutated = True
  2587. def __iter__(self):
  2588. """
  2589. :return:
  2590. An iterator of field key names
  2591. """
  2592. for info in self._fields:
  2593. yield info[0]
  2594. def _set_contents(self, force=False):
  2595. """
  2596. Updates the .contents attribute of the value with the encoded value of
  2597. all of the child objects
  2598. :param force:
  2599. Ensure all contents are in DER format instead of possibly using
  2600. cached BER-encoded data
  2601. """
  2602. if self.children is None:
  2603. self._parse_children()
  2604. contents = BytesIO()
  2605. for index, info in enumerate(self._fields):
  2606. child = self.children[index]
  2607. if child is None:
  2608. child_dump = b''
  2609. elif child.__class__ == tuple:
  2610. if force:
  2611. child_dump = self._lazy_child(index).dump(force=force)
  2612. else:
  2613. child_dump = child[3] + child[4] + child[5]
  2614. else:
  2615. child_dump = child.dump(force=force)
  2616. # Skip values that are the same as the default
  2617. if info[2] and 'default' in info[2]:
  2618. default_value = info[1](**info[2])
  2619. if default_value.dump() == child_dump:
  2620. continue
  2621. contents.write(child_dump)
  2622. self._contents = contents.getvalue()
  2623. self._header = None
  2624. if self._trailer != b'':
  2625. self._trailer = b''
  2626. def _setup(self):
  2627. """
  2628. Generates _field_map, _field_ids and _oid_nums for use in parsing
  2629. """
  2630. cls = self.__class__
  2631. cls._field_map = {}
  2632. cls._field_ids = []
  2633. cls._precomputed_specs = []
  2634. for index, field in enumerate(cls._fields):
  2635. if len(field) < 3:
  2636. field = field + ({},)
  2637. cls._fields[index] = field
  2638. cls._field_map[field[0]] = index
  2639. cls._field_ids.append(_build_id_tuple(field[2], field[1]))
  2640. if cls._oid_pair is not None:
  2641. cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])
  2642. for index, field in enumerate(cls._fields):
  2643. has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks
  2644. is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index
  2645. if has_callback or is_mapped_oid:
  2646. cls._precomputed_specs.append(None)
  2647. else:
  2648. cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))
  2649. def _determine_spec(self, index):
  2650. """
  2651. Determine how a value for a field should be constructed
  2652. :param index:
  2653. The field number
  2654. :return:
  2655. A tuple containing the following elements:
  2656. - unicode string of the field name
  2657. - Ans1Value class of the field spec
  2658. - Asn1Value class of the value spec
  2659. - None or dict of params to pass to the field spec
  2660. - None or Asn1Value class indicating the value spec was derived fomr an OID or a spec callback
  2661. """
  2662. name, field_spec, field_params = self._fields[index]
  2663. value_spec = field_spec
  2664. spec_override = None
  2665. if self._spec_callbacks is not None and name in self._spec_callbacks:
  2666. callback = self._spec_callbacks[name]
  2667. spec_override = callback(self)
  2668. if spec_override:
  2669. # Allow a spec callback to specify both the base spec and
  2670. # the override, for situations such as OctetString and parse_as
  2671. if spec_override.__class__ == tuple and len(spec_override) == 2:
  2672. field_spec, value_spec = spec_override
  2673. if value_spec is None:
  2674. value_spec = field_spec
  2675. spec_override = None
  2676. # When no field spec is specified, use a single return value as that
  2677. elif field_spec is None:
  2678. field_spec = spec_override
  2679. value_spec = field_spec
  2680. spec_override = None
  2681. else:
  2682. value_spec = spec_override
  2683. elif self._oid_nums is not None and self._oid_nums[1] == index:
  2684. oid = self._lazy_child(self._oid_nums[0]).native
  2685. if oid in self._oid_specs:
  2686. spec_override = self._oid_specs[oid]
  2687. value_spec = spec_override
  2688. return (name, field_spec, value_spec, field_params, spec_override)
  2689. def _make_value(self, field_name, field_spec, value_spec, field_params, value):
  2690. """
  2691. Contructs an appropriate Asn1Value object for a field
  2692. :param field_name:
  2693. A unicode string of the field name
  2694. :param field_spec:
  2695. An Asn1Value class that is the field spec
  2696. :param value_spec:
  2697. An Asn1Value class that is the vaue spec
  2698. :param field_params:
  2699. None or a dict of params for the field spec
  2700. :param value:
  2701. The value to construct an Asn1Value object from
  2702. :return:
  2703. An instance of a child class of Asn1Value
  2704. """
  2705. if value is None and 'optional' in field_params:
  2706. return VOID
  2707. specs_different = field_spec != value_spec
  2708. is_any = issubclass(field_spec, Any)
  2709. if issubclass(value_spec, Choice):
  2710. if not isinstance(value, Asn1Value):
  2711. raise ValueError(unwrap(
  2712. '''
  2713. Can not set a native python value to %s, which has the
  2714. choice type of %s – value must be an instance of Asn1Value
  2715. ''',
  2716. field_name,
  2717. type_name(value_spec)
  2718. ))
  2719. if not isinstance(value, value_spec):
  2720. wrapper = value_spec()
  2721. wrapper.validate(value.class_, value.tag, value.contents)
  2722. wrapper._parsed = value
  2723. new_value = wrapper
  2724. else:
  2725. new_value = value
  2726. elif isinstance(value, field_spec):
  2727. new_value = value
  2728. if specs_different:
  2729. new_value.parse(value_spec)
  2730. elif (not specs_different or is_any) and not isinstance(value, value_spec):
  2731. new_value = value_spec(value, **field_params)
  2732. else:
  2733. if isinstance(value, value_spec):
  2734. new_value = value
  2735. else:
  2736. new_value = value_spec(value)
  2737. # For when the field is OctetString or OctetBitString with embedded
  2738. # values we need to wrap the value in the field spec to get the
  2739. # appropriate encoded value.
  2740. if specs_different and not is_any:
  2741. wrapper = field_spec(value=new_value.dump(), **field_params)
  2742. wrapper._parsed = (new_value, new_value.__class__, None)
  2743. new_value = wrapper
  2744. new_value = _fix_tagging(new_value, field_params)
  2745. return new_value
  2746. def _parse_children(self, recurse=False):
  2747. """
  2748. Parses the contents and generates Asn1Value objects based on the
  2749. definitions from _fields.
  2750. :param recurse:
  2751. If child objects that are Sequence or SequenceOf objects should
  2752. be recursively parsed
  2753. :raises:
  2754. ValueError - when an error occurs parsing child objects
  2755. """
  2756. cls = self.__class__
  2757. if self._contents is None:
  2758. if self._fields:
  2759. self.children = [VOID] * len(self._fields)
  2760. for index, (_, _, params) in enumerate(self._fields):
  2761. if 'default' in params:
  2762. if cls._precomputed_specs[index]:
  2763. field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]
  2764. else:
  2765. field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)
  2766. self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)
  2767. return
  2768. try:
  2769. self.children = []
  2770. contents_length = len(self._contents)
  2771. child_pointer = 0
  2772. field = 0
  2773. field_len = len(self._fields)
  2774. parts = None
  2775. again = child_pointer < contents_length
  2776. while again:
  2777. if parts is None:
  2778. parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)
  2779. again = child_pointer < contents_length
  2780. if field < field_len:
  2781. _, field_spec, value_spec, field_params, spec_override = (
  2782. cls._precomputed_specs[field] or self._determine_spec(field))
  2783. # If the next value is optional or default, allow it to be absent
  2784. if field_params and ('optional' in field_params or 'default' in field_params):
  2785. if self._field_ids[field] != (parts[0], parts[2]) and field_spec != Any:
  2786. # See if the value is a valid choice before assuming
  2787. # that we have a missing optional or default value
  2788. choice_match = False
  2789. if issubclass(field_spec, Choice):
  2790. try:
  2791. tester = field_spec(**field_params)
  2792. tester.validate(parts[0], parts[2], parts[4])
  2793. choice_match = True
  2794. except (ValueError):
  2795. pass
  2796. if not choice_match:
  2797. if 'optional' in field_params:
  2798. self.children.append(VOID)
  2799. else:
  2800. self.children.append(field_spec(**field_params))
  2801. field += 1
  2802. again = True
  2803. continue
  2804. if field_spec is None or (spec_override and issubclass(field_spec, Any)):
  2805. field_spec = value_spec
  2806. spec_override = None
  2807. if spec_override:
  2808. child = parts + (field_spec, field_params, value_spec)
  2809. else:
  2810. child = parts + (field_spec, field_params)
  2811. # Handle situations where an optional or defaulted field definition is incorrect
  2812. elif field_len > 0 and field + 1 <= field_len:
  2813. missed_fields = []
  2814. prev_field = field - 1
  2815. while prev_field >= 0:
  2816. prev_field_info = self._fields[prev_field]
  2817. if len(prev_field_info) < 3:
  2818. break
  2819. if 'optional' in prev_field_info[2] or 'default' in prev_field_info[2]:
  2820. missed_fields.append(prev_field_info[0])
  2821. prev_field -= 1
  2822. plural = 's' if len(missed_fields) > 1 else ''
  2823. missed_field_names = ', '.join(missed_fields)
  2824. raise ValueError(unwrap(
  2825. '''
  2826. Data for field %s (%s class, %s method, tag %s) does
  2827. not match the field definition%s of %s
  2828. ''',
  2829. field + 1,
  2830. CLASS_NUM_TO_NAME_MAP.get(parts[0]),
  2831. METHOD_NUM_TO_NAME_MAP.get(parts[1]),
  2832. parts[2],
  2833. plural,
  2834. missed_field_names
  2835. ))
  2836. else:
  2837. child = parts
  2838. if recurse:
  2839. child = _build(*child)
  2840. if isinstance(child, (Sequence, SequenceOf)):
  2841. child._parse_children(recurse=True)
  2842. self.children.append(child)
  2843. field += 1
  2844. parts = None
  2845. index = len(self.children)
  2846. while index < field_len:
  2847. name, field_spec, field_params = self._fields[index]
  2848. if 'default' in field_params:
  2849. self.children.append(field_spec(**field_params))
  2850. elif 'optional' in field_params:
  2851. self.children.append(VOID)
  2852. else:
  2853. raise ValueError(unwrap(
  2854. '''
  2855. Field "%s" is missing from structure
  2856. ''',
  2857. name
  2858. ))
  2859. index += 1
  2860. except (ValueError, TypeError) as e:
  2861. args = e.args[1:]
  2862. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  2863. raise e
  2864. def spec(self, field_name):
  2865. """
  2866. Determines the spec to use for the field specified. Depending on how
  2867. the spec is determined (_oid_pair or _spec_callbacks), it may be
  2868. necessary to set preceeding field values before calling this. Usually
  2869. specs, if dynamic, are controlled by a preceeding ObjectIdentifier
  2870. field.
  2871. :param field_name:
  2872. A unicode string of the field name to get the spec for
  2873. :return:
  2874. A child class of asn1crypto.core.Asn1Value that the field must be
  2875. encoded using
  2876. """
  2877. if not isinstance(field_name, str_cls):
  2878. raise TypeError(unwrap(
  2879. '''
  2880. field_name must be a unicode string, not %s
  2881. ''',
  2882. type_name(field_name)
  2883. ))
  2884. if self._fields is None:
  2885. raise ValueError(unwrap(
  2886. '''
  2887. Unable to retrieve spec for field %s in the class %s because
  2888. _fields has not been set
  2889. ''',
  2890. repr(field_name),
  2891. type_name(self)
  2892. ))
  2893. index = self._field_map[field_name]
  2894. info = self._determine_spec(index)
  2895. return info[2]
  2896. @property
  2897. def native(self):
  2898. """
  2899. The a native Python datatype representation of this value
  2900. :return:
  2901. An OrderedDict or None. If an OrderedDict, all child values are
  2902. recursively converted to native representation also.
  2903. """
  2904. if self.contents is None:
  2905. return None
  2906. if self._native is None:
  2907. if self.children is None:
  2908. self._parse_children(recurse=True)
  2909. try:
  2910. self._native = OrderedDict()
  2911. for index, child in enumerate(self.children):
  2912. if child.__class__ == tuple:
  2913. child = _build(*child)
  2914. self.children[index] = child
  2915. try:
  2916. name = self._fields[index][0]
  2917. except (IndexError):
  2918. name = str_cls(index)
  2919. self._native[name] = child.native
  2920. except (ValueError, TypeError) as e:
  2921. args = e.args[1:]
  2922. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  2923. raise e
  2924. return self._native
  2925. def _copy(self, other, copy_func):
  2926. """
  2927. Copies the contents of another Sequence object to itself
  2928. :param object:
  2929. Another instance of the same class
  2930. :param copy_func:
  2931. An reference of copy.copy() or copy.deepcopy() to use when copying
  2932. lists, dicts and objects
  2933. """
  2934. super(Sequence, self)._copy(other, copy_func)
  2935. if self.children is not None:
  2936. self.children = []
  2937. for child in other.children:
  2938. if child.__class__ == tuple:
  2939. self.children.append(child)
  2940. else:
  2941. self.children.append(child.copy())
  2942. def debug(self, nest_level=1):
  2943. """
  2944. Show the binary data and parsed data in a tree structure
  2945. """
  2946. if self.children is None:
  2947. self._parse_children()
  2948. prefix = ' ' * nest_level
  2949. _basic_debug(prefix, self)
  2950. for field_name in self:
  2951. child = self._lazy_child(self._field_map[field_name])
  2952. if child is not VOID:
  2953. print('%s Field "%s"' % (prefix, field_name))
  2954. child.debug(nest_level + 3)
  2955. def dump(self, force=False):
  2956. """
  2957. Encodes the value using DER
  2958. :param force:
  2959. If the encoded contents already exist, clear them and regenerate
  2960. to ensure they are in DER format instead of BER format
  2961. :return:
  2962. A byte string of the DER-encoded value
  2963. """
  2964. if force:
  2965. self._set_contents(force=force)
  2966. return Asn1Value.dump(self)
  2967. class SequenceOf(Asn1Value):
  2968. """
  2969. Represents a sequence (ordered) of a single type of values from ASN.1 as a
  2970. Python object with a list-like interface
  2971. """
  2972. tag = 16
  2973. class_ = 0
  2974. method = 1
  2975. # A list of child objects
  2976. children = None
  2977. # SequenceOf overrides .contents to be a property so that the mutated state
  2978. # of child objects can be checked to ensure everything is up-to-date
  2979. _contents = None
  2980. # Variable to track if the object has been mutated
  2981. _mutated = False
  2982. # An Asn1Value class to use when parsing children
  2983. _child_spec = None
  2984. def __init__(self, value=None, default=None, contents=None, spec=None, **kwargs):
  2985. """
  2986. Allows setting child objects and the _child_spec via the spec parameter
  2987. before passing everything else along to Asn1Value.__init__()
  2988. :param value:
  2989. A native Python datatype to initialize the object value with
  2990. :param default:
  2991. The default value if no value is specified
  2992. :param contents:
  2993. A byte string of the encoded contents of the value
  2994. :param spec:
  2995. A class derived from Asn1Value to use to parse children
  2996. """
  2997. if spec:
  2998. self._child_spec = spec
  2999. Asn1Value.__init__(self, **kwargs)
  3000. try:
  3001. if contents is not None:
  3002. self.contents = contents
  3003. else:
  3004. if value is None and default is not None:
  3005. value = default
  3006. if value is not None:
  3007. for index, child in enumerate(value):
  3008. self.__setitem__(index, child)
  3009. # Make sure a blank list is serialized
  3010. if self.contents is None:
  3011. self._set_contents()
  3012. except (ValueError, TypeError) as e:
  3013. args = e.args[1:]
  3014. e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
  3015. raise e
  3016. @property
  3017. def contents(self):
  3018. """
  3019. :return:
  3020. A byte string of the DER-encoded contents of the sequence
  3021. """
  3022. if self.children is None:
  3023. return self._contents
  3024. if self._is_mutated():
  3025. self._set_contents()
  3026. return self._contents
  3027. @contents.setter
  3028. def contents(self, value):
  3029. """
  3030. :param value:
  3031. A byte string of the DER-encoded contents of the sequence
  3032. """
  3033. self._contents = value
  3034. def _is_mutated(self):
  3035. """
  3036. :return:
  3037. A boolean - if the sequence or any children (recursively) have been
  3038. mutated
  3039. """
  3040. mutated = self._mutated
  3041. if self.children is not None:
  3042. for child in self.children:
  3043. if isinstance(child, Sequence) or isinstance(child, SequenceOf):
  3044. mutated = mutated or child._is_mutated()
  3045. return mutated
  3046. def _lazy_child(self, index):
  3047. """
  3048. Builds a child object if the child has only been parsed into a tuple so far
  3049. """
  3050. child = self.children[index]
  3051. if child.__class__ == tuple:
  3052. child = _build(*child)
  3053. self.children[index] = child
  3054. return child
  3055. def _make_value(self, value):
  3056. """
  3057. Constructs a _child_spec value from a native Python data type, or
  3058. an appropriate Asn1Value object
  3059. :param value:
  3060. A native Python value, or some child of Asn1Value
  3061. :return:
  3062. An object of type _child_spec
  3063. """
  3064. if isinstance(value, self._child_spec):
  3065. new_value = value
  3066. elif issubclass(self._child_spec, Any):
  3067. if isinstance(value, Asn1Value):
  3068. new_value = value
  3069. else:
  3070. raise ValueError(unwrap(
  3071. '''
  3072. Can not set a native python value to %s where the
  3073. _child_spec is Any – value must be an instance of Asn1Value
  3074. ''',
  3075. type_name(self)
  3076. ))
  3077. elif issubclass(self._child_spec, Choice):
  3078. if not isinstance(value, Asn1Value):
  3079. raise ValueError(unwrap(
  3080. '''
  3081. Can not set a native python value to %s where the
  3082. _child_spec is the choice type %s – value must be an
  3083. instance of Asn1Value
  3084. ''',
  3085. type_name(self),
  3086. self._child_spec.__name__
  3087. ))
  3088. if not isinstance(value, self._child_spec):
  3089. wrapper = self._child_spec()
  3090. wrapper.validate(value.class_, value.tag, value.contents)
  3091. wrapper._parsed = value
  3092. value = wrapper
  3093. new_value = value
  3094. else:
  3095. return self._child_spec(value=value)
  3096. params = {}
  3097. if self._child_spec.tag_type is not None:
  3098. params['tag_type'] = self._child_spec.tag_type
  3099. if params['tag_type'] == 'explicit':
  3100. params['tag'] = self._child_spec.explicit_tag
  3101. else:
  3102. params['tag'] = self._child_spec.tag
  3103. return _fix_tagging(new_value, params)
  3104. def __len__(self):
  3105. """
  3106. :return:
  3107. An integer
  3108. """
  3109. # We inline this checks to prevent method invocation each time
  3110. if self.children is None:
  3111. self._parse_children()
  3112. return len(self.children)
  3113. def __getitem__(self, key):
  3114. """
  3115. Allows accessing children via index
  3116. :param key:
  3117. Integer index of child
  3118. """
  3119. # We inline this checks to prevent method invocation each time
  3120. if self.children is None:
  3121. self._parse_children()
  3122. return self._lazy_child(key)
  3123. def __setitem__(self, key, value):
  3124. """
  3125. Allows overriding a child via index
  3126. :param key:
  3127. Integer index of child
  3128. :param value:
  3129. Native python datatype that will be passed to _child_spec to create
  3130. new child object
  3131. """
  3132. # We inline this checks to prevent method invocation each time
  3133. if self.children is None:
  3134. self._parse_children()
  3135. new_value = self._make_value(value)
  3136. # If adding at the end, create a space for the new value
  3137. if key == len(self.children):
  3138. self.children.append(None)
  3139. if self._native is not None:
  3140. self._native.append(None)
  3141. self.children[key] = new_value
  3142. if self._native is not None:
  3143. self._native[key] = self.children[key].native
  3144. self._mutated = True
  3145. def __delitem__(self, key):
  3146. """
  3147. Allows removing a child via index
  3148. :param key:
  3149. Integer index of child
  3150. """
  3151. # We inline this checks to prevent method invocation each time
  3152. if self.children is None:
  3153. self._parse_children()
  3154. self.children.pop(key)
  3155. if self._native is not None:
  3156. self._native.pop(key)
  3157. self._mutated = True
  3158. def __iter__(self):
  3159. """
  3160. :return:
  3161. An iter() of child objects
  3162. """
  3163. # We inline this checks to prevent method invocation each time
  3164. if self.children is None:
  3165. self._parse_children()
  3166. for index in range(0, len(self.children)):
  3167. yield self._lazy_child(index)
  3168. def __contains__(self, item):
  3169. """
  3170. :param item:
  3171. An object of the type cls._child_spec
  3172. :return:
  3173. A boolean if the item is contained in this SequenceOf
  3174. """
  3175. if item is None or item is VOID:
  3176. return False
  3177. if not isinstance(item, self._child_spec):
  3178. raise TypeError(unwrap(
  3179. '''
  3180. Checking membership in %s is only available for instances of
  3181. %s, not %s
  3182. ''',
  3183. type_name(self),
  3184. type_name(self._child_spec),
  3185. type_name(item)
  3186. ))
  3187. for child in self:
  3188. if child == item:
  3189. return True
  3190. return False
  3191. def append(self, value):
  3192. """
  3193. Allows adding a child to the end of the sequence
  3194. :param value:
  3195. Native python datatype that will be passed to _child_spec to create
  3196. new child object
  3197. """
  3198. # We inline this checks to prevent method invocation each time
  3199. if self.children is None:
  3200. self._parse_children()
  3201. self.children.append(self._make_value(value))
  3202. if self._native is not None:
  3203. self._native.append(self.children[-1].native)
  3204. self._mutated = True
  3205. def _set_contents(self, force=False):
  3206. """
  3207. Encodes all child objects into the contents for this object
  3208. :param force:
  3209. Ensure all contents are in DER format instead of possibly using
  3210. cached BER-encoded data
  3211. """
  3212. if self.children is None:
  3213. self._parse_children()
  3214. contents = BytesIO()
  3215. for child in self:
  3216. contents.write(child.dump(force=force))
  3217. self._contents = contents.getvalue()
  3218. self._header = None
  3219. if self._trailer != b'':
  3220. self._trailer = b''
  3221. def _parse_children(self, recurse=False):
  3222. """
  3223. Parses the contents and generates Asn1Value objects based on the
  3224. definitions from _child_spec.
  3225. :param recurse:
  3226. If child objects that are Sequence or SequenceOf objects should
  3227. be recursively parsed
  3228. :raises:
  3229. ValueError - when an error occurs parsing child objects
  3230. """
  3231. try:
  3232. self.children = []
  3233. if self._contents is None:
  3234. return
  3235. contents_length = len(self._contents)
  3236. child_pointer = 0
  3237. while child_pointer < contents_length:
  3238. parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)
  3239. if self._child_spec:
  3240. child = parts + (self._child_spec,)
  3241. else:
  3242. child = parts
  3243. if recurse:
  3244. child = _build(*child)
  3245. if isinstance(child, (Sequence, SequenceOf)):
  3246. child._parse_children(recurse=True)
  3247. self.children.append(child)
  3248. except (ValueError, TypeError) as e:
  3249. args = e.args[1:]
  3250. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  3251. raise e
  3252. def spec(self):
  3253. """
  3254. Determines the spec to use for child values.
  3255. :return:
  3256. A child class of asn1crypto.core.Asn1Value that child values must be
  3257. encoded using
  3258. """
  3259. return self._child_spec
  3260. @property
  3261. def native(self):
  3262. """
  3263. The a native Python datatype representation of this value
  3264. :return:
  3265. A list or None. If a list, all child values are recursively
  3266. converted to native representation also.
  3267. """
  3268. if self.contents is None:
  3269. return None
  3270. if self._native is None:
  3271. if self.children is None:
  3272. self._parse_children(recurse=True)
  3273. try:
  3274. self._native = [child.native for child in self]
  3275. except (ValueError, TypeError) as e:
  3276. args = e.args[1:]
  3277. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  3278. raise e
  3279. return self._native
  3280. def _copy(self, other, copy_func):
  3281. """
  3282. Copies the contents of another SequenceOf object to itself
  3283. :param object:
  3284. Another instance of the same class
  3285. :param copy_func:
  3286. An reference of copy.copy() or copy.deepcopy() to use when copying
  3287. lists, dicts and objects
  3288. """
  3289. super(SequenceOf, self)._copy(other, copy_func)
  3290. if self.children is not None:
  3291. self.children = []
  3292. for child in other.children:
  3293. if child.__class__ == tuple:
  3294. self.children.append(child)
  3295. else:
  3296. self.children.append(child.copy())
  3297. def debug(self, nest_level=1):
  3298. """
  3299. Show the binary data and parsed data in a tree structure
  3300. """
  3301. if self.children is None:
  3302. self._parse_children()
  3303. prefix = ' ' * nest_level
  3304. _basic_debug(prefix, self)
  3305. for child in self:
  3306. child.debug(nest_level + 1)
  3307. def dump(self, force=False):
  3308. """
  3309. Encodes the value using DER
  3310. :param force:
  3311. If the encoded contents already exist, clear them and regenerate
  3312. to ensure they are in DER format instead of BER format
  3313. :return:
  3314. A byte string of the DER-encoded value
  3315. """
  3316. if force:
  3317. self._set_contents(force=force)
  3318. return Asn1Value.dump(self)
  3319. class Set(Sequence):
  3320. """
  3321. Represents a set of fields (unordered) from ASN.1 as a Python object with a
  3322. dict-like interface
  3323. """
  3324. method = 1
  3325. class_ = 0
  3326. tag = 17
  3327. # A dict of 2-element tuples in the form (class_, tag) as keys and integers
  3328. # as values that are the index of the field in _fields
  3329. _field_ids = None
  3330. def _setup(self):
  3331. """
  3332. Generates _field_map, _field_ids and _oid_nums for use in parsing
  3333. """
  3334. cls = self.__class__
  3335. cls._field_map = {}
  3336. cls._field_ids = {}
  3337. cls._precomputed_specs = []
  3338. for index, field in enumerate(cls._fields):
  3339. if len(field) < 3:
  3340. field = field + ({},)
  3341. cls._fields[index] = field
  3342. cls._field_map[field[0]] = index
  3343. cls._field_ids[_build_id_tuple(field[2], field[1])] = index
  3344. if cls._oid_pair is not None:
  3345. cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])
  3346. for index, field in enumerate(cls._fields):
  3347. has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks
  3348. is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index
  3349. if has_callback or is_mapped_oid:
  3350. cls._precomputed_specs.append(None)
  3351. else:
  3352. cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))
  3353. def _parse_children(self, recurse=False):
  3354. """
  3355. Parses the contents and generates Asn1Value objects based on the
  3356. definitions from _fields.
  3357. :param recurse:
  3358. If child objects that are Sequence or SequenceOf objects should
  3359. be recursively parsed
  3360. :raises:
  3361. ValueError - when an error occurs parsing child objects
  3362. """
  3363. cls = self.__class__
  3364. if self._contents is None:
  3365. if self._fields:
  3366. self.children = [VOID] * len(self._fields)
  3367. for index, (_, _, params) in enumerate(self._fields):
  3368. if 'default' in params:
  3369. if cls._precomputed_specs[index]:
  3370. field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]
  3371. else:
  3372. field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)
  3373. self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)
  3374. return
  3375. try:
  3376. child_map = {}
  3377. contents_length = len(self.contents)
  3378. child_pointer = 0
  3379. seen_field = 0
  3380. while child_pointer < contents_length:
  3381. parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer)
  3382. id_ = (parts[0], parts[2])
  3383. field = self._field_ids.get(id_)
  3384. if field is None:
  3385. raise ValueError(unwrap(
  3386. '''
  3387. Data for field %s (%s class, %s method, tag %s) does
  3388. not match any of the field definitions
  3389. ''',
  3390. seen_field,
  3391. CLASS_NUM_TO_NAME_MAP.get(parts[0]),
  3392. METHOD_NUM_TO_NAME_MAP.get(parts[1]),
  3393. parts[2],
  3394. ))
  3395. _, field_spec, value_spec, field_params, spec_override = (
  3396. cls._precomputed_specs[field] or self._determine_spec(field))
  3397. if field_spec is None or (spec_override and issubclass(field_spec, Any)):
  3398. field_spec = value_spec
  3399. spec_override = None
  3400. if spec_override:
  3401. child = parts + (field_spec, field_params, value_spec)
  3402. else:
  3403. child = parts + (field_spec, field_params)
  3404. if recurse:
  3405. child = _build(*child)
  3406. if isinstance(child, (Sequence, SequenceOf)):
  3407. child._parse_children(recurse=True)
  3408. child_map[field] = child
  3409. seen_field += 1
  3410. total_fields = len(self._fields)
  3411. for index in range(0, total_fields):
  3412. if index in child_map:
  3413. continue
  3414. name, field_spec, value_spec, field_params, spec_override = (
  3415. cls._precomputed_specs[index] or self._determine_spec(index))
  3416. if field_spec is None or (spec_override and issubclass(field_spec, Any)):
  3417. field_spec = value_spec
  3418. spec_override = None
  3419. missing = False
  3420. if not field_params:
  3421. missing = True
  3422. elif 'optional' not in field_params and 'default' not in field_params:
  3423. missing = True
  3424. elif 'optional' in field_params:
  3425. child_map[index] = VOID
  3426. elif 'default' in field_params:
  3427. child_map[index] = field_spec(**field_params)
  3428. if missing:
  3429. raise ValueError(unwrap(
  3430. '''
  3431. Missing required field "%s" from %s
  3432. ''',
  3433. name,
  3434. type_name(self)
  3435. ))
  3436. self.children = []
  3437. for index in range(0, total_fields):
  3438. self.children.append(child_map[index])
  3439. except (ValueError, TypeError) as e:
  3440. args = e.args[1:]
  3441. e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
  3442. raise e
  3443. def _set_contents(self, force=False):
  3444. """
  3445. Encodes all child objects into the contents for this object.
  3446. This method is overridden because a Set needs to be encoded by
  3447. removing defaulted fields and then sorting the fields by tag.
  3448. :param force:
  3449. Ensure all contents are in DER format instead of possibly using
  3450. cached BER-encoded data
  3451. """
  3452. if self.children is None:
  3453. self._parse_children()
  3454. child_tag_encodings = []
  3455. for index, child in enumerate(self.children):
  3456. child_encoding = child.dump(force=force)
  3457. # Skip encoding defaulted children
  3458. name, spec, field_params = self._fields[index]
  3459. if 'default' in field_params:
  3460. if spec(**field_params).dump() == child_encoding:
  3461. continue
  3462. child_tag_encodings.append((child.tag, child_encoding))
  3463. child_tag_encodings.sort(key=lambda ct: ct[0])
  3464. self._contents = b''.join([ct[1] for ct in child_tag_encodings])
  3465. self._header = None
  3466. if self._trailer != b'':
  3467. self._trailer = b''
  3468. class SetOf(SequenceOf):
  3469. """
  3470. Represents a set (unordered) of a single type of values from ASN.1 as a
  3471. Python object with a list-like interface
  3472. """
  3473. tag = 17
  3474. def _set_contents(self, force=False):
  3475. """
  3476. Encodes all child objects into the contents for this object.
  3477. This method is overridden because a SetOf needs to be encoded by
  3478. sorting the child encodings.
  3479. :param force:
  3480. Ensure all contents are in DER format instead of possibly using
  3481. cached BER-encoded data
  3482. """
  3483. if self.children is None:
  3484. self._parse_children()
  3485. child_encodings = []
  3486. for child in self:
  3487. child_encodings.append(child.dump(force=force))
  3488. self._contents = b''.join(sorted(child_encodings))
  3489. self._header = None
  3490. if self._trailer != b'':
  3491. self._trailer = b''
  3492. class EmbeddedPdv(Sequence):
  3493. """
  3494. A sequence structure
  3495. """
  3496. tag = 11
  3497. class NumericString(AbstractString):
  3498. """
  3499. Represents a numeric string from ASN.1 as a Python unicode string
  3500. """
  3501. tag = 18
  3502. _encoding = 'latin1'
  3503. class PrintableString(AbstractString):
  3504. """
  3505. Represents a printable string from ASN.1 as a Python unicode string
  3506. """
  3507. tag = 19
  3508. _encoding = 'latin1'
  3509. class TeletexString(AbstractString):
  3510. """
  3511. Represents a teletex string from ASN.1 as a Python unicode string
  3512. """
  3513. tag = 20
  3514. _encoding = 'teletex'
  3515. class VideotexString(OctetString):
  3516. """
  3517. Represents a videotex string from ASN.1 as a Python byte string
  3518. """
  3519. tag = 21
  3520. class IA5String(AbstractString):
  3521. """
  3522. Represents an IA5 string from ASN.1 as a Python unicode string
  3523. """
  3524. tag = 22
  3525. _encoding = 'ascii'
  3526. class AbstractTime(AbstractString):
  3527. """
  3528. Represents a time from ASN.1 as a Python datetime.datetime object
  3529. """
  3530. @property
  3531. def native(self):
  3532. """
  3533. The a native Python datatype representation of this value
  3534. :return:
  3535. A datetime.datetime object in the UTC timezone or None
  3536. """
  3537. if self.contents is None:
  3538. return None
  3539. if self._native is None:
  3540. string = str_cls(self)
  3541. has_timezone = re.search('[-\\+]', string)
  3542. # We don't know what timezone it is in, or it is UTC because of a Z
  3543. # suffix, so we just assume UTC
  3544. if not has_timezone:
  3545. string = string.rstrip('Z')
  3546. date = self._date_by_len(string)
  3547. self._native = date.replace(tzinfo=timezone.utc)
  3548. else:
  3549. # Python 2 doesn't support the %z format code, so we have to manually
  3550. # process the timezone offset.
  3551. date = self._date_by_len(string[0:-5])
  3552. hours = int(string[-4:-2])
  3553. minutes = int(string[-2:])
  3554. delta = timedelta(hours=abs(hours), minutes=minutes)
  3555. if hours < 0:
  3556. date -= delta
  3557. else:
  3558. date += delta
  3559. self._native = date.replace(tzinfo=timezone.utc)
  3560. return self._native
  3561. class UTCTime(AbstractTime):
  3562. """
  3563. Represents a UTC time from ASN.1 as a Python datetime.datetime object in UTC
  3564. """
  3565. tag = 23
  3566. def set(self, value):
  3567. """
  3568. Sets the value of the object
  3569. :param value:
  3570. A unicode string or a datetime.datetime object
  3571. :raises:
  3572. ValueError - when an invalid value is passed
  3573. """
  3574. if isinstance(value, datetime):
  3575. value = value.strftime('%y%m%d%H%M%SZ')
  3576. if _PY2:
  3577. value = value.decode('ascii')
  3578. AbstractString.set(self, value)
  3579. # Set it to None and let the class take care of converting the next
  3580. # time that .native is called
  3581. self._native = None
  3582. def _date_by_len(self, string):
  3583. """
  3584. Parses a date from a string based on its length
  3585. :param string:
  3586. A unicode string to parse
  3587. :return:
  3588. A datetime.datetime object or a unicode string
  3589. """
  3590. strlen = len(string)
  3591. year_num = int(string[0:2])
  3592. if year_num < 50:
  3593. prefix = '20'
  3594. else:
  3595. prefix = '19'
  3596. if strlen == 10:
  3597. return datetime.strptime(prefix + string, '%Y%m%d%H%M')
  3598. if strlen == 12:
  3599. return datetime.strptime(prefix + string, '%Y%m%d%H%M%S')
  3600. return string
  3601. class GeneralizedTime(AbstractTime):
  3602. """
  3603. Represents a generalized time from ASN.1 as a Python datetime.datetime
  3604. object or asn1crypto.util.extended_datetime object in UTC
  3605. """
  3606. tag = 24
  3607. def set(self, value):
  3608. """
  3609. Sets the value of the object
  3610. :param value:
  3611. A unicode string, a datetime.datetime object or an
  3612. asn1crypto.util.extended_datetime object
  3613. :raises:
  3614. ValueError - when an invalid value is passed
  3615. """
  3616. if isinstance(value, (datetime, extended_datetime)):
  3617. value = value.strftime('%Y%m%d%H%M%SZ')
  3618. if _PY2:
  3619. value = value.decode('ascii')
  3620. AbstractString.set(self, value)
  3621. # Set it to None and let the class take care of converting the next
  3622. # time that .native is called
  3623. self._native = None
  3624. def _date_by_len(self, string):
  3625. """
  3626. Parses a date from a string based on its length
  3627. :param string:
  3628. A unicode string to parse
  3629. :return:
  3630. A datetime.datetime object, asn1crypto.util.extended_datetime object or
  3631. a unicode string
  3632. """
  3633. strlen = len(string)
  3634. date_format = None
  3635. if strlen == 10:
  3636. date_format = '%Y%m%d%H'
  3637. elif strlen == 12:
  3638. date_format = '%Y%m%d%H%M'
  3639. elif strlen == 14:
  3640. date_format = '%Y%m%d%H%M%S'
  3641. elif strlen == 18:
  3642. date_format = '%Y%m%d%H%M%S.%f'
  3643. if date_format:
  3644. if len(string) >= 4 and string[0:4] == '0000':
  3645. # Year 2000 shares a calendar with year 0, and is supported natively
  3646. t = datetime.strptime('2000' + string[4:], date_format)
  3647. return extended_datetime(
  3648. 0,
  3649. t.month,
  3650. t.day,
  3651. t.hour,
  3652. t.minute,
  3653. t.second,
  3654. t.microsecond,
  3655. t.tzinfo
  3656. )
  3657. return datetime.strptime(string, date_format)
  3658. return string
  3659. class GraphicString(AbstractString):
  3660. """
  3661. Represents a graphic string from ASN.1 as a Python unicode string
  3662. """
  3663. tag = 25
  3664. # This is technically not correct since this type can contain any charset
  3665. _encoding = 'latin1'
  3666. class VisibleString(AbstractString):
  3667. """
  3668. Represents a visible string from ASN.1 as a Python unicode string
  3669. """
  3670. tag = 26
  3671. _encoding = 'latin1'
  3672. class GeneralString(AbstractString):
  3673. """
  3674. Represents a general string from ASN.1 as a Python unicode string
  3675. """
  3676. tag = 27
  3677. # This is technically not correct since this type can contain any charset
  3678. _encoding = 'latin1'
  3679. class UniversalString(AbstractString):
  3680. """
  3681. Represents a universal string from ASN.1 as a Python unicode string
  3682. """
  3683. tag = 28
  3684. _encoding = 'utf-32-be'
  3685. class CharacterString(AbstractString):
  3686. """
  3687. Represents a character string from ASN.1 as a Python unicode string
  3688. """
  3689. tag = 29
  3690. # This is technically not correct since this type can contain any charset
  3691. _encoding = 'latin1'
  3692. class BMPString(AbstractString):
  3693. """
  3694. Represents a BMP string from ASN.1 as a Python unicode string
  3695. """
  3696. tag = 30
  3697. _encoding = 'utf-16-be'
  3698. def _basic_debug(prefix, self):
  3699. """
  3700. Prints out basic information about an Asn1Value object. Extracted for reuse
  3701. among different classes that customize the debug information.
  3702. :param prefix:
  3703. A unicode string of spaces to prefix output line with
  3704. :param self:
  3705. The object to print the debugging information about
  3706. """
  3707. print('%s%s Object #%s' % (prefix, type_name(self), id(self)))
  3708. if self._header:
  3709. print('%s Header: 0x%s' % (prefix, binascii.hexlify(self._header or b'').decode('utf-8')))
  3710. has_header = self.method is not None and self.class_ is not None and self.tag is not None
  3711. if has_header:
  3712. method_name = METHOD_NUM_TO_NAME_MAP.get(self.method)
  3713. class_name = CLASS_NUM_TO_NAME_MAP.get(self.class_)
  3714. if self.tag_type == 'explicit':
  3715. print(
  3716. '%s %s tag %s (explicitly tagged)' %
  3717. (
  3718. prefix,
  3719. CLASS_NUM_TO_NAME_MAP.get(self.explicit_class),
  3720. self.explicit_tag
  3721. )
  3722. )
  3723. if has_header:
  3724. print('%s %s %s %s' % (prefix, method_name, class_name, self.tag))
  3725. elif self.tag_type == 'implicit':
  3726. if has_header:
  3727. print('%s %s %s tag %s (implicitly tagged)' % (prefix, method_name, class_name, self.tag))
  3728. elif has_header:
  3729. print('%s %s %s tag %s' % (prefix, method_name, class_name, self.tag))
  3730. print('%s Data: 0x%s' % (prefix, binascii.hexlify(self.contents or b'').decode('utf-8')))
  3731. def _fix_tagging(value, params):
  3732. """
  3733. Checks if a value is properly tagged based on the spec, and re/untags as
  3734. necessary
  3735. :param value:
  3736. An Asn1Value object
  3737. :param params:
  3738. A dict of spec params
  3739. :return:
  3740. An Asn1Value that is properly tagged
  3741. """
  3742. if 'tag_type' in params:
  3743. required_tag_type = params['tag_type']
  3744. retag = False
  3745. if required_tag_type != value.tag_type:
  3746. retag = True
  3747. elif required_tag_type == 'explicit' and value.explicit_tag != params['tag']:
  3748. retag = True
  3749. elif required_tag_type == 'implicit' and value.tag != params['tag']:
  3750. retag = True
  3751. if retag:
  3752. return value.retag(params['tag_type'], params['tag'])
  3753. return value
  3754. if value.tag_type:
  3755. return value.untag()
  3756. return value
  3757. def _build_id_tuple(params, spec):
  3758. """
  3759. Builds a 2-element tuple used to identify fields by grabbing the class_
  3760. and tag from an Asn1Value class and the params dict being passed to it
  3761. :param params:
  3762. A dict of params to pass to spec
  3763. :param spec:
  3764. An Asn1Value class
  3765. :return:
  3766. A 2-element integer tuple in the form (class_, tag)
  3767. """
  3768. # Handle situations where the the spec is not known at setup time
  3769. if spec is None:
  3770. return (None, None)
  3771. required_class = spec.class_
  3772. required_tag = spec.tag
  3773. tag_type = params.get('tag_type', spec.tag_type)
  3774. if tag_type is not None:
  3775. required_class = 2
  3776. required_class = params.get('class_', required_class)
  3777. required_tag = params.get('tag', required_tag)
  3778. return (required_class, required_tag)
  3779. _UNIVERSAL_SPECS = {
  3780. 1: Boolean,
  3781. 2: Integer,
  3782. 3: BitString,
  3783. 4: OctetString,
  3784. 5: Null,
  3785. 6: ObjectIdentifier,
  3786. 7: ObjectDescriptor,
  3787. 8: InstanceOf,
  3788. 9: Real,
  3789. 10: Enumerated,
  3790. 11: EmbeddedPdv,
  3791. 12: UTF8String,
  3792. 13: RelativeOid,
  3793. 16: Sequence,
  3794. 17: Set,
  3795. 18: NumericString,
  3796. 19: PrintableString,
  3797. 20: TeletexString,
  3798. 21: VideotexString,
  3799. 22: IA5String,
  3800. 23: UTCTime,
  3801. 24: GeneralizedTime,
  3802. 25: GraphicString,
  3803. 26: VisibleString,
  3804. 27: GeneralString,
  3805. 28: UniversalString,
  3806. 29: CharacterString,
  3807. 30: BMPString
  3808. }
  3809. def _build(class_, method, tag, header, contents, trailer, spec=None, spec_params=None, nested_spec=None):
  3810. """
  3811. Builds an Asn1Value object generically, or using a spec with optional params
  3812. :param class_:
  3813. An integer representing the ASN.1 class
  3814. :param method:
  3815. An integer representing the ASN.1 method
  3816. :param tag:
  3817. An integer representing the ASN.1 tag
  3818. :param header:
  3819. A byte string of the ASN.1 header (class, method, tag, length)
  3820. :param contents:
  3821. A byte string of the ASN.1 value
  3822. :param trailer:
  3823. A byte string of any ASN.1 trailer (only used by indefinite length encodings)
  3824. :param spec:
  3825. A class derived from Asn1Value that defines what class_ and tag the
  3826. value should have, and the semantics of the encoded value. The
  3827. return value will be of this type. If omitted, the encoded value
  3828. will be decoded using the standard universal tag based on the
  3829. encoded tag number.
  3830. :param spec_params:
  3831. A dict of params to pass to the spec object
  3832. :param nested_spec:
  3833. For certain Asn1Value classes (such as OctetString and BitString), the
  3834. contents can be further parsed and interpreted as another Asn1Value.
  3835. This parameter controls the spec for that sub-parsing.
  3836. :return:
  3837. An object of the type spec, or if not specified, a child of Asn1Value
  3838. """
  3839. if header is None:
  3840. return VOID
  3841. header_set = False
  3842. # If an explicit specification was passed in, make sure it matches
  3843. if spec is not None:
  3844. if spec_params:
  3845. value = spec(contents=contents, **spec_params)
  3846. else:
  3847. value = spec(contents=contents)
  3848. if spec is Any:
  3849. pass
  3850. elif value.tag_type == 'explicit':
  3851. if class_ != value.explicit_class:
  3852. raise ValueError(unwrap(
  3853. '''
  3854. Error parsing %s - explicitly-tagged class should have been
  3855. %s, but %s was found
  3856. ''',
  3857. type_name(value),
  3858. CLASS_NUM_TO_NAME_MAP.get(value.explicit_class),
  3859. CLASS_NUM_TO_NAME_MAP.get(class_, class_)
  3860. ))
  3861. if method != 1:
  3862. raise ValueError(unwrap(
  3863. '''
  3864. Error parsing %s - explicitly-tagged method should have
  3865. been %s, but %s was found
  3866. ''',
  3867. type_name(value),
  3868. METHOD_NUM_TO_NAME_MAP.get(1),
  3869. METHOD_NUM_TO_NAME_MAP.get(method, method)
  3870. ))
  3871. if tag != value.explicit_tag:
  3872. raise ValueError(unwrap(
  3873. '''
  3874. Error parsing %s - explicitly-tagged tag should have been
  3875. %s, but %s was found
  3876. ''',
  3877. type_name(value),
  3878. value.explicit_tag,
  3879. tag
  3880. ))
  3881. original_value = value
  3882. info, _ = _parse(contents, len(contents))
  3883. value = _build(*info, spec=spec)
  3884. value._header = header + value._header
  3885. value._trailer += trailer or b''
  3886. value.tag_type = 'explicit'
  3887. value.explicit_class = original_value.explicit_class
  3888. value.explicit_tag = original_value.explicit_tag
  3889. header_set = True
  3890. elif isinstance(value, Choice):
  3891. value.validate(class_, tag, contents)
  3892. try:
  3893. # Force parsing the Choice now
  3894. value.contents = header + value.contents
  3895. header = b''
  3896. value.parse()
  3897. except (ValueError, TypeError) as e:
  3898. args = e.args[1:]
  3899. e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args
  3900. raise e
  3901. else:
  3902. if class_ != value.class_:
  3903. raise ValueError(unwrap(
  3904. '''
  3905. Error parsing %s - class should have been %s, but %s was
  3906. found
  3907. ''',
  3908. type_name(value),
  3909. CLASS_NUM_TO_NAME_MAP.get(value.class_),
  3910. CLASS_NUM_TO_NAME_MAP.get(class_, class_)
  3911. ))
  3912. if method != value.method:
  3913. # Allow parsing a primitive method as constructed if the value
  3914. # is indefinite length. This is to allow parsing BER.
  3915. ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00'
  3916. if not ber_indef or not isinstance(value, Constructable):
  3917. raise ValueError(unwrap(
  3918. '''
  3919. Error parsing %s - method should have been %s, but %s was found
  3920. ''',
  3921. type_name(value),
  3922. METHOD_NUM_TO_NAME_MAP.get(value.method),
  3923. METHOD_NUM_TO_NAME_MAP.get(method, method)
  3924. ))
  3925. else:
  3926. value.method = method
  3927. value._indefinite = True
  3928. if tag != value.tag and tag != value._bad_tag:
  3929. raise ValueError(unwrap(
  3930. '''
  3931. Error parsing %s - tag should have been %s, but %s was found
  3932. ''',
  3933. type_name(value),
  3934. value.tag,
  3935. tag
  3936. ))
  3937. # For explicitly tagged, un-speced parsings, we use a generic container
  3938. # since we will be parsing the contents and discarding the outer object
  3939. # anyway a little further on
  3940. elif spec_params and 'tag_type' in spec_params and spec_params['tag_type'] == 'explicit':
  3941. original_value = Asn1Value(contents=contents, **spec_params)
  3942. info, _ = _parse(contents, len(contents))
  3943. value = _build(*info, spec=spec)
  3944. value._header = header + value._header
  3945. value._trailer += trailer or b''
  3946. value.tag_type = 'explicit'
  3947. value.explicit_class = original_value.explicit_class
  3948. value.explicit_tag = original_value.explicit_tag
  3949. header_set = True
  3950. # If no spec was specified, allow anything and just process what
  3951. # is in the input data
  3952. else:
  3953. if tag not in _UNIVERSAL_SPECS:
  3954. raise ValueError(unwrap(
  3955. '''
  3956. Unknown element - %s class, %s method, tag %s
  3957. ''',
  3958. CLASS_NUM_TO_NAME_MAP.get(class_),
  3959. METHOD_NUM_TO_NAME_MAP.get(method),
  3960. tag
  3961. ))
  3962. spec = _UNIVERSAL_SPECS[tag]
  3963. value = spec(contents=contents, class_=class_)
  3964. ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00'
  3965. if ber_indef and isinstance(value, Constructable):
  3966. value._indefinite = True
  3967. value.method = method
  3968. if not header_set:
  3969. value._header = header
  3970. value._trailer = trailer or b''
  3971. # Destroy any default value that our contents have overwritten
  3972. value._native = None
  3973. if nested_spec:
  3974. try:
  3975. value.parse(nested_spec)
  3976. except (ValueError, TypeError) as e:
  3977. args = e.args[1:]
  3978. e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args
  3979. raise e
  3980. return value
  3981. def _parse_build(encoded_data, pointer=0, spec=None, spec_params=None, strict=False):
  3982. """
  3983. Parses a byte string generically, or using a spec with optional params
  3984. :param encoded_data:
  3985. A byte string that contains BER-encoded data
  3986. :param pointer:
  3987. The index in the byte string to parse from
  3988. :param spec:
  3989. A class derived from Asn1Value that defines what class_ and tag the
  3990. value should have, and the semantics of the encoded value. The
  3991. return value will be of this type. If omitted, the encoded value
  3992. will be decoded using the standard universal tag based on the
  3993. encoded tag number.
  3994. :param spec_params:
  3995. A dict of params to pass to the spec object
  3996. :param strict:
  3997. A boolean indicating if trailing data should be forbidden - if so, a
  3998. ValueError will be raised when trailing data exists
  3999. :return:
  4000. A 2-element tuple:
  4001. - 0: An object of the type spec, or if not specified, a child of Asn1Value
  4002. - 1: An integer indicating how many bytes were consumed
  4003. """
  4004. encoded_len = len(encoded_data)
  4005. info, new_pointer = _parse(encoded_data, encoded_len, pointer)
  4006. if strict and new_pointer != pointer + encoded_len:
  4007. extra_bytes = pointer + encoded_len - new_pointer
  4008. raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)
  4009. return (_build(*info, spec=spec, spec_params=spec_params), new_pointer)