diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b6ffda..060876c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). [Unreleased][unreleased] ------------------------------------------------------------------------- ### Changed +- Add support for ECDSA public keys in RFC 4253 (OpenSSH) format [#244][244] - Renamed commandline script `jwt` to `jwt-cli` to avoid issues with the script clobbering the `jwt` module in some circumstances. - Better error messages when using an algorithm that requires the cryptography package, but it isn't available [#230][230] @@ -129,3 +130,4 @@ rarely used. Users affected by this should upgrade to 3.3+. [182]: https://github.com/jpadilla/pyjwt/pull/182 [183]: https://github.com/jpadilla/pyjwt/pull/183 [213]: https://github.com/jpadilla/pyjwt/pull/214 +[244]: https://github.com/jpadilla/pyjwt/pull/244 diff --git a/jwt/algorithms.py b/jwt/algorithms.py index 2fe1883b..f6d990ad 100644 --- a/jwt/algorithms.py +++ b/jwt/algorithms.py @@ -356,7 +356,10 @@ def prepare_key(self, key): # a Signing Key or a Verifying Key, so we try # the Verifying Key first. try: - key = load_pem_public_key(key, backend=default_backend()) + if key.startswith(b'ecdsa-sha2-'): + key = load_ssh_public_key(key, backend=default_backend()) + else: + key = load_pem_public_key(key, backend=default_backend()) except ValueError: key = load_pem_private_key(key, password=None, backend=default_backend()) diff --git a/tests/keys/testkey_ec_ssh.pub b/tests/keys/testkey_ec_ssh.pub new file mode 100644 index 00000000..4fa3a6bb --- /dev/null +++ b/tests/keys/testkey_ec_ssh.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFZwnA8QCdL+TiQWBSHE0XsnRJBCFkb6c2DL7+ZfCFDk9khSYh3VrVOOQ1eIrO/oOm20Gp24dvP9XQS0f5B9bLQHgGFnkydPIMaNzPUNCop17F5uHOhtuFIhmOlh3lpTjyj2ten86cCetqN12kawnRs1/iu0wsGoVgk3os6yUAHvFMFGA== diff --git a/tests/test_algorithms.py b/tests/test_algorithms.py index 97fdc225..11d8cd08 100644 --- a/tests/test_algorithms.py +++ b/tests/test_algorithms.py @@ -375,6 +375,13 @@ def test_ec_should_accept_pem_private_key_bytes(self): with open(key_path('testkey_ec'), 'rb') as ec_key: algo.prepare_key(ec_key.read()) + @pytest.mark.skipif(not has_crypto, reason='Not supported without cryptography library') + def test_ec_should_accept_ssh_public_key_bytes(self): + algo = ECAlgorithm(ECAlgorithm.SHA256) + + with open(key_path('testkey_ec_ssh.pub'), 'r') as ec_key: + algo.prepare_key(ec_key.read()) + @pytest.mark.skipif(not has_crypto, reason='Not supported without cryptography library') def test_ec_verify_should_return_false_if_signature_invalid(self): algo = ECAlgorithm(ECAlgorithm.SHA256)