Add clippy::unwrap_used lint (#515)

Lints for usages of `unwrap()` in the `yubikey` crate (not CLI yet).

Replaces them with `?` or `expect()` as the situation warrants.
This commit is contained in:
Tony Arcieri (iqlusion)
2023-08-15 17:02:25 -07:00
committed by GitHub
parent d226209ea4
commit 78313360a1
11 changed files with 65 additions and 51 deletions
+3 -7
View File
@@ -30,7 +30,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{Error, Result, YubiKey}; use crate::{Result, YubiKey};
use rand_core::{OsRng, RngCore}; use rand_core::{OsRng, RngCore};
use std::fmt::{self, Debug, Display}; use std::fmt::{self, Debug, Display};
@@ -48,6 +48,7 @@ const OBJ_CAPABILITY: u32 = 0x005f_c107;
/// - 0xff == Manufacturer ID (dummy) /// - 0xff == Manufacturer ID (dummy)
/// - 0x02 == Card type (javaCard) /// - 0x02 == Card type (javaCard)
/// - next 14 bytes: card ID /// - next 14 bytes: card ID
#[allow(dead_code)]
const CCC_TMPL: &[u8] = &[ const CCC_TMPL: &[u8] = &[
0xf0, 0x15, 0xa0, 0x00, 0x00, 0x01, 0x16, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x15, 0xa0, 0x00, 0x00, 0x01, 0x16, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x01, 0x21, 0xf2, 0x01, 0x21, 0xf3, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x01, 0x21, 0xf2, 0x01, 0x21, 0xf3, 0x00, 0xf4,
@@ -90,12 +91,7 @@ impl CccId {
pub fn get(yubikey: &mut YubiKey) -> Result<Self> { pub fn get(yubikey: &mut YubiKey) -> Result<Self> {
let txn = yubikey.begin_transaction()?; let txn = yubikey.begin_transaction()?;
let response = txn.fetch_object(OBJ_CAPABILITY)?; let response = txn.fetch_object(OBJ_CAPABILITY)?;
Ok(response[..Self::BYTE_SIZE].try_into().map(Self)?)
if response.len() != CCC_TMPL.len() {
return Err(Error::GenericError);
}
Ok(Self(response[..Self::BYTE_SIZE].try_into().unwrap()))
} }
/// Set Cardholder Capability Container (CCC) ID /// Set Cardholder Capability Container (CCC) ID
+4 -6
View File
@@ -223,12 +223,7 @@ pub(crate) fn write_certificate(
) -> Result<()> { ) -> Result<()> {
let object_id = slot.object_id(); let object_id = slot.object_id();
if data.is_none() { if let Some(data) = data {
return txn.save_object(object_id, &[]);
}
let data = data.unwrap();
let mut buf = [0u8; CB_OBJ_MAX]; let mut buf = [0u8; CB_OBJ_MAX];
let mut offset = Tlv::write(&mut buf, TAG_CERT, data)?; let mut offset = Tlv::write(&mut buf, TAG_CERT, data)?;
@@ -237,6 +232,9 @@ pub(crate) fn write_certificate(
offset += Tlv::write(&mut buf[offset..], TAG_CERT_LRC, &[])?; offset += Tlv::write(&mut buf[offset..], TAG_CERT_LRC, &[])?;
txn.save_object(object_id, &buf[..offset]) txn.save_object(object_id, &buf[..offset])
} else {
txn.save_object(object_id, &[])
}
} }
pub mod yubikey_signer { pub mod yubikey_signer {
+7 -10
View File
@@ -30,7 +30,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{Error, Result, YubiKey}; use crate::{Result, YubiKey};
use std::fmt::{self, Debug, Display}; use std::fmt::{self, Debug, Display};
use uuid::Uuid; use uuid::Uuid;
@@ -61,6 +61,7 @@ const OBJ_CHUID: u32 = 0x005f_c102;
/// - 0x35: Exp. Date (hard-coded) /// - 0x35: Exp. Date (hard-coded)
/// - 0x3e: Signature (hard-coded, empty) /// - 0x3e: Signature (hard-coded, empty)
/// - 0xfe: Error Detection Code (hard-coded) /// - 0xfe: Error Detection Code (hard-coded)
#[allow(dead_code)]
const CHUID_TMPL: &[u8] = &[ const CHUID_TMPL: &[u8] = &[
0x30, 0x19, 0xd4, 0xe7, 0x39, 0xda, 0x73, 0x9c, 0xed, 0x39, 0xce, 0x73, 0x9d, 0x83, 0x68, 0x58, 0x30, 0x19, 0xd4, 0xe7, 0x39, 0xda, 0x73, 0x9c, 0xed, 0x39, 0xce, 0x73, 0x9d, 0x83, 0x68, 0x58,
0x21, 0x08, 0x42, 0x10, 0x84, 0x21, 0xc8, 0x42, 0x10, 0xc3, 0xeb, 0x34, 0x10, 0x00, 0x00, 0x00, 0x21, 0x08, 0x42, 0x10, 0x84, 0x21, 0xc8, 0x42, 0x10, 0xc3, 0xeb, 0x34, 0x10, 0x00, 0x00, 0x00,
@@ -86,12 +87,13 @@ impl ChuId {
pub fn fascn(&self) -> [u8; Self::FASCN_SIZE] { pub fn fascn(&self) -> [u8; Self::FASCN_SIZE] {
self.0[CHUID_FASCN_OFFS..(CHUID_FASCN_OFFS + Self::FASCN_SIZE)] self.0[CHUID_FASCN_OFFS..(CHUID_FASCN_OFFS + Self::FASCN_SIZE)]
.try_into() .try_into()
.unwrap() .expect("should be FASCN_SIZE")
} }
/// Return Card UUID/GUID component of CHUID /// Return Card UUID/GUID component of CHUID
pub fn uuid(&self) -> Uuid { pub fn uuid(&self) -> Uuid {
Uuid::from_slice(&self.0[CHUID_GUID_OFFS..(CHUID_GUID_OFFS + 16)]).unwrap() Uuid::from_slice(&self.0[CHUID_GUID_OFFS..(CHUID_GUID_OFFS + 16)])
.expect("should be UUID-sized")
} }
/// Return expiration date component of CHUID /// Return expiration date component of CHUID
@@ -99,19 +101,14 @@ impl ChuId {
pub fn expiration(&self) -> [u8; Self::EXPIRATION_SIZE] { pub fn expiration(&self) -> [u8; Self::EXPIRATION_SIZE] {
self.0[CHUID_EXPIRATION_OFFS..(CHUID_EXPIRATION_OFFS + Self::EXPIRATION_SIZE)] self.0[CHUID_EXPIRATION_OFFS..(CHUID_EXPIRATION_OFFS + Self::EXPIRATION_SIZE)]
.try_into() .try_into()
.unwrap() .expect("should be EXPIRATION_SIZE")
} }
/// Get Cardholder Unique Identifier (CHUID) /// Get Cardholder Unique Identifier (CHUID)
pub fn get(yubikey: &mut YubiKey) -> Result<ChuId> { pub fn get(yubikey: &mut YubiKey) -> Result<ChuId> {
let txn = yubikey.begin_transaction()?; let txn = yubikey.begin_transaction()?;
let response = txn.fetch_object(OBJ_CHUID)?; let response = txn.fetch_object(OBJ_CHUID)?;
Ok(response[..Self::BYTE_SIZE].try_into().map(Self)?)
if response.len() != CHUID_TMPL.len() {
return Err(Error::GenericError);
}
Ok(ChuId(response[..Self::BYTE_SIZE].try_into().unwrap()))
} }
/// Set Cardholder Unique Identifier (CHUID) /// Set Cardholder Unique Identifier (CHUID)
+1 -1
View File
@@ -111,7 +111,7 @@ impl Config {
error!("pin timestamp in admin metadata is an invalid size"); error!("pin timestamp in admin metadata is an invalid size");
} else { } else {
// TODO(tarcieri): double-check endianness is correct // TODO(tarcieri): double-check endianness is correct
let pin_last_changed = u32::from_le_bytes(item.try_into().unwrap()); let pin_last_changed = u32::from_le_bytes([item[0], item[1], item[2], item[3]]);
if pin_last_changed != 0 { if pin_last_changed != 0 {
config.pin_last_changed = config.pin_last_changed =
+12
View File
@@ -164,6 +164,18 @@ impl Display for Error {
} }
} }
impl From<std::array::TryFromSliceError> for Error {
fn from(_: std::array::TryFromSliceError) -> Error {
Error::SizeError
}
}
impl From<std::time::SystemTimeError> for Error {
fn from(_: std::time::SystemTimeError) -> Error {
Error::GenericError
}
}
impl From<pcsc::Error> for Error { impl From<pcsc::Error> for Error {
fn from(err: pcsc::Error) -> Error { fn from(err: pcsc::Error) -> Error {
Error::PcscError { inner: Some(err) } Error::PcscError { inner: Some(err) }
+8 -1
View File
@@ -4,7 +4,14 @@
)] )]
#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)] #![warn(
clippy::mod_module_files,
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
// Adapted from yubico-piv-tool: // Adapted from yubico-piv-tool:
// <https://github.com/Yubico/yubico-piv-tool/> // <https://github.com/Yubico/yubico-piv-tool/>
+9 -7
View File
@@ -140,7 +140,7 @@ impl MsContainer {
let name_bytes_len = Self::NAME_LEN * 2; let name_bytes_len = Self::NAME_LEN * 2;
for (i, chunk) in bytes[..name_bytes_len].chunks_exact(2).enumerate() { for (i, chunk) in bytes[..name_bytes_len].chunks_exact(2).enumerate() {
name[i] = u16::from_le_bytes(chunk.try_into().unwrap()); name[i] = u16::from_le_bytes([chunk[0], chunk[1]]);
} }
let mut cert_fingerprint = [0u8; 20]; let mut cert_fingerprint = [0u8; 20];
@@ -150,11 +150,10 @@ impl MsContainer {
name, name,
slot: bytes[name_bytes_len].try_into()?, slot: bytes[name_bytes_len].try_into()?,
key_spec: bytes[name_bytes_len + 1], key_spec: bytes[name_bytes_len + 1],
key_size_bits: u16::from_le_bytes( key_size_bits: u16::from_le_bytes([
bytes[(name_bytes_len + 2)..(name_bytes_len + 4)] bytes[name_bytes_len + 2],
.try_into() bytes[name_bytes_len + 3],
.unwrap(), ]),
),
flags: bytes[name_bytes_len + 4], flags: bytes[name_bytes_len + 4],
pin_id: bytes[name_bytes_len + 5], pin_id: bytes[name_bytes_len + 5],
associated_echd_container: bytes[name_bytes_len + 6], associated_echd_container: bytes[name_bytes_len + 6],
@@ -183,7 +182,10 @@ impl MsContainer {
bytes.push(self.pin_id); bytes.push(self.pin_id);
bytes.push(self.associated_echd_container); bytes.push(self.associated_echd_container);
bytes.extend_from_slice(&self.cert_fingerprint); bytes.extend_from_slice(&self.cert_fingerprint);
bytes.as_slice().try_into().unwrap() bytes
.as_slice()
.try_into()
.expect("should be REC_LEN-sized")
} }
} }
+1
View File
@@ -767,6 +767,7 @@ impl RsaKeyData {
/// Generates a new RSA key data set from two randomly generated, secret, primes. /// Generates a new RSA key data set from two randomly generated, secret, primes.
/// ///
/// Panics if `secret_p` or `secret_q` are invalid primes. /// Panics if `secret_p` or `secret_q` are invalid primes.
#[allow(clippy::unwrap_used)] // TODO(tarcieri): make fallible and handle errors
pub fn new(secret_p: &[u8], secret_q: &[u8]) -> Self { pub fn new(secret_p: &[u8], secret_q: &[u8]) -> Self {
let p = BigUint::from_bytes_be(secret_p); let p = BigUint::from_bytes_be(secret_p);
let q = BigUint::from_bytes_be(secret_q); let q = BigUint::from_bytes_be(secret_q);
+5 -3
View File
@@ -1,6 +1,6 @@
//! Support for enumerating available PC/SC card readers. //! Support for enumerating available PC/SC card readers.
use crate::{Result, YubiKey}; use crate::{Error, Result, YubiKey};
use std::{ use std::{
borrow::Cow, borrow::Cow,
ffi::CStr, ffi::CStr,
@@ -43,7 +43,8 @@ impl Context {
let Self { ctx, reader_names } = self; let Self { ctx, reader_names } = self;
let reader_cstrs: Vec<_> = { let reader_cstrs: Vec<_> = {
let c = ctx.lock().unwrap(); // TODO(tarcieri): better error?
let c = ctx.lock().map_err(|_| Error::GenericError)?;
// ensure PC/SC context is valid // ensure PC/SC context is valid
c.is_valid()?; c.is_valid()?;
@@ -90,7 +91,8 @@ impl<'ctx> Reader<'ctx> {
/// Connect to this reader, returning its `pcsc::Card`. /// Connect to this reader, returning its `pcsc::Card`.
pub(crate) fn connect(&self) -> Result<pcsc::Card> { pub(crate) fn connect(&self) -> Result<pcsc::Card> {
let ctx = self.ctx.lock().unwrap(); // TODO(tarcieri): better error?
let ctx = self.ctx.lock().map_err(|_| Error::GenericError)?;
Ok(ctx.connect(self.name, pcsc::ShareMode::Shared, pcsc::Protocols::T1)?) Ok(ctx.connect(self.name, pcsc::ShareMode::Shared, pcsc::Protocols::T1)?)
} }
} }
+1 -5
View File
@@ -96,11 +96,7 @@ impl<'tx> Transaction<'tx> {
return Err(Error::GenericError); return Err(Error::GenericError);
} }
if response.data().len() < 3 { Ok(response.data()[..3].try_into().map(Version::new)?)
return Err(Error::SizeError);
}
Ok(Version::new(response.data()[..3].try_into().unwrap()))
} }
/// Get YubiKey device serial number. /// Get YubiKey device serial number.
+7 -4
View File
@@ -371,7 +371,7 @@ impl YubiKey {
} }
// send a response to the cards challenge and a challenge of our own. // send a response to the cards challenge and a challenge of our own.
let response = mgm_key.decrypt(challenge.data()[4..12].try_into().unwrap()); let response = mgm_key.decrypt(challenge.data()[4..12].try_into()?);
let mut data = [0u8; 22]; let mut data = [0u8; 22];
data[0] = TAG_DYN_AUTH; data[0] = TAG_DYN_AUTH;
@@ -517,8 +517,7 @@ impl YubiKey {
// TODO(tarcieri): double check this is little endian // TODO(tarcieri): double check this is little endian
let tnow = SystemTime::now() let tnow = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)?
.unwrap()
.as_secs() .as_secs()
.to_le_bytes(); .to_le_bytes();
@@ -648,7 +647,11 @@ impl YubiKey {
return Err(Error::AuthenticationError); return Err(Error::AuthenticationError);
} }
Ok(response.data()[4..12].try_into().unwrap()) Ok(response
.data()
.get(4..12)
.ok_or(Error::SizeError)?
.try_into()?)
} }
/// Verify an auth response. /// Verify an auth response.