Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ force the UV verification #27

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

## Description

`webauthn` is a library designed for signature validation through the Web Authentication process. Currently, it supports only the ECDSA signature scheme utilizing the secp256r1 curve. This functionality is provided by the [secp256r1 library](https://github.com/0x90d2b2b7fb7599eebb6e7a32980857d8/secp256r1-verify). Support for additional algorithms is planned for future releases.
`webauthn` is a library designed to validate passkeys. Currently, it supports only the ECDSA signature scheme utilizing the secp256r1 curve. This functionality is provided by the [secp256r1 library](https://github.com/0x90d2b2b7fb7599eebb6e7a32980857d8/secp256r1-verify). Support for additional algorithms is planned for future releases.

## Installation

Expand Down
1 change: 0 additions & 1 deletion src/IWebAuthn256r1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pragma solidity >=0.8.19 <0.9.0;

interface IWebAuthn256r1 {
function verify(
bytes1 authenticatorDataFlagMask,
bytes calldata authenticatorData,
bytes calldata clientData,
bytes calldata clientChallenge,
Expand Down
37 changes: 19 additions & 18 deletions src/WebAuthn256r1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ import { Base64 } from "../lib/solady/src/utils/Base64.sol";
/// @notice A library to verify ECDSA signature though WebAuthn on the secp256r1 curve
/// @custom:experimental This is an experimental library.
library WebAuthn256r1 {
/// Those are bit masks that can be used to validate the flag in the
/// authenticator data. The flag is located at byte 32 of the authenticator
/// data and is used to indicate, among other things, wheter the user's
/// presence/verification ceremonies have been performed.
/// This version of the library is opinionated for passkeys that enforce UV.
///
/// Here are some flags you may want to use depending on your needs.
/// - 0x01: User presence (UP) is required. If the UP flag is not set, revert
/// - 0x04: User verification (UV) is required. If the UV flag is not set, revert
/// - 0x05: UV and UP are both accepted. If none of them is set, revert
///
/// Read more about UP here: https://www.w3.org/TR/webauthn-2/#test-of-user-presence
/// Read more about UV here: https://www.w3.org/TR/webauthn-2/#user-verification
bytes1 internal constant UP_FLAG_MASK = 0x01;
bytes1 internal constant UV_FLAG_MASK = 0x04;
bytes1 internal constant BOTH_FLAG_MASK = 0x05;

error InvalidAuthenticatorData();
error InvalidClientData();
error InvalidChallenge();
Expand All @@ -16,20 +33,6 @@ library WebAuthn256r1 {
uint256 private constant CLIENT_CHALLENGE_OFFSET = 0x24;

/// @notice Validate the webauthn data and generate the signature message needed to recover
/// @param authenticatorDataFlagMask This is a bit mask that will be used to validate the flag in the
/// authenticator data. The flag is located at byte 32 of the authenticator
/// data and is used to indicate, among other things, wheter the user's
/// presence/verification ceremonies have been performed.
/// This argument is not expected to be exposed to the end user, it is the
/// responsibility of the caller to enforce the value of the flag for their flows.
///
/// Here are some flags you may want to use depending on your needs.
/// - 0x01: User presence (UP) is required. If the UP flag is not set, revert
/// - 0x04: User verification (UV) is required. If the UV flag is not set, revert
/// - 0x05: UV and UP are both accepted. If none of them is set, revert
///
// Read more about UP here: https://www.w3.org/TR/webauthn-2/#test-of-user-presence
// Read more about UV here: https://www.w3.org/TR/webauthn-2/#user-verification
/// @param authenticatorData The authenticator data structure encodes contextual bindings made by the authenticator.
/// Described here: https://www.w3.org/TR/webauthn-2/#authenticator-data
/// @param clientData This is the client data that was signed. The client data represents the
Expand Down Expand Up @@ -70,7 +73,6 @@ library WebAuthn256r1 {
/// This contract is based on the level 2 of the WebAuthn specification.
/// and until proven otherwise compliant with the level 3 of the specification.
function generateMessage(
bytes1 authenticatorDataFlagMask,
bytes calldata authenticatorData,
bytes calldata clientData,
bytes calldata clientChallenge
Expand All @@ -83,7 +85,7 @@ library WebAuthn256r1 {
// Let the caller check the value of the flag in the authenticator data
// @dev: we don't need to manually check the length of the authenticator data
// here as the EVM will automatically revert if the length is lower than 32
if ((authenticatorData[32] & authenticatorDataFlagMask) == 0) {
if ((authenticatorData[32] & UV_FLAG_MASK) == 0) {
revert InvalidAuthenticatorData();
}

Expand Down Expand Up @@ -113,7 +115,6 @@ library WebAuthn256r1 {

/// @notice Verify ECDSA signature though WebAuthn on the secp256r1 curve
function verify(
bytes1 authenticatorDataFlagMask,
bytes calldata authData,
bytes calldata clientData,
bytes calldata clientChallenge,
Expand All @@ -126,7 +127,7 @@ library WebAuthn256r1 {
returns (bool)
{
unchecked {
bytes32 message = generateMessage(authenticatorDataFlagMask, authData, clientData, clientChallenge);
bytes32 message = generateMessage(authData, clientData, clientChallenge);

return ECDSA256r1.verify(message, r, s, qx, qy);
}
Expand Down
Loading
Loading