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:
committed by
GitHub
parent
d226209ea4
commit
78313360a1
+3
-7
@@ -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
@@ -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
@@ -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
@@ -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 =
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user