Compare commits
3 Commits
d3e8580d00
...
1ec9b9ce9e
Author | SHA1 | Date |
---|---|---|
Cayo Puigdefabregas | 1ec9b9ce9e | |
Cayo Puigdefabregas | 49bff70ed5 | |
Cayo Puigdefabregas | 84a41385d0 |
|
@ -144,3 +144,11 @@ This document is an example and in production it must be adapted to contain the
|
|||
did = generate_did(key, url)
|
||||
definitive_url, document = gen_did_document(did, key)
|
||||
```
|
||||
|
||||
# Differences with didkit from spruceId:
|
||||
Although there is didkit support, there are some small differences in behavior.
|
||||
|
||||
## Namespaces:
|
||||
In didkit it is necessary to define in the context every name, (key) used in the credential or else both the signature and the verification will fail.
|
||||
In pyvckit if a name, (key) is used but is not defined in the context, then that signature or verification will filter out that part of the credential and ignore it as if it did not exist.
|
||||
The signature will be made by deleting that undefined part.
|
||||
|
|
|
@ -144,3 +144,12 @@ Este documento es un ejemplo y en producción hay que adaptarlo para contener la
|
|||
did = generate_did(key, url)
|
||||
definitive_url, document = gen_did_document(did, key)
|
||||
```
|
||||
|
||||
# Diferencias con didkit de spruceId:
|
||||
Aunque hay compatibilidad con didkit, hay algunas pequeñas diferencias en el comportamiento.
|
||||
|
||||
## Espacios de nombres:
|
||||
En didkit es necesario definir en el contexto todo nombre, (clave) usada en la credencial o si no fallará tanto la firma como la verificación.
|
||||
En pyvckit si un nombre, (clave) se usa pero no esta definido en el contexto, entonces esa firma o verificación filtrará esa parte de la credencial y la omitirá como si no existiera.
|
||||
La firma se hará borrando esa parte no definida.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ def main():
|
|||
signing_key = get_signing_key(key)
|
||||
|
||||
credential = json.loads(credential_tmpl)
|
||||
credential["issuer"] = did
|
||||
credential["issuer"]["id"] = did
|
||||
credential["issuanceDate"] = now()
|
||||
cred = json.dumps(credential)
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ credential_tmpl = """{
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M"
|
||||
},
|
||||
"issuer": "",
|
||||
"issuer": {
|
||||
"id": ""
|
||||
},
|
||||
"issuanceDate": ""
|
||||
}"""
|
||||
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
import json
|
||||
import zlib
|
||||
import base64
|
||||
import nacl.encoding
|
||||
import nacl.signing
|
||||
import multicodec
|
||||
import multiformats
|
||||
|
||||
from nacl.signing import VerifyKey
|
||||
from pyroaring import BitMap
|
||||
|
||||
from pyvckit.sign import to_jws_payload
|
||||
from pyvckit.did import resolve_did
|
||||
|
||||
|
||||
def get_signing_input(payload):
|
||||
|
@ -48,6 +52,14 @@ def verify_vc(credential):
|
|||
if not message:
|
||||
return False
|
||||
|
||||
did_issuer = vc.get("issuer", {}) or vc.get("holder", {})
|
||||
if isinstance(did_issuer, dict):
|
||||
did_issuer = did_issuer.get("id")
|
||||
|
||||
did_issuer_method = vc["proof"]["verificationMethod"].split("#")[0]
|
||||
if did_issuer != did_issuer_method:
|
||||
return False
|
||||
|
||||
header_b64, signature = get_signing_input(message)
|
||||
header_jws, signature_jws = jws_split(jws)
|
||||
|
||||
|
@ -57,14 +69,42 @@ def verify_vc(credential):
|
|||
header_jws_json = json.loads(
|
||||
nacl.encoding.URLSafeBase64Encoder.decode(header_jws)
|
||||
)
|
||||
|
||||
for k, v in header.items():
|
||||
if header_jws_json.get(k) != v:
|
||||
return False
|
||||
|
||||
verify_key = get_verify_key(vc)
|
||||
|
||||
try:
|
||||
data_verified = verify_key.verify(signature_jws+signature)
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
return False
|
||||
return data_verified == signature
|
||||
|
||||
if data_verified != signature:
|
||||
return False
|
||||
|
||||
|
||||
if "credentialStatus" in vc:
|
||||
# NOTE: THIS FIELD SHOULD BE SERIALIZED AS AN INTEGER,
|
||||
# BUT IOTA DOCUMENTAITON SERIALIZES IT AS A STRING.
|
||||
# DEFENSIVE CAST ADDED JUST IN CASE.
|
||||
revocation_index = int(vc["credentialStatus"]["revocationBitmapIndex"])
|
||||
|
||||
if did_issuer[:7] == "did:web": # Only DID:WEB can revoke
|
||||
issuer_did_document = resolve_did(did_issuer)
|
||||
issuer_revocation_list = issuer_did_document["service"][0]
|
||||
assert issuer_revocation_list["type"] == "RevocationBitmap2022"
|
||||
revocation_bitmap = BitMap.deserialize(
|
||||
zlib.decompress(
|
||||
base64.b64decode(
|
||||
issuer_revocation_list["serviceEndpoint"].rsplit(",")[1].encode('utf-8')
|
||||
)
|
||||
)
|
||||
)
|
||||
if revocation_index in revocation_bitmap:
|
||||
# Credential has been revoked by the issuer
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -80,7 +80,10 @@ def test_credential():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -105,7 +108,10 @@ def test_presentation():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -136,7 +142,10 @@ def test_verifiable_credential():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -159,7 +168,10 @@ def test_verifiable_presentation():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -189,7 +201,10 @@ def test_verifiable_credential_fail():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -213,7 +228,10 @@ def test_verifiable_presentation_fail1():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -243,7 +261,10 @@ def test_verifiable_presentation_fail2():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did,
|
||||
"name": ""
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,9 @@ def test_pyvckit_credential_validated_from_didkit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -127,7 +129,9 @@ def test_didkit_credential_validated_from_pyvckit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -149,7 +153,9 @@ def test_pyvckit_presentation_validated_from_didkit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -179,7 +185,9 @@ def test_fail_pyvckit_presentation_validated_from_didkit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
|
||||
|
@ -213,7 +221,9 @@ def test_didkit_presentation_validated_from_pyvckit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
cred_signed = render_and_sign_credential(credential, key)
|
||||
|
@ -239,7 +249,9 @@ def test_fail_didkit_presentation_validated_from_pyvckit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
cred_signed = render_and_sign_credential(credential, key)
|
||||
|
@ -268,7 +280,9 @@ def test_fail2_didkit_presentation_validated_from_pyvckit():
|
|||
"credentialSubject": {
|
||||
"id": "did:key:z6MkgGXSJoacuuNdwU1rGfPpFH72GACnzykKTxzCCTZs6Z2M",
|
||||
},
|
||||
"issuer": did,
|
||||
"issuer": {
|
||||
"id": did
|
||||
},
|
||||
"issuanceDate": now()
|
||||
}
|
||||
cred_signed = render_and_sign_credential(credential, key)
|
||||
|
|
Loading…
Reference in New Issue