aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-01-06 00:23:27 +0100
committerDaniel Mueller <deso@posteo.net>2019-01-13 18:37:13 -0800
commit1d1cc940f47c41637adea5c5a1e5d3c80807f9d7 (patch)
tree8a44a82430e3df7ade7a61a6e4e30f100268af2d
parentcb5b22d0886a0a8c19cf1afeef55a8245357cf20 (diff)
downloadnitrocli-1d1cc940f47c41637adea5c5a1e5d3c80807f9d7.tar.gz
nitrocli-1d1cc940f47c41637adea5c5a1e5d3c80807f9d7.tar.bz2
Add the base32 format for OTP secrets
Many applications display OTP secrets in the base32 format (according to RFC 4648). This patch adds base32 as a possible value for the --format option to the otp set subcommand.
-rw-r--r--nitrocli/doc/nitrocli.19
-rw-r--r--nitrocli/doc/nitrocli.1.pdfbin14203 -> 14513 bytes
-rw-r--r--nitrocli/src/args.rs5
-rw-r--r--nitrocli/src/commands.rs8
4 files changed, 20 insertions, 2 deletions
diff --git a/nitrocli/doc/nitrocli.1 b/nitrocli/doc/nitrocli.1
index 16e06a0..036c25f 100644
--- a/nitrocli/doc/nitrocli.1
+++ b/nitrocli/doc/nitrocli.1
@@ -83,7 +83,7 @@ This command might require the user PIN (see the Configuration section).
\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-f\fR|\fB\-\-format ascii\fR|\fBhex\fR]
+[\fB-f\fR|\fB\-\-format ascii\fR|\fBbase32\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).
@@ -92,6 +92,8 @@ Configure a one-time password slot.
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 \fBbase32\fR, the secret is interpreted as a base32 string
+according to RFC 4648.
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.
@@ -230,6 +232,11 @@ Configure a one-time password slot with an ASCII secret representation:
$ \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
+Configure a one-time password slot with a base32 secret representation:
+ $ \fBnitrocli otp set 0 test\-rfc4226 gezdgnbvgy3tqojqgezdgnbvgy3tqojq \-\-format base32 \-\-algorithm hotp\fR
+ $ \fBnitrocli otp set 1 test\-foobar mzxw6ytboi====== \-\-format base32 \-\-algorithm hotp\fR
+ $ \fBnitrocli otp set 0 test\-rfc6238 gezdgnbvgy3tqojqgezdgnbvgy3tqojq \-\-format base32 \-\-algorithm totp \-\-digits 8\fR
+.P
Generate a one-time password:
$ \fBnitrocli otp get 0 \-\-algorithm hotp\fR
755224
diff --git a/nitrocli/doc/nitrocli.1.pdf b/nitrocli/doc/nitrocli.1.pdf
index 4a3528f..5fa9049 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 b109944..b5d4e81 100644
--- a/nitrocli/src/args.rs
+++ b/nitrocli/src/args.rs
@@ -327,6 +327,7 @@ impl From<OtpMode> for nitrokey::OtpMode {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum OtpSecretFormat {
Ascii,
+ Base32,
Hex,
}
@@ -337,6 +338,7 @@ impl fmt::Display for OtpSecretFormat {
"{}",
match *self {
OtpSecretFormat::Ascii => "ascii",
+ OtpSecretFormat::Base32 => "base32",
OtpSecretFormat::Hex => "hex",
}
)
@@ -349,6 +351,7 @@ impl str::FromStr for OtpSecretFormat {
fn from_str(s: &str) -> result::Result<Self, Self::Err> {
match s {
"ascii" => Ok(OtpSecretFormat::Ascii),
+ "base32" => Ok(OtpSecretFormat::Base32),
"hex" => Ok(OtpSecretFormat::Hex),
_ => Err(()),
}
@@ -777,7 +780,7 @@ pub fn otp_set(ctx: &ExecCtx, args: Vec<String>) -> Result<()> {
let _ = parser.refer(&mut secret_format).add_option(
&["-f", "--format"],
argparse::StoreOption,
- "The format of the secret (ascii|hex)",
+ "The format of the secret (ascii|base32|hex)",
);
parse(&parser, args)?;
drop(parser);
diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs
index 71b2bdd..289c257 100644
--- a/nitrocli/src/commands.rs
+++ b/nitrocli/src/commands.rs
@@ -457,6 +457,13 @@ fn prepare_ascii_secret(secret: &str) -> Result<String> {
}
}
+/// Prepare a base32 secret string for libnitrokey.
+fn prepare_base32_secret(secret: &str) -> Result<String> {
+ base32::decode(base32::Alphabet::RFC4648 { padding: false }, secret)
+ .map(|vec| format_bytes(&vec))
+ .ok_or_else(|| Error::Error("Could not parse base32 secret".to_string()))
+}
+
/// Configure a one-time password slot on the Nitrokey device.
pub fn otp_set(
ctx: &args::ExecCtx,
@@ -468,6 +475,7 @@ pub fn otp_set(
) -> Result<()> {
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,
};
let data = nitrokey::OtpSlotData { secret, ..data };