* mgm: Move TDES weak key checking code into a submodule
* piv: Extract management key algorithm into a separate enum
* mgm: Check management key algorithm when fetching from Yubikey
The CHANGELOG lists the specific versions currently pinned; it will
be modified to instead reference the public releases once they exist
and this crate uses them.
This is required due to the `hybrid-array` crate, which has become a
transitive dependency of the majority of our dependencies and will be
required in the very near future.
* 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.
* 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
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
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.
Renames the following to match Rust idioms:
- `APDU` => `Apdu`
- `CCC` => `Ccc`
- `CHUID` => `ChuId`
Also removes `Copy` from `mscmap::Container`, which fixes a clippy lint
about its usage of `to_bytes`.
* Add MgmKey::set_default method
This wipes any metadata related to derived and PIN-protected management
keys, returning the management key to its default state.
* Transaction::set_mgm_key: Take touch requirement as bool
The Option<u8> was inherited from the original C code's usage of an
unsigned char. We don't need that flexibility, because only two cases
are supported.
* Replace MgmKey::set with MgmKey::set_manual
MgmKey::set_default is now implemented as a wrapper around
MgmKey::set_manual, as they both require clearing metadata related to
derived and PIN-protected management keys.
This factors the junk drawer of constants into the relevant files.
There are still a few "global" ones left but they can be addressed in a
followup commit.
YubiKey NEOs are legacy YubiKey devices, most of which contain
unpatchable security vulnerabilities.
They have smaller buffer sizes than YK4 and YK5, which necessitates a
whole bunch of conditional gating and buffer size calculations.
Getting rid of them simplifies this logic and allows us to assume
consistent buffer sizes everywhere.
We never tested on NEOs anyway, and looking at the deleted code it seems
it may have been miscalculating the NEO's buffer size!
If someone *really* wants to support NEOs, it shouldn't be that hard to
restore, but the codebase is definitely cleaner without it.
Converts a bag of constant values (`YKPIV_INS_*`) into an enum
representing APDU instruction codes (a.k.a. `ins`).
Among other things, this makes the `Debug` output for `APDU` more human
meaningful, since it can print a text label for the instruction rather
than a code number, which is helpful in trace debugging.
This commit merges the `apdu` and `response` modules: the responses are
APDU responses, and so the two are related.
This also moves the `trace` logging into the APDU type, which allows it
to display `Debug` output for APDUs and responses, which makes it easier
to understand what's going on (and will be even better once instructions
are converted into an enum so you can actually see what's happening).
This adds an `untested` feature to any functions which have not yet been
tested live against a YubiKey device (which is presently pretty much
everything).
This sets a clear expectation of what is presently supported, and
additionally documents the status in the README (and a series of GitHub
issues).
Adds a `cargo build --all-features` to GitHub Actions' `test` step in
order to make sure that `untested` functionality still compiles.
Callers of this function always pad up to `CB_PIN_MAX` with `0xFF`.
The logic being changed here was previously identical to the `_verify`
function in `ykpiv.c`:
https://github.com/Yubico/yubico-piv-tool/blob/8ba243f/lib/ykpiv.c#L1299
...but @str4d noticed this potentially allows a caller to send an
unpadded PIN, which may (or may not) be an issue.
This commit contains a "big bang" refactor/rewrite which does the
following:
- Replaces all `SCard*` FFI calls with the `pcsc` crate, which provides
a safe, portable PC/SC API across Windows, macOS, and Linux
- Refactors the `util` module into modules representing the various
device functions and concepts, e.g. `certificate`, `key`, `mgm`
- Replaces all usage of `libc` with `std` functionality, and in many
places rewriting functionality to use safe code.
- Removes `ykpiv_` from all function names, and `Piv*` from type names.
In 20/20 hindsight I wish I had done this commit more incrementally so
as to make it easier to review. Que sera sera.
However, realistically we need to test all functionality on the device
to ensure that it actually works. Going forward I would like to put
pretty much all of the current code behind an `untested` cargo feature,
and then remove it for each bit of functionality we test.