Skip to content

Commit

Permalink
Merge pull request #1719 from sicpa-dlab/feature/key-derivation
Browse files Browse the repository at this point in the history
Allow specifying key derivation method on sub-wallet create
  • Loading branch information
swcurran authored Apr 15, 2022
2 parents d197887 + 45de356 commit ef8e258
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 28 deletions.
7 changes: 6 additions & 1 deletion aries_cloudagent/config/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@ def add_arguments(self, parser: ArgumentParser):
help=(
'Specify multitenancy configuration ("wallet_type" and "wallet_name"). '
'For example: "{"wallet_type":"askar-profile","wallet_name":'
'"askar-profile-name"}"'
'"askar-profile-name", "key_derivation_method":"RAW"}"'
'"wallet_name" is only used when "wallet_type" is "askar-profile"'
),
)
Expand Down Expand Up @@ -1668,6 +1668,11 @@ def get_settings(self, args: Namespace):
"wallet_name"
)

if multitenancyConfig.get("key_derivation_method"):
settings[
"multitenant.key_derivation_method"
] = multitenancyConfig.get("key_derivation_method")

return settings


Expand Down
26 changes: 17 additions & 9 deletions aries_cloudagent/multitenant/admin/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,23 @@
from aiohttp import web
from aiohttp_apispec import (
docs,
request_schema,
match_info_schema,
response_schema,
querystring_schema,
request_schema,
response_schema,
)
from marshmallow import fields, validate, validates_schema, ValidationError
from marshmallow import ValidationError, fields, validate, validates_schema

from ...admin.request_context import AdminRequestContext
from ...messaging.valid import JSONWebToken, UUIDFour
from ...core.error import BaseError
from ...core.profile import ProfileManagerProvider
from ...messaging.models.base import BaseModelError
from ...messaging.models.openapi import OpenAPISchema
from ...messaging.valid import JSONWebToken, UUIDFour
from ...multitenant.base import BaseMultitenantManager
from ...storage.error import StorageError, StorageNotFoundError
from ...wallet.models.wallet_record import WalletRecord, WalletRecordSchema
from ...wallet.error import WalletSettingsError

from ...core.error import BaseError
from ...core.profile import ProfileManagerProvider

from ...wallet.models.wallet_record import WalletRecord, WalletRecordSchema
from ..error import WalletKeyMissingError


Expand Down Expand Up @@ -58,6 +56,13 @@ class CreateWalletRequestSchema(OpenAPISchema):
description="Master key used for key derivation.", example="MySecretKey123"
)

wallet_key_derivation = fields.Str(
description="Key derivation",
required=False,
example="RAW",
validate=validate.OneOf(["ARGON2I_MOD", "ARGON2I_INT", "RAW"]),
)

wallet_type = fields.Str(
description="Type of the wallet to create",
example="indy",
Expand Down Expand Up @@ -303,10 +308,13 @@ async def wallet_create(request: web.BaseRequest):

label = body.get("label")
image_url = body.get("image_url")
key_derivation = body.get("wallet_key_derivation")
if label:
settings["default_label"] = label
if image_url:
settings["image_url"] = image_url
if key_derivation: # allow lower levels to handle default
settings["wallet.key_derivation_method"] = key_derivation

try:
multitenant_mgr = context.profile.inject(BaseMultitenantManager)
Expand Down
28 changes: 28 additions & 0 deletions aries_cloudagent/multitenant/admin/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ async def test_wallets_list_query(self):
async def test_wallet_create(self):
body = {
"wallet_name": "test",
"default_label": "test_label",
"wallet_type": "indy",
"wallet_key": "test",
"key_management_mode": "managed",
Expand Down Expand Up @@ -206,6 +207,7 @@ async def test_wallet_create_optional_default_fields(self):
body = {
"wallet_name": "test",
"wallet_key": "test",
"wallet_key_derivation": "ARGON2I_MOD",
"wallet_webhook_urls": [],
"wallet_dispatch_type": "base",
"label": "my_test_label",
Expand All @@ -227,6 +229,32 @@ async def test_wallet_create_optional_default_fields(self):
"image_url": body["image_url"],
"wallet.webhook_urls": body["wallet_webhook_urls"],
"wallet.dispatch_type": body["wallet_dispatch_type"],
"wallet.key_derivation_method": body["wallet_key_derivation"],
},
WalletRecord.MODE_MANAGED,
)

async def test_wallet_create_raw_key_derivation(self):
body = {
"wallet_name": "test",
"wallet_key": "test",
"wallet_key_derivation": "RAW",
}
self.request.json = async_mock.CoroutineMock(return_value=body)

with async_mock.patch.object(test_module.web, "json_response") as mock_response:
self.mock_multitenant_mgr.create_wallet = async_mock.CoroutineMock()
self.mock_multitenant_mgr.create_auth_token = async_mock.CoroutineMock()

await test_module.wallet_create(self.request)
self.mock_multitenant_mgr.create_wallet.assert_called_once_with(
{
"wallet.type": "in_memory",
"wallet.name": body["wallet_name"],
"wallet.key": body["wallet_key"],
"wallet.key_derivation_method": body["wallet_key_derivation"],
"wallet.webhook_urls": [],
"wallet.dispatch_type": "base",
},
WalletRecord.MODE_MANAGED,
)
Expand Down
39 changes: 21 additions & 18 deletions aries_cloudagent/multitenant/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,26 +184,29 @@ async def create_wallet(
)

await wallet_record.save(session)
try:
# provision wallet
profile = await self.get_wallet_profile(
self._profile.context,
wallet_record,
{
"wallet.key": wallet_key,
},
provision=True,
)

# provision wallet
profile = await self.get_wallet_profile(
self._profile.context,
wallet_record,
{
"wallet.key": wallet_key,
},
provision=True,
)

# subwallet context
async with profile.session() as session:
wallet = session.inject(BaseWallet)
public_did_info = await wallet.get_public_did()
# subwallet context
async with profile.session() as session:
wallet = session.inject(BaseWallet)
public_did_info = await wallet.get_public_did()

if public_did_info:
await self.add_key(
wallet_record.wallet_id, public_did_info.verkey, skip_if_exists=True
)
if public_did_info:
await self.add_key(
wallet_record.wallet_id, public_did_info.verkey, skip_if_exists=True
)
except Exception:
await wallet_record.delete_record(session)
raise

return wallet_record

Expand Down
5 changes: 5 additions & 0 deletions aries_cloudagent/wallet/models/wallet_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ def wallet_key(self) -> Optional[str]:
"""Accessor for the key of the wallet."""
return self.settings.get("wallet.key")

@property
def wallet_key_derivation_method(self):
"""Accessor for the key derivation method of the wallet."""
return self.settings.get("wallet.key_derivation_method")

@property
def record_value(self) -> dict:
"""Accessor for the JSON record value generated for this record."""
Expand Down

0 comments on commit ef8e258

Please sign in to comment.