def test_convert_seed_to_mnemonic_raises_validation_error_if_invalid_language(
        valid_bip39_seed):
    with pytest.raises(IdentityValidationError) as err_wrp:
        KeyPairSecretsHelper.seed_bip39_to_mnemonic(valid_bip39_seed,
                                                    lang='invalid_lang')
    assert 'Invalid language for mnemonic:' in str(err_wrp.value)
    assert isinstance(err_wrp.value.__cause__, FileNotFoundError)
def test_get_private_key_from_key_pair_secrets_raises_validation_error_if_invalid_method(
        valid_key_pair_secrets):
    key_pair_secret = KeyPairSecrets(valid_key_pair_secrets.seed,
                                     valid_key_pair_secrets.path,
                                     seed_method='plop',
                                     password='')
    with pytest.raises(IdentityValidationError):
        KeyPairSecretsHelper.get_private_key(key_pair_secret)
示例#3
0
    def _delegate(self, delegating_secrets: KeyPairSecrets, delegating_did: str,
                  subject_secrets: KeyPairSecrets, subject_did: str, delegation_name: str,
                  proof_type: DelegationProofType, delegation_proof_add_method: Callable):
        delegating_doc = self.get_register_document(delegating_did)
        subject_doc = self.get_register_document(subject_did)
        delegating_key_pair = KeyPairSecretsHelper.get_key_pair(delegating_secrets)
        delegating_issuer = AdvancedIdentityLocalApi.get_issuer_by_public_key(delegating_doc,
                                                                              delegating_key_pair.public_base58)
        if proof_type == DelegationProofType.GENERIC:
            subject_issuer, proof = AdvancedIdentityLocalApi.create_generic_delegation_proof(subject_doc,
                                                                                             subject_secrets)
        else:
            subject_issuer, proof = AdvancedIdentityLocalApi.create_delegation_proof(delegating_issuer,
                                                                                     subject_doc,
                                                                                     subject_secrets)

        existing_delegation = RegisterDocumentHelper.get_register_delegation_proof_by_controller(subject_issuer,
                                                                                                 delegating_doc,
                                                                                                 True)
        if existing_delegation and (
                not delegation_name or delegation_name == existing_delegation.name
        ):
            # Found an existing delegation with matching controller and name. Nothing to do.
            return

        if not delegation_name:
            delegation_name = RegisterDocumentHelper.new_random_name_for_document(subject_doc)

        delegation_proof_add_method(proof, subject_issuer, delegation_name,
                                    delegating_issuer, delegating_key_pair)
示例#4
0
    def new_registered_identity(self, purpose: DIDType, key_pair_secrets: KeyPairSecrets,
                                name: str = None, override_doc: bool = False) -> RegisteredIdentity:
        """
        Create and register a new registered identity and its associated register document against the resolver.
        :param key_pair_secrets: new registered identity owner secrets
        :param name: Optional new registered identity name (default: '#<purpose>-0')
                     following this pattern: '#[a-zA-Z\\-\\_0-9]{1, 24}'
        :param purpose: registered identity purpose (HOST, TWIN, USER or AGENT)
        :param override_doc: override registered identity document if already exist (default False)
        :return: registered identity

        :raises:
            IdentityValidationError: if invalid secrets
            IdentityValidationError: if invalid name
            IdentityInvalidDocumentError: if document build error
            IdentityResolverConflictError: register document already exists with different owners
            IdentityResolverError: if can not interact with the resolver
            IdentityDependencyError: if incompatible library dependency
        """
        key_pair = KeyPairSecretsHelper.get_key_pair(key_pair_secrets)
        did = AdvancedIdentityLocalApi.create_identifier(key_pair.public_bytes)
        name = name or f'{ISSUER_SEPARATOR}{purpose}-0'
        issuer = Issuer.build(did, name)
        if override_doc:
            self.register_new_doc(key_pair_secrets, issuer, purpose)
            return RegisteredIdentity(key_pair_secrets, issuer)

        issuer_key = IssuerKey.build(issuer.did, issuer.name, key_pair.public_base58)
        return self.register_new_identity_if_not_exists(issuer_key, key_pair_secrets, purpose)
示例#5
0
def register_doc(valid_key_pair_secrets, valid_issuer):
    proof = Proof.build(valid_key_pair_secrets,
                        valid_issuer,
                        content=valid_issuer.did.encode())
    key_pair = KeyPairSecretsHelper.get_key_pair(valid_key_pair_secrets)
    return RegisterDocumentBuilder() \
        .add_public_key(valid_issuer.name, key_pair.public_base58, revoked=False) \
        .build(valid_issuer.did, DIDType.USER, proof.signature, revoked=False)
示例#6
0
def invalid_doc_no_owner_key(valid_doc, valid_issuer, valid_key_pair_secrets,
                             other_key_pair_secrets):
    public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets(
        other_key_pair_secrets)
    doc_id = valid_doc.did
    return RegisterDocumentBuilder() \
        .add_public_key_obj(RegisterPublicKey('#KeyNotFromOwner', public_base58, revoked=False)) \
        .build(doc_id,
               DIDType.TWIN,
               proof=Proof.build(valid_key_pair_secrets, valid_issuer, content=doc_id.encode()).signature,
               revoked=False)
示例#7
0
def invalid_doc_invalid_proof(valid_doc, doc_invalid_proof,
                              valid_key_pair_secrets):
    public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets(
        valid_key_pair_secrets)
    doc_id = valid_doc.did
    return RegisterDocumentBuilder() \
        .add_public_key_obj(RegisterPublicKey('#Owner', public_base58, revoked=False)) \
        .build(doc_id,
               DIDType.TWIN,
               proof=doc_invalid_proof.signature,
               revoked=False)
def test_cannot_reuse_did_delegation_proof(get_delegation_method):
    twin1_secrets, twin1_issuer, twin1_doc = get_new_document('#Twin1')
    twin2_secrets, twin2_issuer, twin2_doc = get_new_document('#Twin2')
    agent_secrets, agent1_issuer, agent_doc = get_new_document('#Agent1')
    resolver_client = ResolverClientTest(
        docs={
            twin1_doc.did: twin1_doc,
            twin2_doc.did: twin2_doc,
            agent_doc.did: agent_doc,
        })
    api = AdvancedIdentityRegisterApi(resolver_client)

    # Create an agent did delegation proof (targeting a single delegating document: twin1)
    _, proof = AdvancedIdentityLocalApi.create_delegation_proof(
        delegating_issuer=twin1_issuer,
        subject_doc=agent_doc,
        subject_secrets=agent_secrets)

    # Add proof to twin1 document as a delegation proof - the document is valid
    get_delegation_method(api)(
        proof=proof,
        subject_issuer=agent1_issuer,
        delegation_name='#Deleg1',
        doc_owner_issuer=twin1_issuer,
        doc_owner_key_pair=KeyPairSecretsHelper.get_key_pair(twin1_secrets),
    )
    assert is_validator_run_success(api.validate_register_document,
                                    resolver_client.docs[twin1_doc.did])

    # Add proof to twin2 document as a delegation proof - the document is invalid
    get_delegation_method(api)(
        proof=proof,
        subject_issuer=agent1_issuer,
        delegation_name='#Deleg2',
        doc_owner_issuer=twin2_issuer,
        doc_owner_key_pair=KeyPairSecretsHelper.get_key_pair(twin2_secrets),
    )
    with pytest.raises(IdentityInvalidDocumentDelegationError):
        api.validate_register_document(resolver_client.docs[twin2_doc.did])
