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

WIP feat: Add OidcValidator #274

Draft
wants to merge 4 commits into
base: feat/oidc-account-recovery
Choose a base branch
from
Draft
Changes from 3 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
88 changes: 88 additions & 0 deletions src/validators/OidcValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import { Transaction } from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/TransactionHelper.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import { IModuleValidator } from "../interfaces/IModuleValidator.sol";
import { IModule } from "../interfaces/IModule.sol";
import { VerifierCaller } from "../helpers/VerifierCaller.sol";

/// @title OidcValidator
/// @author Matter Labs
/// @custom:security-contact [email protected]
/// @dev This contract allows secure user authentication using OIDC protocol.
contract OidcValidator is VerifierCaller, IModuleValidator {
event OidcKeyUpdated(address indexed account, bytes iss, bool isNew);

struct OidcData {
bytes oidcDigest; // PoseidonHash(sub || aud || iss || salt)
bytes iss; // Issuer
bytes aud; // Audience
}

struct OidcSignature {
bytes zkProof;
bytes kid; // Key id used in the jwt
}

mapping(address => OidcData) public accountData;

/// @notice Runs on module install
/// @param data ABI-encoded OidcData key to add immediately, or empty if not needed
function onInstall(bytes calldata data) external override {
if (data.length > 0) {
require(addValidationKey(data), "OidcValidator: key already exists");
}
}

/// @notice Runs on module uninstall
/// @param data unused
function onUninstall(bytes calldata data) external override {
accountData[msg.sender] = OidcData(bytes(""), bytes(""), bytes(""));
}

/// @notice Adds an `OidcData` for the caller.
/// @param key ABI-encoded `OidcData`.
/// @return true if the key was added, false if it was updated.
function addValidationKey(bytes calldata key) public returns (bool) {

Choose a reason for hiding this comment

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

Consider adding tests while you write this code. I believe that it's going to make you advance stronger :)

OidcData memory oidcData = abi.decode(key, (OidcData));

bool isNew = accountData[msg.sender].oidcDigest.length == 0;
accountData[msg.sender] = oidcData;

emit OidcKeyUpdated(msg.sender, oidcData.iss, isNew);
return isNew;
}

/// @notice Validates a transaction to add a new passkey for the user.
/// @dev Ensures the transaction calls `addValidationKey` in `WebAuthValidator` and verifies the zk proof.
/// - Queries `OidcKeyRegistry` for the provider's public key (`pkop`).
/// - Calls the verifier contract to validate the zk proof.
/// - If the proof is valid, the transaction is approved, allowing `WebAuthValidator` to add the passkey.
/// @param signedHash The hash of the transaction data that was signed.
/// @param signature The signature to be verified, interpreted as an `OidcSignature`.
/// @param transaction The transaction data being validated.
/// @return true if the transaction is valid and authorized, false otherwise.
function validateTransaction(
bytes32 signedHash,
bytes calldata signature,
Transaction calldata transaction
) external view returns (bool){
revert("OidcValidator: validateTransaction not implemented");
}

/// @notice Unimplemented because signature validation is not required.
/// @dev We only need `validateTransaction` to add new passkeys, so this function is intentionally left unimplemented.
function validateSignature(bytes32 signedHash, bytes memory signature) external view returns (bool) {
revert("OidcValidator: validateSignature not implemented");
}

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
return
interfaceId == type(IERC165).interfaceId ||
interfaceId == type(IModuleValidator).interfaceId ||
interfaceId == type(IModule).interfaceId;
}
}
Loading