Skip to content

Commit

Permalink
ssh-key: simplify DSA signature encoding (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarcieri authored Jan 12, 2024
1 parent 2e8621f commit 63a96c5
Showing 1 changed file with 11 additions and 22 deletions.
33 changes: 11 additions & 22 deletions ssh-key/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,36 +324,25 @@ impl Verifier<Signature> for public::KeyData {
#[cfg(feature = "dsa")]
impl Signer<Signature> for DsaKeypair {
fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
fn to_be_bytes_padded(v: &BigUint, len: usize) -> Vec<u8> {
let mut bytes = v.to_bytes_le();
let pad_len = len.saturating_sub(bytes.len());
if pad_len > 0 {
bytes.extend(iter::repeat(0).take(pad_len));
}
bytes.reverse();
bytes
}

let signature = dsa::SigningKey::try_from(self)?
.try_sign_digest(Sha1::new_with_prefix(message))
.map_err(|_| signature::Error::new())?;

// Note that we need to roll our own signature encoding, as [RFC4253 section 6.6]
// specifies two raw 80 bit integer but the dsa::SigningKey serialization
// encodes to a der format.
let mut buf: Vec<u8> = Vec::new();
let mut r = to_be_bytes_padded(signature.r(), DSA_SIGNATURE_SIZE / 2);
let mut s = to_be_bytes_padded(signature.s(), DSA_SIGNATURE_SIZE / 2);
buf.append(&mut r);
buf.append(&mut s);

if buf.len() != DSA_SIGNATURE_SIZE {
return Err(signature::Error::new());
// Encode the format specified in RFC4253 section 6.6: two raw 80-bit integers concatenated
let mut data = Vec::new();

for component in [signature.r(), signature.s()] {
let mut bytes = component.to_bytes_be();
let pad_len = (DSA_SIGNATURE_SIZE / 2).saturating_sub(bytes.len());
data.extend(iter::repeat(0).take(pad_len));
data.append(&mut bytes);
}

debug_assert_eq!(data.len(), DSA_SIGNATURE_SIZE);

Ok(Signature {
algorithm: Algorithm::Dsa,
data: buf,
data,
})
}
}
Expand Down

0 comments on commit 63a96c5

Please sign in to comment.