encryption

This commit is contained in:
nora 2024-08-23 01:02:55 +02:00
parent de8f5dde21
commit e35ff86a12
10 changed files with 494 additions and 7 deletions

View file

@ -3,7 +3,7 @@ use std::{io::Write, path::PathBuf};
use clap::Parser;
use eyre::{bail, Context};
use ssh_agent_client::{IdentityAnswer, SocketAgentConnection};
use ssh_transport::key::SshPubkey;
use ssh_transport::key::PublicKey;
#[derive(clap::Parser, Debug)]
struct Args {
@ -109,6 +109,7 @@ async fn main() -> eyre::Result<()> {
let signature = agent.sign(&key.key_blob, &file, 0).await?;
// TODO: https://github.com/openssh/openssh-portable/blob/a76a6b85108e3032c8175611ecc5746e7131f876/PROTOCOL.sshsig
let signature = pem::encode(&pem::Pem::new("SSH SIGNATURE", signature));
std::io::stdout().write_all(signature.as_bytes())?;
}
@ -148,7 +149,7 @@ async fn list_ids(agent: &mut SocketAgentConnection, print_key_id: bool) -> eyre
}
fn print_key(id: IdentityAnswer, show_key_id: bool) {
let key = SshPubkey::from_wire_encoding(&id.key_blob);
let key = PublicKey::from_wire_encoding(&id.key_blob);
match key {
Ok(key) => {
if show_key_id {

13
bin/ssh-key/Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "ssh-key"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.5.16", features = ["derive"] }
eyre = "0.6.12"
tracing.workspace = true
ssh-keys = { path = "../../lib/ssh-keys" }
base64 = "0.22.1"
rpassword = "7.3.1"

76
bin/ssh-key/src/main.rs Normal file
View file

@ -0,0 +1,76 @@
use std::path::PathBuf;
use base64::Engine;
use clap::Parser;
use eyre::{bail, Context};
use ssh_keys::PrivateKeyType;
#[derive(clap::Parser)]
struct Args {
#[command(subcommand)]
command: Subcommand,
}
#[derive(clap::Subcommand)]
enum Subcommand {
Info {
/// Decrypt the key to get more information. Will not display private information unless --show-private is used
#[arg(short, long)]
decrypt: bool,
/// Show the private key. WARNING: This will display the private key
#[arg(long)]
show_private: bool,
id_file: PathBuf,
},
}
fn main() -> eyre::Result<()> {
let args = Args::parse();
match args.command {
Subcommand::Info {
id_file,
decrypt,
show_private,
} => {
if show_private && !decrypt {
bail!("cannot --show-private without --decrypt");
}
let file = std::fs::read(&id_file)
.wrap_err_with(|| format!("reading file {}", id_file.display()))?;
let keys = ssh_keys::EncryptedPrivateKeys::parse_unencrypted(&file)?;
if decrypt {
let passphrase = if keys.requires_passphrase() {
let phrase = rpassword::prompt_password("passphrase: ")?;
Some(phrase)
} else {
None
};
let keys = keys.parse_private(passphrase.as_deref())?;
for key in keys {
println!("{} {}", key.private_key.public_key(), key.comment);
if show_private {
match key.private_key {
PrivateKeyType::Ed25519 { private_key, .. } => {
println!(
" private key: {}",
base64::prelude::BASE64_STANDARD_NO_PAD.encode(private_key)
)
}
}
}
}
} else {
for key in keys.public_keys {
println!("{key}");
}
}
}
}
Ok(())
}