base.py 33 KB

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