Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions crates/bitwarden-core/src/client/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use bitwarden_crypto::KeyStore;
#[cfg(any(feature = "internal", feature = "secrets"))]
use bitwarden_crypto::SymmetricCryptoKey;
#[cfg(feature = "internal")]
use bitwarden_crypto::{CryptoError, EncString, Kdf, MasterKey, PinKey, UnsignedSharedKey};
use bitwarden_crypto::{
CryptoError, EncString, Kdf, MasterKey, PinKey, UnsignedSharedKey,
safe::PasswordProtectedKeyEnvelope,
};
#[cfg(feature = "internal")]
use bitwarden_state::registry::StateRegistry;
use chrono::Utc;
Expand All @@ -25,10 +28,7 @@ use crate::{
login_method::UserLoginMethod,
},
error::NotAuthenticatedError,
key_management::{
PasswordProtectedKeyEnvelope, SecurityState, SignedSecurityState,
crypto::InitUserCryptoRequest,
},
key_management::{SecurityState, SignedSecurityState, crypto::InitUserCryptoRequest},
};

/// Represents the user's keys, that are encrypted by the user key, and the signed security state.
Expand Down
11 changes: 3 additions & 8 deletions crates/bitwarden-core/src/key_management/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use bitwarden_crypto::{
AsymmetricCryptoKey, CoseSerializable, CryptoError, EncString, Kdf, KeyDecryptable,
KeyEncryptable, MasterKey, Pkcs8PrivateKeyBytes, PrimitiveEncryptable, SignatureAlgorithm,
SignedPublicKey, SigningKey, SpkiPublicKeyBytes, SymmetricCryptoKey, UnsignedSharedKey,
UserKey, dangerous_get_v2_rotated_account_keys, safe::PasswordProtectedKeyEnvelopeError,
UserKey, dangerous_get_v2_rotated_account_keys,
safe::{PasswordProtectedKeyEnvelope, PasswordProtectedKeyEnvelopeError},
};
use bitwarden_encoding::B64;
use bitwarden_error::bitwarden_error;
Expand All @@ -26,7 +27,6 @@ use crate::{
key_management::{
AsymmetricKeyId, SecurityState, SignedSecurityState, SigningKeyId, SymmetricKeyId,
master_password::{MasterPasswordAuthenticationData, MasterPasswordUnlockData},
non_generic_wrappers::PasswordProtectedKeyEnvelope,
},
};

