1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7import abc 8import datetime 9import hashlib 10import ipaddress 11from enum import Enum 12 13import six 14 15from cryptography import utils 16from cryptography.hazmat._der import ( 17 BIT_STRING, 18 DERReader, 19 OBJECT_IDENTIFIER, 20 SEQUENCE, 21) 22from cryptography.hazmat.primitives import constant_time, serialization 23from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey 24from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey 25from cryptography.x509.certificate_transparency import ( 26 SignedCertificateTimestamp, 27) 28from cryptography.x509.general_name import GeneralName, IPAddress, OtherName 29from cryptography.x509.name import RelativeDistinguishedName 30from cryptography.x509.oid import ( 31 CRLEntryExtensionOID, 32 ExtensionOID, 33 OCSPExtensionOID, 34 ObjectIdentifier, 35) 36 37 38def _key_identifier_from_public_key(public_key): 39 if isinstance(public_key, RSAPublicKey): 40 data = public_key.public_bytes( 41 serialization.Encoding.DER, 42 serialization.PublicFormat.PKCS1, 43 ) 44 elif isinstance(public_key, EllipticCurvePublicKey): 45 data = public_key.public_bytes( 46 serialization.Encoding.X962, 47 serialization.PublicFormat.UncompressedPoint, 48 ) 49 else: 50 # This is a very slow way to do this. 51 serialized = public_key.public_bytes( 52 serialization.Encoding.DER, 53 serialization.PublicFormat.SubjectPublicKeyInfo, 54 ) 55 56 reader = DERReader(serialized) 57 with reader.read_single_element(SEQUENCE) as public_key_info: 58 algorithm = public_key_info.read_element(SEQUENCE) 59 public_key = public_key_info.read_element(BIT_STRING) 60 61 # Double-check the algorithm structure. 62 with algorithm: 63 algorithm.read_element(OBJECT_IDENTIFIER) 64 if not algorithm.is_empty(): 65 # Skip the optional parameters field. 66 algorithm.read_any_element() 67 68 # BIT STRING contents begin with the number of padding bytes added. It 69 # must be zero for SubjectPublicKeyInfo structures. 70 if public_key.read_byte() != 0: 71 raise ValueError("Invalid public key encoding") 72 73 data = public_key.data 74 75 return hashlib.sha1(data).digest() 76 77 78def _make_sequence_methods(field_name): 79 def len_method(self): 80 return len(getattr(self, field_name)) 81 82 def iter_method(self): 83 return iter(getattr(self, field_name)) 84 85 def getitem_method(self, idx): 86 return getattr(self, field_name)[idx] 87 88 return len_method, iter_method, getitem_method 89 90 91class DuplicateExtension(Exception): 92 def __init__(self, msg, oid): 93 super(DuplicateExtension, self).__init__(msg) 94 self.oid = oid 95 96 97class ExtensionNotFound(Exception): 98 def __init__(self, msg, oid): 99 super(ExtensionNotFound, self).__init__(msg) 100 self.oid = oid 101 102 103@six.add_metaclass(abc.ABCMeta) 104class ExtensionType(object): 105 @abc.abstractproperty 106 def oid(self): 107 """ 108 Returns the oid associated with the given extension type. 109 """ 110 111 112class Extensions(object): 113 def __init__(self, extensions): 114 self._extensions = extensions 115 116 def get_extension_for_oid(self, oid): 117 for ext in self: 118 if ext.oid == oid: 119 return ext 120 121 raise ExtensionNotFound("No {} extension was found".format(oid), oid) 122 123 def get_extension_for_class(self, extclass): 124 if extclass is UnrecognizedExtension: 125 raise TypeError( 126 "UnrecognizedExtension can't be used with " 127 "get_extension_for_class because more than one instance of the" 128 " class may be present." 129 ) 130 131 for ext in self: 132 if isinstance(ext.value, extclass): 133 return ext 134 135 raise ExtensionNotFound( 136 "No {} extension was found".format(extclass), extclass.oid 137 ) 138 139 __len__, __iter__, __getitem__ = _make_sequence_methods("_extensions") 140 141 def __repr__(self): 142 return "<Extensions({})>".format(self._extensions) 143 144 145@utils.register_interface(ExtensionType) 146class CRLNumber(object): 147 oid = ExtensionOID.CRL_NUMBER 148 149 def __init__(self, crl_number): 150 if not isinstance(crl_number, six.integer_types): 151 raise TypeError("crl_number must be an integer") 152 153 self._crl_number = crl_number 154 155 def __eq__(self, other): 156 if not isinstance(other, CRLNumber): 157 return NotImplemented 158 159 return self.crl_number == other.crl_number 160 161 def __ne__(self, other): 162 return not self == other 163 164 def __hash__(self): 165 return hash(self.crl_number) 166 167 def __repr__(self): 168 return "<CRLNumber({})>".format(self.crl_number) 169 170 crl_number = utils.read_only_property("_crl_number") 171 172 173@utils.register_interface(ExtensionType) 174class AuthorityKeyIdentifier(object): 175 oid = ExtensionOID.AUTHORITY_KEY_IDENTIFIER 176 177 def __init__( 178 self, 179 key_identifier, 180 authority_cert_issuer, 181 authority_cert_serial_number, 182 ): 183 if (authority_cert_issuer is None) != ( 184 authority_cert_serial_number is None 185 ): 186 raise ValueError( 187 "authority_cert_issuer and authority_cert_serial_number " 188 "must both be present or both None" 189 ) 190 191 if authority_cert_issuer is not None: 192 authority_cert_issuer = list(authority_cert_issuer) 193 if not all( 194 isinstance(x, GeneralName) for x in authority_cert_issuer 195 ): 196 raise TypeError( 197 "authority_cert_issuer must be a list of GeneralName " 198 "objects" 199 ) 200 201 if authority_cert_serial_number is not None and not isinstance( 202 authority_cert_serial_number, six.integer_types 203 ): 204 raise TypeError("authority_cert_serial_number must be an integer") 205 206 self._key_identifier = key_identifier 207 self._authority_cert_issuer = authority_cert_issuer 208 self._authority_cert_serial_number = authority_cert_serial_number 209 210 @classmethod 211 def from_issuer_public_key(cls, public_key): 212 digest = _key_identifier_from_public_key(public_key) 213 return cls( 214 key_identifier=digest, 215 authority_cert_issuer=None, 216 authority_cert_serial_number=None, 217 ) 218 219 @classmethod 220 def from_issuer_subject_key_identifier(cls, ski): 221 return cls( 222 key_identifier=ski.digest, 223 authority_cert_issuer=None, 224 authority_cert_serial_number=None, 225 ) 226 227 def __repr__(self): 228 return ( 229 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, " 230 "authority_cert_issuer={0.authority_cert_issuer}, " 231 "authority_cert_serial_number={0.authority_cert_serial_number}" 232 ")>".format(self) 233 ) 234 235 def __eq__(self, other): 236 if not isinstance(other, AuthorityKeyIdentifier): 237 return NotImplemented 238 239 return ( 240 self.key_identifier == other.key_identifier 241 and self.authority_cert_issuer == other.authority_cert_issuer 242 and self.authority_cert_serial_number 243 == other.authority_cert_serial_number 244 ) 245 246 def __ne__(self, other): 247 return not self == other 248 249 def __hash__(self): 250 if self.authority_cert_issuer is None: 251 aci = None 252 else: 253 aci = tuple(self.authority_cert_issuer) 254 return hash( 255 (self.key_identifier, aci, self.authority_cert_serial_number) 256 ) 257 258 key_identifier = utils.read_only_property("_key_identifier") 259 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer") 260 authority_cert_serial_number = utils.read_only_property( 261 "_authority_cert_serial_number" 262 ) 263 264 265@utils.register_interface(ExtensionType) 266class SubjectKeyIdentifier(object): 267 oid = ExtensionOID.SUBJECT_KEY_IDENTIFIER 268 269 def __init__(self, digest): 270 self._digest = digest 271 272 @classmethod 273 def from_public_key(cls, public_key): 274 return cls(_key_identifier_from_public_key(public_key)) 275 276 digest = utils.read_only_property("_digest") 277 278 def __repr__(self): 279 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest) 280 281 def __eq__(self, other): 282 if not isinstance(other, SubjectKeyIdentifier): 283 return NotImplemented 284 285 return constant_time.bytes_eq(self.digest, other.digest) 286 287 def __ne__(self, other): 288 return not self == other 289 290 def __hash__(self): 291 return hash(self.digest) 292 293 294@utils.register_interface(ExtensionType) 295class AuthorityInformationAccess(object): 296 oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS 297 298 def __init__(self, descriptions): 299 descriptions = list(descriptions) 300 if not all(isinstance(x, AccessDescription) for x in descriptions): 301 raise TypeError( 302 "Every item in the descriptions list must be an " 303 "AccessDescription" 304 ) 305 306 self._descriptions = descriptions 307 308 __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") 309 310 def __repr__(self): 311 return "<AuthorityInformationAccess({})>".format(self._descriptions) 312 313 def __eq__(self, other): 314 if not isinstance(other, AuthorityInformationAccess): 315 return NotImplemented 316 317 return self._descriptions == other._descriptions 318 319 def __ne__(self, other): 320 return not self == other 321 322 def __hash__(self): 323 return hash(tuple(self._descriptions)) 324 325 326@utils.register_interface(ExtensionType) 327class SubjectInformationAccess(object): 328 oid = ExtensionOID.SUBJECT_INFORMATION_ACCESS 329 330 def __init__(self, descriptions): 331 descriptions = list(descriptions) 332 if not all(isinstance(x, AccessDescription) for x in descriptions): 333 raise TypeError( 334 "Every item in the descriptions list must be an " 335 "AccessDescription" 336 ) 337 338 self._descriptions = descriptions 339 340 __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") 341 342 def __repr__(self): 343 return "<SubjectInformationAccess({})>".format(self._descriptions) 344 345 def __eq__(self, other): 346 if not isinstance(other, SubjectInformationAccess): 347 return NotImplemented 348 349 return self._descriptions == other._descriptions 350 351 def __ne__(self, other): 352 return not self == other 353 354 def __hash__(self): 355 return hash(tuple(self._descriptions)) 356 357 358class AccessDescription(object): 359 def __init__(self, access_method, access_location): 360 if not isinstance(access_method, ObjectIdentifier): 361 raise TypeError("access_method must be an ObjectIdentifier") 362 363 if not isinstance(access_location, GeneralName): 364 raise TypeError("access_location must be a GeneralName") 365 366 self._access_method = access_method 367 self._access_location = access_location 368 369 def __repr__(self): 370 return ( 371 "<AccessDescription(access_method={0.access_method}, access_locati" 372 "on={0.access_location})>".format(self) 373 ) 374 375 def __eq__(self, other): 376 if not isinstance(other, AccessDescription): 377 return NotImplemented 378 379 return ( 380 self.access_method == other.access_method 381 and self.access_location == other.access_location 382 ) 383 384 def __ne__(self, other): 385 return not self == other 386 387 def __hash__(self): 388 return hash((self.access_method, self.access_location)) 389 390 access_method = utils.read_only_property("_access_method") 391 access_location = utils.read_only_property("_access_location") 392 393 394@utils.register_interface(ExtensionType) 395class BasicConstraints(object): 396 oid = ExtensionOID.BASIC_CONSTRAINTS 397 398 def __init__(self, ca, path_length): 399 if not isinstance(ca, bool): 400 raise TypeError("ca must be a boolean value") 401 402 if path_length is not None and not ca: 403 raise ValueError("path_length must be None when ca is False") 404 405 if path_length is not None and ( 406 not isinstance(path_length, six.integer_types) or path_length < 0 407 ): 408 raise TypeError( 409 "path_length must be a non-negative integer or None" 410 ) 411 412 self._ca = ca 413 self._path_length = path_length 414 415 ca = utils.read_only_property("_ca") 416 path_length = utils.read_only_property("_path_length") 417 418 def __repr__(self): 419 return ( 420 "<BasicConstraints(ca={0.ca}, " "path_length={0.path_length})>" 421 ).format(self) 422 423 def __eq__(self, other): 424 if not isinstance(other, BasicConstraints): 425 return NotImplemented 426 427 return self.ca == other.ca and self.path_length == other.path_length 428 429 def __ne__(self, other): 430 return not self == other 431 432 def __hash__(self): 433 return hash((self.ca, self.path_length)) 434 435 436@utils.register_interface(ExtensionType) 437class DeltaCRLIndicator(object): 438 oid = ExtensionOID.DELTA_CRL_INDICATOR 439 440 def __init__(self, crl_number): 441 if not isinstance(crl_number, six.integer_types): 442 raise TypeError("crl_number must be an integer") 443 444 self._crl_number = crl_number 445 446 crl_number = utils.read_only_property("_crl_number") 447 448 def __eq__(self, other): 449 if not isinstance(other, DeltaCRLIndicator): 450 return NotImplemented 451 452 return self.crl_number == other.crl_number 453 454 def __ne__(self, other): 455 return not self == other 456 457 def __hash__(self): 458 return hash(self.crl_number) 459 460 def __repr__(self): 461 return "<DeltaCRLIndicator(crl_number={0.crl_number})>".format(self) 462 463 464@utils.register_interface(ExtensionType) 465class CRLDistributionPoints(object): 466 oid = ExtensionOID.CRL_DISTRIBUTION_POINTS 467 468 def __init__(self, distribution_points): 469 distribution_points = list(distribution_points) 470 if not all( 471 isinstance(x, DistributionPoint) for x in distribution_points 472 ): 473 raise TypeError( 474 "distribution_points must be a list of DistributionPoint " 475 "objects" 476 ) 477 478 self._distribution_points = distribution_points 479 480 __len__, __iter__, __getitem__ = _make_sequence_methods( 481 "_distribution_points" 482 ) 483 484 def __repr__(self): 485 return "<CRLDistributionPoints({})>".format(self._distribution_points) 486 487 def __eq__(self, other): 488 if not isinstance(other, CRLDistributionPoints): 489 return NotImplemented 490 491 return self._distribution_points == other._distribution_points 492 493 def __ne__(self, other): 494 return not self == other 495 496 def __hash__(self): 497 return hash(tuple(self._distribution_points)) 498 499 500@utils.register_interface(ExtensionType) 501class FreshestCRL(object): 502 oid = ExtensionOID.FRESHEST_CRL 503 504 def __init__(self, distribution_points): 505 distribution_points = list(distribution_points) 506 if not all( 507 isinstance(x, DistributionPoint) for x in distribution_points 508 ): 509 raise TypeError( 510 "distribution_points must be a list of DistributionPoint " 511 "objects" 512 ) 513 514 self._distribution_points = distribution_points 515 516 __len__, __iter__, __getitem__ = _make_sequence_methods( 517 "_distribution_points" 518 ) 519 520 def __repr__(self): 521 return "<FreshestCRL({})>".format(self._distribution_points) 522 523 def __eq__(self, other): 524 if not isinstance(other, FreshestCRL): 525 return NotImplemented 526 527 return self._distribution_points == other._distribution_points 528 529 def __ne__(self, other): 530 return not self == other 531 532 def __hash__(self): 533 return hash(tuple(self._distribution_points)) 534 535 536class DistributionPoint(object): 537 def __init__(self, full_name, relative_name, reasons, crl_issuer): 538 if full_name and relative_name: 539 raise ValueError( 540 "You cannot provide both full_name and relative_name, at " 541 "least one must be None." 542 ) 543 544 if full_name: 545 full_name = list(full_name) 546 if not all(isinstance(x, GeneralName) for x in full_name): 547 raise TypeError( 548 "full_name must be a list of GeneralName objects" 549 ) 550 551 if relative_name: 552 if not isinstance(relative_name, RelativeDistinguishedName): 553 raise TypeError( 554 "relative_name must be a RelativeDistinguishedName" 555 ) 556 557 if crl_issuer: 558 crl_issuer = list(crl_issuer) 559 if not all(isinstance(x, GeneralName) for x in crl_issuer): 560 raise TypeError( 561 "crl_issuer must be None or a list of general names" 562 ) 563 564 if reasons and ( 565 not isinstance(reasons, frozenset) 566 or not all(isinstance(x, ReasonFlags) for x in reasons) 567 ): 568 raise TypeError("reasons must be None or frozenset of ReasonFlags") 569 570 if reasons and ( 571 ReasonFlags.unspecified in reasons 572 or ReasonFlags.remove_from_crl in reasons 573 ): 574 raise ValueError( 575 "unspecified and remove_from_crl are not valid reasons in a " 576 "DistributionPoint" 577 ) 578 579 if reasons and not crl_issuer and not (full_name or relative_name): 580 raise ValueError( 581 "You must supply crl_issuer, full_name, or relative_name when " 582 "reasons is not None" 583 ) 584 585 self._full_name = full_name 586 self._relative_name = relative_name 587 self._reasons = reasons 588 self._crl_issuer = crl_issuer 589 590 def __repr__(self): 591 return ( 592 "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela" 593 "tive_name}, reasons={0.reasons}, " 594 "crl_issuer={0.crl_issuer})>".format(self) 595 ) 596 597 def __eq__(self, other): 598 if not isinstance(other, DistributionPoint): 599 return NotImplemented 600 601 return ( 602 self.full_name == other.full_name 603 and self.relative_name == other.relative_name 604 and self.reasons == other.reasons 605 and self.crl_issuer == other.crl_issuer 606 ) 607 608 def __ne__(self, other): 609 return not self == other 610 611 def __hash__(self): 612 if self.full_name is not None: 613 fn = tuple(self.full_name) 614 else: 615 fn = None 616 617 if self.crl_issuer is not None: 618 crl_issuer = tuple(self.crl_issuer) 619 else: 620 crl_issuer = None 621 622 return hash((fn, self.relative_name, self.reasons, crl_issuer)) 623 624 full_name = utils.read_only_property("_full_name") 625 relative_name = utils.read_only_property("_relative_name") 626 reasons = utils.read_only_property("_reasons") 627 crl_issuer = utils.read_only_property("_crl_issuer") 628 629 630class ReasonFlags(Enum): 631 unspecified = "unspecified" 632 key_compromise = "keyCompromise" 633 ca_compromise = "cACompromise" 634 affiliation_changed = "affiliationChanged" 635 superseded = "superseded" 636 cessation_of_operation = "cessationOfOperation" 637 certificate_hold = "certificateHold" 638 privilege_withdrawn = "privilegeWithdrawn" 639 aa_compromise = "aACompromise" 640 remove_from_crl = "removeFromCRL" 641 642 643@utils.register_interface(ExtensionType) 644class PolicyConstraints(object): 645 oid = ExtensionOID.POLICY_CONSTRAINTS 646 647 def __init__(self, require_explicit_policy, inhibit_policy_mapping): 648 if require_explicit_policy is not None and not isinstance( 649 require_explicit_policy, six.integer_types 650 ): 651 raise TypeError( 652 "require_explicit_policy must be a non-negative integer or " 653 "None" 654 ) 655 656 if inhibit_policy_mapping is not None and not isinstance( 657 inhibit_policy_mapping, six.integer_types 658 ): 659 raise TypeError( 660 "inhibit_policy_mapping must be a non-negative integer or None" 661 ) 662 663 if inhibit_policy_mapping is None and require_explicit_policy is None: 664 raise ValueError( 665 "At least one of require_explicit_policy and " 666 "inhibit_policy_mapping must not be None" 667 ) 668 669 self._require_explicit_policy = require_explicit_policy 670 self._inhibit_policy_mapping = inhibit_policy_mapping 671 672 def __repr__(self): 673 return ( 674 u"<PolicyConstraints(require_explicit_policy={0.require_explicit" 675 u"_policy}, inhibit_policy_mapping={0.inhibit_policy_" 676 u"mapping})>".format(self) 677 ) 678 679 def __eq__(self, other): 680 if not isinstance(other, PolicyConstraints): 681 return NotImplemented 682 683 return ( 684 self.require_explicit_policy == other.require_explicit_policy 685 and self.inhibit_policy_mapping == other.inhibit_policy_mapping 686 ) 687 688 def __ne__(self, other): 689 return not self == other 690 691 def __hash__(self): 692 return hash( 693 (self.require_explicit_policy, self.inhibit_policy_mapping) 694 ) 695 696 require_explicit_policy = utils.read_only_property( 697 "_require_explicit_policy" 698 ) 699 inhibit_policy_mapping = utils.read_only_property( 700 "_inhibit_policy_mapping" 701 ) 702 703 704@utils.register_interface(ExtensionType) 705class CertificatePolicies(object): 706 oid = ExtensionOID.CERTIFICATE_POLICIES 707 708 def __init__(self, policies): 709 policies = list(policies) 710 if not all(isinstance(x, PolicyInformation) for x in policies): 711 raise TypeError( 712 "Every item in the policies list must be a " 713 "PolicyInformation" 714 ) 715 716 self._policies = policies 717 718 __len__, __iter__, __getitem__ = _make_sequence_methods("_policies") 719 720 def __repr__(self): 721 return "<CertificatePolicies({})>".format(self._policies) 722 723 def __eq__(self, other): 724 if not isinstance(other, CertificatePolicies): 725 return NotImplemented 726 727 return self._policies == other._policies 728 729 def __ne__(self, other): 730 return not self == other 731 732 def __hash__(self): 733 return hash(tuple(self._policies)) 734 735 736class PolicyInformation(object): 737 def __init__(self, policy_identifier, policy_qualifiers): 738 if not isinstance(policy_identifier, ObjectIdentifier): 739 raise TypeError("policy_identifier must be an ObjectIdentifier") 740 741 self._policy_identifier = policy_identifier 742 743 if policy_qualifiers: 744 policy_qualifiers = list(policy_qualifiers) 745 if not all( 746 isinstance(x, (six.text_type, UserNotice)) 747 for x in policy_qualifiers 748 ): 749 raise TypeError( 750 "policy_qualifiers must be a list of strings and/or " 751 "UserNotice objects or None" 752 ) 753 754 self._policy_qualifiers = policy_qualifiers 755 756 def __repr__(self): 757 return ( 758 "<PolicyInformation(policy_identifier={0.policy_identifier}, polic" 759 "y_qualifiers={0.policy_qualifiers})>".format(self) 760 ) 761 762 def __eq__(self, other): 763 if not isinstance(other, PolicyInformation): 764 return NotImplemented 765 766 return ( 767 self.policy_identifier == other.policy_identifier 768 and self.policy_qualifiers == other.policy_qualifiers 769 ) 770 771 def __ne__(self, other): 772 return not self == other 773 774 def __hash__(self): 775 if self.policy_qualifiers is not None: 776 pq = tuple(self.policy_qualifiers) 777 else: 778 pq = None 779 780 return hash((self.policy_identifier, pq)) 781 782 policy_identifier = utils.read_only_property("_policy_identifier") 783 policy_qualifiers = utils.read_only_property("_policy_qualifiers") 784 785 786class UserNotice(object): 787 def __init__(self, notice_reference, explicit_text): 788 if notice_reference and not isinstance( 789 notice_reference, NoticeReference 790 ): 791 raise TypeError( 792 "notice_reference must be None or a NoticeReference" 793 ) 794 795 self._notice_reference = notice_reference 796 self._explicit_text = explicit_text 797 798 def __repr__(self): 799 return ( 800 "<UserNotice(notice_reference={0.notice_reference}, explicit_text=" 801 "{0.explicit_text!r})>".format(self) 802 ) 803 804 def __eq__(self, other): 805 if not isinstance(other, UserNotice): 806 return NotImplemented 807 808 return ( 809 self.notice_reference == other.notice_reference 810 and self.explicit_text == other.explicit_text 811 ) 812 813 def __ne__(self, other): 814 return not self == other 815 816 def __hash__(self): 817 return hash((self.notice_reference, self.explicit_text)) 818 819 notice_reference = utils.read_only_property("_notice_reference") 820 explicit_text = utils.read_only_property("_explicit_text") 821 822 823class NoticeReference(object): 824 def __init__(self, organization, notice_numbers): 825 self._organization = organization 826 notice_numbers = list(notice_numbers) 827 if not all(isinstance(x, int) for x in notice_numbers): 828 raise TypeError("notice_numbers must be a list of integers") 829 830 self._notice_numbers = notice_numbers 831 832 def __repr__(self): 833 return ( 834 "<NoticeReference(organization={0.organization!r}, notice_numbers=" 835 "{0.notice_numbers})>".format(self) 836 ) 837 838 def __eq__(self, other): 839 if not isinstance(other, NoticeReference): 840 return NotImplemented 841 842 return ( 843 self.organization == other.organization 844 and self.notice_numbers == other.notice_numbers 845 ) 846 847 def __ne__(self, other): 848 return not self == other 849 850 def __hash__(self): 851 return hash((self.organization, tuple(self.notice_numbers))) 852 853 organization = utils.read_only_property("_organization") 854 notice_numbers = utils.read_only_property("_notice_numbers") 855 856 857@utils.register_interface(ExtensionType) 858class ExtendedKeyUsage(object): 859 oid = ExtensionOID.EXTENDED_KEY_USAGE 860 861 def __init__(self, usages): 862 usages = list(usages) 863 if not all(isinstance(x, ObjectIdentifier) for x in usages): 864 raise TypeError( 865 "Every item in the usages list must be an ObjectIdentifier" 866 ) 867 868 self._usages = usages 869 870 __len__, __iter__, __getitem__ = _make_sequence_methods("_usages") 871 872 def __repr__(self): 873 return "<ExtendedKeyUsage({})>".format(self._usages) 874 875 def __eq__(self, other): 876 if not isinstance(other, ExtendedKeyUsage): 877 return NotImplemented 878 879 return self._usages == other._usages 880 881 def __ne__(self, other): 882 return not self == other 883 884 def __hash__(self): 885 return hash(tuple(self._usages)) 886 887 888@utils.register_interface(ExtensionType) 889class OCSPNoCheck(object): 890 oid = ExtensionOID.OCSP_NO_CHECK 891 892 def __eq__(self, other): 893 if not isinstance(other, OCSPNoCheck): 894 return NotImplemented 895 896 return True 897 898 def __ne__(self, other): 899 return not self == other 900 901 def __hash__(self): 902 return hash(OCSPNoCheck) 903 904 def __repr__(self): 905 return "<OCSPNoCheck()>" 906 907 908@utils.register_interface(ExtensionType) 909class PrecertPoison(object): 910 oid = ExtensionOID.PRECERT_POISON 911 912 def __eq__(self, other): 913 if not isinstance(other, PrecertPoison): 914 return NotImplemented 915 916 return True 917 918 def __ne__(self, other): 919 return not self == other 920 921 def __hash__(self): 922 return hash(PrecertPoison) 923 924 def __repr__(self): 925 return "<PrecertPoison()>" 926 927 928@utils.register_interface(ExtensionType) 929class TLSFeature(object): 930 oid = ExtensionOID.TLS_FEATURE 931 932 def __init__(self, features): 933 features = list(features) 934 if ( 935 not all(isinstance(x, TLSFeatureType) for x in features) 936 or len(features) == 0 937 ): 938 raise TypeError( 939 "features must be a list of elements from the TLSFeatureType " 940 "enum" 941 ) 942 943 self._features = features 944 945 __len__, __iter__, __getitem__ = _make_sequence_methods("_features") 946 947 def __repr__(self): 948 return "<TLSFeature(features={0._features})>".format(self) 949 950 def __eq__(self, other): 951 if not isinstance(other, TLSFeature): 952 return NotImplemented 953 954 return self._features == other._features 955 956 def __ne__(self, other): 957 return not self == other 958 959 def __hash__(self): 960 return hash(tuple(self._features)) 961 962 963class TLSFeatureType(Enum): 964 # status_request is defined in RFC 6066 and is used for what is commonly 965 # called OCSP Must-Staple when present in the TLS Feature extension in an 966 # X.509 certificate. 967 status_request = 5 968 # status_request_v2 is defined in RFC 6961 and allows multiple OCSP 969 # responses to be provided. It is not currently in use by clients or 970 # servers. 971 status_request_v2 = 17 972 973 974_TLS_FEATURE_TYPE_TO_ENUM = {x.value: x for x in TLSFeatureType} 975 976 977@utils.register_interface(ExtensionType) 978class InhibitAnyPolicy(object): 979 oid = ExtensionOID.INHIBIT_ANY_POLICY 980 981 def __init__(self, skip_certs): 982 if not isinstance(skip_certs, six.integer_types): 983 raise TypeError("skip_certs must be an integer") 984 985 if skip_certs < 0: 986 raise ValueError("skip_certs must be a non-negative integer") 987 988 self._skip_certs = skip_certs 989 990 def __repr__(self): 991 return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self) 992 993 def __eq__(self, other): 994 if not isinstance(other, InhibitAnyPolicy): 995 return NotImplemented 996 997 return self.skip_certs == other.skip_certs 998 999 def __ne__(self, other): 1000 return not self == other 1001 1002 def __hash__(self): 1003 return hash(self.skip_certs) 1004 1005 skip_certs = utils.read_only_property("_skip_certs") 1006 1007 1008@utils.register_interface(ExtensionType) 1009class KeyUsage(object): 1010 oid = ExtensionOID.KEY_USAGE 1011 1012 def __init__( 1013 self, 1014 digital_signature, 1015 content_commitment, 1016 key_encipherment, 1017 data_encipherment, 1018 key_agreement, 1019 key_cert_sign, 1020 crl_sign, 1021 encipher_only, 1022 decipher_only, 1023 ): 1024 if not key_agreement and (encipher_only or decipher_only): 1025 raise ValueError( 1026 "encipher_only and decipher_only can only be true when " 1027 "key_agreement is true" 1028 ) 1029 1030 self._digital_signature = digital_signature 1031 self._content_commitment = content_commitment 1032 self._key_encipherment = key_encipherment 1033 self._data_encipherment = data_encipherment 1034 self._key_agreement = key_agreement 1035 self._key_cert_sign = key_cert_sign 1036 self._crl_sign = crl_sign 1037 self._encipher_only = encipher_only 1038 self._decipher_only = decipher_only 1039 1040 digital_signature = utils.read_only_property("_digital_signature") 1041 content_commitment = utils.read_only_property("_content_commitment") 1042 key_encipherment = utils.read_only_property("_key_encipherment") 1043 data_encipherment = utils.read_only_property("_data_encipherment") 1044 key_agreement = utils.read_only_property("_key_agreement") 1045 key_cert_sign = utils.read_only_property("_key_cert_sign") 1046 crl_sign = utils.read_only_property("_crl_sign") 1047 1048 @property 1049 def encipher_only(self): 1050 if not self.key_agreement: 1051 raise ValueError( 1052 "encipher_only is undefined unless key_agreement is true" 1053 ) 1054 else: 1055 return self._encipher_only 1056 1057 @property 1058 def decipher_only(self): 1059 if not self.key_agreement: 1060 raise ValueError( 1061 "decipher_only is undefined unless key_agreement is true" 1062 ) 1063 else: 1064 return self._decipher_only 1065 1066 def __repr__(self): 1067 try: 1068 encipher_only = self.encipher_only 1069 decipher_only = self.decipher_only 1070 except ValueError: 1071 # Users found None confusing because even though encipher/decipher 1072 # have no meaning unless key_agreement is true, to construct an 1073 # instance of the class you still need to pass False. 1074 encipher_only = False 1075 decipher_only = False 1076 1077 return ( 1078 "<KeyUsage(digital_signature={0.digital_signature}, " 1079 "content_commitment={0.content_commitment}, " 1080 "key_encipherment={0.key_encipherment}, " 1081 "data_encipherment={0.data_encipherment}, " 1082 "key_agreement={0.key_agreement}, " 1083 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, " 1084 "encipher_only={1}, decipher_only={2})>" 1085 ).format(self, encipher_only, decipher_only) 1086 1087 def __eq__(self, other): 1088 if not isinstance(other, KeyUsage): 1089 return NotImplemented 1090 1091 return ( 1092 self.digital_signature == other.digital_signature 1093 and self.content_commitment == other.content_commitment 1094 and self.key_encipherment == other.key_encipherment 1095 and self.data_encipherment == other.data_encipherment 1096 and self.key_agreement == other.key_agreement 1097 and self.key_cert_sign == other.key_cert_sign 1098 and self.crl_sign == other.crl_sign 1099 and self._encipher_only == other._encipher_only 1100 and self._decipher_only == other._decipher_only 1101 ) 1102 1103 def __ne__(self, other): 1104 return not self == other 1105 1106 def __hash__(self): 1107 return hash( 1108 ( 1109 self.digital_signature, 1110 self.content_commitment, 1111 self.key_encipherment, 1112 self.data_encipherment, 1113 self.key_agreement, 1114 self.key_cert_sign, 1115 self.crl_sign, 1116 self._encipher_only, 1117 self._decipher_only, 1118 ) 1119 ) 1120 1121 1122@utils.register_interface(ExtensionType) 1123class NameConstraints(object): 1124 oid = ExtensionOID.NAME_CONSTRAINTS 1125 1126 def __init__(self, permitted_subtrees, excluded_subtrees): 1127 if permitted_subtrees is not None: 1128 permitted_subtrees = list(permitted_subtrees) 1129 if not all(isinstance(x, GeneralName) for x in permitted_subtrees): 1130 raise TypeError( 1131 "permitted_subtrees must be a list of GeneralName objects " 1132 "or None" 1133 ) 1134 1135 self._validate_ip_name(permitted_subtrees) 1136 1137 if excluded_subtrees is not None: 1138 excluded_subtrees = list(excluded_subtrees) 1139 if not all(isinstance(x, GeneralName) for x in excluded_subtrees): 1140 raise TypeError( 1141 "excluded_subtrees must be a list of GeneralName objects " 1142 "or None" 1143 ) 1144 1145 self._validate_ip_name(excluded_subtrees) 1146 1147 if permitted_subtrees is None and excluded_subtrees is None: 1148 raise ValueError( 1149 "At least one of permitted_subtrees and excluded_subtrees " 1150 "must not be None" 1151 ) 1152 1153 self._permitted_subtrees = permitted_subtrees 1154 self._excluded_subtrees = excluded_subtrees 1155 1156 def __eq__(self, other): 1157 if not isinstance(other, NameConstraints): 1158 return NotImplemented 1159 1160 return ( 1161 self.excluded_subtrees == other.excluded_subtrees 1162 and self.permitted_subtrees == other.permitted_subtrees 1163 ) 1164 1165 def __ne__(self, other): 1166 return not self == other 1167 1168 def _validate_ip_name(self, tree): 1169 if any( 1170 isinstance(name, IPAddress) 1171 and not isinstance( 1172 name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network) 1173 ) 1174 for name in tree 1175 ): 1176 raise TypeError( 1177 "IPAddress name constraints must be an IPv4Network or" 1178 " IPv6Network object" 1179 ) 1180 1181 def __repr__(self): 1182 return ( 1183 u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, " 1184 u"excluded_subtrees={0.excluded_subtrees})>".format(self) 1185 ) 1186 1187 def __hash__(self): 1188 if self.permitted_subtrees is not None: 1189 ps = tuple(self.permitted_subtrees) 1190 else: 1191 ps = None 1192 1193 if self.excluded_subtrees is not None: 1194 es = tuple(self.excluded_subtrees) 1195 else: 1196 es = None 1197 1198 return hash((ps, es)) 1199 1200 permitted_subtrees = utils.read_only_property("_permitted_subtrees") 1201 excluded_subtrees = utils.read_only_property("_excluded_subtrees") 1202 1203 1204class Extension(object): 1205 def __init__(self, oid, critical, value): 1206 if not isinstance(oid, ObjectIdentifier): 1207 raise TypeError( 1208 "oid argument must be an ObjectIdentifier instance." 1209 ) 1210 1211 if not isinstance(critical, bool): 1212 raise TypeError("critical must be a boolean value") 1213 1214 self._oid = oid 1215 self._critical = critical 1216 self._value = value 1217 1218 oid = utils.read_only_property("_oid") 1219 critical = utils.read_only_property("_critical") 1220 value = utils.read_only_property("_value") 1221 1222 def __repr__(self): 1223 return ( 1224 "<Extension(oid={0.oid}, critical={0.critical}, " 1225 "value={0.value})>" 1226 ).format(self) 1227 1228 def __eq__(self, other): 1229 if not isinstance(other, Extension): 1230 return NotImplemented 1231 1232 return ( 1233 self.oid == other.oid 1234 and self.critical == other.critical 1235 and self.value == other.value 1236 ) 1237 1238 def __ne__(self, other): 1239 return not self == other 1240 1241 def __hash__(self): 1242 return hash((self.oid, self.critical, self.value)) 1243 1244 1245class GeneralNames(object): 1246 def __init__(self, general_names): 1247 general_names = list(general_names) 1248 if not all(isinstance(x, GeneralName) for x in general_names): 1249 raise TypeError( 1250 "Every item in the general_names list must be an " 1251 "object conforming to the GeneralName interface" 1252 ) 1253 1254 self._general_names = general_names 1255 1256 __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") 1257 1258 def get_values_for_type(self, type): 1259 # Return the value of each GeneralName, except for OtherName instances 1260 # which we return directly because it has two important properties not 1261 # just one value. 1262 objs = (i for i in self if isinstance(i, type)) 1263 if type != OtherName: 1264 objs = (i.value for i in objs) 1265 return list(objs) 1266 1267 def __repr__(self): 1268 return "<GeneralNames({})>".format(self._general_names) 1269 1270 def __eq__(self, other): 1271 if not isinstance(other, GeneralNames): 1272 return NotImplemented 1273 1274 return self._general_names == other._general_names 1275 1276 def __ne__(self, other): 1277 return not self == other 1278 1279 def __hash__(self): 1280 return hash(tuple(self._general_names)) 1281 1282 1283@utils.register_interface(ExtensionType) 1284class SubjectAlternativeName(object): 1285 oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME 1286 1287 def __init__(self, general_names): 1288 self._general_names = GeneralNames(general_names) 1289 1290 __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") 1291 1292 def get_values_for_type(self, type): 1293 return self._general_names.get_values_for_type(type) 1294 1295 def __repr__(self): 1296 return "<SubjectAlternativeName({})>".format(self._general_names) 1297 1298 def __eq__(self, other): 1299 if not isinstance(other, SubjectAlternativeName): 1300 return NotImplemented 1301 1302 return self._general_names == other._general_names 1303 1304 def __ne__(self, other): 1305 return not self == other 1306 1307 def __hash__(self): 1308 return hash(self._general_names) 1309 1310 1311@utils.register_interface(ExtensionType) 1312class IssuerAlternativeName(object): 1313 oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME 1314 1315 def __init__(self, general_names): 1316 self._general_names = GeneralNames(general_names) 1317 1318 __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") 1319 1320 def get_values_for_type(self, type): 1321 return self._general_names.get_values_for_type(type) 1322 1323 def __repr__(self): 1324 return "<IssuerAlternativeName({})>".format(self._general_names) 1325 1326 def __eq__(self, other): 1327 if not isinstance(other, IssuerAlternativeName): 1328 return NotImplemented 1329 1330 return self._general_names == other._general_names 1331 1332 def __ne__(self, other): 1333 return not self == other 1334 1335 def __hash__(self): 1336 return hash(self._general_names) 1337 1338 1339@utils.register_interface(ExtensionType) 1340class CertificateIssuer(object): 1341 oid = CRLEntryExtensionOID.CERTIFICATE_ISSUER 1342 1343 def __init__(self, general_names): 1344 self._general_names = GeneralNames(general_names) 1345 1346 __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") 1347 1348 def get_values_for_type(self, type): 1349 return self._general_names.get_values_for_type(type) 1350 1351 def __repr__(self): 1352 return "<CertificateIssuer({})>".format(self._general_names) 1353 1354 def __eq__(self, other): 1355 if not isinstance(other, CertificateIssuer): 1356 return NotImplemented 1357 1358 return self._general_names == other._general_names 1359 1360 def __ne__(self, other): 1361 return not self == other 1362 1363 def __hash__(self): 1364 return hash(self._general_names) 1365 1366 1367@utils.register_interface(ExtensionType) 1368class CRLReason(object): 1369 oid = CRLEntryExtensionOID.CRL_REASON 1370 1371 def __init__(self, reason): 1372 if not isinstance(reason, ReasonFlags): 1373 raise TypeError("reason must be an element from ReasonFlags") 1374 1375 self._reason = reason 1376 1377 def __repr__(self): 1378 return "<CRLReason(reason={})>".format(self._reason) 1379 1380 def __eq__(self, other): 1381 if not isinstance(other, CRLReason): 1382 return NotImplemented 1383 1384 return self.reason == other.reason 1385 1386 def __ne__(self, other): 1387 return not self == other 1388 1389 def __hash__(self): 1390 return hash(self.reason) 1391 1392 reason = utils.read_only_property("_reason") 1393 1394 1395@utils.register_interface(ExtensionType) 1396class InvalidityDate(object): 1397 oid = CRLEntryExtensionOID.INVALIDITY_DATE 1398 1399 def __init__(self, invalidity_date): 1400 if not isinstance(invalidity_date, datetime.datetime): 1401 raise TypeError("invalidity_date must be a datetime.datetime") 1402 1403 self._invalidity_date = invalidity_date 1404 1405 def __repr__(self): 1406 return "<InvalidityDate(invalidity_date={})>".format( 1407 self._invalidity_date 1408 ) 1409 1410 def __eq__(self, other): 1411 if not isinstance(other, InvalidityDate): 1412 return NotImplemented 1413 1414 return self.invalidity_date == other.invalidity_date 1415 1416 def __ne__(self, other): 1417 return not self == other 1418 1419 def __hash__(self): 1420 return hash(self.invalidity_date) 1421 1422 invalidity_date = utils.read_only_property("_invalidity_date") 1423 1424 1425@utils.register_interface(ExtensionType) 1426class PrecertificateSignedCertificateTimestamps(object): 1427 oid = ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS 1428 1429 def __init__(self, signed_certificate_timestamps): 1430 signed_certificate_timestamps = list(signed_certificate_timestamps) 1431 if not all( 1432 isinstance(sct, SignedCertificateTimestamp) 1433 for sct in signed_certificate_timestamps 1434 ): 1435 raise TypeError( 1436 "Every item in the signed_certificate_timestamps list must be " 1437 "a SignedCertificateTimestamp" 1438 ) 1439 self._signed_certificate_timestamps = signed_certificate_timestamps 1440 1441 __len__, __iter__, __getitem__ = _make_sequence_methods( 1442 "_signed_certificate_timestamps" 1443 ) 1444 1445 def __repr__(self): 1446 return "<PrecertificateSignedCertificateTimestamps({})>".format( 1447 list(self) 1448 ) 1449 1450 def __hash__(self): 1451 return hash(tuple(self._signed_certificate_timestamps)) 1452 1453 def __eq__(self, other): 1454 if not isinstance(other, PrecertificateSignedCertificateTimestamps): 1455 return NotImplemented 1456 1457 return ( 1458 self._signed_certificate_timestamps 1459 == other._signed_certificate_timestamps 1460 ) 1461 1462 def __ne__(self, other): 1463 return not self == other 1464 1465 1466@utils.register_interface(ExtensionType) 1467class SignedCertificateTimestamps(object): 1468 oid = ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS 1469 1470 def __init__(self, signed_certificate_timestamps): 1471 signed_certificate_timestamps = list(signed_certificate_timestamps) 1472 if not all( 1473 isinstance(sct, SignedCertificateTimestamp) 1474 for sct in signed_certificate_timestamps 1475 ): 1476 raise TypeError( 1477 "Every item in the signed_certificate_timestamps list must be " 1478 "a SignedCertificateTimestamp" 1479 ) 1480 self._signed_certificate_timestamps = signed_certificate_timestamps 1481 1482 __len__, __iter__, __getitem__ = _make_sequence_methods( 1483 "_signed_certificate_timestamps" 1484 ) 1485 1486 def __repr__(self): 1487 return "<SignedCertificateTimestamps({})>".format(list(self)) 1488 1489 def __hash__(self): 1490 return hash(tuple(self._signed_certificate_timestamps)) 1491 1492 def __eq__(self, other): 1493 if not isinstance(other, SignedCertificateTimestamps): 1494 return NotImplemented 1495 1496 return ( 1497 self._signed_certificate_timestamps 1498 == other._signed_certificate_timestamps 1499 ) 1500 1501 def __ne__(self, other): 1502 return not self == other 1503 1504 1505@utils.register_interface(ExtensionType) 1506class OCSPNonce(object): 1507 oid = OCSPExtensionOID.NONCE 1508 1509 def __init__(self, nonce): 1510 if not isinstance(nonce, bytes): 1511 raise TypeError("nonce must be bytes") 1512 1513 self._nonce = nonce 1514 1515 def __eq__(self, other): 1516 if not isinstance(other, OCSPNonce): 1517 return NotImplemented 1518 1519 return self.nonce == other.nonce 1520 1521 def __ne__(self, other): 1522 return not self == other 1523 1524 def __hash__(self): 1525 return hash(self.nonce) 1526 1527 def __repr__(self): 1528 return "<OCSPNonce(nonce={0.nonce!r})>".format(self) 1529 1530 nonce = utils.read_only_property("_nonce") 1531 1532 1533@utils.register_interface(ExtensionType) 1534class IssuingDistributionPoint(object): 1535 oid = ExtensionOID.ISSUING_DISTRIBUTION_POINT 1536 1537 def __init__( 1538 self, 1539 full_name, 1540 relative_name, 1541 only_contains_user_certs, 1542 only_contains_ca_certs, 1543 only_some_reasons, 1544 indirect_crl, 1545 only_contains_attribute_certs, 1546 ): 1547 if only_some_reasons and ( 1548 not isinstance(only_some_reasons, frozenset) 1549 or not all(isinstance(x, ReasonFlags) for x in only_some_reasons) 1550 ): 1551 raise TypeError( 1552 "only_some_reasons must be None or frozenset of ReasonFlags" 1553 ) 1554 1555 if only_some_reasons and ( 1556 ReasonFlags.unspecified in only_some_reasons 1557 or ReasonFlags.remove_from_crl in only_some_reasons 1558 ): 1559 raise ValueError( 1560 "unspecified and remove_from_crl are not valid reasons in an " 1561 "IssuingDistributionPoint" 1562 ) 1563 1564 if not ( 1565 isinstance(only_contains_user_certs, bool) 1566 and isinstance(only_contains_ca_certs, bool) 1567 and isinstance(indirect_crl, bool) 1568 and isinstance(only_contains_attribute_certs, bool) 1569 ): 1570 raise TypeError( 1571 "only_contains_user_certs, only_contains_ca_certs, " 1572 "indirect_crl and only_contains_attribute_certs " 1573 "must all be boolean." 1574 ) 1575 1576 crl_constraints = [ 1577 only_contains_user_certs, 1578 only_contains_ca_certs, 1579 indirect_crl, 1580 only_contains_attribute_certs, 1581 ] 1582 1583 if len([x for x in crl_constraints if x]) > 1: 1584 raise ValueError( 1585 "Only one of the following can be set to True: " 1586 "only_contains_user_certs, only_contains_ca_certs, " 1587 "indirect_crl, only_contains_attribute_certs" 1588 ) 1589 1590 if not any( 1591 [ 1592 only_contains_user_certs, 1593 only_contains_ca_certs, 1594 indirect_crl, 1595 only_contains_attribute_certs, 1596 full_name, 1597 relative_name, 1598 only_some_reasons, 1599 ] 1600 ): 1601 raise ValueError( 1602 "Cannot create empty extension: " 1603 "if only_contains_user_certs, only_contains_ca_certs, " 1604 "indirect_crl, and only_contains_attribute_certs are all False" 1605 ", then either full_name, relative_name, or only_some_reasons " 1606 "must have a value." 1607 ) 1608 1609 self._only_contains_user_certs = only_contains_user_certs 1610 self._only_contains_ca_certs = only_contains_ca_certs 1611 self._indirect_crl = indirect_crl 1612 self._only_contains_attribute_certs = only_contains_attribute_certs 1613 self._only_some_reasons = only_some_reasons 1614 self._full_name = full_name 1615 self._relative_name = relative_name 1616 1617 def __repr__(self): 1618 return ( 1619 "<IssuingDistributionPoint(full_name={0.full_name}, " 1620 "relative_name={0.relative_name}, " 1621 "only_contains_user_certs={0.only_contains_user_certs}, " 1622 "only_contains_ca_certs={0.only_contains_ca_certs}, " 1623 "only_some_reasons={0.only_some_reasons}, " 1624 "indirect_crl={0.indirect_crl}, " 1625 "only_contains_attribute_certs=" 1626 "{0.only_contains_attribute_certs})>".format(self) 1627 ) 1628 1629 def __eq__(self, other): 1630 if not isinstance(other, IssuingDistributionPoint): 1631 return NotImplemented 1632 1633 return ( 1634 self.full_name == other.full_name 1635 and self.relative_name == other.relative_name 1636 and self.only_contains_user_certs == other.only_contains_user_certs 1637 and self.only_contains_ca_certs == other.only_contains_ca_certs 1638 and self.only_some_reasons == other.only_some_reasons 1639 and self.indirect_crl == other.indirect_crl 1640 and self.only_contains_attribute_certs 1641 == other.only_contains_attribute_certs 1642 ) 1643 1644 def __ne__(self, other): 1645 return not self == other 1646 1647 def __hash__(self): 1648 return hash( 1649 ( 1650 self.full_name, 1651 self.relative_name, 1652 self.only_contains_user_certs, 1653 self.only_contains_ca_certs, 1654 self.only_some_reasons, 1655 self.indirect_crl, 1656 self.only_contains_attribute_certs, 1657 ) 1658 ) 1659 1660 full_name = utils.read_only_property("_full_name") 1661 relative_name = utils.read_only_property("_relative_name") 1662 only_contains_user_certs = utils.read_only_property( 1663 "_only_contains_user_certs" 1664 ) 1665 only_contains_ca_certs = utils.read_only_property( 1666 "_only_contains_ca_certs" 1667 ) 1668 only_some_reasons = utils.read_only_property("_only_some_reasons") 1669 indirect_crl = utils.read_only_property("_indirect_crl") 1670 only_contains_attribute_certs = utils.read_only_property( 1671 "_only_contains_attribute_certs" 1672 ) 1673 1674 1675@utils.register_interface(ExtensionType) 1676class UnrecognizedExtension(object): 1677 def __init__(self, oid, value): 1678 if not isinstance(oid, ObjectIdentifier): 1679 raise TypeError("oid must be an ObjectIdentifier") 1680 self._oid = oid 1681 self._value = value 1682 1683 oid = utils.read_only_property("_oid") 1684 value = utils.read_only_property("_value") 1685 1686 def __repr__(self): 1687 return ( 1688 "<UnrecognizedExtension(oid={0.oid}, " 1689 "value={0.value!r})>".format(self) 1690 ) 1691 1692 def __eq__(self, other): 1693 if not isinstance(other, UnrecognizedExtension): 1694 return NotImplemented 1695 1696 return self.oid == other.oid and self.value == other.value 1697 1698 def __ne__(self, other): 1699 return not self == other 1700 1701 def __hash__(self): 1702 return hash((self.oid, self.value)) 1703