fn ecdsa_sig_ckrs_to_der()

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)
}