Skip to content

Commit

Permalink
ssh-key: handle leading zeroes in Mpint::from_positive_bytes (#171)
Browse files Browse the repository at this point in the history
Changes the method to allow leading zeroes, stripping them and readding
a leading one if need be.

Closes #170
  • Loading branch information
tarcieri authored Oct 20, 2023
1 parent 57327bf commit 414a90b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
27 changes: 23 additions & 4 deletions ssh-key/src/mpint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@ impl Mpint {
/// Create a new multiple precision integer from the given big endian
/// encoded byte slice representing a positive integer.
///
/// The integer should not start with any leading zeroes.
pub fn from_positive_bytes(bytes: &[u8]) -> Result<Self> {
/// The input may begin with leading zeros, which will be stripped when
/// converted to [`Mpint`] encoding.
pub fn from_positive_bytes(mut bytes: &[u8]) -> Result<Self> {
let mut inner = Vec::with_capacity(bytes.len());

match bytes.first().cloned() {
Some(0) => return Err(Error::FormatEncoding),
while bytes.first().copied() == Some(0) {
bytes = &bytes[1..];
}

match bytes.first().copied() {
Some(n) if n >= 0x80 => inner.push(0),
_ => (),
}
Expand Down Expand Up @@ -261,6 +265,21 @@ mod tests {
// Leading zero stripped
assert_eq!(&hex!("80"), n.as_positive_bytes().unwrap())
}
#[test]
fn from_positive_bytes_strips_leading_zeroes() {
assert_eq!(
Mpint::from_positive_bytes(&hex!("00")).unwrap().as_ref(),
b""
);
assert_eq!(
Mpint::from_positive_bytes(&hex!("00 00")).unwrap().as_ref(),
b""
);
assert_eq!(
Mpint::from_positive_bytes(&hex!("00 01")).unwrap().as_ref(),
b"\x01"
);
}

// TODO(tarcieri): drop support for negative numbers?
#[test]
Expand Down
7 changes: 7 additions & 0 deletions ssh-key/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,13 @@ mod tests {
#[cfg(feature = "ed25519")]
const EXAMPLE_MSG: &[u8] = b"Hello, world!";

#[cfg(feature = "p256")]
#[test]
fn convert_ecdsa_sha2_p256() {
let p256_signature = p256::ecdsa::Signature::try_from(hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001").as_ref()).unwrap();
let _ssh_signature = Signature::try_from(p256_signature).unwrap();
}

#[test]
fn decode_dsa() {
let signature = Signature::try_from(DSA_SIGNATURE).unwrap();
Expand Down

0 comments on commit 414a90b

Please sign in to comment.