Skip to content

Commit 45cd616

Browse files
committed
feat: check ssh_type and cryptography key types in bindings
1 parent a06ab98 commit 45cd616

5 files changed

Lines changed: 42 additions & 9 deletions

File tree

‎docs/migrations/authlib.rst‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ When using methods such as ``.as_dict``, ``.as_bytes``, ``.as_pem``, and others,
8080

8181
.. code-block:: python
8282
:caption: Authlib
83-
:emphasize-lines: 1,2
8483
8584
key.as_dict(is_private=True)
8685

‎src/joserfc/_rfc7517/pem.py‎

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from __future__ importannotations
2-
fromtypingimportAny, Literal, cast
2+
fromtypingimportAny, Literal, Tuple, cast
33
fromabcimportABCMeta, abstractmethod
44
fromcryptography.x509importload_pem_x509_certificate
55
fromcryptography.hazmat.primitives.serializationimport (
@@ -19,15 +19,14 @@
1919
fromcryptography.hazmat.backendsimportdefault_backend
2020
from .modelsimportNativeKeyBinding, GenericKey
2121
from .typesimportDictKey
22+
from ..errorsimportInvalidKeyTypeError
2223
from ..utilimportto_bytes
2324

2425

25-
defload_pem_key(raw: bytes, ssh_type: bytes|None=None, password: bytes|None=None) ->Any:
26+
defload_pem_key(raw: bytes, password: bytes|None=None) ->Any:
2627
key: Any
27-
ifssh_typeandraw.startswith(ssh_type):
28-
key=load_ssh_public_key(raw, backend=default_backend())
2928

30-
elifb"OPENSSH PRIVATE"inraw:
29+
ifb"OPENSSH PRIVATE"inraw:
3130
key=load_ssh_private_key(raw, password=password, backend=default_backend())
3231

3332
elifb"PUBLIC"inraw:
@@ -49,7 +48,10 @@ def load_pem_key(raw: bytes, ssh_type: bytes | None = None, password: bytes | No
4948

5049

5150
defdump_pem_key(
52-
key: Any, encoding: Literal["PEM", "DER"] |None=None, private: bool|None=False, password: Any|None=None
51+
key: Any,
52+
encoding: Literal["PEM", "DER"] |None=None,
53+
private: bool|None=False,
54+
password: Any|None=None,
5355
) ->bytes:
5456
"""Export key into PEM/DER format bytes.
5557
@@ -87,7 +89,17 @@ def dump_pem_key(
8789

8890

8991
classCryptographyBinding(NativeKeyBinding, metaclass=ABCMeta):
92+
key_type: str
9093
ssh_type: bytes
94+
cryptography_native_keys: Tuple[Any]
95+
96+
@classmethod
97+
defcheck_ssh_type(cls, value: bytes):
98+
returncls.ssh_typeandvalue.startswith(cls.ssh_type)
99+
100+
@classmethod
101+
defcheck_cryptography_native_key(cls, native_key: Any):
102+
returnisinstance(native_key, cls.cryptography_native_keys)
91103

92104
@classmethod
93105
defconvert_raw_key_to_dict(cls, raw_key: Any, private: bool) ->DictKey:
@@ -105,9 +117,16 @@ def import_from_dict(cls, value: DictKey) -> Any:
105117

106118
@classmethod
107119
defimport_from_bytes(cls, value: bytes, password: Any|None=None) ->Any:
120+
ifcls.check_ssh_type(value):
121+
returnload_ssh_public_key(value, backend=default_backend())
122+
108123
ifpasswordisnotNone:
109124
password=to_bytes(password)
110-
returnload_pem_key(value, cls.ssh_type, password)
125+
126+
key=load_pem_key(value, password)
127+
ifnotcls.check_cryptography_native_key(key):
128+
raiseInvalidKeyTypeError(f"Not a key of: '{cls.key_type}'")
129+
returnkey
111130

112131
@staticmethod
113132
defas_bytes(
@@ -116,7 +135,7 @@ def as_bytes(
116135
private: bool|None=False,
117136
password: Any|None=None,
118137
) ->bytes:
119-
ifprivateisTrue:
138+
ifprivate:
120139
returndump_pem_key(key.private_key, encoding, private, password)
121140
elifprivateisFalse:
122141
returndump_pem_key(key.public_key, encoding, private, password)

‎src/joserfc/_rfc7518/ec_key.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636

3737

3838
classECBinding(CryptographyBinding):
39+
key_type="EC"
3940
ssh_type=b"ecdsa-sha2-"
41+
cryptography_native_keys= (EllipticCurvePrivateKey, EllipticCurvePublicKey)
4042

4143
_dss_curves: dict[str, t.Type[EllipticCurve]] = {}
4244
_curves_dss: dict[str, str] = {}

‎src/joserfc/_rfc7518/rsa_key.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939

4040

4141
classRSABinding(CryptographyBinding):
42+
key_type="RSA"
4243
ssh_type=b"ssh-rsa"
44+
cryptography_native_keys= (RSAPrivateKey, RSAPublicKey)
4345

4446
@staticmethod
4547
defimport_private_key(obj: RSADictKey) ->RSAPrivateKey:

‎src/joserfc/_rfc8037/okp_key.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,18 @@
4646

4747

4848
classOKPBinding(CryptographyBinding):
49+
key_type="OKP"
4950
ssh_type=b"ssh-ed25519"
51+
cryptography_native_keys= (
52+
Ed25519PublicKey,
53+
Ed25519PrivateKey,
54+
Ed448PublicKey,
55+
Ed448PrivateKey,
56+
X25519PublicKey,
57+
X25519PrivateKey,
58+
X448PublicKey,
59+
X448PrivateKey,
60+
)
5061

5162
@staticmethod
5263
defimport_private_key(obj: OKPDictKey) ->PrivateOKPKey:

0 commit comments

Comments
 (0)