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

feat(bindings/crypto-nodejs): Implement an Attachment API. #818

Merged
merged 10 commits into from
Jul 8, 2022

Conversation

Hywan
Copy link
Member

@Hywan Hywan commented Jul 5, 2022

This patch fixes #796.

This patch provides a new API to encrypt and decrypt attachment, i.e. big buffer of type Uint8Array.

This patch also fixes a bug in matrix_sdk_crypto::MediaEncryptedInfo where its web_key field should serialize to and deserialize from key to respect the specification.

It's based on matrix_sdk_crypto::AttachmentEncryptor and AttachmentDecryptor.

Note: I'm really not happy with the fact EncryptedAttachment.encryptedData returns a copy. But we cannot return a &T with napi-rs. I tried to create a new buffer that references data from elsewhere, like with Uint8Array::with_external_data, but the data are collected by the GC (which notifies us before dropping the data); that's not what we want. I then tried with Reference or Ref, but napi-rs doesn't allow to return them from a function, so it's useless. I'll investigate that. In the meantime, as mentionned in #796, right now, there is a copy in the previous matrix-sdk-crypto-nodejs API. This patch is actually better as it doesn't need to serialize and deserialize the entire data, it just computes a new Uint8Array, which is an improvement. This is now fixed. Data are no longer copied!

This patch provides a new API to encrypt and decrypt attachment,
i.e. big buffer of type `Uint8Array`.

It's based on `matrix_sdk_crypto::AttachmentEncryptor` and `AttachmentDecryptor`.
@Hywan Hywan added enhancement New feature or request bindings labels Jul 5, 2022
@Hywan Hywan requested review from gnunicorn, poljar and turt2live July 5, 2022 15:37
@codecov
Copy link

codecov bot commented Jul 5, 2022

Codecov Report

Merging #818 (6d83f01) into main (ba39185) will increase coverage by 0.00%.
The diff coverage is 40.00%.

@@           Coverage Diff           @@
##             main     #818   +/-   ##
=======================================
  Coverage   77.92%   77.92%           
=======================================
  Files          92       92           
  Lines       13919    13930   +11     
=======================================
+ Hits        10846    10855    +9     
- Misses       3073     3075    +2     
Impacted Files Coverage Δ
crates/matrix-sdk/src/encryption/mod.rs 28.24% <0.00%> (ø)
...trix-sdk-crypto/src/file_encryption/attachments.rs 86.53% <66.66%> (ø)
crates/matrix-sdk/src/client/mod.rs 84.44% <0.00%> (-0.12%) ⬇️
crates/matrix-sdk/src/room/common.rs 69.10% <0.00%> (+1.58%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ba39185...6d83f01. Read the comment docs.

Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

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

otherwise this works - just a small property name issue

…ning `Uint8Array`.

The new `napi-rs` release includes a patch that avoids cloning and
copying data inside a `Uint8Array`
(napi-rs/napi-rs#1224), it now returns a
“Node.js reference” of it.

This new `napi-rs` release also includes one of our patch,
napi-rs/napi-rs#1200, which means we no longer
need to depend on our fork.
Based on the [Section 11.11.1.6.1 Extensions to `m.room.message`
msgtypes](https://spec.matrix.org/v1.2/client-server-api/#extensions-to-mroommessage-msgtypes),
the parameter for the JSON Web Key is named `key`, not `web_key`. This
patch fixes that by renaming the field when serializing and
deserializing.
@Hywan Hywan requested a review from turt2live July 7, 2022 08:07
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Looks mostly good, the Clone is a bit of a shame if it can't be avoided.

@gnunicorn gnunicorn removed their request for review July 7, 2022 09:24
Hywan added 4 commits July 7, 2022 13:14
…nInfo`.

We don't want to clone a struct that contains a secret.

However, on the Node.js side, we can only receive arguments by
references. The problem we have is that we cannot transfer the
ownership of `MediaEncryptionInfo` to `AttachmentDecryptor` because we
don't own it. To simulate this behavior, we use `Option.take`.

A new method then appears:
`EncryptedAttachment.hasMediaEncryptionInfoBeenConsumed` to know if
the media encryption info has been consumed by `Attachment.decrypt`
already or not. That way, we can decrypt only once. It is possible to
do a JSON-encoded backup of the media encryption info by calling
`EncryptedAttachment.mediaEncryptionInfo` though.
Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

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

it works

Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

I still think that we should let the decryptor take a borrow of the info, but I'll deal with this later on.

Adding proper zeroization for this is a bit trickier than expected.

Looks good, thanks.

@Hywan Hywan merged commit dc2276c into matrix-org:main Jul 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bindings enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bindings/crypto-nodejs: Expose functions for encrypting/decrypting files (attachments)
3 participants