1use color_eyre::eyre::Result;
2#[cfg(target_family = "wasm")]
3fn main() -> Result<()> {
4 println!("the keystore dump tool is not available for WASM");
5 Ok(())
6}
7
8#[cfg(not(target_family = "wasm"))]
9#[tokio::main]
10async fn main() -> Result<()> {
11 #[derive(Debug, clap::Parser)]
12 #[command(author, version, about, long_about = None)]
13 struct Args {
14 #[arg(short, long)]
15 key: String,
17
18 path: String,
19 }
20
21 use chrono::TimeZone;
22 use clap::Parser as _;
23 use color_eyre::eyre::eyre;
24 use core_crypto_keystore::{Connection as Keystore, DatabaseKey, connection::FetchFromDatabase, entities::*};
25 use openmls::prelude::TlsDeserializeTrait;
26 use serde::ser::{SerializeMap, Serializer};
27
28 color_eyre::install()?;
29
30 let args = Args::parse();
31
32 if !tokio::fs::try_exists(&args.path).await.unwrap_or_default() {
33 return Err(eyre!("File not found: {}", args.path));
34 }
35
36 let key = DatabaseKey::try_from(hex::decode(&args.key)?.as_slice())?;
37 let keystore = Keystore::open_with_key(&args.path, &key)
38 .await
39 .map_err(|e| eyre!("The passkey is probably wrong; [err: {e}]"))?;
40
41 let mut json_serializer = serde_json::Serializer::pretty(std::io::stdout());
42 let mut json_map = json_serializer.serialize_map(None)?;
43
44 let mut credentials: Vec<serde_json::Value> = vec![];
45 for cred in keystore
46 .find_all::<MlsCredential>(Default::default())
47 .await?
48 .into_iter()
49 {
50 let mls_credential = openmls::prelude::Credential::tls_deserialize(&mut cred.credential.as_slice())?;
51 let date = chrono::Utc
52 .timestamp_opt(cred.created_at as i64, 0)
53 .single()
54 .ok_or_else(|| eyre!("Cannot parse credential creation date"))?;
55
56 credentials.push(serde_json::json!({
57 "id": cred.id,
58 "credential": mls_credential,
59 "created_at": date
60 }));
61 }
62 json_map.serialize_entry("mls_credentials", &credentials)?;
63
64 let mut signature_keypairs: Vec<serde_json::Value> = vec![];
65 for kp in keystore
66 .find_all::<MlsSignatureKeyPair>(Default::default())
67 .await?
68 .into_iter()
69 {
70 let mls_keypair = openmls_basic_credential::SignatureKeyPair::tls_deserialize(&mut kp.keypair.as_slice())?;
71 signature_keypairs.push(serde_json::json!({
72 "signature_scheme": kp.signature_scheme,
73 "mls_keypair": mls_keypair,
74 "credential_id": kp.credential_id,
75 }));
76 }
77 json_map.serialize_entry("mls_signature_keypairs", &signature_keypairs)?;
78
79 let hpke_sks: Vec<openmls_traits::types::HpkePrivateKey> = keystore
80 .find_all::<MlsHpkePrivateKey>(Default::default())
81 .await?
82 .into_iter()
83 .map(|hpke_sk| postcard::from_bytes::<openmls_traits::types::HpkePrivateKey>(&hpke_sk.sk))
84 .collect::<postcard::Result<_>>()?;
85 json_map.serialize_entry("mls_hpke_private_keys", &hpke_sks)?;
86
87 let hpke_keypairs: Vec<openmls_traits::types::HpkeKeyPair> = keystore
88 .find_all::<MlsEncryptionKeyPair>(Default::default())
89 .await?
90 .into_iter()
91 .map(|hpke_kp| postcard::from_bytes::<openmls_traits::types::HpkeKeyPair>(&hpke_kp.sk))
92 .collect::<postcard::Result<_>>()?;
93 json_map.serialize_entry("mls_hpke_keypairs", &hpke_keypairs)?;
94
95 let mut external_psks: std::collections::HashMap<String, openmls::schedule::psk::PskBundle> = Default::default();
96 for psk in keystore.find_all::<MlsPskBundle>(Default::default()).await?.into_iter() {
97 let mls_psk = postcard::from_bytes::<openmls::schedule::psk::PskBundle>(&psk.psk)?;
98 external_psks.insert(hex::encode(&psk.psk_id), mls_psk);
99 }
100
101 json_map.serialize_entry("external_psks", &external_psks)?;
102
103 let keypackages: Vec<openmls::prelude::KeyPackage> = keystore
104 .find_all::<MlsKeyPackage>(Default::default())
105 .await?
106 .into_iter()
107 .map(|kp| postcard::from_bytes::<openmls::prelude::KeyPackage>(&kp.keypackage))
108 .collect::<postcard::Result<_>>()?;
109 json_map.serialize_entry("mls_keypackages", &keypackages)?;
110
111 let e2ei_enrollments: Vec<core_crypto::prelude::E2eiEnrollment> = keystore
112 .find_all::<E2eiEnrollment>(Default::default())
113 .await?
114 .into_iter()
115 .map(|enrollment| serde_json::from_slice::<core_crypto::prelude::E2eiEnrollment>(&enrollment.content))
116 .collect::<serde_json::Result<_>>()?;
117 json_map.serialize_entry("e2ei_enrollments", &e2ei_enrollments)?;
118
119 let pgroups: Vec<openmls::prelude::MlsGroup> = keystore
120 .find_all::<PersistedMlsGroup>(Default::default())
121 .await?
122 .into_iter()
123 .map(|pgroup| core_crypto_keystore::deser::<openmls::prelude::MlsGroup>(&pgroup.state))
124 .collect::<core_crypto_keystore::CryptoKeystoreResult<_>>()?;
125 json_map.serialize_entry("mls_groups", &pgroups)?;
126
127 let pegroups: Vec<openmls::prelude::MlsGroup> = keystore
128 .find_all::<PersistedMlsPendingGroup>(Default::default())
129 .await?
130 .into_iter()
131 .map(|pgroup| core_crypto_keystore::deser::<openmls::prelude::MlsGroup>(&pgroup.state))
132 .collect::<core_crypto_keystore::CryptoKeystoreResult<_>>()?;
133 json_map.serialize_entry("mls_pending_groups", &pegroups)?;
134
135 if let Some(proteus_identity) = keystore.find::<ProteusIdentity>(&[]).await? {
136 let identity = {
137 let sk = proteus_identity.sk_raw();
138 let pk = proteus_identity.pk_raw();
139 proteus_wasm::keys::IdentityKeyPair::from_raw_key_pair(*sk, *pk)?
140 };
141 json_map.serialize_entry("proteus_identity", &identity)?;
142
143 let prekeys: Vec<proteus_wasm::keys::PreKey> = keystore
144 .find_all::<ProteusPrekey>(Default::default())
145 .await?
146 .into_iter()
147 .map(|pk| proteus_wasm::keys::PreKey::deserialise(&pk.prekey))
148 .collect::<Result<Vec<_>, proteus_wasm::DecodeError>>()?;
149 json_map.serialize_entry("proteus_prekeys", &prekeys)?;
150
151 let proteus_sessions: Vec<proteus_wasm::session::Session<proteus_wasm::keys::IdentityKeyPair>> = keystore
152 .find_all::<ProteusSession>(Default::default())
153 .await?
154 .into_iter()
155 .map(|session| proteus_wasm::session::Session::deserialise(identity.clone(), &session.session))
156 .collect::<Result<Vec<_>, proteus_wasm::DecodeError>>()?;
157
158 json_map.serialize_entry("proteus_sessions", &proteus_sessions)?;
159 }
160
161 json_map.end()?;
162
163 Ok(())
164}