x509.py 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036
  1. # coding: utf-8
  2. """
  3. ASN.1 type classes for X.509 certificates. Exports the following items:
  4. - Attributes()
  5. - Certificate()
  6. - Extensions()
  7. - GeneralName()
  8. - GeneralNames()
  9. - Name()
  10. Other type classes are defined that help compose the types listed above.
  11. """
  12. from __future__ import unicode_literals, division, absolute_import, print_function
  13. from contextlib import contextmanager
  14. from encodings import idna # noqa
  15. import hashlib
  16. import re
  17. import socket
  18. import stringprep
  19. import sys
  20. import unicodedata
  21. from ._errors import unwrap
  22. from ._iri import iri_to_uri, uri_to_iri
  23. from ._ordereddict import OrderedDict
  24. from ._types import type_name, str_cls, bytes_to_list
  25. from .algos import AlgorithmIdentifier, AnyAlgorithmIdentifier, DigestAlgorithm, SignedDigestAlgorithm
  26. from .core import (
  27. Any,
  28. BitString,
  29. BMPString,
  30. Boolean,
  31. Choice,
  32. Concat,
  33. Enumerated,
  34. GeneralizedTime,
  35. GeneralString,
  36. IA5String,
  37. Integer,
  38. Null,
  39. NumericString,
  40. ObjectIdentifier,
  41. OctetBitString,
  42. OctetString,
  43. ParsableOctetString,
  44. PrintableString,
  45. Sequence,
  46. SequenceOf,
  47. Set,
  48. SetOf,
  49. TeletexString,
  50. UniversalString,
  51. UTCTime,
  52. UTF8String,
  53. VisibleString,
  54. VOID,
  55. )
  56. from .keys import PublicKeyInfo
  57. from .util import int_to_bytes, int_from_bytes, inet_ntop, inet_pton
  58. # The structures in this file are taken from https://tools.ietf.org/html/rfc5280
  59. # and a few other supplementary sources, mostly due to extra supported
  60. # extension and name OIDs
  61. class DNSName(IA5String):
  62. _encoding = 'idna'
  63. _bad_tag = (12, 19)
  64. def __ne__(self, other):
  65. return not self == other
  66. def __eq__(self, other):
  67. """
  68. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.2
  69. :param other:
  70. Another DNSName object
  71. :return:
  72. A boolean
  73. """
  74. if not isinstance(other, DNSName):
  75. return False
  76. return self.__unicode__().lower() == other.__unicode__().lower()
  77. def set(self, value):
  78. """
  79. Sets the value of the DNS name
  80. :param value:
  81. A unicode string
  82. """
  83. if not isinstance(value, str_cls):
  84. raise TypeError(unwrap(
  85. '''
  86. %s value must be a unicode string, not %s
  87. ''',
  88. type_name(self),
  89. type_name(value)
  90. ))
  91. if value.startswith('.'):
  92. encoded_value = b'.' + value[1:].encode(self._encoding)
  93. else:
  94. encoded_value = value.encode(self._encoding)
  95. self._unicode = value
  96. self.contents = encoded_value
  97. self._header = None
  98. if self._trailer != b'':
  99. self._trailer = b''
  100. class URI(IA5String):
  101. def set(self, value):
  102. """
  103. Sets the value of the string
  104. :param value:
  105. A unicode string
  106. """
  107. if not isinstance(value, str_cls):
  108. raise TypeError(unwrap(
  109. '''
  110. %s value must be a unicode string, not %s
  111. ''',
  112. type_name(self),
  113. type_name(value)
  114. ))
  115. self._unicode = value
  116. self.contents = iri_to_uri(value)
  117. self._header = None
  118. if self._trailer != b'':
  119. self._trailer = b''
  120. def __ne__(self, other):
  121. return not self == other
  122. def __eq__(self, other):
  123. """
  124. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.4
  125. :param other:
  126. Another URI object
  127. :return:
  128. A boolean
  129. """
  130. if not isinstance(other, URI):
  131. return False
  132. return iri_to_uri(self.native, True) == iri_to_uri(other.native, True)
  133. def __unicode__(self):
  134. """
  135. :return:
  136. A unicode string
  137. """
  138. if self.contents is None:
  139. return ''
  140. if self._unicode is None:
  141. self._unicode = uri_to_iri(self._merge_chunks())
  142. return self._unicode
  143. class EmailAddress(IA5String):
  144. _contents = None
  145. # If the value has gone through the .set() method, thus normalizing it
  146. _normalized = False
  147. # In the wild we've seen this encoded as a UTF8String and PrintableString
  148. _bad_tag = (12, 19)
  149. @property
  150. def contents(self):
  151. """
  152. :return:
  153. A byte string of the DER-encoded contents of the sequence
  154. """
  155. return self._contents
  156. @contents.setter
  157. def contents(self, value):
  158. """
  159. :param value:
  160. A byte string of the DER-encoded contents of the sequence
  161. """
  162. self._normalized = False
  163. self._contents = value
  164. def set(self, value):
  165. """
  166. Sets the value of the string
  167. :param value:
  168. A unicode string
  169. """
  170. if not isinstance(value, str_cls):
  171. raise TypeError(unwrap(
  172. '''
  173. %s value must be a unicode string, not %s
  174. ''',
  175. type_name(self),
  176. type_name(value)
  177. ))
  178. if value.find('@') != -1:
  179. mailbox, hostname = value.rsplit('@', 1)
  180. encoded_value = mailbox.encode('ascii') + b'@' + hostname.encode('idna')
  181. else:
  182. encoded_value = value.encode('ascii')
  183. self._normalized = True
  184. self._unicode = value
  185. self.contents = encoded_value
  186. self._header = None
  187. if self._trailer != b'':
  188. self._trailer = b''
  189. def __unicode__(self):
  190. """
  191. :return:
  192. A unicode string
  193. """
  194. # We've seen this in the wild as a PrintableString, and since ascii is a
  195. # subset of cp1252, we use the later for decoding to be more user friendly
  196. if self._unicode is None:
  197. contents = self._merge_chunks()
  198. if contents.find(b'@') == -1:
  199. self._unicode = contents.decode('cp1252')
  200. else:
  201. mailbox, hostname = contents.rsplit(b'@', 1)
  202. self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna')
  203. return self._unicode
  204. def __ne__(self, other):
  205. return not self == other
  206. def __eq__(self, other):
  207. """
  208. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.5
  209. :param other:
  210. Another EmailAddress object
  211. :return:
  212. A boolean
  213. """
  214. if not isinstance(other, EmailAddress):
  215. return False
  216. if not self._normalized:
  217. self.set(self.native)
  218. if not other._normalized:
  219. other.set(other.native)
  220. if self._contents.find(b'@') == -1 or other._contents.find(b'@') == -1:
  221. return self._contents == other._contents
  222. other_mailbox, other_hostname = other._contents.rsplit(b'@', 1)
  223. mailbox, hostname = self._contents.rsplit(b'@', 1)
  224. if mailbox != other_mailbox:
  225. return False
  226. if hostname.lower() != other_hostname.lower():
  227. return False
  228. return True
  229. class IPAddress(OctetString):
  230. def parse(self, spec=None, spec_params=None):
  231. """
  232. This method is not applicable to IP addresses
  233. """
  234. raise ValueError(unwrap(
  235. '''
  236. IP address values can not be parsed
  237. '''
  238. ))
  239. def set(self, value):
  240. """
  241. Sets the value of the object
  242. :param value:
  243. A unicode string containing an IPv4 address, IPv4 address with CIDR,
  244. an IPv6 address or IPv6 address with CIDR
  245. """
  246. if not isinstance(value, str_cls):
  247. raise TypeError(unwrap(
  248. '''
  249. %s value must be a unicode string, not %s
  250. ''',
  251. type_name(self),
  252. type_name(value)
  253. ))
  254. original_value = value
  255. has_cidr = value.find('/') != -1
  256. cidr = 0
  257. if has_cidr:
  258. parts = value.split('/', 1)
  259. value = parts[0]
  260. cidr = int(parts[1])
  261. if cidr < 0:
  262. raise ValueError(unwrap(
  263. '''
  264. %s value contains a CIDR range less than 0
  265. ''',
  266. type_name(self)
  267. ))
  268. if value.find(':') != -1:
  269. family = socket.AF_INET6
  270. if cidr > 128:
  271. raise ValueError(unwrap(
  272. '''
  273. %s value contains a CIDR range bigger than 128, the maximum
  274. value for an IPv6 address
  275. ''',
  276. type_name(self)
  277. ))
  278. cidr_size = 128
  279. else:
  280. family = socket.AF_INET
  281. if cidr > 32:
  282. raise ValueError(unwrap(
  283. '''
  284. %s value contains a CIDR range bigger than 32, the maximum
  285. value for an IPv4 address
  286. ''',
  287. type_name(self)
  288. ))
  289. cidr_size = 32
  290. cidr_bytes = b''
  291. if has_cidr:
  292. cidr_mask = '1' * cidr
  293. cidr_mask += '0' * (cidr_size - len(cidr_mask))
  294. cidr_bytes = int_to_bytes(int(cidr_mask, 2))
  295. cidr_bytes = (b'\x00' * ((cidr_size // 8) - len(cidr_bytes))) + cidr_bytes
  296. self._native = original_value
  297. self.contents = inet_pton(family, value) + cidr_bytes
  298. self._bytes = self.contents
  299. self._header = None
  300. if self._trailer != b'':
  301. self._trailer = b''
  302. @property
  303. def native(self):
  304. """
  305. The native Python datatype representation of this value
  306. :return:
  307. A unicode string or None
  308. """
  309. if self.contents is None:
  310. return None
  311. if self._native is None:
  312. byte_string = self.__bytes__()
  313. byte_len = len(byte_string)
  314. value = None
  315. cidr_int = None
  316. if byte_len in set([32, 16]):
  317. value = inet_ntop(socket.AF_INET6, byte_string[0:16])
  318. if byte_len > 16:
  319. cidr_int = int_from_bytes(byte_string[16:])
  320. elif byte_len in set([8, 4]):
  321. value = inet_ntop(socket.AF_INET, byte_string[0:4])
  322. if byte_len > 4:
  323. cidr_int = int_from_bytes(byte_string[4:])
  324. if cidr_int is not None:
  325. cidr_bits = '{0:b}'.format(cidr_int)
  326. cidr = len(cidr_bits.rstrip('0'))
  327. value = value + '/' + str_cls(cidr)
  328. self._native = value
  329. return self._native
  330. def __ne__(self, other):
  331. return not self == other
  332. def __eq__(self, other):
  333. """
  334. :param other:
  335. Another IPAddress object
  336. :return:
  337. A boolean
  338. """
  339. if not isinstance(other, IPAddress):
  340. return False
  341. return self.__bytes__() == other.__bytes__()
  342. class Attribute(Sequence):
  343. _fields = [
  344. ('type', ObjectIdentifier),
  345. ('values', SetOf, {'spec': Any}),
  346. ]
  347. class Attributes(SequenceOf):
  348. _child_spec = Attribute
  349. class KeyUsage(BitString):
  350. _map = {
  351. 0: 'digital_signature',
  352. 1: 'non_repudiation',
  353. 2: 'key_encipherment',
  354. 3: 'data_encipherment',
  355. 4: 'key_agreement',
  356. 5: 'key_cert_sign',
  357. 6: 'crl_sign',
  358. 7: 'encipher_only',
  359. 8: 'decipher_only',
  360. }
  361. class PrivateKeyUsagePeriod(Sequence):
  362. _fields = [
  363. ('not_before', GeneralizedTime, {'implicit': 0, 'optional': True}),
  364. ('not_after', GeneralizedTime, {'implicit': 1, 'optional': True}),
  365. ]
  366. class NotReallyTeletexString(TeletexString):
  367. """
  368. OpenSSL (and probably some other libraries) puts ISO-8859-1
  369. into TeletexString instead of ITU T.61. We use Windows-1252 when
  370. decoding since it is a superset of ISO-8859-1, and less likely to
  371. cause encoding issues, but we stay strict with encoding to prevent
  372. us from creating bad data.
  373. """
  374. _decoding_encoding = 'cp1252'
  375. def __unicode__(self):
  376. """
  377. :return:
  378. A unicode string
  379. """
  380. if self.contents is None:
  381. return ''
  382. if self._unicode is None:
  383. self._unicode = self._merge_chunks().decode(self._decoding_encoding)
  384. return self._unicode
  385. @contextmanager
  386. def strict_teletex():
  387. try:
  388. NotReallyTeletexString._decoding_encoding = 'teletex'
  389. yield
  390. finally:
  391. NotReallyTeletexString._decoding_encoding = 'cp1252'
  392. class DirectoryString(Choice):
  393. _alternatives = [
  394. ('teletex_string', NotReallyTeletexString),
  395. ('printable_string', PrintableString),
  396. ('universal_string', UniversalString),
  397. ('utf8_string', UTF8String),
  398. ('bmp_string', BMPString),
  399. # This is an invalid/bad alternative, but some broken certs use it
  400. ('ia5_string', IA5String),
  401. ]
  402. class NameType(ObjectIdentifier):
  403. _map = {
  404. '2.5.4.3': 'common_name',
  405. '2.5.4.4': 'surname',
  406. '2.5.4.5': 'serial_number',
  407. '2.5.4.6': 'country_name',
  408. '2.5.4.7': 'locality_name',
  409. '2.5.4.8': 'state_or_province_name',
  410. '2.5.4.9': 'street_address',
  411. '2.5.4.10': 'organization_name',
  412. '2.5.4.11': 'organizational_unit_name',
  413. '2.5.4.12': 'title',
  414. '2.5.4.15': 'business_category',
  415. '2.5.4.17': 'postal_code',
  416. '2.5.4.20': 'telephone_number',
  417. '2.5.4.41': 'name',
  418. '2.5.4.42': 'given_name',
  419. '2.5.4.43': 'initials',
  420. '2.5.4.44': 'generation_qualifier',
  421. '2.5.4.45': 'unique_identifier',
  422. '2.5.4.46': 'dn_qualifier',
  423. '2.5.4.65': 'pseudonym',
  424. '2.5.4.97': 'organization_identifier',
  425. # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
  426. '2.23.133.2.1': 'tpm_manufacturer',
  427. '2.23.133.2.2': 'tpm_model',
  428. '2.23.133.2.3': 'tpm_version',
  429. '2.23.133.2.4': 'platform_manufacturer',
  430. '2.23.133.2.5': 'platform_model',
  431. '2.23.133.2.6': 'platform_version',
  432. # https://tools.ietf.org/html/rfc2985#page-26
  433. '1.2.840.113549.1.9.1': 'email_address',
  434. # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf
  435. '1.3.6.1.4.1.311.60.2.1.1': 'incorporation_locality',
  436. '1.3.6.1.4.1.311.60.2.1.2': 'incorporation_state_or_province',
  437. '1.3.6.1.4.1.311.60.2.1.3': 'incorporation_country',
  438. # https://tools.ietf.org/html/rfc4519#section-2.39
  439. '0.9.2342.19200300.100.1.1': 'user_id',
  440. # https://tools.ietf.org/html/rfc2247#section-4
  441. '0.9.2342.19200300.100.1.25': 'domain_component',
  442. # http://www.alvestrand.no/objectid/0.2.262.1.10.7.20.html
  443. '0.2.262.1.10.7.20': 'name_distinguisher',
  444. }
  445. # This order is largely based on observed order seen in EV certs from
  446. # Symantec and DigiCert. Some of the uncommon name-related fields are
  447. # just placed in what seems like a reasonable order.
  448. preferred_order = [
  449. 'incorporation_country',
  450. 'incorporation_state_or_province',
  451. 'incorporation_locality',
  452. 'business_category',
  453. 'serial_number',
  454. 'country_name',
  455. 'postal_code',
  456. 'state_or_province_name',
  457. 'locality_name',
  458. 'street_address',
  459. 'organization_name',
  460. 'organizational_unit_name',
  461. 'title',
  462. 'common_name',
  463. 'user_id',
  464. 'initials',
  465. 'generation_qualifier',
  466. 'surname',
  467. 'given_name',
  468. 'name',
  469. 'pseudonym',
  470. 'dn_qualifier',
  471. 'telephone_number',
  472. 'email_address',
  473. 'domain_component',
  474. 'name_distinguisher',
  475. 'organization_identifier',
  476. 'tpm_manufacturer',
  477. 'tpm_model',
  478. 'tpm_version',
  479. 'platform_manufacturer',
  480. 'platform_model',
  481. 'platform_version',
  482. ]
  483. @classmethod
  484. def preferred_ordinal(cls, attr_name):
  485. """
  486. Returns an ordering value for a particular attribute key.
  487. Unrecognized attributes and OIDs will be sorted lexically at the end.
  488. :return:
  489. An orderable value.
  490. """
  491. attr_name = cls.map(attr_name)
  492. if attr_name in cls.preferred_order:
  493. ordinal = cls.preferred_order.index(attr_name)
  494. else:
  495. ordinal = len(cls.preferred_order)
  496. return (ordinal, attr_name)
  497. @property
  498. def human_friendly(self):
  499. """
  500. :return:
  501. A human-friendly unicode string to display to users
  502. """
  503. return {
  504. 'common_name': 'Common Name',
  505. 'surname': 'Surname',
  506. 'serial_number': 'Serial Number',
  507. 'country_name': 'Country',
  508. 'locality_name': 'Locality',
  509. 'state_or_province_name': 'State/Province',
  510. 'street_address': 'Street Address',
  511. 'organization_name': 'Organization',
  512. 'organizational_unit_name': 'Organizational Unit',
  513. 'title': 'Title',
  514. 'business_category': 'Business Category',
  515. 'postal_code': 'Postal Code',
  516. 'telephone_number': 'Telephone Number',
  517. 'name': 'Name',
  518. 'given_name': 'Given Name',
  519. 'initials': 'Initials',
  520. 'generation_qualifier': 'Generation Qualifier',
  521. 'unique_identifier': 'Unique Identifier',
  522. 'dn_qualifier': 'DN Qualifier',
  523. 'pseudonym': 'Pseudonym',
  524. 'email_address': 'Email Address',
  525. 'incorporation_locality': 'Incorporation Locality',
  526. 'incorporation_state_or_province': 'Incorporation State/Province',
  527. 'incorporation_country': 'Incorporation Country',
  528. 'domain_component': 'Domain Component',
  529. 'name_distinguisher': 'Name Distinguisher',
  530. 'organization_identifier': 'Organization Identifier',
  531. 'tpm_manufacturer': 'TPM Manufacturer',
  532. 'tpm_model': 'TPM Model',
  533. 'tpm_version': 'TPM Version',
  534. 'platform_manufacturer': 'Platform Manufacturer',
  535. 'platform_model': 'Platform Model',
  536. 'platform_version': 'Platform Version',
  537. 'user_id': 'User ID',
  538. }.get(self.native, self.native)
  539. class NameTypeAndValue(Sequence):
  540. _fields = [
  541. ('type', NameType),
  542. ('value', Any),
  543. ]
  544. _oid_pair = ('type', 'value')
  545. _oid_specs = {
  546. 'common_name': DirectoryString,
  547. 'surname': DirectoryString,
  548. 'serial_number': DirectoryString,
  549. 'country_name': DirectoryString,
  550. 'locality_name': DirectoryString,
  551. 'state_or_province_name': DirectoryString,
  552. 'street_address': DirectoryString,
  553. 'organization_name': DirectoryString,
  554. 'organizational_unit_name': DirectoryString,
  555. 'title': DirectoryString,
  556. 'business_category': DirectoryString,
  557. 'postal_code': DirectoryString,
  558. 'telephone_number': PrintableString,
  559. 'name': DirectoryString,
  560. 'given_name': DirectoryString,
  561. 'initials': DirectoryString,
  562. 'generation_qualifier': DirectoryString,
  563. 'unique_identifier': OctetBitString,
  564. 'dn_qualifier': DirectoryString,
  565. 'pseudonym': DirectoryString,
  566. # https://tools.ietf.org/html/rfc2985#page-26
  567. 'email_address': EmailAddress,
  568. # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf
  569. 'incorporation_locality': DirectoryString,
  570. 'incorporation_state_or_province': DirectoryString,
  571. 'incorporation_country': DirectoryString,
  572. 'domain_component': DNSName,
  573. 'name_distinguisher': DirectoryString,
  574. 'organization_identifier': DirectoryString,
  575. 'tpm_manufacturer': UTF8String,
  576. 'tpm_model': UTF8String,
  577. 'tpm_version': UTF8String,
  578. 'platform_manufacturer': UTF8String,
  579. 'platform_model': UTF8String,
  580. 'platform_version': UTF8String,
  581. 'user_id': DirectoryString,
  582. }
  583. _prepped = None
  584. @property
  585. def prepped_value(self):
  586. """
  587. Returns the value after being processed by the internationalized string
  588. preparation as specified by RFC 5280
  589. :return:
  590. A unicode string
  591. """
  592. if self._prepped is None:
  593. self._prepped = self._ldap_string_prep(self['value'].native)
  594. return self._prepped
  595. def __ne__(self, other):
  596. return not self == other
  597. def __eq__(self, other):
  598. """
  599. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
  600. :param other:
  601. Another NameTypeAndValue object
  602. :return:
  603. A boolean
  604. """
  605. if not isinstance(other, NameTypeAndValue):
  606. return False
  607. if other['type'].native != self['type'].native:
  608. return False
  609. return other.prepped_value == self.prepped_value
  610. def _ldap_string_prep(self, string):
  611. """
  612. Implements the internationalized string preparation algorithm from
  613. RFC 4518. https://tools.ietf.org/html/rfc4518#section-2
  614. :param string:
  615. A unicode string to prepare
  616. :return:
  617. A prepared unicode string, ready for comparison
  618. """
  619. # Map step
  620. string = re.sub('[\u00ad\u1806\u034f\u180b-\u180d\ufe0f-\uff00\ufffc]+', '', string)
  621. string = re.sub('[\u0009\u000a\u000b\u000c\u000d\u0085]', ' ', string)
  622. if sys.maxunicode == 0xffff:
  623. # Some installs of Python 2.7 don't support 8-digit unicode escape
  624. # ranges, so we have to break them into pieces
  625. # Original was: \U0001D173-\U0001D17A and \U000E0020-\U000E007F
  626. string = re.sub('\ud834[\udd73-\udd7a]|\udb40[\udc20-\udc7f]|\U000e0001', '', string)
  627. else:
  628. string = re.sub('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]', '', string)
  629. string = re.sub(
  630. '[\u0000-\u0008\u000e-\u001f\u007f-\u0084\u0086-\u009f\u06dd\u070f\u180e\u200c-\u200f'
  631. '\u202a-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb]+',
  632. '',
  633. string
  634. )
  635. string = string.replace('\u200b', '')
  636. string = re.sub('[\u00a0\u1680\u2000-\u200a\u2028-\u2029\u202f\u205f\u3000]', ' ', string)
  637. string = ''.join(map(stringprep.map_table_b2, string))
  638. # Normalize step
  639. string = unicodedata.normalize('NFKC', string)
  640. # Prohibit step
  641. for char in string:
  642. if stringprep.in_table_a1(char):
  643. raise ValueError(unwrap(
  644. '''
  645. X.509 Name objects may not contain unassigned code points
  646. '''
  647. ))
  648. if stringprep.in_table_c8(char):
  649. raise ValueError(unwrap(
  650. '''
  651. X.509 Name objects may not contain change display or
  652. zzzzdeprecated characters
  653. '''
  654. ))
  655. if stringprep.in_table_c3(char):
  656. raise ValueError(unwrap(
  657. '''
  658. X.509 Name objects may not contain private use characters
  659. '''
  660. ))
  661. if stringprep.in_table_c4(char):
  662. raise ValueError(unwrap(
  663. '''
  664. X.509 Name objects may not contain non-character code points
  665. '''
  666. ))
  667. if stringprep.in_table_c5(char):
  668. raise ValueError(unwrap(
  669. '''
  670. X.509 Name objects may not contain surrogate code points
  671. '''
  672. ))
  673. if char == '\ufffd':
  674. raise ValueError(unwrap(
  675. '''
  676. X.509 Name objects may not contain the replacement character
  677. '''
  678. ))
  679. # Check bidirectional step - here we ensure that we are not mixing
  680. # left-to-right and right-to-left text in the string
  681. has_r_and_al_cat = False
  682. has_l_cat = False
  683. for char in string:
  684. if stringprep.in_table_d1(char):
  685. has_r_and_al_cat = True
  686. elif stringprep.in_table_d2(char):
  687. has_l_cat = True
  688. if has_r_and_al_cat:
  689. first_is_r_and_al = stringprep.in_table_d1(string[0])
  690. last_is_r_and_al = stringprep.in_table_d1(string[-1])
  691. if has_l_cat or not first_is_r_and_al or not last_is_r_and_al:
  692. raise ValueError(unwrap(
  693. '''
  694. X.509 Name object contains a malformed bidirectional
  695. sequence
  696. '''
  697. ))
  698. # Insignificant space handling step
  699. string = ' ' + re.sub(' +', ' ', string).strip() + ' '
  700. return string
  701. class RelativeDistinguishedName(SetOf):
  702. _child_spec = NameTypeAndValue
  703. @property
  704. def hashable(self):
  705. """
  706. :return:
  707. A unicode string that can be used as a dict key or in a set
  708. """
  709. output = []
  710. values = self._get_values(self)
  711. for key in sorted(values.keys()):
  712. output.append('%s: %s' % (key, values[key]))
  713. # Unit separator is used here since the normalization process for
  714. # values moves any such character, and the keys are all dotted integers
  715. # or under_score_words
  716. return '\x1F'.join(output)
  717. def __ne__(self, other):
  718. return not self == other
  719. def __eq__(self, other):
  720. """
  721. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
  722. :param other:
  723. Another RelativeDistinguishedName object
  724. :return:
  725. A boolean
  726. """
  727. if not isinstance(other, RelativeDistinguishedName):
  728. return False
  729. if len(self) != len(other):
  730. return False
  731. self_types = self._get_types(self)
  732. other_types = self._get_types(other)
  733. if self_types != other_types:
  734. return False
  735. self_values = self._get_values(self)
  736. other_values = self._get_values(other)
  737. for type_name_ in self_types:
  738. if self_values[type_name_] != other_values[type_name_]:
  739. return False
  740. return True
  741. def _get_types(self, rdn):
  742. """
  743. Returns a set of types contained in an RDN
  744. :param rdn:
  745. A RelativeDistinguishedName object
  746. :return:
  747. A set object with unicode strings of NameTypeAndValue type field
  748. values
  749. """
  750. return set([ntv['type'].native for ntv in rdn])
  751. def _get_values(self, rdn):
  752. """
  753. Returns a dict of prepped values contained in an RDN
  754. :param rdn:
  755. A RelativeDistinguishedName object
  756. :return:
  757. A dict object with unicode strings of NameTypeAndValue value field
  758. values that have been prepped for comparison
  759. """
  760. output = {}
  761. [output.update([(ntv['type'].native, ntv.prepped_value)]) for ntv in rdn]
  762. return output
  763. class RDNSequence(SequenceOf):
  764. _child_spec = RelativeDistinguishedName
  765. @property
  766. def hashable(self):
  767. """
  768. :return:
  769. A unicode string that can be used as a dict key or in a set
  770. """
  771. # Record separator is used here since the normalization process for
  772. # values moves any such character, and the keys are all dotted integers
  773. # or under_score_words
  774. return '\x1E'.join(rdn.hashable for rdn in self)
  775. def __ne__(self, other):
  776. return not self == other
  777. def __eq__(self, other):
  778. """
  779. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
  780. :param other:
  781. Another RDNSequence object
  782. :return:
  783. A boolean
  784. """
  785. if not isinstance(other, RDNSequence):
  786. return False
  787. if len(self) != len(other):
  788. return False
  789. for index, self_rdn in enumerate(self):
  790. if other[index] != self_rdn:
  791. return False
  792. return True
  793. class Name(Choice):
  794. _alternatives = [
  795. ('', RDNSequence),
  796. ]
  797. _human_friendly = None
  798. _sha1 = None
  799. _sha256 = None
  800. @classmethod
  801. def build(cls, name_dict, use_printable=False):
  802. """
  803. Creates a Name object from a dict of unicode string keys and values.
  804. The keys should be from NameType._map, or a dotted-integer OID unicode
  805. string.
  806. :param name_dict:
  807. A dict of name information, e.g. {"common_name": "Will Bond",
  808. "country_name": "US", "organization_name": "Codex Non Sufficit LC"}
  809. :param use_printable:
  810. A bool - if PrintableString should be used for encoding instead of
  811. UTF8String. This is for backwards compatibility with old software.
  812. :return:
  813. An x509.Name object
  814. """
  815. rdns = []
  816. if not use_printable:
  817. encoding_name = 'utf8_string'
  818. encoding_class = UTF8String
  819. else:
  820. encoding_name = 'printable_string'
  821. encoding_class = PrintableString
  822. # Sort the attributes according to NameType.preferred_order
  823. name_dict = OrderedDict(
  824. sorted(
  825. name_dict.items(),
  826. key=lambda item: NameType.preferred_ordinal(item[0])
  827. )
  828. )
  829. for attribute_name, attribute_value in name_dict.items():
  830. attribute_name = NameType.map(attribute_name)
  831. if attribute_name == 'email_address':
  832. value = EmailAddress(attribute_value)
  833. elif attribute_name == 'domain_component':
  834. value = DNSName(attribute_value)
  835. elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']):
  836. value = DirectoryString(
  837. name='printable_string',
  838. value=PrintableString(attribute_value)
  839. )
  840. else:
  841. value = DirectoryString(
  842. name=encoding_name,
  843. value=encoding_class(attribute_value)
  844. )
  845. rdns.append(RelativeDistinguishedName([
  846. NameTypeAndValue({
  847. 'type': attribute_name,
  848. 'value': value
  849. })
  850. ]))
  851. return cls(name='', value=RDNSequence(rdns))
  852. @property
  853. def hashable(self):
  854. """
  855. :return:
  856. A unicode string that can be used as a dict key or in a set
  857. """
  858. return self.chosen.hashable
  859. def __len__(self):
  860. return len(self.chosen)
  861. def __ne__(self, other):
  862. return not self == other
  863. def __eq__(self, other):
  864. """
  865. Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
  866. :param other:
  867. Another Name object
  868. :return:
  869. A boolean
  870. """
  871. if not isinstance(other, Name):
  872. return False
  873. return self.chosen == other.chosen
  874. @property
  875. def native(self):
  876. if self._native is None:
  877. self._native = OrderedDict()
  878. for rdn in self.chosen.native:
  879. for type_val in rdn:
  880. field_name = type_val['type']
  881. if field_name in self._native:
  882. existing = self._native[field_name]
  883. if not isinstance(existing, list):
  884. existing = self._native[field_name] = [existing]
  885. existing.append(type_val['value'])
  886. else:
  887. self._native[field_name] = type_val['value']
  888. return self._native
  889. @property
  890. def human_friendly(self):
  891. """
  892. :return:
  893. A human-friendly unicode string containing the parts of the name
  894. """
  895. if self._human_friendly is None:
  896. data = OrderedDict()
  897. last_field = None
  898. for rdn in self.chosen:
  899. for type_val in rdn:
  900. field_name = type_val['type'].human_friendly
  901. last_field = field_name
  902. if field_name in data:
  903. data[field_name] = [data[field_name]]
  904. data[field_name].append(type_val['value'])
  905. else:
  906. data[field_name] = type_val['value']
  907. to_join = []
  908. keys = data.keys()
  909. if last_field == 'Country':
  910. keys = reversed(list(keys))
  911. for key in keys:
  912. value = data[key]
  913. native_value = self._recursive_humanize(value)
  914. to_join.append('%s: %s' % (key, native_value))
  915. has_comma = False
  916. for element in to_join:
  917. if element.find(',') != -1:
  918. has_comma = True
  919. break
  920. separator = ', ' if not has_comma else '; '
  921. self._human_friendly = separator.join(to_join[::-1])
  922. return self._human_friendly
  923. def _recursive_humanize(self, value):
  924. """
  925. Recursively serializes data compiled from the RDNSequence
  926. :param value:
  927. An Asn1Value object, or a list of Asn1Value objects
  928. :return:
  929. A unicode string
  930. """
  931. if isinstance(value, list):
  932. return ', '.join(
  933. reversed([self._recursive_humanize(sub_value) for sub_value in value])
  934. )
  935. return value.native
  936. @property
  937. def sha1(self):
  938. """
  939. :return:
  940. The SHA1 hash of the DER-encoded bytes of this name
  941. """
  942. if self._sha1 is None:
  943. self._sha1 = hashlib.sha1(self.dump()).digest()
  944. return self._sha1
  945. @property
  946. def sha256(self):
  947. """
  948. :return:
  949. The SHA-256 hash of the DER-encoded bytes of this name
  950. """
  951. if self._sha256 is None:
  952. self._sha256 = hashlib.sha256(self.dump()).digest()
  953. return self._sha256
  954. class AnotherName(Sequence):
  955. _fields = [
  956. ('type_id', ObjectIdentifier),
  957. ('value', Any, {'explicit': 0}),
  958. ]
  959. class CountryName(Choice):
  960. class_ = 1
  961. tag = 1
  962. _alternatives = [
  963. ('x121_dcc_code', NumericString),
  964. ('iso_3166_alpha2_code', PrintableString),
  965. ]
  966. class AdministrationDomainName(Choice):
  967. class_ = 1
  968. tag = 2
  969. _alternatives = [
  970. ('numeric', NumericString),
  971. ('printable', PrintableString),
  972. ]
  973. class PrivateDomainName(Choice):
  974. _alternatives = [
  975. ('numeric', NumericString),
  976. ('printable', PrintableString),
  977. ]
  978. class PersonalName(Set):
  979. _fields = [
  980. ('surname', PrintableString, {'implicit': 0}),
  981. ('given_name', PrintableString, {'implicit': 1, 'optional': True}),
  982. ('initials', PrintableString, {'implicit': 2, 'optional': True}),
  983. ('generation_qualifier', PrintableString, {'implicit': 3, 'optional': True}),
  984. ]
  985. class TeletexPersonalName(Set):
  986. _fields = [
  987. ('surname', TeletexString, {'implicit': 0}),
  988. ('given_name', TeletexString, {'implicit': 1, 'optional': True}),
  989. ('initials', TeletexString, {'implicit': 2, 'optional': True}),
  990. ('generation_qualifier', TeletexString, {'implicit': 3, 'optional': True}),
  991. ]
  992. class OrganizationalUnitNames(SequenceOf):
  993. _child_spec = PrintableString
  994. class TeletexOrganizationalUnitNames(SequenceOf):
  995. _child_spec = TeletexString
  996. class BuiltInStandardAttributes(Sequence):
  997. _fields = [
  998. ('country_name', CountryName, {'optional': True}),
  999. ('administration_domain_name', AdministrationDomainName, {'optional': True}),
  1000. ('network_address', NumericString, {'implicit': 0, 'optional': True}),
  1001. ('terminal_identifier', PrintableString, {'implicit': 1, 'optional': True}),
  1002. ('private_domain_name', PrivateDomainName, {'explicit': 2, 'optional': True}),
  1003. ('organization_name', PrintableString, {'implicit': 3, 'optional': True}),
  1004. ('numeric_user_identifier', NumericString, {'implicit': 4, 'optional': True}),
  1005. ('personal_name', PersonalName, {'implicit': 5, 'optional': True}),
  1006. ('organizational_unit_names', OrganizationalUnitNames, {'implicit': 6, 'optional': True}),
  1007. ]
  1008. class BuiltInDomainDefinedAttribute(Sequence):
  1009. _fields = [
  1010. ('type', PrintableString),
  1011. ('value', PrintableString),
  1012. ]
  1013. class BuiltInDomainDefinedAttributes(SequenceOf):
  1014. _child_spec = BuiltInDomainDefinedAttribute
  1015. class TeletexDomainDefinedAttribute(Sequence):
  1016. _fields = [
  1017. ('type', TeletexString),
  1018. ('value', TeletexString),
  1019. ]
  1020. class TeletexDomainDefinedAttributes(SequenceOf):
  1021. _child_spec = TeletexDomainDefinedAttribute
  1022. class PhysicalDeliveryCountryName(Choice):
  1023. _alternatives = [
  1024. ('x121_dcc_code', NumericString),
  1025. ('iso_3166_alpha2_code', PrintableString),
  1026. ]
  1027. class PostalCode(Choice):
  1028. _alternatives = [
  1029. ('numeric_code', NumericString),
  1030. ('printable_code', PrintableString),
  1031. ]
  1032. class PDSParameter(Set):
  1033. _fields = [
  1034. ('printable_string', PrintableString, {'optional': True}),
  1035. ('teletex_string', TeletexString, {'optional': True}),
  1036. ]
  1037. class PrintableAddress(SequenceOf):
  1038. _child_spec = PrintableString
  1039. class UnformattedPostalAddress(Set):
  1040. _fields = [
  1041. ('printable_address', PrintableAddress, {'optional': True}),
  1042. ('teletex_string', TeletexString, {'optional': True}),
  1043. ]
  1044. class E1634Address(Sequence):
  1045. _fields = [
  1046. ('number', NumericString, {'implicit': 0}),
  1047. ('sub_address', NumericString, {'implicit': 1, 'optional': True}),
  1048. ]
  1049. class NAddresses(SetOf):
  1050. _child_spec = OctetString
  1051. class PresentationAddress(Sequence):
  1052. _fields = [
  1053. ('p_selector', OctetString, {'explicit': 0, 'optional': True}),
  1054. ('s_selector', OctetString, {'explicit': 1, 'optional': True}),
  1055. ('t_selector', OctetString, {'explicit': 2, 'optional': True}),
  1056. ('n_addresses', NAddresses, {'explicit': 3}),
  1057. ]
  1058. class ExtendedNetworkAddress(Choice):
  1059. _alternatives = [
  1060. ('e163_4_address', E1634Address),
  1061. ('psap_address', PresentationAddress, {'implicit': 0})
  1062. ]
  1063. class TerminalType(Integer):
  1064. _map = {
  1065. 3: 'telex',
  1066. 4: 'teletex',
  1067. 5: 'g3_facsimile',
  1068. 6: 'g4_facsimile',
  1069. 7: 'ia5_terminal',
  1070. 8: 'videotex',
  1071. }
  1072. class ExtensionAttributeType(Integer):
  1073. _map = {
  1074. 1: 'common_name',
  1075. 2: 'teletex_common_name',
  1076. 3: 'teletex_organization_name',
  1077. 4: 'teletex_personal_name',
  1078. 5: 'teletex_organization_unit_names',
  1079. 6: 'teletex_domain_defined_attributes',
  1080. 7: 'pds_name',
  1081. 8: 'physical_delivery_country_name',
  1082. 9: 'postal_code',
  1083. 10: 'physical_delivery_office_name',
  1084. 11: 'physical_delivery_office_number',
  1085. 12: 'extension_of_address_components',
  1086. 13: 'physical_delivery_personal_name',
  1087. 14: 'physical_delivery_organization_name',
  1088. 15: 'extension_physical_delivery_address_components',
  1089. 16: 'unformatted_postal_address',
  1090. 17: 'street_address',
  1091. 18: 'post_office_box_address',
  1092. 19: 'poste_restante_address',
  1093. 20: 'unique_postal_name',
  1094. 21: 'local_postal_attributes',
  1095. 22: 'extended_network_address',
  1096. 23: 'terminal_type',
  1097. }
  1098. class ExtensionAttribute(Sequence):
  1099. _fields = [
  1100. ('extension_attribute_type', ExtensionAttributeType, {'implicit': 0}),
  1101. ('extension_attribute_value', Any, {'explicit': 1}),
  1102. ]
  1103. _oid_pair = ('extension_attribute_type', 'extension_attribute_value')
  1104. _oid_specs = {
  1105. 'common_name': PrintableString,
  1106. 'teletex_common_name': TeletexString,
  1107. 'teletex_organization_name': TeletexString,
  1108. 'teletex_personal_name': TeletexPersonalName,
  1109. 'teletex_organization_unit_names': TeletexOrganizationalUnitNames,
  1110. 'teletex_domain_defined_attributes': TeletexDomainDefinedAttributes,
  1111. 'pds_name': PrintableString,
  1112. 'physical_delivery_country_name': PhysicalDeliveryCountryName,
  1113. 'postal_code': PostalCode,
  1114. 'physical_delivery_office_name': PDSParameter,
  1115. 'physical_delivery_office_number': PDSParameter,
  1116. 'extension_of_address_components': PDSParameter,
  1117. 'physical_delivery_personal_name': PDSParameter,
  1118. 'physical_delivery_organization_name': PDSParameter,
  1119. 'extension_physical_delivery_address_components': PDSParameter,
  1120. 'unformatted_postal_address': UnformattedPostalAddress,
  1121. 'street_address': PDSParameter,
  1122. 'post_office_box_address': PDSParameter,
  1123. 'poste_restante_address': PDSParameter,
  1124. 'unique_postal_name': PDSParameter,
  1125. 'local_postal_attributes': PDSParameter,
  1126. 'extended_network_address': ExtendedNetworkAddress,
  1127. 'terminal_type': TerminalType,
  1128. }
  1129. class ExtensionAttributes(SequenceOf):
  1130. _child_spec = ExtensionAttribute
  1131. class ORAddress(Sequence):
  1132. _fields = [
  1133. ('built_in_standard_attributes', BuiltInStandardAttributes),
  1134. ('built_in_domain_defined_attributes', BuiltInDomainDefinedAttributes, {'optional': True}),
  1135. ('extension_attributes', ExtensionAttributes, {'optional': True}),
  1136. ]
  1137. class EDIPartyName(Sequence):
  1138. _fields = [
  1139. ('name_assigner', DirectoryString, {'implicit': 0, 'optional': True}),
  1140. ('party_name', DirectoryString, {'implicit': 1}),
  1141. ]
  1142. class GeneralName(Choice):
  1143. _alternatives = [
  1144. ('other_name', AnotherName, {'implicit': 0}),
  1145. ('rfc822_name', EmailAddress, {'implicit': 1}),
  1146. ('dns_name', DNSName, {'implicit': 2}),
  1147. ('x400_address', ORAddress, {'implicit': 3}),
  1148. ('directory_name', Name, {'explicit': 4}),
  1149. ('edi_party_name', EDIPartyName, {'implicit': 5}),
  1150. ('uniform_resource_identifier', URI, {'implicit': 6}),
  1151. ('ip_address', IPAddress, {'implicit': 7}),
  1152. ('registered_id', ObjectIdentifier, {'implicit': 8}),
  1153. ]
  1154. def __ne__(self, other):
  1155. return not self == other
  1156. def __eq__(self, other):
  1157. """
  1158. Does not support other_name, x400_address or edi_party_name
  1159. :param other:
  1160. The other GeneralName to compare to
  1161. :return:
  1162. A boolean
  1163. """
  1164. if self.name in ('other_name', 'x400_address', 'edi_party_name'):
  1165. raise ValueError(unwrap(
  1166. '''
  1167. Comparison is not supported for GeneralName objects of
  1168. choice %s
  1169. ''',
  1170. self.name
  1171. ))
  1172. if other.name in ('other_name', 'x400_address', 'edi_party_name'):
  1173. raise ValueError(unwrap(
  1174. '''
  1175. Comparison is not supported for GeneralName objects of choice
  1176. %s''',
  1177. other.name
  1178. ))
  1179. if self.name != other.name:
  1180. return False
  1181. return self.chosen == other.chosen
  1182. class GeneralNames(SequenceOf):
  1183. _child_spec = GeneralName
  1184. class Time(Choice):
  1185. _alternatives = [
  1186. ('utc_time', UTCTime),
  1187. ('general_time', GeneralizedTime),
  1188. ]
  1189. class Validity(Sequence):
  1190. _fields = [
  1191. ('not_before', Time),
  1192. ('not_after', Time),
  1193. ]
  1194. class BasicConstraints(Sequence):
  1195. _fields = [
  1196. ('ca', Boolean, {'default': False}),
  1197. ('path_len_constraint', Integer, {'optional': True}),
  1198. ]
  1199. class AuthorityKeyIdentifier(Sequence):
  1200. _fields = [
  1201. ('key_identifier', OctetString, {'implicit': 0, 'optional': True}),
  1202. ('authority_cert_issuer', GeneralNames, {'implicit': 1, 'optional': True}),
  1203. ('authority_cert_serial_number', Integer, {'implicit': 2, 'optional': True}),
  1204. ]
  1205. class DistributionPointName(Choice):
  1206. _alternatives = [
  1207. ('full_name', GeneralNames, {'implicit': 0}),
  1208. ('name_relative_to_crl_issuer', RelativeDistinguishedName, {'implicit': 1}),
  1209. ]
  1210. class ReasonFlags(BitString):
  1211. _map = {
  1212. 0: 'unused',
  1213. 1: 'key_compromise',
  1214. 2: 'ca_compromise',
  1215. 3: 'affiliation_changed',
  1216. 4: 'superseded',
  1217. 5: 'cessation_of_operation',
  1218. 6: 'certificate_hold',
  1219. 7: 'privilege_withdrawn',
  1220. 8: 'aa_compromise',
  1221. }
  1222. class GeneralSubtree(Sequence):
  1223. _fields = [
  1224. ('base', GeneralName),
  1225. ('minimum', Integer, {'implicit': 0, 'default': 0}),
  1226. ('maximum', Integer, {'implicit': 1, 'optional': True}),
  1227. ]
  1228. class GeneralSubtrees(SequenceOf):
  1229. _child_spec = GeneralSubtree
  1230. class NameConstraints(Sequence):
  1231. _fields = [
  1232. ('permitted_subtrees', GeneralSubtrees, {'implicit': 0, 'optional': True}),
  1233. ('excluded_subtrees', GeneralSubtrees, {'implicit': 1, 'optional': True}),
  1234. ]
  1235. class DistributionPoint(Sequence):
  1236. _fields = [
  1237. ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}),
  1238. ('reasons', ReasonFlags, {'implicit': 1, 'optional': True}),
  1239. ('crl_issuer', GeneralNames, {'implicit': 2, 'optional': True}),
  1240. ]
  1241. _url = False
  1242. @property
  1243. def url(self):
  1244. """
  1245. :return:
  1246. None or a unicode string of the distribution point's URL
  1247. """
  1248. if self._url is False:
  1249. self._url = None
  1250. name = self['distribution_point']
  1251. if name.name != 'full_name':
  1252. raise ValueError(unwrap(
  1253. '''
  1254. CRL distribution points that are relative to the issuer are
  1255. not supported
  1256. '''
  1257. ))
  1258. for general_name in name.chosen:
  1259. if general_name.name == 'uniform_resource_identifier':
  1260. url = general_name.native
  1261. if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):
  1262. self._url = url
  1263. break
  1264. return self._url
  1265. class CRLDistributionPoints(SequenceOf):
  1266. _child_spec = DistributionPoint
  1267. class DisplayText(Choice):
  1268. _alternatives = [
  1269. ('ia5_string', IA5String),
  1270. ('visible_string', VisibleString),
  1271. ('bmp_string', BMPString),
  1272. ('utf8_string', UTF8String),
  1273. ]
  1274. class NoticeNumbers(SequenceOf):
  1275. _child_spec = Integer
  1276. class NoticeReference(Sequence):
  1277. _fields = [
  1278. ('organization', DisplayText),
  1279. ('notice_numbers', NoticeNumbers),
  1280. ]
  1281. class UserNotice(Sequence):
  1282. _fields = [
  1283. ('notice_ref', NoticeReference, {'optional': True}),
  1284. ('explicit_text', DisplayText, {'optional': True}),
  1285. ]
  1286. class PolicyQualifierId(ObjectIdentifier):
  1287. _map = {
  1288. '1.3.6.1.5.5.7.2.1': 'certification_practice_statement',
  1289. '1.3.6.1.5.5.7.2.2': 'user_notice',
  1290. }
  1291. class PolicyQualifierInfo(Sequence):
  1292. _fields = [
  1293. ('policy_qualifier_id', PolicyQualifierId),
  1294. ('qualifier', Any),
  1295. ]
  1296. _oid_pair = ('policy_qualifier_id', 'qualifier')
  1297. _oid_specs = {
  1298. 'certification_practice_statement': IA5String,
  1299. 'user_notice': UserNotice,
  1300. }
  1301. class PolicyQualifierInfos(SequenceOf):
  1302. _child_spec = PolicyQualifierInfo
  1303. class PolicyIdentifier(ObjectIdentifier):
  1304. _map = {
  1305. '2.5.29.32.0': 'any_policy',
  1306. }
  1307. class PolicyInformation(Sequence):
  1308. _fields = [
  1309. ('policy_identifier', PolicyIdentifier),
  1310. ('policy_qualifiers', PolicyQualifierInfos, {'optional': True})
  1311. ]
  1312. class CertificatePolicies(SequenceOf):
  1313. _child_spec = PolicyInformation
  1314. class PolicyMapping(Sequence):
  1315. _fields = [
  1316. ('issuer_domain_policy', PolicyIdentifier),
  1317. ('subject_domain_policy', PolicyIdentifier),
  1318. ]
  1319. class PolicyMappings(SequenceOf):
  1320. _child_spec = PolicyMapping
  1321. class PolicyConstraints(Sequence):
  1322. _fields = [
  1323. ('require_explicit_policy', Integer, {'implicit': 0, 'optional': True}),
  1324. ('inhibit_policy_mapping', Integer, {'implicit': 1, 'optional': True}),
  1325. ]
  1326. class KeyPurposeId(ObjectIdentifier):
  1327. _map = {
  1328. # https://tools.ietf.org/html/rfc5280#page-45
  1329. '2.5.29.37.0': 'any_extended_key_usage',
  1330. '1.3.6.1.5.5.7.3.1': 'server_auth',
  1331. '1.3.6.1.5.5.7.3.2': 'client_auth',
  1332. '1.3.6.1.5.5.7.3.3': 'code_signing',
  1333. '1.3.6.1.5.5.7.3.4': 'email_protection',
  1334. '1.3.6.1.5.5.7.3.5': 'ipsec_end_system',
  1335. '1.3.6.1.5.5.7.3.6': 'ipsec_tunnel',
  1336. '1.3.6.1.5.5.7.3.7': 'ipsec_user',
  1337. '1.3.6.1.5.5.7.3.8': 'time_stamping',
  1338. '1.3.6.1.5.5.7.3.9': 'ocsp_signing',
  1339. # http://tools.ietf.org/html/rfc3029.html#page-9
  1340. '1.3.6.1.5.5.7.3.10': 'dvcs',
  1341. # http://tools.ietf.org/html/rfc6268.html#page-16
  1342. '1.3.6.1.5.5.7.3.13': 'eap_over_ppp',
  1343. '1.3.6.1.5.5.7.3.14': 'eap_over_lan',
  1344. # https://tools.ietf.org/html/rfc5055#page-76
  1345. '1.3.6.1.5.5.7.3.15': 'scvp_server',
  1346. '1.3.6.1.5.5.7.3.16': 'scvp_client',
  1347. # https://tools.ietf.org/html/rfc4945#page-31
  1348. '1.3.6.1.5.5.7.3.17': 'ipsec_ike',
  1349. # https://tools.ietf.org/html/rfc5415#page-38
  1350. '1.3.6.1.5.5.7.3.18': 'capwap_ac',
  1351. '1.3.6.1.5.5.7.3.19': 'capwap_wtp',
  1352. # https://tools.ietf.org/html/rfc5924#page-8
  1353. '1.3.6.1.5.5.7.3.20': 'sip_domain',
  1354. # https://tools.ietf.org/html/rfc6187#page-7
  1355. '1.3.6.1.5.5.7.3.21': 'secure_shell_client',
  1356. '1.3.6.1.5.5.7.3.22': 'secure_shell_server',
  1357. # https://tools.ietf.org/html/rfc6494#page-7
  1358. '1.3.6.1.5.5.7.3.23': 'send_router',
  1359. '1.3.6.1.5.5.7.3.24': 'send_proxied_router',
  1360. '1.3.6.1.5.5.7.3.25': 'send_owner',
  1361. '1.3.6.1.5.5.7.3.26': 'send_proxied_owner',
  1362. # https://tools.ietf.org/html/rfc6402#page-10
  1363. '1.3.6.1.5.5.7.3.27': 'cmc_ca',
  1364. '1.3.6.1.5.5.7.3.28': 'cmc_ra',
  1365. '1.3.6.1.5.5.7.3.29': 'cmc_archive',
  1366. # https://tools.ietf.org/html/draft-ietf-sidr-bgpsec-pki-profiles-15#page-6
  1367. '1.3.6.1.5.5.7.3.30': 'bgpspec_router',
  1368. # https://www.ietf.org/proceedings/44/I-D/draft-ietf-ipsec-pki-req-01.txt
  1369. '1.3.6.1.5.5.8.2.2': 'ike_intermediate',
  1370. # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378132(v=vs.85).aspx
  1371. # and https://support.microsoft.com/en-us/kb/287547
  1372. '1.3.6.1.4.1.311.10.3.1': 'microsoft_trust_list_signing',
  1373. '1.3.6.1.4.1.311.10.3.2': 'microsoft_time_stamp_signing',
  1374. '1.3.6.1.4.1.311.10.3.3': 'microsoft_server_gated',
  1375. '1.3.6.1.4.1.311.10.3.3.1': 'microsoft_serialized',
  1376. '1.3.6.1.4.1.311.10.3.4': 'microsoft_efs',
  1377. '1.3.6.1.4.1.311.10.3.4.1': 'microsoft_efs_recovery',
  1378. '1.3.6.1.4.1.311.10.3.5': 'microsoft_whql',
  1379. '1.3.6.1.4.1.311.10.3.6': 'microsoft_nt5',
  1380. '1.3.6.1.4.1.311.10.3.7': 'microsoft_oem_whql',
  1381. '1.3.6.1.4.1.311.10.3.8': 'microsoft_embedded_nt',
  1382. '1.3.6.1.4.1.311.10.3.9': 'microsoft_root_list_signer',
  1383. '1.3.6.1.4.1.311.10.3.10': 'microsoft_qualified_subordination',
  1384. '1.3.6.1.4.1.311.10.3.11': 'microsoft_key_recovery',
  1385. '1.3.6.1.4.1.311.10.3.12': 'microsoft_document_signing',
  1386. '1.3.6.1.4.1.311.10.3.13': 'microsoft_lifetime_signing',
  1387. '1.3.6.1.4.1.311.10.3.14': 'microsoft_mobile_device_software',
  1388. # https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography
  1389. '1.3.6.1.4.1.311.20.2.2': 'microsoft_smart_card_logon',
  1390. # https://opensource.apple.com/source
  1391. # - /Security/Security-57031.40.6/Security/libsecurity_keychain/lib/SecPolicy.cpp
  1392. # - /libsecurity_cssm/libsecurity_cssm-36064/lib/oidsalg.c
  1393. '1.2.840.113635.100.1.2': 'apple_x509_basic',
  1394. '1.2.840.113635.100.1.3': 'apple_ssl',
  1395. '1.2.840.113635.100.1.4': 'apple_local_cert_gen',
  1396. '1.2.840.113635.100.1.5': 'apple_csr_gen',
  1397. '1.2.840.113635.100.1.6': 'apple_revocation_crl',
  1398. '1.2.840.113635.100.1.7': 'apple_revocation_ocsp',
  1399. '1.2.840.113635.100.1.8': 'apple_smime',
  1400. '1.2.840.113635.100.1.9': 'apple_eap',
  1401. '1.2.840.113635.100.1.10': 'apple_software_update_signing',
  1402. '1.2.840.113635.100.1.11': 'apple_ipsec',
  1403. '1.2.840.113635.100.1.12': 'apple_ichat',
  1404. '1.2.840.113635.100.1.13': 'apple_resource_signing',
  1405. '1.2.840.113635.100.1.14': 'apple_pkinit_client',
  1406. '1.2.840.113635.100.1.15': 'apple_pkinit_server',
  1407. '1.2.840.113635.100.1.16': 'apple_code_signing',
  1408. '1.2.840.113635.100.1.17': 'apple_package_signing',
  1409. '1.2.840.113635.100.1.18': 'apple_id_validation',
  1410. '1.2.840.113635.100.1.20': 'apple_time_stamping',
  1411. '1.2.840.113635.100.1.21': 'apple_revocation',
  1412. '1.2.840.113635.100.1.22': 'apple_passbook_signing',
  1413. '1.2.840.113635.100.1.23': 'apple_mobile_store',
  1414. '1.2.840.113635.100.1.24': 'apple_escrow_service',
  1415. '1.2.840.113635.100.1.25': 'apple_profile_signer',
  1416. '1.2.840.113635.100.1.26': 'apple_qa_profile_signer',
  1417. '1.2.840.113635.100.1.27': 'apple_test_mobile_store',
  1418. '1.2.840.113635.100.1.28': 'apple_otapki_signer',
  1419. '1.2.840.113635.100.1.29': 'apple_test_otapki_signer',
  1420. '1.2.840.113625.100.1.30': 'apple_id_validation_record_signing_policy',
  1421. '1.2.840.113625.100.1.31': 'apple_smp_encryption',
  1422. '1.2.840.113625.100.1.32': 'apple_test_smp_encryption',
  1423. '1.2.840.113635.100.1.33': 'apple_server_authentication',
  1424. '1.2.840.113635.100.1.34': 'apple_pcs_escrow_service',
  1425. # http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.201-2.pdf
  1426. '2.16.840.1.101.3.6.8': 'piv_card_authentication',
  1427. '2.16.840.1.101.3.6.7': 'piv_content_signing',
  1428. # https://tools.ietf.org/html/rfc4556.html
  1429. '1.3.6.1.5.2.3.4': 'pkinit_kpclientauth',
  1430. '1.3.6.1.5.2.3.5': 'pkinit_kpkdc',
  1431. # https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/changes.html
  1432. '1.2.840.113583.1.1.5': 'adobe_authentic_documents_trust',
  1433. # https://www.idmanagement.gov/wp-content/uploads/sites/1171/uploads/fpki-pivi-cert-profiles.pdf
  1434. '2.16.840.1.101.3.8.7': 'fpki_pivi_content_signing'
  1435. }
  1436. class ExtKeyUsageSyntax(SequenceOf):
  1437. _child_spec = KeyPurposeId
  1438. class AccessMethod(ObjectIdentifier):
  1439. _map = {
  1440. '1.3.6.1.5.5.7.48.1': 'ocsp',
  1441. '1.3.6.1.5.5.7.48.2': 'ca_issuers',
  1442. '1.3.6.1.5.5.7.48.3': 'time_stamping',
  1443. '1.3.6.1.5.5.7.48.5': 'ca_repository',
  1444. }
  1445. class AccessDescription(Sequence):
  1446. _fields = [
  1447. ('access_method', AccessMethod),
  1448. ('access_location', GeneralName),
  1449. ]
  1450. class AuthorityInfoAccessSyntax(SequenceOf):
  1451. _child_spec = AccessDescription
  1452. class SubjectInfoAccessSyntax(SequenceOf):
  1453. _child_spec = AccessDescription
  1454. # https://tools.ietf.org/html/rfc7633
  1455. class Features(SequenceOf):
  1456. _child_spec = Integer
  1457. class EntrustVersionInfo(Sequence):
  1458. _fields = [
  1459. ('entrust_vers', GeneralString),
  1460. ('entrust_info_flags', BitString)
  1461. ]
  1462. class NetscapeCertificateType(BitString):
  1463. _map = {
  1464. 0: 'ssl_client',
  1465. 1: 'ssl_server',
  1466. 2: 'email',
  1467. 3: 'object_signing',
  1468. 4: 'reserved',
  1469. 5: 'ssl_ca',
  1470. 6: 'email_ca',
  1471. 7: 'object_signing_ca',
  1472. }
  1473. class Version(Integer):
  1474. _map = {
  1475. 0: 'v1',
  1476. 1: 'v2',
  1477. 2: 'v3',
  1478. }
  1479. class TPMSpecification(Sequence):
  1480. _fields = [
  1481. ('family', UTF8String),
  1482. ('level', Integer),
  1483. ('revision', Integer),
  1484. ]
  1485. class SetOfTPMSpecification(SetOf):
  1486. _child_spec = TPMSpecification
  1487. class TCGSpecificationVersion(Sequence):
  1488. _fields = [
  1489. ('major_version', Integer),
  1490. ('minor_version', Integer),
  1491. ('revision', Integer),
  1492. ]
  1493. class TCGPlatformSpecification(Sequence):
  1494. _fields = [
  1495. ('version', TCGSpecificationVersion),
  1496. ('platform_class', OctetString),
  1497. ]
  1498. class SetOfTCGPlatformSpecification(SetOf):
  1499. _child_spec = TCGPlatformSpecification
  1500. class EKGenerationType(Enumerated):
  1501. _map = {
  1502. 0: 'internal',
  1503. 1: 'injected',
  1504. 2: 'internal_revocable',
  1505. 3: 'injected_revocable',
  1506. }
  1507. class EKGenerationLocation(Enumerated):
  1508. _map = {
  1509. 0: 'tpm_manufacturer',
  1510. 1: 'platform_manufacturer',
  1511. 2: 'ek_cert_signer',
  1512. }
  1513. class EKCertificateGenerationLocation(Enumerated):
  1514. _map = {
  1515. 0: 'tpm_manufacturer',
  1516. 1: 'platform_manufacturer',
  1517. 2: 'ek_cert_signer',
  1518. }
  1519. class EvaluationAssuranceLevel(Enumerated):
  1520. _map = {
  1521. 1: 'level1',
  1522. 2: 'level2',
  1523. 3: 'level3',
  1524. 4: 'level4',
  1525. 5: 'level5',
  1526. 6: 'level6',
  1527. 7: 'level7',
  1528. }
  1529. class EvaluationStatus(Enumerated):
  1530. _map = {
  1531. 0: 'designed_to_meet',
  1532. 1: 'evaluation_in_progress',
  1533. 2: 'evaluation_completed',
  1534. }
  1535. class StrengthOfFunction(Enumerated):
  1536. _map = {
  1537. 0: 'basic',
  1538. 1: 'medium',
  1539. 2: 'high',
  1540. }
  1541. class URIReference(Sequence):
  1542. _fields = [
  1543. ('uniform_resource_identifier', IA5String),
  1544. ('hash_algorithm', DigestAlgorithm, {'optional': True}),
  1545. ('hash_value', BitString, {'optional': True}),
  1546. ]
  1547. class CommonCriteriaMeasures(Sequence):
  1548. _fields = [
  1549. ('version', IA5String),
  1550. ('assurance_level', EvaluationAssuranceLevel),
  1551. ('evaluation_status', EvaluationStatus),
  1552. ('plus', Boolean, {'default': False}),
  1553. ('strengh_of_function', StrengthOfFunction, {'implicit': 0, 'optional': True}),
  1554. ('profile_oid', ObjectIdentifier, {'implicit': 1, 'optional': True}),
  1555. ('profile_url', URIReference, {'implicit': 2, 'optional': True}),
  1556. ('target_oid', ObjectIdentifier, {'implicit': 3, 'optional': True}),
  1557. ('target_uri', URIReference, {'implicit': 4, 'optional': True}),
  1558. ]
  1559. class SecurityLevel(Enumerated):
  1560. _map = {
  1561. 1: 'level1',
  1562. 2: 'level2',
  1563. 3: 'level3',
  1564. 4: 'level4',
  1565. }
  1566. class FIPSLevel(Sequence):
  1567. _fields = [
  1568. ('version', IA5String),
  1569. ('level', SecurityLevel),
  1570. ('plus', Boolean, {'default': False}),
  1571. ]
  1572. class TPMSecurityAssertions(Sequence):
  1573. _fields = [
  1574. ('version', Version, {'default': 'v1'}),
  1575. ('field_upgradable', Boolean, {'default': False}),
  1576. ('ek_generation_type', EKGenerationType, {'implicit': 0, 'optional': True}),
  1577. ('ek_generation_location', EKGenerationLocation, {'implicit': 1, 'optional': True}),
  1578. ('ek_certificate_generation_location', EKCertificateGenerationLocation, {'implicit': 2, 'optional': True}),
  1579. ('cc_info', CommonCriteriaMeasures, {'implicit': 3, 'optional': True}),
  1580. ('fips_level', FIPSLevel, {'implicit': 4, 'optional': True}),
  1581. ('iso_9000_certified', Boolean, {'implicit': 5, 'default': False}),
  1582. ('iso_9000_uri', IA5String, {'optional': True}),
  1583. ]
  1584. class SetOfTPMSecurityAssertions(SetOf):
  1585. _child_spec = TPMSecurityAssertions
  1586. class SubjectDirectoryAttributeId(ObjectIdentifier):
  1587. _map = {
  1588. # https://tools.ietf.org/html/rfc2256#page-11
  1589. '2.5.4.52': 'supported_algorithms',
  1590. # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
  1591. '2.23.133.2.16': 'tpm_specification',
  1592. '2.23.133.2.17': 'tcg_platform_specification',
  1593. '2.23.133.2.18': 'tpm_security_assertions',
  1594. # https://tools.ietf.org/html/rfc3739#page-18
  1595. '1.3.6.1.5.5.7.9.1': 'pda_date_of_birth',
  1596. '1.3.6.1.5.5.7.9.2': 'pda_place_of_birth',
  1597. '1.3.6.1.5.5.7.9.3': 'pda_gender',
  1598. '1.3.6.1.5.5.7.9.4': 'pda_country_of_citizenship',
  1599. '1.3.6.1.5.5.7.9.5': 'pda_country_of_residence',
  1600. # https://holtstrom.com/michael/tools/asn1decoder.php
  1601. '1.2.840.113533.7.68.29': 'entrust_user_role',
  1602. }
  1603. class SetOfGeneralizedTime(SetOf):
  1604. _child_spec = GeneralizedTime
  1605. class SetOfDirectoryString(SetOf):
  1606. _child_spec = DirectoryString
  1607. class SetOfPrintableString(SetOf):
  1608. _child_spec = PrintableString
  1609. class SupportedAlgorithm(Sequence):
  1610. _fields = [
  1611. ('algorithm_identifier', AnyAlgorithmIdentifier),
  1612. ('intended_usage', KeyUsage, {'explicit': 0, 'optional': True}),
  1613. ('intended_certificate_policies', CertificatePolicies, {'explicit': 1, 'optional': True}),
  1614. ]
  1615. class SetOfSupportedAlgorithm(SetOf):
  1616. _child_spec = SupportedAlgorithm
  1617. class SubjectDirectoryAttribute(Sequence):
  1618. _fields = [
  1619. ('type', SubjectDirectoryAttributeId),
  1620. ('values', Any),
  1621. ]
  1622. _oid_pair = ('type', 'values')
  1623. _oid_specs = {
  1624. 'supported_algorithms': SetOfSupportedAlgorithm,
  1625. 'tpm_specification': SetOfTPMSpecification,
  1626. 'tcg_platform_specification': SetOfTCGPlatformSpecification,
  1627. 'tpm_security_assertions': SetOfTPMSecurityAssertions,
  1628. 'pda_date_of_birth': SetOfGeneralizedTime,
  1629. 'pda_place_of_birth': SetOfDirectoryString,
  1630. 'pda_gender': SetOfPrintableString,
  1631. 'pda_country_of_citizenship': SetOfPrintableString,
  1632. 'pda_country_of_residence': SetOfPrintableString,
  1633. }
  1634. def _values_spec(self):
  1635. type_ = self['type'].native
  1636. if type_ in self._oid_specs:
  1637. return self._oid_specs[type_]
  1638. return SetOf
  1639. _spec_callbacks = {
  1640. 'values': _values_spec
  1641. }
  1642. class SubjectDirectoryAttributes(SequenceOf):
  1643. _child_spec = SubjectDirectoryAttribute
  1644. class ExtensionId(ObjectIdentifier):
  1645. _map = {
  1646. '2.5.29.9': 'subject_directory_attributes',
  1647. '2.5.29.14': 'key_identifier',
  1648. '2.5.29.15': 'key_usage',
  1649. '2.5.29.16': 'private_key_usage_period',
  1650. '2.5.29.17': 'subject_alt_name',
  1651. '2.5.29.18': 'issuer_alt_name',
  1652. '2.5.29.19': 'basic_constraints',
  1653. '2.5.29.30': 'name_constraints',
  1654. '2.5.29.31': 'crl_distribution_points',
  1655. '2.5.29.32': 'certificate_policies',
  1656. '2.5.29.33': 'policy_mappings',
  1657. '2.5.29.35': 'authority_key_identifier',
  1658. '2.5.29.36': 'policy_constraints',
  1659. '2.5.29.37': 'extended_key_usage',
  1660. '2.5.29.46': 'freshest_crl',
  1661. '2.5.29.54': 'inhibit_any_policy',
  1662. '1.3.6.1.5.5.7.1.1': 'authority_information_access',
  1663. '1.3.6.1.5.5.7.1.11': 'subject_information_access',
  1664. # https://tools.ietf.org/html/rfc7633
  1665. '1.3.6.1.5.5.7.1.24': 'tls_feature',
  1666. '1.3.6.1.5.5.7.48.1.5': 'ocsp_no_check',
  1667. '1.2.840.113533.7.65.0': 'entrust_version_extension',
  1668. '2.16.840.1.113730.1.1': 'netscape_certificate_type',
  1669. # https://tools.ietf.org/html/rfc6962.html#page-14
  1670. '1.3.6.1.4.1.11129.2.4.2': 'signed_certificate_timestamp_list',
  1671. # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/3aec3e50-511a-42f9-a5d5-240af503e470
  1672. '1.3.6.1.4.1.311.20.2': 'microsoft_enroll_certtype',
  1673. }
  1674. class Extension(Sequence):
  1675. _fields = [
  1676. ('extn_id', ExtensionId),
  1677. ('critical', Boolean, {'default': False}),
  1678. ('extn_value', ParsableOctetString),
  1679. ]
  1680. _oid_pair = ('extn_id', 'extn_value')
  1681. _oid_specs = {
  1682. 'subject_directory_attributes': SubjectDirectoryAttributes,
  1683. 'key_identifier': OctetString,
  1684. 'key_usage': KeyUsage,
  1685. 'private_key_usage_period': PrivateKeyUsagePeriod,
  1686. 'subject_alt_name': GeneralNames,
  1687. 'issuer_alt_name': GeneralNames,
  1688. 'basic_constraints': BasicConstraints,
  1689. 'name_constraints': NameConstraints,
  1690. 'crl_distribution_points': CRLDistributionPoints,
  1691. 'certificate_policies': CertificatePolicies,
  1692. 'policy_mappings': PolicyMappings,
  1693. 'authority_key_identifier': AuthorityKeyIdentifier,
  1694. 'policy_constraints': PolicyConstraints,
  1695. 'extended_key_usage': ExtKeyUsageSyntax,
  1696. 'freshest_crl': CRLDistributionPoints,
  1697. 'inhibit_any_policy': Integer,
  1698. 'authority_information_access': AuthorityInfoAccessSyntax,
  1699. 'subject_information_access': SubjectInfoAccessSyntax,
  1700. 'tls_feature': Features,
  1701. 'ocsp_no_check': Null,
  1702. 'entrust_version_extension': EntrustVersionInfo,
  1703. 'netscape_certificate_type': NetscapeCertificateType,
  1704. 'signed_certificate_timestamp_list': OctetString,
  1705. # Not UTF8String as Microsofts docs claim, see:
  1706. # https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.20.2.html
  1707. 'microsoft_enroll_certtype': BMPString,
  1708. }
  1709. class Extensions(SequenceOf):
  1710. _child_spec = Extension
  1711. class TbsCertificate(Sequence):
  1712. _fields = [
  1713. ('version', Version, {'explicit': 0, 'default': 'v1'}),
  1714. ('serial_number', Integer),
  1715. ('signature', SignedDigestAlgorithm),
  1716. ('issuer', Name),
  1717. ('validity', Validity),
  1718. ('subject', Name),
  1719. ('subject_public_key_info', PublicKeyInfo),
  1720. ('issuer_unique_id', OctetBitString, {'implicit': 1, 'optional': True}),
  1721. ('subject_unique_id', OctetBitString, {'implicit': 2, 'optional': True}),
  1722. ('extensions', Extensions, {'explicit': 3, 'optional': True}),
  1723. ]
  1724. class Certificate(Sequence):
  1725. _fields = [
  1726. ('tbs_certificate', TbsCertificate),
  1727. ('signature_algorithm', SignedDigestAlgorithm),
  1728. ('signature_value', OctetBitString),
  1729. ]
  1730. _processed_extensions = False
  1731. _critical_extensions = None
  1732. _subject_directory_attributes_value = None
  1733. _key_identifier_value = None
  1734. _key_usage_value = None
  1735. _subject_alt_name_value = None
  1736. _issuer_alt_name_value = None
  1737. _basic_constraints_value = None
  1738. _name_constraints_value = None
  1739. _crl_distribution_points_value = None
  1740. _certificate_policies_value = None
  1741. _policy_mappings_value = None
  1742. _authority_key_identifier_value = None
  1743. _policy_constraints_value = None
  1744. _freshest_crl_value = None
  1745. _inhibit_any_policy_value = None
  1746. _extended_key_usage_value = None
  1747. _authority_information_access_value = None
  1748. _subject_information_access_value = None
  1749. _private_key_usage_period_value = None
  1750. _tls_feature_value = None
  1751. _ocsp_no_check_value = None
  1752. _issuer_serial = None
  1753. _authority_issuer_serial = False
  1754. _crl_distribution_points = None
  1755. _delta_crl_distribution_points = None
  1756. _valid_domains = None
  1757. _valid_ips = None
  1758. _self_issued = None
  1759. _self_signed = None
  1760. _sha1 = None
  1761. _sha256 = None
  1762. def _set_extensions(self):
  1763. """
  1764. Sets common named extensions to private attributes and creates a list
  1765. of critical extensions
  1766. """
  1767. self._critical_extensions = set()
  1768. for extension in self['tbs_certificate']['extensions']:
  1769. name = extension['extn_id'].native
  1770. attribute_name = '_%s_value' % name
  1771. if hasattr(self, attribute_name):
  1772. setattr(self, attribute_name, extension['extn_value'].parsed)
  1773. if extension['critical'].native:
  1774. self._critical_extensions.add(name)
  1775. self._processed_extensions = True
  1776. @property
  1777. def critical_extensions(self):
  1778. """
  1779. Returns a set of the names (or OID if not a known extension) of the
  1780. extensions marked as critical
  1781. :return:
  1782. A set of unicode strings
  1783. """
  1784. if not self._processed_extensions:
  1785. self._set_extensions()
  1786. return self._critical_extensions
  1787. @property
  1788. def private_key_usage_period_value(self):
  1789. """
  1790. This extension is used to constrain the period over which the subject
  1791. private key may be used
  1792. :return:
  1793. None or a PrivateKeyUsagePeriod object
  1794. """
  1795. if not self._processed_extensions:
  1796. self._set_extensions()
  1797. return self._private_key_usage_period_value
  1798. @property
  1799. def subject_directory_attributes_value(self):
  1800. """
  1801. This extension is used to contain additional identification attributes
  1802. about the subject.
  1803. :return:
  1804. None or a SubjectDirectoryAttributes object
  1805. """
  1806. if not self._processed_extensions:
  1807. self._set_extensions()
  1808. return self._subject_directory_attributes_value
  1809. @property
  1810. def key_identifier_value(self):
  1811. """
  1812. This extension is used to help in creating certificate validation paths.
  1813. It contains an identifier that should generally, but is not guaranteed
  1814. to, be unique.
  1815. :return:
  1816. None or an OctetString object
  1817. """
  1818. if not self._processed_extensions:
  1819. self._set_extensions()
  1820. return self._key_identifier_value
  1821. @property
  1822. def key_usage_value(self):
  1823. """
  1824. This extension is used to define the purpose of the public key
  1825. contained within the certificate.
  1826. :return:
  1827. None or a KeyUsage
  1828. """
  1829. if not self._processed_extensions:
  1830. self._set_extensions()
  1831. return self._key_usage_value
  1832. @property
  1833. def subject_alt_name_value(self):
  1834. """
  1835. This extension allows for additional names to be associate with the
  1836. subject of the certificate. While it may contain a whole host of
  1837. possible names, it is usually used to allow certificates to be used
  1838. with multiple different domain names.
  1839. :return:
  1840. None or a GeneralNames object
  1841. """
  1842. if not self._processed_extensions:
  1843. self._set_extensions()
  1844. return self._subject_alt_name_value
  1845. @property
  1846. def issuer_alt_name_value(self):
  1847. """
  1848. This extension allows associating one or more alternative names with
  1849. the issuer of the certificate.
  1850. :return:
  1851. None or an x509.GeneralNames object
  1852. """
  1853. if not self._processed_extensions:
  1854. self._set_extensions()
  1855. return self._issuer_alt_name_value
  1856. @property
  1857. def basic_constraints_value(self):
  1858. """
  1859. This extension is used to determine if the subject of the certificate
  1860. is a CA, and if so, what the maximum number of intermediate CA certs
  1861. after this are, before an end-entity certificate is found.
  1862. :return:
  1863. None or a BasicConstraints object
  1864. """
  1865. if not self._processed_extensions:
  1866. self._set_extensions()
  1867. return self._basic_constraints_value
  1868. @property
  1869. def name_constraints_value(self):
  1870. """
  1871. This extension is used in CA certificates, and is used to limit the
  1872. possible names of certificates issued.
  1873. :return:
  1874. None or a NameConstraints object
  1875. """
  1876. if not self._processed_extensions:
  1877. self._set_extensions()
  1878. return self._name_constraints_value
  1879. @property
  1880. def crl_distribution_points_value(self):
  1881. """
  1882. This extension is used to help in locating the CRL for this certificate.
  1883. :return:
  1884. None or a CRLDistributionPoints object
  1885. extension
  1886. """
  1887. if not self._processed_extensions:
  1888. self._set_extensions()
  1889. return self._crl_distribution_points_value
  1890. @property
  1891. def certificate_policies_value(self):
  1892. """
  1893. This extension defines policies in CA certificates under which
  1894. certificates may be issued. In end-entity certificates, the inclusion
  1895. of a policy indicates the issuance of the certificate follows the
  1896. policy.
  1897. :return:
  1898. None or a CertificatePolicies object
  1899. """
  1900. if not self._processed_extensions:
  1901. self._set_extensions()
  1902. return self._certificate_policies_value
  1903. @property
  1904. def policy_mappings_value(self):
  1905. """
  1906. This extension allows mapping policy OIDs to other OIDs. This is used
  1907. to allow different policies to be treated as equivalent in the process
  1908. of validation.
  1909. :return:
  1910. None or a PolicyMappings object
  1911. """
  1912. if not self._processed_extensions:
  1913. self._set_extensions()
  1914. return self._policy_mappings_value
  1915. @property
  1916. def authority_key_identifier_value(self):
  1917. """
  1918. This extension helps in identifying the public key with which to
  1919. validate the authenticity of the certificate.
  1920. :return:
  1921. None or an AuthorityKeyIdentifier object
  1922. """
  1923. if not self._processed_extensions:
  1924. self._set_extensions()
  1925. return self._authority_key_identifier_value
  1926. @property
  1927. def policy_constraints_value(self):
  1928. """
  1929. This extension is used to control if policy mapping is allowed and
  1930. when policies are required.
  1931. :return:
  1932. None or a PolicyConstraints object
  1933. """
  1934. if not self._processed_extensions:
  1935. self._set_extensions()
  1936. return self._policy_constraints_value
  1937. @property
  1938. def freshest_crl_value(self):
  1939. """
  1940. This extension is used to help locate any available delta CRLs
  1941. :return:
  1942. None or an CRLDistributionPoints object
  1943. """
  1944. if not self._processed_extensions:
  1945. self._set_extensions()
  1946. return self._freshest_crl_value
  1947. @property
  1948. def inhibit_any_policy_value(self):
  1949. """
  1950. This extension is used to prevent mapping of the any policy to
  1951. specific requirements
  1952. :return:
  1953. None or a Integer object
  1954. """
  1955. if not self._processed_extensions:
  1956. self._set_extensions()
  1957. return self._inhibit_any_policy_value
  1958. @property
  1959. def extended_key_usage_value(self):
  1960. """
  1961. This extension is used to define additional purposes for the public key
  1962. beyond what is contained in the basic constraints.
  1963. :return:
  1964. None or an ExtKeyUsageSyntax object
  1965. """
  1966. if not self._processed_extensions:
  1967. self._set_extensions()
  1968. return self._extended_key_usage_value
  1969. @property
  1970. def authority_information_access_value(self):
  1971. """
  1972. This extension is used to locate the CA certificate used to sign this
  1973. certificate, or the OCSP responder for this certificate.
  1974. :return:
  1975. None or an AuthorityInfoAccessSyntax object
  1976. """
  1977. if not self._processed_extensions:
  1978. self._set_extensions()
  1979. return self._authority_information_access_value
  1980. @property
  1981. def subject_information_access_value(self):
  1982. """
  1983. This extension is used to access information about the subject of this
  1984. certificate.
  1985. :return:
  1986. None or a SubjectInfoAccessSyntax object
  1987. """
  1988. if not self._processed_extensions:
  1989. self._set_extensions()
  1990. return self._subject_information_access_value
  1991. @property
  1992. def tls_feature_value(self):
  1993. """
  1994. This extension is used to list the TLS features a server must respond
  1995. with if a client initiates a request supporting them.
  1996. :return:
  1997. None or a Features object
  1998. """
  1999. if not self._processed_extensions:
  2000. self._set_extensions()
  2001. return self._tls_feature_value
  2002. @property
  2003. def ocsp_no_check_value(self):
  2004. """
  2005. This extension is used on certificates of OCSP responders, indicating
  2006. that revocation information for the certificate should never need to
  2007. be verified, thus preventing possible loops in path validation.
  2008. :return:
  2009. None or a Null object (if present)
  2010. """
  2011. if not self._processed_extensions:
  2012. self._set_extensions()
  2013. return self._ocsp_no_check_value
  2014. @property
  2015. def signature(self):
  2016. """
  2017. :return:
  2018. A byte string of the signature
  2019. """
  2020. return self['signature_value'].native
  2021. @property
  2022. def signature_algo(self):
  2023. """
  2024. :return:
  2025. A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa"
  2026. """
  2027. return self['signature_algorithm'].signature_algo
  2028. @property
  2029. def hash_algo(self):
  2030. """
  2031. :return:
  2032. A unicode string of "md2", "md5", "sha1", "sha224", "sha256",
  2033. "sha384", "sha512", "sha512_224", "sha512_256"
  2034. """
  2035. return self['signature_algorithm'].hash_algo
  2036. @property
  2037. def public_key(self):
  2038. """
  2039. :return:
  2040. The PublicKeyInfo object for this certificate
  2041. """
  2042. return self['tbs_certificate']['subject_public_key_info']
  2043. @property
  2044. def subject(self):
  2045. """
  2046. :return:
  2047. The Name object for the subject of this certificate
  2048. """
  2049. return self['tbs_certificate']['subject']
  2050. @property
  2051. def issuer(self):
  2052. """
  2053. :return:
  2054. The Name object for the issuer of this certificate
  2055. """
  2056. return self['tbs_certificate']['issuer']
  2057. @property
  2058. def serial_number(self):
  2059. """
  2060. :return:
  2061. An integer of the certificate's serial number
  2062. """
  2063. return self['tbs_certificate']['serial_number'].native
  2064. @property
  2065. def key_identifier(self):
  2066. """
  2067. :return:
  2068. None or a byte string of the certificate's key identifier from the
  2069. key identifier extension
  2070. """
  2071. if not self.key_identifier_value:
  2072. return None
  2073. return self.key_identifier_value.native
  2074. @property
  2075. def issuer_serial(self):
  2076. """
  2077. :return:
  2078. A byte string of the SHA-256 hash of the issuer concatenated with
  2079. the ascii character ":", concatenated with the serial number as
  2080. an ascii string
  2081. """
  2082. if self._issuer_serial is None:
  2083. self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii')
  2084. return self._issuer_serial
  2085. @property
  2086. def not_valid_after(self):
  2087. """
  2088. :return:
  2089. A datetime of latest time when the certificate is still valid
  2090. """
  2091. return self['tbs_certificate']['validity']['not_after'].native
  2092. @property
  2093. def not_valid_before(self):
  2094. """
  2095. :return:
  2096. A datetime of the earliest time when the certificate is valid
  2097. """
  2098. return self['tbs_certificate']['validity']['not_before'].native
  2099. @property
  2100. def authority_key_identifier(self):
  2101. """
  2102. :return:
  2103. None or a byte string of the key_identifier from the authority key
  2104. identifier extension
  2105. """
  2106. if not self.authority_key_identifier_value:
  2107. return None
  2108. return self.authority_key_identifier_value['key_identifier'].native
  2109. @property
  2110. def authority_issuer_serial(self):
  2111. """
  2112. :return:
  2113. None or a byte string of the SHA-256 hash of the isser from the
  2114. authority key identifier extension concatenated with the ascii
  2115. character ":", concatenated with the serial number from the
  2116. authority key identifier extension as an ascii string
  2117. """
  2118. if self._authority_issuer_serial is False:
  2119. akiv = self.authority_key_identifier_value
  2120. if akiv and akiv['authority_cert_issuer'].native:
  2121. issuer = self.authority_key_identifier_value['authority_cert_issuer'][0].chosen
  2122. # We untag the element since it is tagged via being a choice from GeneralName
  2123. issuer = issuer.untag()
  2124. authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native
  2125. self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii')
  2126. else:
  2127. self._authority_issuer_serial = None
  2128. return self._authority_issuer_serial
  2129. @property
  2130. def crl_distribution_points(self):
  2131. """
  2132. Returns complete CRL URLs - does not include delta CRLs
  2133. :return:
  2134. A list of zero or more DistributionPoint objects
  2135. """
  2136. if self._crl_distribution_points is None:
  2137. self._crl_distribution_points = self._get_http_crl_distribution_points(self.crl_distribution_points_value)
  2138. return self._crl_distribution_points
  2139. @property
  2140. def delta_crl_distribution_points(self):
  2141. """
  2142. Returns delta CRL URLs - does not include complete CRLs
  2143. :return:
  2144. A list of zero or more DistributionPoint objects
  2145. """
  2146. if self._delta_crl_distribution_points is None:
  2147. self._delta_crl_distribution_points = self._get_http_crl_distribution_points(self.freshest_crl_value)
  2148. return self._delta_crl_distribution_points
  2149. def _get_http_crl_distribution_points(self, crl_distribution_points):
  2150. """
  2151. Fetches the DistributionPoint object for non-relative, HTTP CRLs
  2152. referenced by the certificate
  2153. :param crl_distribution_points:
  2154. A CRLDistributionPoints object to grab the DistributionPoints from
  2155. :return:
  2156. A list of zero or more DistributionPoint objects
  2157. """
  2158. output = []
  2159. if crl_distribution_points is None:
  2160. return []
  2161. for distribution_point in crl_distribution_points:
  2162. distribution_point_name = distribution_point['distribution_point']
  2163. if distribution_point_name is VOID:
  2164. continue
  2165. # RFC 5280 indicates conforming CA should not use the relative form
  2166. if distribution_point_name.name == 'name_relative_to_crl_issuer':
  2167. continue
  2168. # This library is currently only concerned with HTTP-based CRLs
  2169. for general_name in distribution_point_name.chosen:
  2170. if general_name.name == 'uniform_resource_identifier':
  2171. output.append(distribution_point)
  2172. return output
  2173. @property
  2174. def ocsp_urls(self):
  2175. """
  2176. :return:
  2177. A list of zero or more unicode strings of the OCSP URLs for this
  2178. cert
  2179. """
  2180. if not self.authority_information_access_value:
  2181. return []
  2182. output = []
  2183. for entry in self.authority_information_access_value:
  2184. if entry['access_method'].native == 'ocsp':
  2185. location = entry['access_location']
  2186. if location.name != 'uniform_resource_identifier':
  2187. continue
  2188. url = location.native
  2189. if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):
  2190. output.append(url)
  2191. return output
  2192. @property
  2193. def valid_domains(self):
  2194. """
  2195. :return:
  2196. A list of unicode strings of valid domain names for the certificate.
  2197. Wildcard certificates will have a domain in the form: *.example.com
  2198. """
  2199. if self._valid_domains is None:
  2200. self._valid_domains = []
  2201. # For the subject alt name extension, we can look at the name of
  2202. # the choice selected since it distinguishes between domain names,
  2203. # email addresses, IPs, etc
  2204. if self.subject_alt_name_value:
  2205. for general_name in self.subject_alt_name_value:
  2206. if general_name.name == 'dns_name' and general_name.native not in self._valid_domains:
  2207. self._valid_domains.append(general_name.native)
  2208. # If there was no subject alt name extension, and the common name
  2209. # in the subject looks like a domain, that is considered the valid
  2210. # list. This is done because according to
  2211. # https://tools.ietf.org/html/rfc6125#section-6.4.4, the common
  2212. # name should not be used if the subject alt name is present.
  2213. else:
  2214. pattern = re.compile('^(\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$')
  2215. for rdn in self.subject.chosen:
  2216. for name_type_value in rdn:
  2217. if name_type_value['type'].native == 'common_name':
  2218. value = name_type_value['value'].native
  2219. if pattern.match(value):
  2220. self._valid_domains.append(value)
  2221. return self._valid_domains
  2222. @property
  2223. def valid_ips(self):
  2224. """
  2225. :return:
  2226. A list of unicode strings of valid IP addresses for the certificate
  2227. """
  2228. if self._valid_ips is None:
  2229. self._valid_ips = []
  2230. if self.subject_alt_name_value:
  2231. for general_name in self.subject_alt_name_value:
  2232. if general_name.name == 'ip_address':
  2233. self._valid_ips.append(general_name.native)
  2234. return self._valid_ips
  2235. @property
  2236. def ca(self):
  2237. """
  2238. :return;
  2239. A boolean - if the certificate is marked as a CA
  2240. """
  2241. return self.basic_constraints_value and self.basic_constraints_value['ca'].native
  2242. @property
  2243. def max_path_length(self):
  2244. """
  2245. :return;
  2246. None or an integer of the maximum path length
  2247. """
  2248. if not self.ca:
  2249. return None
  2250. return self.basic_constraints_value['path_len_constraint'].native
  2251. @property
  2252. def self_issued(self):
  2253. """
  2254. :return:
  2255. A boolean - if the certificate is self-issued, as defined by RFC
  2256. 5280
  2257. """
  2258. if self._self_issued is None:
  2259. self._self_issued = self.subject == self.issuer
  2260. return self._self_issued
  2261. @property
  2262. def self_signed(self):
  2263. """
  2264. :return:
  2265. A unicode string of "no" or "maybe". The "maybe" result will
  2266. be returned if the certificate issuer and subject are the same.
  2267. If a key identifier and authority key identifier are present,
  2268. they will need to match otherwise "no" will be returned.
  2269. To verify is a certificate is truly self-signed, the signature
  2270. will need to be verified. See the certvalidator package for
  2271. one possible solution.
  2272. """
  2273. if self._self_signed is None:
  2274. self._self_signed = 'no'
  2275. if self.self_issued:
  2276. if self.key_identifier:
  2277. if not self.authority_key_identifier:
  2278. self._self_signed = 'maybe'
  2279. elif self.authority_key_identifier == self.key_identifier:
  2280. self._self_signed = 'maybe'
  2281. else:
  2282. self._self_signed = 'maybe'
  2283. return self._self_signed
  2284. @property
  2285. def sha1(self):
  2286. """
  2287. :return:
  2288. The SHA-1 hash of the DER-encoded bytes of this complete certificate
  2289. """
  2290. if self._sha1 is None:
  2291. self._sha1 = hashlib.sha1(self.dump()).digest()
  2292. return self._sha1
  2293. @property
  2294. def sha1_fingerprint(self):
  2295. """
  2296. :return:
  2297. A unicode string of the SHA-1 hash, formatted using hex encoding
  2298. with a space between each pair of characters, all uppercase
  2299. """
  2300. return ' '.join('%02X' % c for c in bytes_to_list(self.sha1))
  2301. @property
  2302. def sha256(self):
  2303. """
  2304. :return:
  2305. The SHA-256 hash of the DER-encoded bytes of this complete
  2306. certificate
  2307. """
  2308. if self._sha256 is None:
  2309. self._sha256 = hashlib.sha256(self.dump()).digest()
  2310. return self._sha256
  2311. @property
  2312. def sha256_fingerprint(self):
  2313. """
  2314. :return:
  2315. A unicode string of the SHA-256 hash, formatted using hex encoding
  2316. with a space between each pair of characters, all uppercase
  2317. """
  2318. return ' '.join('%02X' % c for c in bytes_to_list(self.sha256))
  2319. def is_valid_domain_ip(self, domain_ip):
  2320. """
  2321. Check if a domain name or IP address is valid according to the
  2322. certificate
  2323. :param domain_ip:
  2324. A unicode string of a domain name or IP address
  2325. :return:
  2326. A boolean - if the domain or IP is valid for the certificate
  2327. """
  2328. if not isinstance(domain_ip, str_cls):
  2329. raise TypeError(unwrap(
  2330. '''
  2331. domain_ip must be a unicode string, not %s
  2332. ''',
  2333. type_name(domain_ip)
  2334. ))
  2335. encoded_domain_ip = domain_ip.encode('idna').decode('ascii').lower()
  2336. is_ipv6 = encoded_domain_ip.find(':') != -1
  2337. is_ipv4 = not is_ipv6 and re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', encoded_domain_ip)
  2338. is_domain = not is_ipv6 and not is_ipv4
  2339. # Handle domain name checks
  2340. if is_domain:
  2341. if not self.valid_domains:
  2342. return False
  2343. domain_labels = encoded_domain_ip.split('.')
  2344. for valid_domain in self.valid_domains:
  2345. encoded_valid_domain = valid_domain.encode('idna').decode('ascii').lower()
  2346. valid_domain_labels = encoded_valid_domain.split('.')
  2347. # The domain must be equal in label length to match
  2348. if len(valid_domain_labels) != len(domain_labels):
  2349. continue
  2350. if valid_domain_labels == domain_labels:
  2351. return True
  2352. is_wildcard = self._is_wildcard_domain(encoded_valid_domain)
  2353. if is_wildcard and self._is_wildcard_match(domain_labels, valid_domain_labels):
  2354. return True
  2355. return False
  2356. # Handle IP address checks
  2357. if not self.valid_ips:
  2358. return False
  2359. family = socket.AF_INET if is_ipv4 else socket.AF_INET6
  2360. normalized_ip = inet_pton(family, encoded_domain_ip)
  2361. for valid_ip in self.valid_ips:
  2362. valid_family = socket.AF_INET if valid_ip.find('.') != -1 else socket.AF_INET6
  2363. normalized_valid_ip = inet_pton(valid_family, valid_ip)
  2364. if normalized_valid_ip == normalized_ip:
  2365. return True
  2366. return False
  2367. def _is_wildcard_domain(self, domain):
  2368. """
  2369. Checks if a domain is a valid wildcard according to
  2370. https://tools.ietf.org/html/rfc6125#section-6.4.3
  2371. :param domain:
  2372. A unicode string of the domain name, where any U-labels from an IDN
  2373. have been converted to A-labels
  2374. :return:
  2375. A boolean - if the domain is a valid wildcard domain
  2376. """
  2377. # The * character must be present for a wildcard match, and if there is
  2378. # most than one, it is an invalid wildcard specification
  2379. if domain.count('*') != 1:
  2380. return False
  2381. labels = domain.lower().split('.')
  2382. if not labels:
  2383. return False
  2384. # Wildcards may only appear in the left-most label
  2385. if labels[0].find('*') == -1:
  2386. return False
  2387. # Wildcards may not be embedded in an A-label from an IDN
  2388. if labels[0][0:4] == 'xn--':
  2389. return False
  2390. return True
  2391. def _is_wildcard_match(self, domain_labels, valid_domain_labels):
  2392. """
  2393. Determines if the labels in a domain are a match for labels from a
  2394. wildcard valid domain name
  2395. :param domain_labels:
  2396. A list of unicode strings, with A-label form for IDNs, of the labels
  2397. in the domain name to check
  2398. :param valid_domain_labels:
  2399. A list of unicode strings, with A-label form for IDNs, of the labels
  2400. in a wildcard domain pattern
  2401. :return:
  2402. A boolean - if the domain matches the valid domain
  2403. """
  2404. first_domain_label = domain_labels[0]
  2405. other_domain_labels = domain_labels[1:]
  2406. wildcard_label = valid_domain_labels[0]
  2407. other_valid_domain_labels = valid_domain_labels[1:]
  2408. # The wildcard is only allowed in the first label, so if
  2409. # The subsequent labels are not equal, there is no match
  2410. if other_domain_labels != other_valid_domain_labels:
  2411. return False
  2412. if wildcard_label == '*':
  2413. return True
  2414. wildcard_regex = re.compile('^' + wildcard_label.replace('*', '.*') + '$')
  2415. if wildcard_regex.match(first_domain_label):
  2416. return True
  2417. return False
  2418. # The structures are taken from the OpenSSL source file x_x509a.c, and specify
  2419. # extra information that is added to X.509 certificates to store trust
  2420. # information about the certificate.
  2421. class KeyPurposeIdentifiers(SequenceOf):
  2422. _child_spec = KeyPurposeId
  2423. class SequenceOfAlgorithmIdentifiers(SequenceOf):
  2424. _child_spec = AlgorithmIdentifier
  2425. class CertificateAux(Sequence):
  2426. _fields = [
  2427. ('trust', KeyPurposeIdentifiers, {'optional': True}),
  2428. ('reject', KeyPurposeIdentifiers, {'implicit': 0, 'optional': True}),
  2429. ('alias', UTF8String, {'optional': True}),
  2430. ('keyid', OctetString, {'optional': True}),
  2431. ('other', SequenceOfAlgorithmIdentifiers, {'implicit': 1, 'optional': True}),
  2432. ]
  2433. class TrustedCertificate(Concat):
  2434. _child_specs = [Certificate, CertificateAux]