Esempio n. 1
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)
Esempio n. 2
0
def test_get_auth_delegation_by_controller_returns_none_if_not_found(
        auth_deleg_proof, min_doc_owner_pub_key):
    doc = get_doc_with_keys(deleg_auth=auth_deleg_proof.values(),
                            public_keys=[min_doc_owner_pub_key])
    issuer = Issuer.build('did:iotics:iotHHHHKpPGWyEC4FFo4d6oyzVVk6MXLmEgY',
                          '#DoesNotExist')
    deleg_proof = RegisterDocumentHelper.get_register_delegation_proof_by_controller(
        issuer, doc, include_auth=True)
    assert not deleg_proof
def test_register_doc_raises_resolver_error_if_can_not_register(
        valid_key_pair_secrets, valid_key_pair):
    resolver_client = ResolverClientTestWithError(
        register_err=IdentityResolverError('an error'))
    api = AdvancedIdentityRegisterApi(resolver_client)
    issuer = Issuer.build(make_identifier(valid_key_pair.public_bytes),
                          '#NewIssuer')
    with pytest.raises(IdentityResolverError):
        api.register_new_doc(valid_key_pair_secrets, issuer, DIDType.AGENT)
Esempio n. 4
0
def test_get_valid_doc_from_token_raises_invalid_issuer_if_can_not_find_issuer(
        simple_doc, valid_private_key):
    not_in_doc_issuer = Issuer.build(simple_doc.did, '#NotInDoc')
    token = get_inconsistent_token(str(not_in_doc_issuer),
                                   simple_doc.to_dict(), valid_private_key)
    with pytest.raises(IdentityResolverError) as err_wrapper:
        ResolverSerializer.get_valid_doc_from_token(
            token, get_controller_doc=raise_if_called)
    assert isinstance(err_wrapper.value.__cause__,
                      IdentityInvalidRegisterIssuerError)
Esempio n. 5
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
Esempio n. 6
0
def test_build_proof_from_challenge_token_raises_issuer_error_if_issuer_not_in_doc(
        register_doc, valid_private_key, valid_key_pair_secrets):
    other_issuer = Issuer.build(register_doc.did, '#OtherIssuer')
    proof = Proof.build(valid_key_pair_secrets,
                        other_issuer,
                        content=b'a content')
    challenge_token = build_new_challenge_token(proof, valid_private_key)

    resolver_client = ResolverClientTest(docs={register_doc.did: register_doc})

    with pytest.raises(IdentityInvalidRegisterIssuerError):
        Proof.from_challenge_token(resolver_client, challenge_token)
Esempio n. 7
0
def test_can_get_issuer_by_public_key(valid_key_pair):
    doc_did = make_identifier(valid_key_pair.public_bytes)
    key_issuer = Issuer.build(doc_did, '#AnIssuer')
    doc = RegisterDocumentBuilder() \
        .add_public_key_obj(RegisterPublicKey(key_issuer.name, valid_key_pair.public_base58, revoked=False)) \
        .build(key_issuer.did,
               DIDType.TWIN,
               proof='a proof, does not matter here',
               revoked=False)
    issuer = RegisterDocumentHelper.get_issuer_from_public_key(
        doc, valid_key_pair.public_base58)
    assert issuer == key_issuer
def test_can_register_a_doc(valid_key_pair_secrets, valid_key_pair):
    resolver_client = ResolverClientTest(docs={})
    api = AdvancedIdentityRegisterApi(resolver_client)
    did = make_identifier(valid_key_pair.public_bytes)
    issuer = Issuer.build(did, '#NewIssuer')
    api.register_new_doc(valid_key_pair_secrets, issuer, DIDType.AGENT)
    registered_doc = resolver_client.docs.get(issuer.did)
    assert registered_doc
    owner_key = registered_doc.public_keys.get(issuer.name)
    assert owner_key.name == issuer.name
    assert owner_key.base58 == valid_key_pair.public_base58
    assert not owner_key.revoked
