x509.py 81 KB

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