_serialization.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 abc
  6. from cryptography import utils
  7. from cryptography.hazmat.bindings._rust import Encoding as Encoding
  8. from cryptography.hazmat.bindings._rust import (
  9. ParameterFormat as ParameterFormat,
  10. )
  11. from cryptography.hazmat.bindings._rust import PrivateFormat as PrivateFormat
  12. from cryptography.hazmat.bindings._rust import PublicFormat as PublicFormat
  13. from cryptography.hazmat.primitives.hashes import HashAlgorithm
  14. # This exists to break an import cycle. These classes are normally accessible
  15. # from the serialization module.
  16. class PBES(utils.Enum):
  17. PBESv1SHA1And3KeyTripleDESCBC = "PBESv1 using SHA1 and 3-Key TripleDES"
  18. PBESv2SHA256AndAES256CBC = "PBESv2 using SHA256 PBKDF2 and AES256 CBC"
  19. class KeySerializationEncryption(metaclass=abc.ABCMeta):
  20. pass
  21. class BestAvailableEncryption(KeySerializationEncryption):
  22. def __init__(self, password: bytes):
  23. if not isinstance(password, bytes) or len(password) == 0:
  24. raise ValueError("Password must be 1 or more bytes.")
  25. self.password = password
  26. class NoEncryption(KeySerializationEncryption):
  27. pass
  28. class KeySerializationEncryptionBuilder:
  29. def __init__(
  30. self,
  31. format: PrivateFormat,
  32. *,
  33. _kdf_rounds: int | None = None,
  34. _hmac_hash: HashAlgorithm | None = None,
  35. _key_cert_algorithm: PBES | None = None,
  36. ) -> None:
  37. self._format = format
  38. self._kdf_rounds = _kdf_rounds
  39. self._hmac_hash = _hmac_hash
  40. self._key_cert_algorithm = _key_cert_algorithm
  41. def kdf_rounds(self, rounds: int) -> KeySerializationEncryptionBuilder:
  42. if self._kdf_rounds is not None:
  43. raise ValueError("kdf_rounds already set")
  44. if not isinstance(rounds, int):
  45. raise TypeError("kdf_rounds must be an integer")
  46. if rounds < 1:
  47. raise ValueError("kdf_rounds must be a positive integer")
  48. return KeySerializationEncryptionBuilder(
  49. self._format,
  50. _kdf_rounds=rounds,
  51. _hmac_hash=self._hmac_hash,
  52. _key_cert_algorithm=self._key_cert_algorithm,
  53. )
  54. def hmac_hash(
  55. self, algorithm: HashAlgorithm
  56. ) -> KeySerializationEncryptionBuilder:
  57. if self._format is not PrivateFormat.PKCS12:
  58. raise TypeError(
  59. "hmac_hash only supported with PrivateFormat.PKCS12"
  60. )
  61. if self._hmac_hash is not None:
  62. raise ValueError("hmac_hash already set")
  63. return KeySerializationEncryptionBuilder(
  64. self._format,
  65. _kdf_rounds=self._kdf_rounds,
  66. _hmac_hash=algorithm,
  67. _key_cert_algorithm=self._key_cert_algorithm,
  68. )
  69. def key_cert_algorithm(
  70. self, algorithm: PBES
  71. ) -> KeySerializationEncryptionBuilder:
  72. if self._format is not PrivateFormat.PKCS12:
  73. raise TypeError(
  74. "key_cert_algorithm only supported with PrivateFormat.PKCS12"
  75. )
  76. if self._key_cert_algorithm is not None:
  77. raise ValueError("key_cert_algorithm already set")
  78. return KeySerializationEncryptionBuilder(
  79. self._format,
  80. _kdf_rounds=self._kdf_rounds,
  81. _hmac_hash=self._hmac_hash,
  82. _key_cert_algorithm=algorithm,
  83. )
  84. def build(self, password: bytes) -> KeySerializationEncryption:
  85. if not isinstance(password, bytes) or len(password) == 0:
  86. raise ValueError("Password must be 1 or more bytes.")
  87. return _KeySerializationEncryption(
  88. self._format,
  89. password,
  90. kdf_rounds=self._kdf_rounds,
  91. hmac_hash=self._hmac_hash,
  92. key_cert_algorithm=self._key_cert_algorithm,
  93. )
  94. class _KeySerializationEncryption(KeySerializationEncryption):
  95. def __init__(
  96. self,
  97. format: PrivateFormat,
  98. password: bytes,
  99. *,
  100. kdf_rounds: int | None,
  101. hmac_hash: HashAlgorithm | None,
  102. key_cert_algorithm: PBES | None,
  103. ):
  104. self._format = format
  105. self.password = password
  106. self._kdf_rounds = kdf_rounds
  107. self._hmac_hash = hmac_hash
  108. self._key_cert_algorithm = key_cert_algorithm