sentc/user/
mod.rs

1#![doc=include_str!("../../doc/user.md")]
2#![doc=include_str!("../../doc/encrypt_user.md")]
3#![doc=include_str!("../../doc/file.md")]
4
5pub mod crypto_sync;
6mod export;
7#[cfg(feature = "file")]
8pub mod file;
9#[cfg(feature = "network")]
10pub mod net;
11
12use std::marker::PhantomData;
13
14use sentc_crypto::entities::user::{UserDataInt, UserKeyDataInt};
15use sentc_crypto::group::Group as SdkGroup;
16use sentc_crypto::sdk_common::group::GroupHmacData;
17use sentc_crypto::sdk_common::user::{UserPublicKeyData, UserVerifyKeyData};
18use sentc_crypto::sdk_common::{DeviceId, SymKeyId, UserId};
19use sentc_crypto::sdk_core::cryptomat::{PwHash, SearchableKeyGen, SortableKeyGen};
20use sentc_crypto::sdk_utils::cryptomat::{
21	PkFromUserKeyWrapper,
22	SearchableKeyComposerWrapper,
23	SignComposerWrapper,
24	SignKeyPairWrapper,
25	SortableKeyComposerWrapper,
26	StaticKeyComposerWrapper,
27	StaticKeyPairWrapper,
28	SymKeyComposerWrapper,
29	SymKeyGenWrapper,
30	SymKeyWrapper,
31	VerifyKFromUserKeyWrapper,
32};
33use sentc_crypto::user::{generate_user_register_data, User as SdkUser};
34
35use crate::error::SentcError;
36use crate::group::prepare_group_keys_ref;
37use crate::KeyMap;
38
39/// The user struct holds all information about the user.
40///
41/// A user got its user group and device keys.
42pub struct User<SGen, StGen, SignGen, SearchGen, SortGen, SC, StC, SignC, SearchC, SortC, PC, VC, PwH>
43where
44	SGen: SymKeyGenWrapper,
45	StGen: StaticKeyPairWrapper,
46	SignGen: SignKeyPairWrapper,
47	SearchGen: SearchableKeyGen,
48	SortGen: SortableKeyGen,
49	SC: SymKeyComposerWrapper,
50	StC: StaticKeyComposerWrapper,
51	SignC: SignComposerWrapper,
52	SearchC: SearchableKeyComposerWrapper,
53	SortC: SortableKeyComposerWrapper,
54	PC: PkFromUserKeyWrapper,
55	VC: VerifyKFromUserKeyWrapper,
56	PwH: PwHash,
57{
58	user_id: UserId,
59	user_identifier: String,
60	device_id: DeviceId,
61
62	jwt: String,
63	refresh_token: String,
64
65	mfa: bool,
66
67	//device keys
68	private_device_key: StC::SkWrapper,
69	public_device_key: StC::PkWrapper,
70	sign_device_key: SignC::SignKWrapper,
71	verify_device_key: SignC::VerifyKWrapper,
72	exported_verify_device_key: UserVerifyKeyData,
73	exported_public_device_key: UserPublicKeyData,
74
75	//user keys
76	#[allow(clippy::type_complexity)]
77	user_keys: Vec<UserKeyDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>>,
78	key_map: KeyMap,
79	newest_key_id: SymKeyId,
80	hmac_keys: Vec<SearchC::SearchableKeyWrapper>,
81
82	base_url: String,
83	app_token: String,
84
85	_sgen: PhantomData<SGen>,
86	_st_gen: PhantomData<StGen>,
87	_sign_gen: PhantomData<SignGen>,
88	_search_gen: PhantomData<SearchGen>,
89	_sort_gen: PhantomData<SortGen>,
90	_sc: PhantomData<SC>,
91	_st_c: PhantomData<StC>,
92	_sign_c: PhantomData<SignC>,
93	_search_c: PhantomData<SearchC>,
94	_sort_c: PhantomData<SortC>,
95	_pc: PhantomData<PC>,
96	_vc: PhantomData<VC>,
97	_pw: PhantomData<PwH>,
98}
99
100impl<SGen, StGen, SignGen, SearchGen, SortGen, SC, StC, SignC, SearchC, SortC, PC, VC, PwH>
101	User<SGen, StGen, SignGen, SearchGen, SortGen, SC, StC, SignC, SearchC, SortC, PC, VC, PwH>
102where
103	SGen: SymKeyGenWrapper,
104	StGen: StaticKeyPairWrapper,
105	SignGen: SignKeyPairWrapper,
106	SearchGen: SearchableKeyGen,
107	SortGen: SortableKeyGen,
108	SC: SymKeyComposerWrapper,
109	StC: StaticKeyComposerWrapper,
110	SignC: SignComposerWrapper,
111	SearchC: SearchableKeyComposerWrapper,
112	SortC: SortableKeyComposerWrapper,
113	PC: PkFromUserKeyWrapper,
114	VC: VerifyKFromUserKeyWrapper,
115	PwH: PwHash,
116{
117	#[allow(clippy::type_complexity)]
118	fn new_user(
119		base_url: String,
120		app_token: String,
121		user_identifier: String,
122		data: UserDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>,
123		mfa: bool,
124	) -> Result<(Self, Vec<GroupHmacData>), SentcError>
125	{
126		let newest_key_id = data
127			.user_keys
128			.first()
129			.ok_or(SentcError::KeyNotFound)?
130			.group_key
131			.get_id()
132			.to_string();
133
134		let mut key_map: KeyMap = Default::default();
135
136		for (i, key) in data.user_keys.iter().enumerate() {
137			key_map.insert(key.group_key.get_id().to_string(), i);
138		}
139
140		Ok((
141			Self {
142				user_id: data.user_id,
143				user_identifier,
144				device_id: data.device_id,
145				jwt: data.jwt,
146				refresh_token: data.refresh_token,
147				mfa,
148				private_device_key: data.device_keys.private_key,
149				public_device_key: data.device_keys.public_key,
150				sign_device_key: data.device_keys.sign_key,
151				verify_device_key: data.device_keys.verify_key,
152				exported_verify_device_key: data.device_keys.exported_verify_key,
153				exported_public_device_key: data.device_keys.exported_public_key,
154				user_keys: data.user_keys,
155				key_map,
156				newest_key_id,
157				hmac_keys: Vec::with_capacity(data.hmac_keys.len()),
158				base_url,
159				app_token,
160
161				_sgen: Default::default(),
162				_st_gen: Default::default(),
163				_sign_gen: Default::default(),
164				_search_gen: Default::default(),
165				_sort_gen: Default::default(),
166				_sc: Default::default(),
167				_st_c: Default::default(),
168				_sign_c: Default::default(),
169				_search_c: Default::default(),
170				_sort_c: Default::default(),
171				_pc: Default::default(),
172				_vc: Default::default(),
173				_pw: Default::default(),
174			},
175			data.hmac_keys,
176		))
177	}
178
179	#[cfg(not(feature = "network"))]
180	#[allow(clippy::too_many_arguments, clippy::type_complexity)]
181	pub fn new(
182		base_url: String,
183		app_token: String,
184		user_identifier: String,
185		data: UserDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>,
186		mfa: bool,
187	) -> Result<Self, SentcError>
188	{
189		let (mut u, hmac_keys) = Self::new_user(base_url, app_token, user_identifier, data, mfa)?;
190
191		u.decrypt_hmac_keys_sync(hmac_keys)?;
192
193		Ok(u)
194	}
195
196	pub fn get_user_id(&self) -> &str
197	{
198		&self.user_id
199	}
200
201	pub fn get_identifier(&self) -> &str
202	{
203		&self.user_identifier
204	}
205
206	pub fn get_device_id(&self) -> &str
207	{
208		&self.device_id
209	}
210
211	pub fn get_jwt_sync(&self) -> &str
212	{
213		&self.jwt
214	}
215
216	pub fn get_refresh_token(&self) -> &str
217	{
218		&self.refresh_token
219	}
220
221	#[allow(clippy::type_complexity)]
222	pub fn get_newest_key(
223		&self,
224	) -> Option<&UserKeyDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>>
225	{
226		let index = self.key_map.get(&self.newest_key_id).unwrap_or(&0);
227
228		self.user_keys.get(*index)
229	}
230
231	pub fn get_newest_public_key(&self) -> Option<&StC::PkWrapper>
232	{
233		self.get_newest_key().map(|k| &k.public_key)
234	}
235
236	pub fn get_newest_exported_public_key(&self) -> Option<&UserPublicKeyData>
237	{
238		self.get_newest_key().map(|k| &k.exported_public_key)
239	}
240
241	pub fn get_newest_sign_key(&self) -> Option<&SignC::SignKWrapper>
242	{
243		self.get_newest_key().map(|k| &k.sign_key)
244	}
245
246	pub fn set_jwt(&mut self, jwt: String)
247	{
248		self.jwt = jwt;
249	}
250
251	pub fn set_refresh_token(&mut self, refresh_token: String)
252	{
253		self.refresh_token = refresh_token;
254	}
255
256	#[allow(clippy::type_complexity)]
257	pub fn get_user_keys(
258		&self,
259		key_id: &str,
260	) -> Option<&UserKeyDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>>
261	{
262		self.key_map
263			.get(key_id)
264			.and_then(|k| self.user_keys.get(*k))
265	}
266
267	pub fn has_user_keys(&self, key_id: &str) -> Option<&usize>
268	{
269		self.key_map.get(key_id)
270	}
271
272	pub fn prepare_register_device_keys(&self, sever_output: &str) -> Result<(String, UserPublicKeyData), SentcError>
273	{
274		let (keys, _) = self.prepare_group_keys_ref(0);
275
276		let key_session = self.user_keys.len() > 50;
277
278		Ok(SdkUser::<
279			SGen,
280			StGen,
281			SignGen,
282			SearchGen,
283			SortGen,
284			SC,
285			StC,
286			SignC,
287			SearchC,
288			SortC,
289			PC,
290			VC,
291			PwH,
292		>::prepare_register_device(sever_output, &keys, key_session)?)
293	}
294
295	pub fn get_mfa(&self) -> bool
296	{
297		self.mfa
298	}
299
300	pub(crate) fn prepare_group_keys_ref(&self, page: usize) -> (Vec<&SC::SymmetricKeyWrapper>, bool)
301	{
302		prepare_group_keys_ref!(self.user_keys, page, 50)
303	}
304
305	pub fn get_private_device_key(&self) -> &StC::SkWrapper
306	{
307		&self.private_device_key
308	}
309
310	pub fn get_public_device_key(&self) -> &StC::PkWrapper
311	{
312		&self.public_device_key
313	}
314
315	pub fn get_verify_device_key(&self) -> &SignC::VerifyKWrapper
316	{
317		&self.verify_device_key
318	}
319
320	pub fn get_exported_verify_device_key(&self) -> &UserVerifyKeyData
321	{
322		&self.exported_verify_device_key
323	}
324
325	pub fn get_exported_public_device_key(&self) -> &UserPublicKeyData
326	{
327		&self.exported_public_device_key
328	}
329
330	#[cfg(not(feature = "network"))]
331	fn decrypt_hmac_keys_sync(&mut self, hmac_keys: Vec<GroupHmacData>) -> Result<(), SentcError>
332	{
333		for hmac_key in hmac_keys {
334			let key = self
335				.get_user_keys(&hmac_key.encrypted_hmac_encryption_key_id)
336				.ok_or(SentcError::KeyNotFound)?;
337
338			let decrypted_hmac_key =
339				SdkGroup::<SGen, StGen, SignGen, SearchGen, SortGen, SC, StC, SignC, SearchC, SortC, PC, VC>::decrypt_group_hmac_key(
340					&key.group_key,
341					hmac_key,
342				)?;
343
344			self.hmac_keys.push(decrypted_hmac_key);
345		}
346
347		Ok(())
348	}
349
350	#[allow(clippy::type_complexity)]
351	pub fn set_hmac_key(
352		&mut self,
353		user_key: &UserKeyDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>,
354		hmac_key: GroupHmacData,
355	) -> Result<(), SentcError>
356	{
357		let decrypted_hmac_key =
358			SdkGroup::<SGen, StGen, SignGen, SearchGen, SortGen, SC, StC, SignC, SearchC, SortC, PC, VC>::decrypt_group_hmac_key(
359				&user_key.group_key,
360				hmac_key,
361			)?;
362
363		self.hmac_keys.push(decrypted_hmac_key);
364
365		Ok(())
366	}
367
368	pub fn prepare_create_group(&self, sign: bool) -> Result<String, SentcError>
369	{
370		let sign_key = if sign { self.get_newest_sign_key() } else { None };
371
372		Ok(SdkGroup::<
373			SGen,
374			StGen,
375			SignGen,
376			SearchGen,
377			SortGen,
378			SC,
379			StC,
380			SignC,
381			SearchC,
382			SortC,
383			PC,
384			VC,
385		>::prepare_create(
386			self.get_newest_public_key()
387				.ok_or(SentcError::KeyNotFound)?,
388			sign_key,
389			self.user_id.to_string(),
390		)?)
391	}
392
393	pub fn create_safety_number_sync(&self, other_user: Option<&str>, other_user_key: Option<&UserVerifyKeyData>) -> Result<String, SentcError>
394	{
395		Ok(SdkUser::<
396			SGen,
397			StGen,
398			SignGen,
399			SearchGen,
400			SortGen,
401			SC,
402			StC,
403			SignC,
404			SearchC,
405			SortC,
406			PC,
407			VC,
408			PwH,
409		>::create_safety_number(
410			&self
411				.get_newest_key()
412				.ok_or(SentcError::KeyNotFound)?
413				.exported_verify_key,
414			self.get_user_id(),
415			other_user_key,
416			other_user,
417		)?)
418	}
419
420	pub fn set_newest_key_id(&mut self, id: SymKeyId)
421	{
422		self.newest_key_id = id;
423	}
424
425	#[allow(clippy::type_complexity)]
426	pub fn extend_user_key(
427		&mut self,
428		user_keys: UserKeyDataInt<SC::SymmetricKeyWrapper, StC::SkWrapper, StC::PkWrapper, SignC::SignKWrapper, SignC::VerifyKWrapper>,
429	)
430	{
431		//keys are already decrypted from the sentc full sdk and the private device key
432		self.key_map
433			.insert(user_keys.group_key.get_id().to_string(), self.user_keys.len());
434		self.user_keys.push(user_keys);
435	}
436
437	//==============================================================================================
438
439	pub fn prepare_register(user_identifier: &str, password: &str) -> Result<String, SentcError>
440	{
441		if user_identifier.is_empty() || password.is_empty() {
442			return Err(SentcError::UsernameOrPasswordRequired);
443		}
444
445		Ok(SdkUser::<
446			SGen,
447			StGen,
448			SignGen,
449			SearchGen,
450			SortGen,
451			SC,
452			StC,
453			SignC,
454			SearchC,
455			SortC,
456			PC,
457			VC,
458			PwH,
459		>::register(user_identifier, password)?)
460	}
461
462	pub fn prepare_register_device_start(device_identifier: &str, password: &str) -> Result<String, SentcError>
463	{
464		if device_identifier.is_empty() || password.is_empty() {
465			return Err(SentcError::UsernameOrPasswordRequired);
466		}
467
468		Ok(SdkUser::<
469			SGen,
470			StGen,
471			SignGen,
472			SearchGen,
473			SortGen,
474			SC,
475			StC,
476			SignC,
477			SearchC,
478			SortC,
479			PC,
480			VC,
481			PwH,
482		>::prepare_register_device_start(device_identifier, password)?)
483	}
484}
485
486pub fn generate_register_data() -> Result<(String, String), SentcError>
487{
488	Ok(generate_user_register_data()?)
489}
490
491pub fn done_register(server_output: &str) -> Result<UserId, SentcError>
492{
493	Ok(sentc_crypto::user::done_register(server_output)?)
494}
495
496pub fn done_register_device_start(server_output: &str) -> Result<(), SentcError>
497{
498	Ok(sentc_crypto::user::done_register_device_start(server_output)?)
499}