1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use crate::{vec, Vec};
use crate::{Voucher, Sign, VoucherError, SignatureAlgorithm};
use crate::debug_println;
use super::utils::minerva_mbedtls_utils::*;
use minerva_mbedtls::{psa_ifce::*, mbedtls_error};
impl Sign for Voucher {
/// Signs the voucher using a PEM-encoded private key
/// based on the signature algorithm `alg`.
///
/// Returns a `&mut Self` reference if the voucher is signed.
///
/// # Errors
///
/// If the voucher is not signed, or the internal signing function fails, a `VoucherError::SigningFailed` is returned.
///
/// # Examples
///
/// ```
/// use minerva_voucher::{Voucher, attr::*, SignatureAlgorithm, Sign};
///
/// static KEY_PEM_F2_00_02: &[u8] = core::include_bytes!(
/// concat!(env!("CARGO_MANIFEST_DIR"), "/data/00-D0-E5-F2-00-02/key.pem"));
///
/// // This is required when the `Sign` trait is backed by mbedtls.
/// minerva_voucher::init_psa_crypto();
///
/// let mut vrq = Voucher::new_vrq();
///
/// vrq.set(Attr::Assertion(Assertion::Proximity))
/// .set(Attr::SerialNumber(b"00-D0-E5-F2-00-02".to_vec()));
///
/// assert!(vrq.get_signature().is_none());
/// vrq.sign(KEY_PEM_F2_00_02, SignatureAlgorithm::ES256).unwrap();
/// assert!(vrq.get_signature().is_some());
/// ```
fn sign(&mut self, privkey_pem: &[u8], alg: SignatureAlgorithm) -> Result<&mut Self, VoucherError> {
if let Err(err) = sign_with_mbedtls(privkey_pem, alg, self.to_sign(alg)) {
debug_println!("sign(): mbedtls_error: {}", err);
Err(VoucherError::SigningFailed)
} else {
Ok(self)
}
}
}
pub fn sign_with_mbedtls(
privkey_pem: &[u8],
alg: SignatureAlgorithm,
(sig_out, sig_struct): (&mut Vec<u8>, &[u8])
) -> Result<(), mbedtls_error> {
let mut sig = vec![];
let (md_ty, ref hash) = compute_digest(sig_struct, &alg);
let f_rng = Some(pk_context::test_f_rng_ptr());
let mut pk = pk_from_privkey_pem(privkey_pem, f_rng)?;
pk.sign(md_ty, hash, &mut sig, f_rng, core::ptr::null_mut())?;
*sig_out = sig;
Ok(())
}