Esempio n. 9
0
def doc_delegating_authentication(delegating_issuer_name, delegating_secrets,
                                  allowed_issuer_secrets, allowed_issuer):
    doc = get_valid_document_from_secret(delegating_secrets,
                                         delegating_issuer_name)
    delegating_issuer = Issuer.build(doc.did, delegating_issuer_name)
    proof = Proof.build(allowed_issuer_secrets,
                        allowed_issuer,
                        content=delegating_issuer.did.encode())
    return RegisterDocumentBuilder() \
        .add_authentication_delegation_obj(RegisterDelegationProof.build('#ADeleg',
                                                                         controller=allowed_issuer,
                                                                         proof=proof.signature)) \
        .build_from_existing(doc)
Esempio n. 10
0
def test_validate_delegation_raises_validation_error_if_delegation_to_self(
        deleg_doc_did, valid_key_pair_secrets):
    deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=valid_key_pair_secrets,
        # parent and delegated doc are the same
        content=deleg_doc_did.encode(),
        p_type=DelegationProofType.DID,
        subject_issuer=Issuer.build(deleg_doc_did, '#AController'))
    resolver_client = ResolverClientTest()
    with pytest.raises(IdentityInvalidDocumentDelegationError):
        DelegationValidation.validate_delegation(resolver_client,
                                                 doc_id=deleg_doc_did,
                                                 deleg_proof=deleg_proof)
Esempio n. 11
0
def test_validate_delegation_raises_validation_error_if_resolver_error(
        doc_did, deleg_doc_did, valid_key_pair_secrets, resolver_err):
    controller_name = '#AController'

    deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=valid_key_pair_secrets,
        content=doc_did.encode(),
        p_type=DelegationProofType.DID,
        subject_issuer=Issuer.build(deleg_doc_did, controller_name))
    resolver_client = ResolverClientWithError(error_to_raise=resolver_err())
    with pytest.raises(IdentityInvalidDocumentDelegationError) as err_wrapper:
        DelegationValidation.validate_delegation(resolver_client,
                                                 doc_id=doc_did,
                                                 deleg_proof=deleg_proof)
    assert isinstance(err_wrapper.value.__cause__, resolver_err)
Esempio n. 12
0
    def get_issuer_from_public_key(doc: RegisterDocument, public_base58: str) -> Optional[Issuer]:
        """
        Find a register key by issuer and returns True/False if found.
        Lookup in the register document public keys (and authentication keys if include_auth is set to True).
        :param doc: existing register document
        :param public_base58: public key to search for as base58 string
        :return: Issuer or None

        :raises:
            IdentityValidationError: if invalid name or did
        """
        for key in doc.public_keys.values():
            if key.base58 == public_base58:
                return Issuer.build(doc.did, key.name)
        return None
Esempio n. 13
0
def test_can_get_valid_issuer_for_control_only(issuer_name,
                                               register_doc_and_deleg_doc):
    doc, deleg_doc = register_doc_and_deleg_doc

    def get_ctrl_doc(did: str):
        assert did.startswith(did)
        return deleg_doc

    assert issuer_name in doc.public_keys or issuer_name in deleg_doc.public_keys
    issuer_key = RegisterDocumentHelper.get_valid_issuer_key_for_control_only(
        doc, issuer_name, get_ctrl_doc)
    assert issuer_key.issuer == Issuer.build(doc.did, issuer_name)
    expected_base58 = doc.public_keys.get(
        issuer_name, deleg_doc.public_keys.get(issuer_name))
    assert expected_base58, f'test setup error, {issuer_name} should be in one of the docs public keys'
    assert issuer_key.public_key_base58 == expected_base58.base58
Esempio n. 14
0
def test_validate_delegation_raises_validation_error_if_invalid_delegation_proof(
        doc_did, deleg_doc_did, valid_issuer_key, other_key_pair_secrets):
    controller_name = '#AController'
    corrupted_deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=other_key_pair_secrets,
        content=doc_did.encode(),
        p_type=DelegationProofType.DID,
        subject_issuer=Issuer.build(deleg_doc_did, controller_name))
    deleg_doc = get_delegation_doc_for(
        controller_name=controller_name,
        doc_id=deleg_doc_did,
        public_base58=valid_issuer_key.public_key_base58)
    resolver_client = ResolverClientTest(docs={deleg_doc_did: deleg_doc})
    with pytest.raises(IdentityInvalidDocumentDelegationError) as err_wrapper:
        DelegationValidation.validate_delegation(
            resolver_client, doc_id=doc_did, deleg_proof=corrupted_deleg_proof)
    assert isinstance(err_wrapper.value.__cause__, IdentityInvalidProofError)
