difftreelog
feat hex secret encoding
in: trunk
3 files changed
Cargo.lockdiffbeforeafterboth812 "clap",812 "clap",813 "ed25519-dalek",813 "ed25519-dalek",814 "fleet-shared",814 "fleet-shared",815 "hex",815 "rand",816 "rand",816 "x25519-dalek",817 "x25519-dalek",817]818]1048source = "registry+https://github.com/rust-lang/crates.io-index"1049source = "registry+https://github.com/rust-lang/crates.io-index"1049checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"1050checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"10511052[[package]]1053name = "hex"1054version = "0.4.3"1055source = "registry+https://github.com/rust-lang/crates.io-index"1056checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"105010571051[[package]]1058[[package]]1052name = "hkdf"1059name = "hkdf"cmds/generator-helper/Cargo.tomldiffbeforeafterboth--- a/cmds/generator-helper/Cargo.toml
+++ b/cmds/generator-helper/Cargo.toml
@@ -10,5 +10,6 @@
clap.workspace = true
ed25519-dalek = { version = "2.1", features = ["rand_core"] }
fleet-shared.workspace = true
+hex = "0.4.3"
rand = "0.8.5"
x25519-dalek = "2.0.1"
cmds/generator-helper/src/main.rsdiffbeforeafterboth--- a/cmds/generator-helper/src/main.rs
+++ b/cmds/generator-helper/src/main.rs
@@ -1,7 +1,7 @@
use std::{
env,
fs::{File, OpenOptions},
- io::{copy, Read, Write},
+ io::{self, copy, stdin, stdout, Read, Write},
str::FromStr,
};
@@ -106,10 +106,29 @@
match encoding {
OutputEncoding::Raw => coerce(w),
OutputEncoding::Base64 => {
- use base64::engine::general_purpose::STANDARD;
- let writer = base64::write::EncoderWriter::new(w, &STANDARD);
+ use base64::{engine::general_purpose::STANDARD, write::EncoderWriter};
+
+ let writer = EncoderWriter::new(w, &STANDARD);
coerce(writer)
}
+ OutputEncoding::Hex => {
+ struct HexWriter<W>(W);
+ impl<W> Write for HexWriter<W>
+ where
+ W: Write,
+ {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ let encoded = hex::encode(buf);
+ self.0.write_all(encoded.as_bytes())?;
+ Ok(buf.len())
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.0.flush()
+ }
+ }
+ coerce(HexWriter(w))
+ }
}
}
@@ -120,6 +139,8 @@
Raw,
/// Encode as base64 (with padding).
Base64,
+ /// Encode as hex (without leading 0x)
+ Hex,
}
#[derive(Parser)]
@@ -175,6 +196,14 @@
#[arg(long, short = 'e', value_enum, default_value_t)]
encoding: OutputEncoding,
},
+ /// Sometimes you also need to reencode secret, this command allows you to get raw data from
+ /// secret encoded using `gh public`... I would like if I knew a better design for some sort of
+ /// such thing. Ideally there should be no need to decode secrets back, but garage wants both
+ /// raw pubkey and raw secret key, yet also requires node id which is hex-reencoded public key.
+ Decode {
+ #[arg(long, short = 'i')]
+ input: String,
+ },
/// Generate keys in well-known schemas.
///
/// Note that this command is only intended to be used in fleet secret generator,
@@ -190,11 +219,11 @@
match opts {
Opts::Public { output, encoding } => {
- write_public(&output, std::io::stdin(), encoding)?;
+ write_public(&output, stdin(), encoding)?;
}
Opts::Private { output, encoding } => {
let recipients = load_identities()?;
- write_private(&recipients, &output, std::io::stdin(), encoding)?;
+ write_private(&recipients, &output, stdin(), encoding)?;
}
Opts::Generate(gen) => {
match gen {
@@ -204,8 +233,10 @@
no_embed_public,
encoding,
} => {
+ use ed25519_dalek::SigningKey;
+
let recipients = load_identities()?;
- let key = ed25519_dalek::SigningKey::generate(&mut rng).to_keypair_bytes();
+ let key = SigningKey::generate(&mut rng).to_keypair_bytes();
write_public(&public, &key[32..], encoding)?;
write_private(
&recipients,
@@ -225,9 +256,11 @@
private,
encoding,
} => {
+ use x25519_dalek::{PublicKey, StaticSecret};
+
let recipients = load_identities()?;
- let key = x25519_dalek::StaticSecret::random_from_rng(rng);
- let public_key: x25519_dalek::PublicKey = (&key).into();
+ let key = StaticSecret::random_from_rng(rng);
+ let public_key: PublicKey = (&key).into();
write_public(&public, public_key.as_bytes().as_slice(), encoding)?;
write_private(&recipients, &private, key.as_bytes().as_slice(), encoding)?;
}
@@ -257,6 +290,20 @@
}
}
}
+ Opts::Decode { input } => {
+ let mut data = Vec::new();
+ File::open(input)?.read_to_end(&mut data)?;
+ let data = String::from_utf8(data).context(
+ "encoded data is always utf-8, you are trying to use decode the wrong way.",
+ )?;
+ let data =
+ SecretData::from_str(&data).map_err(|e| anyhow!("failed to decode data: {e}"))?;
+ ensure!(
+ !data.encrypted,
+ "you can not decrypt secret data, only decode public."
+ );
+ stdout().write_all(&data.data)?;
+ }
}
Ok(())
}