Skip to content

feat(WASM): add nodejs webcrypto provider through feature gate #189

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

nicdard
Copy link

@nicdard nicdard commented Sep 1, 2024

Issues:

Resolves #ISSUE-NUMBER1
Addresses #ISSUE-NUMBER2

Description of changes:

As NodeJs is implementing the WebCrypto API specification, adding the possibility to conditionally compile the webcrypto provider for NodeJs environment.
This can be useful to enhance interoperability.
In my case specifically, I need to have a node compatible provider to simplify testing and benchmarking my application using this library compiled to WASM.

Call-outs:

I am still a beginner in Rust and WASM

Testing:

This change is currently used in my master thesis project (@mulmarta we contacted you a while ago, David Balbás wrote you an email to ask around exporting the epoch secret).

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT license.

@nicdard nicdard requested a review from a team as a code owner September 1, 2024 18:14
@nicdard nicdard force-pushed the provider-crypto-node branch from 77e85be to 559a7c1 Compare September 1, 2024 18:18
@nicdard nicdard changed the title feat(nodejs): add nodejs webcrypto provider through feature gates feat(nodejs): add nodejs webcrypto provider through feature gate Sep 1, 2024
@nicdard nicdard changed the title feat(nodejs): add nodejs webcrypto provider through feature gate feat(WASM): add nodejs webcrypto provider through feature gate Sep 1, 2024
@@ -0,0 +1,5 @@
const crypto = require("node:crypto");
Copy link
Contributor

Choose a reason for hiding this comment

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

Does node:crypto have the exact same api as subtle crypto?

Copy link
Author

@nicdard nicdard Sep 24, 2024

Choose a reason for hiding this comment

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

The Rust code is accessing the subtle object from this crypto object we bind. As I substituted the call to
window.crypto only.

However, I was re-checking the documentation and saw that the correct way is to use:

Suggested change
const crypto = require("node:crypto");
const crypto = require("node:crypto").webcrypto;

I'll test this and change accordingly

Copy link
Author

Choose a reason for hiding this comment

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

it works, pushed the change, thanks!

@@ -23,6 +25,7 @@ serde = ["dep:serde", "zeroize/serde", "hex/serde", "dep:serde_bytes"]
last_resort_key_package_ext = []

[dependencies]
cfg-if = "1.0.0"
Copy link
Contributor

Choose a reason for hiding this comment

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

this doesn't seem to be used?

Copy link
Author

Choose a reason for hiding this comment

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

sorry probably left there by mistake

Comment on lines 14 to 16
web = []
node = []
default = ["std", "rfc_compliant", "fast_serialize", "web"]
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is needed because it is covered in mls-rs-crypto-webcrypto

Copy link
Author

Choose a reason for hiding this comment

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

could you elaborate?

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

cool thanks for pointing out, this helped me with finding a good solution :)

Copy link
Contributor

@mulmarta mulmarta left a comment

Choose a reason for hiding this comment

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

Thanks @nicdard and hope to see the thesis / paper at some point!

Comment on lines 60 to 68
#[cfg(all(target_arch = "wasm32", feature = "node"))]
#[wasm_bindgen(inline_js = r#"
module.exports.date_now = function() {
return Date.now();
};"#)]
extern "C" {
fn date_now() -> f64;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean that I can't compile this for wasm32 with --no-default-features (since date_now is undefined) or --all-features (since date_now is defined twice)? I think in rust features should be additive. Maybe something like not(feature = "web") here? Not sure

Copy link
Author

Choose a reason for hiding this comment

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

oh ok I see, I will try to make them additive, thanks!

Copy link
Author

@nicdard nicdard Sep 24, 2024

Choose a reason for hiding this comment

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

I think I have implemented a good solution now, where I only add a new feature node.

@nicdard
Copy link
Author

nicdard commented Sep 24, 2024

Thanks @nicdard and hope to see the thesis / paper at some point!

Thanks! sure I will share later on when I have the thesis ready if you are interested :)

@nicdard nicdard force-pushed the provider-crypto-node branch from 605891f to d792356 Compare September 24, 2024 20:45
@nicdard nicdard force-pushed the provider-crypto-node branch from 838b066 to ebf2c83 Compare September 24, 2024 21:54
@nicdard nicdard force-pushed the provider-crypto-node branch from ebf2c83 to 3e27f05 Compare September 24, 2024 21:54
@nicdard
Copy link
Author

nicdard commented Oct 15, 2024

@mulmarta @tomleavy I found another compatibility issue with NodeJS: While Chrome generates the public key from a EC private key when importing it fro pkcs8 format, NodeJs doesn't, therefore an empty commit or an update proposal would fail. I am importing the key in jwk to force the generation of the public key part.

The same issue is also present in safari and firefox, with the difference that those are throwing an exception already when you try to import a pkcs8 key as a CryptoKey if it contains only the secret key bytes, so the workaround for Node cannot be applied there.

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

Successfully merging this pull request may close these issues.

3 participants