Esempio n. 15
0
def test_verify_authentication_raises_auth_error_if_issuer_not_in_doc_keys_or_deleg(
        authentication_subject_doc, valid_private_key):
    not_auth_issuer = Issuer.build(authentication_subject_doc.did,
                                   '#OtherIssuer')
    token_from_not_auth_issuer = JwtTokenHelper.create_auth_token(
        iss=str(not_auth_issuer),
        sub=authentication_subject_doc.did,
        aud='http://audience/',
        duration=360,
        private_key=valid_private_key)
    resolver_client = ResolverClientTest(
        docs={authentication_subject_doc.did: authentication_subject_doc})
    with pytest.raises(IdentityAuthenticationFailed) as err_wrapper:
        IdentityAuthValidation.verify_authentication(
            resolver_client, token=token_from_not_auth_issuer)
    assert isinstance(err_wrapper.value.__cause__,
                      IdentityInvalidRegisterIssuerError)
Esempio n. 16
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)
Esempio n. 17
0
def test_can_validate_delegation(doc_did, deleg_doc_did, valid_issuer_key,
                                 valid_key_pair_secrets, proof_type,
                                 get_content):
    controller_name = '#AController'
    deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=valid_key_pair_secrets,
        content=get_content(doc_did),
        p_type=proof_type,
        subject_issuer=Issuer.build(deleg_doc_did, controller_name))
    deleg_doc = get_delegation_doc_for(
        controller_name=controller_name,
        doc_id=deleg_doc_did,
        public_base58=valid_issuer_key.public_key_base58)
    resolver_client = ResolverClientTest(docs={deleg_doc_did: deleg_doc})
    assert is_validator_run_success(DelegationValidation.validate_delegation,
                                    resolver_client,
                                    doc_id=doc_did,
                                    deleg_proof=deleg_proof)
Esempio n. 18
0
def test_validate_delegation_raises_validation_error_if_invalid_proof_type(
        doc_did, deleg_doc_did, valid_issuer_key):
    controller_name = '#AController'
    deleg_proof = RegisterDelegationProof(name='#DelegKey',
                                          controller=Issuer.build(
                                              deleg_doc_did, controller_name),
                                          proof='a signature',
                                          proof_type='not existing type',
                                          revoked=False)
    deleg_doc = get_delegation_doc_for(
        controller_name=controller_name,
        doc_id=deleg_doc_did,
        public_base58=valid_issuer_key.public_key_base58)
    resolver_client = ResolverClientTest(docs={deleg_doc_did: deleg_doc})
    with pytest.raises(IdentityInvalidDocumentDelegationError) as wrapper:
        DelegationValidation.validate_delegation(resolver_client,
                                                 doc_id=doc_did,
                                                 deleg_proof=deleg_proof)
    assert "Invalid proof: invalid type" in str(wrapper.value)
Esempio n. 19
0
def test_can_validate_allowed_for_auth_with_controller_doc(
        allowed_issuer, allowed_issuer_doc):
    controller_issuer_doc = allowed_issuer_doc
    controller_issuer = Issuer.build(controller_issuer_doc.did, '#Plop')
    a_doc_with_controller_allowed_for_auth = get_valid_document(
        new_seed(), '#ASubject', controller=controller_issuer)
    resolver_docs = {
        controller_issuer.did:
        controller_issuer_doc,
        a_doc_with_controller_allowed_for_auth.did:
        a_doc_with_controller_allowed_for_auth
    }
    resolver_client = ResolverClientTest(docs=resolver_docs)

    assert is_validator_run_success(
        IdentityAuthValidation.validate_allowed_for_auth,
        resolver_client,
        allowed_issuer,
        subject_id=a_doc_with_controller_allowed_for_auth.did)
