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 a way of getting the Crypto object #471

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

eric-seppanen
Copy link
Contributor

web_sys understands how to acquire Crypto from a Window or from a WorkerGlobalScope, but neither of these work in a worker context.

It turns out to be possible, but it's not obvious how to do it, so it's convenient to have the worker crate provide this access.

I find this very useful when doing JWT validation; I prefer letting the runtime handle the details of low-level cryptography.

web_sys understands how to acquire Crypto from a Window or from a
WorkerGlobalScope, but neither of these work in a CF worker.

It turns out to be possible, but it's not obvious how to do it, so it's
convenient to have the worker crate provide this access.
@dakom
Copy link
Contributor

dakom commented Apr 3, 2024

From the peanut gallery (just sorta looking through some issues)

I think this is more like the sort of thing that could/should be in optional community-driven wasm crates, rather than part of worker core, since it's not worker-specific (would be useful in many other places!)

For prior art, see gloo: https://github.com/rustwasm/gloo - idea is they are very useful Rusty wrappers around things like timers, event listeners, etc. Actually, I think adding a crypto crate to gloo would be a perfect fit :)

One reason I'm saying this is that it's not really enough to just get the Crypto web_sys handle, you're then going to want SubtleCrypto and the web_sys API stops being very helpful, need Rust-friendly representations of the methods and objects.

For example, the web_sys API takes a plain JS object for generateKey - and from a Rust perspective, we'd want to have this be typechecked, maybe an enum with only the allowed algorithm variants - and then inside of that enum again you're hit with web_sys taking an Object with a Rust-unfriendly API for, say, AesKeyGenParams

Getting all of this right is a bit opinionated, and will add a bit of bloat to worker projects that don't need/use it - but I really do think it's a great idea for the ecosystem as a whole, would love to see a crate that does this (and I do agree it's common enough to be a candidate for gloo) :)

@dakom
Copy link
Contributor

dakom commented Apr 3, 2024

btw, to access properties on the global namespace, you don't really need direct access to globalThis, you can just create bindings via js_namespace property of wasm_bindgen. At the top level that namespace's parent will be global, so it "just works" :)

See for example here: https://github.com/cloudflare/workers-rs/pull/529/files#diff-6401a7b68b5c3371692a10163e6e09c80b32bdaa0d9ceb1ae4ce49f12c7a70f6R50

@eric-seppanen
Copy link
Contributor Author

it's not really enough to just get the Crypto web_sys handle, you're then going to want SubtleCrypto and the web_sys API stops being very helpful, need Rust-friendly representations of the methods and objects.

All of that exists in the web_sys crate. And it works-- I am using it in a project already. The only missing piece is to get access to the web_sys::Crypto object. There is a standard way of doing this, via web_sys::Window::crypto() or web_sys::WorkerGlobalScope::crypto().

But neither of those are available in the workers runtime-- meaning this is a workers-specific problem. So I think the workers crate is the right place to address it.

@dakom
Copy link
Contributor

dakom commented Apr 3, 2024

All of that exists in the web_sys crate

Can you show me an example? As far as I can tell, the web_sys crate expects plain objects and strings, there's no type safety. An idiomatic Rust API would use enums and structs to make it impossible at compiletime to do things like pass an invalid algorithm string or config object

There is a standard way of doing this, via web_sys::Window::crypto() or web_sys::WorkerGlobalScope::crypto()

Are you sure that works, and that you don't need to rather call web_sys::window() or global() (i.e. what you did here is just the standard thing you'd do anywhere)?

I agree with the headspace btw - it would be wonderful to have more Rust-friendly apis built on top of web-sys/js-sys (in fact I have my own personal grab-bag in awsm-web, very familiar with the pain point!)

I'm just raising the question of whether this crate in particular should be limited to creating bindings for worker-specific apis (like durable object, digest stream, etc.,)

For me it's just a question though, I'd be cool with it going either direction :)

@eric-seppanen
Copy link
Contributor Author

I don't have public code to share, but I am successfully using the SubtleCrypto functions in both a browser and worker environment. The web_sys layer is pretty basic, and it may be missing some desirable idioms (e.g. enums for the algorithms, curves, etc.) but it's still perfectly usable.

Even a higher-level wrapper would still need access to the Crypto object to be able to call the underlying functions, which is the part that's accessed differently in a worker context, so this change is still useful.

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.

None yet

2 participants