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

WebAuthn.sol: simplify contains to startsWith #41

Merged
merged 1 commit into from
May 19, 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
267 changes: 129 additions & 138 deletions lcov.info
Original file line number Diff line number Diff line change
Expand Up @@ -428,168 +428,159 @@ BRH:39
end_of_record
TN:
SF:src/WebAuthn.sol
FN:12,WebAuthn.contains
FNDA:11,WebAuthn.contains
DA:17,11
DA:17,11
DA:17,11
DA:18,11
DA:18,11
DA:18,11
DA:20,11
DA:20,11
DA:21,11
DA:21,11
DA:23,11
DA:23,11
DA:23,176
DA:23,176
DA:24,168
DA:24,168
DA:24,168
BRDA:24,0,0,167
BRDA:24,0,1,1
DA:25,1
DA:25,1
DA:28,167
DA:28,167
BRDA:28,1,0,165
BRDA:28,1,1,2
DA:29,2
DA:29,2
DA:33,8
DA:33,8
FN:44,WebAuthn.checkAuthFlags
FN:12,WebAuthn.startsWith
FNDA:6,WebAuthn.startsWith
DA:16,6
DA:16,6
DA:16,6
DA:17,6
DA:17,6
DA:17,6
DA:19,6
DA:19,6
DA:20,6
DA:20,6
DA:22,6
DA:22,6
DA:22,212
DA:22,212
DA:23,209
DA:23,209
BRDA:23,0,0,208
BRDA:23,0,1,1
DA:24,1
DA:24,1
DA:27,208
DA:27,208
BRDA:27,1,0,206
BRDA:27,1,1,2
DA:28,2
DA:28,2
DA:32,3
DA:32,3
FN:43,WebAuthn.checkAuthFlags
FNDA:9,WebAuthn.checkAuthFlags
DA:49,9
DA:49,9
DA:49,9
BRDA:49,2,0,8
BRDA:49,2,1,1
DA:50,1
DA:50,1
DA:57,8
DA:57,8
DA:58,2
DA:58,2
BRDA:56,3,0,7
BRDA:56,3,1,1
DA:60,1
DA:60,1
DA:65,7
DA:65,7
DA:65,7
BRDA:65,4,0,1
BRDA:65,4,1,1
DA:66,2
DA:66,2
DA:66,2
BRDA:66,5,0,1
BRDA:66,5,1,1
DA:67,1
DA:67,1
DA:71,6
DA:71,6
FN:124,WebAuthn.verifySignature
DA:48,9
DA:48,9
DA:48,9
BRDA:48,2,0,8
BRDA:48,2,1,1
DA:49,1
DA:49,1
DA:56,8
DA:56,8
DA:57,5
DA:57,5
BRDA:55,3,0,7
BRDA:55,3,1,1
DA:59,1
DA:59,1
DA:64,7
DA:64,7
DA:64,7
BRDA:64,4,0,1
BRDA:64,4,1,1
DA:65,2
DA:65,2
DA:65,2
BRDA:65,5,0,1
BRDA:65,5,1,1
DA:66,1
DA:66,1
DA:70,6
DA:70,6
FN:123,WebAuthn.verifySignature
FNDA:10,WebAuthn.verifySignature
DA:138,10
DA:138,10
DA:138,10
DA:139,9
DA:139,9
BRDA:137,6,0,6
BRDA:137,6,1,4
DA:141,4
DA:141,4
DA:135,10
DA:135,10
DA:135,10
DA:136,9
DA:136,9
BRDA:134,6,0,6
BRDA:134,6,1,4
DA:138,4
DA:138,4
DA:144,6
DA:144,6
DA:144,6
DA:145,6
DA:145,6
DA:145,6
DA:146,6
DA:146,6
BRDA:146,7,0,5
BRDA:146,7,1,1
DA:147,1
DA:147,1
DA:151,5
DA:151,5
DA:151,5
DA:152,5
DA:152,5
DA:152,5
DA:158,5
DA:158,5
BRDA:158,8,0,3
BRDA:158,8,1,2
DA:159,2
DA:159,2
DA:163,3
DA:163,3
DA:163,3
DA:164,3
DA:164,3
DA:164,3
DA:168,3
DA:168,3
DA:168,3
DA:150,6
DA:150,6
BRDA:150,7,0,3
BRDA:150,7,1,3
DA:151,3
DA:151,3
DA:155,3
DA:155,3
DA:155,3
DA:156,3
DA:156,3
DA:156,3
DA:160,3
DA:160,3
DA:160,3
FNF:3
FNH:3
LF:32
LH:32
BRF:18
BRH:18
LF:29
LH:29
BRF:16
BRH:16
end_of_record
TN:
SF:src/utils/Base64URL.sol
FN:7,Base64URL.encode
FNDA:1799,Base64URL.encode
DA:8,1799
DA:8,1799
DA:8,1799
DA:9,1799
DA:9,1799
DA:9,1799
DA:12,1799
DA:12,1799
DA:13,1799
DA:13,1799
DA:13,1799
DA:13,1795
BRDA:13,0,0,518
FNDA:1800,Base64URL.encode
DA:8,1800
DA:8,1800
DA:8,1800
DA:9,1800
DA:9,1800
DA:9,1800
DA:12,1800
DA:12,1800
DA:13,1800
DA:13,1800
DA:13,1800
DA:13,1796
BRDA:13,0,0,519
BRDA:13,0,1,1281
DA:13,518
DA:13,519
DA:14,1281
DA:14,1281
DA:14,1281
DA:14,1277
BRDA:14,1,0,1281
BRDA:14,1,1,511
DA:14,511
DA:16,1799
DA:16,1799
DA:16,1799
DA:17,1799
DA:17,1799
DA:17,1799
DA:19,1799
DA:19,1799
DA:19,526644
DA:19,526644
DA:20,524845
DA:20,524845
DA:16,1800
DA:16,1800
DA:16,1800
DA:17,1800
DA:17,1800
DA:17,1800
DA:19,1800
DA:19,1800
DA:19,526651
DA:19,526651
DA:20,524851
DA:20,524851
BRDA:20,2,0,1248
BRDA:20,2,1,523597
BRDA:20,2,1,523603
DA:21,1248
DA:21,1248
DA:22,523597
DA:22,523597
DA:22,523603
DA:22,523603
BRDA:22,3,0,176191
BRDA:22,3,1,347406
BRDA:22,3,1,347412
DA:23,176191
DA:23,176191
DA:25,347406
DA:25,347406
DA:29,1799
DA:29,1799
DA:29,1799
DA:25,347412
DA:25,347412
DA:29,1800
DA:29,1800
DA:29,1800
FNF:1
FNH:1
LF:14
Expand Down
36 changes: 14 additions & 22 deletions src/WebAuthn.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@ import "./P256.sol";
* Helper library for external contracts to verify WebAuthn signatures.
**/
library WebAuthn {
/// Checks whether substr occurs in str starting at a given byte offset.
function contains(
string memory substr,
string memory str,
uint256 location
/// Checks whether prefix occurs in the beginning of str.
function startsWith(
string memory prefix,
string memory str
) internal pure returns (bool) {
bytes memory substrBytes = bytes(substr);
bytes memory prefixBytes = bytes(prefix);
bytes memory strBytes = bytes(str);

uint256 substrLen = substrBytes.length;
uint256 prefixLen = prefixBytes.length;
uint256 strLen = strBytes.length;

for (uint256 i = 0; i < substrLen; i++) {
if (location + i >= strLen) {
for (uint256 i = 0; i < prefixLen; i++) {
if (i >= strLen) {
return false;
}

if (substrBytes[i] != strBytes[location + i]) {
if (prefixBytes[i] != strBytes[i]) {
return false;
}
}
Expand Down Expand Up @@ -126,8 +125,6 @@ library WebAuthn {
bytes memory authenticatorData,
bool requireUserVerification,
string memory clientDataJSON,
uint256 challengeLocation,
uint256 responseTypeLocation,
uint256 r,
uint256 s,
uint256 x,
Expand All @@ -142,20 +139,15 @@ library WebAuthn {
}

// Check that response is for an authentication assertion
string memory responseType = '"type":"webauthn.get"';
if (!contains(responseType, clientDataJSON, responseTypeLocation)) {
return false;
}

// Check that challenge is in the clientDataJSON
// and that the challenge is in the clientDataJSON
// as per https://www.w3.org/TR/webauthn-2/#clientdatajson-serialization
string memory challengeB64url = Base64URL.encode(challenge);
string memory challengeProperty = string.concat(
'"challenge":"',
string memory prefix = string.concat(
'{"type":"webauthn.get","challenge":"',
challengeB64url,
'"'
);

if (!contains(challengeProperty, clientDataJSON, challengeLocation)) {
if (!startsWith(prefix, clientDataJSON)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

return false;
}

Expand Down
Loading
Loading