Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 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 @@ -7,7 +7,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.6.0"
version = "0.6.1"
authors = [
"Akshat Mahajan <akshat@cloudflare.com>",
"Gauri Baraskar <gbaraskar@cloudflare.com>",
Expand Down Expand Up @@ -35,4 +35,4 @@ regex = "1.12.2"
time = { version = "0.3.44" }

# workspace dependencies
web-bot-auth = { version = "0.6.0", path = "./crates/web-bot-auth" }
web-bot-auth = { version = "0.6.1", path = "./crates/web-bot-auth" }
2 changes: 1 addition & 1 deletion crates/web-bot-auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ mod tests {
&mut mytest,
time::Duration::seconds(10),
Algorithm::Ed25519,
&private_key.to_vec(),
&private_key,
)
.unwrap();

Expand Down
83 changes: 64 additions & 19 deletions crates/web-bot-auth/src/message_signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,60 @@ pub trait UnsignedMessage {
fn register_header_contents(&mut self, signature_input: String, signature_header: String);
}

/// Trait that provides interface to generate signatures given a message and an algorithm.
/// This is implemented for `Vec<u8>` and friends as a batteries-included way to generate
/// signatures from raw key material, but can be implemented for any type of client-controlled
/// signer as well (yubikey, cloud kms, web3 wallet, etc).
pub trait GenerateSignature {
/// Generate signature given the algorithm and the message to sign.
fn generate_signature(
&self,
algorithm: Algorithm,
msg: &[u8],
) -> Result<Vec<u8>, ImplementationError>;
}

impl GenerateSignature for [u8] {
fn generate_signature(
&self,
algorithm: Algorithm,
msg: &[u8],
) -> Result<Vec<u8>, ImplementationError> {
let signature = match algorithm {
Algorithm::Ed25519 => {
use ed25519_dalek::{Signer, SigningKey};
let signing_key_dalek = SigningKey::try_from(self)
.map_err(|_| ImplementationError::InvalidKeyLength)?;

signing_key_dalek.sign(msg).to_vec()
}
other => return Err(ImplementationError::UnsupportedAlgorithm(other)),
};

Ok(signature)
}
}

impl GenerateSignature for Vec<u8> {
fn generate_signature(
&self,
algorithm: Algorithm,
msg: &[u8],
) -> Result<Vec<u8>, ImplementationError> {
self.as_slice().generate_signature(algorithm, msg)
}
}

impl GenerateSignature for [u8; 32] {
fn generate_signature(
&self,
algorithm: Algorithm,
msg: &[u8],
) -> Result<Vec<u8>, ImplementationError> {
self.as_slice().generate_signature(algorithm, msg)
}
}

/// A struct that implements signing. The struct fields here are serialized into the `Signature-Input`
/// header.
pub struct MessageSigner {
Expand All @@ -273,7 +327,7 @@ pub struct MessageSigner {
}

impl MessageSigner {
/// Sign the provided method with `signing_key`, setting an expiration value of
/// Sign the provided method with `signer`, setting an expiration value of
/// length `expires` from now (the time of signing).
///
/// # Errors
Expand All @@ -285,7 +339,7 @@ impl MessageSigner {
message: &mut impl UnsignedMessage,
expires: Duration,
algorithm: Algorithm,
signing_key: &Vec<u8>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a great change! Looks good to me and is a great addition

signer: &(impl GenerateSignature + ?Sized),
) -> Result<(), ImplementationError> {
let components_to_cover = message.fetch_components_to_cover();
let mut sfv_parameters = sfv::Parameters::new();
Expand Down Expand Up @@ -361,22 +415,13 @@ impl MessageSigner {
}
.into_ascii()?;

let signature = match algorithm {
Algorithm::Ed25519 => {
use ed25519_dalek::{Signer, SigningKey};
let signing_key_dalek = SigningKey::try_from(signing_key.as_slice())
.map_err(|_| ImplementationError::InvalidKeyLength)?;

sfv::Item {
bare_item: sfv::BareItem::ByteSequence(
signing_key_dalek.sign(signature_base.as_bytes()).to_vec(),
),
params: sfv::Parameters::new(),
}
.serialize_value()
}
other => return Err(ImplementationError::UnsupportedAlgorithm(other)),
};
let signature = sfv::Item {
bare_item: sfv::BareItem::ByteSequence(
signer.generate_signature(algorithm, signature_base.as_bytes())?,
),
params: sfv::Parameters::new(),
}
.serialize_value();

message.register_header_contents(signature_params_content, signature);

Expand Down Expand Up @@ -670,7 +715,7 @@ mod tests {
&mut test,
Duration::seconds(10),
Algorithm::Ed25519,
&private_key.to_vec()
&private_key
)
.is_ok()
);
Expand Down
2 changes: 1 addition & 1 deletion examples/signature-agent-card-and-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ async fn fetch(req: HttpRequest, env: Env, _ctx: Context) -> Result<Response> {
&mut generator,
Duration::seconds(10),
Algorithm::Ed25519,
&(signing_key.as_bytes().to_vec()),
signing_key.as_bytes(),
)
.unwrap();
Ok(response)
Expand Down