import didkit import json import idhub_ssikit import logging from sys import stderr def test_all_use_cases(): vcs = [ 'membership-card', 'financial-vulnerability', 'course-credential', 'federation-membership', 'e-operator-claim' ] # Test basic VC issuance: did:key, no revocation checks (they are not supported with did:key) for vc in vcs: print(f"trying {vc} in did:key mode... ", end="", file=stderr) try: signed_cred = issue_vc_test_newstyle(vc, use_web=False) ok, err = idhub_ssikit.verify_credential(signed_cred) if ok: print("OK", file=stderr) else: print("FAILED!", err, file=stderr) except Exception as e: logging.exception("FAILED! With exception:") # Test VC issuance using did:web DIDs for the issuer, unrevoked, and check revocation print("", file=stderr) for vc in vcs: print(f"trying {vc} in did:web mode, unrevoked... ", end="", file=stderr) try: signed_cred = issue_vc_test_newstyle(vc, use_web=True, did_revokes_vc=False) ok, err = idhub_ssikit.verify_credential(signed_cred) if ok: print("OK", file=stderr) else: print("FAILED!", err, file=stderr) except Exception as e: logging.exception("FAILED! With exception:") # Test VC issuance using did:web DIDs for the issuer, *revoked*, and check revocation print("", file=stderr) for vc in vcs: print(f"trying {vc} in did:web mode, *REVOKED*... ", end="", file=stderr) try: signed_cred = issue_vc_test_newstyle(vc, use_web=True, did_revokes_vc=True) ok, err = idhub_ssikit.verify_credential(signed_cred) if not ok: print("OK", file=stderr) else: print("FAILED! Credential ", err, file=stderr) except Exception as e: logging.exception("FAILED! With exception:") # Test VC resistance to tampering by modifying a credential after signature print("", file=stderr) for vc in vcs: print(f"tampering {vc} after issuance, check that it fails to verify... ", end="", file=stderr) try: issue_vc_test_and_fail_verification(vc) # All went well if this doesn't raise an exception print("OK", file=stderr) except Exception as e: logging.exception("FAILED!") # Test VP issuance and signature print("", file=stderr) print(f"doing end-to-end VP test, expected success... ", end="", file=stderr) ok, reason = issue_and_sign_vp_test(revoked_credential=False) assert ok is True print("OK", file=stderr) print(f"doing end-to-end VP test, expected failure... ", end="", file=stderr) ok, reason = issue_and_sign_vp_test(revoked_credential=True) assert ok is False print("OK", file=stderr) def issue_vc_test_newstyle(vc_name, use_web=True, did_revokes_vc=False, holder_jwk=None): jwk_issuer = '{"kty":"OKP","crv":"Ed25519","x":"piojLFIHQ4Z6heRuPI87nrfMJKdet1dJIPG15iGjmDE","d":"zpOBTDrp_iNQTY5nZlIxLA34Sl7FXWXNGehFktznxTM"}' jwk_subject = holder_jwk or '{"kty":"OKP","crv":"Ed25519","x":"BuKyt44QKYSX6kmAt771ai37lIFNwYlhugWXPiqcyYU","d":"qbvMhSCPKvQ-vSkqNr3q8gWY5zPUj7ry0t2YnmT7agc"}' did_subject = didkit.key_to_did("key", jwk_subject) if use_web: if did_revokes_vc: did_issuer = "did:web:idhub.pangea.org:did-registry:allRevoked" else: did_issuer = "did:web:idhub.pangea.org:did-registry:noneRevoked" else: did_issuer = didkit.key_to_did("key", jwk_issuer) vc_template = json.load(open(f'schemas/vc_templates/{vc_name}.json')) data_base = json.load(open(f'schemas/vc_examples/base--data.json')) data_specific = json.load(open(f'schemas/vc_examples/{vc_name}--data.json')) data = idhub_ssikit.deep_merge_dict(data_base, data_specific) data["issuer"]["id"] = did_issuer data["credentialSubject"]["id"] = did_subject if use_web: data["credentialStatus"]["id"] = did_issuer data["credentialStatus"]["revocationBitmapIndex"] = 42 vc_rendered_unsigned = idhub_ssikit.deep_merge_dict(vc_template, data) signed_credential = idhub_ssikit.render_and_sign_credential( vc_rendered_unsigned, jwk_issuer, ) return signed_credential def issue_vc_test_and_fail_verification(vc_name): def replace(s, position, character): return s[:position] + character + s[position+1:] signed_credential = issue_vc_test_newstyle(vc_name) ok, reason = idhub_ssikit.verify_credential(signed_credential) assert ok is True, (ok, reason) signed_credential = replace(signed_credential, (len(signed_credential)//4)*3, ".") ok, reason = idhub_ssikit.verify_credential(signed_credential) assert ok is False, (ok, reason) def issue_and_sign_vp_test(revoked_credential=False): """ In this example execution two Verifiable Credentials associated with a single Holder are issued and then combined into a single Verifiable Presentation. The Verifiable Credentials are of two different models. The use-case is meant to mimic - Holder being a physical person, - Issuer A being "Pare Manel" foundation, - Issuer B being "EXO" foundation, - Verifier (not pictured) being "Som Connexio", which wants verifiable data of the Holder from both Issuers. """ holder_jwk = didkit.generate_ed25519_key() holder_did = didkit.key_to_did("key", holder_jwk) vc1 = issue_vc_test_newstyle('membership-card', use_web=True, holder_jwk=holder_jwk) vc2 = issue_vc_test_newstyle('course-credential', use_web=True, did_revokes_vc=revoked_credential, holder_jwk=holder_jwk) signed_presentation = idhub_ssikit.issue_verifiable_presentation( [json.loads(vc1), json.loads(vc2)], holder_jwk, holder_did, "https://idhub.pangea.org/presentations/42" ) return idhub_ssikit.verify_presentation(signed_presentation) if __name__ == '__main__': test_all_use_cases()