matrix-org / matrix-js-sdk

Matrix Client-Server SDK for JavaScript
Apache License 2.0
1.6k stars 591 forks source link

Use new WebCrypto in a Node environment #1592

Closed yousefamar closed 3 years ago

yousefamar commented 3 years ago

Is your feature request related to a problem? Please describe.

Writing Matrix bots in Node with E2EE room support is a huge pain. One blocker for something quite specific that I hit along the way was this (in fact, that error never actually gets thrown, instead we get an error here because global.crypto is undefined).

Describe the solution you'd like

The current version of node (not LTS) supports WebCrypto. As far as I can tell, the algos that matrix-js-sdk uses are all supported (I could be wrong — based on a quick string search of the codebase). Granted, not everyone is on the newest version, and the API is under "experimental" stability, but it looks like all the methods match the browser equivalents, so it would be good to detect if this API is there, and use it in Node.

Describe alternatives you've considered

I did a search of NPM for other shims and subtleCrypto packages, but they're all quite bad (old, unmaintained, few algos, etc).

Additional context

The higher-level goal here is that I want this bot to log in and for the session to automatically verify (through imported keys). This is similar to what happens in matrix-react-sdk when you have backups and log in to a new session where you can verify with key/passphrase/etc. I've already tried the access token route and hijacking existing sessions, but it introduces too many other problems especially for E2EE rooms, so I'm trying to do this "properly" by having the bot create a new session. I don't know if people have done this before, but judging by the hacks I've had to do, and lack of documentation (or perhaps due to the lack of documentation), I doubt it.

I'm more than happy to implement this myself and PR, as well as write up docs/guides on this and E2EE support, but wanted to raise an issue first in case you guys have some opinions/thoughts, or if there's work being done here/externally that I'm not aware of.

P.S. I'm curious as to why these functions are in matrix-react-sdk rather than here. IMO it should be decoupled from that and moved to this lib? Since it makes it impossible to do anything with exported keys without replicating that code otherwise. Plus there's some subtleCrypto stuff there too, but otherwise should be usable in Node (except for the unnecessary use of window.atob, although that's easily solved because these days converting to/from base64 is a one-liner).

yousefamar commented 3 years ago

I thought about this some more, and I think it's actually better to follow the same pattern that is recommended with using OLM. I.e. just like we do this

global.Olm = require("olm");

the following solves that TODO

global.crypto = require('crypto').webcrypto;

So I'm going to close this issue and instead PR better documentation.