Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py: 40%
81 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 typing
7from cryptography import x509
8from cryptography.hazmat.primitives import serialization
9from cryptography.hazmat.primitives._serialization import PBES as PBES
10from cryptography.hazmat.primitives.asymmetric import (
11 dsa,
12 ec,
13 ed25519,
14 ed448,
15 rsa,
16)
17from cryptography.hazmat.primitives.asymmetric.types import (
18 PRIVATE_KEY_TYPES,
19)
21__all__ = [
22 "PBES",
23 "PKCS12Certificate",
24 "PKCS12KeyAndCertificates",
25 "load_key_and_certificates",
26 "load_pkcs12",
27 "serialize_key_and_certificates",
28]
30_ALLOWED_PKCS12_TYPES = typing.Union[
31 rsa.RSAPrivateKey,
32 dsa.DSAPrivateKey,
33 ec.EllipticCurvePrivateKey,
34 ed25519.Ed25519PrivateKey,
35 ed448.Ed448PrivateKey,
36]
39class PKCS12Certificate:
40 def __init__(
41 self,
42 cert: x509.Certificate,
43 friendly_name: typing.Optional[bytes],
44 ):
45 if not isinstance(cert, x509.Certificate):
46 raise TypeError("Expecting x509.Certificate object")
47 if friendly_name is not None and not isinstance(friendly_name, bytes):
48 raise TypeError("friendly_name must be bytes or None")
49 self._cert = cert
50 self._friendly_name = friendly_name
52 @property
53 def friendly_name(self) -> typing.Optional[bytes]:
54 return self._friendly_name
56 @property
57 def certificate(self) -> x509.Certificate:
58 return self._cert
60 def __eq__(self, other: object) -> bool:
61 if not isinstance(other, PKCS12Certificate):
62 return NotImplemented
64 return (
65 self.certificate == other.certificate
66 and self.friendly_name == other.friendly_name
67 )
69 def __hash__(self) -> int:
70 return hash((self.certificate, self.friendly_name))
72 def __repr__(self) -> str:
73 return "<PKCS12Certificate({}, friendly_name={!r})>".format(
74 self.certificate, self.friendly_name
75 )
78class PKCS12KeyAndCertificates:
79 def __init__(
80 self,
81 key: typing.Optional[PRIVATE_KEY_TYPES],
82 cert: typing.Optional[PKCS12Certificate],
83 additional_certs: typing.List[PKCS12Certificate],
84 ):
85 if key is not None and not isinstance(
86 key,
87 (
88 rsa.RSAPrivateKey,
89 dsa.DSAPrivateKey,
90 ec.EllipticCurvePrivateKey,
91 ed25519.Ed25519PrivateKey,
92 ed448.Ed448PrivateKey,
93 ),
94 ):
95 raise TypeError(
96 "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
97 " private key, or None."
98 )
99 if cert is not None and not isinstance(cert, PKCS12Certificate):
100 raise TypeError("cert must be a PKCS12Certificate object or None")
101 if not all(
102 isinstance(add_cert, PKCS12Certificate)
103 for add_cert in additional_certs
104 ):
105 raise TypeError(
106 "all values in additional_certs must be PKCS12Certificate"
107 " objects"
108 )
109 self._key = key
110 self._cert = cert
111 self._additional_certs = additional_certs
113 @property
114 def key(self) -> typing.Optional[PRIVATE_KEY_TYPES]:
115 return self._key
117 @property
118 def cert(self) -> typing.Optional[PKCS12Certificate]:
119 return self._cert
121 @property
122 def additional_certs(self) -> typing.List[PKCS12Certificate]:
123 return self._additional_certs
125 def __eq__(self, other: object) -> bool:
126 if not isinstance(other, PKCS12KeyAndCertificates):
127 return NotImplemented
129 return (
130 self.key == other.key
131 and self.cert == other.cert
132 and self.additional_certs == other.additional_certs
133 )
135 def __hash__(self) -> int:
136 return hash((self.key, self.cert, tuple(self.additional_certs)))
138 def __repr__(self) -> str:
139 fmt = (
140 "<PKCS12KeyAndCertificates(key={}, cert={}, additional_certs={})>"
141 )
142 return fmt.format(self.key, self.cert, self.additional_certs)
145def load_key_and_certificates(
146 data: bytes,
147 password: typing.Optional[bytes],
148 backend: typing.Any = None,
149) -> typing.Tuple[
150 typing.Optional[PRIVATE_KEY_TYPES],
151 typing.Optional[x509.Certificate],
152 typing.List[x509.Certificate],
153]:
154 from cryptography.hazmat.backends.openssl.backend import backend as ossl
156 return ossl.load_key_and_certificates_from_pkcs12(data, password)
159def load_pkcs12(
160 data: bytes,
161 password: typing.Optional[bytes],
162 backend: typing.Any = None,
163) -> PKCS12KeyAndCertificates:
164 from cryptography.hazmat.backends.openssl.backend import backend as ossl
166 return ossl.load_pkcs12(data, password)
169_PKCS12_CAS_TYPES = typing.Union[
170 x509.Certificate,
171 PKCS12Certificate,
172]
175def serialize_key_and_certificates(
176 name: typing.Optional[bytes],
177 key: typing.Optional[_ALLOWED_PKCS12_TYPES],
178 cert: typing.Optional[x509.Certificate],
179 cas: typing.Optional[typing.Iterable[_PKCS12_CAS_TYPES]],
180 encryption_algorithm: serialization.KeySerializationEncryption,
181) -> bytes:
182 if key is not None and not isinstance(
183 key,
184 (
185 rsa.RSAPrivateKey,
186 dsa.DSAPrivateKey,
187 ec.EllipticCurvePrivateKey,
188 ed25519.Ed25519PrivateKey,
189 ed448.Ed448PrivateKey,
190 ),
191 ):
192 raise TypeError(
193 "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
194 " private key, or None."
195 )
196 if cert is not None and not isinstance(cert, x509.Certificate):
197 raise TypeError("cert must be a certificate or None")
199 if cas is not None:
200 cas = list(cas)
201 if not all(
202 isinstance(
203 val,
204 (
205 x509.Certificate,
206 PKCS12Certificate,
207 ),
208 )
209 for val in cas
210 ):
211 raise TypeError("all values in cas must be certificates")
213 if not isinstance(
214 encryption_algorithm, serialization.KeySerializationEncryption
215 ):
216 raise TypeError(
217 "Key encryption algorithm must be a "
218 "KeySerializationEncryption instance"
219 )
221 if key is None and cert is None and not cas:
222 raise ValueError("You must supply at least one of key, cert, or cas")
224 from cryptography.hazmat.backends.openssl.backend import backend
226 return backend.serialize_key_and_certificates_to_pkcs12(
227 name, key, cert, cas, encryption_algorithm
228 )