pkcs12.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. from __future__ import annotations
  5. import typing
  6. from cryptography import x509
  7. from cryptography.hazmat.bindings._rust import pkcs12 as rust_pkcs12
  8. from cryptography.hazmat.primitives import serialization
  9. from cryptography.hazmat.primitives._serialization import PBES as PBES
  10. from cryptography.hazmat.primitives.asymmetric import (
  11. dsa,
  12. ec,
  13. ed448,
  14. ed25519,
  15. rsa,
  16. )
  17. from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
  18. __all__ = [
  19. "PBES",
  20. "PKCS12Certificate",
  21. "PKCS12KeyAndCertificates",
  22. "PKCS12PrivateKeyTypes",
  23. "load_key_and_certificates",
  24. "load_pkcs12",
  25. "serialize_key_and_certificates",
  26. ]
  27. PKCS12PrivateKeyTypes = typing.Union[
  28. rsa.RSAPrivateKey,
  29. dsa.DSAPrivateKey,
  30. ec.EllipticCurvePrivateKey,
  31. ed25519.Ed25519PrivateKey,
  32. ed448.Ed448PrivateKey,
  33. ]
  34. PKCS12Certificate = rust_pkcs12.PKCS12Certificate
  35. class PKCS12KeyAndCertificates:
  36. def __init__(
  37. self,
  38. key: PrivateKeyTypes | None,
  39. cert: PKCS12Certificate | None,
  40. additional_certs: list[PKCS12Certificate],
  41. ):
  42. if key is not None and not isinstance(
  43. key,
  44. (
  45. rsa.RSAPrivateKey,
  46. dsa.DSAPrivateKey,
  47. ec.EllipticCurvePrivateKey,
  48. ed25519.Ed25519PrivateKey,
  49. ed448.Ed448PrivateKey,
  50. ),
  51. ):
  52. raise TypeError(
  53. "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
  54. " private key, or None."
  55. )
  56. if cert is not None and not isinstance(cert, PKCS12Certificate):
  57. raise TypeError("cert must be a PKCS12Certificate object or None")
  58. if not all(
  59. isinstance(add_cert, PKCS12Certificate)
  60. for add_cert in additional_certs
  61. ):
  62. raise TypeError(
  63. "all values in additional_certs must be PKCS12Certificate"
  64. " objects"
  65. )
  66. self._key = key
  67. self._cert = cert
  68. self._additional_certs = additional_certs
  69. @property
  70. def key(self) -> PrivateKeyTypes | None:
  71. return self._key
  72. @property
  73. def cert(self) -> PKCS12Certificate | None:
  74. return self._cert
  75. @property
  76. def additional_certs(self) -> list[PKCS12Certificate]:
  77. return self._additional_certs
  78. def __eq__(self, other: object) -> bool:
  79. if not isinstance(other, PKCS12KeyAndCertificates):
  80. return NotImplemented
  81. return (
  82. self.key == other.key
  83. and self.cert == other.cert
  84. and self.additional_certs == other.additional_certs
  85. )
  86. def __hash__(self) -> int:
  87. return hash((self.key, self.cert, tuple(self.additional_certs)))
  88. def __repr__(self) -> str:
  89. fmt = (
  90. "<PKCS12KeyAndCertificates(key={}, cert={}, additional_certs={})>"
  91. )
  92. return fmt.format(self.key, self.cert, self.additional_certs)
  93. load_key_and_certificates = rust_pkcs12.load_key_and_certificates
  94. load_pkcs12 = rust_pkcs12.load_pkcs12
  95. _PKCS12CATypes = typing.Union[
  96. x509.Certificate,
  97. PKCS12Certificate,
  98. ]
  99. def serialize_key_and_certificates(
  100. name: bytes | None,
  101. key: PKCS12PrivateKeyTypes | None,
  102. cert: x509.Certificate | None,
  103. cas: typing.Iterable[_PKCS12CATypes] | None,
  104. encryption_algorithm: serialization.KeySerializationEncryption,
  105. ) -> bytes:
  106. if key is not None and not isinstance(
  107. key,
  108. (
  109. rsa.RSAPrivateKey,
  110. dsa.DSAPrivateKey,
  111. ec.EllipticCurvePrivateKey,
  112. ed25519.Ed25519PrivateKey,
  113. ed448.Ed448PrivateKey,
  114. ),
  115. ):
  116. raise TypeError(
  117. "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
  118. " private key, or None."
  119. )
  120. if not isinstance(
  121. encryption_algorithm, serialization.KeySerializationEncryption
  122. ):
  123. raise TypeError(
  124. "Key encryption algorithm must be a "
  125. "KeySerializationEncryption instance"
  126. )
  127. if key is None and cert is None and not cas:
  128. raise ValueError("You must supply at least one of key, cert, or cas")
  129. return rust_pkcs12.serialize_key_and_certificates(
  130. name, key, cert, cas, encryption_algorithm
  131. )