ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ # This file is dual licensed under the terms of the Apache License, Version # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. from __future__ import absolute_import, division, print_function import abc import datetime import hashlib import ipaddress import warnings from enum import Enum import six from cryptography import utils from cryptography.hazmat._der import ( BIT_STRING, DERReader, OBJECT_IDENTIFIER, SEQUENCE ) from cryptography.hazmat.primitives import constant_time, serialization from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.x509.certificate_transparency import ( SignedCertificateTimestamp ) from cryptography.x509.general_name import GeneralName, IPAddress, OtherName from cryptography.x509.name import RelativeDistinguishedName from cryptography.x509.oid import ( CRLEntryExtensionOID, ExtensionOID, OCSPExtensionOID, ObjectIdentifier, ) def _key_identifier_from_public_key(public_key): if isinstance(public_key, RSAPublicKey): data = public_key.public_bytes( serialization.Encoding.DER, serialization.PublicFormat.PKCS1, ) elif isinstance(public_key, EllipticCurvePublicKey): data = public_key.public_bytes( serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint ) else: # This is a very slow way to do this. serialized = public_key.public_bytes( serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo ) reader = DERReader(serialized) with reader.read_single_element(SEQUENCE) as public_key_info: algorithm = public_key_info.read_element(SEQUENCE) public_key = public_key_info.read_element(BIT_STRING) # Double-check the algorithm structure. with algorithm: algorithm.read_element(OBJECT_IDENTIFIER) if not algorithm.is_empty(): # Skip the optional parameters field. algorithm.read_any_element() # BIT STRING contents begin with the number of padding bytes added. It # must be zero for SubjectPublicKeyInfo structures. if public_key.read_byte() != 0: raise ValueError('Invalid public key encoding') data = public_key.data return hashlib.sha1(data).digest() def _make_sequence_methods(field_name): def len_method(self): return len(getattr(self, field_name)) def iter_method(self): return iter(getattr(self, field_name)) def getitem_method(self, idx): return getattr(self, field_name)[idx] return len_method, iter_method, getitem_method class DuplicateExtension(Exception): def __init__(self, msg, oid): super(DuplicateExtension, self).__init__(msg) self.oid = oid class ExtensionNotFound(Exception): def __init__(self, msg, oid): super(ExtensionNotFound, self).__init__(msg) self.oid = oid @six.add_metaclass(abc.ABCMeta) class ExtensionType(object): @abc.abstractproperty def oid(self): """ Returns the oid associated with the given extension type. """ class Extensions(object): def __init__(self, extensions): self._extensions = extensions def get_extension_for_oid(self, oid): for ext in self: if ext.oid == oid: return ext raise ExtensionNotFound("No {} extension was found".format(oid), oid) def get_extension_for_class(self, extclass): if extclass is UnrecognizedExtension: raise TypeError( "UnrecognizedExtension can't be used with " "get_extension_for_class because more than one instance of the" " class may be present." ) for ext in self: if isinstance(ext.value, extclass): return ext raise ExtensionNotFound( "No {} extension was found".format(extclass), extclass.oid ) __len__, __iter__, __getitem__ = _make_sequence_methods("_extensions") def __repr__(self): return ( "".format(self._extensions) ) @utils.register_interface(ExtensionType) class CRLNumber(object): oid = ExtensionOID.CRL_NUMBER def __init__(self, crl_number): if not isinstance(crl_number, six.integer_types): raise TypeError("crl_number must be an integer") self._crl_number = crl_number def __eq__(self, other): if not isinstance(other, CRLNumber): return NotImplemented return self.crl_number == other.crl_number def __ne__(self, other): return not self == other def __hash__(self): return hash(self.crl_number) def __repr__(self): return "".format(self.crl_number) crl_number = utils.read_only_property("_crl_number") @utils.register_interface(ExtensionType) class AuthorityKeyIdentifier(object): oid = ExtensionOID.AUTHORITY_KEY_IDENTIFIER def __init__(self, key_identifier, authority_cert_issuer, authority_cert_serial_number): if (authority_cert_issuer is None) != ( authority_cert_serial_number is None ): raise ValueError( "authority_cert_issuer and authority_cert_serial_number " "must both be present or both None" ) if authority_cert_issuer is not None: authority_cert_issuer = list(authority_cert_issuer) if not all( isinstance(x, GeneralName) for x in authority_cert_issuer ): raise TypeError( "authority_cert_issuer must be a list of GeneralName " "objects" ) if authority_cert_serial_number is not None and not isinstance( authority_cert_serial_number, six.integer_types ): raise TypeError( "authority_cert_serial_number must be an integer" ) self._key_identifier = key_identifier self._authority_cert_issuer = authority_cert_issuer self._authority_cert_serial_number = authority_cert_serial_number @classmethod def from_issuer_public_key(cls, public_key): digest = _key_identifier_from_public_key(public_key) return cls( key_identifier=digest, authority_cert_issuer=None, authority_cert_serial_number=None ) @classmethod def from_issuer_subject_key_identifier(cls, ski): if isinstance(ski, SubjectKeyIdentifier): digest = ski.digest else: digest = ski.value.digest warnings.warn( "Extension objects are deprecated as arguments to " "from_issuer_subject_key_identifier and support will be " "removed soon. Please migrate to passing a " "SubjectKeyIdentifier directly.", utils.DeprecatedIn27, stacklevel=2, ) return cls( key_identifier=digest, authority_cert_issuer=None, authority_cert_serial_number=None ) def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, AuthorityKeyIdentifier): return NotImplemented return ( self.key_identifier == other.key_identifier and self.authority_cert_issuer == other.authority_cert_issuer and self.authority_cert_serial_number == other.authority_cert_serial_number ) def __ne__(self, other): return not self == other def __hash__(self): if self.authority_cert_issuer is None: aci = None else: aci = tuple(self.authority_cert_issuer) return hash(( self.key_identifier, aci, self.authority_cert_serial_number )) key_identifier = utils.read_only_property("_key_identifier") authority_cert_issuer = utils.read_only_property("_authority_cert_issuer") authority_cert_serial_number = utils.read_only_property( "_authority_cert_serial_number" ) @utils.register_interface(ExtensionType) class SubjectKeyIdentifier(object): oid = ExtensionOID.SUBJECT_KEY_IDENTIFIER def __init__(self, digest): self._digest = digest @classmethod def from_public_key(cls, public_key): return cls(_key_identifier_from_public_key(public_key)) digest = utils.read_only_property("_digest") def __repr__(self): return "".format(self.digest) def __eq__(self, other): if not isinstance(other, SubjectKeyIdentifier): return NotImplemented return constant_time.bytes_eq(self.digest, other.digest) def __ne__(self, other): return not self == other def __hash__(self): return hash(self.digest) @utils.register_interface(ExtensionType) class AuthorityInformationAccess(object): oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS def __init__(self, descriptions): descriptions = list(descriptions) if not all(isinstance(x, AccessDescription) for x in descriptions): raise TypeError( "Every item in the descriptions list must be an " "AccessDescription" ) self._descriptions = descriptions __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") def __repr__(self): return "".format(self._descriptions) def __eq__(self, other): if not isinstance(other, AuthorityInformationAccess): return NotImplemented return self._descriptions == other._descriptions def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._descriptions)) class AccessDescription(object): def __init__(self, access_method, access_location): if not isinstance(access_method, ObjectIdentifier): raise TypeError("access_method must be an ObjectIdentifier") if not isinstance(access_location, GeneralName): raise TypeError("access_location must be a GeneralName") self._access_method = access_method self._access_location = access_location def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, AccessDescription): return NotImplemented return ( self.access_method == other.access_method and self.access_location == other.access_location ) def __ne__(self, other): return not self == other def __hash__(self): return hash((self.access_method, self.access_location)) access_method = utils.read_only_property("_access_method") access_location = utils.read_only_property("_access_location") @utils.register_interface(ExtensionType) class BasicConstraints(object): oid = ExtensionOID.BASIC_CONSTRAINTS def __init__(self, ca, path_length): if not isinstance(ca, bool): raise TypeError("ca must be a boolean value") if path_length is not None and not ca: raise ValueError("path_length must be None when ca is False") if ( path_length is not None and (not isinstance(path_length, six.integer_types) or path_length < 0) ): raise TypeError( "path_length must be a non-negative integer or None" ) self._ca = ca self._path_length = path_length ca = utils.read_only_property("_ca") path_length = utils.read_only_property("_path_length") def __repr__(self): return ("").format(self) def __eq__(self, other): if not isinstance(other, BasicConstraints): return NotImplemented return self.ca == other.ca and self.path_length == other.path_length def __ne__(self, other): return not self == other def __hash__(self): return hash((self.ca, self.path_length)) @utils.register_interface(ExtensionType) class DeltaCRLIndicator(object): oid = ExtensionOID.DELTA_CRL_INDICATOR def __init__(self, crl_number): if not isinstance(crl_number, six.integer_types): raise TypeError("crl_number must be an integer") self._crl_number = crl_number crl_number = utils.read_only_property("_crl_number") def __eq__(self, other): if not isinstance(other, DeltaCRLIndicator): return NotImplemented return self.crl_number == other.crl_number def __ne__(self, other): return not self == other def __hash__(self): return hash(self.crl_number) def __repr__(self): return "".format(self) @utils.register_interface(ExtensionType) class CRLDistributionPoints(object): oid = ExtensionOID.CRL_DISTRIBUTION_POINTS def __init__(self, distribution_points): distribution_points = list(distribution_points) if not all( isinstance(x, DistributionPoint) for x in distribution_points ): raise TypeError( "distribution_points must be a list of DistributionPoint " "objects" ) self._distribution_points = distribution_points __len__, __iter__, __getitem__ = _make_sequence_methods( "_distribution_points" ) def __repr__(self): return "".format(self._distribution_points) def __eq__(self, other): if not isinstance(other, CRLDistributionPoints): return NotImplemented return self._distribution_points == other._distribution_points def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._distribution_points)) @utils.register_interface(ExtensionType) class FreshestCRL(object): oid = ExtensionOID.FRESHEST_CRL def __init__(self, distribution_points): distribution_points = list(distribution_points) if not all( isinstance(x, DistributionPoint) for x in distribution_points ): raise TypeError( "distribution_points must be a list of DistributionPoint " "objects" ) self._distribution_points = distribution_points __len__, __iter__, __getitem__ = _make_sequence_methods( "_distribution_points" ) def __repr__(self): return "".format(self._distribution_points) def __eq__(self, other): if not isinstance(other, FreshestCRL): return NotImplemented return self._distribution_points == other._distribution_points def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._distribution_points)) class DistributionPoint(object): def __init__(self, full_name, relative_name, reasons, crl_issuer): if full_name and relative_name: raise ValueError( "You cannot provide both full_name and relative_name, at " "least one must be None." ) if full_name: full_name = list(full_name) if not all(isinstance(x, GeneralName) for x in full_name): raise TypeError( "full_name must be a list of GeneralName objects" ) if relative_name: if not isinstance(relative_name, RelativeDistinguishedName): raise TypeError( "relative_name must be a RelativeDistinguishedName" ) if crl_issuer: crl_issuer = list(crl_issuer) if not all(isinstance(x, GeneralName) for x in crl_issuer): raise TypeError( "crl_issuer must be None or a list of general names" ) if reasons and (not isinstance(reasons, frozenset) or not all( isinstance(x, ReasonFlags) for x in reasons )): raise TypeError("reasons must be None or frozenset of ReasonFlags") if reasons and ( ReasonFlags.unspecified in reasons or ReasonFlags.remove_from_crl in reasons ): raise ValueError( "unspecified and remove_from_crl are not valid reasons in a " "DistributionPoint" ) if reasons and not crl_issuer and not (full_name or relative_name): raise ValueError( "You must supply crl_issuer, full_name, or relative_name when " "reasons is not None" ) self._full_name = full_name self._relative_name = relative_name self._reasons = reasons self._crl_issuer = crl_issuer def __repr__(self): return ( "" .format(self) ) def __eq__(self, other): if not isinstance(other, DistributionPoint): return NotImplemented return ( self.full_name == other.full_name and self.relative_name == other.relative_name and self.reasons == other.reasons and self.crl_issuer == other.crl_issuer ) def __ne__(self, other): return not self == other def __hash__(self): if self.full_name is not None: fn = tuple(self.full_name) else: fn = None if self.crl_issuer is not None: crl_issuer = tuple(self.crl_issuer) else: crl_issuer = None return hash((fn, self.relative_name, self.reasons, crl_issuer)) full_name = utils.read_only_property("_full_name") relative_name = utils.read_only_property("_relative_name") reasons = utils.read_only_property("_reasons") crl_issuer = utils.read_only_property("_crl_issuer") class ReasonFlags(Enum): unspecified = "unspecified" key_compromise = "keyCompromise" ca_compromise = "cACompromise" affiliation_changed = "affiliationChanged" superseded = "superseded" cessation_of_operation = "cessationOfOperation" certificate_hold = "certificateHold" privilege_withdrawn = "privilegeWithdrawn" aa_compromise = "aACompromise" remove_from_crl = "removeFromCRL" @utils.register_interface(ExtensionType) class PolicyConstraints(object): oid = ExtensionOID.POLICY_CONSTRAINTS def __init__(self, require_explicit_policy, inhibit_policy_mapping): if require_explicit_policy is not None and not isinstance( require_explicit_policy, six.integer_types ): raise TypeError( "require_explicit_policy must be a non-negative integer or " "None" ) if inhibit_policy_mapping is not None and not isinstance( inhibit_policy_mapping, six.integer_types ): raise TypeError( "inhibit_policy_mapping must be a non-negative integer or None" ) if inhibit_policy_mapping is None and require_explicit_policy is None: raise ValueError( "At least one of require_explicit_policy and " "inhibit_policy_mapping must not be None" ) self._require_explicit_policy = require_explicit_policy self._inhibit_policy_mapping = inhibit_policy_mapping def __repr__(self): return ( u"".format(self) ) def __eq__(self, other): if not isinstance(other, PolicyConstraints): return NotImplemented return ( self.require_explicit_policy == other.require_explicit_policy and self.inhibit_policy_mapping == other.inhibit_policy_mapping ) def __ne__(self, other): return not self == other def __hash__(self): return hash( (self.require_explicit_policy, self.inhibit_policy_mapping) ) require_explicit_policy = utils.read_only_property( "_require_explicit_policy" ) inhibit_policy_mapping = utils.read_only_property( "_inhibit_policy_mapping" ) @utils.register_interface(ExtensionType) class CertificatePolicies(object): oid = ExtensionOID.CERTIFICATE_POLICIES def __init__(self, policies): policies = list(policies) if not all(isinstance(x, PolicyInformation) for x in policies): raise TypeError( "Every item in the policies list must be a " "PolicyInformation" ) self._policies = policies __len__, __iter__, __getitem__ = _make_sequence_methods("_policies") def __repr__(self): return "".format(self._policies) def __eq__(self, other): if not isinstance(other, CertificatePolicies): return NotImplemented return self._policies == other._policies def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._policies)) class PolicyInformation(object): def __init__(self, policy_identifier, policy_qualifiers): if not isinstance(policy_identifier, ObjectIdentifier): raise TypeError("policy_identifier must be an ObjectIdentifier") self._policy_identifier = policy_identifier if policy_qualifiers: policy_qualifiers = list(policy_qualifiers) if not all( isinstance(x, (six.text_type, UserNotice)) for x in policy_qualifiers ): raise TypeError( "policy_qualifiers must be a list of strings and/or " "UserNotice objects or None" ) self._policy_qualifiers = policy_qualifiers def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, PolicyInformation): return NotImplemented return ( self.policy_identifier == other.policy_identifier and self.policy_qualifiers == other.policy_qualifiers ) def __ne__(self, other): return not self == other def __hash__(self): if self.policy_qualifiers is not None: pq = tuple(self.policy_qualifiers) else: pq = None return hash((self.policy_identifier, pq)) policy_identifier = utils.read_only_property("_policy_identifier") policy_qualifiers = utils.read_only_property("_policy_qualifiers") class UserNotice(object): def __init__(self, notice_reference, explicit_text): if notice_reference and not isinstance( notice_reference, NoticeReference ): raise TypeError( "notice_reference must be None or a NoticeReference" ) self._notice_reference = notice_reference self._explicit_text = explicit_text def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, UserNotice): return NotImplemented return ( self.notice_reference == other.notice_reference and self.explicit_text == other.explicit_text ) def __ne__(self, other): return not self == other def __hash__(self): return hash((self.notice_reference, self.explicit_text)) notice_reference = utils.read_only_property("_notice_reference") explicit_text = utils.read_only_property("_explicit_text") class NoticeReference(object): def __init__(self, organization, notice_numbers): self._organization = organization notice_numbers = list(notice_numbers) if not all(isinstance(x, int) for x in notice_numbers): raise TypeError( "notice_numbers must be a list of integers" ) self._notice_numbers = notice_numbers def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, NoticeReference): return NotImplemented return ( self.organization == other.organization and self.notice_numbers == other.notice_numbers ) def __ne__(self, other): return not self == other def __hash__(self): return hash((self.organization, tuple(self.notice_numbers))) organization = utils.read_only_property("_organization") notice_numbers = utils.read_only_property("_notice_numbers") @utils.register_interface(ExtensionType) class ExtendedKeyUsage(object): oid = ExtensionOID.EXTENDED_KEY_USAGE def __init__(self, usages): usages = list(usages) if not all(isinstance(x, ObjectIdentifier) for x in usages): raise TypeError( "Every item in the usages list must be an ObjectIdentifier" ) self._usages = usages __len__, __iter__, __getitem__ = _make_sequence_methods("_usages") def __repr__(self): return "".format(self._usages) def __eq__(self, other): if not isinstance(other, ExtendedKeyUsage): return NotImplemented return self._usages == other._usages def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._usages)) @utils.register_interface(ExtensionType) class OCSPNoCheck(object): oid = ExtensionOID.OCSP_NO_CHECK def __eq__(self, other): if not isinstance(other, OCSPNoCheck): return NotImplemented return True def __ne__(self, other): return not self == other def __hash__(self): return hash(OCSPNoCheck) def __repr__(self): return "" @utils.register_interface(ExtensionType) class PrecertPoison(object): oid = ExtensionOID.PRECERT_POISON def __eq__(self, other): if not isinstance(other, PrecertPoison): return NotImplemented return True def __ne__(self, other): return not self == other def __hash__(self): return hash(PrecertPoison) def __repr__(self): return "" @utils.register_interface(ExtensionType) class TLSFeature(object): oid = ExtensionOID.TLS_FEATURE def __init__(self, features): features = list(features) if ( not all(isinstance(x, TLSFeatureType) for x in features) or len(features) == 0 ): raise TypeError( "features must be a list of elements from the TLSFeatureType " "enum" ) self._features = features __len__, __iter__, __getitem__ = _make_sequence_methods("_features") def __repr__(self): return "".format(self) def __eq__(self, other): if not isinstance(other, TLSFeature): return NotImplemented return self._features == other._features def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._features)) class TLSFeatureType(Enum): # status_request is defined in RFC 6066 and is used for what is commonly # called OCSP Must-Staple when present in the TLS Feature extension in an # X.509 certificate. status_request = 5 # status_request_v2 is defined in RFC 6961 and allows multiple OCSP # responses to be provided. It is not currently in use by clients or # servers. status_request_v2 = 17 _TLS_FEATURE_TYPE_TO_ENUM = dict((x.value, x) for x in TLSFeatureType) @utils.register_interface(ExtensionType) class InhibitAnyPolicy(object): oid = ExtensionOID.INHIBIT_ANY_POLICY def __init__(self, skip_certs): if not isinstance(skip_certs, six.integer_types): raise TypeError("skip_certs must be an integer") if skip_certs < 0: raise ValueError("skip_certs must be a non-negative integer") self._skip_certs = skip_certs def __repr__(self): return "".format(self) def __eq__(self, other): if not isinstance(other, InhibitAnyPolicy): return NotImplemented return self.skip_certs == other.skip_certs def __ne__(self, other): return not self == other def __hash__(self): return hash(self.skip_certs) skip_certs = utils.read_only_property("_skip_certs") @utils.register_interface(ExtensionType) class KeyUsage(object): oid = ExtensionOID.KEY_USAGE def __init__(self, digital_signature, content_commitment, key_encipherment, data_encipherment, key_agreement, key_cert_sign, crl_sign, encipher_only, decipher_only): if not key_agreement and (encipher_only or decipher_only): raise ValueError( "encipher_only and decipher_only can only be true when " "key_agreement is true" ) self._digital_signature = digital_signature self._content_commitment = content_commitment self._key_encipherment = key_encipherment self._data_encipherment = data_encipherment self._key_agreement = key_agreement self._key_cert_sign = key_cert_sign self._crl_sign = crl_sign self._encipher_only = encipher_only self._decipher_only = decipher_only digital_signature = utils.read_only_property("_digital_signature") content_commitment = utils.read_only_property("_content_commitment") key_encipherment = utils.read_only_property("_key_encipherment") data_encipherment = utils.read_only_property("_data_encipherment") key_agreement = utils.read_only_property("_key_agreement") key_cert_sign = utils.read_only_property("_key_cert_sign") crl_sign = utils.read_only_property("_crl_sign") @property def encipher_only(self): if not self.key_agreement: raise ValueError( "encipher_only is undefined unless key_agreement is true" ) else: return self._encipher_only @property def decipher_only(self): if not self.key_agreement: raise ValueError( "decipher_only is undefined unless key_agreement is true" ) else: return self._decipher_only def __repr__(self): try: encipher_only = self.encipher_only decipher_only = self.decipher_only except ValueError: encipher_only = None decipher_only = None return ("").format( self, encipher_only, decipher_only) def __eq__(self, other): if not isinstance(other, KeyUsage): return NotImplemented return ( self.digital_signature == other.digital_signature and self.content_commitment == other.content_commitment and self.key_encipherment == other.key_encipherment and self.data_encipherment == other.data_encipherment and self.key_agreement == other.key_agreement and self.key_cert_sign == other.key_cert_sign and self.crl_sign == other.crl_sign and self._encipher_only == other._encipher_only and self._decipher_only == other._decipher_only ) def __ne__(self, other): return not self == other def __hash__(self): return hash(( self.digital_signature, self.content_commitment, self.key_encipherment, self.data_encipherment, self.key_agreement, self.key_cert_sign, self.crl_sign, self._encipher_only, self._decipher_only )) @utils.register_interface(ExtensionType) class NameConstraints(object): oid = ExtensionOID.NAME_CONSTRAINTS def __init__(self, permitted_subtrees, excluded_subtrees): if permitted_subtrees is not None: permitted_subtrees = list(permitted_subtrees) if not all( isinstance(x, GeneralName) for x in permitted_subtrees ): raise TypeError( "permitted_subtrees must be a list of GeneralName objects " "or None" ) self._validate_ip_name(permitted_subtrees) if excluded_subtrees is not None: excluded_subtrees = list(excluded_subtrees) if not all( isinstance(x, GeneralName) for x in excluded_subtrees ): raise TypeError( "excluded_subtrees must be a list of GeneralName objects " "or None" ) self._validate_ip_name(excluded_subtrees) if permitted_subtrees is None and excluded_subtrees is None: raise ValueError( "At least one of permitted_subtrees and excluded_subtrees " "must not be None" ) self._permitted_subtrees = permitted_subtrees self._excluded_subtrees = excluded_subtrees def __eq__(self, other): if not isinstance(other, NameConstraints): return NotImplemented return ( self.excluded_subtrees == other.excluded_subtrees and self.permitted_subtrees == other.permitted_subtrees ) def __ne__(self, other): return not self == other def _validate_ip_name(self, tree): if any(isinstance(name, IPAddress) and not isinstance( name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network) ) for name in tree): raise TypeError( "IPAddress name constraints must be an IPv4Network or" " IPv6Network object" ) def __repr__(self): return ( u"".format(self) ) def __hash__(self): if self.permitted_subtrees is not None: ps = tuple(self.permitted_subtrees) else: ps = None if self.excluded_subtrees is not None: es = tuple(self.excluded_subtrees) else: es = None return hash((ps, es)) permitted_subtrees = utils.read_only_property("_permitted_subtrees") excluded_subtrees = utils.read_only_property("_excluded_subtrees") class Extension(object): def __init__(self, oid, critical, value): if not isinstance(oid, ObjectIdentifier): raise TypeError( "oid argument must be an ObjectIdentifier instance." ) if not isinstance(critical, bool): raise TypeError("critical must be a boolean value") self._oid = oid self._critical = critical self._value = value oid = utils.read_only_property("_oid") critical = utils.read_only_property("_critical") value = utils.read_only_property("_value") def __repr__(self): return ("").format(self) def __eq__(self, other): if not isinstance(other, Extension): return NotImplemented return ( self.oid == other.oid and self.critical == other.critical and self.value == other.value ) def __ne__(self, other): return not self == other def __hash__(self): return hash((self.oid, self.critical, self.value)) class GeneralNames(object): def __init__(self, general_names): general_names = list(general_names) if not all(isinstance(x, GeneralName) for x in general_names): raise TypeError( "Every item in the general_names list must be an " "object conforming to the GeneralName interface" ) self._general_names = general_names __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") def get_values_for_type(self, type): # Return the value of each GeneralName, except for OtherName instances # which we return directly because it has two important properties not # just one value. objs = (i for i in self if isinstance(i, type)) if type != OtherName: objs = (i.value for i in objs) return list(objs) def __repr__(self): return "".format(self._general_names) def __eq__(self, other): if not isinstance(other, GeneralNames): return NotImplemented return self._general_names == other._general_names def __ne__(self, other): return not self == other def __hash__(self): return hash(tuple(self._general_names)) @utils.register_interface(ExtensionType) class SubjectAlternativeName(object): oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME def __init__(self, general_names): self._general_names = GeneralNames(general_names) __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") def get_values_for_type(self, type): return self._general_names.get_values_for_type(type) def __repr__(self): return "".format(self._general_names) def __eq__(self, other): if not isinstance(other, SubjectAlternativeName): return NotImplemented return self._general_names == other._general_names def __ne__(self, other): return not self == other def __hash__(self): return hash(self._general_names) @utils.register_interface(ExtensionType) class IssuerAlternativeName(object): oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME def __init__(self, general_names): self._general_names = GeneralNames(general_names) __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") def get_values_for_type(self, type): return self._general_names.get_values_for_type(type) def __repr__(self): return "".format(self._general_names) def __eq__(self, other): if not isinstance(other, IssuerAlternativeName): return NotImplemented return self._general_names == other._general_names def __ne__(self, other): return not self == other def __hash__(self): return hash(self._general_names) @utils.register_interface(ExtensionType) class CertificateIssuer(object): oid = CRLEntryExtensionOID.CERTIFICATE_ISSUER def __init__(self, general_names): self._general_names = GeneralNames(general_names) __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") def get_values_for_type(self, type): return self._general_names.get_values_for_type(type) def __repr__(self): return "".format(self._general_names) def __eq__(self, other): if not isinstance(other, CertificateIssuer): return NotImplemented return self._general_names == other._general_names def __ne__(self, other): return not self == other def __hash__(self): return hash(self._general_names) @utils.register_interface(ExtensionType) class CRLReason(object): oid = CRLEntryExtensionOID.CRL_REASON def __init__(self, reason): if not isinstance(reason, ReasonFlags): raise TypeError("reason must be an element from ReasonFlags") self._reason = reason def __repr__(self): return "".format(self._reason) def __eq__(self, other): if not isinstance(other, CRLReason): return NotImplemented return self.reason == other.reason def __ne__(self, other): return not self == other def __hash__(self): return hash(self.reason) reason = utils.read_only_property("_reason") @utils.register_interface(ExtensionType) class InvalidityDate(object): oid = CRLEntryExtensionOID.INVALIDITY_DATE def __init__(self, invalidity_date): if not isinstance(invalidity_date, datetime.datetime): raise TypeError("invalidity_date must be a datetime.datetime") self._invalidity_date = invalidity_date def __repr__(self): return "".format( self._invalidity_date ) def __eq__(self, other): if not isinstance(other, InvalidityDate): return NotImplemented return self.invalidity_date == other.invalidity_date def __ne__(self, other): return not self == other def __hash__(self): return hash(self.invalidity_date) invalidity_date = utils.read_only_property("_invalidity_date") @utils.register_interface(ExtensionType) class PrecertificateSignedCertificateTimestamps(object): oid = ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS def __init__(self, signed_certificate_timestamps): signed_certificate_timestamps = list(signed_certificate_timestamps) if not all( isinstance(sct, SignedCertificateTimestamp) for sct in signed_certificate_timestamps ): raise TypeError( "Every item in the signed_certificate_timestamps list must be " "a SignedCertificateTimestamp" ) self._signed_certificate_timestamps = signed_certificate_timestamps __len__, __iter__, __getitem__ = _make_sequence_methods( "_signed_certificate_timestamps" ) def __repr__(self): return ( "".format( list(self) ) ) def __hash__(self): return hash(tuple(self._signed_certificate_timestamps)) def __eq__(self, other): if not isinstance(other, PrecertificateSignedCertificateTimestamps): return NotImplemented return ( self._signed_certificate_timestamps == other._signed_certificate_timestamps ) def __ne__(self, other): return not self == other @utils.register_interface(ExtensionType) class OCSPNonce(object): oid = OCSPExtensionOID.NONCE def __init__(self, nonce): if not isinstance(nonce, bytes): raise TypeError("nonce must be bytes") self._nonce = nonce def __eq__(self, other): if not isinstance(other, OCSPNonce): return NotImplemented return self.nonce == other.nonce def __ne__(self, other): return not self == other def __hash__(self): return hash(self.nonce) def __repr__(self): return "".format(self) nonce = utils.read_only_property("_nonce") @utils.register_interface(ExtensionType) class IssuingDistributionPoint(object): oid = ExtensionOID.ISSUING_DISTRIBUTION_POINT def __init__(self, full_name, relative_name, only_contains_user_certs, only_contains_ca_certs, only_some_reasons, indirect_crl, only_contains_attribute_certs): if ( only_some_reasons and ( not isinstance(only_some_reasons, frozenset) or not all( isinstance(x, ReasonFlags) for x in only_some_reasons ) ) ): raise TypeError( "only_some_reasons must be None or frozenset of ReasonFlags" ) if only_some_reasons and ( ReasonFlags.unspecified in only_some_reasons or ReasonFlags.remove_from_crl in only_some_reasons ): raise ValueError( "unspecified and remove_from_crl are not valid reasons in an " "IssuingDistributionPoint" ) if not ( isinstance(only_contains_user_certs, bool) and isinstance(only_contains_ca_certs, bool) and isinstance(indirect_crl, bool) and isinstance(only_contains_attribute_certs, bool) ): raise TypeError( "only_contains_user_certs, only_contains_ca_certs, " "indirect_crl and only_contains_attribute_certs " "must all be boolean." ) crl_constraints = [ only_contains_user_certs, only_contains_ca_certs, indirect_crl, only_contains_attribute_certs ] if len([x for x in crl_constraints if x]) > 1: raise ValueError( "Only one of the following can be set to True: " "only_contains_user_certs, only_contains_ca_certs, " "indirect_crl, only_contains_attribute_certs" ) if ( not any([ only_contains_user_certs, only_contains_ca_certs, indirect_crl, only_contains_attribute_certs, full_name, relative_name, only_some_reasons ]) ): raise ValueError( "Cannot create empty extension: " "if only_contains_user_certs, only_contains_ca_certs, " "indirect_crl, and only_contains_attribute_certs are all False" ", then either full_name, relative_name, or only_some_reasons " "must have a value." ) self._only_contains_user_certs = only_contains_user_certs self._only_contains_ca_certs = only_contains_ca_certs self._indirect_crl = indirect_crl self._only_contains_attribute_certs = only_contains_attribute_certs self._only_some_reasons = only_some_reasons self._full_name = full_name self._relative_name = relative_name def __repr__(self): return ( "".format(self) ) def __eq__(self, other): if not isinstance(other, IssuingDistributionPoint): return NotImplemented return ( self.full_name == other.full_name and self.relative_name == other.relative_name and self.only_contains_user_certs == other.only_contains_user_certs and self.only_contains_ca_certs == other.only_contains_ca_certs and self.only_some_reasons == other.only_some_reasons and self.indirect_crl == other.indirect_crl and self.only_contains_attribute_certs == other.only_contains_attribute_certs ) def __ne__(self, other): return not self == other def __hash__(self): return hash(( self.full_name, self.relative_name, self.only_contains_user_certs, self.only_contains_ca_certs, self.only_some_reasons, self.indirect_crl, self.only_contains_attribute_certs, )) full_name = utils.read_only_property("_full_name") relative_name = utils.read_only_property("_relative_name") only_contains_user_certs = utils.read_only_property( "_only_contains_user_certs" ) only_contains_ca_certs = utils.read_only_property( "_only_contains_ca_certs" ) only_some_reasons = utils.read_only_property("_only_some_reasons") indirect_crl = utils.read_only_property("_indirect_crl") only_contains_attribute_certs = utils.read_only_property( "_only_contains_attribute_certs" ) @utils.register_interface(ExtensionType) class UnrecognizedExtension(object): def __init__(self, oid, value): if not isinstance(oid, ObjectIdentifier): raise TypeError("oid must be an ObjectIdentifier") self._oid = oid self._value = value oid = utils.read_only_property("_oid") value = utils.read_only_property("_value") def __repr__(self): return ( "".format( self ) ) def __eq__(self, other): if not isinstance(other, UnrecognizedExtension): return NotImplemented return self.oid == other.oid and self.value == other.value def __ne__(self, other): return not self == other def __hash__(self): return hash((self.oid, self.value))