From ae8edce055e52c57082953ce4bf98afb41f66ed4 Mon Sep 17 00:00:00 2001 From: broody Date: Thu, 22 Feb 2024 09:47:23 -1000 Subject: [PATCH 1/2] Auth check `set_webauthn_pub_key` --- crates/account_sdk/src/tests/webauthn/mod.rs | 39 ++++++++++++-------- crates/webauthn/auth/src/component.cairo | 22 +++++++---- crates/webauthn/auth/src/interface.cairo | 2 +- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/crates/account_sdk/src/tests/webauthn/mod.rs b/crates/account_sdk/src/tests/webauthn/mod.rs index 3e443a65..17843971 100644 --- a/crates/account_sdk/src/tests/webauthn/mod.rs +++ b/crates/account_sdk/src/tests/webauthn/mod.rs @@ -8,8 +8,9 @@ use starknet::{ use crate::abigen::account::WebauthnPubKey; use crate::abigen::account::WebauthnSignature; +use crate::abigen::account::U256; use crate::{ - tests::runners::devnet_runner::DevnetRunner, + tests::runners::katana_runner::KatanaRunner, webauthn_signer::{cairo_args::VerifyWebauthnSignerArgs, P256r1Signer}, }; @@ -19,34 +20,40 @@ async fn test_set_webauthn_public_key() { let origin = "localhost".to_string(); let signer = P256r1Signer::random(origin.clone()); - let data = utils::WebauthnTestData::::new(private_key, signer).await; + let data = utils::WebauthnTestData::::new(private_key, signer).await; let reader = data.account_reader(); - let public_key = reader + let public_key: WebauthnPubKey = reader .get_webauthn_pub_key() .block_id(BlockId::Tag(BlockTag::Latest)) .call() .await .unwrap(); - - match public_key { - Option::Some(_) => panic!("Public key already set"), - Option::None => (), - } - + assert!( + public_key + == WebauthnPubKey { + x: U256 { low: 0, high: 0 }, + y: U256 { low: 0, high: 0 } + } + ); + + let target_key = data.webauthn_public_key(); data.set_webauthn_public_key().await; - let public_key = reader + let public_key: WebauthnPubKey = reader .get_webauthn_pub_key() .block_id(BlockId::Tag(BlockTag::Latest)) .call() .await .unwrap(); - match public_key { - Option::Some(_) => (), - Option::None => panic!("Public key not set"), - } + assert!( + public_key + == WebauthnPubKey { + x: target_key.0.into(), + y: target_key.1.into(), + } + ) } #[tokio::test] @@ -55,7 +62,7 @@ async fn test_verify_webauthn_explicit() { let origin = "localhost".to_string(); let signer = P256r1Signer::random(origin.clone()); - let data = utils::WebauthnTestData::::new(private_key, signer).await; + let data = utils::WebauthnTestData::::new(private_key, signer).await; data.set_webauthn_public_key().await; let reader = data.account_reader(); @@ -93,7 +100,7 @@ async fn test_verify_webauthn_execute() { let origin = "localhost".to_string(); let signer = P256r1Signer::random(origin.clone()); - let data = utils::WebauthnTestData::::new(private_key, signer).await; + let data = utils::WebauthnTestData::::new(private_key, signer).await; data.set_webauthn_public_key().await; let webauthn_executor = data.webauthn_executor().await; diff --git a/crates/webauthn/auth/src/component.cairo b/crates/webauthn/auth/src/component.cairo index 876f5314..ba03ce5c 100644 --- a/crates/webauthn/auth/src/component.cairo +++ b/crates/webauthn/auth/src/component.cairo @@ -28,6 +28,8 @@ mod webauthn_component { use core::result::ResultTrait; use starknet::info::{TxInfo, get_tx_info, get_block_timestamp}; use starknet::account::Call; + use starknet::get_caller_address; + use starknet::get_contract_address; use core::ecdsa::check_ecdsa_signature; use starknet::secp256r1::{Secp256r1Point, Secp256r1Impl}; use webauthn_auth::webauthn::verify; @@ -35,11 +37,12 @@ mod webauthn_component { #[storage] struct Storage { - public_key: Option, + public_key: WebauthnPubKey, } mod Errors { const INVALID_SIGNATURE: felt252 = 'Account: invalid signature'; + const UNAUTHORIZED: felt252 = 'Account: unauthorized'; } #[embeddable_as(Webauthn)] @@ -49,18 +52,17 @@ mod webauthn_component { fn set_webauthn_pub_key( ref self: ComponentState, public_key: WebauthnPubKey, ) { - self.public_key.write(Option::Some(public_key)); + assert_only_self(); + + self.public_key.write(public_key); } - fn get_webauthn_pub_key(self: @ComponentState,) -> Option { + fn get_webauthn_pub_key(self: @ComponentState,) -> WebauthnPubKey { self.public_key.read() } fn verify_webauthn_signer( self: @ComponentState, signature: WebauthnSignature, tx_hash: felt252, ) -> bool { - let pub = match self.get_webauthn_pub_key() { - Option::Some(pub) => pub, - Option::None => { return false; } - }; + let pub = self.get_webauthn_pub_key(); let pub_key = match Secp256r1Impl::secp256_ec_new_syscall(pub.x, pub.y) { Result::Ok(pub_key) => pub_key, Result::Err(e) => { return false; } @@ -95,4 +97,10 @@ mod webauthn_component { } } } + + fn assert_only_self() { + let caller = get_caller_address(); + let self = get_contract_address(); + assert(self == caller, Errors::UNAUTHORIZED); + } } diff --git a/crates/webauthn/auth/src/interface.cairo b/crates/webauthn/auth/src/interface.cairo index e7ff9c10..a0d61518 100644 --- a/crates/webauthn/auth/src/interface.cairo +++ b/crates/webauthn/auth/src/interface.cairo @@ -3,7 +3,7 @@ use webauthn_auth::component::{WebauthnPubKey, WebauthnSignature}; #[starknet::interface] trait IWebauthn { fn set_webauthn_pub_key(ref self: TContractState, public_key: WebauthnPubKey,); - fn get_webauthn_pub_key(self: @TContractState,) -> Option; + fn get_webauthn_pub_key(self: @TContractState,) -> WebauthnPubKey; fn verify_webauthn_signer( self: @TContractState, signature: WebauthnSignature, tx_hash: felt252, ) -> bool; From 63be1e91fceb3abd8e085ef79b68b02772b5ae9b Mon Sep 17 00:00:00 2001 From: broody Date: Thu, 22 Feb 2024 11:59:26 -1000 Subject: [PATCH 2/2] add back in option --- crates/account_sdk/src/tests/webauthn/mod.rs | 19 +++++++------------ crates/webauthn/auth/src/component.cairo | 11 +++++++---- crates/webauthn/auth/src/interface.cairo | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/crates/account_sdk/src/tests/webauthn/mod.rs b/crates/account_sdk/src/tests/webauthn/mod.rs index 17843971..caab51fd 100644 --- a/crates/account_sdk/src/tests/webauthn/mod.rs +++ b/crates/account_sdk/src/tests/webauthn/mod.rs @@ -8,7 +8,6 @@ use starknet::{ use crate::abigen::account::WebauthnPubKey; use crate::abigen::account::WebauthnSignature; -use crate::abigen::account::U256; use crate::{ tests::runners::katana_runner::KatanaRunner, webauthn_signer::{cairo_args::VerifyWebauthnSignerArgs, P256r1Signer}, @@ -23,24 +22,19 @@ async fn test_set_webauthn_public_key() { let data = utils::WebauthnTestData::::new(private_key, signer).await; let reader = data.account_reader(); - let public_key: WebauthnPubKey = reader + let public_key = reader .get_webauthn_pub_key() .block_id(BlockId::Tag(BlockTag::Latest)) .call() .await .unwrap(); - assert!( - public_key - == WebauthnPubKey { - x: U256 { low: 0, high: 0 }, - y: U256 { low: 0, high: 0 } - } - ); + + assert!(public_key.is_none(), "Public key already set"); let target_key = data.webauthn_public_key(); data.set_webauthn_public_key().await; - let public_key: WebauthnPubKey = reader + let public_key = reader .get_webauthn_pub_key() .block_id(BlockId::Tag(BlockTag::Latest)) .call() @@ -49,10 +43,11 @@ async fn test_set_webauthn_public_key() { assert!( public_key - == WebauthnPubKey { + == Some(WebauthnPubKey { x: target_key.0.into(), y: target_key.1.into(), - } + }), + "Public key mismatch" ) } diff --git a/crates/webauthn/auth/src/component.cairo b/crates/webauthn/auth/src/component.cairo index ba03ce5c..bc15d10b 100644 --- a/crates/webauthn/auth/src/component.cairo +++ b/crates/webauthn/auth/src/component.cairo @@ -37,7 +37,7 @@ mod webauthn_component { #[storage] struct Storage { - public_key: WebauthnPubKey, + public_key: Option, } mod Errors { @@ -54,15 +54,18 @@ mod webauthn_component { ) { assert_only_self(); - self.public_key.write(public_key); + self.public_key.write(Option::Some(public_key)); } - fn get_webauthn_pub_key(self: @ComponentState,) -> WebauthnPubKey { + fn get_webauthn_pub_key(self: @ComponentState,) -> Option { self.public_key.read() } fn verify_webauthn_signer( self: @ComponentState, signature: WebauthnSignature, tx_hash: felt252, ) -> bool { - let pub = self.get_webauthn_pub_key(); + let pub = match self.get_webauthn_pub_key() { + Option::Some(pub) => pub, + Option::None => { return false; } + }; let pub_key = match Secp256r1Impl::secp256_ec_new_syscall(pub.x, pub.y) { Result::Ok(pub_key) => pub_key, Result::Err(e) => { return false; } diff --git a/crates/webauthn/auth/src/interface.cairo b/crates/webauthn/auth/src/interface.cairo index a0d61518..e7ff9c10 100644 --- a/crates/webauthn/auth/src/interface.cairo +++ b/crates/webauthn/auth/src/interface.cairo @@ -3,7 +3,7 @@ use webauthn_auth::component::{WebauthnPubKey, WebauthnSignature}; #[starknet::interface] trait IWebauthn { fn set_webauthn_pub_key(ref self: TContractState, public_key: WebauthnPubKey,); - fn get_webauthn_pub_key(self: @TContractState,) -> WebauthnPubKey; + fn get_webauthn_pub_key(self: @TContractState,) -> Option; fn verify_webauthn_signer( self: @TContractState, signature: WebauthnSignature, tx_hash: felt252, ) -> bool;