diff --git a/src/ssh/privkey.rs b/src/ssh/privkey.rs index 27ff1b5..85a3d83 100644 --- a/src/ssh/privkey.rs +++ b/src/ssh/privkey.rs @@ -299,14 +299,15 @@ impl super::SSHCertificateSigner for PrivateKey { // OpenSSH stores the scalar as an mpint, so it can be shorter // than the curve size or have a leading zero byte. ring needs - // it to be exactly the curve size. + // it to be exactly the curve size. Like OpenSSH, reject + // scalars with half the curve's bits or fewer. let start = key .key .iter() .position(|&b| b != 0) .unwrap_or(key.key.len()); let scalar = &key.key[start..]; - if scalar.len() > scalar_len { + if scalar.len() <= scalar_len / 2 || scalar.len() > scalar_len { return None; } let mut key = Zeroizing::new(vec![0; scalar_len]); diff --git a/tests/keys/unencrypted/ecdsa_256_small_scalar b/tests/keys/unencrypted/ecdsa_256_small_scalar new file mode 100644 index 0000000..b799f71 --- /dev/null +++ b/tests/keys/unencrypted/ecdsa_256_small_scalar @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS +1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQT6ox6CT4FDyusrDmje7nC9Rdxbmnj6 +B0HuIqanudCyL+YHi1pZjfi2W6PSiOcNtgSiXZAnnVhtESgtcE+L0Y8tAAAAkAAAAAcAAA +AHAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPqjHoJPgUPK6ysO +aN7ucL1F3FuaePoHQe4ipqe50LIv5geLWlmN+LZbo9KI5w22BKJdkCedWG0RKC1wT4vRjy +0AAAARAP////////////////////8AAAAAAQIDBAUGBw== +-----END OPENSSH PRIVATE KEY----- diff --git a/tests/signature-creation.rs b/tests/signature-creation.rs index 119336b..7ffaf04 100644 --- a/tests/signature-creation.rs +++ b/tests/signature-creation.rs @@ -148,3 +148,15 @@ fn check_basic_creation_ecdsa_384_short_scalar_full_loop() { assert!(fl_vss.is_ok()); } + +#[test] +fn check_creation_ecdsa_256_small_scalar_fails() { + let private_key = + PrivateKey::from_string(include_str!("keys/unencrypted/ecdsa_256_small_scalar")).unwrap(); + + let message = include_bytes!("messages/Test").to_vec(); + + assert!( + VerifiedSshSignature::new_with_private_key(&message, "file", private_key, None).is_err() + ); +}