pub fn verify_es256(
spki_der: &[u8],
message: &[u8],
signature_der: &[u8],
) -> Result<(), IdentityError>Expand description
Verifies an ECDSA-P-256/SHA-256 signature, the scheme WebAuthn calls ES256 (COSE algorithm -7).
spki_der is the credential public key in SubjectPublicKeyInfo DER —
what getPublicKey() returns for a registration, and what
p256_point_to_spki builds from raw coordinates. message is the
bytes the authenticator signed, which for an assertion is
authenticatorData ‖ SHA-256(clientDataJSON). signature_der is the
ASN.1 (r, s) pair, which is already the encoding openssl expects,
so nothing is reshaped in between.
Verification runs in an openssl subprocess rather than through a
P-256 crate. That is the trade choir-bridge already makes for RS256:
one more dependency against one more process, and this workspace has
consistently chosen the process (D39).
This is the primitive only. It answers “did this key sign these
bytes” and deliberately not “is this assertion bound to the operation
the caller has in mind”. Binding the challenge to
signing_hash(channel, payload) belongs to the caller, and D39 carries
a tripwire for it because an assertion that verifies against the wrong
challenge is a signature attesting to something nobody agreed to.
§Errors
IdentityError::BadSignature when the signature does not verify or
the key is unusable, and IdentityError::Verifier when openssl
could not be run.