Skip to content

Commit b2c4905

Browse files
committed
rust: add zeroizing str to cstr util function
Not using CString as it did not look to me like it was actually preallocating for the null terminator, and reallocation would leave unzeroed copies.
1 parent 5a00420 commit b2c4905

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/rust/bitbox02/src/keystore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn _unlock(password: &str) -> Result<zeroize::Zeroizing<Vec<u8>>, Error> {
7575
let mut seed_len: usize = 0;
7676
match unsafe {
7777
bitbox02_sys::keystore_unlock(
78-
crate::util::str_to_cstr_vec(password)
78+
crate::util::str_to_cstr_vec_zeroizing(password)
7979
.unwrap()
8080
.as_ptr()
8181
.cast(),

src/rust/bitbox02/src/util.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub fn truncate_str(s: &str, len: usize) -> &str {
4242
}
4343

4444
/// Converts a Rust string to a null terminated C string by appending a null
45-
/// terminator. Returns `Err(())` if the input already contians a null byte.
45+
/// terminator. Returns `Err(())` if the input already contains a null byte.
4646
pub fn str_to_cstr_vec(input: &str) -> Result<Vec<core::ffi::c_char>, ()> {
4747
let cstr = alloc::ffi::CString::new(input)
4848
.or(Err(()))?
@@ -53,6 +53,23 @@ pub fn str_to_cstr_vec(input: &str) -> Result<Vec<core::ffi::c_char>, ()> {
5353
Ok(cstr.into_iter().map(|c| c as _).collect())
5454
}
5555

56+
/// Converts a Rust string to a null terminated C string by appending a null
57+
/// terminator. Returns `Err(())` if the input already contains a null byte.
58+
pub fn str_to_cstr_vec_zeroizing(
59+
input: &str,
60+
) -> Result<zeroize::Zeroizing<Vec<core::ffi::c_char>>, ()> {
61+
let bytes = input.as_bytes();
62+
if bytes.contains(&0) {
63+
return Err(());
64+
}
65+
let mut result: zeroize::Zeroizing<Vec<core::ffi::c_char>> =
66+
zeroize::Zeroizing::new(vec![0; bytes.len() + 1]);
67+
for (i, b) in bytes.iter().enumerate() {
68+
result[i] = *b as _;
69+
}
70+
Ok(result)
71+
}
72+
5673
#[cfg(test)]
5774
mod tests {
5875
use super::*;
@@ -134,4 +151,18 @@ mod tests {
134151
);
135152
assert_eq!(str_to_cstr_vec("te\0st"), Err(()));
136153
}
154+
155+
#[test]
156+
fn test_str_to_cstr_vec_zeroizing() {
157+
assert_eq!(str_to_cstr_vec_zeroizing("").unwrap().as_slice(), &[0]);
158+
assert_eq!(
159+
str_to_cstr_vec_zeroizing("test").unwrap(),
160+
b"test\0"
161+
.iter()
162+
.map(|c| *c as _)
163+
.collect::<Vec<core::ffi::c_char>>()
164+
.into(),
165+
);
166+
assert_eq!(str_to_cstr_vec_zeroizing("te\0st"), Err(()));
167+
}
137168
}

0 commit comments

Comments
 (0)