summaryrefslogtreecommitdiffstats
path: root/ffi
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2018-11-22 11:09:11 +0100
committerNeal H. Walfield <neal@pep.foundation>2018-11-22 11:11:01 +0100
commit6a837c6fb88d0320076df53129b22f44eb3ee060 (patch)
tree5268a680a5dee641192ae653ee023c9aa9e02803 /ffi
parentfbaba5b7245e90cb445dd0a702bea371ec9f0757 (diff)
ffi: Wrap PKESK::decrypt.
- Add sq_pkesk_decrypt.
Diffstat (limited to 'ffi')
-rw-r--r--ffi/include/sequoia/openpgp.h14
-rw-r--r--ffi/src/openpgp.rs44
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`