1use libsodium_sys::{
2 crypto_box_MACBYTES as CRYPTO_BOX_MACBYTES, crypto_box_NONCEBYTES as CRYPTO_BOX_NONCEBYTES,
3 crypto_box_PUBLICKEYBYTES as CRYPTO_BOX_PUBLICKEYBYTES,
4 crypto_box_SECRETKEYBYTES as CRYPTO_BOX_SECRETKEYBYTES, crypto_box_easy, crypto_generichash,
5 crypto_scalarmult_base, crypto_sign_BYTES as CRYPTO_SIGN_BYTES,
6 crypto_sign_PUBLICKEYBYTES as CRYPTO_SIGN_PUBLICKEYBYTES,
7 crypto_sign_SECRETKEYBYTES as CRYPTO_SIGN_SECRETKEYBYTES, crypto_sign_detached,
8 crypto_sign_ed25519_sk_to_pk,
9};
10
11use crate::{error::NcryptfError as Error, util::randombytes_buf, VERSION_2_HEADER};
12
13pub struct Request {
15 secret_key: Vec<u8>,
16 signature_secret_key: Vec<u8>,
17 nonce: Option<Vec<u8>>,
18 message: Option<Vec<u8>>,
19}
20
21impl Request {
22 pub fn encrypt(&mut self, data: String, public_key: Vec<u8>) -> Result<Vec<u8>, Error> {
24 match self.encrypt_with_nonce(data, public_key, None, Some(2)) {
25 Ok(result) => {
26 self.message = Some(result.clone());
27 return Ok(result);
28 }
29 Err(error) => return Err(error),
30 };
31 }
32
33 pub fn get_message(&self) -> Option<Vec<u8>> {
35 return self.message.clone();
36 }
37
38 pub fn encrypt_with_nonce(
40 &mut self,
41 data: String,
42 public_key: Vec<u8>,
43 nonce: Option<Vec<u8>>,
44 version: Option<i8>,
45 ) -> Result<Vec<u8>, Error> {
46 let n = match nonce {
47 Some(n) => n,
48 None => randombytes_buf(CRYPTO_BOX_NONCEBYTES as usize),
49 };
50
51 self.nonce = Some(n.clone());
52
53 if public_key.len() != (CRYPTO_BOX_PUBLICKEYBYTES as usize) {
54 return Err(Error::InvalidArgument(format!(
55 "Public key should be {} bytes",
56 CRYPTO_BOX_PUBLICKEYBYTES
57 )));
58 }
59
60 if n.clone().len() != (CRYPTO_BOX_NONCEBYTES as usize) {
61 return Err(Error::InvalidArgument(format!(
62 "Nonce should be {} bytes",
63 CRYPTO_BOX_NONCEBYTES
64 )));
65 }
66
67 match version {
68 Some(2) => {
69 let h = VERSION_2_HEADER;
71 let header = hex::decode(h.to_string()).unwrap();
72 let mut body = match self.encrypt_body(data.clone(), public_key, n.clone()) {
73 Ok(body) => body,
74 Err(error) => return Err(error),
75 };
76
77 let mut ipk: [u8; CRYPTO_BOX_PUBLICKEYBYTES as usize] =
79 vec![0; CRYPTO_BOX_PUBLICKEYBYTES as usize]
80 .try_into()
81 .unwrap();
82 let csk: [u8; CRYPTO_BOX_SECRETKEYBYTES as usize] =
83 self.secret_key.clone().try_into().unwrap();
84 let _result = unsafe { crypto_scalarmult_base(ipk.as_mut_ptr(), csk.as_ptr()) };
85
86 if _result != 0 {
87 return Err(Error::EncryptError);
88 }
89
90 let mut isk: [u8; CRYPTO_SIGN_PUBLICKEYBYTES as usize] =
92 vec![0; CRYPTO_SIGN_PUBLICKEYBYTES as usize]
93 .try_into()
94 .unwrap();
95 let ssk: [u8; CRYPTO_SIGN_SECRETKEYBYTES as usize] =
96 self.signature_secret_key.clone().try_into().unwrap();
97 let _result =
98 unsafe { crypto_sign_ed25519_sk_to_pk(isk.as_mut_ptr(), ssk.as_ptr()) };
99 if _result != 0 {
100 return Err(Error::EncryptError);
101 }
102
103 let mut signature = match self.sign(data.clone()) {
105 Ok(signature) => signature,
106 Err(error) => return Err(error),
107 };
108
109 let mut payload: Vec<u8> = Vec::<u8>::new();
110 payload.append(&mut header.clone());
111 payload.append(&mut n.clone());
112 payload.append(&mut ipk.to_vec());
113 payload.append(&mut body);
114 payload.append(&mut isk.to_vec());
115 payload.append(&mut signature);
116
117 let s: &[u8; CRYPTO_BOX_NONCEBYTES as usize] = &n.clone().try_into().unwrap();
118 let input = payload.clone();
119 let mut hash: [u8; 64] = vec![0; 64].try_into().unwrap();
120
121 let _result = unsafe {
122 crypto_generichash(
123 hash.as_mut_ptr(),
124 64,
125 input.as_ptr(),
126 input.len() as u64,
127 s.as_ptr(),
128 CRYPTO_BOX_NONCEBYTES as usize,
129 )
130 };
131
132 if _result != 0 {
133 return Err(Error::EncryptError);
134 }
135
136 payload.append(&mut hash.to_vec());
137 return Ok(payload);
138 }
139 _ => {
140 return self.encrypt_body(data.clone(), public_key, n.clone());
141 }
142 }
143 }
144
145 fn encrypt_body(
147 &self,
148 data: String,
149 public_key: Vec<u8>,
150 nonce: Vec<u8>,
151 ) -> Result<Vec<u8>, Error> {
152 let message = data.into_bytes();
153 let len = message.len();
154
155 let mut ciphertext = Box::new(vec![0u8; len + (CRYPTO_BOX_MACBYTES as usize)]);
156 let sk: [u8; CRYPTO_BOX_SECRETKEYBYTES as usize] =
157 self.secret_key.clone().try_into().unwrap();
158 let pk: [u8; CRYPTO_BOX_PUBLICKEYBYTES as usize] = public_key.clone().try_into().unwrap();
159 let n: [u8; CRYPTO_BOX_NONCEBYTES as usize] = nonce.clone().try_into().unwrap();
160
161 let result: i32 = unsafe {
162 crypto_box_easy(
163 ciphertext.as_mut_ptr(),
164 message.as_ptr(),
165 message.len().try_into().unwrap(),
166 n.as_ptr(),
167 pk.as_ptr(),
168 sk.as_ptr(),
169 )
170 };
171
172 match result {
173 0 => {
174 return Ok(ciphertext.to_vec());
175 }
176 _ => {
177 return Err(Error::DecryptError);
178 }
179 }
180 }
181
182 pub fn get_nonce(&self) -> Option<Vec<u8>> {
184 return self.nonce.clone();
185 }
186
187 pub fn sign(&self, data: String) -> Result<Vec<u8>, Error> {
189 let mut signature = [0u8; (CRYPTO_SIGN_BYTES as usize)];
190 let key: [u8; CRYPTO_SIGN_SECRETKEYBYTES as usize] =
191 self.signature_secret_key.clone().try_into().unwrap();
192
193 let mut signature_size = signature.len() as u64;
194 let _result = unsafe {
195 crypto_sign_detached(
196 signature.as_mut_ptr(),
197 &mut signature_size,
198 data.as_ptr(),
199 data.len() as u64,
200 key.as_ptr(),
201 )
202 };
203
204 if _result != 0 {
205 return Err(Error::EncryptError);
206 }
207
208 return Ok(signature.to_vec());
209 }
210
211 pub fn from(secret_key: Vec<u8>, signature_secret_key: Vec<u8>) -> Result<Self, Error> {
213 if secret_key.len() != (CRYPTO_BOX_SECRETKEYBYTES as usize) {
214 return Err(Error::InvalidArgument(format!(
215 "Secret key should be {} bytes",
216 CRYPTO_BOX_SECRETKEYBYTES
217 )));
218 }
219 if signature_secret_key.len() != (CRYPTO_SIGN_SECRETKEYBYTES as usize) {
220 return Err(Error::InvalidArgument(format!(
221 "Signature key should be {} bytes",
222 CRYPTO_SIGN_SECRETKEYBYTES
223 )));
224 }
225
226 return Ok(Request {
227 secret_key,
228 signature_secret_key,
229 nonce: None,
230 message: None,
231 });
232 }
233}