Merge pull request #61 from iqlusioninc/test-listing-keys
Test `Key::list`
This commit is contained in:
@@ -66,12 +66,12 @@ functions of the YubiKey:
|
||||
|----|---------------|-------|-------------|
|
||||
| 🚧 | `yubikey` | [#20] | Core functionality: auth, keys, PIN/PUK, encrypt, sign, attest |
|
||||
| ⚠️ | `cccid` | [#21] | Cardholder Capability Container (CCC) IDs |
|
||||
| ⚠️ | `certificate` | [#22] | Certificates for stored keys |
|
||||
| 🚧️ | `certificate` | [#22] | Certificates for stored keys |
|
||||
| ⚠️ | `chuid` | [#23] | Cardholder Unique Identifier (CHUID) |
|
||||
| ⚠️ | `config` | [#24] | Support for reading on-key configuration |
|
||||
| ⚠️ | `container` | [#25] | MS Container Map Records |
|
||||
| ⚠️ | `key` | [#26] | Crypto key management: list, generate, import |
|
||||
| ⚠️ | `mgm` | [#26] | Management Key (MGM) support: set, get, derive
|
||||
| 🚧 | `key` | [#26] | Crypto key management: list, generate, import |
|
||||
| ⚠️ | `mgm` | [#26] | Management Key (MGM) support: set, get, derive |
|
||||
| ⚠️ | `msroots` | [#28] | `msroots` file: PKCS#7 formatted certificate store for enterprise trusted roots |
|
||||
|
||||
Legend:
|
||||
|
||||
@@ -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];
|
||||
|
||||
+10
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use std::{env, sync::Mutex};
|
||||
use yubikey_piv::YubiKey;
|
||||
use yubikey_piv::{key::Key, YubiKey};
|
||||
|
||||
lazy_static! {
|
||||
/// Provide thread-safe access to a YubiKey
|
||||
@@ -29,3 +29,12 @@ fn test_verify_pin() {
|
||||
assert!(yubikey.verify_pin(b"000000").is_err());
|
||||
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_list_keys() {
|
||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
||||
let keys_result = Key::list(&mut yubikey);
|
||||
assert!(keys_result.is_ok());
|
||||
dbg!(keys_result.unwrap());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user