mirror of
https://codeberg.org/tyy/aspm
synced 2024-12-22 20:39:29 -07:00
Handful of things
- Update redb to fix regression when loading db multiple times (though I am likely just going to replace redb with sqlite) - Rename AspKeyType::EdDSA to AspKeyType::Ed25519 - Make `aspm keys list` look nicer
This commit is contained in:
parent
46fa993f45
commit
5390a9389a
7 changed files with 43 additions and 24 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -5,6 +5,7 @@
|
||||||
"Aspm",
|
"Aspm",
|
||||||
"josekit",
|
"josekit",
|
||||||
"PKCS",
|
"PKCS",
|
||||||
"Pkey"
|
"Pkey",
|
||||||
|
"printdoc"
|
||||||
]
|
]
|
||||||
}
|
}
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1026,9 +1026,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redb"
|
name = "redb"
|
||||||
version = "1.0.2"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1770bc0931171df3ced2adc9fd72d59cb47a4dc693d184c73cd382067f6ff44e"
|
checksum = "f41f3c1c8851dafca590c6ccfaa254a694a8e002a754352e68fac81371988838"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"pyo3-build-config",
|
"pyo3-build-config",
|
||||||
|
|
|
@ -18,7 +18,7 @@ thiserror = "1.0.40"
|
||||||
asp = { path = "crates/asp" }
|
asp = { path = "crates/asp" }
|
||||||
indoc = "2.0.1"
|
indoc = "2.0.1"
|
||||||
anstyle = "1.0.1"
|
anstyle = "1.0.1"
|
||||||
redb = "1.0.2"
|
redb = "1.0.3"
|
||||||
dialoguer = { version = "0.10.4", features = ["password"] }
|
dialoguer = { version = "0.10.4", features = ["password"] }
|
||||||
argon2 = { version = "0.5.0", features = ["std"] }
|
argon2 = { version = "0.5.0", features = ["std"] }
|
||||||
data-encoding = "2.4.0"
|
data-encoding = "2.4.0"
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::utils::jwk::JwtExt;
|
||||||
/// An enum representing the possible types of JWK for ASPs
|
/// An enum representing the possible types of JWK for ASPs
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AspKeyType {
|
pub enum AspKeyType {
|
||||||
EdDSA,
|
Ed25519,
|
||||||
ES256,
|
ES256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ impl AspKey {
|
||||||
match jwk.key_type() {
|
match jwk.key_type() {
|
||||||
"OKP" => match jwk.curve() {
|
"OKP" => match jwk.curve() {
|
||||||
Some("Ed25519") => Ok(Self {
|
Some("Ed25519") => Ok(Self {
|
||||||
key_type: AspKeyType::EdDSA,
|
key_type: AspKeyType::Ed25519,
|
||||||
fingerprint: jwk
|
fingerprint: jwk
|
||||||
.get_fingerprint()
|
.get_fingerprint()
|
||||||
.or(Err(AspKeyError::FingerprintError))?,
|
.or(Err(AspKeyError::FingerprintError))?,
|
||||||
|
@ -67,7 +67,7 @@ impl AspKey {
|
||||||
pub fn generate(key_type: AspKeyType) -> Result<Self, AspKeyError> {
|
pub fn generate(key_type: AspKeyType) -> Result<Self, AspKeyError> {
|
||||||
let result: anyhow::Result<Self> = try {
|
let result: anyhow::Result<Self> = try {
|
||||||
match key_type {
|
match key_type {
|
||||||
AspKeyType::EdDSA => {
|
AspKeyType::Ed25519 => {
|
||||||
let jwk = Jwk::generate_ed_key(EdCurve::Ed25519)?;
|
let jwk = Jwk::generate_ed_key(EdCurve::Ed25519)?;
|
||||||
Self {
|
Self {
|
||||||
key_type,
|
key_type,
|
||||||
|
@ -90,14 +90,14 @@ impl AspKey {
|
||||||
|
|
||||||
pub fn create_signer(&self) -> anyhow::Result<Box<dyn JwsSigner>> {
|
pub fn create_signer(&self) -> anyhow::Result<Box<dyn JwsSigner>> {
|
||||||
Ok(match self.key_type {
|
Ok(match self.key_type {
|
||||||
AspKeyType::EdDSA => Box::new(Eddsa.signer_from_jwk(&self.jwk)?),
|
AspKeyType::Ed25519 => Box::new(Eddsa.signer_from_jwk(&self.jwk)?),
|
||||||
AspKeyType::ES256 => Box::new(Es256.signer_from_jwk(&self.jwk)?),
|
AspKeyType::ES256 => Box::new(Es256.signer_from_jwk(&self.jwk)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_verifier(&self) -> anyhow::Result<Box<dyn JwsVerifier>> {
|
pub fn create_verifier(&self) -> anyhow::Result<Box<dyn JwsVerifier>> {
|
||||||
Ok(match self.key_type {
|
Ok(match self.key_type {
|
||||||
AspKeyType::EdDSA => Box::new(Eddsa.verifier_from_jwk(&self.jwk)?),
|
AspKeyType::Ed25519 => Box::new(Eddsa.verifier_from_jwk(&self.jwk)?),
|
||||||
AspKeyType::ES256 => Box::new(Es256.verifier_from_jwk(&self.jwk)?),
|
AspKeyType::ES256 => Box::new(Es256.verifier_from_jwk(&self.jwk)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ impl JwsHeaderExt for JwsHeader {
|
||||||
fn set_asp_key(&mut self, key: &AspKey) -> anyhow::Result<()> {
|
fn set_asp_key(&mut self, key: &AspKey) -> anyhow::Result<()> {
|
||||||
self.set_algorithm(match key.key_type {
|
self.set_algorithm(match key.key_type {
|
||||||
AspKeyType::ES256 => "ES256",
|
AspKeyType::ES256 => "ES256",
|
||||||
AspKeyType::EdDSA => "EdDSA",
|
AspKeyType::Ed25519 => "EdDSA",
|
||||||
});
|
});
|
||||||
self.set_key_id(&key.fingerprint);
|
self.set_key_id(&key.fingerprint);
|
||||||
self.set_jwk(key.jwk.to_public_key()?);
|
self.set_jwk(key.jwk.to_public_key()?);
|
||||||
|
@ -159,7 +159,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_eddsa() {
|
fn generate_eddsa() {
|
||||||
let key = AspKey::generate(AspKeyType::EdDSA);
|
let key = AspKey::generate(AspKeyType::Ed25519);
|
||||||
assert!(key.is_ok(), "key should generate successfully");
|
assert!(key.is_ok(), "key should generate successfully");
|
||||||
let key = key.unwrap();
|
let key = key.unwrap();
|
||||||
assert_eq!(key.jwk.key_type(), "OKP", "key should have type of OKP");
|
assert_eq!(key.jwk.key_type(), "OKP", "key should have type of OKP");
|
||||||
|
@ -229,7 +229,7 @@ mod tests {
|
||||||
fn export_encrypted() {
|
fn export_encrypted() {
|
||||||
let mut secret = [0u8; 32];
|
let mut secret = [0u8; 32];
|
||||||
assert!(openssl::rand::rand_bytes(&mut secret).is_ok());
|
assert!(openssl::rand::rand_bytes(&mut secret).is_ok());
|
||||||
let key = AspKey::generate(AspKeyType::EdDSA);
|
let key = AspKey::generate(AspKeyType::Ed25519);
|
||||||
assert!(key.is_ok());
|
assert!(key.is_ok());
|
||||||
let jwe = key.unwrap().export_encrypted(&secret);
|
let jwe = key.unwrap().export_encrypted(&secret);
|
||||||
assert!(jwe.is_ok());
|
assert!(jwe.is_ok());
|
||||||
|
@ -239,7 +239,7 @@ mod tests {
|
||||||
fn import_encrypted() {
|
fn import_encrypted() {
|
||||||
let mut secret = [0u8; 32];
|
let mut secret = [0u8; 32];
|
||||||
assert!(openssl::rand::rand_bytes(&mut secret).is_ok());
|
assert!(openssl::rand::rand_bytes(&mut secret).is_ok());
|
||||||
let key = AspKey::generate(AspKeyType::EdDSA).unwrap();
|
let key = AspKey::generate(AspKeyType::Ed25519).unwrap();
|
||||||
let encrypted = key.export_encrypted(&secret);
|
let encrypted = key.export_encrypted(&secret);
|
||||||
assert!(encrypted.is_ok());
|
assert!(encrypted.is_ok());
|
||||||
let decrypted = AspKey::from_encrypted(&secret, &encrypted.unwrap());
|
let decrypted = AspKey::from_encrypted(&secret, &encrypted.unwrap());
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl AspmSubcommand for KeysGenerateCommand {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let key = AspKey::generate(match self.key_type {
|
let key = AspKey::generate(match self.key_type {
|
||||||
KeyGenerationType::Ed25519 => AspKeyType::EdDSA,
|
KeyGenerationType::Ed25519 => AspKeyType::Ed25519,
|
||||||
KeyGenerationType::ES256 => AspKeyType::ES256,
|
KeyGenerationType::ES256 => AspKeyType::ES256,
|
||||||
})
|
})
|
||||||
.context("Key generation failed for an unknown reason")?;
|
.context("Key generation failed for an unknown reason")?;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use anstyle::{AnsiColor, Style as Anstyle};
|
use anstyle::{AnsiColor, Reset, Style as Anstyle};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use indoc::printdoc;
|
||||||
use redb::ReadableTable;
|
use redb::ReadableTable;
|
||||||
|
|
||||||
use crate::{commands::AspmSubcommand, db::KEYS_TABLE};
|
use crate::{commands::AspmSubcommand, db::KEYS_TABLE};
|
||||||
|
@ -19,25 +20,42 @@ impl AspmSubcommand for KeysListCommand {
|
||||||
let iter = table.iter().context("Unable to read table entries")?;
|
let iter = table.iter().context("Unable to read table entries")?;
|
||||||
let entries: Vec<_> = iter.collect();
|
let entries: Vec<_> = iter.collect();
|
||||||
|
|
||||||
|
// Construct styles
|
||||||
|
let reset = Reset::default().render();
|
||||||
let header_style = Anstyle::new()
|
let header_style = Anstyle::new()
|
||||||
.bold()
|
.bold()
|
||||||
.underline()
|
.underline()
|
||||||
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightGreen)));
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightMagenta)))
|
||||||
|
.render();
|
||||||
|
let alias_style = Anstyle::new()
|
||||||
|
.underline()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightCyan)))
|
||||||
|
.render();
|
||||||
|
let key_style = Anstyle::new()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightGreen)))
|
||||||
|
.render();
|
||||||
|
let value_style = Anstyle::new()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightYellow)))
|
||||||
|
.render();
|
||||||
|
|
||||||
|
// Print output
|
||||||
println!(
|
println!(
|
||||||
"{style}Saved keys ({n} total):{reset}\n\n",
|
"{header_style}Saved keys ({n} total):{reset}\n",
|
||||||
style = header_style.render(),
|
|
||||||
n = entries.len(),
|
n = entries.len(),
|
||||||
reset = header_style.render_reset()
|
|
||||||
);
|
);
|
||||||
for entry in entries.iter() {
|
for entry in entries.iter() {
|
||||||
if let Ok((fingerprint, value)) = entry {
|
if let Ok((fingerprint, value)) = entry {
|
||||||
let value = value.value();
|
let value = value.value();
|
||||||
println!(
|
printdoc! {
|
||||||
"{alias}: {fingerprint}/${key_type:?}",
|
"
|
||||||
|
{alias_style}{alias}:{reset}
|
||||||
|
{key_style}Fingerprint{reset} {value_style}{fingerprint}{reset}
|
||||||
|
{key_style}Key Type{reset} {value_style}{key_type:?}{reset}
|
||||||
|
",
|
||||||
fingerprint = fingerprint.value(),
|
fingerprint = fingerprint.value(),
|
||||||
key_type = value.key_type,
|
key_type = value.key_type,
|
||||||
alias = value.alias
|
alias = value.alias
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl RedbValue for KeysTableValue {
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_type: match key_type_byte {
|
key_type: match key_type_byte {
|
||||||
0 => AspKeyType::EdDSA,
|
0 => AspKeyType::Ed25519,
|
||||||
1 => AspKeyType::ES256,
|
1 => AspKeyType::ES256,
|
||||||
_ => panic!("parsing key table value failed: unknown key type byte found"),
|
_ => panic!("parsing key table value failed: unknown key type byte found"),
|
||||||
},
|
},
|
||||||
|
@ -111,7 +111,7 @@ impl RedbValue for KeysTableValue {
|
||||||
serialized.push(alias_bytes.len().try_into().unwrap()); // Add the first byte (alias length)
|
serialized.push(alias_bytes.len().try_into().unwrap()); // Add the first byte (alias length)
|
||||||
serialized.extend_from_slice(alias_bytes.as_slice()); // Add the alias bytes
|
serialized.extend_from_slice(alias_bytes.as_slice()); // Add the alias bytes
|
||||||
serialized.push(match value.key_type {
|
serialized.push(match value.key_type {
|
||||||
AspKeyType::EdDSA => 0,
|
AspKeyType::Ed25519 => 0,
|
||||||
AspKeyType::ES256 => 1,
|
AspKeyType::ES256 => 1,
|
||||||
}); // Add the key type byte
|
}); // Add the key type byte
|
||||||
serialized.extend_from_slice(key_bytes); // Add the rest of the bytes, all of which are the key
|
serialized.extend_from_slice(key_bytes); // Add the rest of the bytes, all of which are the key
|
||||||
|
|
Loading…
Reference in a new issue