示例#9
0
    def set_document_creator(self, identity: RegisteredIdentity, creator: str):
        """
        Set creator to the register document associated to the provided registered identity.
        :param identity: registered identity
        :param creator: register document creator decentralised identifier

        :raises:
            IdentityValidationError: if invalid registered identity
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        key_pair = KeyPairSecretsHelper.get_key_pair(identity.key_pair_secrets)
        self.advanced_api.set_document_creator(key_pair, identity.issuer,
                                               creator)
    def get_ownership_of_twin_from_registered_identity(
            self, twin_registered_identity: RegisteredIdentity,
            new_owner_registered_identity: RegisteredIdentity,
            new_owner_key_name: str):
        """
        Get Ownership of a twin using a registered identity you owned.
        :param twin_registered_identity: twin registered identity
        :param new_owner_registered_identity: new owner registered identity
        :param new_owner_key_name: new owner key name

        :raises:
            IdentityValidationError: if invalid registered identities or name
            IdentityRegisterDocumentKeyConflictError: if new owner key name is not unique within the register document
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        new_owner_key_pair = KeyPairSecretsHelper.get_key_pair(
            new_owner_registered_identity.key_pair_secrets)
        current_owner_key_pair = KeyPairSecretsHelper.get_key_pair(
            twin_registered_identity.key_pair_secrets)
        self.advanced_api.add_public_key_to_document(
            new_owner_key_name, new_owner_key_pair.public_base58,
            current_owner_key_pair, twin_registered_identity.issuer)
示例#11
0
    def set_document_revoked(self, identity: RegisteredIdentity,
                             revoked: bool):
        """
        Set register document associated to the provided registered identity revoke field.
        :param identity: registered identity
        :param revoked:  is register document revoked

        :raises:
            IdentityValidationError: if invalid registered identity
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        key_pair = KeyPairSecretsHelper.get_key_pair(identity.key_pair_secrets)
        self.advanced_api.set_document_revoked(key_pair, identity.issuer,
                                               revoked)
示例#12
0
    def build(key_pair: KeyPairSecrets, issuer: Issuer,
              content: bytes) -> 'Proof':
        """
        Build a proof.
        :param key_pair: secrets used to build the proof signature
        :param issuer: proof issuer
        :param content:  proof content
        :return: proof

        :raises:
            IdentityValidationError: if invalid secrets
            IdentityDependencyError: if incompatible library dependency
        """
        private_key = KeyPairSecretsHelper.get_private_key(key_pair)
        sig = private_key.sign(content, ec.ECDSA(hashes.SHA256()))
        proof = base64.b64encode(sig).decode('ascii')
        return Proof(issuer=issuer, content=content, signature=proof)
示例#13
0
def get_valid_document_from_secret(secrets: KeyPairSecrets,
                                   issuer_name: str,
                                   controller: Issuer = None):
    public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets(
        secrets)
    public_bytes = base58.b58decode(public_base58)
    doc_id = make_identifier(public_bytes)
    proof = Proof.build(secrets,
                        Issuer.build(doc_id, issuer_name),
                        content=doc_id.encode())
    return RegisterDocumentBuilder() \
        .add_public_key_obj(RegisterPublicKey(issuer_name, public_base58, revoked=False)) \
        .build(doc_id,
               DIDType.TWIN,
               proof=proof.signature,
               revoked=False,
               controller=controller)
示例#14
0
    def create_generic_delegation_proof(subject_doc: RegisterDocument,
                                        subject_secrets: KeyPairSecrets) -> Tuple[Issuer, APIGenericDelegationProof]:
        """
        Create a delegation proof that can be re-used to setup a delegation from several delegating issuers.
        :param subject_doc: subject/delegated register document
        :param subject_secrets: subject/delegated secrets
        :return: subject/delegated issuer and proof

        :raises:
            IdentityValidationError: if invalid secrets
            IdentityRegisterIssuerNotFoundError: if the issuer matching the subject/delegated secrets is not found
            IdentityDependencyError: if incompatible library dependency
        """
        subject_key_pair = KeyPairSecretsHelper.get_key_pair(subject_secrets)
        subject_issuer = AdvancedIdentityLocalApi.get_issuer_by_public_key(subject_doc,
                                                                           subject_key_pair.public_base58)
        proof = APIGenericDelegationProof.build(subject_secrets, subject_issuer)
        return subject_issuer, proof
示例#15
0
    def register_new_doc(self, key_pair_secrets: KeyPairSecrets, issuer: Issuer,
                         purpose: DIDType):
        """
        Create and register a new document against the resolver.
        :param key_pair_secrets: new register document owner secrets
        :param issuer: new register document owner issuer
        :param purpose: register document purpose (HOST, TWIN, USER or AGENT)

        :raises:
            IdentityValidationError: if invalid secrets
            IdentityInvalidDocumentError: if document build error
            IdentityDependencyError: if incompatible library dependency
        """
        key_pair = KeyPairSecretsHelper.get_key_pair(key_pair_secrets)
        proof = AdvancedIdentityLocalApi.create_proof(key_pair_secrets, issuer, content=issuer.did.encode())
        doc = RegisterDocumentBuilder() \
            .add_public_key(issuer.name, key_pair.public_base58, revoked=False) \
            .build(issuer.did, purpose, proof.signature, revoked=False)
        self.register_updated_document(doc, key_pair, issuer)
示例#16
0
    def remove_ownership(
            self, removed_owner_issuer: Issuer,
            existing_owner_registered_identity: RegisteredIdentity):
        """
        Remove owner from a register document.
        :param removed_owner_issuer: register document owner issuer to remove
        :param existing_owner_registered_identity: other existing doc owner registered identity
        :return: removed register document owner issuer

        :raises:
            IdentityValidationError: if invalid owner
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        existing_owner_key_pair = KeyPairSecretsHelper.get_key_pair(
            existing_owner_registered_identity.key_pair_secrets)
        return self.advanced_api.remove_public_key_from_document(
            removed_owner_issuer, existing_owner_key_pair,
            existing_owner_registered_identity.issuer)
