diff options
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization.py | 12 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_serialization.py | 49 |
2 files changed, 56 insertions, 5 deletions
diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index b95ac1cd..dad419fe 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -102,16 +102,18 @@ def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend): elif curve_name == b"nistp521": curve = ec.SECP521R1() - if len(data) != 1 + 2 * (curve.key_size // 8): - raise ValueError("Malformed key bytes") - if six.indexbytes(data, 0) != 4: raise NotImplementedError( "Compressed elliptic curve points are not supported" ) - x = _int_from_bytes(data[1:1 + curve.key_size // 8], byteorder='big') - y = _int_from_bytes(data[1 + curve.key_size // 8:], byteorder='big') + # key_size is in bits, and sometimes it's not evenly divisible by 8, so we + # add 7 to round up the number of bytes. + if len(data) != 1 + 2 * ((curve.key_size + 7) // 8): + raise ValueError("Malformed key bytes") + + x = _int_from_bytes(data[1:1 + (curve.key_size + 7) // 8], byteorder='big') + y = _int_from_bytes(data[1 + (curve.key_size + 7) // 8:], byteorder='big') return ec.EllipticCurvePublicNumbers(x, y, curve).public_key(backend) diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 2434ee45..fdd88a82 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -812,6 +812,55 @@ class TestECDSASSHSerialization(object): expected_x, expected_y, ec.SECP256R1() ) + def test_load_ssh_public_key_ecdsa_nist_p384(self, backend): + _skip_curve_unsupported(backend, ec.SECP384R1()) + ssh_key = ( + b"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAz" + b"ODQAAABhBMzucOm9wbwg4iMr5QL0ya0XNQGXpw4wM5f12E3tWhdcrzyGHyel71t1" + b"4bvF9JZ2/WIuSxUr33XDl8jYo+lMQ5N7Vanc7f7i3AR1YydatL3wQfZStQ1I3rBa" + b"qQtRSEU8Tg== root@cloud-server-01" + ) + key = load_ssh_public_key(ssh_key, backend) + + expected_x = int( + "31541830871345183397582554827482786756220448716666815789487537666" + "592636882822352575507883817901562613492450642523901", 10 + ) + expected_y = int( + "15111413269431823234030344298767984698884955023183354737123929430" + "995703524272335782455051101616329050844273733614670", 10 + ) + + assert key.public_numbers() == ec.EllipticCurvePublicNumbers( + expected_x, expected_y, ec.SECP384R1() + ) + + def test_load_ssh_public_key_ecdsa_nist_p521(self, backend): + _skip_curve_unsupported(backend, ec.SECP521R1()) + ssh_key = ( + b"ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1" + b"MjEAAACFBAGTrRhMSEgF6Ni+PXNz+5fjS4lw3ypUILVVQ0Av+0hQxOx+MyozELon" + b"I8NKbrbBjijEs1GuImsmkTmWsMXS1j2A7wB4Kseh7W9KA9IZJ1+TMrzWUEwvOOXi" + b"wT23pbaWWXG4NaM7vssWfZBnvz3S174TCXnJ+DSccvWBFnKP0KchzLKxbg== " + b"root@cloud-server-01" + ) + key = load_ssh_public_key(ssh_key, backend) + + expected_x = int( + "54124123120178189598842622575230904027376313369742467279346415219" + "77809037378785192537810367028427387173980786968395921877911964629" + "142163122798974160187785455", 10 + ) + expected_y = int( + "16111775122845033200938694062381820957441843014849125660011303579" + "15284560361402515564433711416776946492019498546572162801954089916" + "006665939539407104638103918", 10 + ) + + assert key.public_numbers() == ec.EllipticCurvePublicNumbers( + expected_x, expected_y, ec.SECP521R1() + ) + def test_load_ssh_public_key_ecdsa_nist_p256_trailing_data(self, backend): ssh_key = ( b"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAy" |