summaryrefslogtreecommitdiffstats
path: root/store/src
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-09-27 14:20:28 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-09-27 14:20:28 +0200
commit3bbb981a7a6de54996e2cd62e517a34831c2cc67 (patch)
treee5896b0a93a4a24b50c62244d9694990edf7f80e /store/src
parent8e2f41ecee0553ec4749883e28eefdeaf52b9fc8 (diff)
store: Add function to query keys by subkeyid from the pool.
Diffstat (limited to 'store/src')
-rw-r--r--store/src/backend/mod.rs20
-rw-r--r--store/src/lib.rs46
-rw-r--r--store/src/store_protocol.capnp1
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));