diff options
-rw-r--r-- | guide/src/chapter_02.md | 142 | ||||
-rw-r--r-- | openpgp-ffi/examples/decrypt-with.c | 31 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 8 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp/types.h | 13 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 150 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 53 | ||||
-rw-r--r-- | openpgp/examples/generate-encrypt-decrypt.rs | 34 | ||||
-rw-r--r-- | openpgp/src/crypto/asymmetric.rs | 10 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 154 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 156 |
10 files changed, 325 insertions, 426 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 0afcf3f3..2a23b65b 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -12,9 +12,10 @@ fragments yields the [`openpgp/examples/generate-encrypt-decrypt.rs`]. use std::io::{self, Write}; extern crate sequoia_openpgp as openpgp; +use openpgp::crypto::SessionKey; +use openpgp::constants::SymmetricAlgorithm; use openpgp::serialize::stream::*; use openpgp::parse::stream::*; -use openpgp::packet::key::SecretKey; const MESSAGE: &'static str = "дружба"; @@ -109,31 +110,26 @@ fn main() { # } # # impl<'a> DecryptionHelper for Helper<'a> { -# fn get_secret(&mut self, -# _pkesks: &[&openpgp::packet::PKESK], -# _skesks: &[&openpgp::packet::SKESK]) -# -> openpgp::Result<Option<Secret>> +# fn decrypt<D>(&mut self, +# pkesks: &[openpgp::packet::PKESK], +# _skesks: &[openpgp::packet::SKESK], +# mut decrypt: D) +# -> openpgp::Result<Option<openpgp::Fingerprint>> +# where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. # let key = self.secret.subkeys().nth(0) # .map(|binding| binding.subkey().clone()) # .unwrap(); -# +# # // The secret key is not encrypted. -# let secret = -# if let Some(SecretKey::Unencrypted { -# ref mpis, -# }) = key.secret() { -# mpis.clone() -# } else { -# unreachable!() -# }; -# -# Ok(Some(Secret::Asymmetric { -# identity: self.secret.fingerprint(), -# key: key, -# secret: secret, -# })) +# let pair = key.into_keypair().unwrap(); +# +# pkesks[0].decrypt(pair.public(), pair.secret()) +# .and_then(|(algo, session_key)| decrypt(algo, &session_key)) +# .map(|_| None) +# // XXX: In production code, return the Fingerprint of the +# // recipient's TPK here # } # } ``` @@ -150,9 +146,10 @@ create it: # use std::io::{self, Write}; # # extern crate sequoia_openpgp as openpgp; +# use openpgp::crypto::SessionKey; +# use openpgp::constants::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; -# use openpgp::packet::key::SecretKey; # # const MESSAGE: &'static str = "дружба"; # @@ -247,31 +244,26 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # } # # impl<'a> DecryptionHelper for Helper<'a> { -# fn get_secret(&mut self, -# _pkesks: &[&openpgp::packet::PKESK], -# _skesks: &[&openpgp::packet::SKESK]) -# -> openpgp::Result<Option<Secret>> +# fn decrypt<D>(&mut self, +# pkesks: &[openpgp::packet::PKESK], +# _skesks: &[openpgp::packet::SKESK], +# mut decrypt: D) +# -> openpgp::Result<Option<openpgp::Fingerprint>> +# where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. # let key = self.secret.subkeys().nth(0) # .map(|binding| binding.subkey().clone()) # .unwrap(); -# +# # // The secret key is not encrypted. -# let secret = -# if let Some(SecretKey::Unencrypted { -# ref mpis, -# }) = key.secret() { -# mpis.clone() -# } else { -# unreachable!() -# }; -# -# Ok(Some(Secret::Asymmetric { -# identity: self.secret.fingerprint(), -# key: key, -# secret: secret, -# })) +# let pair = key.into_keypair().unwrap(); +# +# pkesks[0].decrypt(pair.public(), pair.secret()) +# .and_then(|(algo, session_key)| decrypt(algo, &session_key)) +# .map(|_| None) +# // XXX: In production code, return the Fingerprint of the +# // recipient's TPK here # } # } ``` @@ -288,9 +280,10 @@ implements [`io::Write`], and we simply write the plaintext to it. # use std::io::{self, Write}; # # extern crate sequoia_openpgp as openpgp; +# use openpgp::crypto::SessionKey; +# use openpgp::constants::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; -# use openpgp::packet::key::SecretKey; # # const MESSAGE: &'static str = "дружба"; # @@ -385,31 +378,26 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK) # } # # impl<'a> DecryptionHelper for Helper<'a> { -# fn get_secret(&mut self, -# _pkesks: &[&openpgp::packet::PKESK], -# _skesks: &[&openpgp::packet::SKESK]) -# -> openpgp::Result<Option<Secret>> +# fn decrypt<D>(&mut self, +# pkesks: &[openpgp::packet::PKESK], +# _skesks: &[openpgp::packet::SKESK], +# mut decrypt: D) +# -> openpgp::Result<Option<openpgp::Fingerprint>> +# where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. # let key = self.secret.subkeys().nth(0) # .map(|binding| binding.subkey().clone()) # .unwrap(); -# +# # // The secret key is not encrypted. -# let secret = -# if let Some(SecretKey::Unencrypted { -# ref mpis, -# }) = key.secret() { -# mpis.clone() -# } else { -# unreachable!() -# }; -# -# Ok(Some(Secret::Asymmetric { -# identity: self.secret.fingerprint(), -# key: key, -# secret: secret, -# })) +# let pair = key.into_keypair().unwrap(); +# +# pkesks[0].decrypt(pair.public(), pair.secret()) +# .and_then(|(algo, session_key)| decrypt(algo, &session_key)) +# .map(|_| None) +# // XXX: In production code, return the Fingerprint of the +# // recipient's TPK here # } # } ``` @@ -440,9 +428,10 @@ Decrypted data can be read from this using [`io::Read`]. # use std::io::{self, Write}; # # extern crate sequoia_openpgp as openpgp; +# use openpgp::crypto::SessionKey; +# use openpgp::constants::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; -# use openpgp::packet::key::SecretKey; # # const MESSAGE: &'static str = "дружба"; # @@ -537,10 +526,12 @@ impl<'a> VerificationHelper for Helper<'a> { } impl<'a> DecryptionHelper for Helper<'a> { - fn get_secret(&mut self, - _pkesks: &[&openpgp::packet::PKESK], - _skesks: &[&openpgp::packet::SKESK]) - -> openpgp::Result<Option<Secret>> + fn decrypt<D>(&mut self, + pkesks: &[openpgp::packet::PKESK], + _skesks: &[openpgp::packet::SKESK], + mut decrypt: D) + -> openpgp::Result<Option<openpgp::Fingerprint>> + where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { // The encryption key is the first and only subkey. let key = self.secret.subkeys().nth(0) @@ -548,20 +539,13 @@ impl<'a> DecryptionHelper for Helper<'a> { .unwrap(); // The secret key is not encrypted. - let secret = - if let Some(SecretKey::Unencrypted { - ref mpis, - }) = key.secret() { - mpis.clone() - } else { - unreachable!() - }; - - Ok(Some(Secret::Asymmetric { - identity: self.secret.fingerprint(), - key: key, - secret: secret, - })) + let pair = key.into_keypair().unwrap(); + + pkesks[0].decrypt(pair.public(), pair.secret()) + .and_then(|(algo, session_key)| decrypt(algo, &session_key)) + .map(|_| None) + // XXX: In production code, return the Fingerprint of the + // recipient's TPK here } } ``` diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c index d30b2d52..d68e0902 100644 --- a/openpgp-ffi/examples/decrypt-with.c +++ b/openpgp-ffi/examples/decrypt-with.c @@ -21,7 +21,7 @@ struct decrypt_cookie { pgp_tpk_t key; - int get_secret_keys_called; + int decrypt_called; }; static pgp_status_t @@ -46,18 +46,20 @@ check_signatures_cb(void *cookie_opaque, } static pgp_status_t -get_secret_keys_cb (void *cookie_opaque, - pgp_pkesk_t *pkesks, size_t pkesk_count, - pgp_skesk_t *skesks, size_t skesk_count, - pgp_secret_t *secret) +decrypt_cb (void *cookie_opaque, + pgp_pkesk_t *pkesks, size_t pkesk_count, + pgp_skesk_t *skesks, size_t skesk_count, + pgp_decryptor_do_decrypt_cb_t *decrypt, + void *decrypt_cookie, + pgp_fingerprint_t *identity_out) { + pgp_status_t rc; pgp_error_t err; struct decrypt_cookie *cookie = cookie_opaque; /* Prevent iterations, we only have one key to offer. */ - if (cookie->get_secret_keys_called) - return PGP_STATUS_UNKNOWN_ERROR; - cookie->get_secret_keys_called = 1; + assert (!cookie->decrypt_called); + cookie->decrypt_called = 1; for (int i = 0; i < pkesk_count; i++) { pgp_pkesk_t pkesk = pkesks[i]; @@ -88,8 +90,13 @@ get_secret_keys_cb (void *cookie_opaque, } pgp_key_free (key); - *secret = pgp_secret_cached (algo, session_key, session_key_len); - return PGP_STATUS_SUCCESS; + pgp_session_key_t sk = pgp_session_key_from_bytes (session_key, + session_key_len); + rc = decrypt (decrypt_cookie, algo, sk); + pgp_session_key_free (sk); + + *identity_out = pgp_tpk_fingerprint (cookie->key); + return rc; } return PGP_STATUS_UNKNOWN_ERROR; @@ -117,10 +124,10 @@ main (int argc, char **argv) struct decrypt_cookie cookie = { .key = tpk, - .get_secret_keys_called = 0, + .decrypt_called = 0, }; plaintext = pgp_decryptor_new (&err, source, - get_public_keys_cb, get_secret_keys_cb, + get_public_keys_cb, decrypt_cb, check_signatures_cb, &cookie); if (! plaintext) error (1, 0, "pgp_decryptor_new: %s", pgp_error_to_string (err)); diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 8473e632..aad66926 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1388,12 +1388,6 @@ pgp_writer_stack_t pgp_encryptor_new (pgp_error_t *errp, pgp_encryption_mode_t mode, uint8_t cipher_algo); -/*/ -/// Creates an pgp_secret_t from a decrypted session key. -/*/ -pgp_secret_t pgp_secret_cached(uint8_t algo, - uint8_t *session_key, size_t session_key_len); - void pgp_verification_results_at_level(pgp_verification_results_t results, size_t level, pgp_verification_result_t **r, @@ -1438,7 +1432,7 @@ int pgp_verification_result_level(pgp_verification_result_t r); /*/ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input, pgp_decryptor_get_public_keys_cb_t get_public_keys, - pgp_decryptor_get_secret_keys_cb_t get_secret_keys, + pgp_decryptor_decrypt_cb_t decrypt, pgp_decryptor_check_signatures_cb_t check_signatures, void *cookie); diff --git a/openpgp-ffi/include/sequoia/openpgp/types.h b/openpgp-ffi/include/sequoia/openpgp/types.h index 2ba7fcdc..140554f5 100644 --- a/openpgp-ffi/include/sequoia/openpgp/types.h +++ b/openpgp-ffi/include/sequoia/openpgp/types.h @@ -455,8 +455,6 @@ typedef enum pgp_encryption_mode { PGP_ENCRYPTION_MODE_FOR_TRANSPORT = 1, } pgp_encryption_mode_t; -typedef struct pgp_secret *pgp_secret_t; - typedef struct pgp_verification_results *pgp_verification_results_t; typedef struct pgp_verification_result *pgp_verification_result_t; @@ -475,10 +473,17 @@ typedef pgp_status_t (*pgp_decryptor_get_public_keys_cb_t) (void *, pgp_tpk_t **, size_t *, void (**free)(void *)); -typedef pgp_status_t (*pgp_decryptor_get_secret_keys_cb_t) (void *, +typedef pgp_status_t (pgp_decryptor_do_decrypt_cb_t) ( + void *, + uint8_t, + pgp_session_key_t); + +typedef pgp_status_t (*pgp_decryptor_decrypt_cb_t) (void *, pgp_pkesk_t *, size_t, pgp_skesk_t *, size_t, - pgp_secret_t *); + pgp_decryptor_do_decrypt_cb_t *, + void *, + pgp_fingerprint_t *); typedef pgp_status_t (*pgp_decryptor_check_signatures_cb_t) (void *, pgp_verification_results_t, diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index d26bbbc8..63db33a6 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -11,14 +11,15 @@ //! [`sequoia-openpgp::parse::stream`]: ../../../sequoia_openpgp/parse/stream/index.html use std::ptr; -use std::slice; -use libc::{c_int, size_t, c_void}; +use libc::{c_int, size_t, c_void, uint8_t}; extern crate sequoia_openpgp as openpgp; extern crate time; use self::openpgp::{ RevocationStatus, + crypto::SessionKey, + constants::SymmetricAlgorithm, packet::{ PKESK, SKESK, @@ -27,7 +28,6 @@ use self::openpgp::{ use self::openpgp::parse::stream::{ DecryptionHelper, Decryptor, - Secret, VerificationHelper, VerificationResult, Verifier, @@ -38,10 +38,12 @@ use Maybe; use MoveFromRaw; use MoveIntoRaw; use MoveResultIntoRaw; +use RefRaw; use RefMutRaw; use super::super::{ error::Status, + crypto, io, keyid, packet, @@ -76,30 +78,6 @@ pub extern "system" fn pgp_revocation_status_free( ffi_free!(rs) } -// Secret. - -/// Creates an pgp_secret_t from a decrypted session key. -#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "system" -fn pgp_secret_cached<'a>(algo: u8, - session_key: *const u8, - session_key_len: size_t) - -> *mut Secret -{ - let session_key = if session_key_len > 0 { - unsafe { - slice::from_raw_parts(session_key, session_key_len) - } - } else { - &[] - }; - - box_raw!(Secret::Cached { - algo: algo.into(), - session_key: session_key.to_vec().into() - }) -} - - // Decryptor. /// A message's verification results. @@ -201,11 +179,25 @@ type GetPublicKeysCallback = fn(*mut HelperCookie, &mut *mut *mut TPK, *mut usize, *mut FreeCallback) -> Status; -/// Returns a session key. -type GetSecretKeysCallback = fn(*mut HelperCookie, - *const &PKESK, usize, - *const &SKESK, usize, - &mut *mut Secret) -> Status; +/// Decrypts the message. +/// +/// This function is called with every `PKESK` and `SKESK` found in +/// the message. The implementation must decrypt the symmetric +/// algorithm and session key from one of the PKESK packets, the +/// SKESKs, or retrieve it from a cache, and then call the given +/// function with the symmetric algorithm and the session key. +/// +/// XXX: This needlessly flattens the complex errors returned by the +/// `decrypt` function into a status. +type DecryptCallback = fn(*mut HelperCookie, + *const *const PKESK, usize, + *const *const SKESK, usize, + extern "system" fn (*mut c_void, uint8_t, + *const crypto::SessionKey) + -> Status, + *mut c_void, + *mut Maybe<super::super::fingerprint::Fingerprint>) + -> Status; /// Process the signatures. /// @@ -522,19 +514,19 @@ fn pgp_detached_verifier_new<'a>(errp: Option<&mut *mut ::error::Error>, struct DHelper { vhelper: VHelper, - get_secret_keys_cb: GetSecretKeysCallback, + decrypt_cb: DecryptCallback, } impl DHelper { fn new(get_public_keys: GetPublicKeysCallback, - get_secret_keys: GetSecretKeysCallback, + decrypt: DecryptCallback, check_signatures: CheckSignaturesCallback, cookie: *mut HelperCookie) -> Self { DHelper { vhelper: VHelper::new(get_public_keys, check_signatures, cookie), - get_secret_keys_cb: get_secret_keys, + decrypt_cb: decrypt, } } } @@ -554,15 +546,46 @@ impl VerificationHelper for DHelper { } impl DecryptionHelper for DHelper { - fn get_secret(&mut self, pkesks: &[&PKESK], skesks: &[&SKESK]) - -> Result<Option<Secret>, failure::Error> + fn decrypt<D>(&mut self, pkesks: &[PKESK], skesks: &[SKESK], + mut decrypt: D) + -> openpgp::Result<Option<openpgp::Fingerprint>> + where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { - let mut secret : *mut Secret = ptr::null_mut(); + let mut identity: Maybe<super::super::fingerprint::Fingerprint> = None; + + // The size of PKESK is not known in C. Convert from an array + // of PKESKs to an array of PKESK refs. Likewise for SKESKs. + // + // XXX: .move_into_raw() once PKESK and SKESK are wrapped. + let pkesks : Vec<*const PKESK> = + pkesks.iter().map(|k| k as *const _).collect(); + let skesks : Vec<*const SKESK> = + skesks.iter().map(|k| k as *const _).collect(); + + // XXX: Free the wrappers once PKESK and SKESK are wrapped. + // + // // Free the wrappers. + // pkesks.into_iter().for_each(|o| { + // super::super::packet::pkesk::pgp_pkesk_free(o) }); + // skesks.into_iter().for_each(|o| { + // super::super::packet::skesk::pgp_skesk_free(o) }); + + extern "system" fn trampoline<D>(data: *mut c_void, algo: uint8_t, + sk: *const crypto::SessionKey) + -> Status + where D: FnMut(SymmetricAlgorithm, &SessionKey) + -> openpgp::Result<()> + { + let closure: &mut D = unsafe { &mut *(data as *mut D) }; + (*closure)(algo.into(), sk.ref_raw()).into() + } - let result = (self.get_secret_keys_cb)( + let result = (self.decrypt_cb)( self.vhelper.cookie, pkesks.as_ptr(), pkesks.len(), skesks.as_ptr(), skesks.len(), - &mut secret); + trampoline::<D>, + &mut decrypt as *mut _ as *mut c_void, + &mut identity); if result != Status::Success { // XXX: We need to convert the status to an error. A // status contains less information, but we should do the @@ -572,14 +595,7 @@ impl DecryptionHelper for DHelper { format!("{:?}", result)).into()); } - if secret.is_null() { - return Err(openpgp::Error::MissingSessionKey( - "Callback did not return a session key".into()).into()); - } - - let secret = ffi_param_move!(secret); - - Ok(Some(*secret)) + Ok(identity.move_from_raw()) } } @@ -611,7 +627,7 @@ impl DecryptionHelper for DHelper { /// /// struct decrypt_cookie { /// pgp_tpk_t key; -/// int get_secret_keys_called; +/// int decrypt_called; /// }; /// /// static pgp_status_t @@ -636,18 +652,19 @@ impl DecryptionHelper for DHelper { /// } /// /// static pgp_status_t -/// get_secret_keys_cb (void *cookie_opaque, -/// pgp_pkesk_t *pkesks, size_t pkesk_count, -/// pgp_skesk_t *skesks, size_t skesk_count, -/// pgp_secret_t *secret) +/// decrypt_cb (void *cookie_opaque, +/// pgp_pkesk_t *pkesks, size_t pkesk_count, +/// pgp_skesk_t *skesks, size_t skesk_count, +/// pgp_decryptor_do_decrypt_cb_t *decrypt, +/// void *decrypt_cookie, +/// pgp_fingerprint_t *identity_out) /// { +/// pgp_status_t rc; /// pgp_error_t err; /// struct decrypt_cookie *cookie = cookie_opaque; /// -/// /* Prevent iterations, we only have one key to offer. */ -/// if (cookie->get_secret_keys_called) -/// return PGP_STATUS_UNKNOWN_ERROR; -/// cookie->get_secret_keys_called = 1; +/// assert (! cookie->decrypt_called); +/// cookie->decrypt_called = 1; /// /// for (int i = 0; i < pkesk_count; i++) { /// pgp_pkesk_t pkesk = pkesks[i]; @@ -678,8 +695,13 @@ impl DecryptionHelper for DHelper { /// } /// pgp_key_free (key); /// -/// *secret = pgp_secret_cached (algo, session_key, session_key_len); -/// return PGP_STATUS_SUCCESS; +/// pgp_session_key_t sk = pgp_session_key_from_bytes (session_key, +/// session_key_len); +/// rc = decrypt (decrypt_cookie, algo, sk); +/// pgp_session_key_free (sk); +/// +/// *identity_out = pgp_tpk_fingerprint (cookie->key); +/// return rc; /// } /// /// return PGP_STATUS_UNKNOWN_ERROR; @@ -704,17 +726,17 @@ impl DecryptionHelper for DHelper { /// /// struct decrypt_cookie cookie = { /// .key = tpk, -/// .get_secret_keys_called = 0, +/// .decrypt_called = 0, /// }; /// plaintext = pgp_decryptor_new (NULL, source, -/// get_public_keys_cb, get_secret_keys_cb, +/// get_public_keys_cb, decrypt_cb, /// check_signatures_cb, &cookie); /// assert (plaintext); /// /// nread = pgp_reader_read (NULL, plaintext, buf, sizeof buf); /// assert (nread == 13); /// assert (memcmp (buf, "Test, 1-2-3.\n", nread) == 0); -/// assert (cookie.get_secret_keys_called); +/// assert (cookie.decrypt_called); /// /// pgp_reader_free (plaintext); /// pgp_reader_free (source); @@ -726,13 +748,13 @@ impl DecryptionHelper for DHelper { fn pgp_decryptor_new<'a>(errp: Option<&mut *mut ::error::Error>, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, - get_secret_keys: GetSecretKeysCallback, + decrypt: DecryptCallback, check_signatures: CheckSignaturesCallback, cookie: *mut HelperCookie) -> Maybe<io::Reader> { let helper = DHelper::new( - get_public_keys, get_secret_keys, check_signatures, cookie); + get_public_keys, decrypt, check_signatures, cookie); Decryptor::from_reader(input.ref_mut_raw(), helper) .map(|r| io::ReaderKind::Generic(Box::new(r))) diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index a5b26baa..3d6118f0 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -8,13 +8,13 @@ use std::io; extern crate failure; extern crate sequoia_openpgp as openpgp; -use openpgp::packet::key::SecretKey; +use openpgp::crypto::{KeyPair, SessionKey}; +use openpgp::constants::SymmetricAlgorithm; use openpgp::parse::{ Parse, stream::{ DecryptionHelper, Decryptor, - Secret, VerificationHelper, VerificationResult, }, @@ -47,8 +47,7 @@ pub fn main() { /// keys for the signature verification and implements the /// verification policy. struct Helper { - keys: HashMap<openpgp::KeyID, Secret>, - i: usize, + keys: HashMap<openpgp::KeyID, KeyPair>, } impl Helper { @@ -62,16 +61,10 @@ impl Helper { || s.key_flags().can_encrypt_for_transport())) .unwrap_or(false) { - // Only handle unencrypted secret keys. - if let Some(SecretKey::Unencrypted { ref mpis }) = - key.secret() - { + // This only works for unencrypted secret keys. + if let Ok(keypair) = key.clone().into_keypair() { keys.insert(key.fingerprint().to_keyid(), - Secret::Asymmetric { - identity: tpk.fingerprint(), - key: key.clone(), - secret: mpis.clone(), - }); + keypair); } } } @@ -79,25 +72,31 @@ impl Helper { Helper { keys: keys, - i: 0, } } } impl DecryptionHelper for Helper { - fn get_secret(&mut self, - pkesks: &[&openpgp::packet::PKESK], - _ |