in src/vtok_p11/src/crypto/mod.rs [322:352]
fn ecdsa_sig_ckrs_to_der(ckrs: &[u8]) -> Result<Vec<u8>> {
let mut bn_r = bytes_to_bignum(&ckrs[..ckrs.len() / 2])?;
let mut bn_s = bytes_to_bignum(&ckrs[ckrs.len() / 2..])?;
let mut ec_sig = FfiBox::new(unsafe { ffi::ECDSA_SIG_new() })?;
let rv =
unsafe { ffi::ECDSA_SIG_set0(ec_sig.as_mut_ptr(), bn_r.as_mut_ptr(), bn_s.as_mut_ptr()) };
if rv != 1 {
return Err(Error::GeneralError);
}
// ec_sign now owns bn_r and bn_s; relinquish ownership.
bn_r.into_raw();
bn_s.into_raw();
// i2d_ECDSA_SIG can either:
// - fill in a caller-provided buffer (here, via *der_sig_ptr); or
// - return a new buffer into the caller's ownership.
// We are going with the former here, since we don't want to deal with OPENSSL_free().
let der_sig_max_len = unsafe { ffi::ECDSA_SIG_max_len(ckrs.len() as u64 / 2) };
let mut der_sig = vec![0u8; der_sig_max_len as usize];
let mut der_sig_ptr = der_sig.as_mut_ptr();
let der_sig_len = unsafe { ffi::i2d_ECDSA_SIG(ec_sig.as_ptr(), &mut der_sig_ptr) };
if der_sig_len < 0 {
return Err(Error::GeneralError);
}
der_sig.resize(der_sig_len as usize, 0);
Ok(der_sig)
}