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

Add Diffie-Hellman key exchange for encryption to Account #809

Merged
merged 39 commits into from Jun 6, 2022

Conversation

HenriqueNogara
Copy link
Contributor

@HenriqueNogara HenriqueNogara commented Apr 12, 2022

Description of change

Add Diffie-Hellman key exchange to Account

Links to any relevant issues

closes #756

Type of change

  • Bug fix (a non-breaking change which fixes an issue)
  • Enhancement (a non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Fix

How the change has been tested

New key_exchange example.

Change checklist

  • I have followed the contribution guidelines for this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@HenriqueNogara HenriqueNogara added Enhancement New feature or improvement to an existing feature Wasm Related to Wasm bindings. Becomes part of the Wasm changelog Breaking change A change to the API that requires a major release. Part of "Changed" section in changelog Rust Related to the core Rust code. Becomes part of the Rust changelog. labels Apr 13, 2022
@HenriqueNogara HenriqueNogara marked this pull request as ready for review April 13, 2022 12:52
@HenriqueNogara HenriqueNogara changed the title Feat/dh key exchange Add Diffie-Hellman key exchange to Account Apr 13, 2022
Copy link
Contributor

@cycraig cycraig left a comment

Choose a reason for hiding this comment

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

Preliminary review: I think we need to remove key_exchange (from the Storage interface) and move the Diffie-Hellman operation into the encrypt/decrypt functions. We also need to be more explicit about which encryption algorithm is to be used in both Account and Storage. Lastly, we need to support the A256KW key wrapping algorithm for ECDH-1PU required by DIDComm.

See:

identity-account-storage/src/storage/stronghold.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/traits.rs Outdated Show resolved Hide resolved
identity-account/src/account/account.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/stronghold.rs Outdated Show resolved Hide resolved
identity-account/src/types/encryption_key.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@cycraig cycraig left a comment

Choose a reason for hiding this comment

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

I'm not sure how useful this is until we get support for key wrapping and key concatenation in Stronghold:

We can only really support ECDH-ES with no key wrapping right now.

identity-account-storage/src/storage/stronghold.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/stronghold.rs Outdated Show resolved Hide resolved
identity-account-storage/src/types/encryption_algorithm.rs Outdated Show resolved Hide resolved
@olivereanderson
Copy link
Contributor

olivereanderson commented May 16, 2022

Users can always generate the ephemeral key themselves, and we could perhaps support inputting a pre-generated keypair then. That would also sufficiently address the use-case of using a single epk with multiple recipients.

Supporting a pre-generated keypair (as an Option) sounds like a really sensible thing to do!

Overall the Account should focus on providing necessary cryptographic functionality for DID/DIDComm operations, not scope-creep to become a generic key management system.

Agreed.

@@ -4,6 +4,7 @@ import { stronghold } from '../stronghold';
// Only verifies that no uncaught exceptions are thrown, including syntax errors etc.
describe("Test Stronghold Node.js examples", function () {
it("Multiple Identities", async () => {
await multipleIdentities(await stronghold());
// TODO: Temporarily disabled until iotaledger/stronghold.rs#353 is fixed.
Copy link
Collaborator

Choose a reason for hiding this comment

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

should be okay again after a merging dev

Copy link
Contributor

Choose a reason for hiding this comment

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

To clarify, it's disabled on dev too.

Copy link
Contributor

Choose a reason for hiding this comment

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

And it will be for a while, it looks like 😕: iotaledger/stronghold.rs#353 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use an async RwLock over the Stronghold storage implementation to prevent this bug in the meantime then?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we can, but this issue is supposed to be prioritized now, so perhaps @felsweg-iota can give an update on the current status.

Choose a reason for hiding this comment

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

The current problem with the implementation of the standard interface to Stronghold is, that it internally uses a std::sync::RwLock, since every function in the interface isn't supposed to be async. This actually brings in a problem while working with async code.

There are two solutions to this, and i am just naming them here for reference, @PhilippGackstatter already pointed out the link to the issue:

  • we either change the current standard library locking mechanism to their async counterparts, which will effectively change the interface to operate as pseudo-async,
  • the STM based approach will be finalized and will replace all existing locks.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I'd prefer if we try the RwLock solution in our code to fix it temporarily (if that works), and that could avoid you having to do temporary work if the STM will eventually be the proper solution.

Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks pretty good. The MemStore modifications need some changes. Other than that mostly quality of life stuff, docs, typos, etc. To solve the tuple problem in Wasm, I think you can just make the ephemeral public key part of EncryptedData.

Not sure about the naming, i.e. EcdhEs vs. ECDH_ES, but if it's not too much work to change, I'd prefer the latter, and we can just follow JWA naming in the future, preventing further naming debates 😛.

Edit: Extending the StorageTestSuite is probably the most important outstanding part so both MemStore and Stronghold are tested, ideally in Rust and Wasm.

examples/account/encryption.rs Outdated Show resolved Hide resolved
examples/account/encryption.rs Outdated Show resolved Hide resolved
examples/account/encryption.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/memstore.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/memstore.rs Outdated Show resolved Hide resolved
bindings/wasm/src/account/types/encryption_algorithm.rs Outdated Show resolved Hide resolved
identity-account-storage/src/types/encrypted_data.rs Outdated Show resolved Hide resolved
bindings/wasm/src/account/types/cek_algorithm.rs Outdated Show resolved Hide resolved
bindings/wasm/examples-account/src/node.ts Outdated Show resolved Hide resolved
bindings/stronghold-nodejs/package.json Outdated Show resolved Hide resolved
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Great work, thanks for addressing all the previous comments so thoroughly!

A few more minor comments.

bindings/wasm/src/account/storage/traits.rs Outdated Show resolved Hide resolved
identity-account-storage/src/storage/stronghold.rs Outdated Show resolved Hide resolved
identity/Cargo.toml Outdated Show resolved Hide resolved
@PhilippGackstatter
Copy link
Contributor

One more thing: The StorageTestSuite::encryption test should also be exposed in Wasm (wasm/src/account/storage/test_suite.rs), and called in stronghold-nodejs/examples/src/tests/storage_test_suite.ts.

I'm fine with not implementing the encryption functions for the TS MemStore because that seems non-trivial to do without exposing all the primitives from the Rust library, and I'd rather get this PR merged soon. Realistically, this means it won't be implemented in the TS MemStore for quite a while.

Copy link
Contributor

@cycraig cycraig left a comment

Choose a reason for hiding this comment

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

Great to see how far this PR has come.

Most issues have already been addressed, minor comments.

bindings/stronghold-nodejs/js/stronghold.ts Outdated Show resolved Hide resolved
bindings/wasm/examples-account/src/encryption.ts Outdated Show resolved Hide resolved
bindings/wasm/examples-account/src/encryption.ts Outdated Show resolved Hide resolved
identity-account/src/account/account.rs Outdated Show resolved Hide resolved
identity-account/src/account/account.rs Outdated Show resolved Hide resolved
@HenriqueNogara HenriqueNogara merged commit 9176761 into dev Jun 6, 2022
@HenriqueNogara HenriqueNogara deleted the feat/dh-key-exchange branch June 6, 2022 01:51
@cycraig cycraig changed the title Add Diffie-Hellman key exchange to Account Add Diffie-Hellman key exchange for encryption to Account Jun 7, 2022
@cycraig cycraig mentioned this pull request Jun 13, 2022
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking change A change to the API that requires a major release. Part of "Changed" section in changelog Enhancement New feature or improvement to an existing feature Rust Related to the core Rust code. Becomes part of the Rust changelog. Wasm Related to Wasm bindings. Becomes part of the Wasm changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Task] Add Diffie-Hellman key exchange to Account
6 participants