Esempio n. 20
0
    def remove_authentication_key_from_document(self, name: str,
                                                doc_owner_key_pair: KeyPair,
                                                doc_owner_issuer: Issuer) -> Issuer:

        """
        Remove a register authentication public key from a register document.
        :param name: authentication public key name
        :param doc_owner_key_pair: register document owner key pair
        :param doc_owner_issuer: register document owner issuer
        :return: new key issuer

        :raises:
            IdentityValidationError: if invalid authentication public key name
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        self._update_doc(doc_owner_key_pair, doc_owner_issuer, get_updated_doc=self.auth_key_api.remove_doc_key,
                         key_name=name)
        return Issuer.build(doc_owner_issuer.did, name)
Esempio n. 21
0
def test_can_get_valid_issuer_for_auth(issuer_name,
                                       register_doc_and_deleg_doc):
    doc, deleg_doc = register_doc_and_deleg_doc

    def get_ctrl_doc(did: str):
        assert did.startswith(did)
        return deleg_doc

    all_keys = list(doc.public_keys) + list(doc.auth_keys) + list(
        deleg_doc.public_keys) + list(deleg_doc.auth_keys)
    assert issuer_name in all_keys
    issuer_key = RegisterDocumentHelper.get_valid_issuer_key_for_auth(
        doc, issuer_name, get_ctrl_doc)
    assert issuer_key.issuer == Issuer.build(doc.did, issuer_name)
    exp_base58 = doc.public_keys.get(issuer_name,
                                     doc.auth_keys.get(issuer_name))
    exp_base58 = exp_base58 or deleg_doc.public_keys.get(
        issuer_name, deleg_doc.auth_keys.get(issuer_name))
    assert exp_base58, f'test setup error, {issuer_name} should be in one of the docs public or auth keys'
    assert issuer_key.public_key_base58 == exp_base58.base58
Esempio n. 22
0
    def validate_new_document_proof(doc: RegisterDocument):
        """
        Validate register document proof.
        :param doc: register document.

        :raises:
            IdentityInvalidDocumentError: if register document initial owner public key has been removed
            IdentityInvalidDocumentError: if register document proof is invalid
        """
        try:
            key = RegisterDocumentHelper.get_owner_register_public_key(doc)
            if not key:
                raise IdentityInvalidDocumentError(
                    f'Invalid document \'{doc.did}\', no owner public key')
            ProofValidation.validate_proof(
                Proof(Issuer.build(doc.did, key.name), doc.did.encode('ascii'),
                      doc.proof), key.base58)
        except IdentityInvalidProofError as err:
            raise IdentityInvalidDocumentError(
                f'Invalid document \'{doc.did}\' proof: {err}') from err
Esempio n. 23
0
def test_validate_delegation_raises_validation_error_if_content_does_not_match_proof_type(
        doc_did, deleg_doc_did, valid_issuer_key, valid_key_pair_secrets,
        wrong_type, get_content):
    controller_name = '#AController'
    deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=valid_key_pair_secrets,
        content=get_content(doc_did),
        p_type=wrong_type,
        subject_issuer=Issuer.build(deleg_doc_did, controller_name))
    deleg_doc = get_delegation_doc_for(
        controller_name=controller_name,
        doc_id=deleg_doc_did,
        public_base58=valid_issuer_key.public_key_base58)
    resolver_client = ResolverClientTest(docs={deleg_doc_did: deleg_doc})

    with pytest.raises(IdentityInvalidDocumentDelegationError) as err_wrapper:
        DelegationValidation.validate_delegation(resolver_client,
                                                 doc_id=doc_did,
                                                 deleg_proof=deleg_proof)
    assert isinstance(err_wrapper.value.__cause__, IdentityInvalidProofError)
Esempio n. 24
0
    def revoke_authentication_key_from_document(self, name: str, revoked: bool,
                                                doc_owner_key_pair: KeyPair,
                                                doc_owner_issuer: Issuer) -> Issuer:
        """
        Set register authentication public key revoke field.
        :param name: authentication public key name
        :param revoked: is revoked
        :param doc_owner_key_pair: register document owner key pair
        :param doc_owner_issuer: register document owner issuer
        :return: new key issuer

        :raises:
            IdentityValidationError: if invalid authentication public key name
            IdentityRegisterDocumentKeyNotFoundError: if register authentication public key not found
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        self._update_doc(doc_owner_key_pair, doc_owner_issuer, get_updated_doc=self.auth_key_api.revoke_doc_key,
                         key_name=name, revoked=revoked)
        return Issuer.build(doc_owner_issuer.did, name)
