In openid.rs, calculate_hash calls atproto_auth::pkce::challenge (permalink), which computes the SHA256 and encodes it using base64url encoding without padding.
This does not correctly calculate the hash. at_hash/c_hash should only contain the first half of the hash (from the spec, section 3.1.3.6):
at_hash: OPTIONAL. Access Token hash value. Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the access_token value, where the hash algorithm used is the hash algorithm used in the alg Header Parameter of the ID Token's JOSE Header. For instance, if the alg is RS256, hash the access_token value with SHA-256, then take the left-most 128 bits and base64url-encode them. The at_hash value is a case-sensitive string.
The implementation of calculate_hash should only use the first 128 bits of the hash, but currently uses the full hash.
I'm not familiar with the atproto crates used, but it also seems like the issued jwt could be signed with alg set to ES256, ES256K, or ES384 depending on the configured private keys. If the key was ES384, the hash would need to be SHA384.
In
openid.rs,calculate_hashcallsatproto_auth::pkce::challenge(permalink), which computes the SHA256 and encodes it using base64url encoding without padding.This does not correctly calculate the hash.
at_hash/c_hashshould only contain the first half of the hash (from the spec, section 3.1.3.6):The implementation of
calculate_hashshould only use the first 128 bits of the hash, but currently uses the full hash.I'm not familiar with the atproto crates used, but it also seems like the issued jwt could be signed with
algset toES256,ES256K, orES384depending on the configured private keys. If the key was ES384, the hash would need to be SHA384.