On systems with a physical card-reader, the previous implementation falsely
reports "multiple YubiKeys detected!", even if only one YubiKey is connected.
This change attempts to actually open each reader as a YubiKey, and only
reports "multiple YubiKeys" if it can actually open more than one.
Additionally, this change avoids resetting the YubiKeys in case we find more
than one.
* Fix `StatusWords::code` output for `StatusWords::VerifyFailError`
Closesiqlusioninc/yubikey.rs#473.
* Refactor `Transaction::transfer_data` to match on `StatusWords`
This makes the code more reliable, such that it would have avoided
the bug in iqlusioninc/yubikey.rs#473.
* Return errors from `YubiKey::open_by_serial` that indicate a key may exist
The only such error at the moment is `pcsc::Error::SharingViolation`, which
indicates a transient failure to access a specific reader that could have
been the one we needed (and so a future retry might succeed).
Closesiqlusioninc/yubikey.rs#458.
* Avoid resetting unused devices in YubiKey::open_by_serial
We only connect to readers so that we can determine their serial. We
now try to ensure that the order in which we connect to them doesn't
have an effect on their state after we are done.
* Enable library users to detect if a smart card doesn't support PIV
Closesiqlusioninc/yubikey.rs#456.
* Avoid resetting the card if we fail to select PIV or fetch version/serial
In iqlusioninc/yubikey.rs#88 we added a workaround for what turned out
to be a bug in `pcsc`, where an error was returned if no readers were
available, instead of returning an empty iterator. `pcsc 2.3.1` was
published in 2019, so we can safely rely on it.
Checks the length of the data returned when querying the serial number,
returning an error if it's longer than 4 bytes, and left-padding with
zeroes if it's too short.
This fixes some potential panics due to incorrect slice lengths as were
experienced in #465
Re-exports types from the toplevel instead of placing them in individual
modules (often which only contain one type).
This makes the API easier for users to navigate, while still retaining
the same module structure internally.
Additionally, this commit uses the `uuid` crate for modeling UUIDs.
Renames the type used for storing a configuration setting.
Also changes the internal functions to use `Option<ConfigValue>` as the
return value, rather than comparing to a default value, which makes them
slightly more idiomatic.
Adds a `yubikey::Result` alias with `yubikey::Error` as the error type.
Since we only have one `Error` type, this simplifies the return types
where a `Result` is returned.