summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"])?;