Skip to content

Commit

Permalink
Merge pull request #44 from Indicio-tech/feature/p256
Browse files Browse the repository at this point in the history
feat: add did jwk resolver and support for p256 keys
  • Loading branch information
TheTechmage authored Aug 12, 2024
2 parents 27d6f23 + b28b7fd commit 7354224
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions didcomm_messaging/crypto/backend/askar.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AskarKey(PublicKey):
"ed25519-pub": KeyAlg.ED25519,
"x25519-pub": KeyAlg.X25519,
"secp256k1-pub": KeyAlg.K256,
"p256-pub": KeyAlg.P256,
}
alg_to_codec = {v: k for k, v in codec_to_alg.items()}

Expand Down
2 changes: 2 additions & 0 deletions didcomm_messaging/multiformats/multicodec.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SupportedCodecs(Enum):
bls12381g2 = Multicodec("bls12_381-g2-pub", b"\xeb\x01")
bls12381g1g2 = Multicodec("bls12_381-g1g2-pub", b"\xee\x01")
secp256k1_pub = Multicodec("secp256k1-pub", b"\xe7\x01")
p256_pub = Multicodec("p256-pub", b"\x12\x00")

@classmethod
def by_name(cls, name: str) -> Multicodec:
Expand Down Expand Up @@ -49,6 +50,7 @@ def for_data(cls, data: bytes) -> Multicodec:
"bls12_381-g2-pub",
"bls12_381-g1g2-pub",
"secp256k1-pub",
"p256-pub",
]


Expand Down
69 changes: 69 additions & 0 deletions didcomm_messaging/resolver/jwk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""did:jwk Resolver."""

import re
import json

from didcomm_messaging import DIDResolver
from didcomm_messaging.resolver import DIDResolutionError
from didcomm_messaging.multiformats.multibase import Base64UrlEncoder

b64 = Base64UrlEncoder()


class JWKResolver(DIDResolver):
"""Resolve did:jwk."""

PATTERN = re.compile(r"^did:jwk:(?P<did>[A-Za-z0-9\-_]+)$")

async def resolve(self, did: str) -> dict:
"""Resolve a did:jwk."""
if match := self.PATTERN.match(did):
encoded = match.group("did")
else:
raise DIDResolutionError(f"Invalid DID: {did}")

try:
jwk = json.loads(b64.decode(encoded))
except json.JSONDecodeError:
raise DIDResolutionError("Invalid JWK")

if not isinstance(jwk, dict):
raise DIDResolutionError("Invalid JWK")

if "kty" not in jwk:
raise DIDResolutionError("Invalid JWK")

doc = {
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1",
],
"id": f"did:jwk:{encoded}",
"verificationMethod": [
{
"id": f"did:jwk:{encoded}#0",
"type": "JsonWebKey2020",
"controller": f"did:jwk:{encoded}",
"publicKeyJwk": jwk,
}
],
}

use = jwk.get("use")
if use == "sig":
doc.update(
{
"assertionMethod": [f"did:jwk:{encoded}#0"],
"authentication": [f"did:jwk:{encoded}#0"],
"capabilityInvocation": [f"did:jwk:{encoded}#0"],
"capabilityDelegation": [f"did:jwk:{encoded}#0"],
}
)
elif use == "enc":
doc.update({"keyAgreement": [f"did:jwk:{encoded}#0"]})

return doc

async def is_resolvable(self, did: str) -> bool:
"""Return if did is resolvable by this resolver."""
return bool(self.PATTERN.match(did))

0 comments on commit 7354224

Please sign in to comment.