Skip to content

Use did:key for recipient keys #1886

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

Merged
Merged
Changes from 27 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9a305de
fix: Switch from using Raw public keys to using DID Keys for Mediation
TheTechmage Jul 21, 2022
495584e
fix: Send keys back in did:key format during response
TheTechmage Jul 21, 2022
0975af6
fix: Fix the way routing DIDs are being created/sent
TheTechmage Jul 26, 2022
d0b19d9
fix: Reformat did during grant
TheTechmage Jul 26, 2022
7ff2c0c
Revert "fix: Reformat did during grant"
TheTechmage Jul 26, 2022
1ad866d
fix: Fix how Mediation Grant returns routing keys
TheTechmage Jul 27, 2022
4a0be00
chore: Fix unit tests
TheTechmage Jul 27, 2022
72921d1
feat: Add did:key conversions throughout mediation
TheTechmage Jul 27, 2022
f22af92
fix: Typos in variable names
TheTechmage Jul 27, 2022
4e5d589
fix: Convert from did:key to verkey when retrieving recipient
TheTechmage Jul 27, 2022
a66091a
chore: test
TheTechmage Jul 27, 2022
6460304
fix: Add RoutingKey validator
TheTechmage Aug 2, 2022
27cb777
fix: Decode recipient keys before packing message
TheTechmage Aug 2, 2022
707dad2
fix: Decode routing keys when making DIDDoc
TheTechmage Aug 2, 2022
5ed5247
fix: Fix typo in variable names
TheTechmage Aug 2, 2022
3ee7f43
fix: Fix unit tests after did:key work
TheTechmage Aug 3, 2022
e49c3c3
feat: Search for both route keys when getting recipients
TheTechmage Aug 4, 2022
e55ae7d
fix: Move backwards compat code to proper location & fix tests
TheTechmage Aug 4, 2022
a3ba4bf
fix: Fix invited not getting created/retrieved
TheTechmage Aug 4, 2022
578833c
revert: Changes to non-coordinate mediation related files
TheTechmage Aug 15, 2022
f696323
fix: Limit changes to the coordinate mediation protocol
TheTechmage Aug 15, 2022
3b4a781
Merge branch 'main' into fix/RFC-0211-Compliance
TheTechmage Aug 15, 2022
834bfb1
fix: Fix unit tests
TheTechmage Aug 16, 2022
d86f586
fix: Normalize recipient keys when updating routes
TheTechmage Aug 16, 2022
59640da
ci: Fix coordinate mediation tests
TheTechmage Aug 16, 2022
dc85e32
ci: Fix black formatting errors
TheTechmage Aug 16, 2022
00f4138
Merge remote-tracking branch 'origin/main' into fix/RFC-0211-Compliance
TheTechmage Aug 16, 2022
44c0022
Merge branch 'main' into fix/RFC-0211-Compliance
dbluhm Aug 19, 2022
87c64dc
chore: Reduce code duplication
TheTechmage Aug 22, 2022
fed721b
Merge branch 'fix/RFC-0211-Compliance' of github.com:frostyfrog/aries…
TheTechmage Aug 22, 2022
36f1230
chore: further reduce code duplication
TheTechmage Aug 22, 2022
c13cdf4
Merge branch 'main' into fix/RFC-0211-Compliance
dbluhm Aug 23, 2022
465a09b
Merge branch 'main' into fix/RFC-0211-Compliance
swcurran Aug 23, 2022
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
24 changes: 24 additions & 0 deletions aries_cloudagent/messaging/valid.py
Original file line number Diff line number Diff line change
@@ -349,6 +349,29 @@ def __init__(self):
)


class RoutingKey(Regexp):
"""
Validate between indy or did key.

Validate value against indy (Ed25519VerificationKey2018)
raw public key or DID key specification.
"""

EXAMPLE = DIDKey.EXAMPLE
PATTERN = re.compile(DIDKey.PATTERN.pattern + "|" + IndyRawPublicKey.PATTERN)

def __init__(self):
"""Initializer."""

super().__init__(
RoutingKey.PATTERN,
error=(
"Value {input} is not in W3C did:key"
" or Ed25519VerificationKey2018 key format"
),
)


