RequestSeal.SignatureBase (RequestSeal v0.2.0)

Copy Markdown View Source

Exact ordered RFC 9421 Section 2 signature-base construction.

build/3 consumes a validated RequestSeal.Message and one signature's parameterized Inner List, either serialized bytes or a RequestSeal.StructuredFields.Value of type :inner_list. It returns {:ok, bytes} or a bounded RequestSeal.SignatureBase.Error, never a partial base. Components and all parameters retain their order; equivalent component identifiers with reordered parameters reject. The final "@signature-params" line has no trailing newline. This function performs no signing, verification, key operation, body read, network request, or authorization.

All nine derived components are supported. @request-target, @path, and @query preserve percent-encoded octets. @target-uri assembles the preserved target URI without normalizing it. Only @authority and @scheme normalize host/scheme case and the HTTP(S) default port. Origin-form requests need the caller's explicit :scheme/:authority for these three origin components; absolute-form requests provide them in the raw target. Host and Forwarded fields never supply missing origin facts. Authority/asterisk-form target URIs have empty paths (RFC 9110 Section 7.1); @path normalizes an empty path to /. req requires a response with its validated original :related_request.

@query-param requires the canonical encoded name, rejects duplicate decoded names, and preserves empty values. Parsing uses UTF-8 form semantics; encoding uses RFC 9421 Section 2.2.8's percent-encode-after-encoding operation and its published vectors (%20 for spaces, uppercase hex, no double decoding), under the January 2024 URL Standard referenced by that RFC. Invalid UTF-8 rejects.

Field values trim only HTTP OWS, preserve internal bytes, and combine ordered occurrences with comma-space. Capture must already have removed HTTP/1.1 obsolete folding: Message rejects CR/LF. bs wraps each trimmed occurrence separately, including non-ASCII octets. Without bs, non-ASCII bytes reject. tr selects only trailers; unavailable or pending trailers reject. For fields whose unquoted commas make occurrence boundaries significant, callers must select bs (RFC 9421 Sections 2.1.3 and 7.5.6).

Options:

  • :field_schemas — map of lowercase field names to explicit Structured Fields schemas, default %{}. sf and key require this knowledge. key requires a Dictionary schema and strictly serializes only the selected member. Schemas apply equally to headers, trailers, and the related request; the field's public specification selects its revision, never the input's syntax.
  • :max_components — positive ceiling, default/maximum 256.
  • :max_bytes — positive ceiling for the final base, default/maximum 1,048,576.

The Structured Fields parser's documented ceilings also apply to signature parameters and sf/key fields (including 65,536 serialized bytes). Unknown/duplicate options, malformed direct values, unknown or incompatible component parameters, wrong parameter types, and unavailable components reject. Extension signature metadata retains RFC 8941 types; registered created and expires require Integers, and nonce, alg, keyid, and tag require Strings. Successful construction establishes bytes only, not authentication.

Summary

Functions

Build one ASCII signature base from preserved message facts and ordered parameters.

Functions

build(message, parameters, opts \\ [])

Build one ASCII signature base from preserved message facts and ordered parameters.