Skip to content

Commit c454de7

Browse files
committed
minor optimisations/refactors
1 parent 7c17ea3 commit c454de7

File tree

1 file changed

+16
-26
lines changed

1 file changed

+16
-26
lines changed

contracts/utils/cryptography/WebAuthn.sol

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ library WebAuthn {
6060
/// @dev Bit 4 of the authenticator data flags: "Backup State" bit.
6161
bytes1 private constant AUTH_DATA_FLAGS_BS = 0x10;
6262

63-
/// @dev The expected type string in the client data JSON when verifying assertion signatures.
64-
/// https://www.w3.org/TR/webauthn-2/#dom-collectedclientdata-type
65-
// solhint-disable-next-line quotes
66-
bytes32 private constant EXPECTED_TYPE_HASH = keccak256('"type":"webauthn.get"');
67-
6863
/**
6964
* @dev Performs the absolute minimal verification of a WebAuthn Authentication Assertion.
7065
* This function includes only the essential checks required for basic WebAuthn security:
@@ -89,18 +84,16 @@ library WebAuthn {
8984
// - 32 bytes for rpIdHash
9085
// - 1 byte for flags
9186
// - 4 bytes for signature counter
92-
if (auth.authenticatorData.length < 37) return false;
93-
bytes memory clientDataJSON = bytes(auth.clientDataJSON);
94-
9587
return
96-
validateExpectedTypeHash(clientDataJSON, auth.typeIndex) && // 11
97-
validateChallenge(clientDataJSON, auth.challengeIndex, challenge) && // 12
88+
auth.authenticatorData.length > 36 &&
89+
validateExpectedTypeHash(auth.clientDataJSON, auth.typeIndex) && // 11
90+
validateChallenge(auth.clientDataJSON, auth.challengeIndex, challenge) && // 12
9891
// Handles signature malleability internally
9992
P256.verify(
10093
sha256(
10194
abi.encodePacked(
10295
auth.authenticatorData,
103-
sha256(clientDataJSON) // 19
96+
sha256(bytes(auth.clientDataJSON)) // 19
10497
)
10598
),
10699
auth.r,
@@ -222,30 +215,27 @@ library WebAuthn {
222215
* @dev Validates that the https://www.w3.org/TR/webauthn-2/#type[Type] field in the client data JSON
223216
* is set to "webauthn.get".
224217
*/
225-
function validateExpectedTypeHash(bytes memory clientDataJSON, uint256 typeIndex) internal pure returns (bool) {
218+
function validateExpectedTypeHash(string memory clientDataJSON, uint256 typeIndex) internal pure returns (bool) {
226219
// 21 = length of '"type":"webauthn.get"'
227-
bytes memory typeValueBytes = Bytes.slice(clientDataJSON, typeIndex, typeIndex + 21);
228-
return keccak256(typeValueBytes) == EXPECTED_TYPE_HASH;
220+
bytes memory typeValueBytes = Bytes.slice(bytes(clientDataJSON), typeIndex, typeIndex + 21);
221+
222+
// solhint-disable-next-line quotes
223+
return bytes21(typeValueBytes) == bytes21('"type":"webauthn.get"');
229224
}
230225

231226
/// @dev Validates that the challenge in the client data JSON matches the `expectedChallenge`.
232227
function validateChallenge(
233-
bytes memory clientDataJSON,
228+
string memory clientDataJSON,
234229
uint256 challengeIndex,
235-
bytes memory expectedChallenge
230+
bytes memory challenge
236231
) internal pure returns (bool) {
237-
bytes memory expectedChallengeBytes = bytes(
238-
// solhint-disable-next-line quotes
239-
string.concat('"challenge":"', Base64.encodeURL(expectedChallenge), '"')
240-
);
241-
if (challengeIndex + expectedChallengeBytes.length > clientDataJSON.length) return false;
242-
bytes memory actualChallengeBytes = Bytes.slice(
243-
clientDataJSON,
244-
challengeIndex,
245-
challengeIndex + expectedChallengeBytes.length
232+
// solhint-disable-next-line quotes
233+
string memory expectedChallenge = string.concat('"challenge":"', Base64.encodeURL(challenge), '"');
234+
string memory actualChallenge = string(
235+
Bytes.slice(bytes(clientDataJSON), challengeIndex, challengeIndex + bytes(expectedChallenge).length)
246236
);
247237

248-
return Strings.equal(string(actualChallengeBytes), string(expectedChallengeBytes));
238+
return Strings.equal(actualChallenge, expectedChallenge);
249239
}
250240

251241
/**

0 commit comments

Comments
 (0)