From 669fbb40d894460e9603dcf6e953373e53a19347 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 28 Jan 2020 19:42:41 +0100 Subject: Use CString to store temporary passwords This patch changes the generate_password function and the User and Admin structs to use a CString instead of a Vec when storing temporary passwords. This makes sure that the strings that are passed to the C API are properly null-terminated. --- CHANGELOG.md | 3 +++ src/auth.rs | 17 +++++++++-------- src/util.rs | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cba0e83..be65865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ Copyright (C) 2019-2020 Robin Krahl SPDX-License-Identifier: CC0-1.0 --> +# Unreleased +- Use `CString` to store the temporary password instead of `Vec`. + # v0.5.1 (2020-01-15) - Fix serial number formatting for Nitrokey Pro devices with firmware 0.8 or older in the `list_devices` function. diff --git a/src/auth.rs b/src/auth.rs index cab1021..571e198 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT use std::convert::TryFrom as _; +use std::ffi::CString; use std::marker; use std::ops; use std::os::raw::c_char; @@ -117,7 +118,7 @@ pub trait Authenticate<'a> { } trait AuthenticatedDevice { - fn new(device: T, temp_password: Vec) -> Self; + fn new(device: T, temp_password: CString) -> Self; fn temp_password_ptr(&self) -> *const c_char; } @@ -134,7 +135,7 @@ trait AuthenticatedDevice { #[derive(Debug)] pub struct User<'a, T: Device<'a>> { device: T, - temp_password: Vec, + temp_password: CString, marker: marker::PhantomData<&'a T>, } @@ -150,7 +151,7 @@ pub struct User<'a, T: Device<'a>> { #[derive(Debug)] pub struct Admin<'a, T: Device<'a>> { device: T, - temp_password: Vec, + temp_password: CString, marker: marker::PhantomData<&'a T>, } @@ -169,7 +170,7 @@ where Err(err) => return Err((device, err)), }; let password_ptr = password.as_ptr(); - let temp_password_ptr = temp_password.as_ptr() as *const c_char; + let temp_password_ptr = temp_password.as_ptr(); match callback(password_ptr, temp_password_ptr) { 0 => Ok(A::new(device, temp_password)), rv => Err((device, Error::from(rv))), @@ -246,7 +247,7 @@ impl<'a, T: Device<'a>> GenerateOtp for User<'a, T> { } impl<'a, T: Device<'a>> AuthenticatedDevice for User<'a, T> { - fn new(device: T, temp_password: Vec) -> Self { + fn new(device: T, temp_password: CString) -> Self { User { device, temp_password, @@ -255,7 +256,7 @@ impl<'a, T: Device<'a>> AuthenticatedDevice for User<'a, T> { } fn temp_password_ptr(&self) -> *const c_char { - self.temp_password.as_ptr() as *const c_char + self.temp_password.as_ptr() } } @@ -373,7 +374,7 @@ impl<'a, T: Device<'a>> ConfigureOtp for Admin<'a, T> { } impl<'a, T: Device<'a>> AuthenticatedDevice for Admin<'a, T> { - fn new(device: T, temp_password: Vec) -> Self { + fn new(device: T, temp_password: CString) -> Self { Admin { device, temp_password, @@ -382,7 +383,7 @@ impl<'a, T: Device<'a>> AuthenticatedDevice for Admin<'a, T> { } fn temp_password_ptr(&self) -> *const c_char { - self.temp_password.as_ptr() as *const c_char + self.temp_password.as_ptr() } } diff --git a/src/util.rs b/src/util.rs index 5a56c55..b9b1a68 100644 --- a/src/util.rs +++ b/src/util.rs @@ -75,10 +75,10 @@ pub fn get_last_error() -> Error { } } -pub fn generate_password(length: usize) -> Result, Error> { +pub fn generate_password(length: usize) -> Result { let mut data = vec![0u8; length]; OsRng.fill_bytes(&mut data[..]); - Ok(data) + get_cstring(data) } pub fn get_cstring>>(s: T) -> Result { -- cgit v1.2.1