Repository: go-webauthn/webauthn
Pull request #434 (2025-06-19 09:45:43)

fix(protocol): conditional create fail
This fixes conditional create would fail.
In this case, UP and UV flags will always false.
According to WebAuthn L3 spec, UP flag will be verified when options.mediation is not set to "conditional". 
Step 15:
https://www.w3.org/TR/webauthn-3/#sctn-registering-a-new-credential

Related to #361

coderabbitai[bot]: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->

> [!NOTE]
> Currently processing new changes in this PR. This may take a few minutes, please wait...
> 
> <details>
> <summary>📥 Commits</summary>
> 
> Reviewing files that changed from the base of the PR and between 98b9f20740cadd317ff155fcdf9620e70287576e and aca8350a3475a581d12ef620a557dc68bd4911d6.
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (11)</summary>
> 
> * `protocol/assertion.go` (2 hunks)
> * `protocol/assertion_test.go` (1 hunks)
> * `protocol/attestation.go` (1 hunks)
> * `protocol/attestation_test.go` (1 hunks)
> * `protocol/authenticator.go` (2 hunks)
> * `protocol/authenticator_test.go` (4 hunks)
> * `protocol/credential.go` (2 hunks)
> * `protocol/credential_test.go` (1 hunks)
> * `webauthn/login.go` (2 hunks)
> * `webauthn/registration.go` (2 hunks)
> * `webauthn/types.go` (1 hunks)
> 
> </details>
> 
> ```ascii
>  _______________________________________________
> < Don't count your bugs before they're patched. >
>  -----------------------------------------------
>   \
>    \   \
>         \ /\
>         ( )
>       .( o ).
> ```

<!-- end of auto-generated comment: review in progress by coderabbit.ai -->
<!-- usage_tips_start -->

> [!TIP]
> <details>
> <summary>CodeRabbit can generate a title for your PR based on the changes.</summary>
> 
> Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the `reviews.auto_title_placeholder` setting.
> 
> </details>

<!-- usage_tips_end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=go-webauthn/webauthn&utm_content=434):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Patch:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 8b6d60e..b1b6a62 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -50,7 +50,7 @@ jobs:
 
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
+        uses: github/codeql-action/init@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
         with:
           languages: ${{ matrix.language }}
           # If you wish to specify custom queries, you can do so here or in a config file.
@@ -60,7 +60,7 @@ jobs:
       # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
       # If this step fails, then you should remove it and run the build manually (see below)
       - name: Autobuild
-        uses: github/codeql-action/autobuild@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
+        uses: github/codeql-action/autobuild@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
 
       # ℹ️ Command-line programs to run using the OS shell.
       # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -73,6 +73,6 @@ jobs:
       #   ./location_of_script_within_repo/buildscript.sh
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
+        uses: github/codeql-action/analyze@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
         with:
           category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index fdac45a..d841fea 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -71,6 +71,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
+        uses: github/codeql-action/upload-sarif@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
         with:
           sarif_file: results.sarif
diff --git a/protocol/assertion.go b/protocol/assertion.go
index f3caa91..ddd003f 100644
--- a/protocol/assertion.go
+++ b/protocol/assertion.go
@@ -139,7 +139,7 @@ func (car CredentialAssertionResponse) Parse() (par *ParsedCredentialAssertionDa
 // documentation.
 //
 // Specification: §7.2 Verifying an Authentication Assertion (https://www.w3.org/TR/webauthn/#sctn-verifying-assertion)
-func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, appID string, verifyUser bool, credentialBytes []byte) error {
+func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, appID string, verifyUser bool, verifyUserPresence bool, credentialBytes []byte) error {
 	// Steps 4 through 6 in verifying the assertion data (https://www.w3.org/TR/webauthn/#verifying-assertion) are
 	// "assertive" steps, i.e. "Let JSONtext be the result of running UTF-8 decode on the value of cData."
 	// We handle these steps in part as we verify but also beforehand
@@ -160,7 +160,7 @@ func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPa
 	}
 
 	// Handle steps 11 through 14, verifying the authenticator data.
-	validError = p.Response.AuthenticatorData.Verify(rpIDHash[:], appIDHash[:], verifyUser)
+	validError = p.Response.AuthenticatorData.Verify(rpIDHash[:], appIDHash[:], verifyUser, verifyUserPresence)
 	if validError != nil {
 		return validError
 	}
