oauth: split library + Flow + JWT client-auth
Splits oauth.ml into per-concept single-word files (encoding, provider,
redirect, pkce, state, auth, response, exchange, authz, par, flow, token,
userinfo, jws) and makes oauth.ml a thin facade that re-exports them so
the public Oauth.* API is unchanged.
In the same commit: Oauth.Flow ties state + PKCE + optional PAR + optional
DPoP (with RFC 9449 section 8 nonce-challenge retry) into begin_authz /
complete_authz / refresh_bound, and Oauth.Client_auth gets two more RFC
7523 variants:
- Client_auth.secret_jwt signs the client_assertion with HS256 keyed on
the client_secret. The secret never crosses the wire.
- Client_auth.private_key_jwt signs with a Dpop.key (ES256 or EdDSA),
reusing ocaml-dpop's primitives; Dpop exposes a new sign_message for
that purpose.
apply now takes ~aud (the endpoint URL) so the JWT variants can populate
the audience claim. Callers in exchange.ml / par.ml / flow.ml thread
it through.
11 new tests for Client_auth cover the form-field layout, HS256 signature
equality, kid embedding, EdDSA path, and ES256 signature round-trip
verification. 86 tests pass total.