Skip to content

Commit

Permalink
refactor: split lib into lib and extension
Browse files Browse the repository at this point in the history
  • Loading branch information
junkurihara committed Feb 4, 2024
1 parent 28b5527 commit 72ca78a
Show file tree
Hide file tree
Showing 18 changed files with 134 additions and 93 deletions.
76 changes: 12 additions & 64 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,64 +1,12 @@
[package]
name = "httpsig-rs"
version = "0.1.0"
edition = "2021"
description = "Implementation of IETF draft of http message signatures"
authors = ["Jun Kurihara"]
homepage = "https://github.com/junkurihara/httpsig-rs"
repository = "https://github.com/junkurihara/httpsig-rs"
license = "MIT"
readme = "../README.md"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# serde = { version = "1.0.193", default-features = false, features = ["derive"] }
# serde_json = "1.0.108"
anyhow = { version = "1.0.79" }
tracing = { version = "0.1.40" }
rustc-hash = { version = "1.1.0" }
rand = { version = "0.8.5" }

# crypto
pkcs8 = { version = "0.10.2", default-features = false, features = ["pem"] }
spki = { version = "0.7.3", default-features = false, features = ["pem"] }
sec1 = { version = "0.7.3", default-features = false, features = ["der"] }
ed25519-compact = { version = "2.0.6", default-features = false, features = [
"random",
] }
ecdsa = { version = "0.16.9", default-features = false, features = [
"arithmetic",
] }
p256 = { version = "0.13.2", default-features = false, features = [
"arithmetic",
"ecdsa",
] }
p384 = { version = "0.13.0", default-features = false, features = [
"arithmetic",
"ecdsa",
] }
hmac = { version = "0.12.1" }
sha2 = { version = "0.10.8", default-features = false }

# encoding
base64 = { version = "0.21.6" }

# for request and response headers
http = { version = "1.0.0" }
http-body = { version = "1.0.0" }
http-body-util = { version = "0.1.0" }
bytes = { version = "1.5.0" }

#
async-trait = "0.1.77"
url = "2.5.0"

# for rfc8941 structured field values
sfv = "0.9.4"

[dev-dependencies]
tokio = { version = "1.35.1", default-features = false, features = [
"macros",
"rt-multi-thread",
] } # testing only?
[workspace]

members = ["lib", "ext-hyper"]
resolver = "2"

[profile.release]
codegen-units = 1
incremental = false
lto = "fat"
opt-level = 3
panic = "abort"
strip = true
39 changes: 39 additions & 0 deletions ext-hyper/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[package]
name = "httpsig-hyper"
version = "0.1.0"
edition = "2021"
description = "Hyper extension for http message signatures"
authors = ["Jun Kurihara"]
homepage = "https://github.com/junkurihara/httpsig-rs"
repository = "https://github.com/junkurihara/httpsig-rs"
license = "MIT"
readme = "../README.md"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
httpsig = { path = "../lib" }

anyhow = { version = "1.0.79" }
tracing = { version = "0.1.40" }
async-trait = { version = "0.1.77" }

# content digest
sha2 = { version = "0.10.8", default-features = false }

# encoding
base64 = { version = "0.21.6" }

# for request and response headers
http = { version = "1.0.0" }
http-body = { version = "1.0.0" }
http-body-util = { version = "0.1.0" }
bytes = { version = "1.5.0" }


