mirror of
https://github.com/Noratrieb/cluelessh.git
synced 2026-01-14 16:35:06 +01:00
encryption
This commit is contained in:
parent
de8f5dde21
commit
e35ff86a12
10 changed files with 494 additions and 7 deletions
|
|
@ -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
13
bin/ssh-key/Cargo.toml
Normal 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
76
bin/ssh-key/src/main.rs
Normal 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(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue