Skip to content

Commit 153620f

Browse files
authored
Merge pull request #51 from sicpa-dlab/main
Release 0.3.0
2 parents 1b359fc + 9558660 commit 153620f

8 files changed

Lines changed: 152 additions & 17 deletions

File tree

didcomm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.0"
1+
__version__ = "0.3.0"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from didcomm.common.resolvers import ResolversConfig
2+
from didcomm.common.types import DID_OR_DID_URL
3+
from didcomm.core.utils import is_did_url
4+
5+
6+
async def has_keys_for_forward_next(
7+
_next: DID_OR_DID_URL, resolvers_config: ResolversConfig
8+
) -> bool:
9+
if is_did_url(_next):
10+
next_kids = [_next]
11+
else:
12+
next_did_doc = await resolvers_config.did_resolver.resolve(_next)
13+
if next_did_doc is None:
14+
return False
15+
next_kids = next_did_doc.key_agreement_kids
16+
17+
secret_ids = await resolvers_config.secrets_resolver.get_keys(next_kids)
18+
return len(secret_ids) > 0

didcomm/unpack.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
from dataclasses import dataclass
44
from typing import Optional, List, Union
55

6-
from authlib.common.encoding import to_unicode, to_bytes
6+
from authlib.common.encoding import to_unicode
77

88
from didcomm.common.algorithms import AnonCryptAlg, AuthCryptAlg, SignAlg
99
from didcomm.common.resolvers import ResolversConfig
1010
from didcomm.common.types import JWS, JSON, JSON_OBJ, DID_URL
1111
from didcomm.core.anoncrypt import unpack_anoncrypt, is_anoncrypted
1212
from didcomm.core.authcrypt import is_authcrypted, unpack_authcrypt
13+
from didcomm.core.from_prior import unpack_from_prior_in_place
14+
from didcomm.core.keys.forward_next_keys_selector import has_keys_for_forward_next
1315
from didcomm.core.serialization import (
1416
json_bytes_to_dict,
1517
json_str_to_dict,
1618
dict_to_json_bytes,
1719
)
1820
from didcomm.core.sign import is_signed, unpack_sign
1921
from didcomm.errors import DIDCommValueError
20-
from didcomm.core.from_prior import unpack_from_prior_in_place
2122
from didcomm.message import Message
2223
from didcomm.protocols.routing.forward import is_forward, ForwardMessage
2324

