mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-28 22:43:26 -08:00
feat(deps): Change base64 to base64ct crate (#295)
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
use crate::debug::debug_crypto_array;
|
||||
use anyhow::Context;
|
||||
use rand::{Fill as Randomize, Rng};
|
||||
use rosenpass_to::{ops::copy_slice, To};
|
||||
use rosenpass_util::file::{fopen_r, LoadValue, ReadExactToEnd, StoreValue};
|
||||
use rosenpass_util::b64::{b64_decode, b64_encode};
|
||||
use rosenpass_util::file::{
|
||||
fopen_r, fopen_w, LoadValue, LoadValueB64, ReadExactToEnd, ReadSliceToEnd, StoreValue,
|
||||
StoreValueB64, StoreValueB64Writer, Visibility,
|
||||
};
|
||||
use rosenpass_util::functional::mutating;
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::path::Path;
|
||||
|
||||
@@ -110,3 +116,164 @@ impl<const N: usize> StoreValue for Public<N> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> LoadValueB64 for Public<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn load_b64<const F: usize, P: AsRef<Path>>(path: P) -> Result<Self, Self::Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let mut f = [0u8; F];
|
||||
let mut v = Public::zero();
|
||||
let p = path.as_ref();
|
||||
|
||||
let len = fopen_r(p)?
|
||||
.read_slice_to_end(&mut f)
|
||||
.with_context(|| format!("Could not load file {p:?}"))?;
|
||||
|
||||
b64_decode(&f[0..len], &mut v.value)
|
||||
.with_context(|| format!("Could not decode base64 file {p:?}"))?;
|
||||
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> StoreValueB64 for Public<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn store_b64<const F: usize, P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
||||
let p = path.as_ref();
|
||||
let mut f = [0u8; F];
|
||||
let encoded_str = b64_encode(&self.value, &mut f)
|
||||
.with_context(|| format!("Could not encode base64 file {p:?}"))?;
|
||||
fopen_w(p, Visibility::Public)?
|
||||
.write_all(encoded_str.as_bytes())
|
||||
.with_context(|| format!("Could not write file {p:?}"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> StoreValueB64Writer for Public<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn store_b64_writer<const F: usize, W: std::io::Write>(
|
||||
&self,
|
||||
mut writer: W,
|
||||
) -> Result<(), Self::Error> {
|
||||
let mut f = [0u8; F];
|
||||
let encoded_str = b64_encode(&self.value, &mut f)
|
||||
.with_context(|| format!("Could not encode secret to base64"))?;
|
||||
|
||||
writer
|
||||
.write_all(encoded_str.as_bytes())
|
||||
.with_context(|| format!("Could not write base64 to writer"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Public;
|
||||
use rosenpass_util::{
|
||||
b64::b64_encode,
|
||||
file::{
|
||||
fopen_w, LoadValue, LoadValueB64, StoreValue, StoreValueB64, StoreValueB64Writer,
|
||||
Visibility,
|
||||
},
|
||||
};
|
||||
use std::{fs, os::unix::fs::PermissionsExt};
|
||||
use tempfile::tempdir;
|
||||
|
||||
/// test loading a public from an example file, and then storing it again in a different file
|
||||
#[test]
|
||||
fn test_public_load_store() {
|
||||
const N: usize = 100;
|
||||
|
||||
// Generate original random bytes
|
||||
let original_bytes: [u8; N] = [rand::random(); N];
|
||||
|
||||
// Create a temporary directory
|
||||
let temp_dir = tempdir().unwrap();
|
||||
|
||||
// Store the original public to an example file in the temporary directory
|
||||
let example_file = temp_dir.path().join("example_file");
|
||||
std::fs::write(example_file.clone(), &original_bytes).unwrap();
|
||||
|
||||
// Load the public from the example file
|
||||
|
||||
let loaded_public = Public::load(&example_file).unwrap();
|
||||
|
||||
// Check that the loaded public matches the original bytes
|
||||
assert_eq!(&loaded_public.value, &original_bytes);
|
||||
|
||||
// Store the loaded public to a different file in the temporary directory
|
||||
let new_file = temp_dir.path().join("new_file");
|
||||
loaded_public.store(&new_file).unwrap();
|
||||
|
||||
// Read the contents of the new file
|
||||
let new_file_contents = fs::read(&new_file).unwrap();
|
||||
|
||||
// Read the contents of the original file
|
||||
let original_file_contents = fs::read(&example_file).unwrap();
|
||||
|
||||
// Check that the contents of the new file match the original file
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
}
|
||||
|
||||
/// test loading a base64 encoded public from an example file, and then storing it again in a different file
|
||||
#[test]
|
||||
fn test_public_load_store_base64() {
|
||||
const N: usize = 100;
|
||||
// Generate original random bytes
|
||||
let original_bytes: [u8; N] = [rand::random(); N];
|
||||
// Create a temporary directory
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let example_file = temp_dir.path().join("example_file");
|
||||
let mut encoded_public = [0u8; N * 2];
|
||||
let encoded_public = b64_encode(&original_bytes, &mut encoded_public).unwrap();
|
||||
std::fs::write(&example_file, encoded_public).unwrap();
|
||||
|
||||
// Load the public from the example file
|
||||
let loaded_public = Public::load_b64::<{ N * 2 }, _>(&example_file).unwrap();
|
||||
// Check that the loaded public matches the original bytes
|
||||
assert_eq!(&loaded_public.value, &original_bytes);
|
||||
|
||||
// Store the loaded public to a different file in the temporary directory
|
||||
let new_file = temp_dir.path().join("new_file");
|
||||
loaded_public.store_b64::<{ N * 2 }, _>(&new_file).unwrap();
|
||||
|
||||
// Read the contents of the new file
|
||||
let new_file_contents = fs::read(&new_file).unwrap();
|
||||
// Read the contents of the original file
|
||||
let original_file_contents = fs::read(&example_file).unwrap();
|
||||
// Check that the contents of the new file match the original file
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
|
||||
//Check new file permissions are public
|
||||
let metadata = fs::metadata(&new_file).unwrap();
|
||||
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
|
||||
|
||||
// Store the loaded public to a different file in the temporary directory for a second time
|
||||
let new_file = temp_dir.path().join("new_file_writer");
|
||||
let new_file_writer = fopen_w(new_file.clone(), Visibility::Public).unwrap();
|
||||
loaded_public
|
||||
.store_b64_writer::<{ N * 2 }, _>(&new_file_writer)
|
||||
.unwrap();
|
||||
|
||||
// Read the contents of the new file
|
||||
let new_file_contents = fs::read(&new_file).unwrap();
|
||||
// Read the contents of the original file
|
||||
let original_file_contents = fs::read(&example_file).unwrap();
|
||||
// Check that the contents of the new file match the original file
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
|
||||
//Check new file permissions are public
|
||||
let metadata = fs::metadata(&new_file).unwrap();
|
||||
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user