示例#17
0
    def get_key_pair_from_twin(
            twin_seed: bytes,
            twin_key_name: str,
            seed_method: SeedMethod = SeedMethod.SEED_METHOD_BIP39,
            password: str = '') -> KeyPair:
        """
        Get key pair from twin secrets
        :param twin_seed: twin seed (secrets)
        :param twin_key_name: twin key name (secrets)
        :param password: Optional twin password (secrets)
        :param seed_method: seed method (SEED_METHOD_NONE or SEED_METHOD_BIP39) default=SEED_METHOD_BIP39
        :return: twin key pair

        :raises:
                IdentityValidationError: if invalid twin key seed
                IdentityValidationError: if invalid twin key name
        """
        key_pair_secrets = build_twin_secrets(twin_seed, twin_key_name,
                                              seed_method, password)
        return KeyPairSecretsHelper.get_key_pair(key_pair_secrets)
示例#18
0
def get_valid_delegated_doc_and_deleg_proof(seed: bytes, issuer_name: str,
                                            delegating_doc_id: str,
                                            deleg_name: str):
    secrets = KeyPairSecrets.build(seed, 'iotics/0/something/twindeleg')
    public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets(
        secrets)
    public_bytes = base58.b58decode(public_base58)
    doc_id = make_identifier(public_bytes)
    issuer = Issuer.build(doc_id, issuer_name)
    proof = Proof.build(secrets, issuer, content=doc_id.encode())

    deleg_key = get_delegation_register_proof(
        subject_key_pair_secrets=secrets,
        content=delegating_doc_id.encode(),
        p_type=DelegationProofType.DID,
        subject_issuer=Issuer.build(doc_id, issuer_name),
        deleg_key_name=deleg_name)
    delegated_doc = RegisterDocumentBuilder() \
        .add_public_key_obj(RegisterPublicKey(issuer_name, public_base58, revoked=False)) \
        .build(doc_id, DIDType.TWIN, proof=proof.signature, revoked=False)
    return delegated_doc, deleg_key
    def create_agent_auth_token(agent_registered_identity: RegisteredIdentity,
                                user_did: str,
                                duration: int,
                                audience: str = 'default') -> str:
        """
        Create an agent authentication token.
        :param agent_registered_identity: agent registered identity
        :param user_did: user register document decentralised identifier
        :param duration: token duration in seconds
        :param audience: Optional token audience
        :return: encoded jwt token

        :raises:
            IdentityValidationError: if invalid agent identity
            IdentityValidationError: if invalid token data
            IdentityDependencyError: if incompatible library dependency
        """
        agent_key_pair = KeyPairSecretsHelper.get_key_pair(
            agent_registered_identity.key_pair_secrets)
        return AdvancedIdentityLocalApi.create_agent_auth_token(
            agent_key_pair, agent_registered_identity.issuer, user_did,
            duration, audience)
