mirror of
https://github.com/sonr-io/common.git
synced 2026-01-12 04:09:13 +00:00
368 lines
14 KiB
Go
368 lines
14 KiB
Go
|
|
package webauthn
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"encoding/base64"
|
||
|
|
"io"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
|
||
|
|
"github.com/sonr-io/common/webauthn/webauthncbor"
|
||
|
|
"github.com/sonr-io/common/webauthn/webauthncose"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestParseCredentialCreationResponse(t *testing.T) {
|
||
|
|
type args struct {
|
||
|
|
responseName string
|
||
|
|
}
|
||
|
|
|
||
|
|
byteID, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
)
|
||
|
|
byteAuthData, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
)
|
||
|
|
byteRPIDHash, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvA",
|
||
|
|
)
|
||
|
|
byteCredentialPubKey, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"pSJYIMfCKfxl2SvnqJIiHQysHmpmITNgtCkQ5ESExSRjqrhXAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNc",
|
||
|
|
)
|
||
|
|
byteAttObject, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
)
|
||
|
|
byteClientDataJSON, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ",
|
||
|
|
)
|
||
|
|
|
||
|
|
testCases := []struct {
|
||
|
|
name string
|
||
|
|
args args
|
||
|
|
expected *ParsedCredentialCreationData
|
||
|
|
errString string
|
||
|
|
errType string
|
||
|
|
errDetails string
|
||
|
|
errInfo string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "ShouldParseCredentialRequest",
|
||
|
|
args: args{
|
||
|
|
responseName: "success",
|
||
|
|
},
|
||
|
|
expected: &ParsedCredentialCreationData{
|
||
|
|
ParsedPublicKeyCredential: ParsedPublicKeyCredential{
|
||
|
|
ParsedCredential: ParsedCredential{
|
||
|
|
ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
Type: string(PublicKeyCredentialType),
|
||
|
|
},
|
||
|
|
RawID: byteID,
|
||
|
|
ClientExtensionResults: AuthenticationExtensionsClientOutputs{
|
||
|
|
"appid": true,
|
||
|
|
},
|
||
|
|
AuthenticatorAttachment: Platform,
|
||
|
|
},
|
||
|
|
Response: ParsedAttestationResponse{
|
||
|
|
CollectedClientData: CollectedClientData{
|
||
|
|
Type: CeremonyType("webauthn.create"),
|
||
|
|
Challenge: "W8GzFU8pGjhoRbWrLDlamAfq_y4S1CZG1VuoeRLARrE",
|
||
|
|
Origin: "https://webauthn.io",
|
||
|
|
},
|
||
|
|
AttestationObject: AttestationObject{
|
||
|
|
Format: "none",
|
||
|
|
RawAuthData: byteAuthData,
|
||
|
|
AuthData: AuthenticatorData{
|
||
|
|
RPIDHash: byteRPIDHash,
|
||
|
|
Counter: 0,
|
||
|
|
Flags: 0x041,
|
||
|
|
AttData: AttestedCredentialData{
|
||
|
|
AAGUID: make([]byte, 16),
|
||
|
|
CredentialID: byteID,
|
||
|
|
CredentialPublicKey: byteCredentialPubKey,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
Transports: []AuthenticatorTransport{USB, NFC, "fake"},
|
||
|
|
},
|
||
|
|
Raw: CredentialCreationResponse{
|
||
|
|
PublicKeyCredential: PublicKeyCredential{
|
||
|
|
Credential: Credential{
|
||
|
|
Type: string(PublicKeyCredentialType),
|
||
|
|
ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
},
|
||
|
|
RawID: byteID,
|
||
|
|
ClientExtensionResults: AuthenticationExtensionsClientOutputs{
|
||
|
|
"appid": true,
|
||
|
|
},
|
||
|
|
AuthenticatorAttachment: "platform",
|
||
|
|
},
|
||
|
|
AttestationResponse: AuthenticatorAttestationResponse{
|
||
|
|
AuthenticatorResponse: AuthenticatorResponse{
|
||
|
|
ClientDataJSON: byteClientDataJSON,
|
||
|
|
},
|
||
|
|
AttestationObject: byteAttObject,
|
||
|
|
Transports: []string{"usb", "nfc", "fake"},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
errString: "",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "ShouldHandleTrailingData",
|
||
|
|
args: args{
|
||
|
|
responseName: "trailingData",
|
||
|
|
},
|
||
|
|
expected: nil,
|
||
|
|
errString: "Parse error for Registration",
|
||
|
|
errType: "invalid_request",
|
||
|
|
errDetails: "Parse error for Registration",
|
||
|
|
errInfo: "The body contains trailing data",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range testCases {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
body := io.NopCloser(
|
||
|
|
bytes.NewReader([]byte(testCredentialRequestResponses[tc.args.responseName])),
|
||
|
|
)
|
||
|
|
|
||
|
|
actual, err := ParseCredentialCreationResponseBody(body)
|
||
|
|
|
||
|
|
if tc.errString != "" {
|
||
|
|
assert.EqualError(t, err, tc.errString)
|
||
|
|
|
||
|
|
AssertIsProtocolError(t, err, tc.errType, tc.errDetails, tc.errInfo)
|
||
|
|
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
assert.Equal(t, tc.expected.ClientExtensionResults, actual.ClientExtensionResults)
|
||
|
|
assert.Equal(t, tc.expected.ID, actual.ID)
|
||
|
|
assert.Equal(t, tc.expected.Type, actual.Type)
|
||
|
|
assert.Equal(t, tc.expected.ParsedCredential, actual.ParsedCredential)
|
||
|
|
assert.Equal(t, tc.expected.ParsedPublicKeyCredential, actual.ParsedPublicKeyCredential)
|
||
|
|
assert.Equal(t, tc.expected.ParsedPublicKeyCredential, actual.ParsedPublicKeyCredential)
|
||
|
|
assert.Equal(t, tc.expected.Raw, actual.Raw)
|
||
|
|
assert.Equal(t, tc.expected.RawID, actual.RawID)
|
||
|
|
assert.Equal(t, tc.expected.Response.Transports, actual.Response.Transports)
|
||
|
|
assert.Equal(
|
||
|
|
t,
|
||
|
|
tc.expected.Response.CollectedClientData,
|
||
|
|
actual.Response.CollectedClientData,
|
||
|
|
)
|
||
|
|
assert.Equal(
|
||
|
|
t,
|
||
|
|
tc.expected.Response.AttestationObject.AuthData.AttData.CredentialID,
|
||
|
|
actual.Response.AttestationObject.AuthData.AttData.CredentialID,
|
||
|
|
)
|
||
|
|
assert.Equal(
|
||
|
|
t,
|
||
|
|
tc.expected.Response.AttestationObject.Format,
|
||
|
|
actual.Response.AttestationObject.Format,
|
||
|
|
)
|
||
|
|
|
||
|
|
// Unmarshall CredentialPublicKey
|
||
|
|
var pkExpected, pkActual any
|
||
|
|
|
||
|
|
pkBytesExpected := tc.expected.Response.AttestationObject.AuthData.AttData.CredentialPublicKey
|
||
|
|
assert.NoError(t, webauthncbor.Unmarshal(pkBytesExpected, &pkExpected))
|
||
|
|
|
||
|
|
pkBytesActual := actual.Response.AttestationObject.AuthData.AttData.CredentialPublicKey
|
||
|
|
assert.NoError(t, webauthncbor.Unmarshal(pkBytesActual, &pkActual))
|
||
|
|
|
||
|
|
assert.Equal(t, pkExpected, pkActual)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParsedCredentialCreationData_Verify(t *testing.T) {
|
||
|
|
byteID, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
)
|
||
|
|
byteChallenge, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"W8GzFU8pGjhoRbWrLDlamAfq_y4S1CZG1VuoeRLARrE",
|
||
|
|
)
|
||
|
|
byteAuthData, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
)
|
||
|
|
byteRPIDHash, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvA",
|
||
|
|
)
|
||
|
|
byteCredentialPubKey, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"pSJYIMfCKfxl2SvnqJIiHQysHmpmITNgtCkQ5ESExSRjqrhXAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNc",
|
||
|
|
)
|
||
|
|
byteAttObject, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
)
|
||
|
|
byteClientDataJSON, _ := base64.RawURLEncoding.DecodeString(
|
||
|
|
"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ",
|
||
|
|
)
|
||
|
|
|
||
|
|
type fields struct {
|
||
|
|
ParsedPublicKeyCredential ParsedPublicKeyCredential
|
||
|
|
Response ParsedAttestationResponse
|
||
|
|
Raw CredentialCreationResponse
|
||
|
|
}
|
||
|
|
|
||
|
|
type args struct {
|
||
|
|
storedChallenge URLEncodedBase64
|
||
|
|
verifyUser bool
|
||
|
|
relyingPartyID string
|
||
|
|
relyingPartyOrigin []string
|
||
|
|
credParams []CredentialParameter
|
||
|
|
}
|
||
|
|
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
fields fields
|
||
|
|
args args
|
||
|
|
wantErr bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "Successful Verification Test",
|
||
|
|
fields: fields{
|
||
|
|
ParsedPublicKeyCredential: ParsedPublicKeyCredential{
|
||
|
|
ParsedCredential: ParsedCredential{
|
||
|
|
ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
Type: string(PublicKeyCredentialType),
|
||
|
|
},
|
||
|
|
RawID: byteID,
|
||
|
|
},
|
||
|
|
Response: ParsedAttestationResponse{
|
||
|
|
CollectedClientData: CollectedClientData{
|
||
|
|
Type: CeremonyType("webauthn.create"),
|
||
|
|
Challenge: "W8GzFU8pGjhoRbWrLDlamAfq_y4S1CZG1VuoeRLARrE",
|
||
|
|
Origin: "https://webauthn.io",
|
||
|
|
},
|
||
|
|
AttestationObject: AttestationObject{
|
||
|
|
Format: "none",
|
||
|
|
RawAuthData: byteAuthData,
|
||
|
|
AuthData: AuthenticatorData{
|
||
|
|
RPIDHash: byteRPIDHash,
|
||
|
|
Counter: 0,
|
||
|
|
Flags: 0x041,
|
||
|
|
AttData: AttestedCredentialData{
|
||
|
|
AAGUID: make([]byte, 16),
|
||
|
|
CredentialID: byteID,
|
||
|
|
CredentialPublicKey: byteCredentialPubKey,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
Raw: CredentialCreationResponse{
|
||
|
|
PublicKeyCredential: PublicKeyCredential{
|
||
|
|
Credential: Credential{
|
||
|
|
Type: string(PublicKeyCredentialType),
|
||
|
|
ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
},
|
||
|
|
RawID: byteID,
|
||
|
|
},
|
||
|
|
AttestationResponse: AuthenticatorAttestationResponse{
|
||
|
|
AuthenticatorResponse: AuthenticatorResponse{
|
||
|
|
ClientDataJSON: byteClientDataJSON,
|
||
|
|
},
|
||
|
|
AttestationObject: byteAttObject,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
args: args{
|
||
|
|
storedChallenge: URLEncodedBase64(byteChallenge),
|
||
|
|
verifyUser: false,
|
||
|
|
relyingPartyID: `webauthn.io`,
|
||
|
|
relyingPartyOrigin: []string{`https://webauthn.io`},
|
||
|
|
credParams: []CredentialParameter{
|
||
|
|
{Type: "public-key", Algorithm: webauthncose.AlgES256},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
pcc := &ParsedCredentialCreationData{
|
||
|
|
ParsedPublicKeyCredential: tt.fields.ParsedPublicKeyCredential,
|
||
|
|
Response: tt.fields.Response,
|
||
|
|
Raw: tt.fields.Raw,
|
||
|
|
}
|
||
|
|
if _, err := pcc.Verify(tt.args.storedChallenge.String(), tt.args.verifyUser, false, tt.args.relyingPartyID, tt.args.relyingPartyOrigin, nil, TopOriginIgnoreVerificationMode, nil, tt.args.credParams); (err != nil) != tt.wantErr {
|
||
|
|
t.Errorf(
|
||
|
|
"ParsedCredentialCreationData.Verify() error = %+v, wantErr %v",
|
||
|
|
err,
|
||
|
|
tt.wantErr,
|
||
|
|
)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var testCredentialRequestResponses = map[string]string{
|
||
|
|
`success`: `
|
||
|
|
{
|
||
|
|
"id":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"rawId":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"type":"public-key",
|
||
|
|
"authenticatorAttachment":"platform",
|
||
|
|
"clientExtensionResults":{
|
||
|
|
"appid":true
|
||
|
|
},
|
||
|
|
"response":{
|
||
|
|
"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ",
|
||
|
|
"transports":["usb","nfc","fake"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
`,
|
||
|
|
`trailingData`: `
|
||
|
|
{
|
||
|
|
"id":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"rawId":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"type":"public-key",
|
||
|
|
"authenticatorAttachment":"platform",
|
||
|
|
"clientExtensionResults":{
|
||
|
|
"appid":true
|
||
|
|
},
|
||
|
|
"response":{
|
||
|
|
"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ",
|
||
|
|
"transports":["usb","nfc","fake"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
trailing
|
||
|
|
`,
|
||
|
|
`successDeprecatedTransports`: `
|
||
|
|
{
|
||
|
|
"id":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"rawId":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"type":"public-key",
|
||
|
|
"authenticatorAttachment":"not-valid",
|
||
|
|
"transports":["usb","nfc","fake"],
|
||
|
|
"clientExtensionResults":{
|
||
|
|
"appid":true
|
||
|
|
},
|
||
|
|
"response":{
|
||
|
|
"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
`,
|
||
|
|
`successDeprecatedTransportsAndNew`: `
|
||
|
|
{
|
||
|
|
"id":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"rawId":"6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g",
|
||
|
|
"type":"public-key",
|
||
|
|
"authenticatorAttachment":"cross-platform",
|
||
|
|
"transports":["usb","nfc","fake"],
|
||
|
|
"clientExtensionResults":{
|
||
|
|
"appid":true
|
||
|
|
},
|
||
|
|
"response":{
|
||
|
|
"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQOsa7QYSUFukFOLTmgeK6x2ktirNMgwy_6vIwwtegxI2flS1X-JAkZL5dsadg-9bEz2J7PnsbB0B08txvsyUSvKlAQIDJiABIVggLKF5xS0_BntttUIrm2Z2tgZ4uQDwllbdIfrrBMABCNciWCDHwin8Zdkr56iSIh0MrB5qZiEzYLQpEOREhMUkY6q4Vw",
|
||
|
|
"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJXOEd6RlU4cEdqaG9SYldyTERsYW1BZnFfeTRTMUNaRzFWdW9lUkxBUnJFIiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5pbyIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ",
|
||
|
|
"transports":["usb","nfc"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
`,
|
||
|
|
}
|