sentc_crypto_utils/
lib.rs

1#![no_std]
2#![allow(clippy::type_complexity)]
3
4extern crate alloc;
5
6use alloc::string::String;
7use alloc::vec::Vec;
8
9use base64ct::{Base64, Encoding};
10use pem_rfc7468::LineEnding;
11use sentc_crypto_common::server_default::ServerSuccessOutput;
12use sentc_crypto_common::ServerOutput;
13use sentc_crypto_core::cryptomat::{ClientRandomValue, ClientRandomValueComposer, DeriveAuthKeyForAuth, HashedAuthenticationKey};
14use serde::Deserialize;
15
16use crate::error::SdkUtilError;
17
18pub mod cryptomat;
19pub mod error;
20#[cfg(all(feature = "crypto_full", any(feature = "rustls", feature = "wasm")))]
21pub mod full;
22pub mod group;
23#[cfg(any(feature = "rustls", feature = "wasm"))]
24pub mod http;
25pub mod jwt;
26pub mod user;
27
28pub fn handle_server_response<'de, T: Deserialize<'de>>(res: &'de str) -> Result<T, SdkUtilError>
29{
30	let server_output = ServerOutput::<T>::from_string(res)?;
31
32	if !server_output.status {
33		let err_code = match server_output.err_code {
34			Some(c) => c,
35			None => return Err(SdkUtilError::JsonParse),
36		};
37
38		let err_msg = match server_output.err_msg {
39			Some(m) => m,
40			None => return Err(SdkUtilError::JsonParse),
41		};
42
43		return Err(SdkUtilError::ServerErr(err_code, err_msg));
44	}
45
46	match server_output.result {
47		Some(r) => Ok(r),
48		None => Err(SdkUtilError::JsonParse),
49	}
50}
51
52/**
53Getting the result of a simple server response.
54 */
55pub fn handle_general_server_response(res: &str) -> Result<(), SdkUtilError>
56{
57	handle_server_response::<ServerSuccessOutput>(res)?;
58
59	Ok(())
60}
61
62pub fn client_random_value_to_string(client_random_value: &impl ClientRandomValue) -> String
63{
64	let out = client_random_value.prepare_export();
65
66	Base64::encode_string(out)
67}
68
69pub fn hashed_authentication_key_to_string(hashed_authentication_key_bytes: &impl HashedAuthenticationKey) -> String
70{
71	let out = hashed_authentication_key_bytes.prepare_export();
72
73	Base64::encode_string(out)
74}
75
76pub fn derive_auth_key_for_auth_to_string(derive_auth_key_for_auth: &impl DeriveAuthKeyForAuth) -> String
77{
78	let out = derive_auth_key_for_auth.prepare_export();
79
80	Base64::encode_string(out)
81}
82
83pub fn client_random_value_from_string<C: ClientRandomValueComposer>(client_random_value: &str, alg: &str) -> Result<C::Value, SdkUtilError>
84{
85	let v = Base64::decode_vec(client_random_value).map_err(|_| SdkUtilError::DecodeRandomValueFailed)?;
86	//normally not needed only when the client needs to create the rand value, e.g- for key update.
87	Ok(C::from_bytes(v, alg)?)
88}
89
90/**
91Get the head and the data.
92
93This can not only be used internally, to get the used key_id
94 */
95#[cfg(feature = "encryption")]
96pub fn split_head_and_encrypted_data<'a, T: Deserialize<'a>>(data_with_head: &'a [u8]) -> Result<(T, &[u8]), SdkUtilError>
97{
98	let mut i = 0usize;
99	for data_itr in data_with_head {
100		if *data_itr == 0u8 {
101			//the mark to split the head from the data
102			//found the ii where to split head from data
103			break;
104		}
105
106		i += 1;
107	}
108
109	let head = serde_json::from_slice(&data_with_head[..i])?;
110
111	//ignore the zero byte
112	Ok((head, &data_with_head[i + 1..]))
113}
114
115#[cfg(feature = "encryption")]
116pub fn put_head_and_encrypted_data<T: serde::Serialize>(head: &T, encrypted: &[u8]) -> Result<Vec<u8>, SdkUtilError>
117{
118	let head = serde_json::to_string(head).map_err(|_| SdkUtilError::JsonToStringFailed)?;
119
120	let mut out = Vec::with_capacity(head.len() + 1 + encrypted.len());
121
122	out.extend_from_slice(head.as_bytes());
123	out.extend_from_slice(&[0u8]);
124	out.extend_from_slice(encrypted);
125
126	Ok(out)
127}
128
129pub fn import_key_from_pem(pem: &str) -> Result<Vec<u8>, SdkUtilError>
130{
131	let (_type_label, data) = pem_rfc7468::decode_vec(pem.as_bytes()).map_err(|_| SdkUtilError::ImportingKeyFromPemFailed)?;
132
133	Ok(data)
134}
135
136pub fn export_key_to_pem(key: &[u8]) -> Result<String, SdkUtilError>
137{
138	//export should not panic because we are creating the keys
139	let key = pem_rfc7468::encode_string("PUBLIC KEY", LineEnding::default(), key).map_err(|_| SdkUtilError::ExportingPublicKeyFailed)?;
140
141	Ok(key)
142}