Upgrade dependencies; bump version to v0.9.0-pre (#665)

Note: this is not a release, but bumping the version to reflect breaking
changes that have not yet been released.

The following dependencies have been upgraded to new stable releases:
- `cipher` v0.5
- `der` v0.8
- `sha1` v0.11
- `sha2` v0.11
- `rand(_core)` v0.10

The following dependencies are prereleases which have been upgraded from
older prerelease versions:
- `aes` v0.9.0-rc.4
- `curve25519-dalek` 5.0.0-pre.6
- `des` v0.9.0-rc.3
- `ecdsa` v0.17.0-rc.16
- `ed25519-dalek` v3.0.0-pre.6
- `elliptic-curve` v0.14.0-rc.29
- `p256` v0.14.0-rc.8
- `p384` v0.14.0-rc.8
- `pbkdf2` v0.13.0-rc.10
- `rsa` v0.10.0-rc.17
- `signature` v3.0.0-rc.10
- `x25519-dalek` v3.0.0-pre.6
This commit is contained in:
Tony Arcieri (iqlusion)
2026-04-02 13:35:37 -06:00
committed by GitHub
parent 872ba35f54
commit 95babac2d4
11 changed files with 466 additions and 246 deletions
Generated
+404 -169
View File
File diff suppressed because it is too large Load Diff
+20 -21
View File
@@ -1,6 +1,6 @@
[package]
name = "yubikey"
version = "0.8.0"
version = "0.9.0-pre"
description = """
Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with
support for hardware-backed public-key decryption and digital signatures using
@@ -20,36 +20,35 @@ rust-version = "1.85"
members = [".", "cli"]
[workspace.dependencies]
sha2 = "0.11.0-rc.2"
x509-cert = { version = "0.3.0-rc.2", features = ["builder", "hazmat"] }
sha2 = "0.11"
x509-cert = { version = "0.3.0-rc.4", features = ["builder", "hazmat"] }
[dependencies]
aes = { version = "0.9.0-rc.1", features = ["zeroize"] }
aes = { version = "0.9.0-rc.4", features = ["zeroize"] }
bitflags = "2.5.0"
cipher = { version = "0.5.0-rc.1", features = ["rand_core"] }
der = "0.8.0-rc.9"
des = "0.9.0-rc.1"
elliptic-curve = "0.14.0-rc.13"
cipher = { version = "0.5", features = ["getrandom", "rand_core"] }
curve25519-dalek = "5.0.0-pre.6"
der = "0.8"
des = "0.9.0-rc.3"
ecdsa = { version = "0.17.0-rc.16", features = ["digest", "pem"] }
ed25519-dalek = { version = "3.0.0-pre.6", features = ["alloc", "pkcs8"] }
elliptic-curve = "0.14.0-rc.29"
hex = { package = "base16ct", version = "0.2", features = ["alloc"] }
log = "0.4"
nom = "8"
ecdsa = { version = "0.17.0-rc.6", features = ["digest", "pem"] }
p256 = "=0.14.0-pre.11"
p384 = "=0.14.0-pre.11"
pbkdf2 = { version = "0.13.0-rc.1", default-features = false, features = ["hmac"] }
curve25519-dalek = "5.0.0-pre.0"
x25519-dalek = "3.0.0-pre.0"
ed25519-dalek = { version = "3.0.0-pre.0", features = ["alloc", "pkcs8"] }
p256 = "0.14.0-rc.8"
p384 = "0.14.0-rc.8"
pbkdf2 = { version = "0.13.0-rc.10", default-features = false, features = ["hmac"] }
pcsc = "2.3.1"
rand = "0.9"
rand_core = { version = "0.9", features = ["os_rng"] }
rsa = { version = "0.10.0-rc.8", features = ["sha2"] }
secrecy = "0.8"
sha1 = { version = "0.11.0-rc.2", features = ["oid"] }
rand = "0.10"
rand_core = "0.10"
rsa = { version = "0.10.0-rc.17", features = ["sha2"] }
sha1 = { version = "0.11", features = ["oid"] }
sha2 = { workspace = true, features = ["oid"] }
signature = "3.0.0-rc.4"
signature = "3.0.0-rc.10"
subtle = "2"
uuid = { version = "1.2", features = ["v4"] }
x25519-dalek = "3.0.0-pre.6"
x509-cert.workspace = true
zeroize = "1"
+9 -10
View File
@@ -54,13 +54,14 @@ See [Yubico's guide to PIV-enabled YubiKeys][yk-guide] for more information
on which devices support PIV and the available functionality.
### Supported Algorithms
- **Authentication**: `3DES`
- **Encryption**:
- RSA: `RSA1024`, `RSA2048`, `RSA3072`, `RSA4096`
- ECC: `ECCP256`, `ECCP384` (NIST curves: P-256, P-384)
- RSA: `RSA1024`, `RSA2048`, `RSA3072`, `RSA4096`
- ECC: `ECCP256`, `ECCP384` (NIST curves: P-256, P-384)
- **Signatures**:
- RSASSA-PKCS#1v1.5: `RSA1024`, `RSA2048`, `RSA3072`, `RSA4096`
- ECDSA: `ECCP256`, `ECCP384` (NIST curves: P-256, P-384)
- RSASSA-PKCS#1v1.5: `RSA1024`, `RSA2048`, `RSA3072`, `RSA4096`
- ECDSA: `ECCP256`, `ECCP384` (NIST curves: P-256, P-384)
NOTE:
@@ -76,8 +77,7 @@ Rust **1.60** or newer.
- [YubiKey 4] series
- [YubiKey 5] series
NOTE: Nano and USB-C variants of the above are also supported.
Pre-YK4 [YubiKey NEO] series is **NOT** supported (see [#18]).
NOTE: Nano and USB-C variants of the above are also supported. NEO series is NOT supported.
## Supported Operating Systems
@@ -105,8 +105,8 @@ We would appreciate any help testing this functionality and removing the
## Testing
To run the full test suite, you'll need a connected YubiKey NEO/4/5 device in
the default state (i.e. default PIN/PUK).
To run the full test suite, you'll need a supported YubiKey device connected
which is in the default state (i.e. default PIN/PUK).
Tests which run live against a YubiKey device are marked as `#[ignore]` by
default in order to pass when running in a CI environment. To run these
@@ -217,7 +217,7 @@ or conditions.
[docs-link]: https://docs.rs/yubikey/
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
[msrv-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg
[msrv-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
[safety-link]: https://github.com/rust-secure-code/safety-dance/
[build-image]: https://github.com/iqlusioninc/yubikey.rs/actions/workflows/ci.yml/badge.svg
@@ -234,7 +234,6 @@ or conditions.
[PC/SC]: https://en.wikipedia.org/wiki/PC/SC
[`pcsc` crate]: https://github.com/bluetech/pcsc-rust
[yk-guide]: https://developers.yubico.com/PIV/Introduction/YubiKey_and_PIV.html
[YubiKey NEO]: https://support.yubico.com/support/solutions/articles/15000006494-yubikey-neo
[YubiKey 4]: https://support.yubico.com/support/solutions/articles/15000006486-yubikey-4
[YubiKey 5]: https://www.yubico.com/products/yubikey-5-overview/
[yubico-piv-tool]: https://github.com/Yubico/yubico-piv-tool/
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "yubikey-cli"
version = "0.8.0-pre"
version = "0.9.0-pre"
description = """
Command-line interface for performing encryption and signing using RSA/ECC keys
stored on YubiKey devices.
@@ -12,7 +12,7 @@ readme = "README.md"
categories = ["command-line-utilities", "cryptography", "hardware-support"]
keywords = ["ecdsa", "rsa", "piv", "pcsc", "yubikey"]
edition = "2021"
rust-version = "1.81"
rust-version = "1.85"
[dependencies]
clap = { version = "4", features = ["derive"] }
@@ -23,4 +23,4 @@ once_cell = "1"
sha2.workspace = true
termcolor = "1"
x509-cert.workspace = true
yubikey = { version = "0.8", path = ".." }
yubikey = { version = "=0.9.0-pre", path = ".." }
+2 -4
View File
@@ -25,8 +25,7 @@ Rust **1.60** or newer.
- [YubiKey 4] series
- [YubiKey 5] series
NOTE: Nano and USB-C variants of the above are also supported.
Pre-YK4 [YubiKey NEO] series is **NOT** supported (see [#18]).
NOTE: Nano and USB-C variants of the above are also supported. NEO series is NOT supported.
## Security Warning
@@ -84,7 +83,7 @@ or conditions.
[docs-image]: https://docs.rs/yubikey-cli/badge.svg
[docs-link]: https://docs.rs/yubikey-cli/
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
[maintenance-image]: https://img.shields.io/badge/maintenance-experimental-blue.svg
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
[safety-link]: https://github.com/rust-secure-code/safety-dance/
@@ -98,7 +97,6 @@ or conditions.
[PIV]: https://piv.idmanagement.gov/
[yk-guide]: https://developers.yubico.com/PIV/Introduction/YubiKey_and_PIV.html
[Yubico]: https://www.yubico.com/
[YubiKey NEO]: https://support.yubico.com/support/solutions/articles/15000006494-yubikey-neo
[YubiKey 4]: https://support.yubico.com/support/solutions/articles/15000006486-yubikey-4
[YubiKey 5]: https://www.yubico.com/products/yubikey-5-overview/
[yubico-piv-tool]: https://github.com/Yubico/yubico-piv-tool/
+6 -8
View File
@@ -31,7 +31,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{Result, YubiKey};
use rand_core::{OsRng, RngCore, TryRngCore};
use cipher::common::Generate;
use rand_core::CryptoRng;
use std::fmt::{self, Debug, Display};
/// CCCID offset
@@ -66,15 +67,12 @@ impl CardId {
/// Generate a random CCC Card ID
pub fn generate() -> Self {
let mut rng = OsRng.unwrap_err();
Self::generate_from_rng(&mut rng)
Self(Generate::generate())
}
/// Generate a random CCC Card ID from an [`RngCore`]
pub fn generate_from_rng<R: RngCore + ?Sized>(rng: &mut R) -> Self {
let mut id = [0u8; Self::BYTE_SIZE];
rng.fill_bytes(&mut id);
Self(id)
/// Generate a random CCC Card ID from an [`Rng`]
pub fn generate_from_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Self {
Self(Generate::generate_from_rng(rng))
}
}
+6 -7
View File
@@ -39,7 +39,8 @@ use crate::{
};
use bitflags::bitflags;
use cipher::{
typenum::Unsigned, BlockCipherDecrypt, BlockCipherEncrypt, Key, KeyInit, KeySizeUser,
common::Generate, typenum::Unsigned, BlockCipherDecrypt, BlockCipherEncrypt, Key, KeyInit,
KeySizeUser,
};
use log::error;
use rand::TryCryptoRng;
@@ -202,16 +203,16 @@ impl MgmKey {
pub fn generate(alg: MgmAlgorithmId, rng: &mut impl TryCryptoRng) -> Result<Self> {
match alg {
MgmAlgorithmId::ThreeDes => {
des::TdesEde3::try_generate_key_with_rng(rng).map(MgmKeyKind::Tdes)
Key::<des::TdesEde3>::try_generate_from_rng(rng).map(MgmKeyKind::Tdes)
}
MgmAlgorithmId::Aes128 => {
aes::Aes128::try_generate_key_with_rng(rng).map(MgmKeyKind::Aes128)
Key::<aes::Aes128>::try_generate_from_rng(rng).map(MgmKeyKind::Aes128)
}
MgmAlgorithmId::Aes192 => {
aes::Aes192::try_generate_key_with_rng(rng).map(MgmKeyKind::Aes192)
Key::<aes::Aes192>::try_generate_from_rng(rng).map(MgmKeyKind::Aes192)
}
MgmAlgorithmId::Aes256 => {
aes::Aes256::try_generate_key_with_rng(rng).map(MgmKeyKind::Aes256)
Key::<aes::Aes256>::try_generate_from_rng(rng).map(MgmKeyKind::Aes256)
}
}
.map_err(|e| {
@@ -295,7 +296,6 @@ impl MgmKey {
let mut mgm = Key::<des::TdesEde3>::default();
pbkdf2_hmac::<Sha1>(pin, salt, ITER_MGM_PBKDF2, &mut mgm);
des::TdesEde3::weak_key_test(&mgm).map_err(|_| Error::KeyError)?;
Ok(Self(MgmKeyKind::Tdes(mgm)))
}
@@ -480,7 +480,6 @@ impl MgmKey {
MgmAlgorithmId::ThreeDes => {
let key =
Key::<des::TdesEde3>::try_from(bytes.as_ref()).map_err(|_| Error::SizeError)?;
des::TdesEde3::weak_key_test(&key).map_err(|_| Error::KeyError)?;
Ok(MgmKeyKind::Tdes(key))
}
MgmAlgorithmId::Aes128 => Key::<aes::Aes128>::try_from(bytes.as_ref())
+1 -1
View File
@@ -53,7 +53,7 @@ use crate::{
yubikey::YubiKey,
Buffer, ObjectId,
};
use elliptic_curve::{sec1::EncodedPoint as EcPublicKey, PublicKey};
use elliptic_curve::{sec1::Sec1Point as EcPublicKey, PublicKey};
use log::{debug, error, warn};
use p256::NistP256;
use p384::NistP384;
+2 -7
View File
@@ -41,7 +41,7 @@ use std::{
};
/// Source of how a setting was configured.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum SettingSource {
/// User-specified setting: sourced via `YUBIKEY_PIV_*` environment vars.
User,
@@ -51,15 +51,10 @@ pub enum SettingSource {
Admin,
/// Default setting.
#[default]
Default,
}
impl Default for SettingSource {
fn default() -> Self {
Self::Default
}
}
/// Setting booleans: configuration values sourced from a file or the environment.
///
/// These can be configured globally in `/etc/yubico/yubikeypiv.conf` by a
+10 -11
View File
@@ -41,9 +41,10 @@ use crate::{
reader::{Context, Reader},
transaction::Transaction,
};
use cipher::common::getrandom::SysRng;
use log::{error, info};
use pcsc::Card;
use rand_core::{OsRng, RngCore, TryRngCore};
use rand_core::TryRng;
use std::{
cmp::{Ord, Ordering},
fmt::{self, Display},
@@ -60,7 +61,6 @@ use {
transaction::ChangeRefAction,
Buffer, ObjectId,
},
secrecy::ExposeSecret,
std::time::{SystemTime, UNIX_EPOCH},
};
@@ -77,7 +77,8 @@ pub(crate) const KEY_CARDMGM: u8 = 0x9b;
const TAG_DYN_AUTH: u8 = 0x7c;
/// Cached YubiKey PIN.
pub type CachedPin = secrecy::SecretVec<u8>;
// TODO(tarcieri): add a newtype for this with a zeroize impl
pub type CachedPin = Vec<u8>;
/// YubiKey serial number.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
@@ -320,10 +321,7 @@ impl YubiKey {
pcsc::Disposition::ResetCard,
)?;
let pin = self
.pin
.as_ref()
.map(|p| Buffer::new(p.expose_secret().clone()));
let pin = self.pin.as_ref().map(|p| Buffer::new(p.clone()));
let txn = Transaction::new(&mut self.card)?;
txn.select_piv_application()?;
@@ -443,8 +441,9 @@ impl YubiKey {
data.push(challenge_len as u8);
let mut host_challenge = vec![0u8; challenge_len];
let mut rng = OsRng.unwrap_err();
rng.fill_bytes(&mut host_challenge);
SysRng
.try_fill_bytes(&mut host_challenge)
.map_err(|_| Error::GenericError)?;
data.extend_from_slice(&host_challenge);
@@ -501,7 +500,7 @@ impl YubiKey {
}
if !pin.is_empty() {
self.pin = Some(CachedPin::new(pin.into()))
self.pin = Some(pin.into())
}
Ok(())
@@ -557,7 +556,7 @@ impl YubiKey {
}
if !new_pin.is_empty() {
self.pin = Some(CachedPin::new(new_pin.into()));
self.pin = Some(new_pin.into());
}
Ok(())
+3 -5
View File
@@ -3,9 +3,9 @@
#![forbid(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)]
use cipher::common::{getrandom::SysRng, Generate};
use log::trace;
use once_cell::sync::Lazy;
use rand_core::{OsRng, RngCore, TryRngCore};
use rsa::{pkcs1v15, RsaPublicKey};
use sha2::{Digest, Sha256};
use signature::hazmat::PrehashVerifier;
@@ -129,7 +129,7 @@ fn test_verify_pin() {
#[test]
#[ignore]
fn test_set_mgmkey() {
let mut rng = OsRng;
let mut rng = SysRng;
let mut yubikey = match YUBIKEY.lock() {
Ok(yubikey) => yubikey,
Err(poison) => poison.into_inner(),
@@ -190,9 +190,7 @@ fn generate_self_signed_cert<KT: yubikey_signer::KeyType>() -> Certificate {
// 0x80 0x00 ... (20bytes) is invalid because of high MSB (serial will keep the sign)
// we'll limit ourselves to 19 bytes serial.
let mut serial = [0u8; 19];
let mut rng = OsRng.unwrap_err();
rng.fill_bytes(&mut serial);
let serial = <[u8; 19]>::generate();
let serial = SerialNumber::new(&serial[..]).expect("serial can't be more than 20 bytes long");
let validity = Validity::from_now(Duration::new(500000, 0)).unwrap();