Skip to content

Commit

Permalink
Merge pull request sfackler#785 from P-E-Meunier/split-signer-finish
Browse files Browse the repository at this point in the history
Splitting the sign::Signer::finish function, to avoid allocations
  • Loading branch information
sfackler authored Dec 3, 2017
2 parents b40bddf + 9732264 commit 13a1372
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions openssl/src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,25 +139,47 @@ impl<'a> Signer<'a> {
}
}

pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
/// Computes an upper bound on the signature length.
pub fn finish_len(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
cvt(ffi::EVP_DigestSignFinal(
self.md_ctx,
ptr::null_mut(),
&mut len,
))?;
let mut buf = vec![0; len];
Ok(len)
}
}

/// Outputs the signature into the provided buffer, returning the
/// length of that buffer.
///
/// This method will fail if the buffer is not large enough for
/// the signature, one can use `finish_len` to get an upper bound
/// on the required size.
pub fn finish_into(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe {
let mut len = buf.len();
cvt(ffi::EVP_DigestSignFinal(
self.md_ctx,
buf.as_mut_ptr() as *mut _,
&mut len,
))?;
// The advertised length is not always equal to the real length for things like DSA
buf.truncate(len);
Ok(buf)
Ok(len)
}
}

/// Combines `self.finish_len()` and `self.finish_into()`,
/// allocating a vector of the correct size for the signature.
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
let mut buf = vec![0; self.finish_len()?];
let len = self.finish_into(&mut buf)?;
// The advertised length is not always equal to the real
// length for things like DSA
buf.truncate(len);
Ok(buf)
}
}

impl<'a> Write for Signer<'a> {
Expand Down

0 comments on commit 13a1372

Please sign in to comment.