aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-10-13 05:13:36 -0700
committerDaniel Mueller <deso@posteo.net>2019-10-13 05:13:36 -0700
commit9f3991a74fa5124e298582afa60b229dd005be40 (patch)
tree8738fafcad5982c78ace218fd83f84d9ea5c5b3f
parentc46803a4557c9cd14df5e46192384a831b329179 (diff)
downloadnitrocli-9f3991a74fa5124e298582afa60b229dd005be40.tar.gz
nitrocli-9f3991a74fa5124e298582afa60b229dd005be40.tar.bz2
Properly pad user supplied hexadecimal strings to otp set subcommand
The library ultimately taking care of communicating with the Nitrokey device, libnitrokey, unconditionally expects hexadecimal strings supplied as part of the configuration of an OTP slot to have an even number of bytes. Users should not be aware of this detail and so with this change we take care of padding the supplied string with a leading zero to make such a configuration go through without an error.
-rw-r--r--nitrocli/src/commands.rs15
-rw-r--r--nitrocli/src/tests/otp.rs16
2 files changed, 29 insertions, 2 deletions
diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs
index eac8549..a65f070 100644
--- a/nitrocli/src/commands.rs
+++ b/nitrocli/src/commands.rs
@@ -646,7 +646,7 @@ fn prepare_base32_secret(secret: &str) -> Result<String> {
/// Configure a one-time password slot on the Nitrokey device.
pub fn otp_set(
ctx: &mut args::ExecCtx<'_>,
- data: nitrokey::OtpSlotData,
+ mut data: nitrokey::OtpSlotData,
algorithm: args::OtpAlgorithm,
counter: u64,
time_window: u16,
@@ -656,7 +656,18 @@ pub fn otp_set(
let secret = match secret_format {
args::OtpSecretFormat::Ascii => prepare_ascii_secret(&data.secret)?,
args::OtpSecretFormat::Base32 => prepare_base32_secret(&data.secret)?,
- args::OtpSecretFormat::Hex => data.secret,
+ args::OtpSecretFormat::Hex => {
+ // We need to ensure to provide a string with an even number of
+ // characters in it, just because that's what libnitrokey
+ // expects. So prepend a '0' if that is not the case.
+ // TODO: This code can be removed once upstream issue #164
+ // (https://github.com/Nitrokey/libnitrokey/issues/164) is
+ // addressed.
+ if data.secret.len() % 2 != 0 {
+ data.secret.insert(0, '0')
+ }
+ data.secret
+ }
};
let data = nitrokey::OtpSlotData { secret, ..data };
let device = authenticate_admin(ctx, device)?;
diff --git a/nitrocli/src/tests/otp.rs b/nitrocli/src/tests/otp.rs
index 39ddf29..531ed5f 100644
--- a/nitrocli/src/tests/otp.rs
+++ b/nitrocli/src/tests/otp.rs
@@ -19,6 +19,8 @@
use super::*;
+use crate::args;
+
#[test_device]
fn set_invalid_slot_raw(device: nitrokey::DeviceWrapper) {
let (rc, out, err) = Nitrocli::with_dev(device).run(&["otp", "set", "100", "name", "1234"]);
@@ -97,6 +99,20 @@ fn set_get_totp(device: nitrokey::DeviceWrapper) -> crate::Result<()> {
}
#[test_device]
+fn set_totp_uneven_chars(device: nitrokey::DeviceWrapper) -> crate::Result<()> {
+ let secrets = [
+ (args::OtpSecretFormat::Hex, "123"),
+ (args::OtpSecretFormat::Base32, "FBILDWWGA2"),
+ ];
+
+ let mut ncli = Nitrocli::with_dev(device);
+ for (format, secret) in &secrets {
+ let _ = ncli.handle(&["otp", "set", "-f", format.as_ref(), "3", "foobar", &secret])?;
+ }
+ Ok(())
+}
+
+#[test_device]
fn clear(device: nitrokey::DeviceWrapper) -> crate::Result<()> {
let mut ncli = Nitrocli::with_dev(device);
let _ = ncli.handle(&["otp", "set", "3", "hotp-test", "abcdef"])?;