base.py 28 KB

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