Skip to content

Commit

Permalink
features: support text sign, part II
Browse files Browse the repository at this point in the history
  • Loading branch information
rcrwhyg committed Aug 28, 2024
1 parent d434b81 commit 55383f9
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 64 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"cSpell.words": [
"ABCDEFGHIJKMNPQRSTUVWXYZ",
"csprng",
"dalek",
"genpass",
"rcli",
"subcmd",
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ base64 = "0.22.1"
blake3 = "1.5.4"
clap = { version = "4.5.16", features = ["derive"] }
csv = "1.3.0"
ed25519-dalek = "2.1.1"
ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }
rand = "0.8.5"
serde = { version = "1.0.209", features = ["derive"] }
serde_json = "1.0.127"
Expand Down
2 changes: 2 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ allow = [
"MIT",
"Apache-2.0",
"Unicode-DFS-2016",
"BSD-2-Clause",
"BSD-3-Clause",
#"Apache-2.0 WITH LLVM-exception",
]
# The confidence threshold for detecting a license from license text.
Expand Down
2 changes: 1 addition & 1 deletion fixtures/blake3.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SAI5V%f$1!HvIqB+AZX2QqA-g_fEEGMY
aT#pJeQ*^R^v76ydGP@!jjFWnu^1b^d@
1 change: 1 addition & 0 deletions fixtures/ed25519.pk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
y�1�m�S;e��i��^��e�<�N���2��
1 change: 1 addition & 0 deletions fixtures/ed25519.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:�K����A��K��]�Ѹ-�xz����ݕ
11 changes: 10 additions & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod csv;
mod genpass;
mod text;

use std::path::Path;
use std::path::{Path, PathBuf};

use self::{csv::CsvOpts, genpass::GenPassOpts};
use clap::Parser;
Expand Down Expand Up @@ -42,6 +42,15 @@ pub fn verify_file(filename: &str) -> Result<String, &'static str> {
}
}

pub fn verify_path(path: &str) -> Result<PathBuf, &'static str> {
let p = Path::new(path);
if p.exists() && p.is_dir() {
Ok(path.into())
} else {
Err("Path does not exist or is not a directory")
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 13 additions & 3 deletions src/cli/text.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use std::{fmt, str::FromStr};
use std::{fmt, path::PathBuf, str::FromStr};

use clap::Parser;

use super::verify_file;
use super::{verify_file, verify_path};

#[derive(Debug, Parser)]
pub enum TextSubCommand {
#[command(about = "Sign a message with a private/shared key")]
Sign(TextSignOpts),
#[command(name = "verify", about = "Verify a signed message")]
#[command(about = "Verify a signed message")]
Verify(TextVerifyOpts),
#[command(about = "Generate a new key")]
Generate(TextKeyGenerateOpts),
}

#[derive(Debug, Parser)]
Expand All @@ -34,6 +36,14 @@ pub struct TextVerifyOpts {
pub sig: String,
}

#[derive(Debug, Parser)]
pub struct TextKeyGenerateOpts {
#[arg(short, long, value_parser = parse_format, default_value = "blake3")]
pub format: TextSignFormat,
#[arg(short, long, value_parser = verify_path)]
pub output: PathBuf,
}

#[derive(Debug, Clone, Copy)]
pub enum TextSignFormat {
Blake3,
Expand Down
66 changes: 44 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::os::unix::process;
use std::fs;

use clap::Parser;
use rcli::{
process_csv, process_decode, process_encode, process_genpass, process_text_sign,
Base64SubCommand, Opts, Subcommand, TextSubCommand,
process_csv, process_decode, process_encode, process_genpass, process_text_generate,
process_text_sign, process_text_verify, Base64SubCommand, Opts, Subcommand, TextSignFormat,
TextSubCommand,
};
use zxcvbn::zxcvbn;

fn main() -> anyhow::Result<()> {
let opts: Opts = Opts::parse();
Expand All @@ -17,33 +19,53 @@ fn main() -> anyhow::Result<()> {
};
process_csv(&opts.input, output, opts.format)?;
}
Subcommand::GenPass(opts) => process_genpass(
opts.length,
opts.uppercase,
opts.lowercase,
opts.number,
opts.symbol,
)?,
Subcommand::GenPass(opts) => {
let password = process_genpass(
opts.length,
opts.uppercase,
opts.lowercase,
opts.number,
opts.symbol,
)?;
println!("{}", password);

let estimate = zxcvbn(&password, &[]);
eprintln!("Password strength: {}", estimate.score());
}
Subcommand::Base64(subcmd) => match subcmd {
Base64SubCommand::Encode(opts) => {
process_encode(&opts.input, opts.format)?;
let encoded = process_encode(&opts.input, opts.format)?;
println!("{}", encoded);
}
Base64SubCommand::Decode(opts) => {
process_decode(&opts.input, opts.format)?;
let decoded = process_decode(&opts.input, opts.format)?;
// TODO: decoded data might not be string (but for this example, we assume it is)
let decoded = String::from_utf8(decoded)?;
println!("{}", decoded);
}
},
Subcommand::Text(subcmd) => match subcmd {
TextSubCommand::Sign(opts) => match opts.format {
rcli::TextSignFormat::Blake3 => {
process_text_sign(&opts.input, &opts.key, opts.format);
}

rcli::TextSignFormat::Ed25519 => {
println!("Sign with Ed25519")
}
},
TextSubCommand::Sign(opts) => {
let sig = process_text_sign(&opts.input, &opts.key, opts.format)?;
println!("{}", sig);
}
TextSubCommand::Verify(opts) => {
println!("{:?}", opts);
let verified = process_text_verify(&opts.input, &opts.key, opts.format, &opts.sig)?;
println!("{}", verified);
}
TextSubCommand::Generate(opts) => {
let key = process_text_generate(opts.format)?;
match opts.format {
TextSignFormat::Blake3 => {
let name = opts.output.join("blake3.txt");
fs::write(name, &key[0])?;
}
TextSignFormat::Ed25519 => {
let name = opts.output;
fs::write(name.join("ed25519.sk"), &key[0])?;
fs::write(name.join("ed25519.pk"), &key[1])?;
}
}
}
},
}
Expand Down
15 changes: 5 additions & 10 deletions src/process/b64.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs::File, io::Read};
use std::io::Read;

