Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transform to and from 'did:key' style keys in oob messages #639

Merged
merged 6 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from 5 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
23 changes: 20 additions & 3 deletions aries_cloudagent/protocols/out_of_band/v1_0/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ....config.injection_context import InjectionContext
from ....core.error import BaseError
from ....ledger.base import BaseLedger
from ....wallet.util import did_key_to_naked, naked_to_did_key
from ....protocols.connections.v1_0.manager import ConnectionManager
from ....protocols.connections.v1_0.messages.connection_invitation import (
ConnectionInvitation,
Expand Down Expand Up @@ -142,8 +143,14 @@ async def create_invitation(
service = ServiceMessage(
_id="#inline",
_type="did-communication",
recipient_keys=connection_invitation.recipient_keys,
routing_keys=connection_invitation.routing_keys,
recipient_keys=[
naked_to_did_key(key)
for key in connection_invitation.recipient_keys or []
],
routing_keys=[
nrempel marked this conversation as resolved.
Show resolved Hide resolved
naked_to_did_key(key)
for key in connection_invitation.routing_keys or []
],
service_endpoint=connection_invitation.endpoint,
).validate()

Expand Down Expand Up @@ -196,17 +203,19 @@ async def receive_invitation(
# Get the single service item
if invitation_message.service_blocks:
service = invitation_message.service_blocks[0]

else:
# If it's in the did format, we need to convert to a full service block
service_did = invitation_message.service_dids[0]
async with ledger:
verkey = await ledger.get_key_for_did(service_did)
did_key = naked_to_did_key(verkey)
endpoint = await ledger.get_endpoint_for_did(service_did)
service = ServiceMessage.deserialize(
{
"id": "#inline",
"type": "did-communication",
"recipientKeys": [verkey],
"recipientKeys": [did_key],
"routingKeys": [],
"serviceEndpoint": endpoint,
}
Expand All @@ -224,6 +233,14 @@ async def receive_invitation(
"request block must be empty for invitation message type."
)

# Transform back to 'naked' verkey
service.recipient_keys = [
did_key_to_naked(key) for key in service.recipient_keys or []
]
service.routing_keys = [
did_key_to_naked(key) for key in service.routing_keys
] or []

# Convert to the old message format
connection_invitation = ConnectionInvitation.deserialize(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from marshmallow import fields

from .....messaging.models.base import BaseModel, BaseModelSchema
from .....messaging.valid import INDY_DID, INDY_RAW_PUBLIC_KEY
from .....messaging.valid import INDY_DID, DID_KEY


class Service(BaseModel):
Expand Down Expand Up @@ -58,14 +58,14 @@ class Meta:
did = fields.Str(required=False, description="", **INDY_DID)

recipient_keys = fields.List(
fields.Str(description="Recipient public key", **INDY_RAW_PUBLIC_KEY),
fields.Str(description="Recipient public key", **DID_KEY),
data_key="recipientKeys",
required=False,
description="List of recipient keys",
)

routing_keys = fields.List(
fields.Str(description="Routing key", **INDY_RAW_PUBLIC_KEY),
fields.Str(description="Routing key", **DID_KEY),
data_key="routingKeys",
required=False,
description="List of routing keys",
Expand Down
14 changes: 14 additions & 0 deletions aries_cloudagent/wallet/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
str_to_b64,
set_urlsafe_b64,
unpad,
naked_to_did_key,
did_key_to_naked,
)


Expand Down Expand Up @@ -62,3 +64,15 @@ def test_pad(self):
def test_b58(self):
b58 = bytes_to_b58(BYTES)
assert b58_to_bytes(b58) == BYTES

def test_naked_to_did_key(self):
assert (
naked_to_did_key("8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K")
== "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th"
)

def test_did_key_to_naked(self):
assert (
did_key_to_naked("did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th")
== "8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"
)
18 changes: 18 additions & 0 deletions aries_cloudagent/wallet/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import base58
import base64

from multicodec import add_prefix, remove_prefix


def pad(val: str) -> str:
"""Pad base64 values if need be: JWT calls to omit trailing padding."""
Expand Down Expand Up @@ -57,3 +59,19 @@ def b58_to_bytes(val: str) -> bytes:
def bytes_to_b58(val: bytes) -> str:
"""Convert a byte string to base 58."""
return base58.b58encode(val).decode("ascii")


def naked_to_did_key(key: str) -> str:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"""Convert a naked ed25519 verkey to did:key format."""
key_bytes = b58_to_bytes(key)
prefixed_key_bytes = add_prefix("ed25519-pub", key_bytes)
did_key = f"did:key:z{bytes_to_b58(prefixed_key_bytes)}"
return did_key


def did_key_to_naked(did_key: str) -> str:
"""Convert a did:key to naked ed25519 verkey format."""
stripped_key = did_key.split("did:key:z").pop()
stripped_key_bytes = b58_to_bytes(stripped_key)
naked_key_bytes = remove_prefix(stripped_key_bytes)
return bytes_to_b58(naked_key_bytes)
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ msgpack~=0.6.1
prompt_toolkit~=2.0.9
pynacl~=1.3.0
requests~=2.23.0
pyld==2.0.1
pyld==2.0.1
py_multicodec==0.2.1