示例#20
0
    def add_new_owner(self, new_owner_name: str,
                      new_owner_public_key_base58: str,
                      doc_registered_identity: RegisteredIdentity) -> Issuer:
        """
        Add new register document owner.
        :param new_owner_name: new owner name
        :param new_owner_public_key_base58: new owner public base 58 key
        :param doc_registered_identity: doc owner registered identity
        :return: new register document owner issuer

        :raises:
            IdentityValidationError: if invalid new owner name
            IdentityValidationError: if invalid doc owner registered identity
            IdentityRegisterDocumentKeyConflictError: if new owner name is not unique within the register document
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        key_pair = KeyPairSecretsHelper.get_key_pair(
            doc_registered_identity.key_pair_secrets)
        return self.advanced_api.add_public_key_to_document(
            new_owner_name, new_owner_public_key_base58, key_pair,
            doc_registered_identity.issuer)
def test_can_convert_mnemonic_to_seed_with_spanish(
        valid_bip39_mnemonic_spanish, valid_bip39_seed):
    seed = KeyPairSecretsHelper.mnemonic_bip39_to_seed(
        valid_bip39_mnemonic_spanish, lang='spanish')
    assert seed == valid_bip39_seed
def test_can_get_public_base58_key(valid_key_pair_secrets,
                                   valid_public_base58):
    public_base58_key = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets(
        valid_key_pair_secrets)
    assert public_base58_key == valid_public_base58
def test_can_convert_seed_to_mnemonic(valid_bip39_seed,
                                      valid_bip39_mnemonic_english):
    mnemonic = KeyPairSecretsHelper.seed_bip39_to_mnemonic(valid_bip39_seed)
    assert mnemonic == valid_bip39_mnemonic_english
def test_can_get_private_key_from_key_pair_secrets(valid_key_pair_secrets):
    private_key = KeyPairSecretsHelper.get_private_key(valid_key_pair_secrets)
    assert private_key.key_size == ec.SECP256K1().key_size
    assert private_key.curve.name == ec.SECP256K1().name
def test_validate_bip39_seed_should_raise_if_invalid_seed():
    with pytest.raises(IdentityValidationError):
        KeyPairSecretsHelper.validate_bip39_seed(seed=b'invalid')
def test_validate_bip39_seed_should_not_raise_if_valid_seed(valid_bip39_seed):
    KeyPairSecretsHelper.validate_bip39_seed(valid_bip39_seed)
def test_convert_mnemonic_to_seed_raises_validation_error_if_invalid_language(
        valid_bip39_mnemonic_english):
    with pytest.raises(IdentityValidationError) as err_wrp:
        KeyPairSecretsHelper.mnemonic_bip39_to_seed(
            valid_bip39_mnemonic_english, lang='invalid_lang')
    assert isinstance(err_wrp.value.__cause__, FileNotFoundError)
def test_convert_mnemonic_to_seed_raises_validation_error_if_invalid_seed(
        invalid_mnemonic):
    with pytest.raises(IdentityValidationError):
        KeyPairSecretsHelper.mnemonic_bip39_to_seed(invalid_mnemonic)
def test_can_convert_seed_to_mnemonic_with_spanish(
        valid_bip39_seed, valid_bip39_mnemonic_spanish):
    mnemonic = KeyPairSecretsHelper.seed_bip39_to_mnemonic(valid_bip39_seed,
                                                           lang='spanish')
    assert mnemonic == valid_bip39_mnemonic_spanish
def test_convert_seed_to_mnemonic_raises_validation_error_if_invalid_seed(
        invalid_seed, error_val):
    with pytest.raises(IdentityValidationError) as err_wrp:
        KeyPairSecretsHelper.seed_bip39_to_mnemonic(invalid_seed)
    assert error_val in str(err_wrp.value)