diff options
-rw-r--r-- | nitrocli/Cargo.lock | 22 | ||||
-rw-r--r-- | nitrocli/src/crc32.rs | 22 | ||||
-rw-r--r-- | nitrocli/src/error.rs | 18 | ||||
-rw-r--r-- | nitrocli/src/main.rs | 26 | ||||
-rw-r--r-- | nitrocli/src/nitrokey.rs | 40 | ||||
-rw-r--r-- | nitrocli/src/pinentry.rs | 18 |
6 files changed, 72 insertions, 74 deletions
diff --git a/nitrocli/Cargo.lock b/nitrocli/Cargo.lock index a18c654..8daadf2 100644 --- a/nitrocli/Cargo.lock +++ b/nitrocli/Cargo.lock @@ -1,14 +1,3 @@ -[root] -name = "nitrocli" -version = "0.1.2" -dependencies = [ - "cc 1.0.4", - "hid 0.4.1", - "hidapi-sys 0.1.4", - "libc 0.2.36", - "pkg-config 0.3.9", -] - [[package]] name = "cc" version = "1.0.4" @@ -53,6 +42,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" replace = "libc 0.2.36" [[package]] +name = "nitrocli" +version = "0.1.2" +dependencies = [ + "cc 1.0.4", + "hid 0.4.1", + "hidapi-sys 0.1.4", + "libc 0.2.36", + "pkg-config 0.3.9", +] + +[[package]] name = "pkg-config" version = "0.3.9" diff --git a/nitrocli/src/crc32.rs b/nitrocli/src/crc32.rs index 8431db5..8b85b49 100644 --- a/nitrocli/src/crc32.rs +++ b/nitrocli/src/crc32.rs @@ -1,7 +1,7 @@ // crc32.rs // ************************************************************************* -// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -18,20 +18,20 @@ // ************************************************************************* /// Polynomial used in STM32. -const CRC32_POLYNOMIAL: u32 = 0x04c11db7; +const CRC32_POLYNOMIAL: u32 = 0x04c1_1db7; fn crc32(mut crc: u32, data: u32) -> u32 { - crc = crc ^ data; + crc ^= data; for _ in 0..32 { - if crc & 0x80000000 != 0 { + if crc & 0x8000_0000 != 0 { crc = (crc << 1) ^ CRC32_POLYNOMIAL; } else { - crc = crc << 1; + crc <<= 1; } } - return crc; + crc } @@ -45,20 +45,20 @@ fn as_slice_u32(data: &[u8]) -> &[u32] { unsafe { let ptr = data.as_ptr() as *const u32; let len = data.len() / ::std::mem::size_of::<u32>(); - return ::std::slice::from_raw_parts(ptr, len); + ::std::slice::from_raw_parts(ptr, len) } } /// Calculate the CRC of a byte slice. pub fn crc(data: &[u8]) -> u32 { - let mut crc = 0xffffffff; + let mut crc = 0xffff_ffff; let data = as_slice_u32(data); - for i in 0..data.len() { - crc = crc32(crc, data[i]); + for byte in data { + crc = crc32(crc, *byte); } - return crc; + crc } diff --git a/nitrocli/src/error.rs b/nitrocli/src/error.rs index a88b5a7..ea9a189 100644 --- a/nitrocli/src/error.rs +++ b/nitrocli/src/error.rs @@ -1,7 +1,7 @@ // error.rs // ************************************************************************* -// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -34,32 +34,32 @@ pub enum Error { impl From<libhid::Error> for Error { fn from(e: libhid::Error) -> Error { - return Error::HidError(e); + Error::HidError(e) } } impl From<io::Error> for Error { fn from(e: io::Error) -> Error { - return Error::IoError(e); + Error::IoError(e) } } impl From<string::FromUtf8Error> for Error { fn from(e: string::FromUtf8Error) -> Error { - return Error::Utf8Error(e); + Error::Utf8Error(e) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *&self { - &Error::HidError(ref e) => return write!(f, "hidapi error: {}", e), - &Error::Utf8Error(_) => return write!(f, "Encountered UTF-8 conversion error"), - &Error::IoError(ref e) => return write!(f, "IO error: {}", e.get_ref().unwrap()), - &Error::Error(ref e) => return write!(f, "{}", e), + match *self { + Error::HidError(ref e) => write!(f, "hidapi error: {}", e), + Error::Utf8Error(_) => write!(f, "Encountered UTF-8 conversion error"), + Error::IoError(ref e) => write!(f, "IO error: {}", e.get_ref().unwrap()), + Error::Error(ref e) => write!(f, "{}", e), } } } diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 5c8856e..3ec3243 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -1,7 +1,7 @@ // main.rs // ************************************************************************* -// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -124,13 +124,13 @@ fn transmit<PS, PR>(handle: &mut libhid::Handle, where PS: AsRef<[u8]>, PR: AsRef<[u8]> + Default, { - send(handle, &report)?; + send(handle, report)?; // We need to give the stick some time to handle the command. If we // don't, we might just receive stale data from before. thread::sleep(time::Duration::from_millis(SEND_RECV_DELAY_MS)); - return receive::<PR>(handle); + receive::<PR>(handle) } @@ -144,7 +144,7 @@ fn nitrokey_do(function: &NitroFunc) -> Result<()> { return function(&mut device.open()?); } } - return Err(Error::Error("Nitrokey device not found".to_string())); + Err(Error::Error("Nitrokey device not found".to_string())) } @@ -205,7 +205,7 @@ fn print_status(response: &nitrokey::DeviceStatusResponse) { fn status() -> Result<()> { type Response = nitrokey::Response<nitrokey::DeviceStatusResponse>; - return nitrokey_do(&|handle| { + nitrokey_do(&|handle| { let payload = nitrokey::DeviceStatusCommand::new(); let report = nitrokey::Report::from(payload); @@ -223,8 +223,8 @@ fn status() -> Result<()> { } print_status(response); - return Ok(()); - }); + Ok(()) + }) } @@ -251,7 +251,7 @@ fn wait(handle: &mut libhid::Handle) -> Result<nitrokey::StorageStatus> { fn open() -> Result<()> { type Response = nitrokey::Response<nitrokey::StorageResponse>; - return nitrokey_do(&|handle| { + nitrokey_do(&|handle| { let mut retry = 3; loop { let passphrase = pinentry::inquire_passphrase()?; @@ -284,7 +284,7 @@ fn open() -> Result<()> { } return Ok(()); } - }); + }) } @@ -297,7 +297,7 @@ extern "C" { fn close() -> Result<()> { type Response = nitrokey::Response<nitrokey::StorageResponse>; - return nitrokey_do(&|handle| { + nitrokey_do(&|handle| { // Flush all filesystem caches to disk. We are mostly interested in // making sure that the encrypted volume on the nitrokey we are // about to close is not closed while not all data was written to @@ -320,14 +320,14 @@ fn close() -> Result<()> { let error = format!("Closing encrypted volume failed: {}", status); return Err(Error::Error(error)); } - return Ok(()); - }); + Ok(()) + }) } /// Clear the PIN stored when opening the nitrokey's encrypted volume. fn clear() -> Result<()> { - return pinentry::clear_passphrase(); + pinentry::clear_passphrase() } diff --git a/nitrocli/src/nitrokey.rs b/nitrocli/src/nitrokey.rs index f8995eb..83f5d1f 100644 --- a/nitrocli/src/nitrokey.rs +++ b/nitrocli/src/nitrokey.rs @@ -1,7 +1,7 @@ // nitrokey.rs // ************************************************************************* -// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -71,14 +71,14 @@ impl<P> Report<P> where P: AsRef<[u8]> + Default, { pub fn new() -> Report<P> { - return Report { + Report { data: P::default(), crc: 0, - }; + } } pub fn is_valid(&self) -> bool { - return self.crc == crc(self.data.as_ref()); + self.crc == crc(self.data.as_ref()) } } @@ -87,7 +87,7 @@ impl<P> AsRef<[u8]> for Report<P> where P: AsRef<[u8]>, { fn as_ref(&self) -> &[u8] { - unsafe { return mem::transmute::<&Report<P>, &[u8; 64]>(self) }; + unsafe { mem::transmute::<&Report<P>, &[u8; 64]>(self) } } } @@ -97,10 +97,10 @@ impl<P> From<P> for Report<P> { fn from(payload: P) -> Report<P> { let crc = crc(payload.as_ref()); - return Report { + Report { data: payload, crc: crc, - }; + } } } @@ -109,7 +109,7 @@ impl<P> AsMut<[u8]> for Report<P> where P: AsRef<[u8]>, { fn as_mut(&mut self) -> &mut [u8] { - unsafe { return mem::transmute::<&mut Report<P>, &mut [u8; 64]>(self) }; + unsafe { mem::transmute::<&mut Report<P>, &mut [u8; 64]>(self) } } } @@ -120,21 +120,21 @@ pub struct EmptyPayload { impl Default for EmptyPayload { fn default() -> EmptyPayload { - return EmptyPayload { + EmptyPayload { data: [0u8; 60], - }; + } } } impl AsRef<[u8]> for EmptyPayload { fn as_ref(&self) -> &[u8] { - unsafe { return mem::transmute::<&EmptyPayload, &[u8; 60]>(self) }; + unsafe { mem::transmute::<&EmptyPayload, &[u8; 60]>(self) } } } impl<P> AsRef<Response<P>> for EmptyPayload { fn as_ref(&self) -> &Response<P> { - unsafe { return mem::transmute::<&EmptyPayload, &Response<P>>(self) }; + unsafe { mem::transmute::<&EmptyPayload, &Response<P>>(self) } } } @@ -154,10 +154,10 @@ macro_rules! defaultCommandNew { ( $name:ident, $command:ident ) => { impl $name { pub fn new() -> $name { - return $name{ + $name{ command: Command::$command, padding: [0; 59], - }; + } } } } @@ -167,9 +167,7 @@ macro_rules! defaultPayloadAsRef { ( $name:ty ) => { impl AsRef<[u8]> for $name { fn as_ref(&self) -> &[u8] { - unsafe { - return mem::transmute::<&$name, &[u8; 60]>(self) - }; + unsafe { mem::transmute::<&$name, &[u8; 60]>(self) } } } } @@ -198,10 +196,10 @@ pub struct EnableEncryptedVolumeCommand { impl EnableEncryptedVolumeCommand { - pub fn new(password: &Vec<u8>) -> EnableEncryptedVolumeCommand { + pub fn new(password: &[u8]) -> EnableEncryptedVolumeCommand { let mut report = EnableEncryptedVolumeCommand { command: Command::EnableEncryptedVolume, - kind: 'P' as u8, + kind: b'P', password: [0; 20], padding: [0; 38], }; @@ -210,7 +208,7 @@ impl EnableEncryptedVolumeCommand { let len = cmp::min(report.password.len(), password.len()); report.password[..len].copy_from_slice(&password[..len]); - return report; + report } } @@ -266,7 +264,7 @@ pub struct Response<Payload> { impl<P> AsRef<[u8]> for Response<P> { fn as_ref(&self) -> &[u8] { - unsafe { return mem::transmute::<&Response<P>, &[u8; 60]>(self) }; + unsafe { mem::transmute::<&Response<P>, &[u8; 60]>(self) } } } diff --git a/nitrocli/src/pinentry.rs b/nitrocli/src/pinentry.rs index 8de788f..d96d279 100644 --- a/nitrocli/src/pinentry.rs +++ b/nitrocli/src/pinentry.rs @@ -1,7 +1,7 @@ // pinentry.rs // ************************************************************************* -// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -21,7 +21,7 @@ use error::Error; use std::process; -const CACHE_ID: &'static str = "nitrokey"; +const CACHE_ID: &str = "nitrokey"; fn parse_pinentry_passphrase(response: Vec<u8>) -> Result<Vec<u8>, Error> { @@ -45,14 +45,14 @@ fn parse_pinentry_passphrase(response: Vec<u8>) -> Result<Vec<u8>, Error> { let (_, error) = lines[0].split_at(4); return Err(Error::Error(error.to_string())); } - return Err(Error::Error("Unexpected response: ".to_string() + &string)); + Err(Error::Error("Unexpected response: ".to_string() + &string)) } pub fn inquire_passphrase() -> Result<Vec<u8>, Error> { - const PINENTRY_DESCR: &'static str = "+"; - const PINENTRY_TITLE: &'static str = "Please+enter+user+PIN"; - const PINENTRY_PASSWD: &'static str = "PIN"; + const PINENTRY_DESCR: &str = "+"; + const PINENTRY_TITLE: &str = "Please+enter+user+PIN"; + const PINENTRY_PASSWD: &str = "PIN"; let args = vec![CACHE_ID, PINENTRY_DESCR, PINENTRY_PASSWD, PINENTRY_TITLE].join(" "); let command = "GET_PASSPHRASE --data ".to_string() + &args; @@ -65,7 +65,7 @@ pub fn inquire_passphrase() -> Result<Vec<u8>, Error> { let output = process::Command::new("gpg-connect-agent").arg(command) .arg("/bye") .output()?; - return parse_pinentry_passphrase(output.stdout); + parse_pinentry_passphrase(output.stdout) } @@ -77,7 +77,7 @@ fn parse_pinentry_response(response: Vec<u8>) -> Result<(), Error> { // We got the only valid answer we accept. return Ok(()); } - return Err(Error::Error("Unexpected response: ".to_string() + &string)); + Err(Error::Error("Unexpected response: ".to_string() + &string)) } @@ -88,7 +88,7 @@ pub fn clear_passphrase() -> Result<(), Error> { .arg("/bye") .output()?; - return parse_pinentry_response(output.stdout); + parse_pinentry_response(output.stdout) } |