diff options
-rw-r--r-- | ffi/include/sequoia/openpgp.h | 48 | ||||
-rw-r--r-- | ffi/src/openpgp.rs | 74 |
2 files changed, 121 insertions, 1 deletions
diff --git a/ffi/include/sequoia/openpgp.h b/ffi/include/sequoia/openpgp.h index 19409920..815e8f91 100644 --- a/ffi/include/sequoia/openpgp.h +++ b/ffi/include/sequoia/openpgp.h @@ -240,6 +240,22 @@ sq_status_t sq_packet_pile_serialize (sq_context_t ctx, /*/ typedef struct sq_tpk *sq_tpk_t; + +/*/ +/// A transferable secret key (TSK). +/// +/// A TSK (see [RFC 4880, section 11.2]) can be used to create +/// signatures and decrypt data. +/// +/// [RFC 4880, section 11.2]: https://tools.ietf.org/html/rfc4880#section-11.2 +/*/ +typedef struct sq_tsk *sq_tsk_t; + +/*/ +/// Generates a new RSA 3072 bit key with UID `primary_uid`. +/*/ +sq_tpk_t sq_tpk_new (sq_context_t ctx, char *primary_uid); + /*/ /// Returns the first TPK encountered in the reader. /*/ @@ -312,6 +328,38 @@ void sq_tpk_dump (const sq_tpk_t tpk); /*/ sq_fingerprint_t sq_tpk_fingerprint (const sq_tpk_t tpk); + +/*/ +/// Cast the public key into a secret key that allows using the secret +/// parts of the containing keys. +/*/ +sq_tsk_t sq_tpk_into_tsk (sq_tpk_t tpk); + +/* TSK */ + +/*/ +/// Generates a new RSA 3072 bit key with UID `primary_uid`. +/*/ +sq_tsk_t sq_tsk_new (sq_context_t ctx, char *primary_uid); + +/*/ +/// Frees the TSK. +/*/ +void sq_tsk_free (sq_tsk_t tsk); + +/*/ +/// Returns a reference to the corresponding TPK. +/*/ +sq_tpk_t sq_tsk_tpk (sq_tsk_t tsk); + +/*/ +/// Serializes the TSK. +/*/ +sq_status_t sq_tsk_serialize (sq_context_t ctx, + const sq_tsk_t tsk, + sq_writer_t writer); + + /*/ /// The OpenPGP packet tags as defined in [Section 4.3 of RFC 4880]. /// diff --git a/ffi/src/openpgp.rs b/ffi/src/openpgp.rs index 429ca320..330cb500 100644 --- a/ffi/src/openpgp.rs +++ b/ffi/src/openpgp.rs @@ -10,7 +10,7 @@ use libc::{uint8_t, uint64_t, c_char, c_int, size_t, ssize_t}; extern crate openpgp; -use self::openpgp::{armor, Fingerprint, KeyID, PacketPile, TPK, Packet}; +use self::openpgp::{armor, Fingerprint, KeyID, PacketPile, TPK, TSK, Packet}; use self::openpgp::parse::{PacketParser}; use self::openpgp::serialize::Serialize; use self::openpgp::constants::{ @@ -332,6 +332,19 @@ pub extern "system" fn sq_packet_pile_serialize(ctx: Option<&mut Context>, /* sequoia::keys. */ +/// Generates a new RSA 3072 bit key with UID `primary_uid`. +#[no_mangle] +pub extern "system" fn sq_tpk_new(ctx: Option<&mut Context>, + primary_uid: *const c_char) + -> *mut TPK { + let ctx = ctx.expect("CONTEXT is NULL"); + assert!(!primary_uid.is_null()); + let primary_uid = unsafe { + CStr::from_ptr(primary_uid) + }; + fry_box!(ctx, TPK::new(&primary_uid.to_string_lossy())) +} + /// Returns the first TPK encountered in the reader. #[no_mangle] pub extern "system" fn sq_tpk_from_reader(ctx: Option<&mut Context>, @@ -461,6 +474,65 @@ pub extern "system" fn sq_tpk_fingerprint(tpk: Option<&TPK>) box_raw!(tpk.fingerprint()) } +/// Cast the public key into a secret key that allows using the secret +/// parts of the containing keys. +#[no_mangle] +pub extern "system" fn sq_tpk_into_tsk(tpk: *mut TPK) + -> *mut TSK { + assert!(!tpk.is_null()); + let tpk = unsafe { + Box::from_raw(tpk) + }; + box_raw!(tpk.into_tsk()) +} + +/* TSK */ + +/// Generates a new RSA 3072 bit key with UID `primary_uid`. +#[no_mangle] +pub extern "system" fn sq_tsk_new(ctx: Option<&mut Context>, + primary_uid: *const c_char) + -> *mut TSK { + let ctx = ctx.expect("CONTEXT is NULL"); + assert!(!primary_uid.is_null()); + let primary_uid = unsafe { + CStr::from_ptr(primary_uid) + }; + fry_box!(ctx, TSK::new(&primary_uid.to_string_lossy())) +} + +/// Frees the TSK. +#[no_mangle] +pub extern "system" fn sq_tsk_free(tsk: *mut TSK) { + if tsk.is_null() { + return + } + unsafe { + drop(Box::from_raw(tsk)); + } +} + +/// Returns a reference to the corresponding TPK. +#[no_mangle] +pub extern "system" fn sq_tsk_tpk(tsk: Option<&TSK>) + -> &TPK { + let tsk = tsk.expect("TSK is NULL"); + tsk.tpk() +} + + +/// Serializes the TSK. +#[no_mangle] +pub extern "system" fn sq_tsk_serialize(ctx: Option<&mut Context>, + tsk: Option<&TSK>, + writer: Option<&mut Box<Write>>) + -> Status { + let ctx = ctx.expect("Context is NULL"); + let tsk = tsk.expect("TSK is NULL"); + let writer = writer.expect("Writer is NULL"); + fry_status!(ctx, tsk.serialize(writer)) +} + /* openpgp::Packet. */ /// Frees the Packet. |