Files
web/third_party/go-webauthn/protocol/specification_vectors_e2e_test.go
T
gamertan bfe6cfd29e
verify / verify (push) Successful in 3m40s
auth: publish passkey foundations preview
2026-08-21 17:33:00 -04:00

681 lines
76 KiB
Go
Vendored

package protocol
import (
"bytes"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"encoding/json"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/go-webauthn/webauthn/metadata"
"github.com/go-webauthn/webauthn/protocol/webauthncose"
"github.com/go-webauthn/webauthn/testing/mocks"
)
// WebAuthn Level 3 §16 End-to-End Test Vectors
//
// These tests exercise the full cradle-to-grave path:
// - Registration: ParseCredentialCreationResponseBody → ParsedCredentialCreationData.Verify
// - Authentication: ParseCredentialRequestResponseBody → ParsedCredentialAssertionData.Verify
//
// The spec test vectors that support full attestation (packed with x5c) are validated with a
// custom metadata.Provider that trusts the spec's synthetic attestation CA certificate.
//
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors
func TestSpecVectors_Registration_E2E(t *testing.T) {
testCases := []struct {
name string
attestationObject string
clientDataJSON string
credentialID string
challenge string
format string
credParams []CredentialParameter
rpTopOrigins []string
rpTopOriginVerificationMode TopOriginVerificationMode
allowCrossOrigin bool
mds metadata.Provider
err string
}{
//nolint:gosec
{
// §16.2 None Attestation - ES256
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-none-es256
name: "NoneES256",
attestationObject: "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b559000000008446ccb9ab1db374750b2367ff6f3a1f0020f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4a5010203262001215820afefa16f97ca9b2d23eb86ccb64098d20db90856062eb249c33a9b672f26df61225820930a56b87a2fca66334b03458abf879717c12cc68ed73290af2e2664796b9220",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22414d4d507434557878475453746e63647134313759447742466938767049612d7077386f4f755657345441222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20426b5165446a646354427258426941774a544c453551227d",
credentialID: "f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4",
challenge: "00c30fb78531c464d2b6771dab8d7b603c01162f2fa486bea70f283ae556e130",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.3 Self Attestation (Packed) - ES256
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-self-es256
name: "PackedSelfES256",
attestationObject: "a363666d74667061636b65646761747453746d74a263616c672663736967584630440220067a20754ab925005dbf378097c92120031581c73228d1fb4f5b881bcd7da98302207fc7b147558c7c0eba3af18bd9d121fa3d3a26d17fe3f220272178f473b6006d68617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000df850e09db6afbdfab51697791506cfc0020455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58ca5010203262001215820eb151c8176b225cc651559fecf07af450fd85802046656b34c18f6cf193843c5225820927b8aa427a2be1b8834d233a2d34f61f13bfd44119c325d5896e183fee484f2",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2265476e4374334c55745936366b336a506a796e6962506b31716e666644616966715a774c33417032392d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205539685458764b453255526b4d6e625f307859485667227d",
credentialID: "455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58c",
challenge: "7869c2b772d4b58eba9378cf8f29e26cf935aa77df0da89fa99c0bdc0a76f7e5",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.4 None Attestation - ES256 - Cross Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-crossOrigin
name: "NoneES256CrossOriginNotAllowed",
attestationObject: "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54500000000883f4f6014f19c09d87aa38123be48d000206e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57a501020326200121582022200a473f90b11078851550d03b4e44a2279f8c4eca27b3153dedfe03e4e97d225820cbd0be95e746ad6f5a8191be11756e4c0420e72f65b466d39bc56b8b123a9c6e",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a224f2d57717a514e5463554a484930437257576e7951504859647862694332674872434d475666704c4f306b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a207a5a7175457444523944577170573574425754467567227d",
credentialID: "6e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57",
challenge: "3be5aacd03537142472340ab5969f240f1d87716e20b6807ac230655fa4b3b49",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: false,
err: "Error validating cross origin flag",
},
//nolint:gosec
{
// §16.4 None Attestation - ES256 - Cross Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-crossOrigin
name: "NoneES256CrossOrigin",
attestationObject: "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54500000000883f4f6014f19c09d87aa38123be48d000206e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57a501020326200121582022200a473f90b11078851550d03b4e44a2279f8c4eca27b3153dedfe03e4e97d225820cbd0be95e746ad6f5a8191be11756e4c0420e72f65b466d39bc56b8b123a9c6e",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a224f2d57717a514e5463554a484930437257576e7951504859647862694332674872434d475666704c4f306b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a207a5a7175457444523944577170573574425754467567227d",
credentialID: "6e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57",
challenge: "3be5aacd03537142472340ab5969f240f1d87716e20b6807ac230655fa4b3b49",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: true,
},
//nolint:gosec
{
// §16.5 None Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-topOrigin
name: "NoneES256TopOriginNotAllowed",
attestationObject: "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b5410000000097586fd09799a76401c200455099ef2a0020b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1a5010203262001215820a1c47c1d82da4ebe82cd72207102b380670701993bc35398ae2e5726427fe01d22582086c1080d82987028c7f54ecb1b01185de243b359294a0ed210cd47480f0adc88",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a225468394d595a68706e6a504254786b68555f53646667364f4e58665672454673587a72636b7151664a2d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d227d",
credentialID: "b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1",
challenge: "4e1f4c6198699e33c14f192153f49d7e0e8e3577d5ac416c5f3adc92a41f27e5",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOrigins: []string{"https://example.com/"},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: false,
err: "Error validating cross origin flag",
},
//nolint:gosec
{
// §16.5 None Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-topOrigin
name: "NoneES256TopOrigin",
attestationObject: "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b5410000000097586fd09799a76401c200455099ef2a0020b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1a5010203262001215820a1c47c1d82da4ebe82cd72207102b380670701993bc35398ae2e5726427fe01d22582086c1080d82987028c7f54ecb1b01185de243b359294a0ed210cd47480f0adc88",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a225468394d595a68706e6a504254786b68555f53646667364f4e58665672454673587a72636b7151664a2d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d227d",
credentialID: "b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1",
challenge: "4e1f4c6198699e33c14f192153f49d7e0e8e3577d5ac416c5f3adc92a41f27e5",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOrigins: []string{"https://example.com/"},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: true,
},
//nolint:gosec
{
// §16.6 None Attestation - ES256 - Long Credential ID
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-long-credential-id
name: "NoneES256LongCredentialID",
attestationObject: "a363666d74646e6f6e656761747453746d74a0686175746844617461590483bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b549000000008f3360c2cd1b0ac14ffe0795c5d2638e03ff3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdba50102032620012158203b8176b7504489cc593046d7988abb7905a742de6ac2cdc748a873c663e90cb12258201436d5edc9a75f23999eef9d5950a5c2455514ee1014084720f841a06b828a11",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22455250484a6c7a50586d5553516f4c364858675a7036464d75464f61704d322d7830682d587a5859374777222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
credentialID: "3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdb",
challenge: "1113c7265ccf5e65124282fa1d7819a7a14cb8539aa4cdbec7487e5f35d8ec6c",
format: "none",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.7 Packed Attestation - ES256 (Full Attestation with x5c and MDS)
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-es256
name: "PackedES256WithMDS",
attestationObject: "a363666d74667061636b65646761747453746d74a363616c6726637369675847304502203f19ec4b229f46ab8c45eff29b904ff10c0390dc40bf1216f04a78f4ceba3425022100fe7041a32759aff05a0f9f26c70a999c7a284451ba89234a1d3483c25e21925b637835638159022530820221308201c8a00302010202110088c220f83c8ef1feafe94deae45faad0300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004a91ba4389409dd38a428141940ca8feb1ac0d7b4350558104a3777a49322f3798440f378b3398ab2d3bb7bf91322c92eb23556f59ad0a836fec4c7663b0e4dc3a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414a589ba72d060842ab11f74fb246bdedab16f9b9b301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034700304402201726b9d85ecd8a5ed51163722ca3a20886fd9b242a0aa0453d442116075defd502207ef471e530ac87961a88a7f0d0c17b091ffc6b9238d30f79f635b417be5910e768617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d00000000876ca4f52071c3e9b25509ef2cdf7ed60020c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5a50102032620012158201cf27f25da591208a4239c2e324f104f585525479a29edeedd830f48e77aeae522582059e4b7da6c0106e206ce390c93ab98a15a5ec3887e57f0cc2bece803b920c423",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227752684b58393334424634543345663153324831706c61325a725751475046746877365356756d56494249222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20396138624e596a4b436757724258552d66436c316167227d",
credentialID: "c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5",
challenge: "c1184a5fddf8045e13dc47f54b61f5a656b666b59018f16d870e9256e9952012",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
mds: specTestMDSProvider(t),
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.8 Packed Attestation - ES384 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-es384
name: "PackedES384WithMDS",
attestationObject: "a363666d74667061636b65646761747453746d74a363616c67266373696758473045022100c56ecc970b7843833e0f461fde26233f61eb395161d481558c08b9c6ed61675b022029f5e05033705cd0f9b0a07e149468ec308a4f84906409efdceb1da20a7518d6637835638159022530820221308201c7a00302010202103d0a5588bb87ebb1d4cee4a1807c1b7c300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000417e5cc91d676d370e36aa7de40c25aacb45a3845f13d2932088ece2270b9b431241c219c22d0c256c9438ade00f2c05e62f8ef906b9b997ae9f3c460c2db66f5a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414c7c8dd95382a2230e4c0dd3664338fa908169a9c301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020348003045022054068cc9ae038937b7c468c307edb9c6927ffdeb6a20070c483eb40330f99f10022100cf41953919c3c04693d6b1f42a613753f204e70e85fc6e9b17036170b83596e068617574684461746158c5bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55900000000e950dcda3bdae1d087cda380a897848b0020953ae2dd9f28b1a1d5802c83e1f65833bb9769a08de82d812bc27c13fc6f06a9a5010203382220022158304866bd8b01da789e9eb806e5eab05ae5a638542296ab057a2f1bbce9b58f8a08b9171390b58a37ac7fffc2c5f45857da2258302a0b024c7f4b72072a1f96bd30a7261aae9571dd39870eb29e55c0941c6b08e89629a1ea1216aa64ce57c2807bf3901a",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22566e7344437a3459613848526164314674352d65445962785f574e4854615071336c76626a624e356f4d4d222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
credentialID: "953ae2dd9f28b1a1d5802c83e1f65833bb9769a08de82d812bc27c13fc6f06a9",
challenge: "567b030b3e186bc1d169dd45b79f9e0d86f1fd63474da3eade5bdb8db379a0c3",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES384}},
mds: specTestMDSProvider(t),
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.9 Packed Attestation - ES512 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-es512
name: "PackedES512WithMDS",
attestationObject: "a363666d74667061636b65646761747453746d74a363616c67266373696758473045022100ce158f6c04aa5c14c0dd3e1103cf93664896fb5c337a66dbd7dba31546ff0d41022071cbcd0d3b8e218a6d05374e0ef8031329d25059002ac1603d02d5fd8a0a29cb637835638159022730820223308201c8a0030201020211008a128b7ebe52b993835779e6d9b81355300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004940b68885291536e2f7c60c05acfb252e7eebcf4304425dd93ab7b1962f20492bf18dc0f12862599e81fb764ac92151f9a78fcbb35d7a26c8c52949b18133c06a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604143ffad863abcd3dc5717b8a252189f41af97e7f31301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020349003046022100832c8b64c4f0188bd32e1bec63e13301cdc03165d3ef840d1f3dabb9a5719f83022100add57a9d5bedec98f29222dfc97ea795d055ee13a02a153d02be9ce00aedeb9168617574684461746158e9bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d0000000039d8ce6a3cf61025775083a738e5c2540020d17d5af7e3f37c56622a67c8462c9e1c6336dfccb8b61d359dc47378dba58ce4a5010203382320032158420083240a2c3ad21a3dc0a6daa3d8bc05a46d7cd9825ba010ae2a22686c2d6d663d7d5f678987fb1e767542e63dc197ae915e25f8ee284651af29066910a2cc083f50225842017337df47ab5cce5d716ef8caffa97a3012689b1f326ea6c43a1ba9596c72f71f0122390143552b42be772b4c35ffb961220c743b486a601ea4cb6d5412f5b078d3",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22547549677a5a4b7766684646484c544341635631573968356849354a4b707353313545317869646b33435f536a713149434d722d577448656a366e676a55714f3676366b33374d7a683373437646415f5231303744424f5570326737717654795233677039376a5064516c496d465659644977484d47673562385f63305f4a46767941343572733431314d6e614b72524f2d6a424750636e636935304a684f5151656e4b796c4134684d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a206f3371566a4f4c327454576d3447786b7a495f516767227d",
credentialID: "d17d5af7e3f37c56622a67c8462c9e1c6336dfccb8b61d359dc47378dba58ce4",
challenge: "4ee220cd92b07e11451cb4c201c5755bd879848e492a9b12d79135c62764dc2fd28ead4808cafe5ad1de8fa9e08d4a8eeafea4dfb333877b02bc503f475d3b0c1394a7683baaf4f2477829f7b8cf750948985558748c073068396fcfdcd3f245bf2038e6bb38d7532768aad13be8c118f727722e7426139041e9caca503884c5",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES512}},
mds: specTestMDSProvider(t),
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.10 Packed Attestation - RS256 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-rs256
name: "PackedRS256WithMDS",
attestationObject: "a363666d74667061636b65646761747453746d74a363616c672663736967584730450221008b8c5c6ea8c142c032e0be69e1353d44461c5c9109941cdda951b976eb95b6b302204d52f406c19e254b3ff9589bd18070fb055ac8db12fdd0a6734bea9d7168e900637835638159022630820222308201c7a00302010202101f6fb7a5ece81b45896b983a995da5f3300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004b7b36b7542a11120b443c794d0c99fdc25a06b76586413d81e086163ef6fe147a557afc34e2861d9057d6d465d4705a0310550bdeeb5f35ee35b9425ab859981a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414fb37b647bccfb9e54d989eaaacc1633868703fb3301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020349003046022100b86bc129d92afca7d9869a39f70f139a305b4073a39eb654d81424bed5757d91022100cf9f7c60cab7c4a7d3e7f0020f281a93d4fd0a9f95121b989f56932a68885fba68617574684461746159021bbfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000428f8878298b9862a36ad8c7527bfef20020992a18acc83f67533600c1138a4b4c4bd236de13629cf025ed17cb00b00b74dfa4010303390100205901b403fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012143010001",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2276716a776477414a76566679774e3976367039304f69666b7468752d6b6a79474c48717465705f49354b59222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
credentialID: "992a18acc83f67533600c1138a4b4c4bd236de13629cf025ed17cb00b00b74df",
challenge: "bea8f0770009bd57f2c0df6fea9f743a27e4b61bbe923c862c7aad7a9fc8e4a6",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgRS256}},
mds: specTestMDSProvider(t),
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.11 Packed Attestation - EdDSA
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-eddsa
name: "PackedEdDSAWithMDS",
attestationObject: "a363666d74667061636b65646761747453746d74a363616c67266373696758483046022100d83f60bd80269537583218858aefb03ac57d45fa06e42feaae332d187f62da9f022100a02bd3cb6f7e1d283c93bad1f3f4b5a4c0494463da7fdbf256949116754d1f17637835638159022730820223308201c8a003020102021100b2cfc9ea33c8643b0e1a760463eaf164300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004dd2b7a564b73b8c0b81c4c62e521925c4d1198ec9f583dbf1eebe364b65cd9c29a9bdf346aaa81fb6b9507e5249a52fdaf8e39e26b0b7dc45992a7e233b70f70a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604140ae27546bc7eccb1b4b597bd354f0c0b1f1f8f8e301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020349003046022100a0d434ecb5fc3bfd7da5f41904517ad2836249f561bd834ba7a438a8ab7a4ce8022100fac845bb7a02513b58e9f319654dbe49b0f02b95835bac568c71f8a18cdde9ab6861757468446174615881bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54100000000d5aa33581e8ca478e20fe713f5d32ff20020ce9f840ed96599580cd140fbc7bb3230633f50f61041aff73308ae71caa8a2bda401010327200621582044e06ddd331c36a8dc667bab52bcae63486c916aa5e339e6acebaa84934bf832",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22714b763532723347734e396a526d733576616e6f6f306f303459557a656c6e7878586d5a426e6254733730222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20425f44543567375a445f2d394f544c59583549764551227d",
credentialID: "ce9f840ed96599580cd140fbc7bb3230633f50f61041aff73308ae71caa8a2bd",
challenge: "a8abf9dabdc6b0df63466b39bda9e8a34a34e185337a59f1c579990676d3b3bd",
format: "packed",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgEdDSA}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
{
// §16.13 TPM Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-tpm-es256
name: "TPMES256",
attestationObject: "a363666d746374706d6761747453746d74a663616c67266373696758463044022066e5826a652091030fd444e33c3eca2bc6dc548cf3045013addb38aa6457a21002203f3a5c95c9e707d0e555041bcc8698ee4ebc04e26cc8bae459705471789851766376657263322e30637835638159023a30820236308201dca0030201020210311fc42da0ab10c43a9b1bf3a75e34e2300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004c54e3f109094f60d7699b7db5d838569ffd1f3e1c9e897cd9eb40063f9402e3e9937e936cf1fcd5eb743ff443c97ab2edcd7c8e0e6cf6cfd413b8ab19fffa769a381d33081d0300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604145f546cb6973d4981e80fcdc7463859f5879680e4301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e30100603551d250409300706056781050803305e0603551d110101ff04543052a450304e314c3014060567810502010c0b69643a30303030303030303014060567810502030c0b69643a3030303030303030301e060567810502020c15576562417574686e207465737420766563746f7273300a06082a8648ce3d0403020348003045022063c9a2797b8066f1db34dd609f1ab6695607e7a98e9ff8090a68853c9a9fc949022100a55831a39f5b8a2aa9a68837829cabf43fea2a5cea4859ae851cac78e6ac3e97677075624172656158560023000b0004000000000010001000030010002041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b0020d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d076863657274496e666f5869ff544347801700000020277d0e05579dd013215a62273f7f3a3e7e191ead2654a3036d75a5a3ee37a6b0000000000000000011111111222222223300000000000000000022000b9c42d8aad5939331b9af3711af179f17123178098c9a7d0ca89fcd1fc800f3c7000068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d000000004b92a377fc5f6107c4c85c190adbfd990020ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9a501020326200121582041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b225820d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d07",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227a38677333787a753648595343716950413254776b51475452677a376c364d587376344a427054356f706b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
credentialID: "ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9",
challenge: "cfc82cdf1ceee876120aa88f0364f0910193460cfb97a317b2fe090694f9a299",
format: "tpm",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.14 Android Key Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-android-key-es256
name: "AndroidKeyES256",
attestationObject: "a363666d746b616e64726f69642d6b65796761747453746d74a363616c67266373696758483046022100e95512982aa3f216cff2e87c8ec57057b8529f674eaabeccaa27fd03d8779f19022100afb6bf459da4a826f00d01fc6b60712ff31dc4eb331619c8f874bb17e4314e94637835638159026e3082026a30820210a00302010202101ff91f76b63f44812f998b250b0286bf300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000499169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accfdd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6ba381a83081a5300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604141ac81e50641e8d1339ab9f7eb25f0cd5aac054b0301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e3045060a2b06010401d679020111043730350202012c0a01000201000a01000420b435028d7b6a8f83bb461d41c19b053a9d3cdb30351a4f374cd4cde8dbefb606040030003000300a06082a8648ce3d040302034800304502202d27f0ca39d2f519fc8f49c6d96dfc793059e211ff80516a50398cf1eac2a322022100d482a88c740f64cf6a98ccc6c8b9f5e1e533fa5e509f0a7b4c3a02f964a8eba768617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000ade9705e1ce7085b899a540d02199bf800200a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795a501020326200121582099169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accf225820dd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6b",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2250654877747a5a647a4e345f384d76795869625f7037725f682d385162494438686c334541746d57414641222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205656316351755232714c4d5f616d50666f487a4c3067227d",
credentialID: "0a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795",
challenge: "3de1f0b7365dccde3ff0cbf25e26ffa7baff87ef106c80fc865dc402d9960050",
format: "android-key",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
err: "Attestation certificate extensions contains authorization list with purpose not equal KM_PURPOSE_SIGN",
},
{
// §16.15 Apple Anonymous Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-apple-es256
name: "AppleAnonymousES256",
attestationObject: "a363666d74656170706c656761747453746d74a1637835638159025c30820258308201fea0030201020210394275613d5310b81a29ce90f48b61c1300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200048a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761af728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136ca38196308193300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e0416041412f1ce6c0ae39b403bfc9200317bc183a4e4d766301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e303306092a864886f76364080204263024a1220420d7a86e7233fb843eb0eeb407d8b76ff7e4f82d218cf5dbb461d752073f5cb29a300a06082a8648ce3d0403020348003045022070f5c2ede3000e9dae358d412b26a4acbf18f4cdeb80f5b13fcd564d090c39ec022100f672e2c3dbe117c9b1490b3c660abf5dcd74398187082dacb58b6744de4aca6068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54900000000748210a20076616a733b2114336fc38400209c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8a50102032620012158208a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761a225820f728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136c",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22395f61494954685341486431414a7a34774a6239714a316775616e37576c4464676432596d4b396142676b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20546a4c506e704f6158515572464e6362483274545a41227d",
credentialID: "9c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8",
challenge: "f7f688213852007775009cf8c096fda89d60b9a9fb5a50dd81dd9898af5a0609",
format: "apple",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.16 FIDO U2F Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-fido-u2f-es256
name: "FIDOU2FES256",
attestationObject: "a363666d74686669646f2d7532666761747453746d74a26373696758473045022100f41887a20063bb26867cb9751978accea5b81791a68f4f4dd6ea1fb6a5c086c302204e5e00aa3895777e6608f1f375f95450045da3da57a0e4fd451df35a31d2d98a637835638159022530820221308201c7a003020102021004f66dc6542ea7719dea416d325a2401300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000456fffa7093dede46aefeefb6e520c7ccc78967636e2f92582ba71455f64e93932dff3be4e0d4ef68e3e3b73aa087e26a0a0a30b02dc2aa2309db4c3a2fc936dea360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414420822eb1908b5cd3911017fbcad4641c05e05a3301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034800304502200d0b777f0a0b181ad2830275acc3150fd6092430bcd034fd77beb7bdf8c2d546022100d4864edd95daa3927080855df199f1717299b24a5eecefbd017455a9b934d8f668617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54100000000afb3c2efc054df425013d5c88e79c3c10020a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4a5010203262001215820b0d62de6b30f86f0bac7a9016951391c2e31849e2e64661cbd2b13cd7d5508ad225820503b0bda2a357a9a4b34475a28e65b660b4898a9e3e9bbf0820d43494297edd0",
clientDataJSON: "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22344851334b5a4335797155486f696666786e73414e344445557955344452715177672d4237583049444159222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
credentialID: "a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4",
challenge: "e074372990b9caa507a227dfc67b003780c45325380d1a90c20f81ed7d080c06",
format: "fido-u2f",
credParams: []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
body := specTestBuildRegistrationJSON(t, tc.credentialID, tc.attestationObject, tc.clientDataJSON)
pcc, err := ParseCredentialCreationResponseBody(bytes.NewReader(body))
require.NoError(t, err)
challenge := base64.RawURLEncoding.EncodeToString(specTestDecodeHex(t, tc.challenge))
_, err = pcc.Verify(challenge, specTestRPID, []string{specTestOrigin}, tc.rpTopOrigins, tc.rpTopOriginVerificationMode, tc.allowCrossOrigin, false, true, tc.mds, tc.credParams)
if tc.err == "" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tc.err)
}
assert.Equal(t, tc.format, pcc.Response.AttestationObject.Format)
assert.Equal(t, specTestDecodeHex(t, tc.credentialID), pcc.Response.AttestationObject.AuthData.AttData.CredentialID)
})
}
}
func TestSpecVectors_Authentication_E2E(t *testing.T) {
testCases := []struct {
name string
authenticatorData string
clientDataJSON string
signature string
userHandle string
credentialID string
challenge string
credentialPubKey string
appID string
rpTopOrigins []string
rpTopOriginVerificationMode TopOriginVerificationMode
allowCrossOrigin bool
err string
}{
//nolint:gosec
{
// §16.2 None Attestation - ES256 (Authentication)
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-none-es256
name: "NoneES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224f63446e55685158756c5455506f334a5558543049393770767a7a59425039745a63685879617630314167222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "3046022100f50a4e2e4409249c4a853ba361282f09841df4dd4547a13a87780218deffcd380221008480ac0f0b93538174f575bf11a1dd5d78c6e486013f937295ea13653e331e87",
credentialID: "f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4",
challenge: "39c0e7521417ba54d43e8dc95174f423dee9bf3cd804ff6d65c857c9abf4d408",
credentialPubKey: "a5010203262001215820afefa16f97ca9b2d23eb86ccb64098d20db90856062eb249c33a9b672f26df61225820930a56b87a2fca66334b03458abf879717c12cc68ed73290af2e2664796b9220",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.3 Self Attestation (Packed) - ES256 (Authentication)
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-self-es256
name: "PackedSelfES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a225248696843784e534e493352594d45314f7731476d3132786e726b634a5f6666707637546e2d4a71386773222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a206754623533727a36456853576f6d58477a696d433151227d",
signature: "304402203310b9431903c401f1be2bdc8d23a4007682dbbddcf846994947b7f465daf84002204e94dd00047b316061b3b99772b7efd95994a83ef584b3b6b825ea3550251b66",
credentialID: "455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58c",
challenge: "4478a10b1352348dd160c1353b0d469b5db19eb91c27f7dfa6fed39fe26af20b",
credentialPubKey: "a5010203262001215820eb151c8176b225cc651559fecf07af450fd85802046656b34c18f6cf193843c5225820927b8aa427a2be1b8834d233a2d34f61f13bfd44119c325d5896e183fee484f2",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.4 None Attestation - ES256 - Cross Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-crossOrigin
name: "NoneES256CrossOriginNotAllowed",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226832716c463771445f65356c5f505f62796b7945377135645650674547685f49584a6b655737736e4d5463222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2039327063545644304162792d713464746d6a36656667227d",
signature: "3046022100eb12fcf23b12764c0f122e22371fab92e283879fd798f38ee1841c951b6e40e7022100c76237ff9db77b3c56f30837cda6a09acfa2e915544e609c0733b1184036d1cf",
credentialID: "6e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57",
challenge: "876aa517ba83fdee65fcffdbca4c84eeae5d54f8041a1fc85c991e5bbb273137",
credentialPubKey: "a501020326200121582022200a473f90b11078851550d03b4e44a2279f8c4eca27b3153dedfe03e4e97d225820cbd0be95e746ad6f5a8191be11756e4c0420e72f65b466d39bc56b8b123a9c6e",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: false,
err: "Error validating cross origin flag",
},
//nolint:gosec
{
// §16.4 None Attestation - ES256 - Cross Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-crossOrigin
name: "NoneES256CrossOrigin",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226832716c463771445f65356c5f505f62796b7945377135645650674547685f49584a6b655737736e4d5463222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2039327063545644304162792d713464746d6a36656667227d",
signature: "3046022100eb12fcf23b12764c0f122e22371fab92e283879fd798f38ee1841c951b6e40e7022100c76237ff9db77b3c56f30837cda6a09acfa2e915544e609c0733b1184036d1cf",
credentialID: "6e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57",
challenge: "876aa517ba83fdee65fcffdbca4c84eeae5d54f8041a1fc85c991e5bbb273137",
credentialPubKey: "a501020326200121582022200a473f90b11078851550d03b4e44a2279f8c4eca27b3153dedfe03e4e97d225820cbd0be95e746ad6f5a8191be11756e4c0420e72f65b466d39bc56b8b123a9c6e",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: true,
},
//nolint:gosec
{
// §16.5 None Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-topOrigin
name: "NoneES256TopOrigin",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22315570636a4b53324b6f34377379486a7372787a68572d466f51465132796b3572426c584f6573656f4759222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205569466f4a4d56525148444146574669347678557051227d",
signature: "3045022100b5a70c81780d5fcc9a4f2ae9caae99058f8accaf58b91fb59329646c28ac6ffc022012e101c165db3c8e9957f0c54dd6ca9b56bc3bd2f280bd2faa6c1d02c6e5c171",
credentialID: "b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1",
challenge: "d54a5c8ca4b62a8e3bb321e3b2bc73856f85a10150db2939ac195739eb1ea066",
credentialPubKey: "a5010203262001215820a1c47c1d82da4ebe82cd72207102b380670701993bc35398ae2e5726427fe01d22582086c1080d82987028c7f54ecb1b01185de243b359294a0ed210cd47480f0adc88",
rpTopOrigins: []string{"https://example.com/"},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: false,
err: "Error validating cross origin flag",
},
{
// §16.5 None Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-topOrigin
name: "NoneES256TopOrigin",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22315570636a4b53324b6f34377379486a7372787a68572d466f51465132796b3572426c584f6573656f4759222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205569466f4a4d56525148444146574669347678557051227d",
signature: "3045022100b5a70c81780d5fcc9a4f2ae9caae99058f8accaf58b91fb59329646c28ac6ffc022012e101c165db3c8e9957f0c54dd6ca9b56bc3bd2f280bd2faa6c1d02c6e5c171",
credentialID: "b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1",
challenge: "d54a5c8ca4b62a8e3bb321e3b2bc73856f85a10150db2939ac195739eb1ea066",
credentialPubKey: "a5010203262001215820a1c47c1d82da4ebe82cd72207102b380670701993bc35398ae2e5726427fe01d22582086c1080d82987028c7f54ecb1b01185de243b359294a0ed210cd47480f0adc88",
rpTopOrigins: []string{"https://example.com/"},
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
allowCrossOrigin: true,
},
//nolint:gosec
{
// §16.6 None Attestation - ES256 - Long Credential ID
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-none-es256-long-credential-id
name: "NoneES256LongCredentialID",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22377833727057334f53505a307045664d396a75566d53574d36485a4935634f573875384d6f647047446a73222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "304502203ecef83fb12a0cae7841055f9f87103a99fd14b424194bbf06c4623d3ee6e3fd022100d2ace346db262b1374a6b70faa51f518a42ddca13a4125ce6f5052a75bac9fb6",
credentialID: "3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdb",
challenge: "ef1deba56dce48f674a447ccf63b9599258ce87648e5c396f2ef0ca1da460e3b",
credentialPubKey: "a50102032620012158203b8176b7504489cc593046d7988abb7905a742de6ac2cdc748a873c663e90cb12258201436d5edc9a75f23999eef9d5950a5c2455514ee1014084720f841a06b828a11",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.7 Packed Attestation - ES256 (Full Attestation with x5c and MDS)
// See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-es256
name: "PackedES256Full",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273524276704770587676463446524841565833496d4b4130453958773858306b526a44426c4d6668726255222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20415a4d77794d78496244382d756775464e7036723851227d",
signature: "30450220694969d3ee928de6f02ef23a9c644d7d779916451734a94b432542f498a1ebe90221008b0819c824218a97152cd099c55bfb1477b29d900a49a64018314f9bfccda163",
credentialID: "c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5",
challenge: "b1106fa46a57bef1781511c0557dc898a03413d5f0f17d244630c194c7e1adb5",
credentialPubKey: "a50102032620012158201cf27f25da591208a4239c2e324f104f585525479a29edeedd830f48e77aeae522582059e4b7da6c0106e206ce390c93ab98a15a5ec3887e57f0cc2bece803b920c423",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.8 Packed Attestation - ES384 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-es384
name: "PackedES384",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a225f304844306c32396957623759654b4f39655277516545333753614649454574646941726f4b307446464d222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "3065023100e4efbb46745ed00e67c4d51ab2bacab2af62ffa8b7c5fecec6d7d9bf2582275034a713a3dd731685eee81adfaf6aa63f0230161655353f07e018a3c2539f8de7c8c4cf88d4c32d2be29fe4e76fa096ecc9458bbfe0895d57129ab324130e6f0692db",
credentialID: "953ae2dd9f28b1a1d5802c83e1f65833bb9769a08de82d812bc27c13fc6f06a9",
challenge: "ff41c3d25dbd8966fb61e28ef5e47041e137ed268520412d76202ba0ad2d1453",
credentialPubKey: "a5010203382220022158304866bd8b01da789e9eb806e5eab05ae5a638542296ab057a2f1bbce9b58f8a08b9171390b58a37ac7fffc2c5f45857da2258302a0b024c7f4b72072a1f96bd30a7261aae9571dd39870eb29e55c0941c6b08e89629a1ea1216aa64ce57c2807bf3901a",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.9 Packed Attestation - ES512 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-es512
name: "PackedES512",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22434e4d5a4447334c5055384d746c6d674d7a763136684a4e337a61677a5450564945734e65694b6f7a436279355046703067416f5848657a2d794c67386366306d6f66557669306c3653313565416a6471716d31635637394f6d72616b7a6e544253706f666278644c3479484777525234476b66563630546855473374793536714a4d334b6577635a6b7679354e376134574674434f7a7671416f71553745445a6a7a6c7149454569436b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "3081870242009bda02fe384e77bcb9fb42b07c395b7a53ec9d9616dd0308ab8495c2141c8364c7d16e212a4a4fb8e3987ff6c99eafd64d8484fd28c3fc7968f658a9033d1bb1b802416383e9f3ee20c691b66620299fef36bea2df4d39c92b2ead92f58e7b79ab0d9864d2ebf3b0dcc66ea13234492ccee6e9d421db43c959bcb94c162dc9494136c9f6",
credentialID: "d17d5af7e3f37c56622a67c8462c9e1c6336dfccb8b61d359dc47378dba58ce4",
challenge: "08d3190c6dcb3d4f0cb659a0333bf5ea124ddf36a0cd33d5204b0d7a22a8cc26f2e4f169d200285c77b3fb22e0f1c7f49a87d4be2d25e92d797808ddaaa9b5715efd3a6ada9339d3052a687dbc5d2f8c871b0451e0691f57ad138541b7b72e7aa8933729ec1c664bf2e4dedae1616d08ecefa80a2a53b103663ce5a881048829",
credentialPubKey: "a5010203382320032158420083240a2c3ad21a3dc0a6daa3d8bc05a46d7cd9825ba010ae2a22686c2d6d663d7d5f678987fb1e767542e63dc197ae915e25f8ee284651af29066910a2cc083f50225842017337df47ab5cce5d716ef8caffa97a3012689b1f326ea6c43a1ba9596c72f71f0122390143552b42be772b4c35ffb961220c743b486a601ea4cb6d5412f5b078d3",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.10 Packed Attestation - RS256 (Full Attestation with x5c and MDS)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-rs256
name: "PackedRS256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224b56395a39667150356978617970346e596d7834794e6f33617562597a5333536d75757459423462784d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "01063d52d7c39b4d432fc7063c5d93e582bdcb16889cd71f888d67d880ea730a428498d3bc8e1ee11f2b1ecbe6c292b118c55ffaaddefa8cad0a54dd137c51f1eec673f1bb6c4d1789d6826a222b22d0f585fc901fdc933212e579d199b89d672aa44891333e6a1355536025e82b25590256c3538229b55737083b2f6b9377e49e2472f11952f79fdd0da180b5ffd901b4049a8f081bb40711bef76c62aed943571f2d0575304cb549d68d8892f95086a30f93716aee818f8dc06e96c0d5e0ed4cfa9fd8773d90464b68cf140f7986666ff9c9e3302acd0535d60d769f465e2ab57ef8aabc89fccfef7ba32a64154a8b3d26be2298f470b8cc5377dbe3dfd4b0b45f8f01e63bde6cfc76b62771f9b70aa27cf40152cad93aa5acd784fd4b90f676e2ea828d0bf2400aebbaae4153e5838f537f88b6228346782a93a899be66ec77de45b3efcf311da6321c92e6b0cd11bfe653bf3e98cee8e341f02d67dbb6f9c98d9e8178090cfb5b70fbc6d541599ac794ae2f1d4de1286ec8de8c2daf7b1d15c8438e90d924df5c19045220a4c8438c1b979bbe016cf3d0eeec23c3999d4882cc645b776de930756612cdc6dd398160ff02a6",
credentialID: "992a18acc83f67533600c1138a4b4c4bd236de13629cf025ed17cb00b00b74df",
challenge: "295f59f5fa8fe62c5aca9e27626c78c8da376ae6d8cd2dd29aebad601e1bc4c5",
credentialPubKey: "a4010303390100205901b403fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012143010001",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.11 Packed Attestation - EdDSA (Authentication)
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-packed-eddsa
name: "PackedEdDSA",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50100000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2269566c583442786a4f6d6d44534b4c596f7870557439736e364d48454f7943413135726947514a6e763949222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "f5c59c7e46c34f6f8cc197101ddf9934fa2595f68eb1913a637e8419eb9ba4cfdfc48f85393bc0d40b011f0d6fecb097d6607525713223a0dc0d453993dae00b",
credentialID: "ce9f840ed96599580cd140fbc7bb3230633f50f61041aff73308ae71caa8a2bd",
challenge: "895957e01c633a698348a2d8a31a54b7db27e8c1c43b2080d79ae2190267bfd2",
credentialPubKey: "a401010327200621582044e06ddd331c36a8dc667bab52bcae63486c916aa5e339e6acebaa84934bf832",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.13 TPM Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-tpm-es256
name: "TPMES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2241416b375a7349645731364a393642776768474a422d6f2d554330304f7a464c6a46705531693279417673222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "3045022060dc76b1607ec716c6e5eba8d056695ed6bc47b2e3d7a729c34e759e3ab66aa0022100d010a9e8fddcb64c439dfdca628ddb33cf245d567d157d9f66f942601bed9b38",
credentialID: "ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9",
challenge: "00093b66c21d5b5e89f7a07082118907ea3e502d343b314b8c5a54d62db202fb",
credentialPubKey: "a501020326200121582041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b225820d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d07",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.14 Android Key Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-android-key-es256
name: "AndroidKeyES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22354f344679703238375851525a55447954746d74786971756851645742534b45545f702d36685433723459222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2071784a78422d5f78677277794d4c3631386472536e41227d",
signature: "3045022100a2b5e37da43ceb63566f6e2817c6cbef261073d0cadfd213ff6229bd33ddea6c02203d77eb3202fc92b9b5bb843ef082c7766f8c7f23194c92708ff2f3d1de765a8f",
credentialID: "0a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795",
challenge: "e4ee05ca9dbced74116540f24ed9adc62aae8507560522844ffa7eea14f7af86",
credentialPubKey: "a501020326200121582099169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accf225820dd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6b",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.15 Apple Anonymous Attestation - ES256 - Top Origin
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-apple-es256
name: "AppleAnonymousES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22302d73705a4751654a76375149304136637433676b37476353366b416a442d6432445f503030656d625155222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "3046022100ee35db795ce28044e1f8231d68b3d79a9882f7415aa35c1b5ac74d24251073c8022100dcc65691650a412d0ceef843710c09827acf26c7845bddac07eec95863e7fc4c",
credentialID: "9c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8",
challenge: "d3eb2964641e26fed023403a72dde093b19c4ba9008c3f9dd83fcfd347a66d05",
credentialPubKey: "a50102032620012158208a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761a225820f728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136c",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
//nolint:gosec
{
// §16.16 FIDO U2F Attestation - ES256
// See: https://w3c.github.io/webauthn/#sctn-test-vectors-fido-u2f-es256
name: "FIDOU2FES256",
authenticatorData: "bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50100000000",
clientDataJSON: "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a222d5178684b59485954316d554f4e3461554139326b6d36537a49532d2d4f417362694e5650774249564455222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d",
signature: "304402206172459958fea907b7292b92f555034bfd884895f287a76200c1ba287239137002204727b166147e26a21bbc2921d192ebfed569b79438538e5c128b5e28e6926dd7",
credentialID: "a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4",
challenge: "f90c612981d84f599438de1a500f76926e92cc84bef8e02c6e23553f00485435",
credentialPubKey: "a5010203262001215820b0d62de6b30f86f0bac7a9016951391c2e31849e2e64661cbd2b13cd7d5508ad225820503b0bda2a357a9a4b34475a28e65b660b4898a9e3e9bbf0820d43494297edd0",
rpTopOriginVerificationMode: TopOriginExplicitVerificationMode,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
body := specTestBuildAssertionJSON(t, tc.credentialID, tc.authenticatorData, tc.clientDataJSON, tc.signature, tc.userHandle)
par, err := ParseCredentialRequestResponseBody(bytes.NewReader(body))
require.NoError(t, err)
challenge := base64.RawURLEncoding.EncodeToString(specTestDecodeHex(t, tc.challenge))
credPubKey := specTestDecodeHex(t, tc.credentialPubKey)
err = par.Verify(challenge, specTestRPID, tc.appID, []string{specTestOrigin}, tc.rpTopOrigins, tc.rpTopOriginVerificationMode, tc.allowCrossOrigin, false, true, credPubKey)
if tc.err == "" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tc.err)
}
})
}
}
func TestSpecVectors_CACertificate(t *testing.T) {
assert.Equal(t, "WebAuthn test vectors", specTestCACert.Subject.CommonName)
assert.Equal(t, "W3C", specTestCACert.Subject.Organization[0])
assert.Equal(t, "Authenticator Attestation CA", specTestCACert.Subject.OrganizationalUnit[0])
assert.True(t, specTestCACert.IsCA)
}
// Supporting constants, types, and functions.
const (
specTestOrigin = "https://example.org"
// §16.1 Attestation Root Certificate used in tests.
specTestCACertHex = "30820207308201ada003020102021100ed7f905d8bd0b414d1784913170a90b6300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a3062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200043269300e5ff7b699015f70cf80a8763bf705bc2e2af0c1b39cff718b7c35880ca30f319078d91b03389a006fdfc8a1dcd84edfa07d30aa13474a248a0dab5baaa3423040300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e0416041445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d04030203480030450220483063b6bb08dcc83da33a02c11d2f42203176893554d138c614a36908724cc8022100f5ef2c912d4500b3e2f5b591d0622491e9f220dfd1f9734ec484bb7e90887663"
)
var (
specTestCACert *x509.Certificate
)
func specTestHexToBase64URL(t *testing.T, hexStr string) string {
t.Helper()
return base64.RawURLEncoding.EncodeToString(specTestDecodeHex(t, hexStr))
}
func specTestBuildRegistrationJSON(t *testing.T, credentialIDHex, attestationObjectHex, clientDataJSONHex string) []byte {
t.Helper()
id := specTestHexToBase64URL(t, credentialIDHex)
attObj := specTestHexToBase64URL(t, attestationObjectHex)
cdj := specTestHexToBase64URL(t, clientDataJSONHex)
response := map[string]any{
"id": id,
"rawId": id,
"type": "public-key",
"response": map[string]any{
"attestationObject": attObj,
"clientDataJSON": cdj,
},
}
data, err := json.Marshal(response)
require.NoError(t, err)
return data
}
func specTestBuildAssertionJSON(t *testing.T, credentialIDHex, authenticatorDataHex, clientDataJSONHex, signatureHex, userHandleHex string) []byte {
t.Helper()
id := specTestHexToBase64URL(t, credentialIDHex)
resp := map[string]any{
"authenticatorData": specTestHexToBase64URL(t, authenticatorDataHex),
"clientDataJSON": specTestHexToBase64URL(t, clientDataJSONHex),
"signature": specTestHexToBase64URL(t, signatureHex),
}
if userHandleHex != "" {
resp["userHandle"] = specTestHexToBase64URL(t, userHandleHex)
}
response := map[string]any{
"id": id,
"rawId": id,
"type": "public-key",
"response": resp,
}
data, err := json.Marshal(response)
require.NoError(t, err)
return data
}
// specTestMDSProvider returns a metadata.Provider that trusts the spec's synthetic attestation
// CA certificate (§16.1) for the packed attestation AAGUIDs.
func specTestMDSProvider(t *testing.T) metadata.Provider {
t.Helper()
knownAAGUIDs := map[uuid.UUID]bool{
uuid.Must(uuid.FromBytes(specTestDecodeHex(t, "876ca4f52071c3e9b25509ef2cdf7ed6"))): true, // ES256.
uuid.Must(uuid.FromBytes(specTestDecodeHex(t, "e950dcda3bdae1d087cda380a897848b"))): true, // ES384.
uuid.Must(uuid.FromBytes(specTestDecodeHex(t, "39d8ce6a3cf61025775083a738e5c254"))): true, // ES512.
uuid.Must(uuid.FromBytes(specTestDecodeHex(t, "428f8878298b9862a36ad8c7527bfef2"))): true, // RS256.
uuid.Must(uuid.FromBytes(specTestDecodeHex(t, "d5aa33581e8ca478e20fe713f5d32ff2"))): true, // EdDSA.
}
entry := &metadata.Entry{
MetadataStatement: metadata.Statement{
AttestationTypes: metadata.AuthenticatorAttestationTypes{metadata.BasicFull},
AttestationRootCertificates: []*x509.Certificate{specTestCACert},
},
StatusReports: []metadata.StatusReport{
{Status: metadata.FidoCertified},
},
}
ctrl := gomock.NewController(t)
mds := mocks.NewMockMetadataProvider(ctrl)
mds.EXPECT().GetEntry(gomock.Any(), gomock.Any()).DoAndReturn(func(_ interface{}, aaguid uuid.UUID) (*metadata.Entry, error) {
if knownAAGUIDs[aaguid] {
return entry, nil
}
return nil, nil
}).AnyTimes()
mds.EXPECT().GetValidateEntry(gomock.Any()).Return(false).AnyTimes()
mds.EXPECT().GetValidateEntryPermitZeroAAGUID(gomock.Any()).Return(true).AnyTimes()
mds.EXPECT().GetValidateTrustAnchor(gomock.Any()).Return(true).AnyTimes()
mds.EXPECT().GetValidateStatus(gomock.Any()).Return(false).AnyTimes()
mds.EXPECT().GetValidateAttestationTypes(gomock.Any()).Return(true).AnyTimes()
return mds
}
func init() {
data, err := hex.DecodeString(specTestCACertHex)
if err != nil {
panic(err)
}
cert, err := x509.ParseCertificate(data)
if err != nil {
panic(err)
}
specTestCACert = cert
attAndroidKeyHardwareRootsCertPool.AddCert(cert)
attAppleHardwareRootsCertPool.AddCert(cert)
tpmManufacturers = append(tpmManufacturers, tpmManufacturer{"00000000", "WebAuthn Test", "WebAuthnTest"})
}