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
|
if [ "$SIGN_FPR" != "$FOUND_FPR" ] ; then
|
||||||
echo "Found wrong fingerprint '$FOUND_FPR' - expected '$SIGN_FPR'"
|
echo "Found wrong fingerprint '$FOUND_FPR' - expected '$SIGN_FPR'"
|
||||||
RESULT_CODE=1
|
exit 1
|
||||||
else
|
|
||||||
RESULT_CODE=0
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "no encryption detected"
|
echo "no encryption detected"
|
||||||
@@ -43,3 +41,31 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
global = true,
|
global = true,
|
||||||
help = "Certification store (SEQUOIA_HOME).",
|
help = "Certificate store (SEQUOIA_HOME).",
|
||||||
)]
|
)]
|
||||||
pub home: Option<String>,
|
pub home: Option<String>,
|
||||||
|
|
||||||
@@ -207,6 +207,7 @@ pub struct SignkeyCommand {
|
|||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum SignkeySubcommand {
|
pub enum SignkeySubcommand {
|
||||||
Set(SignkeySetCommand),
|
Set(SignkeySetCommand),
|
||||||
|
Create(SignkeyCreateCommand),
|
||||||
#[clap(
|
#[clap(
|
||||||
about = "Show the fingerprint of the signing key."
|
about = "Show the fingerprint of the signing key."
|
||||||
)]
|
)]
|
||||||
@@ -239,3 +240,19 @@ pub struct SignkeySetCommand {
|
|||||||
pub cert: Option<String>,
|
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;
|
use crate::types::husk_context::HuskContext;
|
||||||
|
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
pub mod create;
|
||||||
|
|
||||||
pub async fn dispatch(cmd: SignkeyCommand, config: HuskConfigContainer) -> Result<()> {
|
pub async fn dispatch(cmd: SignkeyCommand, config: HuskConfigContainer) -> Result<()> {
|
||||||
match cmd.subcommand {
|
match cmd.subcommand {
|
||||||
SignkeySubcommand::Set(set_cmd) => {
|
SignkeySubcommand::Set(set_cmd) => {
|
||||||
set::dispatch(set_cmd, config).await?;
|
set::dispatch(set_cmd, config).await?;
|
||||||
},
|
},
|
||||||
|
SignkeySubcommand::Create(create_cmd) => {
|
||||||
|
create::dispatch(create_cmd, config).await?;
|
||||||
|
}
|
||||||
SignkeySubcommand::Show => {
|
SignkeySubcommand::Show => {
|
||||||
let context = HuskContext::new(&config.into())?;
|
let context = HuskContext::new(&config.into())?;
|
||||||
if let Some(key) = context.signing_key {
|
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
|
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)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use sequoia_cert_store::store::CertD;
|
use sequoia_cert_store::store::CertD;
|
||||||
|
|||||||
Reference in New Issue
Block a user