keyfork-shard: derive cert from combined secret to ensure data integrity

This commit is contained in:
Ryan Heywood 2023-10-19 20:10:02 -05:00
parent 0615a66ace
commit 7a80799115
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
2 changed files with 31 additions and 2 deletions

View File

@ -20,7 +20,7 @@ use openpgp::{
Marshal, Marshal,
}, },
types::KeyFlags, types::KeyFlags,
KeyID, PacketPile KeyID, PacketPile,
}; };
pub use sequoia_openpgp as openpgp; pub use sequoia_openpgp as openpgp;
use sharks::{Share, Sharks}; use sharks::{Share, Sharks};
@ -234,6 +234,31 @@ pub fn combine(
.map_err(|e| WrappedError(e.to_string()))?; .map_err(|e| WrappedError(e.to_string()))?;
let secret = Sharks(threshold).recover(&shares)?; let secret = Sharks(threshold).recover(&shares)?;
let userid = UserID::from("keyfork-sss");
let kdr = DerivationRequest::new(
DerivationAlgorithm::Ed25519,
&DerivationPath::from_str("m/7366512'/0'")?,
)
.derive_with_master_seed(secret.to_vec())?;
let derived_cert = keyfork_derive_openpgp::derive(
kdr,
&[KeyFlags::empty().set_certification().set_signing()],
userid,
)?;
// NOTE: Signatures on certs will be different. Compare fingerprints instead.
if Some(derived_cert.fingerprint()) != keyring.root_cert().map(Cert::fingerprint) {
return Err(WrappedError(format!(
"Derived {} != expected {}",
derived_cert.fingerprint(),
keyring
.root_cert()
.expect("cert was previously set")
.fingerprint()
))
.into());
}
output.write_all(smex::encode(&secret).as_bytes())?; output.write_all(smex::encode(&secret).as_bytes())?;
Ok(()) Ok(())

View File

@ -47,6 +47,10 @@ impl Keyring {
cert cert
} }
pub fn root_cert(&self) -> Option<&Cert> {
self.root.as_ref()
}
pub fn get_cert_for_primary_keyid<'a>(&'a self, keyid: &KeyID) -> Option<&'a Cert> { pub fn get_cert_for_primary_keyid<'a>(&'a self, keyid: &KeyID) -> Option<&'a Cert> {
self.full_certs.iter().find(|cert| &cert.keyid() == keyid) self.full_certs.iter().find(|cert| &cert.keyid() == keyid)
} }