Esempio n. 25
0
def test_validate_delegation_raises_validation_error_if_public_key_not_in_deleg_controller_doc(
        doc_did, deleg_doc_did, valid_issuer_key, valid_key_pair_secrets):
    controller_name = '#AController'
    deleg_proof = get_delegation_register_proof(
        subject_key_pair_secrets=valid_key_pair_secrets,
        content=doc_did.encode(),
        p_type=DelegationProofType.DID,
        subject_issuer=Issuer.build(deleg_doc_did, controller_name))
    deleg_doc = get_doc_with_keys(did=doc_did,
                                  public_keys=[
                                      RegisterPublicKey.build(
                                          '#NotMatchingTheController',
                                          valid_issuer_key.public_key_base58,
                                          revoked=False),
                                  ])
    resolver_client = ResolverClientTest({deleg_doc_did: deleg_doc})
    with pytest.raises(IdentityInvalidDocumentDelegationError) as err_wrapper:
        DelegationValidation.validate_delegation(resolver_client,
                                                 doc_id=doc_did,
                                                 deleg_proof=deleg_proof)
    assert isinstance(err_wrapper.value.__cause__, IdentityValidationError)
Esempio n. 26
0
    def add_public_key_to_document(self, name: str,
                                   new_public_key_base58: str,
                                   doc_owner_key_pair: KeyPair,
                                   doc_owner_issuer: Issuer) -> Issuer:
        """
        Add a new register public key to a register document.
        :param name: new public key name
        :param new_public_key_base58: public key base 58
        :param doc_owner_key_pair: register document owner key pair
        :param doc_owner_issuer: register document owner issuer
        :return: new register document owner issuer

        :raises:
            IdentityValidationError: if invalid new public key name
            IdentityRegisterDocumentKeyConflictError: if public key name is not unique within the register document
            IdentityInvalidDocumentError: if invalid register document
            IdentityResolverError: if resolver error
        """
        new_key = RegisterPublicKey.build(name, new_public_key_base58)
        self._update_doc(doc_owner_key_pair, doc_owner_issuer, get_updated_doc=self.public_key_api.add_doc_key,
                         key=new_key)
        return Issuer.build(doc_owner_issuer.did, name)
def test_can_delegate_control(base_doc, valid_key_pair_secrets,
                              other_key_pair_secrets):
    subject_doc = get_valid_document_from_secret(other_key_pair_secrets,
                                                 '#DelegatedDoc')
    resolver_client = ResolverClientTest(docs={
        base_doc.did: base_doc,
        subject_doc.did: subject_doc
    })
    api = AdvancedIdentityRegisterApi(resolver_client)
    assert not resolver_client.docs[base_doc.did].control_delegation_proof
    api.delegate_control(delegating_secrets=valid_key_pair_secrets,
                         delegating_did=base_doc.did,
                         subject_secrets=other_key_pair_secrets,
                         subject_did=subject_doc.did,
                         delegation_name='#NewControlDeleg')
    control_deleg = resolver_client.docs[
        base_doc.did].control_delegation_proof.get('#NewControlDeleg')
    assert control_deleg
    assert control_deleg.name == '#NewControlDeleg'
    assert not control_deleg.revoked
    assert control_deleg.proof
    assert control_deleg.controller == Issuer.build(subject_doc.did,
                                                    '#DelegatedDoc')
Esempio n. 28
0
def doc_with_doc_deleg(valid_issuer_key, doc_did, deleg_doc_did):
    doc = get_doc_with_keys(
        did=doc_did,
        public_keys=[
            RegisterPublicKey.build('#Key1', 'base58Key1', revoked=False)
        ],
        deleg_control=[
            RegisterDelegationProof.build(valid_issuer_key.issuer.name,
                                          controller=Issuer.build(
                                              deleg_doc_did, '#plop1'),
                                          proof='aproof',
                                          revoked=False),
        ],
    )

    deleg_doc = get_doc_with_keys(did=deleg_doc_did,
                                  public_keys=[
                                      RegisterPublicKey.build(
                                          valid_issuer_key.issuer.name,
                                          valid_issuer_key.public_key_base58,
                                          revoked=False),
                                  ])
    return doc, deleg_doc
def base_doc_issuer(base_doc, base_doc_issuer_name):
    return Issuer.build(base_doc.did, base_doc_issuer_name)
def other_doc_issuer(other_doc_did):
    return Issuer.build(other_doc_did, '#DelegatedDoc')