Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/google/uuid v1.6.0
github.com/mitchellh/mapstructure v1.5.0
github.com/stretchr/testify v1.11.0
go.uber.org/mock v0.6.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQ
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
Expand Down
47 changes: 26 additions & 21 deletions protocol/attestation_androidkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"crypto/x509"
"encoding/asn1"
"fmt"
"time"

"github.com/go-webauthn/webauthn/metadata"
"github.com/go-webauthn/webauthn/protocol/webauthncose"
)

func init() {
RegisterAttestationFormat(AttestationFormatAndroidKey, verifyAndroidKeyFormat)
RegisterAttestationFormat(AttestationFormatAndroidKey, attestationFormatValidationHandlerAndroidKey)
}

// The android-key attestation statement looks like:
Expand All @@ -29,7 +30,7 @@ func init() {
// }
//
// Specification: §8.4. Android Key Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-android-key-attestation)
func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (attestationType string, x5cs []any, err error) {
func attestationFormatValidationHandlerAndroidKey(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (attestationType string, x5cs []any, err error) {
// Given the verification procedure inputs attStmt, authenticatorData and clientDataHash, the verification procedure is as follows:
// §8.4.1. Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract
// the contained fields.
Expand All @@ -56,42 +57,42 @@ func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte, _ meta

// §8.4.2. Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash
// using the public key in the first certificate in x5c with the algorithm specified in alg.
attCertBytes, valid := x5c[0].([]byte)
if !valid {
return "", nil, ErrAttestation.WithDetails("Error getting certificate from x5c cert chain")
var certs []*x509.Certificate

if certs, err = parseX5C(x5c); err != nil {
return "", nil, ErrAttestation.WithDetails("Error parsing x5c cert chain").WithError(err)
}

attCert, err := x509.ParseCertificate(attCertBytes)
if err != nil {
return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err)
credCert := certs[0]

if _, err = certChainVerify(certs, attAndroidKeyHardwareRootsCertPool, true, time.Now().Add(time.Hour*8760).UTC()); err != nil {
return "", nil, ErrInvalidAttestation.WithDetails("Error validating x5c cert chain").WithError(err)
}

signatureData := append(att.RawAuthData, clientDataHash...) //nolint:gocritic // This is intentional.

coseAlg := webauthncose.COSEAlgorithmIdentifier(alg)
if err = attCert.CheckSignature(webauthncose.SigAlgFromCOSEAlg(coseAlg), signatureData, sig); err != nil {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)).WithError(err)
if err = credCert.CheckSignature(webauthncose.SigAlgFromCOSEAlg(coseAlg), signatureData, sig); err != nil {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v", err)).WithError(err)
}

// Verify that the public key in the first certificate in x5c matches the credentialPublicKey in the attestedCredentialData in authenticatorData.
pubKey, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey)
if err != nil {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err)
var attPublicKeyData webauthncose.EC2PublicKeyData
if attPublicKeyData, err = verifyAttestationECDSAPublicKeyMatch(att, credCert); err != nil {
return "", nil, err
}

e := pubKey.(webauthncose.EC2PublicKeyData)

valid, err = e.Verify(signatureData, sig)
if err != nil || !valid {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err)
var valid bool
if valid, err = attPublicKeyData.Verify(signatureData, sig); err != nil || !valid {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v", err)).WithError(err)
}

// §8.4.3. Verify that the attestationChallenge field in the attestation certificate extension data is identical to clientDataHash.
// attCert.Extensions.
var attExtBytes []byte

for _, ext := range attCert.Extensions {
if ext.Id.Equal([]int{1, 3, 6, 1, 4, 1, 11129, 2, 1, 17}) {
for _, ext := range credCert.Extensions {
if ext.Id.Equal(oidExtensionAndroidKeystore) {
attExtBytes = ext.Value
}
}
Expand All @@ -114,7 +115,7 @@ func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte, _ meta
}

// The AuthorizationList.allApplications field is not present on either authorization list (softwareEnforced nor teeEnforced), since PublicKeyCredential MUST be scoped to the RP ID.
if nil != decoded.SoftwareEnforced.AllApplications || nil != decoded.TeeEnforced.AllApplications {
if decoded.SoftwareEnforced.AllApplications != nil || decoded.TeeEnforced.AllApplications != nil {
return "", nil, ErrAttestationFormat.WithDetails("Attestation certificate extensions contains all applications field")
}

Expand Down Expand Up @@ -239,3 +240,7 @@ const (
KM_PURPOSE_DERIVE_KEY /* Usable with EC keys. */
KM_PURPOSE_WRAP /* Usable with wrapped keys. */
)

var (
attAndroidKeyHardwareRootsCertPool *x509.CertPool
)
104 changes: 84 additions & 20 deletions protocol/attestation_androidkey_test.go

Large diffs are not rendered by default.

56 changes: 22 additions & 34 deletions protocol/attestation_apple.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@ package protocol

import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"fmt"
"math/big"
"time"

"github.com/go-webauthn/webauthn/metadata"
"github.com/go-webauthn/webauthn/protocol/webauthncose"
)

func init() {
RegisterAttestationFormat(AttestationFormatApple, verifyAppleFormat)
RegisterAttestationFormat(AttestationFormatApple, attestationFormatValidationHandlerAppleAnonymous)
}

// The apple attestation statement looks like:
Expand All @@ -31,7 +27,7 @@ func init() {
// }
//
// Specification: §8.8. Apple Anonymous Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-apple-anonymous-attestation)
func verifyAppleFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (attestationType string, x5cs []any, err error) {
func attestationFormatValidationHandlerAppleAnonymous(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (attestationType string, x5cs []any, err error) {
// Step 1. Verify that attStmt is valid CBOR conforming to the syntax defined
// above and perform CBOR decoding on it to extract the contained fields.
// If x5c is not present, return an error.
Expand All @@ -41,27 +37,29 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte, _ metadata.
return "", nil, ErrAttestationFormat.WithDetails("Error retrieving x5c value")
}

credCertBytes, valid := x5c[0].([]byte)
if !valid {
return "", nil, ErrAttestation.WithDetails("Error getting certificate from x5c cert chain")
}

credCert, err := x509.ParseCertificate(credCertBytes)
if err != nil {
return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err)
}

// Step 2. Concatenate authenticatorData and clientDataHash to form nonceToHash.
nonceToHash := append(att.RawAuthData, clientDataHash...) //nolint:gocritic // This is intentional.

// Step 3. Perform SHA-256 hash of nonceToHash to produce nonce.
nonce := sha256.Sum256(nonceToHash)

// Step 4. Verify that nonce equals the value of the extension with OID 1.2.840.113635.100.8.2 in credCert.
var certs []*x509.Certificate

if certs, err = parseX5C(x5c); err != nil {
return "", nil, ErrAttestation.WithDetails("Error parsing x5c cert chain").WithError(err)
}

credCert := certs[0]

if _, err = certChainVerify(certs, attAppleHardwareRootsCertPool, true, time.Now().Add(time.Hour*8760).UTC()); err != nil {
return "", nil, ErrInvalidAttestation.WithDetails("Error validating x5c cert chain").WithError(err)
}

var attExtBytes []byte

for _, ext := range credCert.Extensions {
if ext.Id.Equal([]int{1, 2, 840, 113635, 100, 8, 2}) {
if ext.Id.Equal(oidExtensionAppleAnonymousAttestation) {
attExtBytes = ext.Value
}
}
Expand All @@ -81,22 +79,8 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte, _ metadata.
}

// Step 5. Verify that the credential public key equals the Subject Public Key of credCert.
// TODO: Probably move this part to webauthncose.go.
pubKey, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey)
if err != nil {
return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err)
}

credPK := pubKey.(webauthncose.EC2PublicKeyData)
subjectPK := credCert.PublicKey.(*ecdsa.PublicKey)
credPKInfo := &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: big.NewInt(0).SetBytes(credPK.XCoord),
Y: big.NewInt(0).SetBytes(credPK.YCoord),
}

if !credPKInfo.Equal(subjectPK) {
return "", nil, ErrInvalidAttestation.WithDetails("Certificate public key does not match public key in authData")
if _, err = verifyAttestationECDSAPublicKeyMatch(att, credCert); err != nil {
return "", nil, err
}

// Step 6. If successful, return implementation-specific values representing attestation type Anonymization CA and attestation trust path x5c.
Expand All @@ -108,3 +92,7 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte, _ metadata.
type AppleAnonymousAttestation struct {
Nonce []byte `asn1:"tag:1,explicit"`
}

var (
attAppleHardwareRootsCertPool *x509.CertPool
)
42 changes: 23 additions & 19 deletions protocol/attestation_apple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (
"testing"

"github.com/go-webauthn/webauthn/metadata"
"github.com/stretchr/testify/assert"
)

func Test_verifyAppleFormat(t *testing.T) {
func Test_VerifyAppleFormat(t *testing.T) {
type args struct {
att AttestationObject
clientDataHash []byte
Expand All @@ -16,35 +17,38 @@ func Test_verifyAppleFormat(t *testing.T) {
successAttResponse := attestationTestUnpackResponse(t, appleTestResponse["success"]).Response.AttestationObject
successClientDataHash := sha256.Sum256(attestationTestUnpackResponse(t, appleTestResponse["success"]).Raw.AttestationResponse.ClientDataJSON)

tests := []struct {
name string
args args
want string
want1 []any
wantErr bool
testCases := []struct {
name string
args args
attestationType string
x5cs []any
err string
}{
{
"success",
"ShouldSuccessfullyParseAppleFormat",
args{
successAttResponse,
successClientDataHash[:],
},
string(metadata.AnonCA),
nil,
false,
[]any{
[]byte{0x30, 0x82, 0x2, 0x44, 0x30, 0x82, 0x1, 0xc9, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x6, 0x1, 0x75, 0x2, 0x7d, 0x61, 0x83, 0x30, 0xa, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x2, 0x30, 0x48, 0x31, 0x1c, 0x30, 0x1a, 0x6, 0x3, 0x55, 0x4, 0x3, 0xc, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x31, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0xa, 0xc, 0xa, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x8, 0xc, 0xa, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x30, 0x1e, 0x17, 0xd, 0x32, 0x30, 0x31, 0x30, 0x30, 0x37, 0x30, 0x39, 0x34, 0x36, 0x31, 0x32, 0x5a, 0x17, 0xd, 0x32, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x39, 0x35, 0x36, 0x31, 0x32, 0x5a, 0x30, 0x81, 0x91, 0x31, 0x49, 0x30, 0x47, 0x6, 0x3, 0x55, 0x4, 0x3, 0xc, 0x40, 0x36, 0x31, 0x32, 0x37, 0x36, 0x66, 0x63, 0x30, 0x32, 0x64, 0x33, 0x66, 0x65, 0x38, 0x64, 0x31, 0x36, 0x62, 0x33, 0x33, 0x62, 0x35, 0x35, 0x34, 0x39, 0x64, 0x38, 0x31, 0x39, 0x32, 0x33, 0x36, 0x63, 0x38, 0x31, 0x37, 0x34, 0x36, 0x61, 0x38, 0x33, 0x66, 0x32, 0x65, 0x39, 0x34, 0x61, 0x36, 0x65, 0x34, 0x62, 0x65, 0x65, 0x31, 0x63, 0x37, 0x30, 0x66, 0x38, 0x31, 0x62, 0x35, 0x62, 0x63, 0x31, 0x1a, 0x30, 0x18, 0x6, 0x3, 0x55, 0x4, 0xb, 0xc, 0x11, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0xa, 0xc, 0xa, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x8, 0xc, 0xa, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x30, 0x59, 0x30, 0x13, 0x6, 0x7, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x2, 0x1, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0x3, 0x42, 0x0, 0x4, 0x79, 0xfe, 0x59, 0x8, 0xbb, 0x51, 0x29, 0xc8, 0x9, 0x38, 0xb7, 0x54, 0xc0, 0x4d, 0x2b, 0x34, 0xe, 0xfa, 0x66, 0x15, 0xb9, 0x87, 0x69, 0x8b, 0xf5, 0x9d, 0xa4, 0xe5, 0x3e, 0xa3, 0xe6, 0xfe, 0xfb, 0x3, 0xda, 0xa1, 0x27, 0xd, 0x58, 0x4, 0xe8, 0xab, 0x61, 0xc1, 0x5a, 0xac, 0xa2, 0x43, 0x5c, 0x7d, 0xbf, 0x36, 0x9d, 0x71, 0xca, 0x15, 0xc5, 0x23, 0xb0, 0x0, 0x4a, 0x1b, 0x75, 0xb7, 0xa3, 0x55, 0x30, 0x53, 0x30, 0xc, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x2, 0x30, 0x0, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x4, 0xf0, 0x30, 0x33, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x8, 0x2, 0x4, 0x26, 0x30, 0x24, 0xa1, 0x22, 0x4, 0x20, 0x9c, 0x60, 0x2, 0x15, 0x40, 0xb3, 0xe1, 0x98, 0x34, 0xdf, 0xe3, 0x7e, 0xc6, 0x24, 0x45, 0xc8, 0x9e, 0x1b, 0x29, 0x4f, 0x79, 0x2c, 0xe4, 0x6b, 0x94, 0x13, 0xc3, 0x23, 0xe, 0xf3, 0x86, 0x81, 0x30, 0xa, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x2, 0x3, 0x69, 0x0, 0x30, 0x66, 0x2, 0x31, 0x0, 0xda, 0x1c, 0x18, 0xeb, 0x23, 0xbe, 0x71, 0x0, 0x5e, 0xd2, 0x5f, 0x3c, 0x85, 0xe7, 0x34, 0x90, 0x7, 0xf2, 0xe0, 0xf4, 0xf8, 0xd3, 0x77, 0x2c, 0x9e, 0xfb, 0xe, 0xec, 0xb6, 0x2a, 0xb2, 0xf3, 0x82, 0xba, 0x96, 0x6a, 0x3c, 0x77, 0x77, 0xc8, 0xa6, 0xd6, 0x23, 0x2d, 0xc, 0x7c, 0xd5, 0xbb, 0x2, 0x31, 0x0, 0xaf, 0xb, 0xc3, 0x12, 0x37, 0xe6, 0x9e, 0xc2, 0x26, 0x94, 0xd1, 0xb3, 0x2c, 0x77, 0x14, 0x5b, 0x74, 0x37, 0xab, 0x8, 0x92, 0x63, 0xdf, 0x12, 0x5b, 0xdc, 0xa6, 0x70, 0x96, 0x87, 0xaf, 0x27, 0x77, 0x5a, 0xa, 0x60, 0x9c, 0xad, 0x9a, 0xc0, 0x3d, 0x87, 0xcb, 0xa7, 0x69, 0x3, 0x3a, 0xc8},
[]byte{0x30, 0x82, 0x2, 0x34, 0x30, 0x82, 0x1, 0xba, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x10, 0x56, 0x25, 0x53, 0x95, 0xc7, 0xa7, 0xfb, 0x40, 0xeb, 0xe2, 0x28, 0xd8, 0x26, 0x8, 0x53, 0xb6, 0x30, 0xa, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x3, 0x30, 0x4b, 0x31, 0x1f, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x4, 0x3, 0xc, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0xa, 0xc, 0xa, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x8, 0xc, 0xa, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x30, 0x1e, 0x17, 0xd, 0x32, 0x30, 0x30, 0x33, 0x31, 0x38, 0x31, 0x38, 0x33, 0x38, 0x30, 0x31, 0x5a, 0x17, 0xd, 0x33, 0x30, 0x30, 0x33, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x48, 0x31, 0x1c, 0x30, 0x1a, 0x6, 0x3, 0x55, 0x4, 0x3, 0xc, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x31, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0xa, 0xc, 0xa, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x8, 0xc, 0xa, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x30, 0x76, 0x30, 0x10, 0x6, 0x7, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x2, 0x1, 0x6, 0x5, 0x2b, 0x81, 0x4, 0x0, 0x22, 0x3, 0x62, 0x0, 0x4, 0x83, 0x2e, 0x87, 0x2f, 0x26, 0x14, 0x91, 0x81, 0x2, 0x25, 0xb9, 0xf5, 0xfc, 0xd6, 0xbb, 0x63, 0x78, 0xb5, 0xf5, 0x5f, 0x3f, 0xcb, 0x4, 0x5b, 0xc7, 0x35, 0x99, 0x34, 0x75, 0xfd, 0x54, 0x90, 0x44, 0xdf, 0x9b, 0xfe, 0x19, 0x21, 0x17, 0x65, 0xc6, 0x9a, 0x1d, 0xda, 0x5, 0xb, 0x38, 0xd4, 0x50, 0x83, 0x40, 0x1a, 0x43, 0x4f, 0xb2, 0x4d, 0x11, 0x2d, 0x56, 0xc3, 0xe1, 0xcf, 0xbf, 0xcb, 0x98, 0x91, 0xfe, 0xc0, 0x69, 0x60, 0x81, 0xbe, 0xf9, 0x6c, 0xbc, 0x77, 0xc8, 0x8d, 0xdd, 0xaf, 0x46, 0xa5, 0xae, 0xe1, 0xdd, 0x51, 0x5b, 0x5a, 0xfa, 0xab, 0x93, 0xbe, 0x9c, 0xb, 0x26, 0x91, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x8, 0x30, 0x6, 0x1, 0x1, 0xff, 0x2, 0x1, 0x0, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0x26, 0xd7, 0x64, 0xd9, 0xc5, 0x78, 0xc2, 0x5a, 0x67, 0xd1, 0xa7, 0xde, 0x6b, 0x12, 0xd0, 0x1b, 0x63, 0xf1, 0xc6, 0xd7, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d, 0xe, 0x4, 0x16, 0x4, 0x14, 0xeb, 0xae, 0x82, 0xc4, 0xff, 0xa1, 0xac, 0x5b, 0x51, 0xd4, 0xcf, 0x24, 0x61, 0x5, 0x0, 0xbe, 0x63, 0xbd, 0x77, 0x88, 0x30, 0xe, 0x6, 0x3, 0x55, 0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x1, 0x6, 0x30, 0xa, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x3, 0x3, 0x68, 0x0, 0x30, 0x65, 0x2, 0x31, 0x0, 0xdd, 0x8b, 0x1a, 0x34, 0x81, 0xa5, 0xfa, 0xd9, 0xdb, 0xb4, 0xe7, 0x65, 0x7b, 0x84, 0x1e, 0x14, 0x4c, 0x27, 0xb7, 0x5b, 0x87, 0x6a, 0x41, 0x86, 0xc2, 0xb1, 0x47, 0x57, 0x50, 0x33, 0x72, 0x27, 0xef, 0xe5, 0x54, 0x45, 0x7e, 0xf6, 0x48, 0x95, 0xc, 0x63, 0x2e, 0x5c, 0x48, 0x3e, 0x70, 0xc1, 0x2, 0x30, 0x2c, 0x8a, 0x60, 0x44, 0xdc, 0x20, 0x1f, 0xcf, 0xe5, 0x9b, 0xc3, 0x4d, 0x29, 0x30, 0xc1, 0x48, 0x78, 0x51, 0xd9, 0x60, 0xed, 0x6a, 0x75, 0xf1, 0xeb, 0x4a, 0xca, 0xbe, 0x38, 0xcd, 0x25, 0xb8, 0x97, 0xd0, 0xc8, 0x5, 0xbe, 0xf0, 0xc7, 0xf7, 0x8b, 0x7, 0xa5, 0x71, 0xc6, 0xe8, 0xe, 0x7}},
"",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, _, err := verifyAppleFormat(tt.args.att, tt.args.clientDataHash, nil)
if (err != nil) != tt.wantErr {
t.Errorf("verifyAppleFormat() error = %v, wantErr %v", err, tt.wantErr)
return
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
attestationType, x5cs, err := attestationFormatValidationHandlerAppleAnonymous(tc.args.att, tc.args.clientDataHash, nil)

assert.Equal(t, tc.attestationType, attestationType)
assert.Equal(t, tc.x5cs, x5cs)

if got != tt.want {
t.Errorf("verifyAppleFormat() got = %v, want %v", got, tt.want)
if tc.err != "" {
assert.EqualError(t, err, tc.err)
} else {
assert.NoError(t, err)
}
})
}
Expand Down
Loading
Loading