bitwarden_core/client/
encryption_settings.rsuse bitwarden_crypto::{AsymmetricCryptoKey, KeyStore, SymmetricCryptoKey};
#[cfg(feature = "internal")]
use bitwarden_crypto::{AsymmetricEncString, EncString};
use bitwarden_error::bitwarden_error;
use thiserror::Error;
use uuid::Uuid;
use crate::{
key_management::{AsymmetricKeyId, KeyIds, SymmetricKeyId},
MissingPrivateKeyError, VaultLockedError,
};
#[bitwarden_error(flat)]
#[derive(Debug, Error)]
pub enum EncryptionSettingsError {
#[error("Cryptography error, {0}")]
Crypto(#[from] bitwarden_crypto::CryptoError),
#[error(transparent)]
InvalidBase64(#[from] base64::DecodeError),
#[error(transparent)]
VaultLocked(#[from] VaultLockedError),
#[error("Invalid private key")]
InvalidPrivateKey,
#[error(transparent)]
MissingPrivateKey(#[from] MissingPrivateKeyError),
}
pub struct EncryptionSettings {}
impl EncryptionSettings {
#[cfg(feature = "internal")]
pub(crate) fn new_decrypted_key(
user_key: SymmetricCryptoKey,
private_key: EncString,
store: &KeyStore<KeyIds>,
) -> Result<(), EncryptionSettingsError> {
use bitwarden_crypto::KeyDecryptable;
use log::warn;
use crate::key_management::{AsymmetricKeyId, SymmetricKeyId};
let private_key = {
let dec: Vec<u8> = private_key.decrypt_with_key(&user_key)?;
AsymmetricCryptoKey::from_der(&dec)
.map_err(|_| {
warn!("Invalid private key");
})
.ok()
};
#[allow(deprecated)]
{
let mut ctx = store.context_mut();
ctx.set_symmetric_key(SymmetricKeyId::User, user_key)?;
if let Some(private_key) = private_key {
ctx.set_asymmetric_key(AsymmetricKeyId::UserPrivateKey, private_key)?;
}
}
Ok(())
}
#[cfg(feature = "secrets")]
pub(crate) fn new_single_key(key: SymmetricCryptoKey, store: &KeyStore<KeyIds>) {
#[allow(deprecated)]
store
.context_mut()
.set_symmetric_key(SymmetricKeyId::User, key)
.expect("Mutable context");
}
#[cfg(feature = "internal")]
pub(crate) fn set_org_keys(
org_enc_keys: Vec<(Uuid, AsymmetricEncString)>,
store: &KeyStore<KeyIds>,
) -> Result<(), EncryptionSettingsError> {
let mut ctx = store.context_mut();
if org_enc_keys.is_empty() {
return Ok(());
}
if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) {
return Err(MissingPrivateKeyError.into());
}
ctx.retain_symmetric_keys(|key_ref| !matches!(key_ref, SymmetricKeyId::Organization(_)));
for (org_id, org_enc_key) in org_enc_keys {
ctx.decrypt_symmetric_key_with_asymmetric_key(
AsymmetricKeyId::UserPrivateKey,
SymmetricKeyId::Organization(org_id),
&org_enc_key,
)?;
}
Ok(())
}
}