Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions app/credentials.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""MolTrust Verifiable Credentials - W3C VC Data Model"""
import os, json, datetime, hashlib
import jcs
from nacl.signing import SigningKey
from app.crypto.kms_signer import get_decrypted_signing_key_hex

Expand Down Expand Up @@ -27,14 +28,15 @@ def issue_credential(subject_did: str, credential_type: str, claims: dict) -> di
}

signing_key = get_signing_key()
payload = json.dumps(credential, sort_keys=True).encode()
payload = jcs.canonicalize(credential)
signed = signing_key.sign(payload)

credential["proof"] = {
"type": "Ed25519Signature2020",
"created": now.isoformat() + "Z",
"verificationMethod": f"{ISSUER_DID}#key-1",
"proofPurpose": "assertionMethod",
"canonicalizationAlgorithm": "JCS",
"proofValue": signed.signature.hex()
}
return credential
Expand All @@ -48,12 +50,18 @@ def verify_credential(credential: dict) -> dict:

try:
cred_copy = {k: v for k, v in credential.items() if k != "proof"}
payload = json.dumps(cred_copy, sort_keys=True).encode()
signature = bytes.fromhex(proof["proofValue"])

signing_key = get_signing_key()
verify_key = signing_key.verify_key
verify_key.verify(payload, signature)

# Try JCS first (new credentials), fall back to sort_keys (legacy)
if proof.get("canonicalizationAlgorithm") == "JCS":
payload = jcs.canonicalize(cred_copy)
verify_key.verify(payload, signature)
else:
payload = json.dumps(cred_copy, sort_keys=True).encode()
verify_key.verify(payload, signature)

exp = credential.get("expirationDate", "")
if exp:
Expand Down
5 changes: 3 additions & 2 deletions app/swarm/endorsement.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,16 @@ async def issue_endorsement(

# 11. Ed25519 Signatur (HIGH-5: real signing, no more sandbox_unsigned)
from app.credentials import get_signing_key
import json as _json
import jcs as _jcs
signing_key = get_signing_key()
payload = _json.dumps(vc, sort_keys=True).encode()
payload = _jcs.canonicalize(vc)
signed = signing_key.sign(payload)
vc["proof"] = {
"type": "Ed25519Signature2020",
"created": now.isoformat(),
"verificationMethod": "did:web:api.moltrust.ch#key-1",
"proofPurpose": "assertionMethod",
"canonicalizationAlgorithm": "JCS",
"proofValue": signed.signature.hex()
}

Expand Down