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,
},
types::KeyFlags,
KeyID, PacketPile
KeyID, PacketPile,
};
pub use sequoia_openpgp as openpgp;
use sharks::{Share, Sharks};
@ -106,7 +106,7 @@ pub fn discover_certs(path: impl AsRef<Path>) -> Result<Vec<Cert>> {
}
}
pub fn parse_messages(reader: impl Read + Send + Sync) -> Result<VecDeque<EncryptedMessage> >{
pub fn parse_messages(reader: impl Read + Send + Sync) -> Result<VecDeque<EncryptedMessage>> {
let mut pkesks = Vec::new();
let mut encrypted_messages = VecDeque::new();
@ -234,6 +234,31 @@ pub fn combine(
.map_err(|e| WrappedError(e.to_string()))?;
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())?;
Ok(())

View File

@ -47,6 +47,10 @@ impl Keyring {
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> {
self.full_certs.iter().find(|cert| &cert.keyid() == keyid)
}