Skip to content

Commit b7b8dec

Browse files
authored
[PM-8618] Credential Exchange (#32)
Initial implementation of the Credential Exchange Format. Currently supports the following types: - Login - BasicAuth - Passkey - Totp (Export only) - Note (Export only)
1 parent 28c7e29 commit b7b8dec

File tree

20 files changed

+1295
-117
lines changed

20 files changed

+1295
-117
lines changed

Cargo.lock

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bitwarden-exporters/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ license-file.workspace = true
1515
keywords.workspace = true
1616

1717
[features]
18-
uniffi = ["dep:uniffi"] # Uniffi bindings
18+
uniffi = ["dep:uniffi", "bitwarden-core/uniffi"] # Uniffi bindings
1919

2020
[dependencies]
2121
base64 = ">=0.22.1, <0.23"
2222
bitwarden-core = { workspace = true }
2323
bitwarden-crypto = { workspace = true }
24+
bitwarden-fido = { workspace = true }
2425
bitwarden-vault = { workspace = true }
2526
chrono = { workspace = true, features = ["std"] }
27+
credential-exchange-types = { git = "https://github.com/bitwarden/credential-exchange.git", rev = "60bf99f097af72144b0eaa757ccb50fd46049f24" }
2628
csv = "1.3.0"
2729
schemars = { workspace = true }
2830
serde = { workspace = true }
@@ -31,5 +33,8 @@ thiserror = { workspace = true }
3133
uniffi = { workspace = true, optional = true }
3234
uuid = { workspace = true }
3335

36+
[dev-dependencies]
37+
rand = ">=0.8.5, <0.9"
38+
3439
[lints]
3540
workspace = true

crates/bitwarden-exporters/src/client_exporter.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use bitwarden_core::Client;
22
use bitwarden_vault::{Cipher, Collection, Folder};
33

44
use crate::{
5-
export::{export_organization_vault, export_vault},
6-
ExportError, ExportFormat,
5+
export::{export_cxf, export_organization_vault, export_vault, import_cxf},
6+
Account, ExportError, ExportFormat,
77
};
88

99
pub struct ClientExporters<'a> {
@@ -32,6 +32,30 @@ impl<'a> ClientExporters<'a> {
3232
) -> Result<String, ExportError> {
3333
export_organization_vault(collections, ciphers, format)
3434
}
35+
36+
/// Credential Exchange Format (CXF)
37+
///
38+
/// *Warning:* Expect this API to be unstable, and it will change in the future.
39+
///
40+
/// For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager).
41+
/// Ideally the input should be immediately serialized from [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount).
42+
pub fn export_cxf(
43+
&self,
44+
account: Account,
45+
ciphers: Vec<Cipher>,
46+
) -> Result<String, ExportError> {
47+
export_cxf(self.client, account, ciphers)
48+
}
49+
50+
/// Credential Exchange Format (CXF)
51+
///
52+
/// *Warning:* Expect this API to be unstable, and it will change in the future.
53+
///
54+
/// For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager).
55+
/// Ideally the input should be immediately serialized from [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount).
56+
pub fn import_cxf(&self, payload: String) -> Result<Vec<Cipher>, ExportError> {
57+
import_cxf(self.client, payload)
58+
}
3559
}
3660

3761
pub trait ClientExportersExt<'a> {

crates/bitwarden-exporters/src/csv.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ mod tests {
139139
r#match: None,
140140
}],
141141
totp: None,
142+
fido2_credentials: None,
142143
})),
143144
favorite: false,
144145
reprompt: 0,
@@ -160,6 +161,7 @@ mod tests {
160161
r#match: None,
161162
}],
162163
totp: Some("steam://ABCD123".to_string()),
164+
fido2_credentials: None,
163165
})),
164166
favorite: true,
165167
reprompt: 0,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::borrow::Cow;
2+
3+
use thiserror::Error;
4+
5+
#[derive(Error, Debug)]
6+
pub enum CxpError {
7+
#[error("JSON error: {0}")]
8+
Serde(#[from] serde_json::Error),
9+
10+
#[error("Internal error: {0}")]
11+
Internal(Cow<'static, str>),
12+
}

0 commit comments

Comments
 (0)