diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-09-27 14:20:28 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-09-27 14:20:28 +0200 |
commit | 3bbb981a7a6de54996e2cd62e517a34831c2cc67 (patch) | |
tree | e5896b0a93a4a24b50c62244d9694990edf7f80e /store/src | |
parent | 8e2f41ecee0553ec4749883e28eefdeaf52b9fc8 (diff) |
store: Add function to query keys by subkeyid from the pool.
Diffstat (limited to 'store/src')
-rw-r--r-- | store/src/backend/mod.rs | 20 | ||||
-rw-r--r-- | store/src/lib.rs | 46 | ||||
-rw-r--r-- | store/src/store_protocol.capnp | 1 |
3 files changed, 67 insertions, 0 deletions
diff --git a/store/src/backend/mod.rs b/store/src/backend/mod.rs index b05da547..98c39fac 100644 --- a/store/src/backend/mod.rs +++ b/store/src/backend/mod.rs @@ -234,6 +234,26 @@ impl node::Server for NodeServer { .from_server::<capnp_rpc::Server>())); Promise::ok(()) } + + fn lookup_by_subkeyid(&mut self, + params: node::LookupBySubkeyidParams, + mut results: node::LookupBySubkeyidResults) + -> Promise<(), capnp::Error> { + bind_results!(results); + let keyid = pry!(params.get()).get_keyid(); + + let key_id: ID = sry!( + self.c.query_row( + "SELECT key FROM key_by_keyid + WHERE key_by_keyid.keyid = ?1", + &[&(keyid as i64)], |row| row.get(0))); + + pry!(pry!(results.get().get_result()).set_ok( + node::key::ToClient::new( + KeyServer::new(self.c.clone(), key_id)) + .from_server::<capnp_rpc::Server>())); + Promise::ok(()) + } } struct StoreServer { diff --git a/store/src/lib.rs b/store/src/lib.rs index ad863787..a7f6d242 100644 --- a/store/src/lib.rs +++ b/store/src/lib.rs @@ -210,6 +210,52 @@ impl Pool { let key = make_request!(&mut core, request)?; Ok(Key::new(Rc::new(RefCell::new(core)), key)) } + + /// Looks up a key in the common key pool by (Sub)KeyID. + /// + /// The KeyID may also reference a signing- or + /// certification-capable subkey. The reason for this restriction + /// is that anyone can attach any subkey to her TPK, but signing- + /// or certification-capable subkeys require back signatures. + /// + /// # Example + /// + /// ``` + /// # extern crate openpgp; + /// # extern crate sequoia_core; + /// # extern crate sequoia_store; + /// # use openpgp::{TPK, KeyID}; + /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; + /// # use sequoia_store::{Pool, Result}; + /// # fn main() { f().unwrap(); } + /// # fn f() -> Result<()> { + /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # .network_policy(NetworkPolicy::Offline) + /// # .ipc_policy(IPCPolicy::Internal) + /// # .ephemeral().build()?; + /// # let tpk = TPK::from_bytes( + /// # include_bytes!("../../openpgp/tests/data/keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp")) + /// # .unwrap(); + /// Pool::import(&ctx, &tpk)?; + /// + /// // Lookup by the primary key's KeyID. + /// let key = Pool::lookup_by_subkeyid(&ctx, &KeyID::from_hex("069C0C348DD82C19")?)?; + /// assert_eq!(key.tpk()?.fingerprint(), tpk.fingerprint()); + /// + /// // Lookup by the subkey's KeyID. + /// let key = Pool::lookup_by_subkeyid(&ctx, &KeyID::from_hex("22E3FAFE96B56C32")?)?; + /// assert_eq!(key.tpk()?.fingerprint(), tpk.fingerprint()); + /// # Ok(()) + /// # } + /// ``` + pub fn lookup_by_subkeyid(c: &Context, keyid: &KeyID) -> Result<Key> { + let (mut core, client) = Store::connect(c)?; + let mut request = client.lookup_by_subkeyid_request(); + request.get().set_keyid(keyid.as_u64()?); + let key = make_request!(&mut core, request)?; + Ok(Key::new(Rc::new(RefCell::new(core)), key)) + } + } /// A public key store. diff --git a/store/src/store_protocol.capnp b/store/src/store_protocol.capnp index 7bec0b59..ded91ddf 100644 --- a/store/src/store_protocol.capnp +++ b/store/src/store_protocol.capnp @@ -9,6 +9,7 @@ interface Node { import @4 (key: Data) -> (result: Result(Key)); lookupByKeyid @5 (keyid: UInt64) -> (result: Result(Key)); lookupByFingerprint @6 (fingerprint: Text) -> (result: Result(Key)); + lookupBySubkeyid @7 (keyid: UInt64) -> (result: Result(Key)); interface Store { add @0 (label: Text, fingerprint: Text) -> (result: Result(Binding)); |