diff options
35 files changed, 638 insertions, 262 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index 56c131fb..78978161 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -51,7 +51,7 @@ fn main() { # fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) # -> openpgp::Result<()> { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().alive().revoked(false).for_signing().nth(0).unwrap(). +# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). # key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. @@ -196,7 +196,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) # -> openpgp::Result<()> { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().alive().revoked(false).for_signing().nth(0).unwrap(). +# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). # key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. @@ -341,7 +341,7 @@ implements [`io::Write`], and we simply write the plaintext to it. fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) -> openpgp::Result<()> { // Get the keypair to do the signing from the Cert. - let keypair = tsk.keys().alive().revoked(false).for_signing().nth(0).unwrap(). + let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). key().clone().mark_parts_secret().unwrap().into_keypair()?; // Start streaming an OpenPGP message. @@ -497,7 +497,7 @@ Verified data can be read from this using [`io::Read`]. # fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) # -> openpgp::Result<()> { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().alive().revoked(false).for_signing().nth(0).unwrap(). +# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). # key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 9f4c3a0a..f6cb4b48 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -51,7 +51,7 @@ fn main() { # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().alive().revoked(false) +# recipient.keys().policy(None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); @@ -192,7 +192,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().alive().revoked(false) +# recipient.keys().policy(None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); @@ -333,7 +333,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) -> openpgp::Result<()> { // Build a vector of recipients to hand to Encryptor. let mut recipients = - recipient.keys().alive().revoked(false) + recipient.keys().policy(None).alive().revoked(false) .for_transport_encryption() .map(|ka| ka.key().into()) .collect::<Vec<_>>(); @@ -488,7 +488,7 @@ Decrypted data can be read from this using [`io::Read`]. # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().alive().revoked(false) +# recipient.keys().policy(None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs index 2b9252cc..0f824d60 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -74,7 +74,7 @@ impl<'a> Helper<'a> { // Map (sub)KeyIDs to secrets. let mut keys = HashMap::new(); for cert in certs { - for ka in cert.keys() { + for ka in cert.keys().policy(None) { if ka.binding_signature(None) .map(|s| (s.key_flags().for_storage_encryption() || s.key_flags().for_transport_encryption())) diff --git a/ipc/examples/gpg-agent-sign.rs b/ipc/examples/gpg-agent-sign.rs index b5f32a9c..a80f3935 100644 --- a/ipc/examples/gpg-agent-sign.rs +++ b/ipc/examples/gpg-agent-sign.rs @@ -39,9 +39,10 @@ fn main() { // Construct a KeyPair for every signing-capable (sub)key. let mut signers = certs.iter().flat_map(|cert| { - cert.keys().alive().revoked(false).for_signing().filter_map(|ka| { - KeyPair::new(&ctx, ka.key()).ok() - }) + cert.keys().policy(None).alive().revoked(false).for_signing() + .filter_map(|ka| { + KeyPair::new(&ctx, ka.key()).ok() + }) }).collect::<Vec<KeyPair>>(); // Compose a writer stack corresponding to the output format and diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs index 889402b5..b76a24d9 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -96,7 +96,7 @@ fn sign() { let keypair = KeyPair::new( &ctx, - cert.keys().alive().revoked(false) + cert.keys().policy(None).alive().revoked(false) .for_signing().take(1).next().unwrap().key()) .unwrap(); @@ -210,7 +210,7 @@ fn decrypt() { let mut message = Vec::new(); { let recipient = - cert.keys().alive().revoked(false) + cert.keys().policy(None).alive().revoked(false) .key_flags( KeyFlags::default().set_transport_encryption(true)) .map(|ka| ka.key().into()) @@ -278,8 +278,8 @@ fn decrypt() { { let mut keypair = KeyPair::new( self.ctx, - self.cert.keys().alive().revoked(false). - key_flags( + self.cert.keys().policy(None).alive().revoked(false) + .key_flags( KeyFlags::default().set_transport_encryption(true)) .take(1).next().unwrap().key()) .unwrap(); diff --git a/net/src/lib.rs b/net/src/lib.rs index f7add939..048031fe 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -182,8 +182,8 @@ impl KeyServer { Some(armor::Kind::PublicKey))); match Cert::from_reader(r) { Ok(cert) => { - if cert.keys().any(|ka| { - KeyID::from(ka.key().fingerprint()) + if cert.keys().any(|key| { + KeyID::from(key.fingerprint()) == keyid_want }) { future::done(Ok(cert)) diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c index c85b96f8..d395abd9 100644 --- a/openpgp-ffi/examples/decrypt-with.c +++ b/openpgp-ffi/examples/decrypt-with.c @@ -157,7 +157,7 @@ decrypt_cb (void *cookie_opaque, pgp_cert_key_iter_t key_iter = pgp_cert_key_iter (cookie->key); pgp_key_t key; - while ((key = pgp_cert_key_iter_next (key_iter, NULL, NULL))) { + while ((key = pgp_cert_key_iter_next (key_iter))) { pgp_keyid_t this_keyid = pgp_key_keyid (key); int match = pgp_keyid_equal (this_keyid, keyid); pgp_keyid_free (this_keyid); diff --git a/openpgp-ffi/examples/encrypt-for.c b/openpgp-ffi/examples/encrypt-for.c index 65bd8a45..aeb4dea4 100644 --- a/openpgp-ffi/examples/encrypt-for.c +++ b/openpgp-ffi/examples/encrypt-for.c @@ -36,14 +36,14 @@ main (int argc, char **argv) if (cert == NULL) error (1, 0, "pgp_cert_from_file: %s", pgp_error_to_string (err)); - pgp_cert_key_iter_t iter = pgp_cert_key_iter (cert); - pgp_cert_key_iter_alive (iter); - pgp_cert_key_iter_revoked (iter, false); - pgp_cert_key_iter_for_storage_encryption (iter); - pgp_cert_key_iter_for_transport_encryption (iter); + pgp_cert_valid_key_iter_t iter = pgp_cert_valid_key_iter (cert, 0); + pgp_cert_valid_key_iter_alive (iter); + pgp_cert_valid_key_iter_revoked (iter, false); + pgp_cert_valid_key_iter_for_storage_encryption (iter); + pgp_cert_valid_key_iter_for_transport_encryption (iter); size_t recipients_len; pgp_recipient_t *recipients = - pgp_recipients_from_key_iter (iter, &recipients_len); + pgp_recipients_from_valid_key_iter (iter, &recipients_len); sink = pgp_writer_from_fd (STDOUT_FILENO); diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 4468ccb5..1a27fad9 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -607,6 +607,41 @@ void pgp_user_id_binding_iter_free (pgp_user_id_binding_iter_t iter); /* openpgp::cert::KeyIter. */ /*/ +/// Changes the iterator to only return keys that have secret keys. +/// +/// Note: you may not call this function after starting to iterate. +/*/ +void pgp_cert_key_iter_secret (pgp_cert_key_iter_t iter); + +/*/ +/// Changes the iterator to only return keys that have unencrypted +/// secret keys. +/// +/// Note: you may not call this function after starting to iterate. +/*/ +void pgp_cert_key_iter_unencrypted_secret (pgp_cert_key_iter_t iter); + +/*/ +/// Changes the iterator to only return keys that have unencrypted +/// secret keys. +/// +/// Note: you may not call this function after starting to iterate. +/*/ +pgp_cert_valid_key_iter_t pgp_cert_key_iter_policy + (pgp_cert_key_iter_t iter, time_t when); + +/*/ +/// Returns a reference to the next key. Returns NULL if there are no +/// more elements. +/*/ +pgp_key_t pgp_cert_key_iter_next (pgp_cert_key_iter_t iter); + +/*/ +/// Frees an pgp_cert_key_iter_t. +/*/ +void pgp_cert_key_iter_free (pgp_cert_key_iter_t iter); + +/*/ /// Changes the iterator to only return keys that are certification /// capable. /// @@ -617,7 +652,7 @@ void pgp_user_id_binding_iter_free (pgp_user_id_binding_iter_t iter); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_for_certification (pgp_cert_key_iter_t iter); +void pgp_cert_valid_key_iter_for_certification (pgp_cert_valid_key_iter_t iter); /*/ /// Changes the iterator to only return keys that are certification @@ -630,7 +665,7 @@ void pgp_cert_key_iter_for_certification (pgp_cert_key_iter_t iter); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_for_signing (pgp_cert_key_iter_t iter); +void pgp_cert_valid_key_iter_for_signing (pgp_cert_valid_key_iter_t iter); /*/ /// Changes the iterator to only return keys that are capable of @@ -643,7 +678,7 @@ void pgp_cert_key_iter_for_signing (pgp_cert_key_iter_t iter); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_for_storage_encryption (pgp_cert_key_iter_t); +void pgp_cert_valid_key_iter_for_storage_encryption (pgp_cert_valid_key_iter_t); /*/ /// Changes the iterator to only return keys that are capable of @@ -656,28 +691,16 @@ void pgp_cert_key_iter_for_storage_encryption (pgp_cert_key_iter_t); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_for_transport_encryption (pgp_cert_key_iter_t); +void pgp_cert_valid_key_iter_for_transport_encryption (pgp_cert_valid_key_iter_t); /*/ /// Changes the iterator to only return keys that are alive. /// -/// If you call this function (or `pgp_cert_key_iter_alive_at`), only -/// the last value is used. +/// If you call this function, only the last value is used. /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_alive (pgp_cert_key_iter_t iter); - -/*/ -/// Changes the iterator to only return keys that are alive at the -/// specified time. -/// -/// If you call this function (or `pgp_cert_key_iter_alive`), only the -/// last value is used. -/// -/// Note: you may not call this function after starting to iterate. -/*/ -void pgp_cert_key_iter_alive_at (pgp_cert_key_iter_t iter, time_t when); +void pgp_cert_valid_key_iter_alive (pgp_cert_valid_key_iter_t iter); /*/ /// Changes the iterator to only return keys whose revocation status @@ -685,14 +708,14 @@ void pgp_cert_key_iter_alive_at (pgp_cert_key_iter_t iter, time_t when); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_revoked (pgp_cert_key_iter_t iter, bool revoked); +void pgp_cert_valid_key_iter_revoked (pgp_cert_valid_key_iter_t iter, bool revoked); /*/ /// Changes the iterator to only return keys that have secret keys. /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_secret (pgp_cert_key_iter_t iter); +void pgp_cert_valid_key_iter_secret (pgp_cert_valid_key_iter_t iter); /*/ /// Changes the iterator to only return keys that have unencrypted @@ -700,7 +723,7 @@ void pgp_cert_key_iter_secret (pgp_cert_key_iter_t iter); /// /// Note: you may not call this function after starting to iterate. /*/ -void pgp_cert_key_iter_unencrypted_secret (pgp_cert_key_iter_t iter); +void pgp_cert_valid_key_iter_unencrypted_secret (pgp_cert_valid_key_iter_t iter); /*/ /// Returns a reference to the next key. Returns NULL if there are no @@ -714,14 +737,14 @@ void pgp_cert_key_iter_unencrypted_secret (pgp_cert_key_iter_t iter); /// If rev is not NULL, this stores the key's revocation status in /// *rev. /*/ -pgp_key_t pgp_cert_key_iter_next (pgp_cert_key_iter_t iter, - pgp_signature_t *signature, - pgp_revocation_status_t *rev); +pgp_key_t pgp_cert_valid_key_iter_next (pgp_cert_valid_key_iter_t iter, + pgp_signature_t *signature, + pgp_revocation_status_t *rev); /*/ -/// Frees an pgp_cert_key_iter_t. +/// Frees an pgp_cert_valid_key_iter_t. /*/ -void pgp_cert_key_iter_free (pgp_cert_key_iter_t iter); +void pgp_cert_valid_key_iter_free (pgp_cert_valid_key_iter_t iter); /* openpgp::cert. */ @@ -917,6 +940,15 @@ pgp_user_id_binding_iter_t pgp_cert_user_id_binding_iter (pgp_cert_t cert); pgp_cert_key_iter_t pgp_cert_key_iter (pgp_cert_t cert); /*/ +/// Returns an iterator over all valid `Key`s in a Cert. +/// +/// That is, this returns an iterator over the primary key and any +/// subkeys that are valid (i.e., have a self-signature at time +/// `when`). +/*/ +pgp_cert_valid_key_iter_t pgp_cert_valid_key_iter (pgp_cert_t cert, time_t when); + +/*/ /// Returns the Cert's primary user id (if any). /*/ char *pgp_cert_primary_user_id(pgp_cert_t cert); diff --git a/openpgp-ffi/include/sequoia/openpgp/serialize.h b/openpgp-ffi/include/sequoia/openpgp/serialize.h index 09d62c95..5f9239b5 100644 --- a/openpgp-ffi/include/sequoia/openpgp/serialize.h +++ b/openpgp-ffi/include/sequoia/openpgp/serialize.h @@ -37,4 +37,12 @@ void pgp_recipient_set_keyid (pgp_recipient_t, pgp_keyid_t); /*/ pgp_recipient_t *pgp_recipients_from_key_iter (pgp_cert_key_iter_t, size_t *); +/*/ +/// Collects recipients from a `pgp_cert_valid_key_iter_t`. +/// +/// Consumes the iterator. The returned buffer must be freed using +/// libc's allocator. +/*/ +pgp_recipient_t *pgp_recipients_from_valid_key_iter (pgp_cert_valid_key_iter_t, size_t *); + #endif diff --git a/openpgp-ffi/include/sequoia/openpgp/types.h b/openpgp-ffi/include/sequoia/openpgp/types.h index c0b3bbd7..e85916f3 100644 --- a/openpgp-ffi/include/sequoia/openpgp/types.h +++ b/openpgp-ffi/include/sequoia/openpgp/types.h @@ -379,6 +379,11 @@ typedef struct pgp_user_id_binding_iter *pgp_user_id_binding_iter_t; typedef struct pgp_cert_key_iter *pgp_cert_key_iter_t; /*/ +/// An iterator over valid keys in a Cert. +/*/ +typedef struct pgp_cert_valid_key_iter *pgp_cert_valid_key_iter_t; + +/*/ /// An OpenPGP Certificate. /// /// A Certificate (see [RFC 4880, section 11.1]) can be used to verify diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs index 0c91dd88..90aac1ea 100644 --- a/openpgp-ffi/src/cert.rs +++ b/openpgp-ffi/src/cert.rs @@ -26,6 +26,7 @@ use self::openpgp::{ CertRevocationBuilder, UserIDBinding, UserIDBindingIter, + ValidKeyIter, }, }; @@ -459,17 +460,11 @@ pub extern "C" fn pgp_cert_key_iter_free( ffi_free!(iter) } -/// Changes the iterator to only return keys that are certification -/// capable. -/// -/// If you call this function and, e.g., the `for_signing` -/// function, the *union* of the values is used. That is, the -/// iterator will return keys that are certification capable *or* -/// signing capable. +/// Changes the iterator to only return keys that have secret keys. /// /// Note: you may not call this function after starting to iterate. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_cert_key_iter_for_certification<'a>( +pub extern "C" fn pgp_cert_key_iter_secret<'a>( iter_wrapper: *mut KeyIterWrapper<'a>) { let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); @@ -479,20 +474,15 @@ pub extern "C" fn pgp_cert_key_iter_for_certification<'a>( use std::mem; let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_certification(); + iter_wrapper.iter = unsafe { std::mem::transmute(tmp.secret()) }; } -/// Changes the iterator to only return keys that are certification -/// capable. -/// -/// If you call this function and, e.g., the `for_signing` -/// function, the *union* of the values is used. That is, the -/// iterator will return keys that are certification capable *or* -/// signing capable. +/// Changes the iterator to only return keys that have unencrypted +/// secret keys. /// /// Note: you may not call this function after starting to iterate. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_cert_key_iter_for_signing<'a>( +pub extern "C" fn pgp_cert_key_iter_unencrypted_secret<'a>( iter_wrapper: *mut KeyIterWrapper<'a>) { let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); @@ -502,21 +492,19 @@ pub extern "C" fn pgp_cert_key_iter_for_signing<'a>( use std::mem; let tmp = mem::replace(&mut iter_wrapper.iter, unsafe { mem::zeroed() }); - iter_wrapper.iter = tmp.for_signing(); + iter_wrapper.iter = + unsafe { std::mem::transmute(tmp.unencrypted_secret()) }; } -/// Changes the iterator to only return keys that are capable of -/// encrypting data at rest. -/// -/// If you call this function and, e.g., the `for_signing` -/// function, the *union* of the values is used. That is, the -/// it |