Summary: For SECURE_ENCLAVE, the explainer derives the certified key's digest from the canonical JWK of the subject key, while the attestation format that user agents actually produce hashes the DER SubjectPublicKeyInfo (SPKI). A verifier following the explainer therefore computes a different digest than the one in the statement, and verification fails. The explainer also states that SECURE_ENCLAVE omits sub_key, which leaves the verifier without the key material it needs to recompute that digest independently.
Details:
sub_key is described as TPM-only and omitted for SECURE_ENCLAVE: README.md:330 and :388. The TPM-only qualifier is repeated for the Base64URL-encoded inclusion at README.md:671 and :698.
- The JSON examples omit
sub_key entirely: README.md:304-311 (registration) and :362-369 (binding).
- The digest is specified over the canonical JWK:
README.md:322 (d := hash(canonical_jwk(IdP_sk-pub), hash_alg(alg))) and README.md:380 (the same over RP_sk-pub), with matching prose at README.md:317 and :375. The wire format hashes the SPKI instead.
- Registration validation inherits the mismatch:
README.md:597 verifies the second half of raw_stmt against the canonical JWK digest.
- Binding validation takes a shortcut:
README.md:641 lifts the second half of raw_stmt and Base64URL-encodes it directly as cnf.jkt. This is only correct if that field already is an RFC 7638 thumbprint. The TPM path at README.md:647 does the right thing — it reconstructs the canonical JWK from sub_key and hashes that — and SECURE_ENCLAVE should mirror it.
- The UA-side build steps repeat the canonical-JWK derivation at
README.md:669 and :696.
Proposed change:
- Specify
sub_key for SECURE_ENCLAVE, and state that its encoding is determined by fmt: TPMT_PUBLIC for TPM, DER SubjectPublicKeyInfo for SECURE_ENCLAVE.
- Add
sub_key to the examples at README.md:304-311 and :362-369.
- Define the
SECURE_ENCLAVE digest as the hash of the DER SPKI, matching the wire format.
- Drop the
cnf.jkt shortcut at README.md:641. Require reconstructing the canonical JWK from sub_key and hashing that, as the TPM path already does, so that the digest inside raw_stmt serves purely as an integrity check rather than as a value the verifier forwards.
Summary: For
SECURE_ENCLAVE, the explainer derives the certified key's digest from the canonical JWK of the subject key, while the attestation format that user agents actually produce hashes the DERSubjectPublicKeyInfo(SPKI). A verifier following the explainer therefore computes a different digest than the one in the statement, and verification fails. The explainer also states thatSECURE_ENCLAVEomitssub_key, which leaves the verifier without the key material it needs to recompute that digest independently.Details:
sub_keyis described asTPM-only and omitted forSECURE_ENCLAVE:README.md:330and:388. TheTPM-only qualifier is repeated for the Base64URL-encoded inclusion atREADME.md:671and:698.sub_keyentirely:README.md:304-311(registration) and:362-369(binding).README.md:322(d := hash(canonical_jwk(IdP_sk-pub), hash_alg(alg))) andREADME.md:380(the same overRP_sk-pub), with matching prose atREADME.md:317and:375. The wire format hashes the SPKI instead.README.md:597verifies the second half ofraw_stmtagainst the canonical JWK digest.README.md:641lifts the second half ofraw_stmtand Base64URL-encodes it directly ascnf.jkt. This is only correct if that field already is an RFC 7638 thumbprint. TheTPMpath atREADME.md:647does the right thing — it reconstructs the canonical JWK fromsub_keyand hashes that — andSECURE_ENCLAVEshould mirror it.README.md:669and:696.Proposed change:
sub_keyforSECURE_ENCLAVE, and state that its encoding is determined byfmt:TPMT_PUBLICforTPM, DERSubjectPublicKeyInfoforSECURE_ENCLAVE.sub_keyto the examples atREADME.md:304-311and:362-369.SECURE_ENCLAVEdigest as the hash of the DER SPKI, matching the wire format.cnf.jktshortcut atREADME.md:641. Require reconstructing the canonical JWK fromsub_keyand hashing that, as theTPMpath already does, so that the digest insideraw_stmtserves purely as an integrity check rather than as a value the verifier forwards.