Skip to content

Commit

Permalink
Add support for namespaces signature verification
Browse files Browse the repository at this point in the history
  • Loading branch information
thibmeu committed May 31, 2024
1 parent e3a841e commit d69fa77
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 56 deletions.
38 changes: 29 additions & 9 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ resolver = "2"
bincode = "2.0.0-rc.3"
ed25519-dalek = { version = "2" }
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.192", features = ["derive"] }
serde_json = "1.0.108"
serde = "1.0.203"
serde_json = "1.0.117"
uuid = { version = "1.8.0", features = ["v4", "serde"] }


Expand Down
2 changes: 1 addition & 1 deletion plexi_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name = "plexi"
path = "src/main.rs"

[dependencies]
anyhow = "1.0.81"
anyhow = "1.0.86"
clap = { version = "4.5.4", features = ["derive"] }
clap-verbosity-flag = "2.2.0"
ed25519-dalek = { workspace = true }
Expand Down
14 changes: 11 additions & 3 deletions plexi_cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

use clap::{Parser, Subcommand};

/// 1. First interaction
Expand All @@ -20,22 +22,28 @@ pub struct Cli {
pub enum Commands {
#[command(verbatim_doc_comment)]
Verify {
/// Namespace ID
# [arg(short, long)]
namespace: String,
/// Ed25519 public key in hex format.
#[arg(long)]
publickey: String,
/// Path to a file to read from.
input: Option<String>,
input: Option<PathBuf>,
},
#[command(verbatim_doc_comment)]
Sign {
/// Namespace ID
# [arg(short, long)]
namespace: String,
/// Ed25519 signing key in hex format.
#[arg(long)]
signingkey: String,
/// Write the result to the file at path OUTPUT.
#[arg(short, long)]
output: Option<String>,
output: Option<PathBuf>,
/// Path to a file to read from.
input: Option<String>,
input: Option<PathBuf>,
},
}

Expand Down
24 changes: 15 additions & 9 deletions plexi_cli/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::{fs, io};
use std::{fs, io, path::PathBuf};

// TODO: consider color_eyre, and chaining with [.context](https://docs.rs/anyhow/latest/anyhow/trait.Context.html#tymethod.context)
use anyhow::{anyhow, Result};
use ed25519_dalek::{ed25519::signature::SignerMut, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH};
use plexi_core::{SignatureMessage, SignatureResponse};

pub fn file_or_stdin(input: Option<String>) -> Result<Box<dyn io::Read>> {
pub fn file_or_stdin(input: Option<PathBuf>) -> Result<Box<dyn io::Read>> {
let reader: Box<dyn io::Read> = match input {
Some(path) => Box::new(io::BufReader::new(
fs::File::open(path).map_err(|_e| anyhow!("cannot read input file"))?,
Expand All @@ -14,7 +15,7 @@ pub fn file_or_stdin(input: Option<String>) -> Result<Box<dyn io::Read>> {
Ok(reader)
}

pub fn file_or_stdout(output: Option<String>) -> Result<Box<dyn io::Write>> {
pub fn file_or_stdout(output: Option<PathBuf>) -> Result<Box<dyn io::Write>> {
let writer: Box<dyn io::Write> = match output {
Some(path) => Box::new(io::BufWriter::new(
fs::File::create(path).map_err(|_e| anyhow!("cannot create output file"))?,
Expand All @@ -24,7 +25,7 @@ pub fn file_or_stdout(output: Option<String>) -> Result<Box<dyn io::Write>> {
Ok(writer)
}

pub fn sign(signingkey: &str, output: Option<String>, input: Option<String>) -> Result<String> {
pub fn sign(namespace: &str, signingkey: &str, output: Option<PathBuf>, input: Option<PathBuf>) -> Result<String> {
let src = file_or_stdin(input)?;
let dst = file_or_stdout(output)?;

Expand All @@ -40,8 +41,9 @@ pub fn sign(signingkey: &str, output: Option<String>, input: Option<String>) ->
let signature = secret_key.sign(&message.to_vec()?);

let signature_response = SignatureResponse::new(
namespace.to_string(),
message.timestamp(),
message.epoch(),
&message.epoch(),
message.digest(),
signature.to_vec(),
);
Expand All @@ -51,24 +53,28 @@ pub fn sign(signingkey: &str, output: Option<String>, input: Option<String>) ->
Ok("".to_string())
}

pub fn verify(publickey: &str, input: Option<String>) -> Result<String> {
pub fn verify(namespace: &str, public_key: &str, input: Option<PathBuf>) -> Result<String> {
let src = file_or_stdin(input)?;

let signature_response: SignatureResponse = serde_json::from_reader(src)?;

let public_key: [u8; PUBLIC_KEY_LENGTH] = hex::decode(publickey)
if signature_response.namespace() != namespace {
return Err(anyhow!("namespace does not match"));
}

let public_key: [u8; PUBLIC_KEY_LENGTH] = hex::decode(public_key)
.map_err(|_e| anyhow!("cannot decode public key"))?
.as_slice()
.try_into()
.map_err(|_e| anyhow!("cannot convert public key"))?;
let publickey = ed25519_dalek::VerifyingKey::from_bytes(&public_key)
let public_key = ed25519_dalek::VerifyingKey::from_bytes(&public_key)
.map_err(|_| anyhow!("cannot create public key"))?;

let signature = ed25519_dalek::Signature::from_bytes(&signature_response.signature());

let message: SignatureMessage = signature_response.into();

publickey
public_key
.verify_strict(&message.to_vec()?, &signature)
.map_err(|_e| anyhow!("cannot verify signature"))?;

Expand Down
9 changes: 7 additions & 2 deletions plexi_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ fn main() {
.init();

let output = match cli.command {
cli::Commands::Verify { publickey, input } => cmd::verify(&publickey, input),
cli::Commands::Verify {
namespace,
publickey: public_key,
input,
} => cmd::verify(&namespace, &public_key, input),
cli::Commands::Sign {
namespace,
signingkey,
output,
input,
} => cmd::sign(&signingkey, output, input),
} => cmd::sign(&namespace, &signingkey, output, input),
};

match output {
Expand Down
6 changes: 3 additions & 3 deletions plexi_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ categories = ["cryptography"]
license = "Apache-2.0"

[dependencies]
anyhow = "1.0.81"
bincode = { workspace = true }
ed25519-dalek = { workspace = true }
hex = { workspace = true, features = ["serde"] }
serde = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
uuid = { workspace = true, features = ["v4", "serde"] }
thiserror = "1.0.61"
uuid = { workspace = true, features = ["v4", "serde"] }
Loading

0 comments on commit d69fa77

Please sign in to comment.