Skip to content

Commit ef87bc7

Browse files
committed
Added a convertor for hazmat-imported keys (currently only openssl backend).
1 parent efaed04 commit ef87bc7

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

securesystemslib/convert/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

securesystemslib/convert/hazmat.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
"""
2+
This module contains functions to convert `cryptography.hazmat` keys into `securesystemlib` key dicts.
3+
"""
4+
5+
6+
import typing
7+
8+
from cryptography.hazmat.backends.openssl.ec import (
9+
_EllipticCurvePrivateKey,
10+
_EllipticCurvePublicKey,
11+
)
12+
from cryptography.hazmat.backends.openssl.ed25519 import (
13+
_Ed25519PrivateKey,
14+
_Ed25519PublicKey,
15+
)
16+
from cryptography.hazmat.backends.openssl.rsa import (
17+
_RSAPrivateKey,
18+
_RSAPublicKey,
19+
)
20+
from cryptography.hazmat.primitives.serialization import (
21+
Encoding,
22+
NoEncryption,
23+
PrivateFormat,
24+
PublicFormat,
25+
)
26+
27+
from ..keys import (
28+
format_ed25519_dict,
29+
import_ecdsakey_from_pem,
30+
import_rsakey_from_pem,
31+
)
32+
33+
34+
def _hazmat_key_to_pem(
35+
key: typing.Union[
36+
_RSAPrivateKey,
37+
_EllipticCurvePrivateKey,
38+
]
39+
) -> str:
40+
"""The approach already used in this lib is to convert keys into PEM and then to parse from it."""
41+
42+
if key.__class__.__name__.endswith("PrivateKey"):
43+
serialized = key.private_bytes(
44+
Encoding.PEM,
45+
PrivateFormat.TraditionalOpenSSL,
46+
NoEncryption(),
47+
)
48+
elif key.__class__.__name__.endswith("PublicKey"):
49+
serialized = key.public_bytes(
50+
Encoding.PEM,
51+
PublicFormat.SubjectPublicKeyInfo,
52+
)
53+
else:
54+
raise TypeError(key)
55+
56+
return serialized.decode("utf-8")
57+
58+
59+
def _import_hazmat_ed25519_private_key(
60+
key: _Ed25519PrivateKey,
61+
) -> dict:
62+
"""Imports hazmat ed25519 private key"""
63+
64+
pub = key.public_key().public_bytes(
65+
Encoding.Raw,
66+
PublicFormat.Raw,
67+
)
68+
sec = key.private_bytes(
69+
Encoding.Raw,
70+
PrivateFormat.Raw,
71+
NoEncryption(),
72+
)
73+
return format_ed25519_dict(
74+
pub,
75+
sec,
76+
)
77+
78+
79+
def _import_hazmat_ed25519_public_key(
80+
key: _Ed25519PublicKey,
81+
) -> dict:
82+
"""Imports hazmat ed25519 public key"""
83+
84+
pub = key.public_bytes(
85+
Encoding.Raw,
86+
PublicFormat.Raw,
87+
)
88+
return format_ed25519_dict(
89+
pub,
90+
None,
91+
)
92+
93+
94+
def _import_rsa_key(
95+
key: _RSAPrivateKey,
96+
) -> dict:
97+
"""Imports hazmat RSA key"""
98+
99+
return import_rsakey_from_pem(_hazmat_key_to_pem(key))
100+
101+
102+
def _import_ecdsa_key(
103+
key: _EllipticCurvePrivateKey,
104+
) -> dict:
105+
"""Imports hazmat ECDSA key"""
106+
107+
return import_ecdsakey_from_pem(_hazmat_key_to_pem(key))
108+
109+
110+
_typeMapping = {
111+
_Ed25519PrivateKey: _import_hazmat_ed25519_private_key,
112+
_Ed25519PublicKey: _import_hazmat_ed25519_public_key,
113+
_RSAPrivateKey: _import_rsa_key,
114+
_RSAPublicKey: _import_rsa_key,
115+
_EllipticCurvePrivateKey: _import_ecdsa_key,
116+
_EllipticCurvePublicKey: _import_ecdsa_key,
117+
}
118+
119+
120+
def import_hazmat_key(
121+
key: typing.Union[
122+
_RSAPrivateKey, _EllipticCurvePrivateKey, _Ed25519PrivateKey
123+
]
124+
) -> dict:
125+
"""
126+
<Purpose>
127+
Converts a `cryptography.hazmat` key into a dictionary conformant to 'securesystemslib.formats.KEY_SCHEMA'.
128+
129+
<Arguments>
130+
key:
131+
A key of the classes from `cryptography.hazmat` module. Currently only keys of `openssl` backend are implemented.
132+
133+
<Exceptions>
134+
securesystemslib.exceptions.FormatError, if 'key_value' does not conform to
135+
'securesystemslib.formats.KEYVAL_SCHEMA', or if the private key is not
136+
present in 'key_value' if requested by the caller via 'private'.
137+
NotImplementedError, if we cannot convert a key of this type.
138+
139+
<Side Effects>
140+
None.
141+
142+
<Returns>
143+
A 'securesystemslib.formats.KEY_SCHEMA' dictionary."""
144+
145+
key_type = type(key)
146+
try:
147+
mapper = _typeMapping[key_type]
148+
except KeyError as ex:
149+
raise NotImplementedError(key_type) from ex
150+
else:
151+
return mapper(key)

0 commit comments

Comments
 (0)