Skip to content

Commit 03dccda

Browse files
committed
Implement new key format
1 parent b091af6 commit 03dccda

File tree

18 files changed

+206
-62
lines changed

18 files changed

+206
-62
lines changed

Cargo.lock

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bitwarden-core/src/auth/access_token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ mod tests {
9797
"ec2c1d46-6a4b-4751-a310-af9601317f2d"
9898
);
9999
assert_eq!(token.client_secret, "C2IgxjjLF7qSshsbwe8JGcbM075YXw");
100-
assert_eq!(token.encryption_key.to_base64(), "H9/oIRLtL9nGCQOVDjSMoEbJsjWXSOCb3qeyDt6ckzS3FhyboEDWyTP/CQfbIszNmAVg2ExFganG1FVFGXO/Jg==");
100+
assert_eq!(token.encryption_key.to_base64().unwrap(), "H9/oIRLtL9nGCQOVDjSMoEbJsjWXSOCb3qeyDt6ckzS3FhyboEDWyTP/CQfbIszNmAVg2ExFganG1FVFGXO/Jg==");
101101
}
102102

103103
#[test]

crates/bitwarden-core/src/auth/auth_request.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub(crate) fn approve_auth_request(
102102
let key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
103103

104104
Ok(AsymmetricEncString::encrypt_rsa2048_oaep_sha1(
105-
&key.to_vec(),
105+
&key.to_encoded(false).unwrap(),
106106
&public_key,
107107
)?)
108108
}
@@ -125,7 +125,7 @@ fn test_auth_request() {
125125

126126
let decrypted = auth_request_decrypt_user_key(request.private_key, encrypted).unwrap();
127127

128-
assert_eq!(&decrypted.to_vec(), secret);
128+
assert_eq!(&decrypted.to_encoded(false).unwrap(), secret);
129129
}
130130

131131
#[cfg(test)]
@@ -178,7 +178,7 @@ mod tests {
178178
let dec = auth_request_decrypt_user_key(private_key.to_owned(), enc_user_key).unwrap();
179179

180180
assert_eq!(
181-
&dec.to_vec(),
181+
&dec.to_encoded(false).unwrap(),
182182
&[
183183
201, 37, 234, 213, 21, 75, 40, 70, 149, 213, 234, 16, 19, 251, 162, 245, 161, 74,
184184
34, 245, 211, 151, 211, 192, 95, 10, 117, 50, 88, 223, 23, 157
@@ -197,7 +197,7 @@ mod tests {
197197
.unwrap();
198198

199199
assert_eq!(
200-
&dec.to_vec(),
200+
&dec.to_encoded(false).unwrap(),
201201
&[
202202
109, 128, 172, 147, 206, 123, 134, 95, 16, 36, 155, 113, 201, 18, 186, 230, 216,
203203
212, 173, 188, 74, 11, 134, 131, 137, 242, 105, 178, 105, 126, 52, 139, 248, 91,
@@ -272,6 +272,6 @@ mod tests {
272272
.to_base64()
273273
};
274274

275-
assert_eq!(existing_key, new_key);
275+
assert_eq!(existing_key.unwrap(), new_key.unwrap());
276276
}
277277
}

crates/bitwarden-core/src/auth/password/validate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub(crate) fn validate_password_user_key(
6565
#[allow(deprecated)]
6666
let existing_key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
6767

68-
if user_key.to_vec() != existing_key.to_vec() {
68+
if user_key.to_encoded(false).ok() != existing_key.to_encoded(false).ok() {
6969
return Err(AuthValidateError::WrongUserKey);
7070
}
7171

crates/bitwarden-core/src/auth/pin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) fn validate_pin(
3737
return Ok(false);
3838
};
3939

40-
Ok(user_key.to_vec() == decrypted_key.to_vec())
40+
Ok(user_key.to_encoded(false).ok() == decrypted_key.to_encoded(false).ok())
4141
}
4242
}
4343
}

crates/bitwarden-core/src/auth/tde.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub(super) fn make_register_tde_keys(
2323
let key_pair = user_key.make_key_pair()?;
2424

2525
let admin_reset =
26-
AsymmetricEncString::encrypt_rsa2048_oaep_sha1(&user_key.0.to_vec(), &public_key)?;
26+
AsymmetricEncString::encrypt_rsa2048_oaep_sha1(&user_key.0.to_encoded(false)?, &public_key)?;
2727

2828
let device_key = if remember_device {
2929
Some(DeviceKey::trust_device(&user_key.0)?)

crates/bitwarden-core/src/mobile/crypto.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub async fn get_user_encryption_key(client: &Client) -> Result<String, MobileCr
227227
#[allow(deprecated)]
228228
let user_key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
229229

230-
Ok(user_key.to_base64())
230+
user_key.to_base64().map_err(Into::into)
231231
}
232232

233233
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
@@ -375,7 +375,7 @@ pub(super) fn enroll_admin_password_reset(
375375
let key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
376376

377377
Ok(AsymmetricEncString::encrypt_rsa2048_oaep_sha1(
378-
&key.to_vec(),
378+
&key.to_encoded(false)?,
379379
&public_key,
380380
)?)
381381
}
@@ -586,6 +586,7 @@ mod tests {
586586
ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)
587587
.unwrap()
588588
.to_base64()
589+
.unwrap()
589590
};
590591

591592
let client2_key = {
@@ -595,6 +596,7 @@ mod tests {
595596
ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)
596597
.unwrap()
597598
.to_base64()
599+
.unwrap()
598600
};
599601

600602
assert_eq!(client_key, client2_key);
@@ -651,6 +653,7 @@ mod tests {
651653
ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)
652654
.unwrap()
653655
.to_base64()
656+
.unwrap()
654657
};
655658

656659
let client2_key = {
@@ -660,6 +663,7 @@ mod tests {
660663
ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)
661664
.unwrap()
662665
.to_base64()
666+
.unwrap()
663667
};
664668

665669
assert_eq!(client_key, client2_key);
@@ -704,7 +708,7 @@ mod tests {
704708
.to_base64()
705709
};
706710

707-
assert_eq!(client_key, client3_key);
711+
assert_eq!(client_key.unwrap(), client3_key.unwrap());
708712
}
709713

