1use crate::aliases::{PasswordString, RandomPassword32};
11use crate::{decrypt, encrypt, AescryptError};
12use pipe::pipe;
13use secure_gate::SecureRandomExt;
14use std::io::{Read, Write};
15
16fn convert_to_v3_impl<R, W>(
18 input: R,
19 output: W,
20 old_password: &PasswordString,
21 new_password: Option<&PasswordString>,
22 iterations: u32,
23) -> Result<Option<PasswordString>, AescryptError>
24where
25 R: Read + Send + 'static,
26 W: Write + Send + 'static,
27{
28 let generated = if new_password.is_none() {
30 Some(PasswordString::new(
31 RandomPassword32::random_hex().to_string(),
32 ))
33 } else {
34 None
35 };
36
37 let new_pass = generated.as_ref().unwrap_or_else(|| new_password.unwrap());
39
40 std::thread::scope(|s| -> Result<(), AescryptError> {
41 let (mut pipe_reader, pipe_writer) = pipe();
42
43 let decrypt_thread = s.spawn({
44 let old_password = old_password.clone();
45 move || decrypt(input, pipe_writer, &old_password)
46 });
47
48 let encrypt_thread = s.spawn({
49 let new_pass = new_pass.clone();
50 move || encrypt(&mut pipe_reader, output, &new_pass, iterations)
51 });
52
53 decrypt_thread.join().unwrap()?;
54 encrypt_thread.join().unwrap()?;
55
56 Ok(())
57 })?;
58
59 Ok(generated)
60}
61
62#[deprecated(
67 since = "0.1.6",
68 note = "use convert_to_v3_ext(..., Some(password), ...) instead — this wrapper will be removed in v1.0"
69)]
70pub fn convert_to_v3<R, W>(
71 input: R,
72 output: W,
73 password: &crate::aliases::Password, iterations: u32,
75) -> Result<(), AescryptError>
76where
77 R: Read + Send + 'static,
78 W: Write + Send + 'static,
79{
80 let password_str: &crate::aliases::PasswordString = unsafe {
84 &*(password as *const crate::aliases::Password as *const crate::aliases::PasswordString)
88 };
89
90 convert_to_v3_impl(input, output, password_str, Some(password_str), iterations)?;
91 Ok(())
92}
93
94pub fn convert_to_v3_ext<R, W>(
104 input: R,
105 output: W,
106 old_password: &PasswordString,
107 new_password: Option<&PasswordString>,
108 iterations: u32,
109) -> Result<Option<PasswordString>, AescryptError>
110where
111 R: Read + Send + 'static,
112 W: Write + Send + 'static,
113{
114 convert_to_v3_impl(input, output, old_password, new_password, iterations)
115}