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

Creating askar subwallet with wallet_key_derivation creates broken wallet #2682

Closed
jamshale opened this issue Dec 18, 2023 · 7 comments
Closed
Assignees

Comments

@jamshale
Copy link
Contributor

If you create a subwallet with POST multitenancy/wallet by changing the type from indy to askar with the wallet_key_derivation param which is in the sample payload it will get a ProfileSessionUnavailable error. However, the wallet is still created, but in a broken state. Any call to the api with the created token will receive a 500 error.

I beleive this option shouldn't be used with an askar wallet?

The request for an askar wallet with this parameter included should be prevented and the swagger docs should be updated to have a valid payload for an askar wallet instead of indy.

@jamshale jamshale self-assigned this Dec 18, 2023
@swcurran
Copy link
Member

@andrewwhitehead ^^^

@jamshale
Copy link
Contributor Author

Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/askar/store.py", line 154, in open_store
    store = await Store.open(
  File "/usr/local/lib/python3.9/site-packages/aries_askar/store.py", line 352, in open
    return Store(await bindings.store_open(uri, key_method, pass_key, profile), uri)
  File "/usr/local/lib/python3.9/site-packages/aries_askar/bindings/__init__.py", line 84, in store_open
    return await invoke_async(
  File "/usr/local/lib/python3.9/site-packages/aries_askar/bindings/lib.py", line 362, in invoke_async
    return await self.loaded.invoke_async(
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
aries_askar.error.AskarError: Error fetching store configuration
Caused by: error returned from database: (code: 1) no such table: config

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 181, in ready_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 218, in debug_middleware
    return await handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 386, in check_multitenant_authorization
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 404, in setup_context
    profile = await self.multitenant_manager.get_profile_for_token(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/multitenant/base.py", line 380, in get_profile_for_token
    profile = await self.get_wallet_profile(context, wallet, extra_settings)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/multitenant/manager.py", line 83, in get_wallet_profile
    profile, _ = await wallet_config(context, provision=provision)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/config/wallet.py", line 54, in wallet_config
    profile = await mgr.open(context, profile_cfg)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/askar/profile.py", line 297, in open
    opened = await store_config.open_store(provision=False)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/askar/store.py", line 168, in open_store
    raise ProfileError("Error opening store") from err
aries_cloudagent.core.error.ProfileError: Error opening store

Error that happens when using token from broken wallet ^

@Ennovate-com
Copy link
Contributor

Ennovate-com commented Dec 20, 2023

The request for an askar wallet with this parameter included should be prevented and the swagger docs should be updated to have a valid payload for an askar wallet instead of indy.

For me, it works OK when the wallet_type is askar, using the sample payload below, at least when the base wallet is askar. I removed the image_url and wallet_webhook_urls items from the payload and changed the wallet_type to askar.

{
  "extra_settings": {},
  "key_management_mode": "managed",
  "label": "Alice",
  "wallet_dispatch_type": "default",
  "wallet_key": "MySecretKey123",
  "wallet_key_derivation": "RAW",
  "wallet_name": "MyNewWallet",
  "wallet_type": "askar"
}

Response: Code 200

{
  "created_at": "2023-12-20T14:58:32.177580Z",
  "updated_at": "2023-12-20T14:58:32.196825Z",
  "wallet_id": "758add5f-3094-4b7f-a3f9-dbf2be02566a",
  "key_management_mode": "managed",
  "settings": {
    "wallet.type": "askar",
    "wallet.name": "MyNewWallet",
    "wallet.webhook_urls": [],
    "wallet.dispatch_type": "base",
    "default_label": "Alice",
    "wallet.key_derivation_method": "RAW",
    "wallet.id": "758add5f-3094-4b7f-a3f9-dbf2be02566a"
  },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRfaWQiOiI3NThhZGQ1Zi0zMDk0LTRiN2YtYTNmOS1kYmYyYmUwMjU2NmEiLCJpYXQiOjE3MDMwODQzMTJ9.mbihtMFdbH_MzZat0pAOa9jqjazpwzfxqbhQWBcUDxk"
}

The resulting subwallets work fine.

I am a bit confused by the part in the OP saying that the subwallet type was specified by changing the type from indy to askar with the wallet_key_derivation param .... The subwallet type is specified with the wallet_type parameter, not the wallet_key_derivation parameter. So I left the wallet_key_derivation parameter as RAW and did not change it to askar.

It looks like when the base wallet is indy and the subwallet is askar, it might be trying to access the base wallet as an askar wallet, rather than as an indy wallet as it should.

I'm not sure if the wallet_key_derivation parameter is ignored in my test case above nor whether including that parameter in the payload or giving it a bad value (ex: askar, as suggested by the OP, instead of RAW, ARGON2I_MOD or ARGON2I_INT) when the subwallet type is not the same as the base wallet type might be what causes it to access the base wallet using the wrong wallet type.

I also wonder if there are any tests which cover the case where an askar subwallet is being created with an indy base wallet or an indy subwallet is being created with an askar base wallet. If not, and those are supported configurations, those tests should probably be added - initially xfailed until the issue is fixed. I don't have the Indy module installed - running all tests gives me the message Skipping Indy-specific tests: python3-indy module not installed. - so I can't easily tell if there are already any xfailed tests for those cases.

@jamshale
Copy link
Contributor Author

jamshale commented Dec 20, 2023

Hi. To add clarification. My subwallet is failing with the same payload you posted.

{
"extra_settings": {},
"key_management_mode": "managed",
"label": "Alice",
"wallet_dispatch_type": "default",
"wallet_key": "MySecretKey123",
"wallet_key_derivation": "RAW",
"wallet_name": "MyNewWallet",
"wallet_type": "askar"
}

It works fine if I have the payload without the wallet_key_derivation param such as.

{
"extra_settings": {},
"key_management_mode": "managed",
"label": "Alice",
"wallet_dispatch_type": "default",
"wallet_key": "MySecretKey123",
"wallet_name": "MyNewWallet2",
"wallet_type": "askar"
}

I'm not sure what's going on. Possibly it's an environment issue. It's happening for me with faber demo and when I launch from vscode. I don't seem to have any other issues.

@jamshale
Copy link
Contributor Author

jamshale commented Jan 2, 2024

Was looking at this again and the error is still happening for me from the faber demo with the payload

{
"extra_settings": {},
"key_management_mode": "managed",
"label": "Alice",
"wallet_dispatch_type": "default",
"wallet_key": "MySecretKey123",
"wallet_key_derivation": "RAW",
"wallet_name": "MyNewWallet",
"wallet_type": "askar"
}

but I could see an exception aries_askar.error.AskarError: Incorrect length for encoded raw key I hadn't noticed before.

Not sure if anyone has any insight into why this might be happening for me?

I'll keep this open for now and see if I can figure anything else out, but I'm not sure how I could be doing anything wrong to cause this.

@swcurran swcurran assigned andrewwhitehead and unassigned jamshale Jan 3, 2024
@andrewwhitehead
Copy link
Member

The default wallet key derivation uses Argon2 to calculate the raw key, a method which is meant to be resistant to brute force attacks on weak passwords. When using the RAW key derivation method, the key is not run through Argon2: it must be the 32-byte wallet decryption key itself, encoded in base58. In Python, new random keys can be generated with aries_askar.Store.generate_raw_key() (for example, 7j7sgqeEG2MmheN9SivEqUFaKhXhzAZbqS6cmmeRKvhU).

It seems like in this case when the key derivation method is provided when creating the subwallet, it is either ignored during the creation process, or a random key is being used instead of the provided key (because the provided key is not in the right format). I think that ideally, if the key derivation method is set to RAW, then the key should not be provided at all, and a random key should be generated and stored in the root wallet instead. If a key is provided, then it must be a valid RAW key.

@jamshale
Copy link
Contributor Author

Going to close. If we want to generate a random key it can be brought up in a new ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants