Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #85 from getwax/68-calldata-decode-stack-limit
Browse files Browse the repository at this point in the history
Use original library function (calldata params)
  • Loading branch information
JohnGuilding authored Sep 15, 2023
2 parents d2cfd8f + eb8f46d commit 4085e2c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 26 deletions.
99 changes: 78 additions & 21 deletions account-integrations/safe/src/SafeWebAuthnPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,92 @@ contract SafeWebAuthnPlugin is BaseAccount {
return _publicKey;
}

struct LocalVarStruct {
bytes1 authenticatorDataFlagMask;
uint256 clientChallengeDataOffset;
}

function _validateSignature(
UserOperation calldata userOp,
bytes32 userOpHash
) internal override returns (uint256 validationData) {
{
bytes calldata authenticatorData;
bytes calldata clientData;
uint256[2] calldata signature;
uint256[2] calldata pubKey;
LocalVarStruct memory s;

{
// parse length of all fixed-length params (including length)
uint i = 0;
uint dataLen = 32;
uint256 paramLen = abi.decode(userOp.signature[i:i+dataLen], (uint256));
// Fixed-length params (bytes1, (uint256?), uint256, uint256[2], uint256[2]). Expect 8 slots = 256 bytes
i += dataLen; // advance index

// decode fixed length params (values to memory)
dataLen = 3 * 32; //lenFixedParams - 32; // -32 already read length
(
bytes memory authenticatorData,
bytes1 authenticatorDataFlagMask,
bytes memory clientData,
uint256 clientChallengeDataOffset,
uint256[2] memory signature,
uint256[2] memory pubKey
s.authenticatorDataFlagMask,
, // some number
s.clientChallengeDataOffset
) = abi.decode(
userOp.signature,
(bytes, bytes1, bytes, uint256, uint256[2], uint256[2])
);

bool verified = FCL_WebAuthn.checkSignature(
authenticatorData,
authenticatorDataFlagMask,
clientData,
userOpHash,
clientChallengeDataOffset,
signature,
pubKey
userOp.signature[i:i+dataLen],
(
bytes1,
uint256, //not sure what is encoded here
uint256
)
);
if (!verified) return SIG_VALIDATION_FAILED;
return 0;
i += dataLen; // advance index


bytes calldata calldataLocation;
// load fixed length array params (pointers to calldata)
dataLen = 2 * 32;
calldataLocation = userOp.signature[i:i+dataLen];
assembly{
signature := calldataLocation.offset
}
i += dataLen; // advance index

calldataLocation = userOp.signature[i:i+dataLen];
assembly{
pubKey := calldataLocation.offset
}
i += dataLen; // advance index

// parse length of authenticatorData
dataLen = 32;
paramLen = abi.decode(userOp.signature[i:i+dataLen], (uint256));
i += dataLen; // advance index
// assign authenticatorData to sig splice
dataLen = paramLen;//((paramLen >> 5) + 1) << 5; // (round up to next slot)

authenticatorData = userOp.signature[i:i+dataLen];
i += ((dataLen >> 5) + 1) << 5; // advance index (round up to next slot)

// parse length of clientData
dataLen = 32;
paramLen = abi.decode(userOp.signature[i:i+dataLen], (uint256));
i += dataLen; // advance index
// assign clientData to sig splice
dataLen = paramLen;// ((paramLen >> 5) + 1) << 5; // (round up to next slot)
clientData = userOp.signature[i:i+dataLen];
i += ((dataLen >> 5) + 1) << 5; // advance index (round up to next slot)
}

bool verified = FCL_WebAuthn.checkSignature(
authenticatorData,
s.authenticatorDataFlagMask,
clientData,
userOpHash,
s.clientChallengeDataOffset,
signature,
pubKey
);
if (!verified) return SIG_VALIDATION_FAILED;
return 0;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions account-integrations/safe/src/lib/FCL_Webauthn.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ library FCL_WebAuthn {

/** @notice Modified from original Fresh Crypto Lib code to use memory instead of calldata */
function checkSignature(
bytes memory authenticatorData,
bytes calldata authenticatorData,
bytes1 authenticatorDataFlagMask,
bytes memory clientData,
bytes calldata clientData,
bytes32 clientChallenge,
uint256 clientChallengeDataOffset,
uint256[2] memory rs,
uint256[2] memory Q
uint256[2] calldata rs,
uint256[2] calldata Q
) internal returns (bool) {
// Let the caller check if User Presence (0x01) or User Verification (0x04) are set

Expand Down
6 changes: 6 additions & 0 deletions account-integrations/safe/test/forge/utils/TestHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,11 @@ abstract contract TestHelper is Test {
signature,
publicKey
);
// console2.logString("authenticatorData");
// console2.logBytes(authenticatorData);
// console2.logString("flagMask");
// console2.logBytes1(authenticatorDataFlagMask);
// console2.logString("userOp");
// console2.logBytes(userOpSignature);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe("SafeWebAuthnPlugin", () => {
const clientData =
"0x7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22efbfbd22efbfbd5f21efbfbd1b113e63efbfbdefbfbd6defbfbd4fefbfbdefbfbd11efbfbd11efbfbd40efbfbdefbfbdefbfbd64efbfbdefbfbd3cefbfbd58222c226f726967696e223a2268747470733a2f2f646576656c6f706d656e742e666f72756d64616f732e636f6d227d";
const clientChallengeDataOffset = 36;
const signature = [
const signature: [BigNumberish, BigNumberish] = [
BigInt(
"36788204816852931931532076736929768488646494203674172515272861180041446565109"
),
Expand Down

0 comments on commit 4085e2c

Please sign in to comment.