class IndyCredDefId(Regexp):
"""Validate value against indy credential definition identifier specification."""

@@ -788,6 +811,7 @@ def __init__(
JWT = {"validate": JSONWebToken(), "example": JSONWebToken.EXAMPLE}
DID_KEY = {"validate": DIDKey(), "example": DIDKey.EXAMPLE}
DID_POSTURE = {"validate": DIDPosture(), "example": DIDPosture.EXAMPLE}
ROUTING_KEY = {"validate": RoutingKey(), "example": RoutingKey.EXAMPLE}
INDY_DID = {"validate": IndyDID(), "example": IndyDID.EXAMPLE}
GENERIC_DID = {"validate": MaybeIndyDID(), "example": MaybeIndyDID.EXAMPLE}
INDY_RAW_PUBLIC_KEY = {
41 changes: 23 additions & 18 deletions aries_cloudagent/multitenant/tests/test_route_manager.py
Original file line number Diff line number Diff line change
@@ -13,6 +13,11 @@
from ...storage.error import StorageNotFoundError
from ..route_manager import MultitenantRouteManager

TEST_RECORD_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"
TEST_VERKEY = "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL"
TEST_ROUTE_RECORD_VERKEY = "9WCgWKUaAJj3VWxxtzvvMQN3AoFxoBtBDo9ntwJnVVCC"
TEST_ROUTE_VERKEY = "did:key:z6MknxTj6Zj1VrDWc1ofaZtmCVv2zNXpD58Xup4ijDGoQhya"


@pytest.fixture
def wallet_id():
@@ -68,18 +73,18 @@ async def test_route_for_key_sub_mediator_no_base_mediator(
) as mock_create_route_record:
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
mediation_record,
skip_if_exists=False,
replace_key=None,
)

mock_create_route_record.assert_called_once_with(
recipient_key="test-recipient-key", internal_wallet_id=wallet_id
recipient_key=TEST_VERKEY, internal_wallet_id=wallet_id
)
assert keylist_update
assert keylist_update.serialize()["updates"] == [
{"action": "add", "recipient_key": "test-recipient-key"}
{"action": "add", "recipient_key": TEST_VERKEY}
]
assert mock_responder.messages
assert (
@@ -112,18 +117,18 @@ async def test_route_for_key_sub_mediator_and_base_mediator(
) as mock_create_route_record:
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
mediation_record,
skip_if_exists=False,
replace_key=None,
)

mock_create_route_record.assert_called_once_with(
recipient_key="test-recipient-key", internal_wallet_id=wallet_id
recipient_key=TEST_VERKEY, internal_wallet_id=wallet_id
)
assert keylist_update
assert keylist_update.serialize()["updates"] == [
{"action": "add", "recipient_key": "test-recipient-key"}
{"action": "add", "recipient_key": TEST_VERKEY}
]
assert mock_responder.messages
assert (
@@ -153,18 +158,18 @@ async def test_route_for_key_base_mediator_no_sub_mediator(
) as mock_create_route_record:
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
None,
skip_if_exists=False,
replace_key=None,
)

mock_create_route_record.assert_called_once_with(
recipient_key="test-recipient-key", internal_wallet_id=wallet_id
recipient_key=TEST_VERKEY, internal_wallet_id=wallet_id
)
assert keylist_update
assert keylist_update.serialize()["updates"] == [
{"action": "add", "recipient_key": "test-recipient-key"}
{"action": "add", "recipient_key": TEST_VERKEY}
]
assert mock_responder.messages
assert (
@@ -187,7 +192,7 @@ async def test_route_for_key_skip_if_exists_and_exists(
):
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
mediation_record,
skip_if_exists=True,
replace_key=None,
@@ -212,14 +217,14 @@ async def test_route_for_key_skip_if_exists_and_absent(
):
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
mediation_record,
skip_if_exists=True,
replace_key=None,
)
assert keylist_update
assert keylist_update.serialize()["updates"] == [
{"action": "add", "recipient_key": "test-recipient-key"}
{"action": "add", "recipient_key": TEST_VERKEY}
]
assert mock_responder.messages
assert (
@@ -239,15 +244,15 @@ async def test_route_for_key_replace_key(
)
keylist_update = await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
mediation_record,
skip_if_exists=False,
replace_key="test-replace-key",
replace_key=TEST_ROUTE_VERKEY,
)
assert keylist_update
assert keylist_update.serialize()["updates"] == [
{"action": "add", "recipient_key": "test-recipient-key"},
{"action": "remove", "recipient_key": "test-replace-key"},
{"action": "add", "recipient_key": TEST_VERKEY},
{"action": "remove", "recipient_key": TEST_ROUTE_VERKEY},
]
assert mock_responder.messages
assert (
@@ -264,10 +269,10 @@ async def test_route_for_key_no_mediator(
assert (
await route_manager._route_for_key(
sub_profile,
"test-recipient-key",
TEST_VERKEY,
None,
skip_if_exists=True,
replace_key="test-replace-key",
replace_key=TEST_ROUTE_VERKEY,
)
is None
)
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@

TEST_CONN_ID = "conn-id"
TEST_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"
TEST_VERKEY_DIDKEY = "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL"


class TestKeylistQueryHandler(AsyncTestCase):
@@ -77,4 +78,4 @@ async def test_handler(self):
result, _target = responder.messages[0]
assert isinstance(result, Keylist)
assert len(result.keys) == 1
assert result.keys[0].recipient_key == TEST_VERKEY
assert result.keys[0].recipient_key == TEST_VERKEY_DIDKEY
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@
from .. import mediation_grant_handler as test_module

TEST_CONN_ID = "conn-id"
TEST_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"
TEST_RECORD_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"
TEST_VERKEY = "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL"
TEST_ENDPOINT = "https://example.com"


@@ -58,7 +59,7 @@ async def test_handler(self):
assert record
assert record.state == MediationRecord.STATE_GRANTED
assert record.endpoint == TEST_ENDPOINT
assert record.routing_keys == [TEST_VERKEY]
assert record.routing_keys == [TEST_RECORD_VERKEY]

async def test_handler_connection_has_set_to_default_meta(self):
handler, responder = MediationGrantHandler(), MockResponder()
20 changes: 18 additions & 2 deletions aries_cloudagent/protocols/coordinate_mediation/v1_0/manager.py
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@

from ....core.error import BaseError
from ....core.profile import Profile, ProfileSession
from ....did.did_key import DIDKey
from ....storage.base import BaseStorage
from ....storage.error import StorageNotFoundError
from ....storage.record import StorageRecord
@@ -248,9 +249,16 @@ async def update_keylist(
RouteUpdate.ACTION_CREATE: KeylistUpdateRule.RULE_ADD,
}

def normalize_public_key(key: str):
if key.startswith("did:key:"):
return DIDKey.from_did(key).public_key_b58

return key

def rule_to_update(rule: KeylistUpdateRule):
recipient_key = normalize_public_key(rule.recipient_key)
return RouteUpdate(
recipient_key=rule.recipient_key, action=action_map[rule.action]
recipient_key=recipient_key, action=action_map[rule.action]
)

def updated_to_keylist_updated(updated: RouteUpdated):
@@ -445,7 +453,15 @@ async def request_granted(self, record: MediationRecord, grant: MediationGrant):
"""
record.state = MediationRecord.STATE_GRANTED
record.endpoint = grant.endpoint
record.routing_keys = grant.routing_keys
# record.routing_keys = grant.routing_keys
routing_keys = []
for key in grant.routing_keys:
routing_keys.append(
DIDKey.from_did(key).public_key_b58
if key.startswith("did:key:")
else key
)
record.routing_keys = routing_keys
async with self._profile.session() as session:
await record.save(session, reason="Mediation request granted.")

Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@
from marshmallow import EXCLUDE, fields

from ......messaging.models.base import BaseModel, BaseModelSchema
from ......messaging.valid import INDY_RAW_PUBLIC_KEY
from ......messaging.valid import DID_KEY
from ......did.did_key import DIDKey
from ......wallet.key_type import KeyType


class KeylistKey(BaseModel):
@@ -32,7 +34,12 @@ def __init__(

"""
super().__init__(**kwargs)
self.recipient_key = recipient_key
if recipient_key.startswith("did:key:"):
self.recipient_key = recipient_key
else:
self.recipient_key = DIDKey.from_public_key_b58(
recipient_key, KeyType.ED25519
).did


class KeylistKeySchema(BaseModelSchema):
@@ -44,4 +51,4 @@ class Meta:
model_class = KeylistKey
unknown = EXCLUDE

recipient_key = fields.Str(required=True, **INDY_RAW_PUBLIC_KEY)
recipient_key = fields.Str(required=True, **DID_KEY)
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@
from marshmallow.validate import OneOf

from ......messaging.models.base import BaseModel, BaseModelSchema
from ......messaging.valid import INDY_RAW_PUBLIC_KEY
from ......messaging.valid import ROUTING_KEY
from ......did.did_key import DIDKey
from ......wallet.key_type import KeyType


class KeylistUpdateRule(BaseModel):
@@ -32,7 +34,12 @@ def __init__(self, recipient_key: str, action: str, **kwargs):

"""
super().__init__(**kwargs)
self.recipient_key = recipient_key
if recipient_key.startswith("did:key:"):
self.recipient_key = recipient_key
else:
self.recipient_key = DIDKey.from_public_key_b58(
recipient_key, KeyType.ED25519
).did
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps a helper method similar to the normalize_public_key method would be good since we perform this normalization several times throughout the messages.inner package.

self.action = action


@@ -45,7 +52,7 @@ class Meta:
model_class = KeylistUpdateRule

recipient_key = fields.Str(
description="Key to remove or add", required=True, **INDY_RAW_PUBLIC_KEY
description="Key to remove or add", required=True, **ROUTING_KEY
)
action = fields.Str(
required=True,
Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@
from marshmallow import EXCLUDE, fields

from ......messaging.models.base import BaseModel, BaseModelSchema
from ......messaging.valid import INDY_RAW_PUBLIC_KEY
from ......messaging.valid import DID_KEY
from ......did.did_key import DIDKey
from ......wallet.key_type import KeyType


class KeylistUpdated(BaseModel):
@@ -40,7 +42,12 @@ def __init__(

"""
super().__init__(**kwargs)
self.recipient_key = recipient_key
if recipient_key.startswith("did:key:"):
self.recipient_key = recipient_key
else:
self.recipient_key = DIDKey.from_public_key_b58(
recipient_key, KeyType.ED25519
).did
self.action = action
self.result = result

@@ -54,6 +61,6 @@ class Meta:
model_class = KeylistUpdated
unknown = EXCLUDE

recipient_key = fields.Str(required=True, **INDY_RAW_PUBLIC_KEY)
recipient_key = fields.Str(required=True, **DID_KEY)
action = fields.Str(required=True)
result = fields.Str(required=True)
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
from marshmallow import fields

from .....messaging.agent_message import AgentMessage, AgentMessageSchema
from .....did.did_key import DIDKey
from .....wallet.key_type import KeyType
from ..message_types import MEDIATE_GRANT, PROTOCOL_PACKAGE

HANDLER_CLASS = (
@@ -41,7 +43,18 @@ def __init__(
"""
super(MediationGrant, self).__init__(**kwargs)
self.endpoint = endpoint
self.routing_keys = list(routing_keys) if routing_keys else []
self.routing_keys = (
list(
(
key
if key.startswith("did:key:")
else DIDKey.from_public_key_b58(key, KeyType.ED25519).did
)
for key in routing_keys
)
if routing_keys
else []
)


class MediationGrantSchema(AgentMessageSchema):
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ class TestKeylist(MessageTest, TestCase):
"pagination": KeylistQueryPaginate(10, 10),
"keys": [
KeylistKey(
recipient_key="3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx",
recipient_key="did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
action="added",
result="success",
)
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ class TestKeylistUpdate(MessageTest, TestCase):
SCHEMA = KeylistUpdateSchema
VALUES = {
"updates": [
KeylistUpdateRule("3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx", "add")
KeylistUpdateRule(
"did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", "add"
)
]
}
Loading