Bump MSRV to 1.81 (#582)

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.
This commit is contained in:
Jack Grigg
2024-11-26 07:58:24 +13:00
committed by GitHub
parent 0a90dc3ca8
commit 32cd92af50
13 changed files with 50 additions and 64 deletions
+4 -4
View File
@@ -36,13 +36,13 @@ jobs:
toolchain: stable toolchain: stable
deps: true deps: true
- platform: ubuntu-latest - platform: ubuntu-latest
toolchain: 1.74.0 # MSRV toolchain: 1.81.0 # MSRV
deps: sudo apt-get install libpcsclite-dev deps: sudo apt-get install libpcsclite-dev
- platform: windows-latest - platform: windows-latest
toolchain: 1.74.0 # MSRV toolchain: 1.81.0 # MSRV
deps: true deps: true
- platform: macos-latest - platform: macos-latest
toolchain: 1.74.0 # MSRV toolchain: 1.81.0 # MSRV
deps: true deps: true
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
@@ -82,7 +82,7 @@ jobs:
- uses: actions-rs/toolchain@v1 - uses: actions-rs/toolchain@v1
with: with:
profile: minimal profile: minimal
toolchain: 1.74.0 # MSRV toolchain: 1.81.0 # MSRV
components: clippy components: clippy
override: true override: true
- run: sudo apt-get install libpcsclite-dev - run: sudo apt-get install libpcsclite-dev
+4
View File
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- MSRV is now 1.81.
## 0.8.0 (2023-08-15) ## 0.8.0 (2023-08-15)
### Added ### Added
- `impl Debug for {Context, YubiKey}` ([#457]) - `impl Debug for {Context, YubiKey}` ([#457])
+1 -1
View File
@@ -14,7 +14,7 @@ readme = "README.md"
categories = ["api-bindings", "authentication", "cryptography", "hardware-support"] categories = ["api-bindings", "authentication", "cryptography", "hardware-support"]
keywords = ["ecdsa", "encryption", "rsa", "piv", "signature"] keywords = ["ecdsa", "encryption", "rsa", "piv", "signature"]
edition = "2021" edition = "2021"
rust-version = "1.65" rust-version = "1.81"
[workspace] [workspace]
members = [".", "cli"] members = [".", "cli"]
+1 -1
View File
@@ -214,7 +214,7 @@ or conditions.
[docs-link]: https://docs.rs/yubikey/ [docs-link]: https://docs.rs/yubikey/
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg [license-image]: https://img.shields.io/badge/license-BSD-blue.svg
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING [license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
[msrv-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [msrv-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg [safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
[safety-link]: https://github.com/rust-secure-code/safety-dance/ [safety-link]: https://github.com/rust-secure-code/safety-dance/
[build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push [build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push
+4
View File
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- MSRV is now 1.81.
## 0.7.0 (2022-11-14) ## 0.7.0 (2022-11-14)
### Changed ### Changed
- Bump `clap` to v4.0 ([#438]) - Bump `clap` to v4.0 ([#438])
+1 -1
View File
@@ -12,7 +12,7 @@ readme = "README.md"
categories = ["command-line-utilities", "cryptography", "hardware-support"] categories = ["command-line-utilities", "cryptography", "hardware-support"]
keywords = ["ecdsa", "rsa", "piv", "pcsc", "yubikey"] keywords = ["ecdsa", "rsa", "piv", "pcsc", "yubikey"]
edition = "2021" edition = "2021"
rust-version = "1.56" rust-version = "1.81"
[dependencies] [dependencies]
clap = { version = "4", features = ["derive"] } clap = { version = "4", features = ["derive"] }
+1 -1
View File
@@ -196,7 +196,7 @@ pub fn print_cert_info(
print_cert_attr( print_cert_attr(
stream, stream,
"Fingerprint", "Fingerprint",
&hex::upper::encode_string(&fingerprint), hex::upper::encode_string(&fingerprint),
)?; )?;
print_cert_attr( print_cert_attr(
stream, stream,
+2 -2
View File
@@ -192,8 +192,8 @@ impl std::error::Error for Error {
} }
} }
impl From<x509_cert::der::Error> for Error { impl From<der::Error> for Error {
fn from(_err: x509_cert::der::Error) -> Error { fn from(_err: der::Error) -> Error {
Error::ParseError Error::ParseError
} }
} }
+12 -20
View File
@@ -155,15 +155,12 @@ impl MgmKey {
pub fn get_protected(yubikey: &mut YubiKey) -> Result<Self> { pub fn get_protected(yubikey: &mut YubiKey) -> Result<Self> {
let txn = yubikey.begin_transaction()?; let txn = yubikey.begin_transaction()?;
let protected_data = ProtectedData::read(&txn).map_err(|e| { let protected_data = ProtectedData::read(&txn)
error!("could not read protected data (err: {:?})", e); .inspect_err(|e| error!("could not read protected data (err: {:?})", e))?;
e
})?;
let item = protected_data.get_item(TAG_PROTECTED_MGM).map_err(|e| { let item = protected_data
error!("could not read protected MGM from metadata (err: {:?})", e); .get_item(TAG_PROTECTED_MGM)
e .inspect_err(|e| error!("could not read protected MGM from metadata (err: {:?})", e))?;
})?;
if item.len() != DES_LEN_3DES { if item.len() != DES_LEN_3DES {
error!( error!(
@@ -196,12 +193,10 @@ impl MgmKey {
pub fn set_manual(&self, yubikey: &mut YubiKey, require_touch: bool) -> Result<()> { pub fn set_manual(&self, yubikey: &mut YubiKey, require_touch: bool) -> Result<()> {
let txn = yubikey.begin_transaction()?; let txn = yubikey.begin_transaction()?;
txn.set_mgm_key(self, require_touch).map_err(|e| { txn.set_mgm_key(self, require_touch)
// Log a warning, since the device mgm key is corrupt or we're in a state // Log a warning, since the device mgm key is corrupt or we're in a state
// where we can't set the mgm key. // where we can't set the mgm key.
error!("could not set new derived mgm key, err = {}", e); .inspect_err(|e| error!("could not set new derived mgm key, err = {}", e))?;
e
})?;
// After this point, we've set the mgm key, so the function should succeed, // After this point, we've set the mgm key, so the function should succeed,
// regardless of being able to set the metadata. // regardless of being able to set the metadata.
@@ -255,12 +250,10 @@ impl MgmKey {
pub fn set_protected(&self, yubikey: &mut YubiKey) -> Result<()> { pub fn set_protected(&self, yubikey: &mut YubiKey) -> Result<()> {
let txn = yubikey.begin_transaction()?; let txn = yubikey.begin_transaction()?;
txn.set_mgm_key(self, false).map_err(|e| { txn.set_mgm_key(self, false)
// log a warning, since the device mgm key is corrupt or we're in // log a warning, since the device mgm key is corrupt or we're in
// a state where we can't set the mgm key // a state where we can't set the mgm key
error!("could not set new derived mgm key, err = {}", e); .inspect_err(|e| error!("could not set new derived mgm key, err = {}", e))?;
e
})?;
// after this point, we've set the mgm key, so the function should // after this point, we've set the mgm key, so the function should
// succeed, regardless of being able to set the metadata // succeed, regardless of being able to set the metadata
@@ -272,10 +265,9 @@ impl MgmKey {
if let Err(e) = protected_data.set_item(TAG_PROTECTED_MGM, self.as_ref()) { if let Err(e) = protected_data.set_item(TAG_PROTECTED_MGM, self.as_ref()) {
error!("could not set protected mgm item, err = {:?}", e); error!("could not set protected mgm item, err = {:?}", e);
} else { } else {
protected_data.write(&txn).map_err(|e| { protected_data
error!("could not write protected data, err = {:?}", e); .write(&txn)
e .inspect_err(|e| error!("could not write protected data, err = {:?}", e))?;
})?;
} }
// set the protected mgm flag in admin data // set the protected mgm flag in admin data
+3 -4
View File
@@ -96,10 +96,9 @@ impl MsRoots {
} }
} }
MsRoots::new(&data).map(Some).map_err(|e| { MsRoots::new(&data)
error!("error parsing msroots: {:?}", e); .map(Some)
e .inspect_err(|e| error!("error parsing msroots: {:?}", e))
})
} }
/// Write `msroots` file to YubiKey /// Write `msroots` file to YubiKey
+2 -8
View File
@@ -66,10 +66,7 @@ impl<'tx> Transaction<'tx> {
.p1(0x04) .p1(0x04)
.data(piv::APPLET_ID) .data(piv::APPLET_ID)
.transmit(self, 0xFF) .transmit(self, 0xFF)
.map_err(|e| { .inspect_err(|e| error!("failed communicating with card: '{}'", e))?;
error!("failed communicating with card: '{}'", e);
e
})?;
if !response.is_success() { if !response.is_success() {
error!( error!(
@@ -335,10 +332,7 @@ impl<'tx> Transaction<'tx> {
let response = self let response = self
.transfer_data(&templ, &indata[..offset], 1024) .transfer_data(&templ, &indata[..offset], 1024)
.map_err(|e| { .inspect_err(|e| error!("sign command failed to communicate: {}", e))?;
error!("sign command failed to communicate: {}", e);
e
})?;
if !response.is_success() { if !response.is_success() {
error!("failed sign command with code {:x}", response.code()); error!("failed sign command with code {:x}", response.code());
+13 -17
View File
@@ -42,7 +42,7 @@ use crate::{
transaction::Transaction, transaction::Transaction,
}; };
use log::{error, info}; use log::{error, info};
use pcsc::{Card, Disposition}; use pcsc::Card;
use rand_core::{OsRng, RngCore}; use rand_core::{OsRng, RngCore};
use std::{ use std::{
fmt::{self, Display}, fmt::{self, Display},
@@ -293,7 +293,10 @@ impl YubiKey {
/// `YubiKey` implements `Drop` which automatically disconnects the card using /// `YubiKey` implements `Drop` which automatically disconnects the card using
/// `Disposition::ResetCard`; you only need to call this function if you want to /// `Disposition::ResetCard`; you only need to call this function if you want to
/// handle errors or use a different disposition method. /// handle errors or use a different disposition method.
pub fn disconnect(self, disposition: Disposition) -> core::result::Result<(), (Self, Error)> { pub fn disconnect(
self,
disposition: pcsc::Disposition,
) -> core::result::Result<(), (Self, Error)> {
let Self { let Self {
card, card,
name, name,
@@ -523,15 +526,11 @@ impl YubiKey {
admin_data admin_data
.set_item(TAG_ADMIN_TIMESTAMP, &tnow) .set_item(TAG_ADMIN_TIMESTAMP, &tnow)
.map_err(|e| { .inspect_err(|e| error!("could not set pin timestamp, err = {}", e))?;
error!("could not set pin timestamp, err = {}", e);
e
})?;
admin_data.write(&txn).map_err(|e| { admin_data
error!("could not write admin data, err = {}", e); .write(&txn)
e .inspect_err(|e| error!("could not write admin data, err = {}", e))?;
})?;
Ok(()) Ok(())
} }
@@ -581,7 +580,7 @@ impl YubiKey {
// Attempt to set the "PUK blocked" flag in admin data. // Attempt to set the "PUK blocked" flag in admin data.
let mut admin_data = AdminData::read(&txn) let mut admin_data = AdminData::read(&txn)
.map(|data| { .inspect(|data| {
if let Ok(item) = data.get_item(TAG_ADMIN_FLAGS_1) { if let Ok(item) = data.get_item(TAG_ADMIN_FLAGS_1) {
if item.len() == flags.len() { if item.len() == flags.len() {
flags.copy_from_slice(item) flags.copy_from_slice(item)
@@ -593,8 +592,6 @@ impl YubiKey {
); );
} }
} }
data
}) })
.unwrap_or_default(); .unwrap_or_default();
@@ -703,10 +700,9 @@ impl<'a> TryFrom<&'a Reader<'_>> for YubiKey {
type Error = Error; type Error = Error;
fn try_from(reader: &'a Reader<'_>) -> Result<Self> { fn try_from(reader: &'a Reader<'_>) -> Result<Self> {
let mut card = reader.connect().map_err(|e| { let mut card = reader
error!("error connecting to reader '{}': {}", reader.name(), e); .connect()
e .inspect_err(|e| error!("error connecting to reader '{}': {}", reader.name(), e))?;
})?;
info!("connected to reader: {}", reader.name()); info!("connected to reader: {}", reader.name());
+2 -5
View File
@@ -12,9 +12,7 @@ use signature::hazmat::PrehashVerifier;
use std::{env, str::FromStr, sync::Mutex, time::Duration}; use std::{env, str::FromStr, sync::Mutex, time::Duration};
use x509_cert::{der::Encode, name::Name, serial_number::SerialNumber, time::Validity}; use x509_cert::{der::Encode, name::Name, serial_number::SerialNumber, time::Validity};
use yubikey::{ use yubikey::{
certificate, certificate::{yubikey_signer, Certificate},
certificate::yubikey_signer,
certificate::Certificate,
piv::{self, AlgorithmId, Key, ManagementSlotId, RetiredSlotId, SlotId}, piv::{self, AlgorithmId, Key, ManagementSlotId, RetiredSlotId, SlotId},
Error, MgmKey, PinPolicy, Serial, TouchPolicy, YubiKey, Error, MgmKey, PinPolicy, Serial, TouchPolicy, YubiKey,
}; };
@@ -317,8 +315,7 @@ fn test_read_metadata() {
#[ignore] #[ignore]
fn test_parse_cert_from_der() { fn test_parse_cert_from_der() {
let bob_der = std::fs::read("tests/assets/Bob.der").expect(".der file not found"); let bob_der = std::fs::read("tests/assets/Bob.der").expect(".der file not found");
let cert = let cert = Certificate::from_bytes(bob_der).expect("Failed to parse valid certificate");
certificate::Certificate::from_bytes(bob_der).expect("Failed to parse valid certificate");
assert_eq!( assert_eq!(
cert.subject(), cert.subject(),
"CN=Bob", "CN=Bob",