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.2.2, created at 2023-03-26 06:36 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +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 ed448,
14 ed25519,
15 rsa,
16)
17from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
19__all__ = [
20 "PBES",
21 "PKCS12PrivateKeyTypes",
22 "PKCS12Certificate",
23 "PKCS12KeyAndCertificates",
24 "load_key_and_certificates",
25 "load_pkcs12",
26 "serialize_key_and_certificates",
27]
29PKCS12PrivateKeyTypes = typing.Union[
30 rsa.RSAPrivateKey,
31 dsa.DSAPrivateKey,
32 ec.EllipticCurvePrivateKey,
33 ed25519.Ed25519PrivateKey,
34 ed448.Ed448PrivateKey,
35]
38class PKCS12Certificate:
39 def __init__(
40 self,
41 cert: x509.Certificate,
42 friendly_name: typing.Optional[bytes],
43 ):
44 if not isinstance(cert, x509.Certificate):
45 raise TypeError("Expecting x509.Certificate object")
46 if friendly_name is not None and not isinstance(friendly_name, bytes):
47 raise TypeError("friendly_name must be bytes or None")
48 self._cert = cert
49 self._friendly_name = friendly_name
51 @property
52 def friendly_name(self) -> typing.Optional[bytes]:
53 return self._friendly_name
55 @property
56 def certificate(self) -> x509.Certificate:
57 return self._cert
59 def __eq__(self, other: object) -> bool:
60 if not isinstance(other, PKCS12Certificate):
61 return NotImplemented
63 return (
64 self.certificate == other.certificate
65 and self.friendly_name == other.friendly_name
66 )
68 def __hash__(self) -> int:
69 return hash((self.certificate, self.friendly_name))
71 def __repr__(self) -> str:
72 return "<PKCS12Certificate({}, friendly_name={!r})>".format(
73 self.certificate, self.friendly_name
74 )
77class PKCS12KeyAndCertificates:
78 def __init__(
79 self,
80 key: typing.Optional[PrivateKeyTypes],
81 cert: typing.Optional[PKCS12Certificate],
82 additional_certs: typing.List[PKCS12Certificate],
83 ):
84 if key is not None and not isinstance(
85 key,
86 (
87 rsa.RSAPrivateKey,
88 dsa.DSAPrivateKey,
89 ec.EllipticCurvePrivateKey,
90 ed25519.Ed25519PrivateKey,
91 ed448.Ed448PrivateKey,
92 ),
93 ):
94 raise TypeError(
95 "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
96 " private key, or None."
97 )
98 if cert is not None and not isinstance(cert, PKCS12Certificate):
99 raise TypeError("cert must be a PKCS12Certificate object or None")
100 if not all(
101 isinstance(add_cert, PKCS12Certificate)
102 for add_cert in additional_certs
103 ):
104 raise TypeError(
105 "all values in additional_certs must be PKCS12Certificate"
106 " objects"
107 )
108 self._key = key
109 self._cert = cert
110 self._additional_certs = additional_certs
112 @property
113 def key(self) -> typing.Optional[PrivateKeyTypes]:
114 return self._key
116 @property
117 def cert(self) -> typing.Optional[PKCS12Certificate]:
118 return self._cert
120 @property
121 def additional_certs(self) -> typing.List[PKCS12Certificate]:
122 return self._additional_certs
124 def __eq__(self, other: object) -> bool:
125 if not isinstance(other, PKCS12KeyAndCertificates):
126 return NotImplemented
128 return (
129 self.key == other.key
130 and self.cert == other.cert
131 and self.additional_certs == other.additional_certs
132 )
134 def __hash__(self) -> int:
135 return hash((self.key, self.cert, tuple(self.additional_certs)))
137 def __repr__(self) -> str:
138 fmt = (
139 "<PKCS12KeyAndCertificates(key={}, cert={}, additional_certs={})>"
140 )
141 return fmt.format(self.key, self.cert, self.additional_certs)
144def load_key_and_certificates(
145 data: bytes,
146 password: typing.Optional[bytes],
147 backend: typing.Any = None,
148) -> typing.Tuple[
149 typing.Optional[PrivateKeyTypes],
150 typing.Optional[x509.Certificate],
151 typing.List[x509.Certificate],
152]:
153 from cryptography.hazmat.backends.openssl.backend import backend as ossl
155 return ossl.load_key_and_certificates_from_pkcs12(data, password)
158def load_pkcs12(
159 data: bytes,
160 password: typing.Optional[bytes],
161 backend: typing.Any = None,
162) -> PKCS12KeyAndCertificates:
163 from cryptography.hazmat.backends.openssl.backend import backend as ossl
165 return ossl.load_pkcs12(data, password)
168_PKCS12CATypes = typing.Union[
169 x509.Certificate,
170 PKCS12Certificate,
171]
174def serialize_key_and_certificates(
175 name: typing.Optional[bytes],
176 key: typing.Optional[PKCS12PrivateKeyTypes],
177 cert: typing.Optional[x509.Certificate],
178 cas: typing.Optional[typing.Iterable[_PKCS12CATypes]],
179 encryption_algorithm: serialization.KeySerializationEncryption,
180) -> bytes:
181 if key is not None and not isinstance(
182 key,
183 (
184 rsa.RSAPrivateKey,
185 dsa.DSAPrivateKey,
186 ec.EllipticCurvePrivateKey,
187 ed25519.Ed25519PrivateKey,
188 ed448.Ed448PrivateKey,
189 ),
190 ):
191 raise TypeError(
192 "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448"
193 " private key, or None."
194 )
195 if cert is not None and not isinstance(cert, x509.Certificate):
196 raise TypeError("cert must be a certificate or None")
198 if cas is not None:
199 cas = list(cas)
200 if not all(
201 isinstance(
202 val,
203 (
204 x509.Certificate,
205 PKCS12Certificate,
206 ),
207 )
208 for val in cas
209 ):
210 raise TypeError("all values in cas must be certificates")
212 if not isinstance(
213 encryption_algorithm, serialization.KeySerializationEncryption
214 ):
215 raise TypeError(
216 "Key encryption algorithm must be a "
217 "KeySerializationEncryption instance"
218 )
220 if key is None and cert is None and not cas:
221 raise ValueError("You must supply at least one of key, cert, or cas")
223 from cryptography.hazmat.backends.openssl.backend import backend
225 return backend.serialize_key_and_certificates_to_pkcs12(
226 name, key, cert, cas, encryption_algorithm
227 )