use base64::{
engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD},
Expand All @@ -7,7 +7,7 @@ use base64::{

use crate::{cli::Base64Format, get_reader};

pub fn process_encode(input: &str, format: Base64Format) -> anyhow::Result<()> {
pub fn process_encode(input: &str, format: Base64Format) -> anyhow::Result<String> {
let mut reader: Box<dyn Read> = get_reader(input)?;

let mut buf = Vec::new();
Expand All @@ -18,11 +18,10 @@ pub fn process_encode(input: &str, format: Base64Format) -> anyhow::Result<()> {
Base64Format::UrlSafe => URL_SAFE_NO_PAD.encode(&buf),
};

println!("{}", encoded);
Ok(())
Ok(encoded)
}

pub fn process_decode(input: &str, format: Base64Format) -> anyhow::Result<()> {
pub fn process_decode(input: &str, format: Base64Format) -> anyhow::Result<Vec<u8>> {
let mut reader: Box<dyn Read> = get_reader(input)?;

let mut buf = String::new();
Expand All @@ -35,11 +34,7 @@ pub fn process_decode(input: &str, format: Base64Format) -> anyhow::Result<()> {
Base64Format::UrlSafe => URL_SAFE_NO_PAD.decode(buf)?,
};

// TODO: decoded data might not be string (but for this example, we assume it is)
let decoded = String::from_utf8(decoded)?;
println!("{}", decoded);

Ok(())
Ok(decoded)
}

#[cfg(test)]
Expand Down
10 changes: 2 additions & 8 deletions src/process/gen_pass.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rand::seq::SliceRandom;
use zxcvbn::zxcvbn;

const UPPER: &[u8] = b"ABCDEFGHIJKMNPQRSTUVWXYZ";
const LOWER: &[u8] = b"abcdefghijkmnpqrstuvwxyz";
Expand All @@ -12,7 +11,7 @@ pub fn process_genpass(
lower: bool,
number: bool,
symbol: bool,
) -> anyhow::Result<()> {
) -> anyhow::Result<String> {
let mut rng = rand::thread_rng();
let mut password = Vec::new();
let mut chars = Vec::new();
Expand Down Expand Up @@ -44,11 +43,6 @@ pub fn process_genpass(
password.shuffle(&mut rng);

let password = String::from_utf8(password)?;
println!("{}", password);

// output password strength in stderr
let estimate = zxcvbn(&password, &[]);
eprintln!("Password strength: {}", estimate.score());

Ok(())
Ok(password)
}
2 changes: 1 addition & 1 deletion src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ mod text;
pub use b64::{process_decode, process_encode};
pub use csv_convert::process_csv;
pub use gen_pass::process_genpass;
pub use text::process_text_sign;
pub use text::{process_text_generate, process_text_sign, process_text_verify};
Loading

0 comments on commit 55383f9

Please sign in to comment.