1 //! `KeyAmalgamation`s.
2 //!
3 //!
4 //! Wraps [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`].
5 //!
6 //! [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`]: ../../../sequoia_openpgp/cert/key_amalgamation/struct.KeyAmalgamation.html
7 
8 use std::slice;
9 use libc::{size_t, time_t};
10 
11 extern crate sequoia_openpgp as openpgp;
12 use self::openpgp::packet::key;
13 use self::openpgp::cert::amalgamation::ValidAmalgamation;
14 use self::openpgp::cert::amalgamation::ValidateAmalgamation;
15 use self::openpgp::crypto;
16 
17 use super::packet::key::Key;
18 use super::packet::signature::Signature;
19 use super::policy::Policy;
20 use super::revocation_status::RevocationStatus;
21 
22 use crate::error::Status;
23 use crate::Maybe;
24 use crate::MoveIntoRaw;
25 use crate::MoveResultIntoRaw;
26 use crate::RefRaw;
27 use crate::MoveFromRaw;
28 use crate::maybe_time;
29 
30 /// A local alias to appease the proc macro transformation.
31 type ErasedKeyAmalgamation<'a> =
32     openpgp::cert::amalgamation::key::ErasedKeyAmalgamation<'a, key::UnspecifiedParts>;
33 
34 /// A `KeyAmalgamation` holds a `Key` and associated data.
35 ///
36 /// Wraps [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`].
37 ///
38 /// [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`]: ../../../sequoia_openpgp/cert/key_amalgamation/struct.KeyAmalgamation.html
39 #[crate::ffi_wrapper_type(prefix = "pgp_",
40                      derive = "Clone, Debug")]
41 pub struct KeyAmalgamation<'a>(ErasedKeyAmalgamation<'a>);
42 
43 /// A local alias to appease the proc macro transformation.
44 type ValidErasedKeyAmalgamation<'a> =
45     openpgp::cert::amalgamation::key::ValidErasedKeyAmalgamation<'a, key::UnspecifiedParts>;
46 
47 /// Returns a reference to the `Key`.
48 #[::sequoia_ffi_macros::extern_fn] #[no_mangle]
pgp_key_amalgamation_key<'a>(ka: *const KeyAmalgamation<'a>) -> *const Key49 pub extern "C" fn pgp_key_amalgamation_key<'a>(ka: *const KeyAmalgamation<'a>)
50     -> *const Key
51 {
52     let ka = ka.ref_raw();
53 
54     ka.key().parts_as_unspecified().role_as_unspecified()
55         .move_into_raw()
56 }
57 
58 /// A `ValidKeyAmalgamation` holds a `Key` and associated data
59 /// including a policy and a reference time.
60 ///
61 /// Wraps [`sequoia-openpgp::cert::key_amalgamation::ValidKeyAmalgamation`].
62 ///
63 /// [`sequoia-openpgp::cert::key_amalgamation::ValidKeyAmalgamation`]: ../../../sequoia_openpgp/cert/key_amalgamation/struct.ValidKeyAmalgamation.html
64 #[crate::ffi_wrapper_type(prefix = "pgp_",
65                      derive = "Clone, Debug")]
66 pub struct ValidKeyAmalgamation<'a>(ValidErasedKeyAmalgamation<'a>);
67 
68 /// Returns a reference to the `Key`.
69 #[::sequoia_ffi_macros::extern_fn] #[no_mangle]
pgp_valid_key_amalgamation_key<'a>(ka: *const ValidKeyAmalgamation<'a>) -> *const Key70 pub extern "C" fn pgp_valid_key_amalgamation_key<'a>(ka: *const ValidKeyAmalgamation<'a>)
71     -> *const Key
72 {
73     let ka = ka.ref_raw();
74 
75     ka.key().parts_as_unspecified().role_as_unspecified()
76         .move_into_raw()
77 }
78 
79 /// Returns the Key Amalgamation's revocation status.
80 #[::sequoia_ffi_macros::extern_fn] #[no_mangle]
pgp_valid_key_amalgamation_revocation_status<'a>(ka: *const ValidKeyAmalgamation<'a>) -> *mut RevocationStatus<'a>81 pub extern "C" fn pgp_valid_key_amalgamation_revocation_status<'a>(ka: *const ValidKeyAmalgamation<'a>)
82     -> *mut RevocationStatus<'a>
83 {
84     ka.ref_raw()
85         .revocation_status()
86         .move_into_raw()
87 }
88 
89 /// Returns the Key Amalgamation's binding signature.
90 #[::sequoia_ffi_macros::extern_fn] #[no_mangle]
pgp_valid_key_amalgamation_binding_signature<'a>(ka: *const ValidKeyAmalgamation<'a>) -> *const Signature91 pub extern "C" fn pgp_valid_key_amalgamation_binding_signature<'a>(ka: *const ValidKeyAmalgamation<'a>)
92     -> *const Signature
93 {
94     ka.ref_raw()
95         .binding_signature()
96         .move_into_raw()
97 }
98 
99 /// Creates one or more self-signatures that when merged with the
100 /// certificate cause the key to expire at the specified time.
101 ///
102 /// The returned buffer must be freed using libc's allocator.
103 #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
pgp_valid_key_amalgamation_set_expiration_time( errp: Option<&mut *mut crate::error::Error>, ka: *const ValidKeyAmalgamation, primary_signer: *mut Box<dyn crypto::Signer>, expiry: time_t, sigs: *mut *mut *mut Signature, sig_count: *mut size_t) -> Status104 fn pgp_valid_key_amalgamation_set_expiration_time(
105     errp: Option<&mut *mut crate::error::Error>,
106     ka: *const ValidKeyAmalgamation,
107     primary_signer: *mut Box<dyn crypto::Signer>,
108     expiry: time_t,
109     sigs: *mut *mut *mut Signature, sig_count: *mut size_t)
110     -> Status
111 {
112     ffi_make_fry_from_errp!(errp);
113 
114     let ka = ka.ref_raw();
115     let signer = ffi_param_ref_mut!(primary_signer);
116     let expiry = maybe_time(expiry);
117     let sigs = ffi_param_ref_mut!(sigs);
118     let sig_count = ffi_param_ref_mut!(sig_count);
119 
120     match ka.set_expiration_time(signer.as_mut(), expiry) {
121         Ok(new_sigs) => {
122             let buffer = unsafe {
123                 libc::calloc(new_sigs.len(), std::mem::size_of::<*mut Signature>())
124                     as *mut *mut Signature
125             };
126             let sl = unsafe {
127                 slice::from_raw_parts_mut(buffer, new_sigs.len())
128             };
129             *sig_count = new_sigs.len();
130             sl.iter_mut().zip(new_sigs.into_iter())
131                 .for_each(|(e, sig)| *e = sig.move_into_raw());
132             *sigs = buffer;
133             Status::Success
134         }
135         Err(err) => {
136             Err::<(), anyhow::Error>(err).move_into_raw(errp)
137         }
138     }
139 }
140 
141 /// Changes the policy applied to the `ValidKeyAmalgamation`.
142 ///
143 /// This consumes the key amalgamation.
144 #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
pgp_valid_key_amalgamation_with_policy<'a>(errp: Option<&mut *mut crate::error::Error>, ka: *mut ValidKeyAmalgamation<'a>, policy: *const Policy, time: time_t) -> Maybe<ValidKeyAmalgamation<'a>>145 fn pgp_valid_key_amalgamation_with_policy<'a>(errp: Option<&mut *mut crate::error::Error>,
146                                               ka: *mut ValidKeyAmalgamation<'a>,
147                                               policy: *const Policy,
148                                               time: time_t)
149     -> Maybe<ValidKeyAmalgamation<'a>>
150 {
151     ffi_make_fry_from_errp!(errp);
152 
153     let ka = ka.move_from_raw();
154     let policy = policy.ref_raw();
155     let time = maybe_time(time);
156 
157     ka.with_policy(&**policy, time).move_into_raw(errp)
158 }
159