mirror of
https://codeberg.org/tyy/aspm
synced 2024-12-22 20:39:29 -07:00
Fix pkcs#8 conversion for P-256 keys
This commit is contained in:
parent
bb6bed5531
commit
ec1b9f3bf9
4 changed files with 75 additions and 66 deletions
|
@ -67,7 +67,7 @@ impl JwtExt for Jwk {
|
||||||
// 4. Convert that Pkey into the PKCS#8 encoded private key (and then base64 encode it)
|
// 4. Convert that Pkey into the PKCS#8 encoded private key (and then base64 encode it)
|
||||||
let key_pair: Box<dyn KeyPair> = match self.key_type() {
|
let key_pair: Box<dyn KeyPair> = match self.key_type() {
|
||||||
"EC" => match self.curve() {
|
"EC" => match self.curve() {
|
||||||
Some("p-256") => Box::new(EcKeyPair::from_jwk(self)?),
|
Some("P-256") => Box::new(EcKeyPair::from_jwk(self)?),
|
||||||
_ => bail!("Unsupported curve type"),
|
_ => bail!("Unsupported curve type"),
|
||||||
},
|
},
|
||||||
"OKP" => match self.curve() {
|
"OKP" => match self.curve() {
|
||||||
|
|
|
@ -2,72 +2,72 @@ use anstyle::{AnsiColor, Color as AnstyleColor, Reset, Style as Anstyle};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use asp::keys::AspKeyType;
|
use asp::keys::AspKeyType;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use dialoguer::{Confirm, theme::ColorfulTheme, console::Term};
|
use dialoguer::{console::Term, theme::ColorfulTheme, Confirm};
|
||||||
use indoc::writedoc;
|
use indoc::writedoc;
|
||||||
use sea_orm::ModelTrait;
|
use sea_orm::ModelTrait;
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
entities::keys::{Entity as KeysEntity, Model as KeysModel},
|
commands::{AspmSubcommand, KeysEntityExt, KeysQueryResult},
|
||||||
commands::{AspmSubcommand, KeysQueryResult, KeysEntityExt}
|
entities::keys::{Entity as KeysEntity, Model as KeysModel},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Deletes a saved key, after asking for confirmation.
|
/// Deletes a saved key, after asking for confirmation.
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
pub struct KeysDeleteCommand {
|
pub struct KeysDeleteCommand {
|
||||||
/// Will disable any confirmation prompts. This is not recommended unless you knowingly give a full fingerprint, as it is easy to accidentally (and permanently) delete wrong keys otherwise.
|
/// Will disable any confirmation prompts. This is not recommended unless you knowingly give a full fingerprint, as it is easy to accidentally (and permanently) delete wrong keys otherwise.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
no_confirm: bool,
|
no_confirm: bool,
|
||||||
/// The key to export. This can either be a fingerprint obtained with the `keys list` command, or an alias to search for.
|
/// The key to export. This can either be a fingerprint obtained with the `keys list` command, or an alias to search for.
|
||||||
key: String,
|
key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl AspmSubcommand for KeysDeleteCommand {
|
impl AspmSubcommand for KeysDeleteCommand {
|
||||||
async fn execute(&self, state: crate::AspmState) -> Result<(), anyhow::Error> {
|
async fn execute(&self, state: crate::AspmState) -> Result<(), anyhow::Error> {
|
||||||
// Fetch key from db
|
// Fetch key from db
|
||||||
let entry = KeysEntity::query_key(&state.db, &self.key)
|
let entry = KeysEntity::query_key(&state.db, &self.key)
|
||||||
.await
|
.await
|
||||||
.context("Unable to query keys from database")?;
|
.context("Unable to query keys from database")?;
|
||||||
let key: KeysModel = match entry {
|
let key: KeysModel = match entry {
|
||||||
KeysQueryResult::None => {
|
KeysQueryResult::None => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{style}No keys matching the given query were found{reset}",
|
"{style}No keys matching the given query were found{reset}",
|
||||||
style = Anstyle::new()
|
style = Anstyle::new()
|
||||||
.fg_color(Some(AnstyleColor::Ansi(AnsiColor::BrightRed)))
|
.fg_color(Some(AnstyleColor::Ansi(AnsiColor::BrightRed)))
|
||||||
.render(),
|
.render(),
|
||||||
reset = Reset.render()
|
reset = Reset.render()
|
||||||
);
|
);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
KeysQueryResult::One(key) => key,
|
KeysQueryResult::One(key) => key,
|
||||||
KeysQueryResult::Many(mut keys) => {
|
KeysQueryResult::Many(mut keys) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{style}More than one keys matching the given query were found{reset}",
|
"{style}More than one keys matching the given query were found{reset}",
|
||||||
style = Anstyle::new()
|
style = Anstyle::new()
|
||||||
.fg_color(Some(AnstyleColor::Ansi(AnsiColor::BrightYellow)))
|
.fg_color(Some(AnstyleColor::Ansi(AnsiColor::BrightYellow)))
|
||||||
.render(),
|
.render(),
|
||||||
reset = Reset::default().render()
|
reset = Reset::default().render()
|
||||||
);
|
);
|
||||||
keys.remove(0)
|
keys.remove(0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.no_confirm {
|
if !self.no_confirm {
|
||||||
// Construct styles
|
// Construct styles
|
||||||
let reset = Reset::default().render();
|
let reset = Reset::default().render();
|
||||||
let alias_style = Anstyle::new()
|
let alias_style = Anstyle::new()
|
||||||
.underline()
|
.underline()
|
||||||
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightCyan)))
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightCyan)))
|
||||||
.render();
|
.render();
|
||||||
let key_style = Anstyle::new()
|
let key_style = Anstyle::new()
|
||||||
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightGreen)))
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightGreen)))
|
||||||
.render();
|
.render();
|
||||||
let value_style = Anstyle::new()
|
let value_style = Anstyle::new()
|
||||||
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightYellow)))
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightYellow)))
|
||||||
.render();
|
.render();
|
||||||
let _ = writedoc! {
|
let _ = writedoc! {
|
||||||
std::io::stderr(),
|
std::io::stderr(),
|
||||||
"
|
"
|
||||||
{alias_style}{alias}:{reset}
|
{alias_style}{alias}:{reset}
|
||||||
|
@ -79,20 +79,22 @@ impl AspmSubcommand for KeysDeleteCommand {
|
||||||
alias = key.alias
|
alias = key.alias
|
||||||
};
|
};
|
||||||
|
|
||||||
let confirmation = Confirm::with_theme(&ColorfulTheme::default())
|
let confirmation = Confirm::with_theme(&ColorfulTheme::default())
|
||||||
.with_prompt("Are you sure you want to delete this key?")
|
.with_prompt("Are you sure you want to delete this key?")
|
||||||
.interact_on(&Term::stderr())
|
.interact_on(&Term::stderr())
|
||||||
.context("Unable to prompt on stderr")?;
|
.context("Unable to prompt on stderr")?;
|
||||||
|
|
||||||
if !confirmation {
|
if !confirmation {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fingerprint = key.fingerprint.clone();
|
let fingerprint = key.fingerprint.clone();
|
||||||
key.delete(&state.db).await.context("Unable to delete key")?;
|
key.delete(&state.db)
|
||||||
println!("Successfully deleted key with fingerprint {}", fingerprint);
|
.await
|
||||||
|
.context("Unable to delete key")?;
|
||||||
|
println!("Successfully deleted key with fingerprint {}", fingerprint);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
pub mod delete;
|
||||||
pub mod export;
|
pub mod export;
|
||||||
pub mod generate;
|
pub mod generate;
|
||||||
#[cfg(feature = "gpg-compat")]
|
#[cfg(feature = "gpg-compat")]
|
||||||
pub mod import_gpg;
|
pub mod import_gpg;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod delete;
|
|
||||||
|
|
||||||
/// A subcommand to allow the management of keys, which can then be used to create, modify, or delete profiles.
|
/// A subcommand to allow the management of keys, which can then be used to create, modify, or delete profiles.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
|
|
@ -87,7 +87,14 @@ fn main() {
|
||||||
if let Err(e) = cli(parsed) {
|
if let Err(e) = cli(parsed) {
|
||||||
match verbose {
|
match verbose {
|
||||||
true => {
|
true => {
|
||||||
eprintln!("An error occurred while running that command:\n{e:?}");
|
eprintln!(
|
||||||
|
"An error occurred while running that command:\n{e:?}\nStack:\n{stack}",
|
||||||
|
stack = e
|
||||||
|
.chain()
|
||||||
|
.map(|entry| format!("\t- {entry}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
false => eprintln!("An error occurred while running that command:\n{e}"),
|
false => eprintln!("An error occurred while running that command:\n{e}"),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue