-
Notifications
You must be signed in to change notification settings - Fork 17
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
Refactor/email auth simplification #104
base: main
Are you sure you want to change the base?
Conversation
…and tests to use the interface
…and replay protection
Refactor/email auth simplification
🚨 Report Summary
For more details view the full report in OpenZeppelin Code Inspector |
… update signature validation logic
…te EmailAuthSigner import
@zkfriendly Thank you for your PR! |
Thank you for the review.
The main goal of this PR is to provide a simpler primitive that can be used everywhere. For context, there is already an implementation here that doesn’t modify the EmailAuth library; instead, it uses it internally while exposing a much simpler interface. However, after reviewing it, @JohnGuilding suggested that we should aim to simplify the underlying EmailAuth library as well.
Given our goal and the fact that an implementation with a simpler interface already exists, it seems that if cloning and modifying EmailAuth is not an option, we can simply discard this PR and adopt the other implementation that builds upon the existing EmailAuth. cc @JohnGuilding
I agree. Even with the changes in this PR, the functions and structs in EmailAuth remain unchanged; code organization is a bit different to prevent duplicate code, but everything stays the same. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cheers @zkfriendly left some comments.
Let's jump on a call tomorrow if we need to discuss the 1271 signature comments some more
}, | ||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not strictly needed and can be removed safely. That said, benefits are mainly consistency across environments and corepack compatibility
/// @dev Unlike EmailAuth.sol which handles nullifiers internally, this contract is designed | ||
/// to be used like a signature verification mechanism where the calling contract manages | ||
/// its own replay protection. | ||
contract EmailAuthSigner is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts an EmailSigner
?
/// The templateId of the sign hash command. | ||
uint256 public templateId; | ||
|
||
constructor() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add _disableInitializers()
here https://docs.openzeppelin.com/contracts/5.x/api/proxy#Initializable-_disableInitializers--
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's a security feature, I think it's worth adding to EmailAuth
constructor too
templateId = _templateId; | ||
require( | ||
_dkimRegistryAddr != address(0), | ||
"invalid dkim registry address" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in breakout call, lets move to use custom errors if you're in agreement
|
||
// Magic value returned by older versions of EIP1271 when validating data and signature | ||
// bytes4(keccak256("isValidSignature(bytes,bytes)")). Used by Gnosis Safe and others. | ||
bytes4 internal constant EIP1271_MAGIC_VALUE_DATA = 0x20c13b0b; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: thoughts on this naming convention to make it explicit https://github.com/safe-global/safe-modules/blob/main/modules/passkey/contracts/libraries/ERC1271.sol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice yes, we should do that.
|
||
contract ERC1271SignatureValidator { | ||
/// Mapping to store if a hash has been signed. | ||
mapping(bytes32 => bool) public isHashSigned; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Where is this updated?
- What do you think about verifying proof etc directly in
isValidSignature
? And state updates can be handled in higher level logic such as how contract signatures work on Safes https://github.com/safe-global/safe-smart-account/blob/1c8b24a0a438e8c2cd089a9d830d1688a47a28d5/contracts/Safe.sol#L140-L142
This way the EmailSigner
can be used to verify "signatures" in a single step rather than approve + verify
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this updated?
this part is actually not implemented here yet. And I think your second point is a great idea for how to build this.
/// handling replay protection. The calling contract should implement its own mechanisms | ||
/// to prevent replay attacks, similar to how nonces are used with ECDSA signatures. | ||
/// @param emailAuthMsg The email auth message containing all necessary information for authentication. | ||
function authEmail(EmailAuthMsg memory emailAuthMsg) public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to above comment on 1271 validation - thinking that verifySignature is executing most of this logic
Description
This PR introduces a new simplified
EmailAuthSigner
contract that provides a signature-like authentication mechanism using emails. Unlike the existingEmailAuth
contract which handles nullifiers internally, this new contract is designed to be used like a signature verification mechanism where the calling contract manages its own replay protection.Key changes:
EmailAuthSigner.sol
contractIEmailAuth.sol
interface to standardize common functionalityEmailAuthMsg
struct to the interfaceType of change
How Has This Been Tested?
Added new test files and cases:
EmailAuthSigner.t.sol
with comprehensive test coverage including:All existing tests have been updated to work with the interface changes and continue to pass.
Checklist: