Attesto.Thumbprint (Attesto v0.5.0)

Copy Markdown View Source

Canonical SHA-256 thumbprint shape, shared across the sender-constraint schemes.

Three different specs converge on the same 32-byte-digest-as-base64url shape:

  • RFC 7638 JWK thumbprints (DPoP cnf.jkt),
  • RFC 8705 §3.1 X.509 certificate thumbprints (cnf.x5t#S256), and
  • the RFC 7515 §4.1.8 x5t#S256 JOSE header parameter.

In every case the value is

Base.url_encode64(<32-byte SHA-256 digest>, padding: false)

which is exactly 43 characters drawn from the RFC 4648 §5 alphabet [A-Za-z0-9_-].

Why 43 base64url characters is necessary but not sufficient

The last character of a 43-character base64url-no-pad string encodes only the final 4 bits of the 256-bit digest, so its low 2 bits are structurally zero. A 43-character string whose last character carries non-zero trailing bits is therefore not something Base.url_encode64/2 could ever have produced. Accepting such a value as a thumbprint would let a caller embed a cnf binding that no real key or certificate could ever match - silently turning a sender-constraint into a no-op. valid?/1 rejects these by decoding and re-encoding: a value is canonical iff it round-trips to itself and decodes to exactly 32 bytes.

Summary

Functions

The fixed character length of a well-formed SHA-256 base64url-no-pad thumbprint. Exposed so documentation / API specs can advertise the same shape this module enforces.

Compute the SHA-256 thumbprint of bytes in the canonical base64url-no-pad shape this module validates.

Returns true iff value is the canonical base64url-no-pad encoding of a 32-byte SHA-256 digest: 43 characters from the base64url alphabet that decode to exactly 32 bytes and re-encode unchanged. Anything else - wrong length, illegal characters, non-canonical trailing bits, or a non-binary - returns false.

Functions

length()

@spec length() :: pos_integer()

The fixed character length of a well-formed SHA-256 base64url-no-pad thumbprint. Exposed so documentation / API specs can advertise the same shape this module enforces.

of(bytes)

@spec of(binary()) :: String.t()

Compute the SHA-256 thumbprint of bytes in the canonical base64url-no-pad shape this module validates.

valid?(value)

@spec valid?(term()) :: boolean()

Returns true iff value is the canonical base64url-no-pad encoding of a 32-byte SHA-256 digest: 43 characters from the base64url alphabet that decode to exactly 32 bytes and re-encode unchanged. Anything else - wrong length, illegal characters, non-canonical trailing bits, or a non-binary - returns false.