Skip to content
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
1 change: 1 addition & 0 deletions pallets/identity-management-mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
]
std = [
"log/std",
"codec/std",
"sp-std/std",
"sp-runtime/std",
Expand Down
10 changes: 5 additions & 5 deletions pallets/identity-management-mock/src/identity_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use crate::{BlockNumberOf, Config, Metadata};
pub struct IdentityContext<T: Config> {
// the metadata
pub metadata: Option<Metadata>,
// the block number (of parent chain) where the linking was intially requested
pub linking_request_block: Option<BlockNumberOf<T>>,
// the block number (of parent chain) where the creation was intially requested
pub creation_request_block: Option<BlockNumberOf<T>>,
// the block number (of parent chain) where the verification was intially requested
pub verification_request_block: Option<BlockNumberOf<T>>,
// if this did is verified
Expand All @@ -41,7 +41,7 @@ impl<T: Config> Default for IdentityContext<T> {
fn default() -> Self {
Self {
metadata: None,
linking_request_block: None,
creation_request_block: None,
verification_request_block: None,
is_verified: false,
}
Expand All @@ -50,12 +50,12 @@ impl<T: Config> Default for IdentityContext<T> {

impl<T: Config> IdentityContext<T> {
pub fn new(
linking_request_block: BlockNumberOf<T>,
creation_request_block: BlockNumberOf<T>,
verification_request_block: BlockNumberOf<T>,
) -> Self {
Self {
metadata: None,
linking_request_block: Some(linking_request_block),
creation_request_block: Some(creation_request_block),
verification_request_block: Some(verification_request_block),
is_verified: false,
}
Expand Down
47 changes: 27 additions & 20 deletions pallets/identity-management-mock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub mod pallet {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// origin to manage caller whitelist
type ManageWhitelistOrigin: EnsureOrigin<Self::Origin>;
// maximum delay in block numbers between linking an identity and verifying an identity
// maximum delay in block numbers between creating an identity and verifying an identity
#[pallet::constant]
type MaxVerificationDelay: Get<BlockNumberOf<Self>>;
// some extrinsics should only be called by origins from TEE
Expand Down Expand Up @@ -171,9 +171,9 @@ pub mod pallet {
ShieldingKeyDecryptionFailed,
/// unexpected decoded type
WrongDecodedType,
/// identity already exists when linking an identity
IdentityAlreadyExist,
/// identity not exist when unlinking an identity
/// identity already verified when creating an identity
IdentityAlreadyVerified,
/// identity not exist when removing an identity
IdentityNotExist,
/// no shielding key for a given AccountId
ShieldingKeyNotExist,
Expand All @@ -187,8 +187,8 @@ pub mod pallet {
RecoverSubstratePubkeyFailed,
/// verify evm signature failed
VerifyEvmSignatureFailed,
/// the linking request block is zero
LinkingRequestBlockZero,
/// the creation request block is zero
CreationRequestBlockZero,
/// the challenge code doesn't exist
ChallengeCodeNotExist,
/// wrong signature type
Expand Down Expand Up @@ -310,14 +310,17 @@ pub mod pallet {
},
};

ensure!(
!IDGraphs::<T>::contains_key(&who, &identity),
Error::<T>::IdentityAlreadyExist
);
if let Some(c) = IDGraphs::<T>::get(&who, &identity) {
ensure!(!c.is_verified, Error::<T>::IdentityAlreadyVerified);
}

let key = UserShieldingKeys::<T>::get(&who).ok_or(Error::<T>::ShieldingKeyNotExist)?;

// emit the challenge code event, TODO: use randomness pallet
let code = Self::get_mock_challenge_code();
let code = Self::get_mock_challenge_code(
<frame_system::Pallet<T>>::block_number(),
ChallengeCodes::<T>::get(&who, &identity),
);
ChallengeCodes::<T>::insert(&who, &identity, &code);
Self::deposit_event(Event::<T>::ChallengeCodeGeneratedPlain {
account: who.clone(),
Expand All @@ -333,7 +336,7 @@ pub mod pallet {
// emit the IdentityCreated event
let context = IdentityContext {
metadata,
linking_request_block: Some(<frame_system::Pallet<T>>::block_number()),
creation_request_block: Some(<frame_system::Pallet<T>>::block_number()),
verification_request_block: None,
is_verified: false,
};
Expand Down Expand Up @@ -381,7 +384,7 @@ pub mod pallet {
Ok(())
}

/// Verify a linked identity
/// Verify a created identity
#[pallet::weight(195_000_000)]
pub fn verify_identity(
origin: OriginFor<T>,
Expand Down Expand Up @@ -424,11 +427,11 @@ pub mod pallet {

IDGraphs::<T>::try_mutate(&who, &identity, |context| -> DispatchResult {
let mut c = context.take().ok_or(Error::<T>::IdentityNotExist)?;
let linking_request_block =
c.linking_request_block.ok_or(Error::<T>::LinkingRequestBlockZero)?;
ensure!(linking_request_block <= now, Error::<T>::VerificationRequestTooEarly);
let creation_request_block =
c.creation_request_block.ok_or(Error::<T>::CreationRequestBlockZero)?;
ensure!(creation_request_block <= now, Error::<T>::VerificationRequestTooEarly);
ensure!(
now - linking_request_block <= T::MaxVerificationDelay::get(),
now - creation_request_block <= T::MaxVerificationDelay::get(),
Error::<T>::VerificationRequestTooLate
);
c.is_verified = true;
Expand Down Expand Up @@ -534,9 +537,13 @@ pub mod pallet {
}

// TODO: maybe use randomness pallet
fn get_mock_challenge_code() -> ChallengeCode {
let now = <frame_system::Pallet<T>>::block_number();
blake2_128(&now.encode())
pub fn get_mock_challenge_code(
bn: BlockNumberOf<T>,
maybe_code: Option<ChallengeCode>,
) -> ChallengeCode {
let mut code = bn.encode();
code.append(&mut maybe_code.encode());
blake2_128(&code)
}

fn verify_substrate_signature(
Expand Down
10 changes: 6 additions & 4 deletions pallets/identity-management-mock/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub use mock_tee_primitives::{
};
pub use parity_crypto::publickey::{sign, Generator, KeyPair as EvmPair, Message, Random};
use sp_core::sr25519::Pair as SubstratePair; // TODO: maybe use more generic struct
use sp_core::{blake2_128, Pair, H256};
use sp_core::{Pair, H256};
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
Expand Down Expand Up @@ -239,6 +239,10 @@ pub fn setup_create_identity(
) {
let key = setup_user_shieding_key(who);
let encrypted_identity = tee_encrypt(identity.encode().as_slice());
let code = IdentityManagementMock::get_mock_challenge_code(
bn,
IdentityManagementMock::challenge_codes(&who, &identity),
);
assert_ok!(IdentityManagementMock::create_identity(
Origin::signed(who),
H256::random(),
Expand All @@ -256,12 +260,10 @@ pub fn setup_create_identity(
account: aes_encrypted_account.clone(),
}));

// double check the challenge code
let code = blake2_128(bn.encode().as_slice());
System::assert_has_event(Event::IdentityManagementMock(
crate::Event::ChallengeCodeGeneratedPlain { account: who, identity, code },
));
let aes_encrypted_code = aes_encrypt_default(&key, code.encode().as_slice());
let aes_encrypted_code = aes_encrypt_default(&key, code.as_slice());
System::assert_has_event(Event::IdentityManagementMock(crate::Event::ChallengeCodeGenerated {
account: aes_encrypted_account,
identity: aes_encrypted_identity,
Expand Down
65 changes: 53 additions & 12 deletions pallets/identity-management-mock/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,59 @@ fn create_eth_identity_works() {
});
}

#[test]
fn create_two_distinct_twitter_identities_works() {
new_test_ext().execute_with(|| {
// create and verify the first twitter handle
System::set_block_number(3);
setup_verify_twitter_identity(2, create_mock_twitter_identity(b"alice"), 3);
// create second twitter handle works
System::set_block_number(4);
setup_create_identity(2, create_mock_twitter_identity(b"bob"), 4);
});
}

#[test]
fn create_twitter_identity_twice_works() {
new_test_ext().execute_with(|| {
let who = 2;
let identity = create_mock_twitter_identity(b"alice");
// create a twitter identity
System::set_block_number(3);
setup_create_identity(who, identity.clone(), 3);
let old_code = IdentityManagementMock::challenge_codes(who, &identity).unwrap();
// create the same twitter identity for the second time
// it should succeed and generate a new challenge code
System::set_block_number(5);
setup_create_identity(who, identity.clone(), 5);
let new_code = IdentityManagementMock::challenge_codes(who, &identity).unwrap();
assert!(old_code != new_code);
let c = IdentityManagementMock::id_graphs(who, &identity).unwrap();
assert!(c.creation_request_block == Some(5));
});
}

#[test]
fn create_twitter_identity_after_verification_fails() {
new_test_ext().execute_with(|| {
let who = 2;
let identity = create_mock_twitter_identity(b"alice");
System::set_block_number(3);
setup_verify_twitter_identity(who, identity.clone(), 3);
System::set_block_number(4);
let encrypted_identity = tee_encrypt(identity.encode().as_slice());
assert_noop!(
IdentityManagementMock::create_identity(
Origin::signed(who),
H256::random(),
encrypted_identity.to_vec(),
None
),
Error::<Test>::IdentityAlreadyVerified
);
});
}

// actually it should always be successful, as we don't have on-chain web2 verification
// for the mock pallet
#[test]
Expand Down Expand Up @@ -101,18 +154,6 @@ fn verify_eth_identity_works() {
});
}

#[test]
fn double_create_twitter_identity_works() {
new_test_ext().execute_with(|| {
// create and verify the first twitter handle
System::set_block_number(3);
setup_verify_twitter_identity(2, create_mock_twitter_identity(b"alice"), 3);
// create second twitter handle works
System::set_block_number(4);
setup_create_identity(2, create_mock_twitter_identity(b"bob"), 4);
});
}

#[test]
fn wrong_polkadot_verification_message_fails() {
new_test_ext().execute_with(|| {
Expand Down
2 changes: 1 addition & 1 deletion tee-worker/app-libs/stf/src/trusted_call_litentry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl TrustedCallSigned {
who: who.clone(),
identity: identity.clone(),
metadata,
linking_request_block: bn,
creation_request_block: bn,
}
.dispatch_bypass_filter(ita_sgx_runtime::Origin::root())
.map_err(|e| StfError::Dispatch(format!("{:?}", e.error)))?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use litentry_primitives::ParentchainBlockNumber;
pub struct IdentityContext<T: Config> {
// the metadata
pub metadata: Option<MetadataOf<T>>,
// the block number (of parent chain) where the linking was intially requested
pub linking_request_block: Option<ParentchainBlockNumber>,
// the block number (of parent chain) where the creation was intially requested
pub creation_request_block: Option<ParentchainBlockNumber>,
// the block number (of parent chain) where the verification was intially requested
pub verification_request_block: Option<ParentchainBlockNumber>,
// if this did is verified
Expand All @@ -42,7 +42,7 @@ impl<T: Config> Default for IdentityContext<T> {
fn default() -> Self {
Self {
metadata: None,
linking_request_block: None,
creation_request_block: None,
verification_request_block: None,
is_verified: false,
}
Expand All @@ -51,12 +51,12 @@ impl<T: Config> Default for IdentityContext<T> {

impl<T: Config> IdentityContext<T> {
pub fn new(
linking_request_block: ParentchainBlockNumber,
creation_request_block: ParentchainBlockNumber,
verification_request_block: ParentchainBlockNumber,
) -> Self {
Self {
metadata: None,
linking_request_block: Some(linking_request_block),
creation_request_block: Some(creation_request_block),
verification_request_block: Some(verification_request_block),
is_verified: false,
}
Expand Down
19 changes: 9 additions & 10 deletions tee-worker/litentry/pallets/identity-management/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub mod pallet {
/// maximum metadata length
#[pallet::constant]
type MaxMetadataLength: Get<u32>;
/// maximum delay in block numbers between linking an identity and verifying an identity
/// maximum delay in block numbers between creating an identity and verifying an identity
#[pallet::constant]
type MaxVerificationDelay: Get<ParentchainBlockNumber>;
}
Expand All @@ -91,8 +91,8 @@ pub mod pallet {
pub enum Error<T> {
/// challenge code doesn't exist
ChallengeCodeNotExist,
/// the pair (litentry-account, identity) already exists
IdentityAlreadyExist,
/// the pair (litentry-account, identity) already verified when creating an identity
IdentityAlreadyVerified,
/// the pair (litentry-account, identity) doesn't exist
IdentityNotExist,
/// the identity was not created before verification
Expand Down Expand Up @@ -186,16 +186,15 @@ pub mod pallet {
who: T::AccountId,
identity: Identity,
metadata: Option<MetadataOf<T>>,
linking_request_block: ParentchainBlockNumber,
creation_request_block: ParentchainBlockNumber,
) -> DispatchResult {
T::ManageOrigin::ensure_origin(origin)?;
ensure!(
!IDGraphs::<T>::contains_key(&who, &identity),
Error::<T>::IdentityAlreadyExist
);
if let Some(c) = IDGraphs::<T>::get(&who, &identity) {
ensure!(!c.is_verified, Error::<T>::IdentityAlreadyVerified);
}
let context = IdentityContext {
metadata,
linking_request_block: Some(linking_request_block),
creation_request_block: Some(creation_request_block),
..Default::default()
};
IDGraphs::<T>::insert(&who, &identity, context);
Expand Down Expand Up @@ -227,7 +226,7 @@ pub mod pallet {
IDGraphs::<T>::try_mutate(&who, &identity, |context| -> DispatchResult {
let mut c = context.take().ok_or(Error::<T>::IdentityNotExist)?;

if let Some(b) = c.linking_request_block {
if let Some(b) = c.creation_request_block {
ensure!(
b <= verification_request_block,
Error::<T>::VerificationRequestTooEarly
Expand Down
Loading