Skip to main content

acme_proxy_core/jws/
mod.rs

1//! JSON Web Signature, as RFC 8555 §6.2 uses it: the wire types ([`AcmeJwsRequest`],
2//! [`ProtectedHeader`], [`Jwk`]) and, in [`signature`], the cryptography —
3//! including the DER-SPKI encoding by hand and the rule that the verification
4//! algorithm is never chosen from the client's `alg` alone.
5//!
6//! Free of any HTTP type: the axum extractors that run it on every request are
7//! `extractors`, and the two nested-JWS surfaces ([`crate::eab`],
8//! [`crate::key_change`]) and the relay's upstream client verify and sign with it
9//! too.
10
11pub mod signature;
12
13use serde::{Deserialize, Serialize};
14
15/// Represents a JSON Web Signature (JWS) request structure used in ACME protocol.
16#[derive(Debug, Serialize, Deserialize, Clone)]
17pub struct AcmeJwsRequest {
18    pub protected: String,
19    pub signature: String,
20    pub payload: String,
21}
22
23/// Represents the JWK (JSON Web Key) structure used in ACME JWS headers.
24#[derive(Deserialize, Debug, PartialEq)]
25#[serde(tag = "kty")]
26pub enum Jwk {
27    /// RSA key type with modulus (n) and public exponent (e)
28    RSA { n: String, e: String },
29    /// Elliptic Curve key type with curve (crv) and coordinates (x, y)
30    EC { crv: String, x: String, y: String },
31}
32
33/// Represents the protected header of an ACME JWS request.
34///
35/// Deliberately *not* `deny_unknown_fields`: RFC 8555 §6.2 enumerates the
36/// fields it expects, but silently ignoring an extra member costs nothing and
37/// refusing one would reject clients over a harmless addition. `crit` is the
38/// exception — see the field below.
39#[derive(Debug, Deserialize)]
40pub struct ProtectedHeader {
41    pub alg: String,
42    pub jwk: Option<Jwk>,
43    pub kid: Option<String>,
44    pub nonce: String,
45    pub url: String,
46    /// Header extensions the sender marks as critical (RFC 7515 §4.1.11).
47    ///
48    /// This server implements no critical extension, so *every* value here is
49    /// unrecognized and the JWS must be rejected — which is why the field is
50    /// parsed at all: ignoring it would silently accept a request whose sender
51    /// demanded we understand something we do not.
52    pub crit: Option<Vec<String>>,
53}