summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-01-06 00:10:44 +0100
committerDaniel Mueller <deso@posteo.net>2019-01-13 18:36:58 -0800
commit53a2893ee725e4ad678b2060fd71729ff55e6cee (patch)
tree0d17667568b8f6fcb19fa111cc5efd8a7c16df13
parent091e01ba40e488dfd68b43db56fc0693a350510a (diff)
downloadnitrocli-53a2893ee725e4ad678b2060fd71729ff55e6cee.tar.gz
nitrocli-53a2893ee725e4ad678b2060fd71729ff55e6cee.tar.bz2
Add the --format option to otp set to select the secret format
This patch introduces the -f/--format options for the otp set subcommand to specify the format of the OTP secret. Previously, the default format was hexadecimal and ASCII format could be selected using the --ascii option. The new --format option takes the argument hex or ascii, defaulting to hex, and replaces the --ascii option. This patch does not remove the --ascii option but marks it as deprecated. It may not be set together with --format, and a warning is printed if it is set. It should be deleted with the next minor release. This patch prepares the addition of a new format, base32.
-rw-r--r--nitrocli/CHANGELOG.md3
-rw-r--r--nitrocli/doc/nitrocli.120
-rw-r--r--nitrocli/doc/nitrocli.1.pdfbin14041 -> 14203 bytes
-rw-r--r--nitrocli/src/args.rs53
-rw-r--r--nitrocli/src/commands.rs11
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
index 5127435..4a3528f 100644
--- a/nitrocli/doc/nitrocli.1.pdf
+++ b/nitrocli/doc/nitrocli.1.pdf
Binary files differ
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)?)?;