diff options
Diffstat (limited to 'ffi/src/openpgp/mod.rs')
-rw-r--r-- | ffi/src/openpgp/mod.rs | 707 |
1 files changed, 2 insertions, 705 deletions
diff --git a/ffi/src/openpgp/mod.rs b/ffi/src/openpgp/mod.rs index 6f52484e..05afe9c0 100644 --- a/ffi/src/openpgp/mod.rs +++ b/ffi/src/openpgp/mod.rs @@ -1,7 +1,7 @@ //! XXX use failure; -use std::ffi::{CString, CStr}; +use std::ffi::CStr; use std::mem::forget; use std::ptr; use std::slice; @@ -17,7 +17,6 @@ use self::openpgp::{ Fingerprint, KeyID, RevocationStatus, - PacketPile, TPK, TSK, Packet, @@ -30,13 +29,6 @@ use self::openpgp::{ }, crypto::Password, }; -use self::openpgp::tpk::{ - CipherSuite, - TPKBuilder, - UserIDBinding, - UserIDBindingIter, - KeyIter -}; use self::openpgp::packet; use self::openpgp::parse::{ Parse, @@ -56,7 +48,6 @@ use self::openpgp::parse::stream::{ use self::openpgp::serialize::Serialize; use self::openpgp::constants::{ DataFormat, - ReasonForRevocation, }; use super::error::Status; @@ -66,6 +57,7 @@ pub mod armor; pub mod fingerprint; pub mod keyid; pub mod packet_pile; +pub mod tpk; /* openpgp::packet::Tag. */ @@ -102,420 +94,6 @@ pub extern "system" fn sq_tag_to_string(tag: u8) -> *const c_char { }.as_bytes().as_ptr() as *const c_char } -/* sequoia::keys. */ - -/// Returns the first TPK encountered in the reader. -#[no_mangle] -pub extern "system" fn sq_tpk_from_reader(ctx: Option<&mut Context>, - reader: Option<&mut Box<Read>>) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - let reader = reader.expect("Reader is NULL"); - fry_box!(ctx, TPK::from_reader(reader)) -} - -/// Returns the first TPK encountered in the file. -#[no_mangle] -pub extern "system" fn sq_tpk_from_file(ctx: Option<&mut Context>, - filename: *const c_char) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - assert!(! filename.is_null()); - let filename = unsafe { - CStr::from_ptr(filename).to_string_lossy().into_owned() - }; - fry_box!(ctx, TPK::from_file(&filename)) -} - -/// Returns the first TPK found in `m`. -/// -/// Consumes `m`. -#[no_mangle] -pub extern "system" fn sq_tpk_from_packet_pile(ctx: Option<&mut Context>, - m: *mut PacketPile) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - assert!(! m.is_null()); - let m = unsafe { Box::from_raw(m) }; - fry_box!(ctx, TPK::from_packet_pile(*m)) -} - -/// Returns the first TPK found in `buf`. -/// -/// `buf` must be an OpenPGP-encoded TPK. -#[no_mangle] -pub extern "system" fn sq_tpk_from_bytes(ctx: Option<&mut Context>, - b: *const uint8_t, len: size_t) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - assert!(!b.is_null()); - let buf = unsafe { - slice::from_raw_parts(b, len as usize) - }; - - fry_box!(ctx, TPK::from_bytes(buf)) -} - -/// Returns the first TPK found in the packet parser. -/// -/// Consumes the packet parser result. -#[no_mangle] -pub extern "system" fn sq_tpk_from_packet_parser(ctx: Option<&mut Context>, - ppr: *mut PacketParserResult) - -> *mut TPK -{ - let ctx = ctx.expect("Context is NULL"); - assert!(! ppr.is_null()); - let ppr = unsafe { Box::from_raw(ppr) }; - - fry_box!(ctx, TPK::from_packet_parser(*ppr)) -} - -/// Frees the TPK. -#[no_mangle] -pub extern "system" fn sq_tpk_free(tpk: *mut TPK) { - if tpk.is_null() { - return - } - unsafe { - drop(Box::from_raw(tpk)); - } -} - -/// Clones the TPK. -#[no_mangle] -pub extern "system" fn sq_tpk_clone(tpk: Option<&TPK>) - -> *mut TPK { - let tpk = tpk.expect("TPK is NULL"); - box_raw!(tpk.clone()) -} - -/// Compares TPKs. -#[no_mangle] -pub extern "system" fn sq_tpk_equal(a: Option<&TPK>, - b: Option<&TPK>) - -> bool { - let a = a.expect("TPK 'a' is NULL"); - let b = b.expect("TPK 'b' is NULL"); - a == b -} - -/// Serializes the TPK. -#[no_mangle] -pub extern "system" fn sq_tpk_serialize(ctx: Option<&mut Context>, - tpk: Option<&TPK>, - writer: Option<&mut Box<Write>>) - -> Status { - let ctx = ctx.expect("Context is NULL"); - let tpk = tpk.expect("TPK is NULL"); - let writer = writer.expect("Writer is NULL"); - fry_status!(ctx, tpk.serialize(writer)) -} - -/// Merges `other` into `tpk`. -/// -/// If `other` is a different key, then nothing is merged into -/// `tpk`, but `tpk` is still canonicalized. -/// -/// Consumes `tpk` and `other`. -#[no_mangle] -pub extern "system" fn sq_tpk_merge(ctx: Option<&mut Context>, - tpk: *mut TPK, - other: *mut TPK) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - assert!(! tpk.is_null()); - let tpk = unsafe { Box::from_raw(tpk) }; - assert!(! other.is_null()); - let other = unsafe { Box::from_raw(other) }; - fry_box!(ctx, tpk.merge(*other)) -} - -/// Adds packets to the TPK. -/// -/// This recanonicalizes the TPK. If the packets are invalid, they -/// are dropped. -/// -/// Consumes `tpk` and the packets in `packets`. The buffer, however, -/// must be managed by the caller. -#[no_mangle] -pub extern "system" fn sq_tpk_merge_packets(ctx: Option<&mut Context>, - tpk: *mut TPK, - packets: *mut *mut Packet, - packets_len: size_t) - -> *mut TPK { - let ctx = ctx.expect("Context is NULL"); - assert!(! tpk.is_null()); - let tpk = unsafe { Box::from_raw(tpk) }; - let packets = unsafe { - slice::from_raw_parts_mut(packets, packets_len) - }; - let packets = - packets.iter_mut().map(|p| *unsafe { Box::from_raw(*p) } ).collect(); - fry_box!(ctx, tpk.merge_packets(packets)) -} - -/// Dumps the TPK. -/// -/// XXX Remove this. -#[no_mangle] -pub extern "system" fn sq_tpk_dump(tpk: Option<&TPK>) { - let tpk = tpk.expect("TPK is NULL"); - println!("{:?}", *tpk); -} - -/// Returns the fingerprint. -#[no_mangle] -pub extern "system" fn sq_tpk_fingerprint(tpk: Option<&TPK>) - -> *mut Fingerprint { - let tpk = tpk.expect("TPK is NULL"); - 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()) -} - -/// Returns a reference to the TPK's primary key. -/// -/// The tpk still owns the key. The caller should neither modify nor -/// free the key. -#[no_mangle] -pub extern "system" fn sq_tpk_primary(tpk: Option<&TPK>) - -> Option<&packet::Key> { - let tpk = tpk.expect("TPK is NULL"); - Some(tpk.primary()) -} - -/// Returns the TPK's revocation status. -/// -/// Note: this only returns whether the TPK has been revoked, and does -/// not reflect whether an individual user id, user attribute or -/// subkey has been revoked. -#[no_mangle] -pub extern "system" fn sq_tpk_revocation_status(tpk: Option<&TPK>) - -> *mut RevocationStatus { - let tpk = tpk.expect("TPK is NULL"); - box_raw!(tpk.revoked()) -} - -fn int_to_reason_for_revocation(code: c_int) -> ReasonForRevocation { - match code { - 0 => ReasonForRevocation::KeyCompromised, - 1 => ReasonForRevocation::Unspecified, - 2 => ReasonForRevocation::KeySuperseded, - 3 => ReasonForRevocation::KeyCompromised, - 4 => ReasonForRevocation::KeyRetired, - 5 => ReasonForRevocation::UIDRetired, - _ => panic!("Bad reason for revocation: {}", code), - } -} - - -/// Returns a new revocation certificate for the TPK. -/// -/// This function does *not* consume `tpk`. -/// -/// # Example -/// -/// ```c -/// #include <assert.h> -/// #include <sequoia.h> -/// -/// sq_context_t ctx; -/// sq_tpk_builder_t builder; -/// sq_tpk_t tpk; -/// sq_signature_t revocation; -/// -/// ctx = sq_context_new ("org.sequoia-pgp.tests", NULL); -/// -/// builder = sq_tpk_builder_default (); -/// sq_tpk_builder_set_cipher_suite (&builder, SQ_TPK_CIPHER_SUITE_CV25519); -/// sq_tpk_builder_generate (ctx, builder, &tpk, &revocation); -/// assert (tpk); -/// assert (revocation); -/// sq_signature_free (revocation); /* Free the generated one. */ -/// -/// revocation = sq_tpk_revoke (ctx, tpk, -/// SQ_REASON_FOR_REVOCATION_KEY_COMPROMISED, -/// "It was the maid :/"); -/// assert (revocation); -/// -/// sq_packet_t packet = sq_signature_to_packet (revocation); -/// tpk = sq_tpk_merge_packets (ctx, tpk, &packet, 1); -/// assert (tpk); -/// -/// sq_revocation_status_t rs = sq_tpk_revocation_status (tpk); -/// assert (sq_revocation_status_variant (rs) == SQ_REVOCATION_STATUS_REVOKED); -/// sq_revocation_status_free (rs); -/// -/// sq_tpk_free (tpk); -/// sq_context_free (ctx); -/// ``` -#[no_mangle] -pub extern "system" fn sq_tpk_revoke(ctx: Option<&mut Context>, - tpk: Option<&mut TPK>, - code: c_int, - reason: Option<*const c_char>) - -> *mut packet::Signature -{ - let ctx = ctx.expect("Context is NULL"); - let tpk = tpk.expect("TPK is NULL"); - let code = int_to_reason_for_revocation(code); - let reason = if let Some(reason) = reason { - unsafe { - CStr::from_ptr(reason).to_bytes() - } - } else { - b"" - }; - - fry_box!(ctx, tpk.revoke(code, reason)) -} - -/// Adds a revocation certificate to the tpk. -/// -/// This function consumes the tpk. -/// -/// # Example -/// -/// ```c -/// #include <assert.h> -/// #include <sequoia.h> -/// -/// sq_context_t ctx; -/// sq_tpk_builder_t builder; -/// sq_tpk_t tpk; -/// sq_signature_t revocation; -/// -/// ctx = sq_context_new ("org.sequoia-pgp.tests", NULL); -/// -/// builder = sq_tpk_builder_default (); -/// sq_tpk_builder_set_cipher_suite (&builder, SQ_TPK_CIPHER_SUITE_CV25519); -/// sq_tpk_builder_generate (ctx, builder, &tpk, &revocation); -/// assert (tpk); -/// assert (revocation); -/// sq_signature_free (revocation); /* Free the generated one. */ -/// -/// tpk = sq_tpk_revoke_in_place (ctx, tpk, -/// SQ_REASON_FOR_REVOCATION_KEY_COMPROMISED, -/// "It was the maid :/"); -/// -/// sq_revocation_status_t rs = sq_tpk_revocation_status (tpk); -/// assert (sq_revocation_status_variant (rs) == SQ_REVOCATION_STATUS_REVOKED); -/// sq_revocation_status_free (rs); -/// -/// sq_tpk_free (tpk); -/// sq_context_free (ctx); -/// ``` -#[no_mangle] -pub extern "system" fn sq_tpk_revoke_in_place(ctx: Option<&mut Context>, - tpk: *mut TPK, - code: c_int, - reason: Option<*const c_char>) - -> *mut TPK -{ - let ctx = ctx.expect("Context is NULL"); - assert!(!tpk.is_null()); - let tpk = unsafe { - Box::from_raw(tpk) - }; - let code = int_to_reason_for_revocation(code); - let reason = if let Some(reason) = reason { - unsafe { - CStr::from_ptr(reason).to_bytes() - } - } else { - b"" - }; - - fry_box!(ctx, tpk.revoke_in_place(code, reason)) -} - -/// Returns whether the TPK has expired. -#[no_mangle] -pub extern "system" fn sq_tpk_expired(tpk: Option<&TPK>) - -> c_int { - let tpk = tpk.expect("TPK is NULL"); - - tpk.expired() as c_int -} - -/// Returns whether the TPK has expired. -#[no_mangle] -pub extern "system" fn sq_tpk_expired_at(tpk: Option<&TPK>, when: time_t) - -> c_int { - let tpk = tpk.expect("TPK is NULL"); - tpk.expired_at(time::at(time::Timespec::new(when as i64, 0))) as c_int -} - -/// Returns whether the TPK is alive. -#[no_mangle] -pub extern "system" fn sq_tpk_alive(tpk: Option<&TPK>) - -> c_int { - let tpk = tpk.expect("TPK is NULL"); - - tpk.alive() as c_int -} - -/// Returns whether the TPK is alive at the specified time. -#[no_mangle] -pub extern "system" fn sq_tpk_alive_at(tpk: Option<&TPK>, when: time_t) - -> c_int { - let tpk = tpk.expect("TPK is NULL"); - tpk.alive_at(time::at(time::Timespec::new(when as i64, 0))) as c_int -} - -/// Changes the TPK's expiration. -/// -/// Expiry is when the key should expire in seconds relative to the -/// key's creation (not the current time). -/// -/// This function consumes `tpk` and returns a new `TPK`. -#[no_mangle] -pub extern "system" fn sq_tpk_set_expiry(ctx: Option<&mut Context>, - tpk: *mut TPK, expiry: u32) - -> *mut TPK { - let ctx = ctx.expect("CTX is NULL"); - assert!(!tpk.is_null()); - let tpk = unsafe { - Box::from_raw(tpk) - }; - - fry_box!(ctx, tpk.set_expiry_in_seconds(expiry)) -} - -/// Returns whether the TPK includes any secret key material. -#[no_mangle] -pub extern "system" fn sq_tpk_is_tsk(tpk: Option<&TPK>) - -> c_int { - let tpk = tpk.expect("TPK is NULL"); - tpk.is_tsk() as c_int -} - -/// Returns an iterator over the TPK's user id bindings. -#[no_mangle] -pub extern "system" fn sq_tpk_primary_user_id(tpk: Option<&TPK>) - -> *mut c_char -{ - let tpk = tpk.expect("TPK is NULL"); - if let Some(binding) = tpk.userids().nth(0) { - CString::new(binding.userid().userid()) - .unwrap() // Errors only on internal nul bytes. - .into_raw() - } else { - ptr::null_mut() - } -} - fn revocation_status_to_int(rs: &RevocationStatus) -> c_int { match rs { RevocationStatus::Revoked(_) => 0, @@ -550,287 +128,6 @@ pub extern "system" fn sq_revocation_status_free( }; } -/* UserIDBinding */ - -/// Returns the user id. -/// -/// This function may fail and return NULL if the user id contains an -/// interior NUL byte. We do this rather than complicate the API, as -/// there is no valid use for such user ids; they must be malicious. -/// -/// The caller must free the returned value. -#[no_mangle] -pub extern "system" fn sq_user_id_binding_user_id( - binding: Option<&UserIDBinding>) - -> *mut c_char -{ - let binding = binding.expect("Binding is NULL"); - - if let Ok(c_str) = CString::new(binding.userid().userid()) { - c_str.into_raw() - } else { - ptr::null_mut() - } -} - -/// Returns a reference to the self-signature, if any. -#[no_mangle] -pub extern "system" fn sq_user_id_binding_selfsig( - binding: Option<&UserIDBinding>) - -> Option<&Signature> -{ - let binding = binding.expect("Binding is NULL"); - binding.binding_signature() -} - - -/* UserIDBindingIter */ - -/// Returns an iterator over the TPK's user id bindings. -#[no_mangle] -pub extern "system" fn sq_tpk_user_id_binding_iter(tpk: Option<&TPK>) - -> *mut UserIDBindingIter -{ - let tpk = tpk.expect("TPK is NULL"); - box_raw!(tpk.userids()) -} - -/// Frees a sq_user_id_binding_iter_t. -#[no_mangle] -pub extern "system" fn sq_user_id_binding_iter_free( - iter: *mut UserIDBindingIter) -{ - if iter.is_null() { return }; - unsafe { - drop(Box::from_raw(iter)) - }; -} - -/// Returns the next `UserIDBinding`. -#[no_mangle] -pub extern "system" fn sq_user_id_binding_iter_next<'a>( - iter: Option<&mut UserIDBindingIter<'a>>) - -> Option<&'a UserIDBinding> -{ - let iter = iter.expect("Iterator is NULL"); - iter.next() -} - -/* tpk::KeyIter. */ - -/// Wrapers a KeyIter for export via the FFI. -pub struct KeyIterWrapper<'a> { - iter: KeyIter<'a>, - rso: Option<RevocationStatus<'a>>, -} - -/// Returns an iterator over the TPK's keys. -/// -/// This iterates over both the primary key and any subkeys. -#[no_mangle] -pub extern "system" fn sq_tpk_key_iter(tpk: Option<&TPK>) - -> *mut KeyIterWrapper -{ - let tpk = tpk.expect("TPK is NULL"); - box_raw!(KeyIterWrapper { - iter: tpk.keys(), - rso: None, - }) -} - -/// Frees a sq_tpk_key_iter_t. -#[no_mangle] -pub extern "system" fn sq_tpk_key_iter_free( - iter: *mut KeyIterWrapper) -{ - if iter.is_null() { return }; - unsafe { - drop(Box::from_raw(iter)) - }; -} - -/// Returns the next key. Returns NULL if there are no more elements. -/// -/// If sigo is not NULL, stores the current self-signature (if any) in -/// *sigo. (Note: subkeys always have signatures, but a primary key -/// may not have a direct signature, and there might not be any user -/// ids.) -/// -/// If rso is not NULL, this stores the key's revocation status in -/// *rso. -#[no_mangle] -pub extern "system" fn sq_tpk_key_iter_next<'a>( - iter_wrapper: Option<&'a mut KeyIterWrapper<'a>>, - sigo: Option<&mut Option<&'a packet::Signature>>, - rso: Option<&mut &'a RevocationStatus<'a>>) - -> Option<&'a packet::Key> -{ - let iter_wrapper = iter_wrapper.expect("Iterator is NULL"); - iter_wrapper.rso = None; - - if let Some((sig, rs, key)) = iter_wrapper.iter.next() { - if let Some(ptr) = sigo { - *ptr = sig; - } - - if let Some(ptr) = rso { - iter_wrapper.rso = Some(rs); - *ptr = iter_wrapper.rso.as_ref().unwrap(); - } - - Some(key) - } else { - None - } -} - -/* TPKBuilder */ - -/// Creates a default `sq_tpk_builder_t`. -/// -/// # Example -/// -/// ```c -/// #include <assert.h> -/// #include <sequoia.h> -/// -/// sq_context_t ctx; -/// sq_tpk_builder_t builder; -/// sq_tpk_t tpk; -/// sq_signature_t revocation; -/// -/// ctx = sq_context_new ("org.sequoia-pgp.tests", NULL); -/// -/// builder = sq_tpk_builder_default (); -/// sq_tpk_builder_set_cipher_suite (&builder, SQ_TPK_CIPHER_SUITE_CV25519); -/// sq_tpk_builder_add_userid (&builder, "some@example.org"); -/// sq_tpk_builder_add_signing_subkey (&builder); -/// sq_tpk_builder_add_encryption_subkey (&builder); -/// sq_tpk_builder_generate (ctx, builder, &tpk, &revocation); -/// assert (tpk); -/// assert (revocation); -/// ``` -#[no_mangle] -pub extern "system" fn sq_tpk_builder_default() -> *mut TPKBuilder { - box_raw!(TPKBuilder::default()) -} - -/// Generates a key compliant to [Autocrypt Level 1]. -/// -/// [Autocrypt Level 1]: https://autocrypt.org/level1.html -#[no_mangle] -pub extern "system" fn sq_tpk_builder_autocrypt() -> *mut TPKBuilder { - use self::openpgp::autocrypt::Autocrypt; - box_raw!(TPKBuilder::autocrypt(Autocrypt::V1)) -} - -/// Frees an `sq_tpk_builder_t`. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_free(tpkb: *mut TPKBuilder) -{ - if tpkb.is_null() { - return - } - unsafe { - drop(Box::from_raw(tpkb)); - } -} - -/// Sets the encryption and signature algorithms for primary and all -/// subkeys. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_set_cipher_suite - (tpkb: Option<&mut *mut TPKBuilder>, cs: c_int) -{ - use self::CipherSuite::*; - let tpkb = tpkb.expect("TPKB is NULL"); - assert!(! tpkb.is_null()); - let tpkb_ = unsafe { Box::from_raw(*tpkb) }; - let cs = match cs { - 0 => Cv25519, - 1 => RSA3k, - n => panic!("Bad ciphersuite: {}", n), - }; - let tpkb_ = tpkb_.set_cipher_suite(cs); - *tpkb = box_raw!(tpkb_); -} - -/// Adds a new user ID. The first user ID added replaces the default -/// ID that is just the empty string. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_add_userid - (tpkb: Option<&mut *mut TPKBuilder>, uid: *const c_char) -{ - let tpkb = tpkb.expect("TPKB is NULL"); - assert!(!tpkb.is_null()); - let tpkb_ = unsafe { Box::from_raw(*tpkb) }; - let uid = unsafe { CStr::from_ptr(uid).to_string_lossy().to_string() }; - let tpkb_ = tpkb_.add_userid(uid.as_ref()); - *tpkb = box_raw!(tpkb_); -} - -/// Adds a signing capable subkey. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_add_signing_subkey - (tpkb: Option<&mut *mut TPKBuilder>) -{ - let tpkb = tpkb.expect("TPKB is NULL"); - assert!(!tpkb.is_null()); - let tpkb_ = unsafe { Box::from_raw(*tpkb) }; - let tpkb_ = tpkb_.add_signing_subkey(); - *tpkb = box_raw!(tpkb_); -} - -/// Adds an encryption capable subkey. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_add_encryption_subkey - (tpkb: Option<&mut *mut TPKBuilder>) -{ - let tpkb = tpkb.expect("TPKB is NULL"); - assert!(!tpkb.is_null()); - let tpkb_ = unsafe { Box::from_raw(*tpkb) }; - let tpkb_ = tpkb_.add_encryption_subkey(); - *tpkb = box_raw!(tpkb_); -} - -/// Adds an certification capable subkey. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_add_certification_subkey - (tpkb: Option<&mut *mut TPKBuilder>) -{ - let tpkb = tpkb.expect("TPKB is NULL"); - assert!(!tpkb.is_null()); - let tpkb_ = unsafe { Box::from_raw(*tpkb) }; - let tpkb_ = tpkb_.add_certification_subkey(); - *tpkb = box_raw!(tpkb_); -} - -/// Generates the actual TPK. -/// -/// Consumes `tpkb`. -#[no_mangle] -pub extern "system" fn sq_tpk_builder_generate - (ctx: Option<&mut Context>, tpkb: *mut TPKBuilder, - tpk_out: Option<&mut *mut TPK>, - revocation_out: Option<&mut *mut Signature>) - -> Status -{ - let ctx = ctx.expect("CTX is NULL"); - assert!(!tpkb.is_null()); - let tpk_out = tpk_out.expect("TPK is NULL"); - let revocation_out = revocation_out.expect("REVOCATION is NULL"); - let tpkb = unsafe { Box::from_raw(tpkb) }; - match tpkb.generate() { - Ok((tpk, revocation)) => { - *tpk_out = box_raw!(tpk); - *revocation_out = box_raw!(revocation); - Status::Success - }, - Err(e) => fry_status!(ctx, Err::<(), failure::Error>(e)), - } -} - - /* TSK */ /// Generates a new RSA 3072 bit key with UID `primary_uid`. |