@@ -44,11 +45,9 @@ async def unpack(
4445
unpack_config = unpack_config or UnpackConfig()
4546

4647
if isinstance(packed_msg, str):
47-
msg = to_bytes(packed_msg)
48-
msg_as_dict = json_str_to_dict(packed_msg)
48+
packed_msg = json_str_to_dict(packed_msg)
4949
elif isinstance(packed_msg, dict):
50-
msg = dict_to_json_bytes(packed_msg)
51-
msg_as_dict = packed_msg
50+
pass
5251
else:
5352
# FIXME in python it should be a kind of TypeError instead
5453
raise DIDCommValueError(
@@ -62,6 +61,18 @@ async def unpack(
6261
anonymous_sender=False,
6362
)
6463

64+
return await _do_unpack(resolvers_config, packed_msg, unpack_config, metadata)
65+
66+
67+
async def _do_unpack(
68+
resolvers_config: ResolversConfig,
69+
packed_msg: JSON_OBJ,
70+
unpack_config: UnpackConfig,
71+
metadata: Metadata,
72+
) -> UnpackResult:
73+
msg = dict_to_json_bytes(packed_msg)
74+
msg_as_dict = packed_msg
75+
6576
if is_anoncrypted(msg_as_dict):
6677
unwrap_anoncrypt_result = await unpack_anoncrypt(
6778
msg_as_dict,
@@ -76,11 +87,13 @@ async def unpack(
7687
metadata.encrypted_to = unwrap_anoncrypt_result.to_kids
7788
metadata.enc_alg_anon = unwrap_anoncrypt_result.alg
7889

79-
if is_forward(msg_as_dict) and unpack_config.unwrap_re_wrapping_forward:
90+
if unpack_config.unwrap_re_wrapping_forward and is_forward(msg_as_dict):
8091
fwd_msg = ForwardMessage.from_json(msg)
81-
msg_as_dict = fwd_msg.forwarded_msg
82-
msg = dict_to_json_bytes(msg_as_dict)
83-
metadata.re_wrapped_in_forward = True
92+
if await has_keys_for_forward_next(fwd_msg.body.next, resolvers_config):
93+
metadata.re_wrapped_in_forward = True
94+
return await _do_unpack(
95+
resolvers_config, fwd_msg.forwarded_msg, unpack_config, metadata
96+
)
8497

8598
if is_authcrypted(msg_as_dict):
8699
unwrap_authcrypt_result = await unpack_authcrypt(

docs/release.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Release
2+
3+
Assumptions:
4+
5+
* `main` branch can wait until release PR is merged
6+
7+
The steps:
8+
9+
1. **release**:
10+
1. **review adjust if needed the release version in `main`** to match the changes from the latest release following the [SemVer rules](https://semver.org/#summary).
11+
2. [create](https://github.com/sicpa-dlab/didcomm-python/compare/stable...main) a **PR from `main` to `stable`** (you may likely want to name it as `release-<version>`)
12+
3. once merged [release pipeline](https://github.com/sicpa-dlab/didcomm-python/actions/workflows/release.yml) will publish the release to [PyPI](https://pypi.org/project/didcomm)
13+
2. **bump next release version in `main`**
14+
* **Note** decision about the next release version should be based on the same [SemVer](https://semver.org/) rules and the expected changes. Usually it would be either a MINOR or MAJOR (if incompatible changes are planned) release.

tests/test_vectors/did_doc/did_doc_charlie.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
{
3838
"kty": "OKP",
3939
"crv": "Ed25519",
40-
"x": "G-boxFB6vOZBu-wXkm-9Lh79I8nf9Z50cILaOgKKGww",
40+
"x": "VDXDwuGKVq91zxU6q7__jLDUq8_C5cuxECgd-1feFTE",
4141
}
4242
),
4343
),

tests/test_vectors/secrets/mock_secrets_resolver_charlie.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
value=json_dumps(
3333
{
3434
"kty": "OKP",
35-
"d": "pFRUKkyzx4kHdJtFSnlPA9WzqkDT1HWV0xZ5OYZd2SY",
35+
"d": "T2azVap7CYD_kB8ilbnFYqwwYb5N-GcD6yjGEvquZXg",
3636
"crv": "Ed25519",
37-
"x": "G-boxFB6vOZBu-wXkm-9Lh79I8nf9Z50cILaOgKKGww",
37+
"x": "VDXDwuGKVq91zxU6q7__jLDUq8_C5cuxECgd-1feFTE",
3838
}
3939
),
4040
),

tests/unit/unpack/test_unpack_forward.py

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,60 @@
33
from didcomm.core.serialization import dict_to_json
44
from didcomm.message import Message
55
from didcomm.pack_encrypted import pack_encrypted
6-
from didcomm.protocols.routing.forward import unpack_forward, wrap_in_forward
6+
from didcomm.protocols.routing.forward import (
7+
unpack_forward,
8+
wrap_in_forward,
9+
ForwardMessage,
10+
is_forward,
11+
)
712
from didcomm.unpack import unpack, UnpackConfig
813
from tests.test_vectors.common import ALICE_DID, BOB_DID
914

1015

1116
@pytest.mark.asyncio
12-
async def test_mediator_re_wrap_to_receiver(
17+
async def test_mediator_re_wrap_anoncrypt_to_receiver(
18+
resolvers_config_alice, resolvers_config_bob, resolvers_config_mediator1
19+
):
20+
# ALICE
21+
message = Message(
22+
body={"aaa": 1, "bbb": 2},
23+
id="1234567890",
24+
type="my-protocol/1.0",
25+
to=[BOB_DID],
26+
created_time=1516269022,
27+
expires_time=1516385931,
28+
)
29+
pack_result = await pack_encrypted(
30+
resolvers_config=resolvers_config_alice,
31+
message=message,
32+
to=BOB_DID,
33+
)
34+
35+
# BOB MEDIATOR 1: re-wrap to Bob
36+
old_forward_bob = await unpack_forward(
37+
resolvers_config_mediator1, pack_result.packed_msg, True
38+
)
39+
new_packed_forward_bob = await wrap_in_forward(
40+
resolvers_config=resolvers_config_mediator1,
41+
packed_msg=old_forward_bob.forwarded_msg,
42+
to=old_forward_bob.forward_msg.body.next,
43+
routing_keys=[old_forward_bob.forward_msg.body.next],
44+
headers={"expires_time": 99999},
45+
)
46+
47+
# BOB
48+
unpack_result_bob = await unpack(
49+
resolvers_config_bob,
50+
dict_to_json(new_packed_forward_bob.msg_encrypted.msg),
51+
unpack_config=UnpackConfig(unwrap_re_wrapping_forward=True),
52+
)
53+
54+
assert unpack_result_bob.message == message
55+
assert unpack_result_bob.metadata.re_wrapped_in_forward
56+
57+
58+
@pytest.mark.asyncio
59+
async def test_mediator_re_wrap_authcrypt_to_receiver(
1360
resolvers_config_alice, resolvers_config_bob, resolvers_config_mediator1
1461
):
1562
# ALICE
@@ -50,3 +97,46 @@ async def test_mediator_re_wrap_to_receiver(
5097

5198
assert unpack_result_bob.message == message
5299
assert unpack_result_bob.metadata.re_wrapped_in_forward
100+
101+
102+
@pytest.mark.asyncio
103+
async def test_unwrap_re_wrapping_forward_mode_for_no_re_wrapping(
104+
resolvers_config_alice, resolvers_config_bob, resolvers_config_mediator1
105+
):
106+
# ALICE
107+
message = Message(
108+
body={"aaa": 1, "bbb": 2},
109+
id="1234567890",
110+
type="my-protocol/1.0",
111+
to=[BOB_DID],
112+
created_time=1516269022,
113+
expires_time=1516385931,
114+
)
115+
pack_result = await pack_encrypted(
116+
resolvers_config=resolvers_config_alice,
117+
message=message,
118+
to=BOB_DID,
119+
)
120+
121+
# BOB MEDIATOR 1
122+
unpack_result_mediator = await unpack(
123+
resolvers_config_mediator1,
124+
pack_result.packed_msg,
125+
unpack_config=UnpackConfig(unwrap_re_wrapping_forward=True),
126+
)
127+
128+
msg_mediator_as_dict = unpack_result_mediator.message.as_dict()
129+
assert is_forward(msg_mediator_as_dict)
130+
forward_message = ForwardMessage.from_dict(msg_mediator_as_dict)
131+
assert forward_message.body.next == BOB_DID
132+
assert not unpack_result_mediator.metadata.re_wrapped_in_forward
133+
134+
# BOB
135+
unpack_result_bob = await unpack(
136+
resolvers_config_bob,
137+
forward_message.forwarded_msg,
138+
unpack_config=UnpackConfig(unwrap_re_wrapping_forward=True),
139+
)
140+
141+
assert unpack_result_bob.message == message
142+
assert not unpack_result_bob.metadata.re_wrapped_in_forward

tests/unit/unpack/test_unpack_plaintext_with_from_prior.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"to": ["did:example:bob"],
1515
"created_time": 1516269022,
1616
"expires_time": 1516385931,
17-
"from_prior": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpleGFtcGxlOmNoYXJsaWUja2V5LTEifQ.eyJpc3MiOiJkaWQ6ZXhhbXBsZTpjaGFybGllIiwic3ViIjoiZGlkOmV4YW1wbGU6YWxpY2UiLCJhdWQiOiIxMjMiLCJleHAiOjEyMzQsIm5iZiI6MTIzNDUsImlhdCI6MTIzNDU2LCJqdGkiOiJkZmcifQ.9F1o6duu_lC6LTZN-RN3R6uUl_p63ma30i8nNu2xoCmOc-lE9G1z1-iZ2jZ81kFmq5aOMyhcVXat6TOGJdcVDA",
17+
"from_prior": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6ImRpZDpleGFtcGxlOmNoYXJsaWUja2V5LTEifQ.eyJpc3MiOiJkaWQ6ZXhhbXBsZTpjaGFybGllIiwic3ViIjoiZGlkOmV4YW1wbGU6YWxpY2UiLCJhdWQiOiIxMjMiLCJleHAiOjEyMzQsIm5iZiI6MTIzNDUsImlhdCI6MTIzNDU2LCJqdGkiOiJkZmcifQ.xIdfOLizPZMOZPAqMatEuBk0OrVge6jN1nxYlWUISz0XUXdW6TbwDbMgTinx2CLxtxev_gqEuZw5c98E3-eaAQ",
1818
"body": {"messagespecificattribute": "and its value"},
1919
}
2020
)

0 commit comments

Comments
 (0)