diff --git a/protocol/authenticator.go b/protocol/authenticator.go
index d3c351a..ac75b15 100644
--- a/protocol/authenticator.go
+++ b/protocol/authenticator.go
@@ -385,7 +385,7 @@ func ResidentKeyNotRequired() *bool {
 
 // Verify on AuthenticatorData handles Steps 13 through 15 & 17 for Registration
 // and Steps 15 through 18 for Assertion.
-func (a *AuthenticatorData) Verify(rpIdHash []byte, appIDHash []byte, userVerificationRequired bool) error {
+func (a *AuthenticatorData) Verify(rpIdHash []byte, appIDHash []byte, userVerificationRequired bool, userPresenceRequired bool) error {
 
 	// Registration Step 13 & Assertion Step 15
 	// Verify that the RP ID hash in authData is indeed the SHA-256
@@ -394,17 +394,17 @@ func (a *AuthenticatorData) Verify(rpIdHash []byte, appIDHash []byte, userVerifi
 		return ErrVerification.WithInfo(fmt.Sprintf("RP Hash mismatch. Expected %x and Received %x", a.RPIDHash, rpIdHash))
 	}
 
-	// Registration Step 14 & Assertion Step 16
+	// Registration Step 15 & Assertion Step 16
 	// Verify that the User Present bit of the flags in authData is set.
-	if !a.Flags.UserPresent() {
-		return ErrVerification.WithInfo(fmt.Sprintf("User presence flag not set by authenticator"))
+	if userPresenceRequired && !a.Flags.UserPresent() {
+		return ErrVerification.WithInfo("User presence required but flag not set by authenticator")
 	}
 
 	// Registration Step 15 & Assertion Step 17
 	// If user verification is required for this assertion, verify that
 	// the User Verified bit of the flags in authData is set.
 	if userVerificationRequired && !a.Flags.UserVerified() {
-		return ErrVerification.WithInfo(fmt.Sprintf("User verification required but flag not set by authenticator"))
+		return ErrVerification.WithInfo("User verification required but flag not set by authenticator")
 	}
 
 	// Registration Step 17 & Assertion Step 18
diff --git a/protocol/credential.go b/protocol/credential.go
index 66f1537..153403e 100644
--- a/protocol/credential.go
+++ b/protocol/credential.go
@@ -145,7 +145,7 @@ func (ccr CredentialCreationResponse) Parse() (pcc *ParsedCredentialCreationData
 // Verify the Client and Attestation data.
 //
 // Specification: §7.1. Registering a New Credential (https://www.w3.org/TR/webauthn/#sctn-registering-a-new-credential)
-func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUser bool, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, mds metadata.Provider, credParams []CredentialParameter) (clientDataHash []byte, err error) {
+func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUser bool, verifyUserPresence bool, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, mds metadata.Provider, credParams []CredentialParameter) (clientDataHash []byte, err error) {
 	// Handles steps 3 through 6 - Verifying the Client Data against the Relying Party's stored data
 	if err = pcc.Response.CollectedClientData.Verify(storedChallenge, CreateCeremony, rpOrigins, rpTopOrigins, rpTopOriginsVerify); err != nil {
 		return nil, err
@@ -161,7 +161,7 @@ func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUs
 
 	// We do the above step while parsing and decoding the CredentialCreationResponse
 	// Handle steps 9 through 14 - This verifies the attestation object.
-	if err = pcc.Response.AttestationObject.Verify(relyingPartyID, clientDataHash, verifyUser, mds, credParams); err != nil {
+	if err = pcc.Response.AttestationObject.Verify(relyingPartyID, clientDataHash, verifyUser, verifyUserPresence, mds, credParams); err != nil {
 		return clientDataHash, err
 	}
 
diff --git a/webauthn/login.go b/webauthn/login.go
index aa6b53e..352a4bd 100644
--- a/webauthn/login.go
+++ b/webauthn/login.go
@@ -357,6 +357,7 @@ func (webauthn *WebAuthn) validateLogin(user User, session SessionData, parsedRe
 	}
 
 	shouldVerifyUser := session.UserVerification == protocol.VerificationRequired
+	shouldVerifyUserPresence := true
 
 	rpID := webauthn.Config.RPID
 	rpOrigins := webauthn.Config.RPOrigins
@@ -367,7 +368,7 @@ func (webauthn *WebAuthn) validateLogin(user User, session SessionData, parsedRe
 	}
 
 	// Handle steps 4 through 16.
-	if err = parsedResponse.Verify(session.Challenge, rpID, rpOrigins, rpTopOrigins, webauthn.Config.RPTopOriginVerificationMode, appID, shouldVerifyUser, credential.PublicKey); err != nil {
+	if err = parsedResponse.Verify(session.Challenge, rpID, rpOrigins, rpTopOrigins, webauthn.Config.RPTopOriginVerificationMode, appID, shouldVerifyUser, shouldVerifyUserPresence, credential.PublicKey); err != nil {
 		return nil, err
 	}
 
diff --git a/webauthn/registration.go b/webauthn/registration.go
index bd16b3d..aeaeba6 100644
--- a/webauthn/registration.go
+++ b/webauthn/registration.go
@@ -101,6 +101,7 @@ func (webauthn *WebAuthn) BeginMediatedRegistration(user User, mediation protoco
 		UserID:           user.WebAuthnID(),
 		UserVerification: creation.Response.AuthenticatorSelection.UserVerification,
 		CredParams:       creation.Response.Parameters,
+		Mediation:        creation.Mediation,
 	}
 
 	if webauthn.Config.Timeouts.Registration.Enforce {
@@ -231,10 +232,11 @@ func (webauthn *WebAuthn) CreateCredential(user User, session SessionData, parse
 	}
 
 	shouldVerifyUser := session.UserVerification == protocol.VerificationRequired
+	shouldVerifyUserPresence := session.Mediation != protocol.MediationConditional
 
 	var clientDataHash []byte
 
-	if clientDataHash, err = parsedResponse.Verify(session.Challenge, shouldVerifyUser, webauthn.Config.RPID, webauthn.Config.RPOrigins, webauthn.Config.RPTopOrigins, webauthn.Config.RPTopOriginVerificationMode, webauthn.Config.MDS, session.CredParams); err != nil {
+	if clientDataHash, err = parsedResponse.Verify(session.Challenge, shouldVerifyUser, shouldVerifyUserPresence, webauthn.Config.RPID, webauthn.Config.RPOrigins, webauthn.Config.RPTopOrigins, webauthn.Config.RPTopOriginVerificationMode, webauthn.Config.MDS, session.CredParams); err != nil {
 		return nil, err
 	}
 
diff --git a/webauthn/types.go b/webauthn/types.go
index 9e8ee8e..5af251d 100644
--- a/webauthn/types.go
+++ b/webauthn/types.go
@@ -209,7 +209,8 @@ type SessionData struct {
 	AllowedCredentialIDs [][]byte  `json:"allowed_credentials,omitempty"`
 	Expires              time.Time `json:"expires"`
 
-	UserVerification protocol.UserVerificationRequirement `json:"userVerification"`
-	Extensions       protocol.AuthenticationExtensions    `json:"extensions,omitempty"`
-	CredParams       []protocol.CredentialParameter       `json:"credParams,omitempty"`
+	UserVerification protocol.UserVerificationRequirement    `json:"userVerification"`
+	Extensions       protocol.AuthenticationExtensions       `json:"extensions,omitempty"`
+	CredParams       []protocol.CredentialParameter          `json:"credParams,omitempty"`
+	Mediation        protocol.CredentialMediationRequirement `json:"mediation,omitempty"`
 }


Test patch:
diff --git a/protocol/assertion_test.go b/protocol/assertion_test.go
index c93f467..cb101d2 100644
--- a/protocol/assertion_test.go
+++ b/protocol/assertion_test.go
@@ -180,7 +180,7 @@ func TestParsedCredentialAssertionData_Verify(t *testing.T) {
 				Raw:                       tt.fields.Raw,
 			}
 
-			if err := p.Verify(tt.args.storedChallenge.String(), tt.args.relyingPartyID, tt.args.relyingPartyOrigin, nil, TopOriginIgnoreVerificationMode, "", tt.args.verifyUser, tt.args.credentialBytes); (err != nil) != tt.wantErr {
+			if err := p.Verify(tt.args.storedChallenge.String(), tt.args.relyingPartyID, tt.args.relyingPartyOrigin, nil, TopOriginIgnoreVerificationMode, "", tt.args.verifyUser, false, tt.args.credentialBytes); (err != nil) != tt.wantErr {
 				t.Errorf("ParsedCredentialAssertionData.Verify() error = %v, wantErr %v", err, tt.wantErr)
 			}
 		})
diff --git a/protocol/attestation.go b/protocol/attestation.go
index 2d7d3af..0bf8aae 100644
--- a/protocol/attestation.go
+++ b/protocol/attestation.go
@@ -128,11 +128,11 @@ func (ccr *AuthenticatorAttestationResponse) Parse() (p *ParsedAttestationRespon
 //
 // Steps 13 through 15 are verified against the auth data. These steps are identical to 15 through 18 for assertion so we
 // handle them with AuthData.
-func (a *AttestationObject) Verify(relyingPartyID string, clientDataHash []byte, userVerificationRequired bool, mds metadata.Provider, credParams []CredentialParameter) (err error) {
+func (a *AttestationObject) Verify(relyingPartyID string, clientDataHash []byte, userVerificationRequired bool, userPresenceRequired bool, mds metadata.Provider, credParams []CredentialParameter) (err error) {
 	rpIDHash := sha256.Sum256([]byte(relyingPartyID))
 
 	// Begin Step 13 through 15. Verify that the rpIdHash in authData is the SHA-256 hash of the RP ID expected by the RP.
-	if err = a.AuthData.Verify(rpIDHash[:], nil, userVerificationRequired); err != nil {
+	if err = a.AuthData.Verify(rpIDHash[:], nil, userVerificationRequired, userPresenceRequired); err != nil {
 		return err
 	}
 
diff --git a/protocol/attestation_test.go b/protocol/attestation_test.go
index 8ccb1f6..d3be883 100644
--- a/protocol/attestation_test.go
+++ b/protocol/attestation_test.go
@@ -29,7 +29,7 @@ func TestAttestationVerify(t *testing.T) {
 
 			pcc.Response = *parsedAttestationResponse
 
-			_, err = pcc.Verify(options.Response.Challenge.String(), false, options.Response.RelyingParty.ID, []string{options.Response.RelyingParty.Name}, nil, TopOriginIgnoreVerificationMode, nil, options.Response.Parameters)
+			_, err = pcc.Verify(options.Response.Challenge.String(), false, false, options.Response.RelyingParty.ID, []string{options.Response.RelyingParty.Name}, nil, TopOriginIgnoreVerificationMode, nil, options.Response.Parameters)
 
 			require.NoError(t, err)
 		})
diff --git a/protocol/authenticator_test.go b/protocol/authenticator_test.go
index 2765dcf..3710741 100644
--- a/protocol/authenticator_test.go
+++ b/protocol/authenticator_test.go
@@ -431,6 +431,7 @@ func TestAuthenticatorData_Verify(t *testing.T) {
 	type args struct {
 		rpIdHash                 []byte
 		userVerificationRequired bool
+		userPresenceRequired     bool
 	}
 
 	tests := []struct {
@@ -473,12 +474,13 @@ func TestAuthenticatorData_Verify(t *testing.T) {
 				Flags:    AuthenticatorFlags(0x04),
 			},
 			args: args{
-				rpIdHash: []byte{1, 2, 3},
+				rpIdHash:             []byte{1, 2, 3},
+				userPresenceRequired: true,
 			},
 			errString:  "Error validating the authenticator response",
 			errType:    "verification_error",
 			errDetails: "Error validating the authenticator response",
-			errInfo:    "User presence flag not set by authenticator",
+			errInfo:    "User presence required but flag not set by authenticator",
 		},
 		{
 			name: "User verification required",
@@ -489,6 +491,7 @@ func TestAuthenticatorData_Verify(t *testing.T) {
 			args: args{
 				rpIdHash:                 []byte{1, 2, 3},
 				userVerificationRequired: true,
+				userPresenceRequired:     true,
 			},
 			errString:  "Error validating the authenticator response",
 			errType:    "verification_error",
@@ -506,7 +509,7 @@ func TestAuthenticatorData_Verify(t *testing.T) {
 				AttData:  tt.fields.AttData,
 				ExtData:  tt.fields.ExtData,
 			}
-			err := a.Verify(tt.args.rpIdHash, nil, tt.args.userVerificationRequired)
+			err := a.Verify(tt.args.rpIdHash, nil, tt.args.userVerificationRequired, tt.args.userPresenceRequired)
 			if tt.errString != "" {
 				assert.EqualError(t, err, tt.errString)
 
diff --git a/protocol/credential_test.go b/protocol/credential_test.go
index 4068e51..35689ef 100644
--- a/protocol/credential_test.go
+++ b/protocol/credential_test.go
@@ -243,7 +243,7 @@ func TestParsedCredentialCreationData_Verify(t *testing.T) {
 				Response:                  tt.fields.Response,
 				Raw:                       tt.fields.Raw,
 			}
-			if _, err := pcc.Verify(tt.args.storedChallenge.String(), tt.args.verifyUser, tt.args.relyingPartyID, tt.args.relyingPartyOrigin, nil, TopOriginIgnoreVerificationMode, nil, tt.args.credParams); (err != nil) != tt.wantErr {
+			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)
 			}
 		})