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