diff options
author | Neal H. Walfield <neal@pep.foundation> | 2018-11-22 11:09:11 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2018-11-22 11:11:01 +0100 |
commit | 6a837c6fb88d0320076df53129b22f44eb3ee060 (patch) | |
tree | 5268a680a5dee641192ae653ee023c9aa9e02803 /ffi | |
parent | fbaba5b7245e90cb445dd0a702bea371ec9f0757 (diff) |
ffi: Wrap PKESK::decrypt.
- Add sq_pkesk_decrypt.
Diffstat (limited to 'ffi')
-rw-r--r-- | ffi/include/sequoia/openpgp.h | 14 | ||||
-rw-r--r-- | ffi/src/openpgp.rs | 44 |
2 files changed, 58 insertions, 0 deletions
diff --git a/ffi/include/sequoia/openpgp.h b/ffi/include/sequoia/openpgp.h index 9d1ebdc1..63e1ff6e 100644 --- a/ffi/include/sequoia/openpgp.h +++ b/ffi/include/sequoia/openpgp.h @@ -514,6 +514,20 @@ sq_keyid_t sq_signature_issuer(sq_signature_t sig); /*/ sq_fingerprint_t sq_signature_issuer_fingerprint(sq_signature_t sig); + +/*/ +/// Returns the session key. +/// +/// `key` of size `key_len` must be a buffer large enough to hold the +/// session key. If `key` is NULL, or not large enough, then the key +/// is not written to it. Either way, `key_len` is set to the size of +/// the session key. +/*/ +sq_status_t sq_pkesk_decrypt (sq_context_t ctx, sq_pkesk_t pkesk, + sq_p_key_t secret_key, + uint8_t *algo, /* XXX */ + uint8_t *key, size_t *key_len); + typedef enum sq_reason_for_revocation { /*/ /// No reason specified (key revocations or cert revocations) diff --git a/ffi/src/openpgp.rs b/ffi/src/openpgp.rs index 95d1f521..fd4db5e6 100644 --- a/ffi/src/openpgp.rs +++ b/ffi/src/openpgp.rs @@ -22,7 +22,9 @@ use self::openpgp::{ Packet, packet::{ Signature, + PKESK, }, + SecretKey, crypto::Password, }; use self::openpgp::tpk::{ @@ -1486,6 +1488,48 @@ pub extern "system" fn sq_skesk_decrypt(ctx: Option<&mut Context>, } } +/// Returns the session key. +/// +/// `key` of size `key_len` must be a buffer large enough to hold the +/// session key. If `key` is NULL, or not large enough, then the key +/// is not written to it. Either way, `key_len` is set to the size of +/// the session key. +#[no_mangle] +pub extern "system" fn sq_pkesk_decrypt(ctx: Option<&mut Context>, + pkesk: Option<&PKESK>, + secret_key: Option<&packet::Key>, + algo: Option<&mut uint8_t>, // XXX + key: *mut uint8_t, + key_len: Option<&mut size_t>) + -> Status { + let ctx = ctx.expect("Context is NULL"); + let pkesk = pkesk.expect("PKESK is NULL"); + let secret_key = secret_key.expect("SECRET_KEY is NULL"); + let algo = algo.expect("Algo is NULL"); + let key_len = key_len.expect("Key length is NULL"); + + if let Some(SecretKey::Unencrypted{ mpis: ref secret_part }) = secret_key.secret() { + match pkesk.decrypt(secret_key, secret_part) { + Ok((a, k)) => { + *algo = a.into(); + if !key.is_null() && *key_len >= k.len() { + unsafe { + ::std::ptr::copy(k.as_ptr(), + key, + k.len()); + } + } + *key_len = k.len(); + Status::Success + }, + Err(e) => fry_status!(ctx, Err::<(), failure::Error>(e)), + } + } else { + // XXX: Better message. + panic!("No secret parts"); + } +} + /* openpgp::parse. */ /// Starts parsing OpenPGP packets stored in a `sq_reader_t` |