710714
#[test]
@@ -746,7 +750,7 @@ mod tests {
746750
.dangerous_get_symmetric_key(SymmetricKeyId::User)
747751
.unwrap();
748752

749-
assert_eq!(&decrypted, &expected.to_vec());
753+
assert_eq!(&decrypted, &expected.to_encoded(false).unwrap())
750754
}
751755

752756
#[test]
@@ -784,7 +788,7 @@ mod tests {
784788
fn test_make_key_pair() {
785789
let (user_key, _) = setup_asymmetric_keys_test();
786790

787-
let response = make_key_pair(user_key.0.to_base64()).unwrap();
791+
let response = make_key_pair(user_key.0.to_base64().unwrap()).unwrap();
788792

789793
assert!(!response.user_public_key.is_empty());
790794
let encrypted_private_key = response.user_key_encrypted_private_key;
@@ -797,7 +801,7 @@ mod tests {
797801
let (user_key, key_pair) = setup_asymmetric_keys_test();
798802

799803
let request = VerifyAsymmetricKeysRequest {
800-
user_key: user_key.0.to_base64(),
804+
user_key: user_key.0.to_base64().unwrap(),
801805
user_public_key: key_pair.public,
802806
user_key_encrypted_private_key: key_pair.private,
803807
};
@@ -813,7 +817,7 @@ mod tests {
813817
let undecryptable_private_key = "2.cqD39M4erPZ3tWaz2Fng9w==|+Bsp/xvM30oo+HThKN12qirK0A63EjMadcwethCX7kEgfL5nEXgAFsSgRBMpByc1djgpGDMXzUTLOE+FejXRsrEHH/ICZ7jPMgSR+lV64Mlvw3fgvDPQdJ6w3MCmjPueGQtrlPj1K78BkRomN3vQwwRBFUIJhLAnLshTOIFrSghoyG78na7McqVMMD0gmC0zmRaSs2YWu/46ES+2Rp8V5OC4qdeeoJM9MQfaOtmaqv7NRVDeDM3DwoyTJAOcon8eovMKE4jbFPUboiXjNQBkBgjvLhco3lVJnFcQuYgmjqrwuUQRsfAtZjxFXg/RQSH2D+SI5uRaTNQwkL4iJqIw7BIKtI0gxDz6eCVdq/+DLhpImgCV/aaIhF/jkpGqLCceFsYMbuqdULMM1VYKgV+IAuyC65R+wxOaKS+1IevvPnNp7tgKAvT5+shFg8piusj+rQ49daX2SmV2OImwdWMmmX93bcVV0xJ/WYB1yrqmyRUcTwyvX3RQF25P5okIIzFasRp8jXFZe8C6f93yzkn1TPQbp95zF4OsWjfPFVH4hzca07ACt2HjbAB75JakWbFA5MbCF8aOIwIfeLVhVlquQXCldOHCsl22U/f3HTGLB9OS8F83CDAy7qZqpKha9Im8RUhHoyf+lXrky0gyd6un7Ky8NSkVOGd8CEG7bvZfutxv/qtAjEM9/lV78fh8TQIy9GNgioMzplpuzPIJOgMaY/ZFZj6a8H9OMPneN5Je0H/DwHEglSyWy7CMgwcbQgXYGXc8rXTTxL71GUAFHzDr4bAJvf40YnjndoL9tf+oBw8vVNUccoD4cjyOT5w8h7M3Liaxk9/0O8JR98PKxxpv1Xw6XjFCSEHeG2y9FgDUASFR4ZwG1qQBiiLMnJ7e9kvxsdnmasBux9H0tOdhDhAM16Afk3NPPKA8eztJVHJBAfQiaNiUA4LIJ48d8EpUAe2Tvz0WW/gQThplUINDTpvPf+FojLwc5lFwNIPb4CVN1Ui8jOJI5nsOw4BSWJvLzJLxawHxX/sBuK96iXza+4aMH+FqYKt/twpTJtiVXo26sPtHe6xXtp7uO4b+bL9yYUcaAci69L0W8aNdu8iF0lVX6kFn2lOL8dBLRleGvixX9gYEVEsiI7BQBjxEBHW/YMr5F4M4smqCpleZIAxkse1r2fQ33BSOJVQKInt4zzgdKwrxDzuVR7RyiIUuNXHsprKtRHNJrSc4x5kWFUeivahed2hON+Ir/ZvrxYN6nJJPeYYH4uEm1Nn4osUzzfWILlqpmDPK1yYy365T38W8wT0cbdcJrI87ycS37HeB8bzpFJZSY/Dzv48Yy19mDZJHLJLCRqyxNeIlBPsVC8fvxQhzr+ZyS3Wi8Dsa2Sgjt/wd0xPULLCJlb37s+1aWgYYylr9QR1uhXheYfkXFED+saGWwY1jlYL5e2Oo9n3sviBYwJxIZ+RTKFgwlXV5S+Jx/MbDpgnVHP1KaoU6vvzdWYwMChdHV/6PhZVbeT2txq7Qt+zQN59IGrOWf6vlMkHxfUzMTD58CE+xAaz/D05ljHMesLj9hb3MSrymw0PcwoFGWUMIzIQE73pUVYNE7fVHa8HqUOdoxZ5dRZqXRVox1xd9siIPE3e6CuVQIMabTp1YLno=|Y38qtTuCwNLDqFnzJ3Cgbjm1SE15OnhDm9iAMABaQBA=".parse().unwrap();
814818

815819
let request = VerifyAsymmetricKeysRequest {
816-
user_key: user_key.0.to_base64(),
820+
user_key: user_key.0.to_base64().unwrap(),
817821
user_public_key: key_pair.public,
818822
user_key_encrypted_private_key: undecryptable_private_key,
819823
};
@@ -834,7 +838,7 @@ mod tests {
834838
.unwrap();
835839

836840
let request = VerifyAsymmetricKeysRequest {
837-
user_key: user_key.0.to_base64(),
841+
user_key: user_key.0.to_base64().unwrap(),
838842
user_public_key: key_pair.public,
839843
user_key_encrypted_private_key: invalid_private_key,
840844
};
@@ -850,7 +854,7 @@ mod tests {
850854
let new_key_pair = user_key.make_key_pair().unwrap();
851855

852856
let request = VerifyAsymmetricKeysRequest {
853-
user_key: user_key.0.to_base64(),
857+
user_key: user_key.0.to_base64().unwrap(),
854858
user_public_key: key_pair.public,
855859
user_key_encrypted_private_key: new_key_pair.private,
856860
};

crates/bitwarden-crypto/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ argon2 = { version = ">=0.5.0, <0.6", features = [
2929
base64 = ">=0.22.1, <0.23"
3030
bitwarden-error = { workspace = true }
3131
cbc = { version = ">=0.1.2, <0.2", features = ["alloc", "zeroize"] }
32+
ciborium = "0.2.2"
3233
generic-array = { version = ">=0.14.7, <1.0", features = ["zeroize"] }
3334
hkdf = ">=0.12.3, <0.13"
3435
hmac = ">=0.12.1, <0.13"
@@ -40,6 +41,7 @@ rayon = ">=1.8.1, <2.0"
4041
rsa = ">=0.9.2, <0.10"
4142
schemars = { workspace = true }
4243
serde = { workspace = true }
44+
serde_bytes = "0.11.15"
4345
sha1 = ">=0.10.5, <0.11"
4446
sha2 = ">=0.10.6, <0.11"
4547
subtle = ">=2.5.0, <3.0"

crates/bitwarden-crypto/src/error.rs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pub enum CryptoError {
5353

5454
#[error("Key algorithm does not match encrypted data type")]
5555
WrongKeyType,
56+
57+
#[error("Encoding error")]
58+
EncodingError,
5659
}
5760

5861
#[derive(Debug, Error)]

crates/bitwarden-crypto/src/keys/device_key.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl DeviceKey {
3535
let device_private_key = AsymmetricCryptoKey::generate(&mut rng);
3636

3737
// Encrypt both the key and mac_key of the user key
38-
let data = user_key.to_vec();
38+
let data = user_key.to_encoded(false)?;
3939

4040
let protected_user_key =
4141
AsymmetricEncString::encrypt_rsa2048_oaep_sha1(&data, &device_private_key)?;
@@ -49,7 +49,7 @@ impl DeviceKey {
4949
.encrypt_with_key(&device_key.0)?;
5050

5151
Ok(TrustDeviceResponse {
52-
device_key: device_key.to_base64(),
52+
device_key: device_key.to_base64()?,
5353
protected_user_key,
5454
protected_device_private_key,
5555
protected_device_public_key,
@@ -71,7 +71,7 @@ impl DeviceKey {
7171
Ok(user_key)
7272
}
7373

74-
fn to_base64(&self) -> String {
74+
fn to_base64(&self) -> Result<String> {
7575
self.0.to_base64()
7676
}
7777
}

crates/bitwarden-crypto/src/keys/master_key.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl MasterKey {
6060

6161
/// Derive the master key hash, used for local and remote password validation.
6262
pub fn derive_master_key_hash(&self, password: &[u8], purpose: HashPurpose) -> Result<String> {
63-
let hash = util::pbkdf2(self.inner_bytes(), password, purpose as u32);
63+
let hash = util::pbkdf2(self.inner_bytes().as_slice(), password, purpose as u32);
6464

6565
Ok(STANDARD.encode(hash))
6666
}
@@ -113,7 +113,7 @@ pub(super) fn encrypt_user_key(
113113
user_key: &SymmetricCryptoKey,
114114
) -> Result<EncString> {
115115
let stretched_master_key = stretch_key(master_key)?;
116-
let user_key_bytes = Zeroizing::new(user_key.to_vec());
116+
let user_key_bytes = Zeroizing::new(user_key.to_encoded(false)?);
117117
EncString::encrypt_aes256_hmac(&user_key_bytes, &stretched_master_key)
118118
}
119119

crates/bitwarden-crypto/src/keys/shareable_key.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ mod tests {
4444
#[test]
4545
fn test_derive_shareable_key() {
4646
let key = derive_shareable_key(Zeroizing::new(*b"&/$%F1a895g67HlX"), "test_key", None);
47-
assert_eq!(SymmetricCryptoKey::Aes256CbcHmacKey(key).to_base64(), "4PV6+PcmF2w7YHRatvyMcVQtI7zvCyssv/wFWmzjiH6Iv9altjmDkuBD1aagLVaLezbthbSe+ktR+U6qswxNnQ==");
47+
assert_eq!(SymmetricCryptoKey::Aes256CbcHmacKey(key).to_base64().unwrap(), "4PV6+PcmF2w7YHRatvyMcVQtI7zvCyssv/wFWmzjiH6Iv9altjmDkuBD1aagLVaLezbthbSe+ktR+U6qswxNnQ==");
4848

4949
let key = derive_shareable_key(
5050
Zeroizing::new(*b"67t9b5g67$%Dh89n"),
5151
"test_key",
5252
Some("test"),
5353
);
54-
assert_eq!(SymmetricCryptoKey::Aes256CbcHmacKey(key).to_base64(), "F9jVQmrACGx9VUPjuzfMYDjr726JtL300Y3Yg+VYUnVQtQ1s8oImJ5xtp1KALC9h2nav04++1LDW4iFD+infng==");
54+
assert_eq!(SymmetricCryptoKey::Aes256CbcHmacKey(key).to_base64().unwrap(), "F9jVQmrACGx9VUPjuzfMYDjr726JtL300Y3Yg+VYUnVQtQ1s8oImJ5xtp1KALC9h2nav04++1LDW4iFD+infng==");
5555
}
5656
}

0 commit comments

Comments
 (0)