Test Key::list
Adds a live-against-the-device test which ensures keys can be successfully listed.
This commit is contained in:
@@ -71,7 +71,6 @@ impl APDU {
|
||||
}
|
||||
|
||||
/// Set this APDU's class
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn cla(&mut self, value: u8) -> &mut Self {
|
||||
self.cla = value;
|
||||
self
|
||||
@@ -267,7 +266,6 @@ pub(crate) struct Response {
|
||||
|
||||
impl Response {
|
||||
/// Create a new response from the given status words and buffer
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn new(status_words: StatusWords, data: Vec<u8>) -> Response {
|
||||
Response { status_words, data }
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ impl Certificate {
|
||||
}
|
||||
|
||||
/// Write this certificate into the YubiKey in the given slot
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn write(&self, yubikey: &mut YubiKey, slot: SlotId, certinfo: u8) -> Result<(), Error> {
|
||||
let max_size = yubikey.obj_size_max();
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
@@ -150,6 +151,7 @@ impl Certificate {
|
||||
}
|
||||
|
||||
/// Delete a certificate located at the given slot of the given YubiKey
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn delete(yubikey: &mut YubiKey, slot: SlotId) -> Result<(), Error> {
|
||||
let max_size = yubikey.obj_size_max();
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
@@ -236,6 +238,7 @@ pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result<Bu
|
||||
}
|
||||
|
||||
/// Write certificate
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) fn write_certificate(
|
||||
txn: &Transaction<'_>,
|
||||
slot: SlotId,
|
||||
|
||||
+28
-18
@@ -38,18 +38,24 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use crate::{
|
||||
apdu::{Ins, StatusWords},
|
||||
certificate::{self, Certificate},
|
||||
consts::*,
|
||||
error::Error,
|
||||
yubikey::YubiKey,
|
||||
ObjectId,
|
||||
};
|
||||
use log::debug;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::{
|
||||
apdu::{Ins, StatusWords},
|
||||
consts::*,
|
||||
policy::{PinPolicy, TouchPolicy},
|
||||
serialization::*,
|
||||
settings,
|
||||
yubikey::YubiKey,
|
||||
Buffer, ObjectId,
|
||||
settings, Buffer,
|
||||
};
|
||||
use log::{debug, error, warn};
|
||||
use std::convert::TryFrom;
|
||||
#[cfg(feature = "untested")]
|
||||
use log::{error, warn};
|
||||
|
||||
/// Slot identifiers.
|
||||
/// <https://developers.yubico.com/PIV/Introduction/Certificate_slots.html>
|
||||
@@ -312,6 +318,7 @@ impl From<AlgorithmId> for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
impl AlgorithmId {
|
||||
/// Writes the `AlgorithmId` in the format the YubiKey expects during key generation.
|
||||
pub(crate) fn write(self, buf: &mut [u8]) -> usize {
|
||||
@@ -367,19 +374,9 @@ impl Key {
|
||||
}
|
||||
}
|
||||
|
||||
// Keygen messages
|
||||
// TODO(tarcieri): extract these into an I18N-handling type?
|
||||
const SZ_SETTING_ROCA: &str = "Enable_Unsafe_Keygen_ROCA";
|
||||
const SZ_ROCA_ALLOW_USER: &str =
|
||||
"was permitted by an end-user configuration setting, but is not recommended.";
|
||||
const SZ_ROCA_ALLOW_ADMIN: &str =
|
||||
"was permitted by an administrator configuration setting, but is not recommended.";
|
||||
const SZ_ROCA_BLOCK_USER: &str = "was blocked due to an end-user configuration setting.";
|
||||
const SZ_ROCA_BLOCK_ADMIN: &str = "was blocked due to an administrator configuration setting.";
|
||||
const SZ_ROCA_DEFAULT: &str = "was permitted by default, but is not recommended. The default behavior will change in a future Yubico release.";
|
||||
|
||||
/// Information about a generated key
|
||||
// TODO(tarcieri): this could use some more work
|
||||
#[cfg(feature = "untested")]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum GeneratedKey {
|
||||
/// RSA keys
|
||||
@@ -403,6 +400,7 @@ pub enum GeneratedKey {
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
impl GeneratedKey {
|
||||
/// Get the algorithm
|
||||
pub fn algorithm(&self) -> AlgorithmId {
|
||||
@@ -414,6 +412,7 @@ impl GeneratedKey {
|
||||
}
|
||||
|
||||
/// Generate key
|
||||
#[cfg(feature = "untested")]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub fn generate(
|
||||
yubikey: &mut YubiKey,
|
||||
@@ -422,6 +421,17 @@ pub fn generate(
|
||||
pin_policy: PinPolicy,
|
||||
touch_policy: TouchPolicy,
|
||||
) -> Result<GeneratedKey, Error> {
|
||||
// Keygen messages
|
||||
// TODO(tarcieri): extract these into an I18N-handling type?
|
||||
const SZ_SETTING_ROCA: &str = "Enable_Unsafe_Keygen_ROCA";
|
||||
const SZ_ROCA_ALLOW_USER: &str =
|
||||
"was permitted by an end-user configuration setting, but is not recommended.";
|
||||
const SZ_ROCA_ALLOW_ADMIN: &str =
|
||||
"was permitted by an administrator configuration setting, but is not recommended.";
|
||||
const SZ_ROCA_BLOCK_USER: &str = "was blocked due to an end-user configuration setting.";
|
||||
const SZ_ROCA_BLOCK_ADMIN: &str = "was blocked due to an administrator configuration setting.";
|
||||
const SZ_ROCA_DEFAULT: &str = "was permitted by default, but is not recommended. The default behavior will change in a future Yubico release.";
|
||||
|
||||
let setting_roca: settings::BoolValue;
|
||||
|
||||
match algorithm {
|
||||
|
||||
@@ -138,7 +138,6 @@
|
||||
mod apdu;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod cccid;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod certificate;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod chuid;
|
||||
@@ -148,7 +147,6 @@ pub mod consts;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod container;
|
||||
pub mod error;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod key;
|
||||
#[cfg(feature = "untested")]
|
||||
mod metadata;
|
||||
@@ -156,10 +154,8 @@ mod metadata;
|
||||
pub mod mgm;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod msroots;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod policy;
|
||||
pub mod readers;
|
||||
#[cfg(feature = "untested")]
|
||||
mod serialization;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod settings;
|
||||
|
||||
@@ -35,6 +35,7 @@ impl From<PinPolicy> for u8 {
|
||||
impl PinPolicy {
|
||||
/// Writes the `PinPolicy` in the format the YubiKey expects during key generation or
|
||||
/// importation.
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) fn write(self, buf: &mut [u8]) -> usize {
|
||||
match self {
|
||||
PinPolicy::Default => 0,
|
||||
@@ -84,6 +85,7 @@ impl From<TouchPolicy> for u8 {
|
||||
impl TouchPolicy {
|
||||
/// Writes the `TouchPolicy` in the format the YubiKey expects during key generation
|
||||
/// or importation.
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) fn write(self, buf: &mut [u8]) -> usize {
|
||||
match self {
|
||||
TouchPolicy::Default => 0,
|
||||
|
||||
@@ -35,6 +35,7 @@ use crate::{consts::*, ObjectId};
|
||||
// TODO(tarcieri): refactor these into better serializers/message builders
|
||||
|
||||
/// Set length
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) fn set_length(buffer: &mut [u8], length: usize) -> usize {
|
||||
if length < 0x80 {
|
||||
buffer[0] = length as u8;
|
||||
|
||||
+8
-9
@@ -1,23 +1,24 @@
|
||||
//! YubiKey PC/SC transactions
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::{
|
||||
apdu::Response,
|
||||
key::{AlgorithmId, SlotId},
|
||||
mgm::MgmKey,
|
||||
serialization::*,
|
||||
Buffer, ObjectId,
|
||||
};
|
||||
use crate::{
|
||||
apdu::{Ins, StatusWords, APDU},
|
||||
consts::*,
|
||||
error::Error,
|
||||
serialization::*,
|
||||
yubikey::*,
|
||||
Buffer, ObjectId,
|
||||
};
|
||||
use log::{error, trace};
|
||||
use std::convert::TryInto;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::{
|
||||
key::{AlgorithmId, SlotId},
|
||||
mgm::MgmKey,
|
||||
};
|
||||
|
||||
/// Exclusive transaction with the YubiKey's PC/SC card.
|
||||
pub(crate) struct Transaction<'tx> {
|
||||
inner: pcsc::Transaction<'tx>,
|
||||
@@ -364,7 +365,6 @@ impl<'tx> Transaction<'tx> {
|
||||
/// messages into smaller APDU-sized messages (using the provided APDU
|
||||
/// template to construct them), and then sending those via
|
||||
/// [`Transaction::transmit`].
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn transfer_data(
|
||||
&self,
|
||||
templ: &[u8],
|
||||
@@ -448,7 +448,6 @@ impl<'tx> Transaction<'tx> {
|
||||
}
|
||||
|
||||
/// Fetch an object.
|
||||
#[cfg(feature = "untested")]
|
||||
pub fn fetch_object(&self, object_id: ObjectId) -> Result<Buffer, Error> {
|
||||
let mut indata = [0u8; 5];
|
||||
let templ = [0, Ins::GetData.code(), 0x3f, 0xff];
|
||||
|
||||
Reference in New Issue
Block a user