package protocol import ( "crypto/sha256" "encoding/hex" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/go-webauthn/webauthn/metadata" "github.com/go-webauthn/webauthn/protocol/webauthncbor" "github.com/go-webauthn/webauthn/protocol/webauthncose" ) // WebAuthn Level 3 Specification Test Vectors // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors // // All test vectors use: // - RP ID: example.org // - Origin: https://example.org // - Certificate validity: 2024-01-01 to 3024-01-01 // - Deterministic random via HKDF-SHA-256 from IKM "WebAuthn test vectors" // - ECDSA signatures use deterministic nonces per RFC 6979 // §16.2 None Attestation - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-none-es256 func TestSpecVectors_NoneES256(t *testing.T) { attObjHex := "a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b559000000008446ccb9ab1db374750b2367ff6f3a1f0020f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4a5010203262001215820afefa16f97ca9b2d23eb86ccb64098d20db90856062eb249c33a9b672f26df61225820930a56b87a2fca66334b03458abf879717c12cc68ed73290af2e2664796b9220" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22414d4d507434557878475453746e63647134313759447742466938767049612d7077386f4f755657345441222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20426b5165446a646354427258426941774a544c453551227d" att := specTestParseAndVerify(t, attObjHex, clientDataJSONHex, specCredParamsES256) assert.Equal(t, stmtFmtNone, att.Format) assert.True(t, att.AuthData.Flags.HasUserPresent()) assert.True(t, att.AuthData.Flags.HasAttestedCredentialData()) assert.Empty(t, att.AttStatement) credID := specTestDecodeHex(t, "f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) } // §16.3 Self Attestation (Packed) - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-self-es256 func TestSpecVectors_PackedSelfES256(t *testing.T) { attObjHex := "a363666d74667061636b65646761747453746d74a263616c672663736967584630440220067a20754ab925005dbf378097c92120031581c73228d1fb4f5b881bcd7da98302207fc7b147558c7c0eba3af18bd9d121fa3d3a26d17fe3f220272178f473b6006d68617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000df850e09db6afbdfab51697791506cfc0020455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58ca5010203262001215820eb151c8176b225cc651559fecf07af450fd85802046656b34c18f6cf193843c5225820927b8aa427a2be1b8834d233a2d34f61f13bfd44119c325d5896e183fee484f2" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2265476e4374334c55745936366b336a506a796e6962506b31716e666644616966715a774c33417032392d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205539685458764b453255526b4d6e625f307859485667227d" att := specTestParseAndVerify(t, attObjHex, clientDataJSONHex, specCredParamsES256) assert.Equal(t, "packed", att.Format) assert.True(t, att.AuthData.Flags.HasUserPresent()) assert.True(t, att.AuthData.Flags.HasUserVerified()) assert.True(t, att.AuthData.Flags.HasAttestedCredentialData()) credID := specTestDecodeHex(t, "455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58c") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) rawClientDataJSON := specTestDecodeHex(t, clientDataJSONHex) clientDataHash := sha256.Sum256(rawClientDataJSON) attestationType, _, err := attestationFormatValidationHandlerPacked(att, clientDataHash[:], nil) require.NoError(t, err) assert.Equal(t, string(metadata.BasicSurrogate), attestationType) } // §16.7 Packed Attestation - ES256 (Full Attestation with x5c) // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-packed-es256 func TestSpecVectors_PackedES256(t *testing.T) { attObjHex := "a363666d74667061636b65646761747453746d74a363616c6726637369675847304502203f19ec4b229f46ab8c45eff29b904ff10c0390dc40bf1216f04a78f4ceba3425022100fe7041a32759aff05a0f9f26c70a999c7a284451ba89234a1d3483c25e21925b637835638159022530820221308201c8a00302010202110088c220f83c8ef1feafe94deae45faad0300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004a91ba4389409dd38a428141940ca8feb1ac0d7b4350558104a3777a49322f3798440f378b3398ab2d3bb7bf91322c92eb23556f59ad0a836fec4c7663b0e4dc3a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414a589ba72d060842ab11f74fb246bdedab16f9b9b301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034700304402201726b9d85ecd8a5ed51163722ca3a20886fd9b242a0aa0453d442116075defd502207ef471e530ac87961a88a7f0d0c17b091ffc6b9238d30f79f635b417be5910e768617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d00000000876ca4f52071c3e9b25509ef2cdf7ed60020c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5a50102032620012158201cf27f25da591208a4239c2e324f104f585525479a29edeedd830f48e77aeae522582059e4b7da6c0106e206ce390c93ab98a15a5ec3887e57f0cc2bece803b920c423" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227752684b58393334424634543345663153324831706c61325a725751475046746877365356756d56494249222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20396138624e596a4b436757724258552d66436c316167227d" att := specTestParseAndVerify(t, attObjHex, clientDataJSONHex, specCredParamsES256) assert.Equal(t, "packed", att.Format) credID := specTestDecodeHex(t, "c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) rawClientDataJSON := specTestDecodeHex(t, clientDataJSONHex) clientDataHash := sha256.Sum256(rawClientDataJSON) attestationType, x5cs, err := attestationFormatValidationHandlerPacked(att, clientDataHash[:], nil) require.NoError(t, err) assert.Equal(t, string(metadata.BasicFull), attestationType) assert.NotEmpty(t, x5cs) } // §16.13 TPM Attestation - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-tpm-es256 // // The spec test vectors use synthetic manufacturer ID "00000000" which is not in the real TPM // manufacturer registry. This test validates CBOR parsing, authData, and rpIdHash but the // format-specific handler rejects the synthetic manufacturer. func TestSpecVectors_TPMES256(t *testing.T) { attObjHex := "a363666d746374706d6761747453746d74a663616c67266373696758463044022066e5826a652091030fd444e33c3eca2bc6dc548cf3045013addb38aa6457a21002203f3a5c95c9e707d0e555041bcc8698ee4ebc04e26cc8bae459705471789851766376657263322e30637835638159023a30820236308201dca0030201020210311fc42da0ab10c43a9b1bf3a75e34e2300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004c54e3f109094f60d7699b7db5d838569ffd1f3e1c9e897cd9eb40063f9402e3e9937e936cf1fcd5eb743ff443c97ab2edcd7c8e0e6cf6cfd413b8ab19fffa769a381d33081d0300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604145f546cb6973d4981e80fcdc7463859f5879680e4301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e30100603551d250409300706056781050803305e0603551d110101ff04543052a450304e314c3014060567810502010c0b69643a30303030303030303014060567810502030c0b69643a3030303030303030301e060567810502020c15576562417574686e207465737420766563746f7273300a06082a8648ce3d0403020348003045022063c9a2797b8066f1db34dd609f1ab6695607e7a98e9ff8090a68853c9a9fc949022100a55831a39f5b8a2aa9a68837829cabf43fea2a5cea4859ae851cac78e6ac3e97677075624172656158560023000b0004000000000010001000030010002041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b0020d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d076863657274496e666f5869ff544347801700000020277d0e05579dd013215a62273f7f3a3e7e191ead2654a3036d75a5a3ee37a6b0000000000000000011111111222222223300000000000000000022000b9c42d8aad5939331b9af3711af179f17123178098c9a7d0ca89fcd1fc800f3c7000068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d000000004b92a377fc5f6107c4c85c190adbfd990020ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9a501020326200121582041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b225820d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d07" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227a38677333787a753648595343716950413254776b51475452677a376c364d587376344a427054356f706b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d" att := specTestParseAttestationObject(t, attObjHex) assert.Equal(t, "tpm", att.Format) credID := specTestDecodeHex(t, "ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) clientDataHash := sha256.Sum256(specTestDecodeHex(t, clientDataJSONHex)) _, _, err := attestationFormatValidationHandlerTPM(att, clientDataHash[:], nil) assert.NoError(t, err) } // §16.14 Android Key Attestation - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-android-key-es256 // // The spec test vectors use a synthetic certificate whose Android keystore extension encodes the // AttestationSecurityLevel and KeymasterSecurityLevel fields as ASN.1 INTEGER instead of ENUMERATED. // Real Android keystore certificates use ENUMERATED, so the full format handler cannot parse the // synthetic extension. This test validates CBOR parsing, authData, and rpIdHash only. func TestSpecVectors_AndroidKeyES256(t *testing.T) { attObjHex := "a363666d746b616e64726f69642d6b65796761747453746d74a363616c67266373696758483046022100e95512982aa3f216cff2e87c8ec57057b8529f674eaabeccaa27fd03d8779f19022100afb6bf459da4a826f00d01fc6b60712ff31dc4eb331619c8f874bb17e4314e94637835638159026f3082026b30820210a00302010202101ff91f76b63f44812f998b250b0286bf300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000499169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accfdd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6ba381a83081a5300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604141ac81e50641e8d1339ab9f7eb25f0cd5aac054b0301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e3045060a2b06010401d679020111043730350202012c0201000201000201000420b435028d7b6a8f83bb461d41c19b053a9d3cdb30351a4f374cd4cde8dbefb606040030003000300a06082a8648ce3d040302034900304602210081671f2474f336e6b5a868d28b47cd054c0ed4261f531fcdf1a1ceed19f600ad022100e7ac683848c34842a432ff4a26e9dbc537b88e83fc4cb59138de3ca3a3e1081468617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000ade9705e1ce7085b899a540d02199bf800200a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795a501020326200121582099169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accf225820dd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6b" att := specTestParseAttestationObject(t, attObjHex) assert.Equal(t, "android-key", att.Format) credID := specTestDecodeHex(t, "0a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) rpIDHash := sha256.Sum256([]byte(specTestRPID)) assert.Equal(t, rpIDHash[:], att.AuthData.RPIDHash) } // §16.15 Apple Anonymous Attestation - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-apple-es256 // // The spec test vectors use a synthetic CA not in the hardcoded Apple hardware root pool. // This test validates CBOR parsing, authData, and rpIdHash. func TestSpecVectors_AppleES256(t *testing.T) { attObjHex := "a363666d74656170706c656761747453746d74a1637835638159025c30820258308201fea0030201020210394275613d5310b81a29ce90f48b61c1300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200048a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761af728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136ca38196308193300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e0416041412f1ce6c0ae39b403bfc9200317bc183a4e4d766301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e303306092a864886f76364080204263024a1220420d7a86e7233fb843eb0eeb407d8b76ff7e4f82d218cf5dbb461d752073f5cb29a300a06082a8648ce3d0403020348003045022070f5c2ede3000e9dae358d412b26a4acbf18f4cdeb80f5b13fcd564d090c39ec022100f672e2c3dbe117c9b1490b3c660abf5dcd74398187082dacb58b6744de4aca6068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54900000000748210a20076616a733b2114336fc38400209c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8a50102032620012158208a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761a225820f728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136c" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22395f61494954685341486431414a7a34774a6239714a316775616e37576c4464676432596d4b396142676b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20546a4c506e704f6158515572464e6362483274545a41227d" att := specTestParseAttestationObject(t, attObjHex) assert.Equal(t, "apple", att.Format) credID := specTestDecodeHex(t, "9c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) clientDataHash := sha256.Sum256(specTestDecodeHex(t, clientDataJSONHex)) _, _, err := attestationFormatValidationHandlerAppleAnonymous(att, clientDataHash[:], nil) assert.NoError(t, err) } // §16.16 FIDO U2F Attestation - ES256 // See: https://www.w3.org/TR/webauthn-3/#sctn-test-vectors-fido-u2f-es256 // // The spec test vector uses a non-zero AAGUID (afb3c2ef...) which is correctly rejected by // the FIDO U2F handler per §8.6 which requires AAGUID to be all zeros. This test validates // CBOR parsing, authData, rpIdHash, and credential algorithm matching. func TestSpecVectors_FIDOU2FES256(t *testing.T) { attObjHex := "a363666d74686669646f2d7532666761747453746d74a26373696758473045022100f41887a20063bb26867cb9751978accea5b81791a68f4f4dd6ea1fb6a5c086c302204e5e00aa3895777e6608f1f375f95450045da3da57a0e4fd451df35a31d2d98a637835638159022530820221308201c7a003020102021004f66dc6542ea7719dea416d325a2401300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000456fffa7093dede46aefeefb6e520c7ccc78967636e2f92582ba71455f64e93932dff3be4e0d4ef68e3e3b73aa087e26a0a0a30b02dc2aa2309db4c3a2fc936dea360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414420822eb1908b5cd3911017fbcad4641c05e05a3301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034800304502200d0b777f0a0b181ad2830275acc3150fd6092430bcd034fd77beb7bdf8c2d546022100d4864edd95daa3927080855df199f1717299b24a5eecefbd017455a9b934d8f668617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54100000000afb3c2efc054df425013d5c88e79c3c10020a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4a5010203262001215820b0d62de6b30f86f0bac7a9016951391c2e31849e2e64661cbd2b13cd7d5508ad225820503b0bda2a357a9a4b34475a28e65b660b4898a9e3e9bbf0820d43494297edd0" clientDataJSONHex := "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22344851334b5a4335797155486f696666786e73414e344445557955344452715177672d4237583049444159222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d" att := specTestParseAttestationObject(t, attObjHex) assert.Equal(t, "fido-u2f", att.Format) credID := specTestDecodeHex(t, "a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4") assert.Equal(t, credID, att.AuthData.AttData.CredentialID) rpIDHash := sha256.Sum256([]byte(specTestRPID)) require.NoError(t, att.AuthData.Verify(rpIDHash[:], nil, false, true)) var pk webauthncose.PublicKeyData require.NoError(t, webauthncbor.Unmarshal(att.AuthData.AttData.CredentialPublicKey, &pk)) assert.Equal(t, int64(webauthncose.AlgES256), pk.Algorithm) clientDataHash := sha256.Sum256(specTestDecodeHex(t, clientDataJSONHex)) _, _, err := attestationFormatValidationHandlerFIDOU2F(att, clientDataHash[:], nil) assert.NoError(t, err) } // Supporting constants, variables, and functions. const specTestRPID = "example.org" var specCredParamsES256 = []CredentialParameter{{Type: PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}} func specTestDecodeHex(t *testing.T, s string) []byte { t.Helper() data, err := hex.DecodeString(s) require.NoError(t, err) return data } func specTestParseAndVerify(t *testing.T, attObjHex, clientDataJSONHex string, credParams []CredentialParameter) AttestationObject { t.Helper() rawAttObj := specTestDecodeHex(t, attObjHex) rawClientDataJSON := specTestDecodeHex(t, clientDataJSONHex) var att AttestationObject require.NoError(t, webauthncbor.Unmarshal(rawAttObj, &att)) require.NoError(t, att.AuthData.Unmarshal(att.RawAuthData)) rpIDHash := sha256.Sum256([]byte(specTestRPID)) assert.Equal(t, rpIDHash[:], att.AuthData.RPIDHash) clientDataHash := sha256.Sum256(rawClientDataJSON) require.NoError(t, att.Verify(specTestRPID, clientDataHash[:], false, true, nil, credParams)) return att } func specTestParseAttestationObject(t *testing.T, attObjHex string) AttestationObject { t.Helper() rawAttObj := specTestDecodeHex(t, attObjHex) var att AttestationObject require.NoError(t, webauthncbor.Unmarshal(rawAttObj, &att)) require.NoError(t, att.AuthData.Unmarshal(att.RawAuthData)) rpIDHash := sha256.Sum256([]byte(specTestRPID)) assert.Equal(t, rpIDHash[:], att.AuthData.RPIDHash) return att }