diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-14 11:06:07 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-14 11:06:07 -0800 |
commit | 3399c44a72fa52113d3935c2040765a9d5e42f2c (patch) | |
tree | 6482a7bd60d3787f265b7cc8e966ad99c26423fb | |
parent | d8e4f651a453a37345153a3dfc8593f2419b08af (diff) | |
download | nitrocli-3399c44a72fa52113d3935c2040765a9d5e42f2c.tar.gz nitrocli-3399c44a72fa52113d3935c2040765a9d5e42f2c.tar.bz2 |
Add tests for otp command
This change adds a set of tests for the otp command. We cover some
variants of the status, set, get, and clear. Testing all the possible
combinations is out of scope and so only a more or less arbitrary subset
of arguments was chosen.
-rw-r--r-- | nitrocli/src/args.rs | 6 | ||||
-rw-r--r-- | nitrocli/src/tests/otp.rs | 72 |
2 files changed, 75 insertions, 3 deletions
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index b15ca65..789001e 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -463,7 +463,7 @@ fn otp_get(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut algorithm).add_option( &["-a", "--algorithm"], argparse::Store, - "The OTP algorithm to use (hotp|totp)", + "The OTP algorithm to use (hotp|totp, default: totp)", ); let _ = parser.refer(&mut time).add_option( &["-t", "--time"], @@ -497,7 +497,7 @@ pub fn otp_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut algorithm).add_option( &["-a", "--algorithm"], argparse::Store, - "The OTP algorithm to use (hotp or totp, default: totp)", + "The OTP algorithm to use (hotp|totp, default: totp)", ); let _ = parser.refer(&mut name).required().add_argument( "name", @@ -577,7 +577,7 @@ fn otp_clear(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut algorithm).add_option( &["-a", "--algorithm"], argparse::Store, - "The OTP algorithm to use (hotp|totp)", + "The OTP algorithm to use (hotp|totp, default: totp)", ); parse(ctx, &parser, args)?; drop(parser); diff --git a/nitrocli/src/tests/otp.rs b/nitrocli/src/tests/otp.rs index 403cc80..d99a6f8 100644 --- a/nitrocli/src/tests/otp.rs +++ b/nitrocli/src/tests/otp.rs @@ -40,3 +40,75 @@ fn set_invalid_slot(device: nitrokey::DeviceWrapper) { ) ); } + +#[test_device] +fn status(device: nitrokey::DeviceWrapper) -> crate::Result<()> { + let re = regex::Regex::new( + r#"^alg\tslot\tname +((totp|hotp)\t\d+\t.+\n)+$"#, + ) + .unwrap(); + + let mut ncli = Nitrocli::with_dev(device); + // Make sure that we have at least something to display by ensuring + // that there are there is one slot programmed. + let _ = ncli.handle(&["otp", "set", "0", "the-name", "123456"])?; + + let out = ncli.handle(&["otp", "status"])?; + assert!(re.is_match(&out), out); + Ok(()) +} + +#[test_device] +fn set_get_hotp(device: nitrokey::DeviceWrapper) -> crate::Result<()> { + // Secret and expected HOTP values as per RFC 4226: Appendix D -- HOTP + // Algorithm: Test Values. + const SECRET: &str = "12345678901234567890"; + const OTP1: &str = concat!(755224, "\n"); + const OTP2: &str = concat!(287082, "\n"); + + let mut ncli = Nitrocli::with_dev(device); + let _ = ncli.handle(&[ + "otp", "set", "-a", "hotp", "-f", "ascii", "1", "name", &SECRET, + ])?; + + let out = ncli.handle(&["otp", "get", "-a", "hotp", "1"])?; + assert_eq!(out, OTP1); + + let out = ncli.handle(&["otp", "get", "-a", "hotp", "1"])?; + assert_eq!(out, OTP2); + Ok(()) +} + +#[test_device] +fn set_get_totp(device: nitrokey::DeviceWrapper) -> crate::Result<()> { + // Secret and expected TOTP values as per RFC 6238: Appendix B -- + // Test Vectors. + const SECRET: &str = "12345678901234567890"; + const TIME: &str = stringify!(1111111111); + const OTP: &str = concat!(14050471, "\n"); + + let mut ncli = Nitrocli::with_dev(device); + let _ = ncli.handle(&["otp", "set", "-d", "8", "-f", "ascii", "2", "name", &SECRET])?; + + let out = ncli.handle(&["otp", "get", "-t", TIME, "2"])?; + assert_eq!(out, OTP); + 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"])?; + let _ = ncli.handle(&["otp", "clear", "3"])?; + let res = ncli.handle(&["otp", "get", "3"]); + + assert_eq!( + res.unwrap_cmd_err(), + ( + Some("Could not generate OTP"), + nitrokey::CommandError::SlotNotProgrammed + ) + ); + Ok(()) +} |