Expand Down Expand Up @@ -412,12 +412,7 @@ pub(super) fn enroll_pin(
let key_store = client.internal.get_key_store();
let mut ctx = key_store.context_mut();

let key_envelope =
PasswordProtectedKeyEnvelope(bitwarden_crypto::safe::PasswordProtectedKeyEnvelope::seal(
SymmetricKeyId::User,
&pin,
&ctx,
)?);
let key_envelope = PasswordProtectedKeyEnvelope::seal(SymmetricKeyId::User, &pin, &ctx)?;
let encrypted_pin = pin.encrypt(&mut ctx, SymmetricKeyId::User)?;
Ok(EnrollPinResponse {
pin_protected_user_key_envelope: key_envelope,
Expand Down
4 changes: 1 addition & 3 deletions crates/bitwarden-core/src/key_management/crypto_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bitwarden_crypto::{CryptoError, Decryptable, Kdf};
#[cfg(feature = "internal")]
use bitwarden_crypto::{EncString, UnsignedSharedKey};
use bitwarden_crypto::{EncString, UnsignedSharedKey, safe::PasswordProtectedKeyEnvelope};
use bitwarden_encoding::B64;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
Expand All @@ -10,8 +10,6 @@ use super::crypto::{
MakeKeyPairResponse, VerifyAsymmetricKeysRequest, VerifyAsymmetricKeysResponse,
derive_key_connector, make_key_pair, verify_asymmetric_keys,
};
#[cfg(any(feature = "wasm", test))]
use crate::key_management::PasswordProtectedKeyEnvelope;
#[cfg(feature = "internal")]
use crate::key_management::{
SymmetricKeyId,
Expand Down
4 changes: 0 additions & 4 deletions crates/bitwarden-core/src/key_management/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ pub use crypto_client::CryptoClient;
#[cfg(feature = "internal")]
mod master_password;
#[cfg(feature = "internal")]
mod non_generic_wrappers;
#[cfg(feature = "internal")]
pub(crate) use non_generic_wrappers::*;
#[cfg(feature = "internal")]
mod security_state;
#[cfg(feature = "internal")]
mod user_decryption;
Expand Down

This file was deleted.

8 changes: 4 additions & 4 deletions crates/bitwarden-core/src/uniffi_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

use std::{num::NonZeroU32, str::FromStr};

use bitwarden_crypto::safe::PasswordProtectedKeyEnvelope;
use bitwarden_uniffi_error::convert_result;
use uuid::Uuid;

use crate::key_management::{PasswordProtectedKeyEnvelope, SignedSecurityState};
use crate::key_management::SignedSecurityState;

uniffi::use_remote_type!(bitwarden_crypto::NonZeroU32);

Expand Down Expand Up @@ -36,7 +37,6 @@ uniffi::custom_type!(SignedSecurityState, String, {

uniffi::custom_type!(PasswordProtectedKeyEnvelope, String, {
remote,
try_lift: |val| convert_result(bitwarden_crypto::safe::PasswordProtectedKeyEnvelope::from_str(&val)
.map(PasswordProtectedKeyEnvelope)),
lower: |obj| obj.0.into(),
try_lift: |val| convert_result(PasswordProtectedKeyEnvelope::from_str(&val)),
lower: |obj| obj.into(),
});
11 changes: 5 additions & 6 deletions crates/bitwarden-crypto/examples/protect_key_with_password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ fn main() {
ctx.clear_local();

// Load the envelope from disk and unseal it with the PIN, and store it in the context.
let deserialized: PasswordProtectedKeyEnvelope<ExampleIds> =
PasswordProtectedKeyEnvelope::try_from(
disk.load("vault_key_envelope")
.expect("Loading from disk should work"),
)
.expect("Deserializing envelope should work");
let deserialized: PasswordProtectedKeyEnvelope = PasswordProtectedKeyEnvelope::try_from(
disk.load("vault_key_envelope")
.expect("Loading from disk should work"),
)
.expect("Deserializing envelope should work");
deserialized
.unseal(ExampleSymmetricKey::VaultKey, pin, &mut ctx)
.expect("Unsealing should work");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! single recipient's unprotected headers. The output from the KDF - "envelope key", is used to
//! wrap the symmetric key, that is sealed by the envelope.

use std::{marker::PhantomData, num::TryFromIntError, str::FromStr};
use std::{num::TryFromIntError, str::FromStr};

use argon2::Params;
use bitwarden_encoding::{B64, FromStrVisitor};
Expand All @@ -22,6 +22,8 @@ use coset::{CborSerializable, CoseError, Header, HeaderBuilder};
use rand::RngCore;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[cfg(feature = "wasm")]
use tsify::Tsify;

use crate::{
BitwardenLegacyKeyBytes, ContentFormat, CoseKeyBytes, EncodedSymmetricKey, KeyIds,
Expand All @@ -47,17 +49,17 @@ const ENVELOPE_ARGON2_OUTPUT_KEY_SIZE: usize = 32;
/// be provided.
///
/// Internally, Argon2 is used as the KDF and XChaCha20-Poly1305 is used to encrypt the key.
pub struct PasswordProtectedKeyEnvelope<Ids: KeyIds> {
_phantom: PhantomData<Ids>,
#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct PasswordProtectedKeyEnvelope {
cose_encrypt: coset::CoseEncrypt,
}

impl<Ids: KeyIds> PasswordProtectedKeyEnvelope<Ids> {
impl PasswordProtectedKeyEnvelope {
/// Seals a symmetric key with a password, using the current default KDF parameters and a random
/// salt.
///
/// This should never fail, except for memory allocation error, when running the KDF.
pub fn seal(
pub fn seal<Ids: KeyIds>(
key_to_seal: Ids::Symmetric,
password: &str,
ctx: &KeyStoreContext<Ids>,
Expand Down Expand Up @@ -129,15 +131,12 @@ impl<Ids: KeyIds> PasswordProtectedKeyEnvelope<Ids> {
.build();
cose_encrypt.unprotected.iv = nonce.into();

Ok(PasswordProtectedKeyEnvelope {
_phantom: PhantomData,
cose_encrypt,
})
Ok(PasswordProtectedKeyEnvelope { cose_encrypt })
}

/// Unseals a symmetric key from the password-protected envelope, and stores it in the key store
/// context.
pub fn unseal(
pub fn unseal<Ids: KeyIds>(
&self,
target_keyslot: Ids::Symmetric,
password: &str,
Expand Down Expand Up @@ -229,36 +228,33 @@ impl<Ids: KeyIds> PasswordProtectedKeyEnvelope<Ids> {
}
}

impl<Ids: KeyIds> From<&PasswordProtectedKeyEnvelope<Ids>> for Vec<u8> {
fn from(val: &PasswordProtectedKeyEnvelope<Ids>) -> Self {
impl From<&PasswordProtectedKeyEnvelope> for Vec<u8> {
fn from(val: &PasswordProtectedKeyEnvelope) -> Self {
val.cose_encrypt
.clone()
.to_vec()
.expect("Serialization to cose should not fail")
}
}

impl<Ids: KeyIds> TryFrom<&Vec<u8>> for PasswordProtectedKeyEnvelope<Ids> {
impl TryFrom<&Vec<u8>> for PasswordProtectedKeyEnvelope {
type Error = CoseError;

fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
let cose_encrypt = coset::CoseEncrypt::from_slice(value)?;
Ok(PasswordProtectedKeyEnvelope {
_phantom: PhantomData,
cose_encrypt,
})
Ok(PasswordProtectedKeyEnvelope { cose_encrypt })
}
}

impl<Ids: KeyIds> std::fmt::Debug for PasswordProtectedKeyEnvelope<Ids> {
impl std::fmt::Debug for PasswordProtectedKeyEnvelope {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PasswordProtectedKeyEnvelope")
.field("cose_encrypt", &self.cose_encrypt)
.finish()
}
}

impl<Ids: KeyIds> FromStr for PasswordProtectedKeyEnvelope<Ids> {
impl FromStr for PasswordProtectedKeyEnvelope {
type Err = PasswordProtectedKeyEnvelopeError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand All @@ -275,14 +271,14 @@ impl<Ids: KeyIds> FromStr for PasswordProtectedKeyEnvelope<Ids> {
}
}

impl<Ids: KeyIds> From<PasswordProtectedKeyEnvelope<Ids>> for String {
fn from(val: PasswordProtectedKeyEnvelope<Ids>) -> Self {
impl From<PasswordProtectedKeyEnvelope> for String {
fn from(val: PasswordProtectedKeyEnvelope) -> Self {
let serialized: Vec<u8> = (&val).into();
B64::from(serialized).to_string()
}
}

impl<'de, Ids: KeyIds> Deserialize<'de> for PasswordProtectedKeyEnvelope<Ids> {
impl<'de> Deserialize<'de> for PasswordProtectedKeyEnvelope {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
Expand All @@ -291,7 +287,7 @@ impl<'de, Ids: KeyIds> Deserialize<'de> for PasswordProtectedKeyEnvelope<Ids> {
}
}

impl<Ids: KeyIds> Serialize for PasswordProtectedKeyEnvelope<Ids> {
impl Serialize for PasswordProtectedKeyEnvelope {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
Expand Down Expand Up @@ -547,7 +543,7 @@ mod tests {
let serialized: Vec<u8> = (&envelope).into();

// Unseal the key from the envelope
let deserialized: PasswordProtectedKeyEnvelope<TestIds> =
let deserialized: PasswordProtectedKeyEnvelope =
PasswordProtectedKeyEnvelope::try_from(&serialized).unwrap();
deserialized
.unseal(TestSymmKey::A(1), password, &mut ctx)
Expand Down Expand Up @@ -580,7 +576,7 @@ mod tests {
let serialized: Vec<u8> = (&envelope).into();

// Unseal the key from the envelope
let deserialized: PasswordProtectedKeyEnvelope<TestIds> =
let deserialized: PasswordProtectedKeyEnvelope =
PasswordProtectedKeyEnvelope::try_from(&serialized).unwrap();
deserialized
.unseal(TestSymmKey::A(1), password, &mut ctx)
Expand All @@ -607,7 +603,7 @@ mod tests {
let new_password = "new_test_password";

// Seal the key with a password
let envelope: PasswordProtectedKeyEnvelope<TestIds> =
let envelope: PasswordProtectedKeyEnvelope =
PasswordProtectedKeyEnvelope::seal_ref(&key, password).expect("Sealing should work");

// Reseal
Expand Down Expand Up @@ -635,7 +631,7 @@ mod tests {
let envelope = PasswordProtectedKeyEnvelope::seal(test_key, password, &ctx).unwrap();

// Attempt to unseal with the wrong password
let deserialized: PasswordProtectedKeyEnvelope<TestIds> =
let deserialized: PasswordProtectedKeyEnvelope =
PasswordProtectedKeyEnvelope::try_from(&(&envelope).into()).unwrap();
assert!(matches!(
deserialized.unseal(TestSymmKey::A(1), wrong_password, &mut ctx),
Expand Down
10 changes: 9 additions & 1 deletion crates/bitwarden-crypto/src/uniffi_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::{num::NonZeroU32, str::FromStr};

use bitwarden_uniffi_error::convert_result;

use crate::{CryptoError, EncString, SignedPublicKey, UnsignedSharedKey};
use crate::{
CryptoError, EncString, SignedPublicKey, UnsignedSharedKey, safe::PasswordProtectedKeyEnvelope,
};

uniffi::custom_type!(NonZeroU32, u32, {
remote,
Expand Down Expand Up @@ -32,3 +34,9 @@ uniffi::custom_type!(SignedPublicKey, String, {
},
lower: |obj| obj.into(),
});

uniffi::custom_type!(PasswordProtectedKeyEnvelope, String, {
remote,
try_lift: |val| convert_result(PasswordProtectedKeyEnvelope::from_str(&val)),
lower: |obj| obj.into(),
});
Loading