def test_build_proof_from_challenge_token_raises_validation_error_if_invalid_token_data( register_doc, valid_private_key): invalid_challenge_token = jwt.encode({'invalid': 'data'}, valid_private_key, algorithm=TOKEN_ALGORITHM) resolver_client = ResolverClientTest(docs={register_doc.did: register_doc}) with pytest.raises(IdentityValidationError): Proof.from_challenge_token(resolver_client, invalid_challenge_token)
def _is_valid_issuer_or_reusable_proof(deleg_proof: RegisterDelegationProof, public_key: RegisterPublicKey, doc_id: str): controller_issuer = deleg_proof.controller if deleg_proof.proof_type == DelegationProofType.DID: proof = Proof(controller_issuer, doc_id.encode('ascii'), deleg_proof.proof) ProofValidation.validate_proof(proof, public_key.base58) elif deleg_proof.proof_type == DelegationProofType.GENERIC: proof = Proof(controller_issuer, b'', deleg_proof.proof) ProofValidation.validate_proof(proof, public_key.base58) else: raise IdentityInvalidProofError(f'Invalid proof: invalid type {deleg_proof.proof_type}')
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)
def test_can_build_proof_from_challenge_token(valid_private_key, valid_key_pair_secrets, valid_issuer, register_doc): proof = Proof.build(valid_key_pair_secrets, valid_issuer, content=b'a content') challenge_token = build_new_challenge_token(proof, valid_private_key) resolver_client = ResolverClientTest(docs={register_doc.did: register_doc}) deserialized_proof = Proof.from_challenge_token(resolver_client, challenge_token) assert deserialized_proof.issuer == proof.issuer assert deserialized_proof.content == proof.content assert deserialized_proof.signature == proof.signature
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)
def test_validate_proof_with_corrupted_signature_raises_validation_error( other_key_pair): corrupted_proof = Proof(issuer=valid_proof, content=b'a content', signature='plop not a signature') with pytest.raises(IdentityInvalidProofError) as err_wrapper: is_validator_run_success(ProofValidation.validate_proof, corrupted_proof, other_key_pair.public_base58) assert isinstance(err_wrapper.value.__cause__, ValueError)
def test_can_build_challenge_token(valid_private_key, valid_key_pair_secrets, valid_issuer): content = b'a content' proof = Proof.build(valid_key_pair_secrets, valid_issuer, content) challenge_token = build_new_challenge_token(proof, valid_private_key) assert challenge_token decoded = JwtTokenHelper.decode_token(challenge_token) assert decoded['iss'] == str(valid_issuer) assert decoded['aud'] == content.decode('ascii') assert decoded['proof'] == proof.signature
def get_proof_from_challenge_token(self, challenge_token: str) -> Proof: """ Get the proof from a challenge token. :param challenge_token: challenge jwt token :return: valid proof :raises: IdentityValidationError: if invalid challenge token """ return Proof.from_challenge_token(self.resolver_client, challenge_token)
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)
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)
def get_delegation_register_proof( subject_key_pair_secrets: KeyPairSecrets, subject_issuer: Issuer, content: bytes, p_type: DelegationProofType, deleg_key_name='#DelegKey') -> RegisterDelegationProof: proof = Proof.build(subject_key_pair_secrets, subject_issuer, content=content) return RegisterDelegationProof.build(deleg_key_name, controller=subject_issuer, proof=proof.signature, p_type=p_type, revoked=False)
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)
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
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 test_can_build_proof(valid_key_pair_secrets, valid_issuer): content = b'a content' proof = Proof.build(valid_key_pair_secrets, valid_issuer, content) assert proof.issuer == valid_issuer assert proof.content == content assert proof.signature
def valid_proof(valid_key_pair_secrets, valid_issuer): return Proof.build(valid_key_pair_secrets, valid_issuer, content=b'a content')
def test_build_proof_raises_validation_error_if_invalid_inputs( invalid_key_pair_secrets, valid_issuer): with pytest.raises(IdentityValidationError) as err_wrapper: Proof.build(invalid_key_pair_secrets, valid_issuer, b'a content') assert isinstance(err_wrapper.value.__cause__, ValueError)
def doc_invalid_proof(valid_key_pair_secrets, valid_issuer): return Proof.build(valid_key_pair_secrets, valid_issuer, content='not the doc id'.encode())
def test_build_challenge_token_raises_validation_error_if_can_not_create_token( valid_key_pair_secrets, valid_issuer): proof = Proof.build(valid_key_pair_secrets, valid_issuer, b'a content') with pytest.raises(IdentityValidationError) as err_wrapper: build_new_challenge_token(proof, private_key='not a private key') assert isinstance(err_wrapper.value.__cause__, ValueError)
def test_build_proof_from_challenge_token_raises_validation_error_if_invalid_token( register_doc): resolver_client = ResolverClientTest(docs={register_doc.did: register_doc}) with pytest.raises(IdentityValidationError) as err_wrapper: Proof.from_challenge_token(resolver_client, 'invalid token') assert isinstance(err_wrapper.value.__cause__, DecodeError)
def build(key_pair: KeyPairSecrets, issuer: Issuer, content: bytes) -> 'APIProof': proof = Proof.build(key_pair, issuer, content) return APIProof(proof.issuer, proof.content, proof.signature)