oidc-provider.util

Shared utility functions for the OIDC provider.

Includes constant-time-eq? for timing-safe string comparison, hash-client-secret / verify-client-secret for PBKDF2-based client secret hashing, and valid-web-redirect-uri? / valid-native-redirect-uri? for redirect URI validation split by application_type per OpenID Connect Dynamic Client Registration 1.0.

constant-time-eq?

(constant-time-eq? a b)

Compares two strings in constant time using MessageDigest/isEqual to prevent timing side-channel attacks.

generate-client-id

(generate-client-id)

Generates a unique client identifier as a random UUID string.

generate-client-secret

(generate-client-secret)

Generates a cryptographically random client secret suitable for OAuth2 confidential clients.

Delegates to the Nimbus SDK Secret class, which produces a 256-bit SecureRandom base64url-encoded value. Integrators building admin APIs can use this to create client secrets that are consistent with those issued by oidc-provider.registration/handle-registration-request.

hash-client-secret

(hash-client-secret secret)

Hashes a client secret using PBKDF2WithHmacSHA256 with a random 160-bit salt and 310,000 iterations per OWASP recommendations.

Returns an encoded string in the format algorithm:iterations:salt:hash where binary values are base64-encoded. Use verify-client-secret to check a plaintext secret against the returned hash.

hash-token

(hash-token token)

Computes a SHA-256 digest of token and returns it as a base64url string without padding.

Intended for hashing high-entropy opaque tokens (access tokens, refresh tokens, authorization codes) before storage. Unlike hash-client-secret, no salt or key-stretching is needed because the input is already 256-bit random.

truncate

(truncate s max-len)

Returns s truncated to at most max-len characters, appending "..." when truncation occurs.

valid-native-redirect-uri?

(valid-native-redirect-uri? uri-str)

Returns true when uri-str is a valid redirect URI for application_type "native" clients. Accepts HTTPS, HTTP on loopback (localhost/127.0.0.1/::1), or custom URI schemes (e.g., cursor://callback) per RFC 8252 Section 7.1. Rejects URIs with fragments per RFC 6749 Section 3.1.2.

valid-redirect-uri-https-only?

(valid-redirect-uri-https-only? uri-str)

Returns true when uri-str is an absolute URI with HTTPS scheme only and no fragment. Unlike valid-native-redirect-uri?, this rejects HTTP even on loopback addresses. Rejects URIs with fragment components per RFC 6749 Section 3.1.2. Intended for metadata-document clients where HTTPS is strictly required.

valid-web-redirect-uri?

(valid-web-redirect-uri? uri-str)

Returns true when uri-str is an absolute HTTPS URI with a host and no fragment. For application_type "web" clients per OpenID Connect Dynamic Client Registration. Rejects URIs with fragment components per RFC 6749 Section 3.1.2.

validate-issuer

(validate-issuer issuer-str allow-http?)

Validates that issuer-str is a well-formed issuer identifier per RFC 8414 ยง2. The issuer must be an absolute HTTPS URL with a host and no query or fragment component. When allow-http? is true, HTTP scheme is also accepted (useful for local development). Throws ex-info with an :invalid-issuer error on failure.

verify-client-secret

(verify-client-secret secret hashed)

Verifies a plaintext secret against a hashed string produced by hash-client-secret.

Parses the encoded algorithm:iterations:salt:hash format, re-derives the key with the same parameters, and compares in constant time. Returns true if the secret matches, false otherwise. Returns false on malformed hash input.