[dev-dependencies]
tokio = { version = "1.35.1", default-features = false, features = [
"macros",
"rt-multi-thread",
] } # testing only?
File renamed without changes.
12 changes: 6 additions & 6 deletions src/ext/hyper_http.rs → ext-hyper/src/hyper_http.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::{
use anyhow::{bail, ensure};
use async_trait::async_trait;
use http::Request;
use http_body::Body;
use httpsig::prelude::{
message_component::{
build_http_message_component, DerivedComponentName, HttpMessageComponent, HttpMessageComponentId, HttpMessageComponentName,
HttpMessageComponentParam,
},
// signature_base::SignatureBase,
signature_params::HttpSignatureParams,
};
use anyhow::{bail, ensure};
use async_trait::async_trait;
use http::Request;
use http_body::Body;
//

// hyper's http specific extension to generate and verify http signature

Expand Down
File renamed without changes.
46 changes: 46 additions & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "httpsig"
version = "0.1.0"
edition = "2021"
description = "Implementation of IETF draft of http message signatures"
authors = ["Jun Kurihara"]
homepage = "https://github.com/junkurihara/httpsig-rs"
repository = "https://github.com/junkurihara/httpsig-rs"
license = "MIT"
readme = "../README.md"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = { version = "1.0.79" }
tracing = { version = "0.1.40" }
rustc-hash = { version = "1.1.0" }
rand = { version = "0.8.5" }

# crypto
pkcs8 = { version = "0.10.2", default-features = false, features = ["pem"] }
spki = { version = "0.7.3", default-features = false, features = ["pem"] }
sec1 = { version = "0.7.3", default-features = false, features = ["der"] }
ed25519-compact = { version = "2.0.6", default-features = false, features = [
"random",
] }
ecdsa = { version = "0.16.9", default-features = false, features = [
"arithmetic",
] }
p256 = { version = "0.13.2", default-features = false, features = [
"arithmetic",
"ecdsa",
] }
p384 = { version = "0.13.0", default-features = false, features = [
"arithmetic",
"ecdsa",
] }
hmac = { version = "0.12.1" }
sha2 = { version = "0.10.8", default-features = false }

# encoding
base64 = { version = "0.21.6" }

# for rfc8941 structured field values
sfv = "0.9.4"
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 12 additions & 1 deletion src/lib.rs → lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod crypto;
mod ext;
mod message_component;
mod signature_base;
mod signature_params;
Expand All @@ -12,6 +11,18 @@ use crate::{
// signature_params::{HttpSignatureParams, HttpSignatureParamsBuilder},
};

pub mod prelude {
pub mod message_component {
pub use crate::message_component::{
build_http_message_component, DerivedComponentName, HttpMessageComponent, HttpMessageComponentId, HttpMessageComponentName,
HttpMessageComponentParam,
};
}
pub mod signature_params {
pub use crate::signature_params::HttpSignatureParams;
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ use rustc_hash::FxHashSet as HashSet;
/* ---------------------------------------------------------------- */
#[derive(Debug, Clone)]
/// Http message component
pub(crate) struct HttpMessageComponent {
pub struct HttpMessageComponent {
/// Http message component id
pub(crate) id: HttpMessageComponentId,
pub id: HttpMessageComponentId,
/// Http message component value
pub(crate) value: HttpMessageComponentValue,
pub value: HttpMessageComponentValue,
}

impl HttpMessageComponent {
/// Create HttpMessageComponent from serialized string, i.e., `"<id>": <value>` in the signature input
pub(crate) fn from_serialized_str(serialized_str: &str) -> std::result::Result<Self, anyhow::Error> {
pub fn from_serialized_str(serialized_str: &str) -> std::result::Result<Self, anyhow::Error> {
let Some((id, value)) = serialized_str.split_once(':') else {
bail!("Invalid http message component: {}", serialized_str);
};
Expand Down Expand Up @@ -68,16 +68,16 @@ impl std::fmt::Display for HttpMessageComponent {
/* ---------------------------------------------------------------- */
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
/// Http message component id
pub(crate) struct HttpMessageComponentId {
pub struct HttpMessageComponentId {
/// Http message component name
pub(crate) name: HttpMessageComponentName,
pub name: HttpMessageComponentName,
/// Http message component params
pub(crate) params: HttpMessageComponentParams,
pub params: HttpMessageComponentParams,
}

impl HttpMessageComponentId {
/// Add `req` field param to the component, which is used to generate signature input for response from its corresponding request.
pub(crate) fn add_req_param(&mut self) {
pub fn add_req_param(&mut self) {
self.params.0.insert(HttpMessageComponentParam::Req);
}
}
Expand Down Expand Up @@ -148,7 +148,7 @@ impl TryFrom<(&str, &str)> for HttpMessageComponentId {
/* ---------------------------------------------------------------- */
#[derive(Debug, Clone, PartialEq, Eq)]
/// Http message component value
pub(crate) struct HttpMessageComponentValue {
pub struct HttpMessageComponentValue {
/// inner value originally from http message header or derived from http message
inner: String,
}
Expand All @@ -168,7 +168,7 @@ impl std::fmt::Display for HttpMessageComponentValue {
/* ---------------------------------------------------------------- */
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
/// Http message component identifier
pub(crate) enum HttpMessageComponentName {
pub enum HttpMessageComponentName {
/// Http field component, which is in the form of `<field_name>` without being wrapped by double quotations
HttpField(String),
/// Derived component
Expand Down Expand Up @@ -198,7 +198,7 @@ impl std::fmt::Display for HttpMessageComponentName {
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
/// Http message component parameters that appends with `;` in the signature input
/// https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#secion-2.1
pub(crate) enum HttpMessageComponentParam {
pub enum HttpMessageComponentParam {
/// sf: https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#section-2.1.1
Sf,
/// key: https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#section-2.1.2
Expand Down Expand Up @@ -248,7 +248,7 @@ impl From<&str> for HttpMessageComponentParam {
}

#[derive(PartialEq, Eq, Debug, Clone)]
pub(crate) struct HttpMessageComponentParams(pub(crate) HashSet<HttpMessageComponentParam>);
pub struct HttpMessageComponentParams(pub HashSet<HttpMessageComponentParam>);
impl std::hash::Hash for HttpMessageComponentParams {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let mut params = self.0.iter().map(|v| v.clone().into()).collect::<Vec<String>>();
Expand Down Expand Up @@ -286,7 +286,7 @@ impl std::fmt::Display for HttpMessageComponentParams {
#[derive(PartialEq, Eq, Clone, Hash, Debug)]
/// Derive components from http message, which is expressed as @method, @path, @authority, etc. in @signature-params
/// https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#name-derived-components
pub(crate) enum DerivedComponentName {
pub enum DerivedComponentName {
Method,
TargetUri,
Authority,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod component;
mod parse;

pub(crate) use component::{
pub use component::{
DerivedComponentName, HttpMessageComponent, HttpMessageComponentId, HttpMessageComponentName, HttpMessageComponentParam,
HttpMessageComponentValue,
};
pub(crate) use parse::build_http_message_component;
pub use parse::build_http_message_component;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use anyhow::{bail, ensure};
use sfv::{Parser, SerializeValue};

/// Build http message component from given id and its associated field values
pub(crate) fn build_http_message_component(
pub fn build_http_message_component(
id: &HttpMessageComponentId,
field_values: &[String],
) -> anyhow::Result<HttpMessageComponent> {
Expand Down
9 changes: 3 additions & 6 deletions src/signature_base.rs → lib/src/signature_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{message_component::HttpMessageComponent, signature_params::HttpSigna

/// Signature Base
/// https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-19.html#section-2.5
pub(crate) struct SignatureBase {
pub struct SignatureBase {
/// HTTP message field and derived components ordered as in the vector in signature params
component_lines: Vec<HttpMessageComponent>,
/// signature params
Expand All @@ -14,10 +14,7 @@ impl SignatureBase {
/// This should not be exposed to user and not used directly.
/// TODO: Use wrapper functions generating SignatureBase from base HTTP request and Signer itself instead when newly generating signature
/// TODO: When verifying signature, use wrapper functions generating SignatureBase from HTTP request containing signature params itself instead.
pub(crate) fn try_new(
component_lines: &Vec<HttpMessageComponent>,
signature_params: &HttpSignatureParams,
) -> anyhow::Result<Self> {
pub fn try_new(component_lines: &Vec<HttpMessageComponent>, signature_params: &HttpSignatureParams) -> anyhow::Result<Self> {
// check if the order of component lines is the same as the order of covered message component ids
if component_lines.len() != signature_params.covered_components.len() {
anyhow::bail!("The number of component lines is not the same as the number of covered message component ids");
Expand All @@ -38,7 +35,7 @@ impl SignatureBase {
}

/// Returns the signature base string as bytes to be signed
pub(crate) fn as_bytes(&self) -> Vec<u8> {
pub fn as_bytes(&self) -> Vec<u8> {
let string = self.to_string();
string.as_bytes().to_vec()
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 72ca78a

Please sign in to comment.