Skip to main content

verify_assertion

Function verify_assertion 

Source
pub fn verify_assertion(
    verifier: Option<&dyn Es256Verifier>,
    keys: &AssertionKeys,
    assertion: &str,
    client_id: &str,
    audiences: &[&str],
    now: SystemTime,
) -> Result<VerifiedAssertion, AssertionFailure>
Available on crate feature client-assertion only.
Expand description

Verify one RFC 7523 section 3 client assertion.

audiences is what section 3 (3) will accept as naming this server: the caller passes the token endpoint URL and the issuer identifier. now is the server’s clock.

The ORDER of the checks below is the security property of this function:

  1. alg comes from keys, which is the REGISTRATION, and never from the token header. This is the whole of the defence against JWS algorithm confusion, and it is structural rather than a check that could be forgotten: AssertionKeys holds either a secret or public keys, so there is no value an attacker can put in the header that routes an HMAC verification at a public key it already knows.
  2. The SIGNATURE is verified before any claim is read for anything but its own sake. Acting on an unauthenticated claim, even only to produce a better error message, is how a verifier ends up telling an attacker which client ids exist.
  3. Everything after that is the section 3 claim set, in the section’s own order.

verifier is the ES256 backend, the host’s to choose after 0.9.0: enable jwt-p256 for crate::jwt::P256Verifier, or pass your own.

It is an Option, and unlike crate::dpop::verify_proof’s it HAS to be, because only ONE of the two RFC 7523 methods involves a curve at all. private_key_jwt is ES256 and None refuses it, for that function’s reason: a caller holding no verifier must refuse the credential rather than verify it leniently. client_secret_jwt is HS256 over the registered secret (RFC 7518 section 3.2), and there is no elliptic curve on that path, no key for a verifier to check and nothing for a backend to contribute. Taking a verifier by value here made a build with client-assertion and no ES256 backend refuse a perfectly valid HMAC, which is a refusal no RFC asks for.

PUBLIC because VerifiedAssertion and AssertionFailure are, and a type no consumer can obtain is a type that should not have been exported. It is also the other half of unverified_subject, which has always been public: exposing the “believe nothing” lookup while hiding the verification it exists to feed left the safe path out of reach.