Patch rama-crypto to drop bindgen

This commit is contained in:
viyatb-oai
2026-01-12 18:21:03 -08:00
parent 981c7c3261
commit 74d748cefb
14 changed files with 3659 additions and 56 deletions

View File

@@ -97,14 +97,6 @@ crate.annotation(
},
)
crate.annotation(
crate = "rama-crypto",
patch_args = ["-p1"],
patches = [
"//patches:rama-crypto-no-bindgen.patch",
],
)
# Fix readme inclusions
crate.annotation(
crate = "windows-link",

42
codex-rs/Cargo.lock generated
View File

@@ -667,27 +667,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "aws-lc-fips-sys"
version = "0.13.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57900537c00a0565a35b63c4c281b372edfc9744b072fd4a3b414350a8f5ed48"
dependencies = [
"bindgen",
"cc",
"cmake",
"dunce",
"fs_extra",
"regex",
]
[[package]]
name = "aws-lc-rs"
version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288"
dependencies = [
"aws-lc-fips-sys",
"aws-lc-sys",
"untrusted 0.7.1",
"zeroize",
@@ -699,7 +684,6 @@ version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1"
dependencies = [
"bindgen",
"cc",
"cmake",
"dunce",
@@ -796,9 +780,7 @@ dependencies = [
"bitflags 2.10.0",
"cexpr",
"clang-sys",
"itertools 0.13.0",
"log",
"prettyplease",
"itertools 0.10.5",
"proc-macro2",
"quote",
"regex",
@@ -3916,7 +3898,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.6.1",
"socket2 0.5.10",
"system-configuration",
"tokio",
"tower-service",
@@ -5731,16 +5713,6 @@ dependencies = [
"yansi",
]
[[package]]
name = "prettyplease"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2"
dependencies = [
"proc-macro2",
"syn 2.0.104",
]
[[package]]
name = "proc-macro-crate"
version = "3.4.0"
@@ -5805,7 +5777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425"
dependencies = [
"anyhow",
"itertools 0.13.0",
"itertools 0.10.5",
"proc-macro2",
"quote",
"syn 2.0.104",
@@ -5891,7 +5863,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls",
"socket2 0.6.1",
"socket2 0.5.10",
"thiserror 2.0.17",
"tokio",
"tracing",
@@ -5928,7 +5900,7 @@ dependencies = [
"cfg_aliases 0.2.1",
"libc",
"once_cell",
"socket2 0.6.1",
"socket2 0.5.10",
"tracing",
"windows-sys 0.60.2",
]
@@ -6047,8 +6019,6 @@ dependencies = [
[[package]]
name = "rama-crypto"
version = "0.3.0-alpha.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91965fc4cb4bc45bd2980f6388f97dbc955bcf164fdbd81fc0e9155c4e9abe2f"
dependencies = [
"aws-lc-rs",
"base64",
@@ -9246,7 +9216,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.48.0",
]
[[package]]

View File

@@ -301,6 +301,7 @@ opt-level = 0
# ratatui = { path = "../../ratatui" }
crossterm = { git = "https://github.com/nornagon/crossterm", branch = "nornagon/color-query" }
ratatui = { git = "https://github.com/nornagon/ratatui", branch = "nornagon-v0.29.0-patch" }
rama-crypto = { path = "vendor/rama-crypto" }
# Uncomment to debug local changes.
# rmcp = { path = "../../rust-sdk/crates/rmcp" }

View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "766bbc6ff5ec1a5a2fb0af31caa66e90dfd2d1ff"
},
"path_in_vcs": "rama-crypto"
}

1744
codex-rs/vendor/rama-crypto/Cargo.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff

148
codex-rs/vendor/rama-crypto/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,148 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2024"
rust-version = "1.88.0"
name = "rama-crypto"
version = "0.3.0-alpha.3"
authors = ["Glen De Cauwsemaecker <glen@plabayo.tech>"]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "All crypto logic used by rama"
readme = "README.md"
keywords = [
"cyrpto",
"security",
"certificates",
"network",
"rama",
]
categories = [
"asynchronous",
"network-programming",
"web-programming",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/plabayo/rama"
[package.metadata.cargo-public-api-crates]
allowed = []
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[features]
default = []
[lib]
name = "rama_crypto"
path = "src/lib.rs"
[dependencies.aws-lc-rs]
version = "1.13"
[dependencies.base64]
version = "0.22"
[dependencies.rama-core]
version = "0.3.0-alpha.3"
[dependencies.rama-utils]
version = "0.3.0-alpha.3"
[dependencies.rcgen]
version = "0.14"
features = [
"pem",
"aws_lc_rs",
"x509-parser",
]
default-features = false
[dependencies.rustls-pki-types]
version = "^1"
[dependencies.serde]
version = "1.0"
[dependencies.serde_json]
version = "1.0"
[dependencies.x509-parser]
version = "0.18"
[dev-dependencies.tokio]
version = "1.47"
features = ["full"]
[dev-dependencies.tokio-test]
version = "0.4"
[lints.clippy]
await_holding_lock = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
equatable_if_let = "warn"
exit = "warn"
filter_map_next = "warn"
fn_params_excessive_bools = "warn"
if_let_mutex = "warn"
implicit_clone = "warn"
imprecise_flops = "warn"
inefficient_to_string = "warn"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
manual_let_else = "warn"
match_same_arms = "warn"
match_wildcard_for_single_variants = "warn"
mem_forget = "warn"
must_use_candidate = "warn"
needless_borrow = "warn"
needless_continue = "warn"
needless_pass_by_ref_mut = "warn"
needless_pass_by_value = "warn"
option_option = "warn"
redundant_clone = "warn"
ref_option = "warn"
rest_pat_in_fully_bound_structs = "warn"
return_self_not_must_use = "warn"
single_match_else = "warn"
str_to_string = "warn"
suboptimal_flops = "warn"
todo = "warn"
trivially_copy_pass_by_ref = "warn"
type_complexity = "allow"
unnested_or_patterns = "warn"
unused_self = "warn"
use_self = "warn"
verbose_file_reads = "warn"
[lints.clippy.all]
level = "warn"
priority = -1
[lints.rust]
unreachable_pub = "deny"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(fuzzing)"]

39
codex-rs/vendor/rama-crypto/Cargo.toml.orig generated vendored Normal file
View File

@@ -0,0 +1,39 @@
[package]
name = "rama-crypto"
description = "All crypto logic used by rama"
version = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
repository = { workspace = true }
keywords = ["cyrpto", "security", "certificates", "network", "rama"]
categories = ["asynchronous", "network-programming", "web-programming"]
authors = { workspace = true }
rust-version = { workspace = true }
[package.metadata.cargo-public-api-crates]
allowed = []
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = []
[dependencies]
aws-lc-rs = { workspace = true }
base64 = { workspace = true }
rama-core = { workspace = true }
rama-utils = { workspace = true }
rcgen = { workspace = true }
rustls-pki-types = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
x509-parser = { workspace = true }
[dev-dependencies]
tokio = { workspace = true, features = ["full"] }
tokio-test = { workspace = true }
[lints]
workspace = true

55
codex-rs/vendor/rama-crypto/README.md vendored Normal file
View File

@@ -0,0 +1,55 @@
[![rama banner](../docs/img/rama_banner.jpeg)](https://ramaproxy.org/)
[![Crates.io][crates-badge]][crates-url]
[![Docs.rs][docs-badge]][docs-url]
[![MIT License][license-mit-badge]][license-mit-url]
[![Apache 2.0 License][license-apache-badge]][license-apache-url]
[![rust version][rust-version-badge]][rust-version-url]
[![Build Status][actions-badge]][actions-url]
[![Discord][discord-badge]][discord-url]
[![Buy Me A Coffee][bmac-badge]][bmac-url]
[![GitHub Sponsors][ghs-badge]][ghs-url]
[![Paypal Donation][paypal-badge]][paypal-url]
[crates-badge]: https://img.shields.io/crates/v/rama-unix.svg
[crates-url]: https://crates.io/crates/rama-unix
[docs-badge]: https://img.shields.io/docsrs/rama-unix/latest
[docs-url]: https://docs.rs/rama-unix/latest/rama_unix/index.html
[license-mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[license-mit-url]: https://github.com/plabayo/rama/blob/main/LICENSE-MIT
[license-apache-badge]: https://img.shields.io/badge/license-APACHE-blue.svg
[license-apache-url]: https://github.com/plabayo/rama/blob/main/LICENSE-APACHE
[rust-version-badge]: https://img.shields.io/badge/rustc-1.85+-blue?style=flat-square&logo=rust
[rust-version-url]: https://www.rust-lang.org
[actions-badge]: https://github.com/plabayo/rama/actions/workflows/CI.yml/badge.svg?branch=main
[actions-url]: https://github.com/plabayo/rama/actions/workflows/CI.yml
[discord-badge]: https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white
[discord-url]: https://discord.gg/29EetaSYCD
[bmac-badge]: https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black
[bmac-url]: https://www.buymeacoffee.com/plabayo
[ghs-badge]: https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA
[ghs-url]: https://github.com/sponsors/plabayo
[paypal-badge]: https://img.shields.io/badge/paypal-contribution?style=for-the-badge&color=blue
[paypal-url]: https://www.paypal.com/donate/?hosted_button_id=P3KCGT2ACBVFE
🦙 Rama (ラマ) is a modular service framework for the 🦀 Rust language to move and transform your network packets.
The reasons behind the creation of rama can be read in [the "Why Rama" chapter](https://ramaproxy.org/book/why_rama).
## rama-crypto
Crypto primitives and dependencies used by rama.
This includes but is not limited to:
- Certificates
- Javascript object signing and encryption (JOSE): JWS, JWK, JWT, JWE...
- Public and private keys
- Signing
Crate used by the end-user `rama` crate.
Learn more about `rama`:
- Github: <https://github.com/plabayo/rama>
- Book: <https://ramaproxy.org/book/>

View File

@@ -0,0 +1,101 @@
use std::ops::Deref;
use aws_lc_rs::signature::{
ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED_SIGNING, EcdsaSigningAlgorithm,
EcdsaVerificationAlgorithm,
};
use rama_core::error::OpaqueError;
use serde::{Deserialize, Serialize};
use crate::jose::JWKEllipticCurves;
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
#[serde(rename_all = "UPPERCASE")]
/// [`JWA`] or JSON Web Algorithms as defined in [`rfc7518`]
///
/// Some algorithms are required to be implemented when supporting
/// JWA, while others are recommended or optional.
///
/// TODO support all algorithms: https://github.com/plabayo/rama/issues/621
///
/// [`rfc7518`]: https://datatracker.ietf.org/doc/html/rfc7518
pub enum JWA {
/// HMAC using SHA-256 (Required)
HS256,
/// HMAC using SHA-384 (Optional)
HS384,
/// HMAC using SHA-512 (Optional)
HS512,
/// RSASSA-PKCS1-v1_5 using SHA-256 (Recommended)
RS256,
/// RSASSA-PKCS1-v1_5 using SHA-384 (Optional)
RS384,
/// RSASSA-PKCS1-v1_5 using SHA-512 (Optional)
RS512,
/// ECDSA using P-256 and SHA-256 (Recommended+)
ES256,
/// ECDSA using P-384 and SHA-384 (Optional)
ES384,
/// ECDSA using P-521 and SHA-512 (Optional)
ES512,
/// RSASSA-PSS using SHA-256 and MGF1 with SHA-256 (Optional)
PS256,
/// RSASSA-PSS using SHA-384 and MGF1 with SHA-384 (Optional)
PS384,
/// RSASSA-PSS using SHA-512 and MGF1 with SHA-512 (Optional)
PS512,
}
impl From<JWKEllipticCurves> for JWA {
fn from(value: JWKEllipticCurves) -> Self {
match value {
JWKEllipticCurves::P256 => Self::ES256,
JWKEllipticCurves::P384 => Self::ES384,
JWKEllipticCurves::P521 => Self::ES512,
}
}
}
impl TryFrom<JWA> for JWKEllipticCurves {
type Error = OpaqueError;
fn try_from(value: JWA) -> Result<Self, Self::Error> {
match value {
JWA::ES256 => Ok(Self::P256),
JWA::ES384 => Ok(Self::P384),
JWA::ES512 => Ok(Self::P521),
JWA::HS256 | JWA::HS384 | JWA::HS512 => Err(OpaqueError::from_display(
"Hmac cannot be converted to elliptic curve",
)),
JWA::RS256 | JWA::RS384 | JWA::RS512 | JWA::PS256 | JWA::PS384 | JWA::PS512 => Err(
OpaqueError::from_display("RSA cannot be converted to elliptic curve"),
),
}
}
}
impl TryFrom<JWA> for &'static EcdsaSigningAlgorithm {
type Error = OpaqueError;
fn try_from(value: JWA) -> Result<Self, Self::Error> {
match value {
JWA::ES256 | JWA::ES512 => Ok(&ECDSA_P256_SHA256_FIXED_SIGNING),
JWA::ES384 => Ok(&ECDSA_P384_SHA384_FIXED_SIGNING),
JWA::HS256 | JWA::HS384 | JWA::HS512 => Err(OpaqueError::from_display(
"Hmac cannot be converted to elliptic curve",
)),
JWA::RS256 | JWA::RS384 | JWA::RS512 | JWA::PS256 | JWA::PS384 | JWA::PS512 => Err(
OpaqueError::from_display("RSA cannot be converted to elliptic curve"),
),
}
}
}
impl TryFrom<JWA> for &'static EcdsaVerificationAlgorithm {
type Error = OpaqueError;
fn try_from(value: JWA) -> Result<Self, Self::Error> {
let signing_algo: &'static EcdsaSigningAlgorithm = value.try_into()?;
Ok(signing_algo.deref())
}
}

View File

@@ -0,0 +1,325 @@
use aws_lc_rs::{
digest::{Digest, SHA256, digest},
pkcs8::Document,
rand::SystemRandom,
signature::{
self, ECDSA_P256_SHA256_FIXED_SIGNING, EcdsaKeyPair, EcdsaSigningAlgorithm,
EcdsaVerificationAlgorithm, KeyPair, Signature,
},
};
use base64::{Engine as _, prelude::BASE64_URL_SAFE_NO_PAD};
use rama_core::error::{ErrorContext, OpaqueError};
use serde::{Deserialize, Serialize, Serializer, ser::SerializeStruct};
use crate::jose::{JWA, Signer};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
/// [`JWK`] or JSON Web Key as defined in [`rfc7517`]
///
/// [`rfc7517`]: https://datatracker.ietf.org/doc/html/rfc7517
pub struct JWK {
/// Algorithm intended for use with this key
pub alg: JWA,
#[serde(flatten)]
/// Key type (e.g., RSA, EC, oct)
pub key_type: JWKType,
#[serde(skip_serializing_if = "Option::is_none")]
/// Intended use (e.g., "sig" for signature, "enc" for encryption)
pub r#use: Option<JWKUse>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Operations this key supports (e.g., ["sign", "verify"])
pub key_ops: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// X.509 certificate chain
pub x5c: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// X.509 certificate SHA-1 thumbprint (base64url-encoded)
pub x5t: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "x5t#S256")]
/// X.509 certificate SHA-256 thumbprint (base64url-encoded)
pub x5t_sha256: Option<String>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[serde(tag = "kty")]
/// The "kty" (key type) parameter identifies the cryptographic algorithm family used with the key, such as "RSA", "EC", or "OCT"
pub enum JWKType {
RSA {
n: String,
e: String,
},
/// Elleptic curve
EC {
crv: JWKEllipticCurves,
x: String,
y: String,
},
/// an octet sequence key, which represents a symmetric key
OCT {
k: String,
},
}
impl Serialize for JWKType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// Order here is important as this output will be used to generate jwk thumb
match &self {
Self::EC { crv, x, y } => {
let mut state = serializer.serialize_struct("JWKType", 4)?;
state.serialize_field("crv", crv)?;
state.serialize_field("kty", "EC")?;
state.serialize_field("x", x)?;
state.serialize_field("y", y)?;
state.end()
}
Self::RSA { n, e } => {
let mut state = serializer.serialize_struct("JWKType", 3)?;
state.serialize_field("e", e)?;
state.serialize_field("kty", "RSA")?;
state.serialize_field("n", n)?;
state.end()
}
Self::OCT { k } => {
let mut state = serializer.serialize_struct("JWKType", 2)?;
state.serialize_field("k", k)?;
state.serialize_field("kty", "OCT")?;
state.end()
}
}
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum JWKEllipticCurves {
#[serde(rename = "P-256")]
P256,
#[serde(rename = "P-384")]
P384,
#[serde(rename = "P-521")]
P521,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
/// [`JWKUse`] identifies the intended use of the public key
pub enum JWKUse {
#[serde(rename = "sig")]
Signature,
#[serde(rename = "enc")]
Encryption,
}
impl JWK {
/// Create a [`JWK`] for the given [`EcdsaKeyPair`]
///
/// Warning: make sure to specify the correct algorithm.
/// If `https://github.com/aws/aws-lc-rs/pull/834` gets merged this won't be needed anymore
fn new_from_escdsa_keypair(key: &EcdsaKeyPair, alg: JWA) -> Result<Self, OpaqueError> {
let curve = alg.try_into()?;
// 0x04 prefix + x + y
let pub_key = key.public_key().as_ref();
let middle = (pub_key.len() - 1) / 2;
let (x, y) = key.public_key().as_ref()[1..].split_at(middle);
Ok(Self {
alg,
key_type: JWKType::EC {
crv: curve,
x: BASE64_URL_SAFE_NO_PAD.encode(x),
y: BASE64_URL_SAFE_NO_PAD.encode(y),
},
r#use: Some(JWKUse::Signature),
key_ops: None,
x5c: None,
x5t: None,
x5t_sha256: None,
})
}
/// [`JWKThumb`] as defined in [`rfc7638`] is url safe identifier for a [`JWK`]
///
/// [`rfc7638`]: https://datatracker.ietf.org/doc/html/rfc7638
pub fn thumb_sha256(&self) -> Result<Digest, OpaqueError> {
Ok(digest(
&SHA256,
&serde_json::to_vec(&self.key_type).context("failed to serialise JWK")?,
))
}
/// Convert this [`JWK`] to an unparsed public key which can be used to verify signatures
///
/// Warning no verification is done on this key until `.verify()` is called
pub fn unparsed_public_key(
&self,
) -> Result<signature::UnparsedPublicKey<Vec<u8>>, OpaqueError> {
match &self.key_type {
JWKType::RSA { .. } => Err(OpaqueError::from_display("currently not supported")),
JWKType::OCT { .. } => Err(OpaqueError::from_display(
"Symmetric key cannot be converted to public key",
)),
JWKType::EC { crv, x, y } => {
let alg: &'static EcdsaVerificationAlgorithm =
JWA::from(crv.to_owned()).try_into()?;
let x_bytes = BASE64_URL_SAFE_NO_PAD
.decode(x)
.context("decode ec curve x point")?;
let y_bytes = BASE64_URL_SAFE_NO_PAD
.decode(y)
.context("decode ec curve y point")?;
let mut point_bytes = Vec::with_capacity(1 + x_bytes.len() + y_bytes.len());
point_bytes.push(0x04);
point_bytes.extend_from_slice(&x_bytes);
point_bytes.extend_from_slice(&y_bytes);
Ok(signature::UnparsedPublicKey::new(alg, point_bytes))
}
}
}
}
/// [`EcdsaKey`] which is used to identify and authenticate our requests
///
/// This contains the private and public key we will be using for JWS
pub struct EcdsaKey {
rng: SystemRandom,
alg: JWA,
inner: EcdsaKeyPair,
}
impl EcdsaKey {
/// Create a new [`EcdsaKey`] from the given [`EcdsaKeyPair`]
pub fn new(key_pair: EcdsaKeyPair, alg: JWA, rng: SystemRandom) -> Result<Self, OpaqueError> {
// Check if passed algorithm is a correct elliptic curve one
let _curve = JWKEllipticCurves::try_from(alg)?;
Ok(Self {
rng,
alg,
inner: key_pair,
})
}
/// Generate a new [`EcdsaKey`] from a newly generated [`EcdsaKeyPair`] using P-256 EC
pub fn generate() -> Result<Self, OpaqueError> {
let key_pair = EcdsaKeyPair::generate(&ECDSA_P256_SHA256_FIXED_SIGNING)
.context("generate EcdsaKeyPair")?;
Self::new(key_pair, JWA::ES256, SystemRandom::new())
}
/// Generate a new [`EcdsaKey`] from the given pkcs8 der
pub fn from_pkcs8_der(
pkcs8_der: &[u8],
alg: JWA,
rng: SystemRandom,
) -> Result<Self, OpaqueError> {
let ec_alg: &'static EcdsaSigningAlgorithm = alg.try_into()?;
let key_pair = EcdsaKeyPair::from_pkcs8(ec_alg, pkcs8_der)
.context("create EcdsaKeyPair from pkcs8")?;
Self::new(key_pair, alg, rng)
}
/// Create pkcs8 der for the current [`EcdsaKeyPair`]
pub fn pkcs8_der(&self) -> Result<(JWA, Document), OpaqueError> {
let doc = self
.inner
.to_pkcs8v1()
.context("create pkcs8 der from keypair")?;
Ok((self.alg, doc))
}
/// Create a [`JWK`] for this [`EcdsaKey`]
#[must_use]
pub fn create_jwk(&self) -> JWK {
// `expect` because `new_for_escdsa_keypair`` can only fail if curve is not elliptic but we already check that in `new`
JWK::new_from_escdsa_keypair(&self.inner, self.alg).expect("create JWK from escdsa keypair")
}
#[must_use]
pub fn rng(&self) -> &SystemRandom {
&self.rng
}
#[must_use]
pub fn alg(&self) -> JWA {
self.alg
}
}
#[derive(Serialize)]
struct EcdsaKeySigningHeaders<'a> {
alg: JWA,
jwk: &'a JWK,
}
impl Signer for EcdsaKey {
type Signature = Signature;
type Error = OpaqueError;
fn set_headers(
&self,
protected_headers: &mut super::jws::Headers,
_unprotected_headers: &mut super::jws::Headers,
) -> Result<(), Self::Error> {
let jwk = self.create_jwk();
protected_headers.try_set_headers(EcdsaKeySigningHeaders {
alg: jwk.alg,
jwk: &jwk,
})?;
Ok(())
}
fn sign(&self, data: &str) -> Result<Self::Signature, Self::Error> {
let sig = self
.inner
.sign(self.rng(), data.as_bytes())
.context("sign protected data")?;
Ok(sig)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn jwk_thumb_order_is_correct() {
let jwk_type = JWKType::EC {
crv: JWKEllipticCurves::P256,
x: "x".into(),
y: "y".into(),
};
let output = serde_json::to_string(&jwk_type).unwrap();
let expected_output = r##"{"crv":"P-256","kty":"EC","x":"x","y":"y"}"##;
assert_eq!(&output, expected_output);
let jwk_type = JWKType::RSA {
n: "n".into(),
e: "e".into(),
};
let output = serde_json::to_string(&jwk_type).unwrap();
let expected_output = r##"{"e":"e","kty":"RSA","n":"n"}"##;
assert_eq!(&output, expected_output);
let jwk_type = JWKType::OCT { k: "k".into() };
let output = serde_json::to_string(&jwk_type).unwrap();
let expected_output = r##"{"k":"k","kty":"OCT"}"##;
assert_eq!(&output, expected_output);
}
#[test]
fn can_generate_and_reuse_keys() {
let key = EcdsaKey::generate().unwrap();
let stored = key.pkcs8_der().unwrap();
let recreated_key =
EcdsaKey::from_pkcs8_der(stored.1.as_ref(), stored.0, SystemRandom::new()).unwrap();
assert_eq!(key.create_jwk(), recreated_key.create_jwk())
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
//! # JOSE: JSON Object Signing and Encryption
//!
//! JOSE is an IETF standard for securely transferring data between parties using JSON.
//! It provides a general framework for signing and encrypting any kind of data, and it's
//! the foundation for technologies like JSON Web Tokens (JWTs).
//!
//! The JOSE framework is made up of several key components:
//!
//! * JWS (JSON Web Signature): This specification defines how to create a digital signature for
//! any data. A JWS proves data integrity and authenticity. It consists of a Header, a
//! Payload (the data), and a Signature, all encoded in Base64Url and joined by dots.
//! See [`rfc7515`] for more details.
//!
//! * JWE (JSON Web Encryption): This defines a standard way to encrypt data. A JWE ensures
//! the confidentiality of the information, making sure only authorized parties can read it.
//! See [`rfc7516`] for more details.
//!
//! * JWK (JSON Web Key): This specifies a JSON format for representing cryptographic keys.
//! This makes it simple to share the public keys required to verify signatures or encrypt data.
//! See [`rfc7517`] for more details.
//!
//! * JWA (JSON Web Algorithm): This is essentially a list of the specific cryptographic
//! algorithms that are used for signing and encryption within the JOSE framework. The alg
//! parameter in the JOSE header identifies which algorithm was used.
//! See [`rfc7518`] for more details.
//!
//! [`rfc7515`]: https://datatracker.ietf.org/doc/html/rfc7515
//! [`rfc7516`]: https://datatracker.ietf.org/doc/html/rfc7516
//! [`rfc7517`]: https://datatracker.ietf.org/doc/html/rfc7517
//! [`rfc7518`]: https://datatracker.ietf.org/doc/html/rfc7518
mod jwa;
pub use jwa::JWA;
mod jwk;
pub use jwk::{EcdsaKey, JWK, JWKEllipticCurves, JWKType, JWKUse};
mod jws;
pub use jws::{
DecodedJWS, DecodedJWSFlattened, DecodedSignature, EMPTY_PAYLOAD, Empty, Headers, JWS,
JWSBuilder, JWSCompact, JWSFlattened, NO_PAYLOAD, Signer, ToVerifySignature, Verifier,
};

68
codex-rs/vendor/rama-crypto/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,68 @@
//! Crypto primitives and dependencies used by rama.
//!
//! This includes but is not limited to:
//! - Certificates
//! - Javascript object signing and encryption (JOSE): JWS, JWK, JWE...
//! - Public and private keys
//! - Signing
//!
//! # Rama
//!
//! Crate used by the end-user `rama` crate and `rama` crate authors alike.
//!
//! Learn more about `rama`:
//!
//! - Github: <https://github.com/plabayo/rama>
//! - Book: <https://ramaproxy.org/book/>
#![doc(
html_favicon_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png"
)]
#![doc(html_logo_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png")]
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
#![cfg_attr(test, allow(clippy::float_cmp))]
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]
pub mod jose;
pub mod dep {
//! Dependencies for rama crypto modules.
//!
//! Exported for your convenience
pub mod aws_lc_rs {
//! Re-export of the [`aws-lc-rs`] crate.
//!
//! [`aws-lc-rs`]: https://docs.rs/aws-lc-rs
#[doc(inline)]
pub use aws_lc_rs::*;
}
pub mod rcgen {
//! Re-export of the [`rcgen`] crate.
//!
//! [`rcgen`]: https://docs.rs/rcgen
#[doc(inline)]
pub use rcgen::*;
}
pub mod pki_types {
//! Re-export of the [`rustls-pki-types`] crate.
//!
//! [`rustls_pki_types`]: https://docs.rs/rustls-pki-types
#[doc(inline)]
pub use rustls_pki_types::*;
}
pub mod x509_parser {
//! Re-export of the [`x509_parser`] crate.
//!
//! [`x509_parser`]: https://docs.rs/x509_parser
#[doc(inline)]
pub use x509_parser::*;
}
}

View File

@@ -1,12 +0,0 @@
diff --git a/Cargo.toml b/Cargo.toml
index d23b5b0..a361f43 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,7 +45,6 @@ path = "src/lib.rs"
[dependencies.aws-lc-rs]
version = "1.13"
-features = ["bindgen"]
[dependencies.base64]
version = "0.22"