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 os 10from enum import Enum 11 12import six 13 14from cryptography import utils 15from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa 16from cryptography.x509.extensions import Extension, ExtensionType 17from cryptography.x509.name import Name 18 19 20_EARLIEST_UTC_TIME = datetime.datetime(1950, 1, 1) 21 22 23def _reject_duplicate_extension(extension, extensions): 24 # This is quadratic in the number of extensions 25 for e in extensions: 26 if e.oid == extension.oid: 27 raise ValueError('This extension has already been set.') 28 29 30def _convert_to_naive_utc_time(time): 31 """Normalizes a datetime to a naive datetime in UTC. 32 33 time -- datetime to normalize. Assumed to be in UTC if not timezone 34 aware. 35 """ 36 if time.tzinfo is not None: 37 offset = time.utcoffset() 38 offset = offset if offset else datetime.timedelta() 39 return time.replace(tzinfo=None) - offset 40 else: 41 return time 42 43 44class Version(Enum): 45 v1 = 0 46 v3 = 2 47 48 49def load_pem_x509_certificate(data, backend): 50 return backend.load_pem_x509_certificate(data) 51 52 53def load_der_x509_certificate(data, backend): 54 return backend.load_der_x509_certificate(data) 55 56 57def load_pem_x509_csr(data, backend): 58 return backend.load_pem_x509_csr(data) 59 60 61def load_der_x509_csr(data, backend): 62 return backend.load_der_x509_csr(data) 63 64 65def load_pem_x509_crl(data, backend): 66 return backend.load_pem_x509_crl(data) 67 68 69def load_der_x509_crl(data, backend): 70 return backend.load_der_x509_crl(data) 71 72 73class InvalidVersion(Exception): 74 def __init__(self, msg, parsed_version): 75 super(InvalidVersion, self).__init__(msg) 76 self.parsed_version = parsed_version 77 78 79@six.add_metaclass(abc.ABCMeta) 80class Certificate(object): 81 @abc.abstractmethod 82 def fingerprint(self, algorithm): 83 """ 84 Returns bytes using digest passed. 85 """ 86 87 @abc.abstractproperty 88 def serial_number(self): 89 """ 90 Returns certificate serial number 91 """ 92 93 @abc.abstractproperty 94 def version(self): 95 """ 96 Returns the certificate version 97 """ 98 99 @abc.abstractmethod 100 def public_key(self): 101 """ 102 Returns the public key 103 """ 104 105 @abc.abstractproperty 106 def not_valid_before(self): 107 """ 108 Not before time (represented as UTC datetime) 109 """ 110 111 @abc.abstractproperty 112 def not_valid_after(self): 113 """ 114 Not after time (represented as UTC datetime) 115 """ 116 117 @abc.abstractproperty 118 def issuer(self): 119 """ 120 Returns the issuer name object. 121 """ 122 123 @abc.abstractproperty 124 def subject(self): 125 """ 126 Returns the subject name object. 127 """ 128 129 @abc.abstractproperty 130 def signature_hash_algorithm(self): 131 """ 132 Returns a HashAlgorithm corresponding to the type of the digest signed 133 in the certificate. 134 """ 135 136 @abc.abstractproperty 137 def signature_algorithm_oid(self): 138 """ 139 Returns the ObjectIdentifier of the signature algorithm. 140 """ 141 142 @abc.abstractproperty 143 def extensions(self): 144 """ 145 Returns an Extensions object. 146 """ 147 148 @abc.abstractproperty 149 def signature(self): 150 """ 151 Returns the signature bytes. 152 """ 153 154 @abc.abstractproperty 155 def tbs_certificate_bytes(self): 156 """ 157 Returns the tbsCertificate payload bytes as defined in RFC 5280. 158 """ 159 160 @abc.abstractmethod 161 def __eq__(self, other): 162 """ 163 Checks equality. 164 """ 165 166 @abc.abstractmethod 167 def __ne__(self, other): 168 """ 169 Checks not equal. 170 """ 171 172 @abc.abstractmethod 173 def __hash__(self): 174 """ 175 Computes a hash. 176 """ 177 178 @abc.abstractmethod 179 def public_bytes(self, encoding): 180 """ 181 Serializes the certificate to PEM or DER format. 182 """ 183 184 185@six.add_metaclass(abc.ABCMeta) 186class CertificateRevocationList(object): 187 @abc.abstractmethod 188 def public_bytes(self, encoding): 189 """ 190 Serializes the CRL to PEM or DER format. 191 """ 192 193 @abc.abstractmethod 194 def fingerprint(self, algorithm): 195 """ 196 Returns bytes using digest passed. 197 """ 198 199 @abc.abstractmethod 200 def get_revoked_certificate_by_serial_number(self, serial_number): 201 """ 202 Returns an instance of RevokedCertificate or None if the serial_number 203 is not in the CRL. 204 """ 205 206 @abc.abstractproperty 207 def signature_hash_algorithm(self): 208 """ 209 Returns a HashAlgorithm corresponding to the type of the digest signed 210 in the certificate. 211 """ 212 213 @abc.abstractproperty 214 def signature_algorithm_oid(self): 215 """ 216 Returns the ObjectIdentifier of the signature algorithm. 217 """ 218 219 @abc.abstractproperty 220 def issuer(self): 221 """ 222 Returns the X509Name with the issuer of this CRL. 223 """ 224 225 @abc.abstractproperty 226 def next_update(self): 227 """ 228 Returns the date of next update for this CRL. 229 """ 230 231 @abc.abstractproperty 232 def last_update(self): 233 """ 234 Returns the date of last update for this CRL. 235 """ 236 237 @abc.abstractproperty 238 def extensions(self): 239 """ 240 Returns an Extensions object containing a list of CRL extensions. 241 """ 242 243 @abc.abstractproperty 244 def signature(self): 245 """ 246 Returns the signature bytes. 247 """ 248 249 @abc.abstractproperty 250 def tbs_certlist_bytes(self): 251 """ 252 Returns the tbsCertList payload bytes as defined in RFC 5280. 253 """ 254 255 @abc.abstractmethod 256 def __eq__(self, other): 257 """ 258 Checks equality. 259 """ 260 261 @abc.abstractmethod 262 def __ne__(self, other): 263 """ 264 Checks not equal. 265 """ 266 267 @abc.abstractmethod 268 def __len__(self): 269 """ 270 Number of revoked certificates in the CRL. 271 """ 272 273 @abc.abstractmethod 274 def __getitem__(self, idx): 275 """ 276 Returns a revoked certificate (or slice of revoked certificates). 277 """ 278 279 @abc.abstractmethod 280 def __iter__(self): 281 """ 282 Iterator over the revoked certificates 283 """ 284 285 @abc.abstractmethod 286 def is_signature_valid(self, public_key): 287 """ 288 Verifies signature of revocation list against given public key. 289 """ 290 291 292@six.add_metaclass(abc.ABCMeta) 293class CertificateSigningRequest(object): 294 @abc.abstractmethod 295 def __eq__(self, other): 296 """ 297 Checks equality. 298 """ 299 300 @abc.abstractmethod 301 def __ne__(self, other): 302 """ 303 Checks not equal. 304 """ 305 306 @abc.abstractmethod 307 def __hash__(self): 308 """ 309 Computes a hash. 310 """ 311 312 @abc.abstractmethod 313 def public_key(self): 314 """ 315 Returns the public key 316 """ 317 318 @abc.abstractproperty 319 def subject(self): 320 """ 321 Returns the subject name object. 322 """ 323 324 @abc.abstractproperty 325 def signature_hash_algorithm(self): 326 """ 327 Returns a HashAlgorithm corresponding to the type of the digest signed 328 in the certificate. 329 """ 330 331 @abc.abstractproperty 332 def signature_algorithm_oid(self): 333 """ 334 Returns the ObjectIdentifier of the signature algorithm. 335 """ 336 337 @abc.abstractproperty 338 def extensions(self): 339 """ 340 Returns the extensions in the signing request. 341 """ 342 343 @abc.abstractmethod 344 def public_bytes(self, encoding): 345 """ 346 Encodes the request to PEM or DER format. 347 """ 348 349 @abc.abstractproperty 350 def signature(self): 351 """ 352 Returns the signature bytes. 353 """ 354 355 @abc.abstractproperty 356 def tbs_certrequest_bytes(self): 357 """ 358 Returns the PKCS#10 CertificationRequestInfo bytes as defined in RFC 359 2986. 360 """ 361 362 @abc.abstractproperty 363 def is_signature_valid(self): 364 """ 365 Verifies signature of signing request. 366 """ 367 368 369@six.add_metaclass(abc.ABCMeta) 370class RevokedCertificate(object): 371 @abc.abstractproperty 372 def serial_number(self): 373 """ 374 Returns the serial number of the revoked certificate. 375 """ 376 377 @abc.abstractproperty 378 def revocation_date(self): 379 """ 380 Returns the date of when this certificate was revoked. 381 """ 382 383 @abc.abstractproperty 384 def extensions(self): 385 """ 386 Returns an Extensions object containing a list of Revoked extensions. 387 """ 388 389 390class CertificateSigningRequestBuilder(object): 391 def __init__(self, subject_name=None, extensions=[]): 392 """ 393 Creates an empty X.509 certificate request (v1). 394 """ 395 self._subject_name = subject_name 396 self._extensions = extensions 397 398 def subject_name(self, name): 399 """ 400 Sets the certificate requestor's distinguished name. 401 """ 402 if not isinstance(name, Name): 403 raise TypeError('Expecting x509.Name object.') 404 if self._subject_name is not None: 405 raise ValueError('The subject name may only be set once.') 406 return CertificateSigningRequestBuilder(name, self._extensions) 407 408 def add_extension(self, extension, critical): 409 """ 410 Adds an X.509 extension to the certificate request. 411 """ 412 if not isinstance(extension, ExtensionType): 413 raise TypeError("extension must be an ExtensionType") 414 415 extension = Extension(extension.oid, critical, extension) 416 _reject_duplicate_extension(extension, self._extensions) 417 418 return CertificateSigningRequestBuilder( 419 self._subject_name, self._extensions + [extension] 420 ) 421 422 def sign(self, private_key, algorithm, backend): 423 """ 424 Signs the request using the requestor's private key. 425 """ 426 if self._subject_name is None: 427 raise ValueError("A CertificateSigningRequest must have a subject") 428 return backend.create_x509_csr(self, private_key, algorithm) 429 430 431class CertificateBuilder(object): 432 def __init__(self, issuer_name=None, subject_name=None, 433 public_key=None, serial_number=None, not_valid_before=None, 434 not_valid_after=None, extensions=[]): 435 self._version = Version.v3 436 self._issuer_name = issuer_name 437 self._subject_name = subject_name 438 self._public_key = public_key 439 self._serial_number = serial_number 440 self._not_valid_before = not_valid_before 441 self._not_valid_after = not_valid_after 442 self._extensions = extensions 443 444 def issuer_name(self, name): 445 """ 446 Sets the CA's distinguished name. 447 """ 448 if not isinstance(name, Name): 449 raise TypeError('Expecting x509.Name object.') 450 if self._issuer_name is not None: 451 raise ValueError('The issuer name may only be set once.') 452 return CertificateBuilder( 453 name, self._subject_name, self._public_key, 454 self._serial_number, self._not_valid_before, 455 self._not_valid_after, self._extensions 456 ) 457 458 def subject_name(self, name): 459 """ 460 Sets the requestor's distinguished name. 461 """ 462 if not isinstance(name, Name): 463 raise TypeError('Expecting x509.Name object.') 464 if self._subject_name is not None: 465 raise ValueError('The subject name may only be set once.') 466 return CertificateBuilder( 467 self._issuer_name, name, self._public_key, 468 self._serial_number, self._not_valid_before, 469 self._not_valid_after, self._extensions 470 ) 471 472 def public_key(self, key): 473 """ 474 Sets the requestor's public key (as found in the signing request). 475 """ 476 if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey, 477 ec.EllipticCurvePublicKey)): 478 raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,' 479 ' or EllipticCurvePublicKey.') 480 if self._public_key is not None: 481 raise ValueError('The public key may only be set once.') 482 return CertificateBuilder( 483 self._issuer_name, self._subject_name, key, 484 self._serial_number, self._not_valid_before, 485 self._not_valid_after, self._extensions 486 ) 487 488 def serial_number(self, number): 489 """ 490 Sets the certificate serial number. 491 """ 492 if not isinstance(number, six.integer_types): 493 raise TypeError('Serial number must be of integral type.') 494 if self._serial_number is not None: 495 raise ValueError('The serial number may only be set once.') 496 if number <= 0: 497 raise ValueError('The serial number should be positive.') 498 499 # ASN.1 integers are always signed, so most significant bit must be 500 # zero. 501 if number.bit_length() >= 160: # As defined in RFC 5280 502 raise ValueError('The serial number should not be more than 159 ' 503 'bits.') 504 return CertificateBuilder( 505 self._issuer_name, self._subject_name, 506 self._public_key, number, self._not_valid_before, 507 self._not_valid_after, self._extensions 508 ) 509 510 def not_valid_before(self, time): 511 """ 512 Sets the certificate activation time. 513 """ 514 if not isinstance(time, datetime.datetime): 515 raise TypeError('Expecting datetime object.') 516 if self._not_valid_before is not None: 517 raise ValueError('The not valid before may only be set once.') 518 time = _convert_to_naive_utc_time(time) 519 if time < _EARLIEST_UTC_TIME: 520 raise ValueError('The not valid before date must be on or after' 521 ' 1950 January 1).') 522 if self._not_valid_after is not None and time > self._not_valid_after: 523 raise ValueError( 524 'The not valid before date must be before the not valid after ' 525 'date.' 526 ) 527 return CertificateBuilder( 528 self._issuer_name, self._subject_name, 529 self._public_key, self._serial_number, time, 530 self._not_valid_after, self._extensions 531 ) 532 533 def not_valid_after(self, time): 534 """ 535 Sets the certificate expiration time. 536 """ 537 if not isinstance(time, datetime.datetime): 538 raise TypeError('Expecting datetime object.') 539 if self._not_valid_after is not None: 540 raise ValueError('The not valid after may only be set once.') 541 time = _convert_to_naive_utc_time(time) 542 if time < _EARLIEST_UTC_TIME: 543 raise ValueError('The not valid after date must be on or after' 544 ' 1950 January 1.') 545 if (self._not_valid_before is not None and 546 time < self._not_valid_before): 547 raise ValueError( 548 'The not valid after date must be after the not valid before ' 549 'date.' 550 ) 551 return CertificateBuilder( 552 self._issuer_name, self._subject_name, 553 self._public_key, self._serial_number, self._not_valid_before, 554 time, self._extensions 555 ) 556 557 def add_extension(self, extension, critical): 558 """ 559 Adds an X.509 extension to the certificate. 560 """ 561 if not isinstance(extension, ExtensionType): 562 raise TypeError("extension must be an ExtensionType") 563 564 extension = Extension(extension.oid, critical, extension) 565 _reject_duplicate_extension(extension, self._extensions) 566 567 return CertificateBuilder( 568 self._issuer_name, self._subject_name, 569 self._public_key, self._serial_number, self._not_valid_before, 570 self._not_valid_after, self._extensions + [extension] 571 ) 572 573 def sign(self, private_key, algorithm, backend): 574 """ 575 Signs the certificate using the CA's private key. 576 """ 577 if self._subject_name is None: 578 raise ValueError("A certificate must have a subject name") 579 580 if self._issuer_name is None: 581 raise ValueError("A certificate must have an issuer name") 582 583 if self._serial_number is None: 584 raise ValueError("A certificate must have a serial number") 585 586 if self._not_valid_before is None: 587 raise ValueError("A certificate must have a not valid before time") 588 589 if self._not_valid_after is None: 590 raise ValueError("A certificate must have a not valid after time") 591 592 if self._public_key is None: 593 raise ValueError("A certificate must have a public key") 594 595 return backend.create_x509_certificate(self, private_key, algorithm) 596 597 598class CertificateRevocationListBuilder(object): 599 def __init__(self, issuer_name=None, last_update=None, next_update=None, 600 extensions=[], revoked_certificates=[]): 601 self._issuer_name = issuer_name 602 self._last_update = last_update 603 self._next_update = next_update 604 self._extensions = extensions 605 self._revoked_certificates = revoked_certificates 606 607 def issuer_name(self, issuer_name): 608 if not isinstance(issuer_name, Name): 609 raise TypeError('Expecting x509.Name object.') 610 if self._issuer_name is not None: 611 raise ValueError('The issuer name may only be set once.') 612 return CertificateRevocationListBuilder( 613 issuer_name, self._last_update, self._next_update, 614 self._extensions, self._revoked_certificates 615 ) 616 617 def last_update(self, last_update): 618 if not isinstance(last_update, datetime.datetime): 619 raise TypeError('Expecting datetime object.') 620 if self._last_update is not None: 621 raise ValueError('Last update may only be set once.') 622 last_update = _convert_to_naive_utc_time(last_update) 623 if last_update < _EARLIEST_UTC_TIME: 624 raise ValueError('The last update date must be on or after' 625 ' 1950 January 1.') 626 if self._next_update is not None and last_update > self._next_update: 627 raise ValueError( 628 'The last update date must be before the next update date.' 629 ) 630 return CertificateRevocationListBuilder( 631 self._issuer_name, last_update, self._next_update, 632 self._extensions, self._revoked_certificates 633 ) 634 635 def next_update(self, next_update): 636 if not isinstance(next_update, datetime.datetime): 637 raise TypeError('Expecting datetime object.') 638 if self._next_update is not None: 639 raise ValueError('Last update may only be set once.') 640 next_update = _convert_to_naive_utc_time(next_update) 641 if next_update < _EARLIEST_UTC_TIME: 642 raise ValueError('The last update date must be on or after' 643 ' 1950 January 1.') 644 if self._last_update is not None and next_update < self._last_update: 645 raise ValueError( 646 'The next update date must be after the last update date.' 647 ) 648 return CertificateRevocationListBuilder( 649 self._issuer_name, self._last_update, next_update, 650 self._extensions, self._revoked_certificates 651 ) 652 653 def add_extension(self, extension, critical): 654 """ 655 Adds an X.509 extension to the certificate revocation list. 656 """ 657 if not isinstance(extension, ExtensionType): 658 raise TypeError("extension must be an ExtensionType") 659 660 extension = Extension(extension.oid, critical, extension) 661 _reject_duplicate_extension(extension, self._extensions) 662 return CertificateRevocationListBuilder( 663 self._issuer_name, self._last_update, self._next_update, 664 self._extensions + [extension], self._revoked_certificates 665 ) 666 667 def add_revoked_certificate(self, revoked_certificate): 668 """ 669 Adds a revoked certificate to the CRL. 670 """ 671 if not isinstance(revoked_certificate, RevokedCertificate): 672 raise TypeError("Must be an instance of RevokedCertificate") 673 674 return CertificateRevocationListBuilder( 675 self._issuer_name, self._last_update, 676 self._next_update, self._extensions, 677 self._revoked_certificates + [revoked_certificate] 678 ) 679 680 def sign(self, private_key, algorithm, backend): 681 if self._issuer_name is None: 682 raise ValueError("A CRL must have an issuer name") 683 684 if self._last_update is None: 685 raise ValueError("A CRL must have a last update time") 686 687 if self._next_update is None: 688 raise ValueError("A CRL must have a next update time") 689 690 return backend.create_x509_crl(self, private_key, algorithm) 691 692 693class RevokedCertificateBuilder(object): 694 def __init__(self, serial_number=None, revocation_date=None, 695 extensions=[]): 696 self._serial_number = serial_number 697 self._revocation_date = revocation_date 698 self._extensions = extensions 699 700 def serial_number(self, number): 701 if not isinstance(number, six.integer_types): 702 raise TypeError('Serial number must be of integral type.') 703 if self._serial_number is not None: 704 raise ValueError('The serial number may only be set once.') 705 if number <= 0: 706 raise ValueError('The serial number should be positive') 707 708 # ASN.1 integers are always signed, so most significant bit must be 709 # zero. 710 if number.bit_length() >= 160: # As defined in RFC 5280 711 raise ValueError('The serial number should not be more than 159 ' 712 'bits.') 713 return RevokedCertificateBuilder( 714 number, self._revocation_date, self._extensions 715 ) 716 717 def revocation_date(self, time): 718 if not isinstance(time, datetime.datetime): 719 raise TypeError('Expecting datetime object.') 720 if self._revocation_date is not None: 721 raise ValueError('The revocation date may only be set once.') 722 time = _convert_to_naive_utc_time(time) 723 if time < _EARLIEST_UTC_TIME: 724 raise ValueError('The revocation date must be on or after' 725 ' 1950 January 1.') 726 return RevokedCertificateBuilder( 727 self._serial_number, time, self._extensions 728 ) 729 730 def add_extension(self, extension, critical): 731 if not isinstance(extension, ExtensionType): 732 raise TypeError("extension must be an ExtensionType") 733 734 extension = Extension(extension.oid, critical, extension) 735 _reject_duplicate_extension(extension, self._extensions) 736 return RevokedCertificateBuilder( 737 self._serial_number, self._revocation_date, 738 self._extensions + [extension] 739 ) 740 741 def build(self, backend): 742 if self._serial_number is None: 743 raise ValueError("A revoked certificate must have a serial number") 744 if self._revocation_date is None: 745 raise ValueError( 746 "A revoked certificate must have a revocation date" 747 ) 748 749 return backend.create_x509_revoked_certificate(self) 750 751 752def random_serial_number(): 753 return utils.int_from_bytes(os.urandom(20), "big") >> 1 754