diff options
-rw-r--r-- | nitrocli/CHANGELOG.md | 3 | ||||
-rw-r--r-- | nitrocli/doc/nitrocli.1 | 20 | ||||
-rw-r--r-- | nitrocli/doc/nitrocli.1.pdf | bin | 14041 -> 14203 bytes | |||
-rw-r--r-- | nitrocli/src/args.rs | 53 | ||||
-rw-r--r-- | nitrocli/src/commands.rs | 11 |
5 files changed, 71 insertions, 16 deletions
diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index e32123e..e94d63f 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -3,6 +3,9 @@ Unreleased - Added the `-v`/`--verbose` option to control libnitrokey log level - Added the `-m`/`--model` option to restrict connections to a device model +- Added the `-f`/`--format` option for the `otp set` subcommand to + choose the secret format + - Deprecated the `--ascii` option - Bumped `nitrokey` dependency to `0.3.0` diff --git a/nitrocli/doc/nitrocli.1 b/nitrocli/doc/nitrocli.1 index e4dbf10..16e06a0 100644 --- a/nitrocli/doc/nitrocli.1 +++ b/nitrocli/doc/nitrocli.1 @@ -82,15 +82,19 @@ This command might require the user PIN (see the Configuration section). \fBnitrocli otp set \fIslot name secret \ \fR[\fB\-a\fR|\fB\-\-algorithm \fIalgorithm\fR] \ [\fB\-d\fR|\fB\-\-digits \fIdigits\fR] [\fB\-c\fR|\fB\-\-counter \fIcounter\fR] \ -[\fB\-t\fR|\fB\-\-time-window \fItime window\fR] [\fB\-\-ascii\fR] +[\fB\-t\fR|\fB\-\-time-window \fItime-window\fR] \ +[\fB-f\fR|\fB\-\-format ascii\fR|\fBhex\fR] Configure a one-time password slot. \fIslot\fR is the number of the slot to configure. \fIname\fR is the name of the slot (may not be empty). \fIsecret\fR is the secret value to store in that slot. -If \fB\-\-ascii\fR is set, each character of the given secret is interpreted as -the ASCII code of one byte. -Otherwise, every two characters are interpreted as the hexadecimal value of one -byte. + +The \fB\-\-format\fR option specifies the format of the secret. +If it is set to \fBascii\fR, each character of the given secret is interpreted +as the ASCII code of one byte. +If it is set to \fBhex\fR, every two characters are interpreted as the +hexadecimal value of one byte. +The default value is \fBhex\fR. \fIalgorithm\fR is the OTP algorithm to use. Possible values are \fBhotp\fR for the HOTP algorithm according to RFC 4226 and @@ -222,9 +226,9 @@ Configure a one-time password slot with a hexadecimal secret representation: $ \fBnitrocli otp set 0 test\-rfc6238 3132333435363738393031323334353637383930 \-\-algorithm totp \-\-digits 8\fR .P Configure a one-time password slot with an ASCII secret representation: - $ \fBnitrocli otp set 0 test\-rfc4226 12345678901234567890 \-\-ascii \-\-algorithm hotp\fR - $ \fBnitrocli otp set 1 test\-foobar foobar \-\-ascii \-\-algorithm hotp\fR - $ \fBnitrocli otp set 0 test\-rfc6238 12345678901234567890 \-\-ascii \-\-algorithm totp \-\-digits 8\fR + $ \fBnitrocli otp set 0 test\-rfc4226 12345678901234567890 \-\-format ascii \-\-algorithm hotp\fR + $ \fBnitrocli otp set 1 test\-foobar foobar \-\-format ascii \-\-algorithm hotp\fR + $ \fBnitrocli otp set 0 test\-rfc6238 12345678901234567890 \-\-format ascii \-\-algorithm totp \-\-digits 8\fR .P Generate a one-time password: $ \fBnitrocli otp get 0 \-\-algorithm hotp\fR diff --git a/nitrocli/doc/nitrocli.1.pdf b/nitrocli/doc/nitrocli.1.pdf Binary files differindex 5127435..4a3528f 100644 --- a/nitrocli/doc/nitrocli.1.pdf +++ b/nitrocli/doc/nitrocli.1.pdf diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index ad296c2..b109944 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -324,6 +324,37 @@ impl From<OtpMode> for nitrokey::OtpMode { } } +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum OtpSecretFormat { + Ascii, + Hex, +} + +impl fmt::Display for OtpSecretFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match *self { + OtpSecretFormat::Ascii => "ascii", + OtpSecretFormat::Hex => "hex", + } + ) + } +} + +impl str::FromStr for OtpSecretFormat { + type Err = (); + + fn from_str(s: &str) -> result::Result<Self, Self::Err> { + match s { + "ascii" => Ok(OtpSecretFormat::Ascii), + "hex" => Ok(OtpSecretFormat::Hex), + _ => Err(()), + } + } +} + #[derive(Debug)] enum PinCommand { Clear, @@ -700,6 +731,7 @@ pub fn otp_set(ctx: &ExecCtx, args: Vec<String>) -> Result<()> { let mut counter: u64 = 0; let mut time_window: u16 = 30; let mut ascii = false; + let mut secret_format: Option<OtpSecretFormat> = None; let mut parser = argparse::ArgumentParser::new(); parser.set_description("Configures a one-time password slot"); let _ = @@ -740,11 +772,28 @@ pub fn otp_set(ctx: &ExecCtx, args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut ascii).add_option( &["--ascii"], argparse::StoreTrue, - "Interpret the given secret as an ASCII string of the secret", + "Interpret the given secret as an ASCII string of the secret (deprecated, use --format instead)" + ); + let _ = parser.refer(&mut secret_format).add_option( + &["-f", "--format"], + argparse::StoreOption, + "The format of the secret (ascii|hex)", ); parse(&parser, args)?; drop(parser); + if ascii { + if secret_format.is_some() { + return Err(Error::Error( + "The --format and the --ascii option cannot be used at the same time".to_string(), + )); + } + + println!("Warning: The --ascii option is deprecated. Please use --format ascii instead."); + secret_format = Some(OtpSecretFormat::Ascii); + } + let secret_format = secret_format.unwrap_or(OtpSecretFormat::Hex); + let data = nitrokey::OtpSlotData { number: slot, name, @@ -753,7 +802,7 @@ pub fn otp_set(ctx: &ExecCtx, args: Vec<String>) -> Result<()> { use_enter: false, token_id: None, }; - commands::otp_set(ctx, data, algorithm, counter, time_window, ascii) + commands::otp_set(ctx, data, algorithm, counter, time_window, secret_format) } /// Clear an OTP slot. diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index ac2bbf1..c1942e8 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -450,7 +450,7 @@ fn prepare_secret(secret: &str) -> Result<String> { ) } else { Err(Error::Error( - "The given secret is not an ASCII string despite --ascii being set".to_string(), + "The given secret is not an ASCII string despite --format ascii being set".to_string(), )) } } @@ -462,12 +462,11 @@ pub fn otp_set( algorithm: args::OtpAlgorithm, counter: u64, time_window: u16, - ascii: bool, + secret_format: args::OtpSecretFormat, ) -> Result<()> { - let secret = if ascii { - prepare_secret(&data.secret)? - } else { - data.secret + let secret = match secret_format { + args::OtpSecretFormat::Ascii => prepare_secret(&data.secret)?, + args::OtpSecretFormat::Hex => data.secret, }; let data = nitrokey::OtpSlotData { secret, ..data }; let device = authenticate_admin(get_device(ctx)?)?; |