diff --git a/src/Attestations/Packed.php b/src/Attestations/Packed.php index 9011940..3a282a0 100644 --- a/src/Attestations/Packed.php +++ b/src/Attestations/Packed.php @@ -58,8 +58,8 @@ public function verify(AuthenticatorData $data, BinaryString $clientDataHash): V $acd = $data->getAttestedCredentialData(); $alg = COSE\Algorithm::tryFrom($this->data['alg']); - if ($alg !== $acd->coseKey->algorithm) { - throw new Exception('8.2/v3.a'); + if ($alg === null) { + throw new Exception('8.2/v1'); } if (array_key_exists('x5c', $this->data)) { @@ -144,6 +144,13 @@ public function verify(AuthenticatorData $data, BinaryString $clientDataHash): V ]); } else { // Self attestation in use + // In the x5c branch, alg describes the attestation certificate's + // signature, so it is only cross-referenced against the credential + // key here. + if ($alg !== $acd->coseKey->algorithm) { + throw new Exception('8.2/v3.a'); + } + $credentialPublicKey = $acd->coseKey->getPublicKey(); $result = openssl_verify( diff --git a/tests/integration/w3c-packed-rs256/auth-req.json b/tests/integration/w3c-packed-rs256/auth-req.json new file mode 100644 index 0000000..9feec79 --- /dev/null +++ b/tests/integration/w3c-packed-rs256/auth-req.json @@ -0,0 +1,5 @@ +{ + "publicKey": { + "challenge": "KV9Z9fqP5ixayp4nYmx4yNo3aubYzS3SmuutYB4bxMU" + } +} diff --git a/tests/integration/w3c-packed-rs256/auth-res.json b/tests/integration/w3c-packed-rs256/auth-res.json new file mode 100644 index 0000000..e281316 --- /dev/null +++ b/tests/integration/w3c-packed-rs256/auth-res.json @@ -0,0 +1,9 @@ +{ + "rawId": "mSoYrMg_Z1M2AMETiktMS9I23hNinPAl7RfLALALdN8", + "response": { + "authenticatorData": "v6vDdDKViwYzYNOtZGHJxHNa5_jt1GWSpeDwFFKy5LUZAAAAAA", + "signature": "AQY9UtfDm01DL8cGPF2T5YK9yxaInNcfiI1n2IDqcwpChJjTvI4e4R8rHsvmwpKxGMVf-q3e-oytClTdE3xR8e7Gc_G7bE0XidaCaiIrItD1hfyQH9yTMhLledGZuJ1nKqRIkTM-ahNVU2Al6CslWQJWw1OCKbVXNwg7L2uTd-SeJHLxGVL3n90NoYC1_9kBtASajwgbtAcRvvdsYq7ZQ1cfLQV1MEy1SdaNiJL5UIajD5Nxau6Bj43AbpbA1eDtTPqf2Hc9kEZLaM8UD3mGZm_5yeMwKs0FNdYNdp9GXiq1fviqvIn8z-97oypkFUqLPSa-Ipj0cLjMU3fb49_UsLRfjwHmO95s_Ha2J3H5twqifPQBUsrZOqWs14T9S5D2duLqgo0L8kAK67quQVPlg49Tf4i2IoNGeCqTqJm-Zux33kWz788xHaYyHJLmsM0Rv-ZTvz6YzujjQfAtZ9u2-cmNnoF4CQz7W3D7xtVBWZrHlK4vHU3hKG7I3owtr3sdFchDjpDZJN9cGQRSIKTIQ4wbl5u-AWzz0O7sI8OZnUiCzGRbd23pMHVmEs3G3TmBYP8Cpg", + "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiS1Y5WjlmcVA1aXhheXA0bllteDR5Tm8zYXViWXpTM1NtdXV0WUI0YnhNVSIsIm9yaWdpbiI6Imh0dHBzOi8vZXhhbXBsZS5vcmciLCJjcm9zc09yaWdpbiI6ZmFsc2V9" + }, + "type": "public-key" +} diff --git a/tests/integration/w3c-packed-rs256/metadata.json b/tests/integration/w3c-packed-rs256/metadata.json new file mode 100644 index 0000000..36c6dd1 --- /dev/null +++ b/tests/integration/w3c-packed-rs256/metadata.json @@ -0,0 +1,4 @@ +{ + "id": "mSoYrMg_Z1M2AMETiktMS9I23hNinPAl7RfLALALdN8", + "origin": "https://example.org" +} diff --git a/tests/integration/w3c-packed-rs256/reg-req.json b/tests/integration/w3c-packed-rs256/reg-req.json new file mode 100644 index 0000000..46d9e97 --- /dev/null +++ b/tests/integration/w3c-packed-rs256/reg-req.json @@ -0,0 +1,5 @@ +{ + "publicKey": { + "challenge": "vqjwdwAJvVfywN9v6p90Oifkthu-kjyGLHqtep_I5KY" + } +} diff --git a/tests/integration/w3c-packed-rs256/reg-res.json b/tests/integration/w3c-packed-rs256/reg-res.json new file mode 100644 index 0000000..9a85ce4 --- /dev/null +++ b/tests/integration/w3c-packed-rs256/reg-res.json @@ -0,0 +1,11 @@ +{ + "id": "mSoYrMg_Z1M2AMETiktMS9I23hNinPAl7RfLALALdN8", + "rawId": "mSoYrMg_Z1M2AMETiktMS9I23hNinPAl7RfLALALdN8", + "response": { + "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidnFqd2R3QUp2VmZ5d045djZwOTBPaWZrdGh1LWtqeUdMSHF0ZXBfSTVLWSIsIm9yaWdpbiI6Imh0dHBzOi8vZXhhbXBsZS5vcmciLCJjcm9zc09yaWdpbiI6ZmFsc2V9", + "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAIuMXG6owULAMuC-aeE1PURGHFyRCZQc3alRuXbrlbazAiBNUvQGwZ4lSz_5WJvRgHD7BVrI2xL90KZzS-qdcWjpAGN4NWOBWQImMIICIjCCAcegAwIBAgIQH2-3pezoG0WJa5g6mV2l8zAKBggqhkjOPQQDAjBiMR4wHAYDVQQDDBVXZWJBdXRobiB0ZXN0IHZlY3RvcnMxDDAKBgNVBAoMA1czQzElMCMGA1UECwwcQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbiBDQTELMAkGA1UEBhMCQUEwIBcNMjQwMTAxMDAwMDAwWhgPMzAyNDAxMDEwMDAwMDBaMF8xHjAcBgNVBAMMFVdlYkF1dGhuIHRlc3QgdmVjdG9yczEMMAoGA1UECgwDVzNDMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMQswCQYDVQQGEwJBQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLeza3VCoREgtEPHlNDJn9wloGt2WGQT2B4IYWPvb-FHpVevw04oYdkFfW1GXUcFoDEFUL3utfNe41uUJauFmYGjYDBeMAwGA1UdEwEB_wQCMAAwDgYDVR0PAQH_BAQDAgeAMB0GA1UdDgQWBBT7N7ZHvM-55U2YnqqswWM4aHA_szAfBgNVHSMEGDAWgBRFr_cVsN14Z0H-6ZbrwWVHo5MbHjAKBggqhkjOPQQDAgNJADBGAiEAuGvBKdkq_KfZhpo59w8TmjBbQHOjnrZU2BQkvtV1fZECIQDPn3xgyrfEp9Pn8AIPKBqT1P0Kn5USG5ifVpMqaIhfumhhdXRoRGF0YVkCG7-rw3QylYsGM2DTrWRhycRzWuf47dRlkqXg8BRSsuS1XQAAAABCj4h4KYuYYqNq2MdSe_7yACCZKhisyD9nUzYAwROKS0xL0jbeE2Kc8CXtF8sAsAt036QBAwM5AQAgWQG0A_____________________________________________________________________________________________________________________________________________________________________________________________________________________f_________________________________________________________________________________________________________________________________________________________gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASFDAQAB", + "transports": [] + }, + "type": "public-key", + "authenticatorAttachment": "" +}