-
Notifications
You must be signed in to change notification settings - Fork 25
[PM-26459] Implement data envelope #336
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
Conversation
# Conflicts: # crates/bitwarden-crypto/src/store/context.rs # crates/bitwarden-crypto/src/traits/key_id.rs
|
Great job! No new security vulnerabilities introduced in this pull request |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #336 +/- ##
==========================================
- Coverage 78.37% 78.34% -0.03%
==========================================
Files 291 293 +2
Lines 29391 29892 +501
==========================================
+ Hits 23034 23419 +385
- Misses 6357 6473 +116 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
# Conflicts: # crates/bitwarden-crypto/src/store/context.rs # crates/bitwarden-vault/src/cipher/attachment.rs # crates/bitwarden-wasm-internal/src/pure_crypto.rs
|
1 similar comment
|
# Conflicts: # crates/bitwarden-core/src/key_management/crypto.rs # crates/bitwarden-crypto/src/store/context.rs # crates/bitwarden-vault/src/cipher/cipher.rs # crates/bitwarden-wasm-internal/src/pure_crypto.rs
# Conflicts: # crates/bitwarden-crypto/src/safe/password_protected_key_envelope.rs
f5187ff to
16369db
Compare
…k-internal into km/beeep/safe-data-envelope
Hinton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks great, some general thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if these macros provide much value, at best they save 2 lines of code but they also interup the control flow. I know we have precedence of this with require! ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo, in this case it's not so much about saving 2 lines, versus readability. The ensure is used in a cluster of checks. Thus, matches or an equality check seem (slightly) harder to parse than something that states "ensure_{matches/equal}":
ensure_matches!(msg.protected.header.alg, Some(coset::Algorithm::PrivateUse(XCHACHA20_POLY1305)) => DataEnvelopeError::DecryptionError);
ensure_equal!(msg.protected.header.key_id, cek.key_id => DataEnvelopeError::WrongKey);
ensure_equal!(envelope_namespace, *namespace => DataEnvelopeError::InvalidNamespace);
ensure_equal!(content_format, CONTENT_TYPE_PADDED_CBOR => DataEnvelopeError::UnsupportedContentFormat);
vs
if !matches(msg.protected.header.alg, Some(coset::Algorithm::PrivateUse(XCHACHA20_POLY1305))) {
return Err(DataEnvelopeError::DecryptionError);
}
if !msg.protected.header.key_id == cek.key_id {
return Err(DataEnvelopeError::WrongKey);
}
if !envelope_namespace == *namespace {
return Err(DataEnvelopeError::InvalidNamespace);
}
if !content_format == CONTENT_TYPE_PADDED_CBOR {
return Err(DataEnvelopeError::UnsupportedContentFormat);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just saying that in the first case to understand what's actually going in I need to jump into the macros. The syntax is somewhat confusing with the last argument being an expression.
Unwrapped everything I need to know to follow the execution flow is there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. These were intended to make readability nicer, if they don't I'll undo them.
Looking for additional feedback @mzieniukbw and @Thomas-Avery. Do you have thoughts on readability here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I'll make this an item for the next KM dev sync. I'll make a follow-up PR to undo the macros assuming the outcome is that they don't provide readability benefit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: undoing this in a follow-up PR.
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum DataEnvelopeNamespace { | ||
| /// The namespace for vault items | ||
| VaultItem = 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: This is generally called Cipher in other places. Could this cause confusion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vault team is free to rename this entry; However I'll argue that despite precedent of using the term for a long time, Cipher is extremely confusing, especially in the context of an end-to-end encrypted app. Thus I opted for simpler naming here.
I've added a comment clarifying that this is the same as "ciphers"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC @bitwarden/team-vault-dev
Thomas-Avery
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, have a few minor things and some questions/confusion around versioning.
Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
|
Claude, re: Critical issues:
As the review is not useful, I'm muting it. |




🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-26459
https://bitwarden.atlassian.net/wiki/spaces/EN/pages/2052653095/Draft+Tech+Breakdown+-+DataEnvelope
📔 Objective
Important
The confluence document has a more detailed breakdown. This is a shortened version.
Consumers want to protect complex structs such as:
Currently, they serialize these themselves (organization reports are serialized as json), and encrypt fields individually. This is slow to handle during encrypt/decrypt, and complex to maintain. The server now has to know the same representation as clients. At the same time, this can be abused by the server omitting certain fields, or swapping encrypted fields encrypted under the same key.
EncStrings are not the correct abstraction layer. A new abstraction / API that is safe and easier to use (an impossible to misuse) is needed.
Security Definition
Attacker model: The relevant attacker model here is a fully compromised server. That’s what E2E encryption / zero knowledge protect against.
Security Goals:
SG1: The structure should not be modifiable (malleable)
SG2: The attacker should not be able to infer anything about the contents of the structure aside from length
SG3: The structure should only be encryptable in the specific section of code that the developer intends
This PR implements a "DataEnvelope". The DataEnvelope solves the problem of encrypting entire structs. The caller just provides a struct that is Serializable/Deserializable, and gets back an encrypted blob. The caller does not decide serialization.
Further, we force the creation of a "content encryption key" by the interface. This ensures that teams do not create a coupling to keys. When implementing key-rotation we do not want to re-upload data, but only re-upload re-encrypted keys, and the content-encryption-key enforces this key being present.
An example is provided to show usage.
⏰ Reminders before review
team
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmedissue and could potentially benefit from discussion
:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes