Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/_serialization.py: 56%
79 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
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.
5import abc
6import typing
8from cryptography import utils
9from cryptography.hazmat.primitives.hashes import HashAlgorithm
11# This exists to break an import cycle. These classes are normally accessible
12# from the serialization module.
15class PBES(utils.Enum):
16 PBESv1SHA1And3KeyTripleDESCBC = "PBESv1 using SHA1 and 3-Key TripleDES"
17 PBESv2SHA256AndAES256CBC = "PBESv2 using SHA256 PBKDF2 and AES256 CBC"
20class Encoding(utils.Enum):
21 PEM = "PEM"
22 DER = "DER"
23 OpenSSH = "OpenSSH"
24 Raw = "Raw"
25 X962 = "ANSI X9.62"
26 SMIME = "S/MIME"
29class PrivateFormat(utils.Enum):
30 PKCS8 = "PKCS8"
31 TraditionalOpenSSL = "TraditionalOpenSSL"
32 Raw = "Raw"
33 OpenSSH = "OpenSSH"
34 PKCS12 = "PKCS12"
36 def encryption_builder(self) -> "KeySerializationEncryptionBuilder":
37 if self not in (PrivateFormat.OpenSSH, PrivateFormat.PKCS12):
38 raise ValueError(
39 "encryption_builder only supported with PrivateFormat.OpenSSH"
40 " and PrivateFormat.PKCS12"
41 )
42 return KeySerializationEncryptionBuilder(self)
45class PublicFormat(utils.Enum):
46 SubjectPublicKeyInfo = "X.509 subjectPublicKeyInfo with PKCS#1"
47 PKCS1 = "Raw PKCS#1"
48 OpenSSH = "OpenSSH"
49 Raw = "Raw"
50 CompressedPoint = "X9.62 Compressed Point"
51 UncompressedPoint = "X9.62 Uncompressed Point"
54class ParameterFormat(utils.Enum):
55 PKCS3 = "PKCS3"
58class KeySerializationEncryption(metaclass=abc.ABCMeta):
59 pass
62class BestAvailableEncryption(KeySerializationEncryption):
63 def __init__(self, password: bytes):
64 if not isinstance(password, bytes) or len(password) == 0:
65 raise ValueError("Password must be 1 or more bytes.")
67 self.password = password
70class NoEncryption(KeySerializationEncryption):
71 pass
74class KeySerializationEncryptionBuilder(object):
75 def __init__(
76 self,
77 format: PrivateFormat,
78 *,
79 _kdf_rounds: typing.Optional[int] = None,
80 _hmac_hash: typing.Optional[HashAlgorithm] = None,
81 _key_cert_algorithm: typing.Optional[PBES] = None,
82 ) -> None:
83 self._format = format
85 self._kdf_rounds = _kdf_rounds
86 self._hmac_hash = _hmac_hash
87 self._key_cert_algorithm = _key_cert_algorithm
89 def kdf_rounds(self, rounds: int) -> "KeySerializationEncryptionBuilder":
90 if self._kdf_rounds is not None:
91 raise ValueError("kdf_rounds already set")
93 if not isinstance(rounds, int):
94 raise TypeError("kdf_rounds must be an integer")
96 if rounds < 1:
97 raise ValueError("kdf_rounds must be a positive integer")
99 return KeySerializationEncryptionBuilder(
100 self._format,
101 _kdf_rounds=rounds,
102 _hmac_hash=self._hmac_hash,
103 _key_cert_algorithm=self._key_cert_algorithm,
104 )
106 def hmac_hash(
107 self, algorithm: HashAlgorithm
108 ) -> "KeySerializationEncryptionBuilder":
109 if self._format is not PrivateFormat.PKCS12:
110 raise TypeError(
111 "hmac_hash only supported with PrivateFormat.PKCS12"
112 )
114 if self._hmac_hash is not None:
115 raise ValueError("hmac_hash already set")
116 return KeySerializationEncryptionBuilder(
117 self._format,
118 _kdf_rounds=self._kdf_rounds,
119 _hmac_hash=algorithm,
120 _key_cert_algorithm=self._key_cert_algorithm,
121 )
123 def key_cert_algorithm(
124 self, algorithm: PBES
125 ) -> "KeySerializationEncryptionBuilder":
126 if self._format is not PrivateFormat.PKCS12:
127 raise TypeError(
128 "key_cert_algorithm only supported with "
129 "PrivateFormat.PKCS12"
130 )
131 if self._key_cert_algorithm is not None:
132 raise ValueError("key_cert_algorithm already set")
133 return KeySerializationEncryptionBuilder(
134 self._format,
135 _kdf_rounds=self._kdf_rounds,
136 _hmac_hash=self._hmac_hash,
137 _key_cert_algorithm=algorithm,
138 )
140 def build(self, password: bytes) -> KeySerializationEncryption:
141 if not isinstance(password, bytes) or len(password) == 0:
142 raise ValueError("Password must be 1 or more bytes.")
144 return _KeySerializationEncryption(
145 self._format,
146 password,
147 kdf_rounds=self._kdf_rounds,
148 hmac_hash=self._hmac_hash,
149 key_cert_algorithm=self._key_cert_algorithm,
150 )
153class _KeySerializationEncryption(KeySerializationEncryption):
154 def __init__(
155 self,
156 format: PrivateFormat,
157 password: bytes,
158 *,
159 kdf_rounds: typing.Optional[int],
160 hmac_hash: typing.Optional[HashAlgorithm],
161 key_cert_algorithm: typing.Optional[PBES],
162 ):
163 self._format = format
164 self.password = password
166 self._kdf_rounds = kdf_rounds
167 self._hmac_hash = hmac_hash
168 self._key_cert_algorithm = key_cert_algorithm