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}