diff options
author | Neal H. Walfield <neal@pep.foundation> | 2020-01-31 14:20:53 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2020-01-31 15:59:16 +0100 |
commit | a464ce819ccd1fa07ff8c6d0be74cff5eec5cf34 (patch) | |
tree | 31ed9d18b9c7802a93b4e4c8e6e85d1121b201d8 /openpgp-ffi/src | |
parent | b9b6533bd5394cd5cdb6b91b5c5ca7a02e3ea199 (diff) |
openpgp: Add a policy object.
- Change all functions that need to evaluate the validity of a
signature (either directly or indirectly to take a policy object.
- Use the policy object to allow the user to place additional
constraints on a signature's validity.
- This addresses the first half of #274 (it introduces the policy
object, but does not yet implement any policy).
Diffstat (limited to 'openpgp-ffi/src')
-rw-r--r-- | openpgp-ffi/src/cert.rs | 54 | ||||
-rw-r--r-- | openpgp-ffi/src/common.rs | 1 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 26 | ||||
-rw-r--r-- | openpgp-ffi/src/policy.rs | 36 |
4 files changed, 95 insertions, 22 deletions
diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs index 65c56f9f..e2a58c03 100644 --- a/openpgp-ffi/src/cert.rs +++ b/openpgp-ffi/src/cert.rs @@ -41,6 +41,7 @@ use super::packet::signature::Signature; use super::packet_pile::PacketPile; use super::tsk::TSK; use super::revocation_status::RevocationStatus; +use super::policy::Policy; use crate::Maybe; use crate::RefRaw; @@ -168,10 +169,13 @@ fn pgp_cert_primary_key(cert: *const Cert) -> *const Key { /// If `when` is 0, then returns the Cert's revocation status as of the /// time of the call. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" -fn pgp_cert_revoked(cert: *const Cert, when: time_t) +fn pgp_cert_revoked(cert: *const Cert, policy: *const Policy, when: time_t) -> *mut RevocationStatus<'static> { - cert.ref_raw().revoked(maybe_time(when)).move_into_raw() + let policy = &**policy.ref_raw(); + cert.ref_raw() + .revoked(policy, maybe_time(when)) + .move_into_raw() } fn int_to_reason_for_revocation(code: c_int) -> ReasonForRevocation { @@ -203,6 +207,7 @@ fn int_to_reason_for_revocation(code: c_int) -> ReasonForRevocation { /// pgp_key_t primary_key; /// pgp_key_pair_t primary_keypair; /// pgp_signer_t primary_signer; +/// pgp_policy_t policy = pgp_standard_policy (); /// /// builder = pgp_cert_builder_new (); /// pgp_cert_builder_set_cipher_suite (&builder, PGP_CERT_CIPHER_SUITE_CV25519); @@ -227,11 +232,12 @@ fn int_to_reason_for_revocation(code: c_int) -> ReasonForRevocation { /// cert = pgp_cert_merge_packets (NULL, cert, &packet, 1); /// assert (cert); /// -/// pgp_revocation_status_t rs = pgp_cert_revoked (cert, 0); +/// pgp_revocation_status_t rs = pgp_cert_revoked (cert, policy, 0); /// assert (pgp_revocation_status_variant (rs) == PGP_REVOCATION_STATUS_REVOKED); /// pgp_revocation_status_free (rs); /// /// pgp_cert_free (cert); +/// pgp_policy_free (policy); /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_revoke(errp: Option<&mut *mut crate::error::Error>, @@ -273,6 +279,7 @@ fn pgp_cert_revoke(errp: Option<&mut *mut crate::error::Error>, /// pgp_key_t primary_key; /// pgp_key_pair_t primary_keypair; /// pgp_signer_t primary_signer; +/// pgp_policy_t policy = pgp_standard_policy (); /// /// builder = pgp_cert_builder_new (); /// pgp_cert_builder_set_cipher_suite (&builder, PGP_CERT_CIPHER_SUITE_CV25519); @@ -293,11 +300,12 @@ fn pgp_cert_revoke(errp: Option<&mut *mut crate::error::Error>, /// pgp_signer_free (primary_signer); /// pgp_key_pair_free (primary_keypair); /// -/// pgp_revocation_status_t rs = pgp_cert_revoked (cert, 0); +/// pgp_revocation_status_t rs = pgp_cert_revoked (cert, policy, 0); /// assert (pgp_revocation_status_variant (rs) == PGP_REVOCATION_STATUS_REVOKED); /// pgp_revocation_status_free (rs); /// /// pgp_cert_free (cert); +/// pgp_policy_free (policy); /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_revoke_in_place(errp: Option<&mut *mut crate::error::Error>, @@ -324,9 +332,12 @@ fn pgp_cert_revoke_in_place(errp: Option<&mut *mut crate::error::Error>, /// If `when` is 0, then the current time is used. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_alive(errp: Option<&mut *mut crate::error::Error>, - cert: *const Cert, when: time_t) -> Status { + cert: *const Cert, policy: *const Policy, when: time_t) + -> Status +{ + let policy = &**policy.ref_raw(); ffi_make_fry_from_errp!(errp); - ffi_try_status!(cert.ref_raw().alive(maybe_time(when))) + ffi_try_status!(cert.ref_raw().alive(policy, maybe_time(when))) } /// Changes the Cert's expiration. @@ -338,14 +349,17 @@ fn pgp_cert_alive(errp: Option<&mut *mut crate::error::Error>, #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_set_expiry(errp: Option<&mut *mut crate::error::Error>, cert: *mut Cert, + policy: *const Policy, primary_signer: *mut Box<dyn crypto::Signer>, expiry: u32) - -> Maybe<Cert> { + -> Maybe<Cert> +{ + let policy = &**policy.ref_raw(); let cert = cert.move_from_raw(); let signer = ffi_param_ref_mut!(primary_signer); - cert.set_expiry(signer.as_mut(), - Some(std::time::Duration::new(expiry as u64, 0))) + cert.set_expiry(policy, signer.as_mut(), + Some(std::time::Duration::new(expiry as u64, 0))) .move_into_raw(errp) } @@ -359,11 +373,12 @@ fn pgp_cert_is_tsk(cert: *const Cert) /// Returns an iterator over the Cert's user id bindings. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" -fn pgp_cert_primary_user_id(cert: *const Cert) +fn pgp_cert_primary_user_id(cert: *const Cert, policy: *const Policy) -> *mut c_char { let cert = cert.ref_raw(); - if let Some(binding) = cert.primary_userid(None) { + let policy = &**policy.ref_raw(); + if let Some(binding) = cert.primary_userid(policy, None) { ffi_return_string!(binding.userid().value()) } else { ptr::null_mut() @@ -392,11 +407,13 @@ pub extern "C" fn pgp_user_id_binding_user_id( /// Returns a reference to the self-signature, if any. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_user_id_binding_selfsig( - binding: *const UserIDBinding) + binding: *const UserIDBinding, + policy: *const Policy) -> Maybe<Signature> { let binding = ffi_param_ref!(binding); - binding.binding_signature(None).move_into_raw() + let policy = &**policy.ref_raw(); + binding.binding_signature(policy, None).move_into_raw() } @@ -505,9 +522,11 @@ pub extern "C" fn pgp_cert_key_iter_unencrypted_secret<'a>( #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_cert_key_iter_policy<'a>( iter_wrapper: *mut KeyIterWrapper<'a>, + policy: *const Policy, when: time_t) -> *mut ValidKeyIterWrapper<'static> { + let policy = policy.ref_raw(); let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); if iter_wrapper.next_called { panic!("Can't change KeyIter filter after iterating."); @@ -517,7 +536,9 @@ pub extern "C" fn pgp_cert_key_iter_policy<'a>( let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); box_raw!(ValidKeyIterWrapper { - iter: unsafe { std::mem::transmute(tmp.policy(maybe_time(when))) }, + iter: unsafe { + std::mem::transmute(tmp.set_policy(&**policy, maybe_time(when))) + }, next_called: false, }) } @@ -561,7 +582,8 @@ pub struct ValidKeyIterWrapper<'a> { /// subkeys that are valid (i.e., have a self-signature at time /// `when`). #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_cert_valid_key_iter(cert: *const Cert, when: time_t) +pub extern "C" fn pgp_cert_valid_key_iter(cert: *const Cert, + policy: *const Policy, when: time_t) -> *mut ValidKeyIterWrapper<'static> { let cert = cert.ref_raw(); @@ -570,7 +592,7 @@ pub extern "C" fn pgp_cert_valid_key_iter(cert: *const Cert, when: time_t) next_called: false, }); - pgp_cert_key_iter_policy(iter, when) + pgp_cert_key_iter_policy(iter, policy, when) } /// Frees a pgp_cert_key_iter_t. diff --git a/openpgp-ffi/src/common.rs b/openpgp-ffi/src/common.rs index c22e5c9e..592c4776 100644 --- a/openpgp-ffi/src/common.rs +++ b/openpgp-ffi/src/common.rs @@ -342,3 +342,4 @@ pub mod serialize; pub mod cert; pub mod tsk; pub mod revocation_status; +pub mod policy; diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index e0a5e7c4..0fb0bec9 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -50,6 +50,7 @@ use super::super::{ packet::signature::Signature, packet::key::Key, parse::PacketParser, + policy::Policy, revocation_status::RevocationStatus, }; @@ -509,6 +510,7 @@ impl VerificationHelper for VHelper { /// pgp_reader_t plaintext; /// uint8_t buf[128]; /// ssize_t nread; +/// pgp_policy_t policy = pgp_standard_policy (); /// /// cert = pgp_cert_from_file (NULL, "../openpgp/tests/data/keys/testy.pgp"); /// assert(cert); @@ -520,7 +522,7 @@ impl VerificationHelper for VHelper { /// struct verify_cookie cookie = { /// .key = cert, /* Move. */ /// }; -/// plaintext = pgp_verifier_new (NULL, source, +/// plaintext = pgp_verifier_new (NULL, policy, source, /// get_public_keys_cb, check_cb, /// &cookie, 1554542219); /// assert (source); @@ -532,11 +534,13 @@ impl VerificationHelper for VHelper { /// /// pgp_reader_free (plaintext); /// pgp_reader_free (source); +/// pgp_policy_free (policy); /// return 0; /// } /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, + policy: *const Policy, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, check: CheckCallback, @@ -544,9 +548,10 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, time: time_t) -> Maybe<io::Reader> { + let policy = policy.ref_raw().as_ref(); let helper = VHelper::new(get_public_keys, check, cookie); - Verifier::from_reader(input.ref_mut_raw(), helper, maybe_time(time)) + Verifier::from_reader(policy, input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) } @@ -620,6 +625,7 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, /// pgp_reader_t plaintext; /// uint8_t buf[128]; /// ssize_t nread; +/// pgp_policy_t policy = pgp_standard_policy (); /// /// cert = pgp_cert_from_file (NULL, /// "../openpgp/tests/data/keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp"); @@ -637,7 +643,7 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, /// struct verify_cookie cookie = { /// .key = cert, /* Move. */ /// }; -/// plaintext = pgp_detached_verifier_new (NULL, signature, source, +/// plaintext = pgp_detached_verifier_new (NULL, policy, signature, source, /// get_public_keys_cb, check_cb, /// &cookie, 1554542219); /// assert (source); @@ -650,11 +656,13 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, /// pgp_reader_free (plaintext); /// pgp_reader_free (source); /// pgp_reader_free (signature); +/// pgp_policy_free (policy); /// return 0; /// } /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_detached_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, + policy: *const Policy, signature_input: *mut io::Reader, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, @@ -663,9 +671,11 @@ fn pgp_detached_verifier_new<'a>(errp: Option<&mut *mut crate::error::Error>, time: time_t) -> Maybe<io::Reader> { + let policy = policy.ref_raw().as_ref(); + let helper = VHelper::new(get_public_keys, check, cookie); - DetachedVerifier::from_reader(signature_input.ref_mut_raw(), + DetachedVerifier::from_reader(policy, signature_input.ref_mut_raw(), input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) @@ -897,6 +907,7 @@ impl DecryptionHelper for DHelper { /// pgp_reader_t plaintext; /// uint8_t buf[128]; /// ssize_t nread; +/// pgp_policy_t policy = pgp_standard_policy (); /// /// cert = pgp_cert_from_file ( /// NULL, "../openpgp/tests/data/keys/testy-private.pgp"); @@ -910,7 +921,7 @@ impl DecryptionHelper for DHelper { /// .key = cert, /// .decrypt_called = 0, /// }; -/// plaintext = pgp_decryptor_new (NULL, source, +/// plaintext = pgp_decryptor_new (NULL, policy, source, /// get_public_keys_cb, decrypt_cb, /// check_cb, NULL, &cookie, 1554542219); /// assert (plaintext); @@ -923,11 +934,13 @@ impl DecryptionHelper for DHelper { /// pgp_reader_free (plaintext); /// pgp_reader_free (source); /// pgp_cert_free (cert); +/// pgp_policy_free (policy); /// return 0; /// } /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_decryptor_new<'a>(errp: Option<&mut *mut crate::error::Error>, + policy: *const Policy, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, decrypt: DecryptCallback, @@ -937,10 +950,11 @@ fn pgp_decryptor_new<'a>(errp: Option<&mut *mut crate::error::Error>, time: time_t) -> Maybe<io::Reader> { + let policy = policy.ref_raw().as_ref(); let helper = DHelper::new( get_public_keys, decrypt, check, inspect, cookie); - Decryptor::from_reader(input.ref_mut_raw(), helper, maybe_time(time)) + Decryptor::from_reader(policy, input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) } diff --git a/openpgp-ffi/src/policy.rs b/openpgp-ffi/src/policy.rs new file mode 100644 index 00000000..2c00ae52 --- /dev/null +++ b/openpgp-ffi/src/policy.rs @@ -0,0 +1,36 @@ +//! Policy objects. +//! +//! This module allows the caller to specify low-level policy like +//! what algorithms are allowed. +//! +//! Wraps the policy object functions, see +//! [`sequoia-openpgp::policy`]. +//! +//! [`sequoia-openpgp::policy`]: ../../sequoia_openpgp/policy/index.html + +extern crate sequoia_openpgp as openpgp; + +use crate::MoveIntoRaw; + +use self::openpgp::policy; + +/// A policy object. +#[crate::ffi_wrapper_type( + prefix = "pgp_", + derive = "Clone, Debug")] +pub struct Policy(Box<policy::Policy>); + +/// A StandardPolicy object. +#[crate::ffi_wrapper_type( + prefix = "pgp_", + derive = "Clone, Debug")] +pub struct StandardPolicy(policy::StandardPolicy); + +/// Returns a new standard policy. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_standard_policy() + -> *mut Policy +{ + let p : Box<policy::Policy> = Box::new(policy::StandardPolicy::new()); + p.move_into_raw() +} |