diff options
| author | Robin Krahl <robin.krahl@ireas.org> | 2020-01-15 13:24:48 +0100 | 
|---|---|---|
| committer | Robin Krahl <robin.krahl@ireas.org> | 2020-01-15 13:24:58 +0100 | 
| commit | 817409140a8778215d2d65d614d3672166fff576 (patch) | |
| tree | 3be135582759a2d16f2c29fc2dfb682938cd2c8c | |
| parent | 62d37c8d4e7d1caca21f23978198b721efc5973b (diff) | |
| parent | 5e5d5493331305c97f6ffd059246f0cbff4ae696 (diff) | |
| download | nitrokey-rs-817409140a8778215d2d65d614d3672166fff576.tar.gz nitrokey-rs-817409140a8778215d2d65d614d3672166fff576.tar.bz2 | |
Merge branch 'release-0.5.1'
| -rw-r--r-- | CHANGELOG.md | 4 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | examples/list-devices.rs | 2 | ||||
| -rw-r--r-- | examples/otp.rs | 2 | ||||
| -rw-r--r-- | src/device/mod.rs | 69 | 
6 files changed, 57 insertions, 24 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ee7d3..cba0e83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Copyright (C) 2019-2020 Robin Krahl <robin.krahl@ireas.org>  SPDX-License-Identifier: CC0-1.0  --> +# v0.5.1 (2020-01-15) +- Fix serial number formatting for Nitrokey Pro devices with firmware 0.8 or +  older in the `list_devices` function. +  # v0.5.0 (2020-01-14)  - List these libnitrokey functions as unsupported:    - `NK_change_firmware_password_pro` @@ -3,7 +3,7 @@  [package]  name = "nitrokey" -version = "0.5.0" +version = "0.5.1"  authors = ["Robin Krahl <robin.krahl@ireas.org>"]  edition = "2018"  homepage = "https://code.ireas.org/nitrokey-rs/" @@ -102,7 +102,7 @@ in the `LICENSES` directory.  `libnitrokey` is licensed under the [LGPL-3.0][].  `nitrokey-rs` complies with [version 3.0 of the REUSE specification][reuse].  [API reference]: https://docs.rs/nitrokey -[examples]: https://docs.rs/crate/nitrokey/0.4.0/source/examples/ +[examples]: https://git.ireas.org/nitrokey-rs/tree/examples  [`nitrocli`]: https://github.com/d-e-s-o/nitrocli/tree/master/nitrocli  [Nitrokey udev rules]: https://www.nitrokey.com/documentation/frequently-asked-questions-faq#openpgp-card-not-available  [`libnitrokey`]: https://github.com/nitrokey/libnitrokey diff --git a/examples/list-devices.rs b/examples/list-devices.rs index 9c14533..47fa054 100644 --- a/examples/list-devices.rs +++ b/examples/list-devices.rs @@ -1,5 +1,5 @@  // Copyright (C) 2020 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: CC-0 +// SPDX-License-Identifier: CC0-1.0  //! Enumerates all connected Nitrokey devices and prints some information about them. diff --git a/examples/otp.rs b/examples/otp.rs index 819de28..f2c6f3c 100644 --- a/examples/otp.rs +++ b/examples/otp.rs @@ -1,5 +1,5 @@  // Copyright (C) 2020 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: CC-0 +// SPDX-License-Identifier: CC0-1.0  //! Connects to a Nitrokey device, configures an TOTP slot and generates a one-time password from  //! it. diff --git a/src/device/mod.rs b/src/device/mod.rs index 16d6b11..0234bf0 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -5,7 +5,6 @@ mod pro;  mod storage;  mod wrapper; -use std::cmp;  use std::convert::{TryFrom, TryInto};  use std::ffi;  use std::fmt; @@ -120,21 +119,38 @@ impl fmt::Display for DeviceInfo {  /// Parses a serial number returned by hidapi and transforms it to the Nitrokey format.  /// -/// If the serial number is all zero, this function returns `None`.  Otherwise, all leading zeros -/// (except the last eight characters) are stripped and `Some(_)` is returned.  If the serial -/// number has less than eight characters, leading zeros are added. +/// If the serial number is all zero, this function returns `None`.  Otherwise, it uses the last +/// eight characters.  If these are all zero, the first eight characters are used instead.  This +/// function also makes sure that the returned string is lowercase, consistent with libnitrokey’s +/// hex string formatting. +/// +/// The reason for this behavior is that the Nitrokey Storage does not report its serial number at +/// all (all zero value), while the Nitrokey Pro with firmware 0.9 or later writes its serial +/// number to the last eight characters.  Nitrokey Pro devices with firmware 0.8 or earlier wrote +/// their serial number to the first eight characters.  fn get_hidapi_serial_number(serial_number: &str) -> Option<String> { -    let mut iter = serial_number.char_indices().skip_while(|(_, c)| *c == '0'); -    let first_non_null = iter.next(); +    let len = serial_number.len(); +    if len < 8 { +        // The serial number in the USB descriptor has 12 bytes, we need at least four of them +        return None; +    } + +    let iter = serial_number.char_indices().rev(); +    let first_non_null = iter.skip_while(|(_, c)| *c == '0').next();      if let Some((i, _)) = first_non_null { -        // keep at least the last 8 characters -        let len = serial_number.len(); -        let cut = cmp::min(len.saturating_sub(8), i); -        let (_, suffix) = serial_number.split_at(cut); -        // if necessary, add leading zeros to reach 8 characters -        let fill = 8usize.saturating_sub(len); -        Some("0".repeat(fill) + suffix) +        if len - i < 8 { +            // The last eight characters contain at least one non-zero character --> use them +            let mut serial_number = serial_number.split_at(len - 8).1.to_string(); +            serial_number.make_ascii_lowercase(); +            Some(serial_number) +        } else { +            // The last eight characters are all zero --> use the first eight +            let mut serial_number = serial_number.split_at(8).0.to_string(); +            serial_number.make_ascii_lowercase(); +            Some(serial_number) +        }      } else { +        // The serial number is all zero          None      }  } @@ -615,10 +631,7 @@ mod tests {      fn hidapi_serial_number() {          assert_eq!(None, get_hidapi_serial_number(""));          assert_eq!(None, get_hidapi_serial_number("00000000000000000")); -        assert_eq!( -            Some("00001234".to_string()), -            get_hidapi_serial_number("1234") -        ); +        assert_eq!(None, get_hidapi_serial_number("1234"));          assert_eq!(              Some("00001234".to_string()),              get_hidapi_serial_number("00001234") @@ -628,12 +641,28 @@ mod tests {              get_hidapi_serial_number("000000001234")          );          assert_eq!( -            Some("100000001234".to_string()), +            Some("00001234".to_string()),              get_hidapi_serial_number("100000001234")          );          assert_eq!( -            Some("10000001234".to_string()), -            get_hidapi_serial_number("010000001234") +            Some("12340000".to_string()), +            get_hidapi_serial_number("123400000000") +        ); +        assert_eq!( +            Some("00005678".to_string()), +            get_hidapi_serial_number("000000000000000000005678") +        ); +        assert_eq!( +            Some("00001234".to_string()), +            get_hidapi_serial_number("000012340000000000000000") +        ); +        assert_eq!( +            Some("0000ffff".to_string()), +            get_hidapi_serial_number("00000000000000000000FFFF") +        ); +        assert_eq!( +            Some("0000ffff".to_string()), +            get_hidapi_serial_number("00000000000000000000ffff")          );      }  } | 
