Add signkey create
- Add a CLI command for creating a new signing key.
This commit is contained in:
@@ -30,9 +30,7 @@ if [ -f /var/mail/juliette ] ; then
|
||||
|
||||
if [ "$SIGN_FPR" != "$FOUND_FPR" ] ; then
|
||||
echo "Found wrong fingerprint '$FOUND_FPR' - expected '$SIGN_FPR'"
|
||||
RESULT_CODE=1
|
||||
else
|
||||
RESULT_CODE=0
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "no encryption detected"
|
||||
@@ -43,3 +41,31 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "set new signing key"
|
||||
|
||||
SIGN_FPR=$($HUSK_BIN --config config/config.toml signkey create | cut -d ':' -f 2 | tr -d ' ')
|
||||
echo "new signing key $SIGN_FPR"
|
||||
|
||||
# remove old mail
|
||||
rm /var/mail/juliette
|
||||
|
||||
echo "send mail to juliette@example.com"
|
||||
send_test_mail juliette@example.com
|
||||
|
||||
if [ -f /var/mail/juliette ] ; then
|
||||
if grep -q "BEGIN PGP MESSAGE" /var/mail/juliette ; then
|
||||
|
||||
FOUND_FPR=$(sq packet dump /var/mail/juliette | grep "Issuer Fingerprint:" | cut -d ':' -f 2 | tr -d ' ')
|
||||
|
||||
if [ "$SIGN_FPR" != "$FOUND_FPR" ] ; then
|
||||
echo "Found wrong fingerprint '$FOUND_FPR' - expected '$SIGN_FPR'"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "no encryption detected"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "no mail detected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+18
-1
@@ -18,7 +18,7 @@ pub struct CliArgs {
|
||||
#[clap(
|
||||
long,
|
||||
global = true,
|
||||
help = "Certification store (SEQUOIA_HOME).",
|
||||
help = "Certificate store (SEQUOIA_HOME).",
|
||||
)]
|
||||
pub home: Option<String>,
|
||||
|
||||
@@ -207,6 +207,7 @@ pub struct SignkeyCommand {
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum SignkeySubcommand {
|
||||
Set(SignkeySetCommand),
|
||||
Create(SignkeyCreateCommand),
|
||||
#[clap(
|
||||
about = "Show the fingerprint of the signing key."
|
||||
)]
|
||||
@@ -239,3 +240,19 @@ pub struct SignkeySetCommand {
|
||||
pub cert: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(
|
||||
about = "Create a new signing key.",
|
||||
)]
|
||||
pub struct SignkeyCreateCommand {
|
||||
#[clap(
|
||||
long,
|
||||
help = "Set the userid of the new key.",
|
||||
value_name = "USERID",
|
||||
default_value = "Husk signing key",
|
||||
)]
|
||||
pub userid: String,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,12 +9,16 @@ use crate::config::HuskConfigContainer;
|
||||
use crate::types::husk_context::HuskContext;
|
||||
|
||||
pub mod set;
|
||||
pub mod create;
|
||||
|
||||
pub async fn dispatch(cmd: SignkeyCommand, config: HuskConfigContainer) -> Result<()> {
|
||||
match cmd.subcommand {
|
||||
SignkeySubcommand::Set(set_cmd) => {
|
||||
set::dispatch(set_cmd, config).await?;
|
||||
},
|
||||
SignkeySubcommand::Create(create_cmd) => {
|
||||
create::dispatch(create_cmd, config).await?;
|
||||
}
|
||||
SignkeySubcommand::Show => {
|
||||
let context = HuskContext::new(&config.into())?;
|
||||
if let Some(key) = context.signing_key {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//! signkey create command
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use sequoia_openpgp::cert::CertBuilder;
|
||||
use sequoia_directories::Home;
|
||||
|
||||
use crate::cli::cli_args::SignkeyCreateCommand;
|
||||
use crate::common::crypto;
|
||||
use crate::config::{HuskConfig, HuskConfigContainer};
|
||||
use crate::types::husk_context::HuskContext;
|
||||
|
||||
pub async fn dispatch(cmd: SignkeyCreateCommand, config: HuskConfigContainer)
|
||||
-> Result<()> {
|
||||
|
||||
let config: HuskConfig = config.into();
|
||||
let context = HuskContext::new(&config)?;
|
||||
let sequoia_home = Home::new(PathBuf::from(&config.sequoia_home))?;
|
||||
|
||||
// XXX: cleanup the userid before using
|
||||
let (cert, _) = CertBuilder::new()
|
||||
.add_signing_subkey()
|
||||
.add_userid(cmd.userid)
|
||||
.generate()?;
|
||||
|
||||
if crypto::import_key(sequoia_home, &cert) {
|
||||
let vc = cert.with_policy(&context.policy, None)?;
|
||||
crypto::set_signing_key(&context, &vc)?;
|
||||
|
||||
println!("New signing key: {}", vc.fingerprint());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -692,6 +692,33 @@ pub fn get_all_keys(sequoia_home: Home) -> Vec<Key> {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn import_key(sequoia_home: Home, cert: &Cert) -> bool {
|
||||
let mut imported = false;
|
||||
std::thread::scope(|s| {
|
||||
s.spawn(|| {
|
||||
if let Ok(keystore_base) = Context::configure()
|
||||
.home(sequoia_home.data_dir(sequoia_directories::Component::Keystore))
|
||||
.build() {
|
||||
if let Ok(mut keystore) = Keystore::connect(&keystore_base) {
|
||||
if let Ok(mut backends) = keystore.backends() {
|
||||
for backend in &mut backends {
|
||||
if let Ok(id) = backend.id() {
|
||||
if id == "softkeys" {
|
||||
if let Ok(_) = backend.import(cert) {
|
||||
imported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
imported
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use sequoia_cert_store::store::CertD;
|
||||
|
||||
Reference in New Issue
Block a user