Merge pull request #66 from iqlusioninc/tame-consts
consts: Whittle down to the essentials
This commit is contained in:
+6
-1
@@ -55,6 +55,11 @@ const OID_EC_PUBLIC_KEY: &str = "1.2.840.10045.2.1";
|
||||
const OID_NIST_P256: &str = "1.2.840.10045.3.1.7";
|
||||
const OID_NIST_P384: &str = "1.3.132.0.34";
|
||||
|
||||
#[allow(dead_code)]
|
||||
const CERTINFO_UNCOMPRESSED: u8 = 0;
|
||||
#[cfg(feature = "untested")]
|
||||
const CERTINFO_GZIP: u8 = 1;
|
||||
|
||||
/// Information about a public key within a [`Certificate`].
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum PublicKeyInfo {
|
||||
@@ -273,7 +278,7 @@ pub(crate) fn write_certificate(
|
||||
// write compression info and LRC trailer
|
||||
buf[offset] = TAG_CERT_COMPRESS;
|
||||
buf[offset + 1] = 0x01;
|
||||
buf[offset + 2] = if certinfo == YKPIV_CERTINFO_GZIP {
|
||||
buf[offset + 2] = if certinfo == CERTINFO_GZIP {
|
||||
0x01
|
||||
} else {
|
||||
0x00
|
||||
|
||||
@@ -37,6 +37,9 @@ use std::{
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
const CB_ADMIN_TIMESTAMP: usize = 0x04;
|
||||
const PROTECTED_FLAGS_1_PUK_NOBLOCK: u8 = 0x01;
|
||||
|
||||
/// Config
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Config {
|
||||
|
||||
+1
-84
@@ -33,75 +33,17 @@
|
||||
|
||||
// TODO(tarcieri): document these!
|
||||
#![allow(missing_docs, non_upper_case_globals)]
|
||||
|
||||
pub const szLOG_SOURCE: &str = "yubikey-piv.rs";
|
||||
#![cfg_attr(not(feature = "untested"), allow(dead_code))]
|
||||
|
||||
pub const ADMIN_FLAGS_1_PUK_BLOCKED: u8 = 0x01;
|
||||
pub const ADMIN_FLAGS_1_PROTECTED_MGM: u8 = 0x02;
|
||||
|
||||
/// PIV Applet ID
|
||||
pub const PIV_AID: [u8; 5] = [0xa0, 0x00, 0x00, 0x03, 0x08];
|
||||
|
||||
/// MGMT Applet ID.
|
||||
/// <https://developers.yubico.com/PIV/Introduction/Admin_access.html>
|
||||
pub const MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17];
|
||||
|
||||
/// YubiKey OTP Applet ID. Needed to query serial on YK4.
|
||||
pub const YK_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01];
|
||||
|
||||
pub const CB_ADMIN_TIMESTAMP: usize = 0x04;
|
||||
pub const CB_ADMIN_SALT: usize = 16;
|
||||
|
||||
pub const CB_ATR_MAX: usize = 33;
|
||||
|
||||
pub const CB_BUF_MAX: usize = 3072;
|
||||
|
||||
pub const CB_ECC_POINTP256: usize = 65;
|
||||
pub const CB_ECC_POINTP384: usize = 97;
|
||||
|
||||
pub const CB_OBJ_MAX: usize = CB_BUF_MAX - 9;
|
||||
|
||||
pub const CB_OBJ_TAG_MIN: usize = 2; // 1 byte tag + 1 byte len
|
||||
pub const CB_OBJ_TAG_MAX: usize = (CB_OBJ_TAG_MIN + 2); // 1 byte tag + 3 bytes len
|
||||
|
||||
pub const CB_PAGE: usize = 4096;
|
||||
pub const CB_PIN_MAX: usize = 8;
|
||||
|
||||
pub const CHREF_ACT_CHANGE_PIN: i32 = 0;
|
||||
pub const CHREF_ACT_UNBLOCK_PIN: i32 = 1;
|
||||
pub const CHREF_ACT_CHANGE_PUK: i32 = 2;
|
||||
|
||||
pub const CONTAINER_NAME_LEN: usize = 40;
|
||||
pub const CONTAINER_REC_LEN: usize = (2 * CONTAINER_NAME_LEN) + 27; // 80 + 1 + 1 + 2 + 1 + 1 + 1 + 20
|
||||
|
||||
pub const DES_TYPE_3DES: u8 = 1;
|
||||
|
||||
pub const DES_LEN_DES: usize = 8;
|
||||
pub const DES_LEN_3DES: usize = DES_LEN_DES * 3;
|
||||
|
||||
// device types
|
||||
|
||||
pub const DEVTYPE_UNKNOWN: u32 = 0x0000_0000;
|
||||
pub const DEVTYPE_YK: u32 = 0x594B_0000; //"YK"
|
||||
pub const DEVTYPE_YK4: u32 = (DEVTYPE_YK | 0x0000_0034); // "4"
|
||||
pub const DEVYTPE_YK5: u32 = (DEVTYPE_YK | 0x0000_0035); // "5"
|
||||
|
||||
pub const ITER_MGM_PBKDF2: usize = 10000;
|
||||
|
||||
pub const PROTECTED_FLAGS_1_PUK_NOBLOCK: u8 = 0x01;
|
||||
|
||||
// sw is status words, see NIST special publication 800-73-4, section 5.6
|
||||
|
||||
pub const SW_SUCCESS: i32 = 0x9000;
|
||||
pub const SW_ERR_SECURITY_STATUS: i32 = 0x6982;
|
||||
pub const SW_ERR_AUTH_BLOCKED: i32 = 0x6983;
|
||||
pub const SW_ERR_INCORRECT_PARAM: i32 = 0x6a80;
|
||||
|
||||
// this is a custom sw for yubikey
|
||||
|
||||
pub const SW_ERR_INCORRECT_SLOT: i32 = 0x6b00;
|
||||
pub const SW_ERR_NOT_SUPPORTED: i32 = 0x6d00;
|
||||
|
||||
pub const TAG_CERT: u8 = 0x70;
|
||||
pub const TAG_CERT_COMPRESS: u8 = 0x71;
|
||||
pub const TAG_CERT_LRC: u8 = 0xFE;
|
||||
@@ -119,28 +61,3 @@ pub const TAG_MSROOTS_MID: u8 = 0x83;
|
||||
pub const TAG_RSA_MODULUS: u8 = 0x81;
|
||||
pub const TAG_RSA_EXP: u8 = 0x82;
|
||||
pub const TAG_ECC_POINT: u8 = 0x86;
|
||||
|
||||
pub const YKPIV_ALGO_3DES: u8 = 0x03;
|
||||
|
||||
pub const YKPIV_CERTINFO_UNCOMPRESSED: u8 = 0;
|
||||
pub const YKPIV_CERTINFO_GZIP: u8 = 1;
|
||||
|
||||
pub const YKPIV_KEY_CARDMGM: u8 = 0x9b;
|
||||
|
||||
pub const YKPIV_OBJ_FINGERPRINTS: u32 = 0x005f_c103;
|
||||
pub const YKPIV_OBJ_SECURITY: u32 = 0x005f_c106;
|
||||
pub const YKPIV_OBJ_FACIAL: u32 = 0x005f_c108;
|
||||
pub const YKPIV_OBJ_PRINTED: u32 = 0x005f_c109;
|
||||
pub const YKPIV_OBJ_DISCOVERY: u32 = 0x7e;
|
||||
pub const YKPIV_OBJ_KEY_HISTORY: u32 = 0x005f_c10c;
|
||||
pub const YKPIV_OBJ_IRIS: u32 = 0x005f_c121;
|
||||
|
||||
// Internal object IDs
|
||||
|
||||
pub const YKPIV_OBJ_ADMIN_DATA: u32 = 0x005f_ff00;
|
||||
pub const YKPIV_OBJ_MSCMAP: u32 = 0x005f_ff10;
|
||||
pub const YKPIV_OBJ_MSROOTS1: u32 = 0x005f_ff11;
|
||||
pub const YKPIV_OBJ_MSROOTS2: u32 = 0x005f_ff12;
|
||||
pub const YKPIV_OBJ_MSROOTS3: u32 = 0x005f_ff13;
|
||||
pub const YKPIV_OBJ_MSROOTS4: u32 = 0x005f_ff14;
|
||||
pub const YKPIV_OBJ_MSROOTS5: u32 = 0x005f_ff15;
|
||||
|
||||
+11
-3
@@ -40,6 +40,14 @@ use std::{
|
||||
fmt::{self, Debug},
|
||||
};
|
||||
|
||||
/// Container name length
|
||||
const CONTAINER_NAME_LEN: usize = 40;
|
||||
|
||||
/// Container record length: 27 = 80 + 1 + 1 + 2 + 1 + 1 + 1 + 20
|
||||
const CONTAINER_REC_LEN: usize = (2 * CONTAINER_NAME_LEN) + 27;
|
||||
|
||||
const OBJ_MSCMAP: u32 = 0x005f_ff10;
|
||||
|
||||
/// MS Container Map(?) Records
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Container {
|
||||
@@ -72,7 +80,7 @@ impl Container {
|
||||
/// Read MS Container Map records
|
||||
pub fn read_mscmap(yubikey: &mut YubiKey) -> Result<Vec<Self>, Error> {
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
let response = txn.fetch_object(YKPIV_OBJ_MSCMAP)?;
|
||||
let response = txn.fetch_object(OBJ_MSCMAP)?;
|
||||
let mut containers = vec![];
|
||||
|
||||
if response.len() < CB_OBJ_TAG_MIN {
|
||||
@@ -110,7 +118,7 @@ impl Container {
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
|
||||
if n_containers == 0 {
|
||||
return txn.save_object(YKPIV_OBJ_MSCMAP, &[]);
|
||||
return txn.save_object(OBJ_MSCMAP, &[]);
|
||||
}
|
||||
|
||||
let req_len = 1 + set_length(&mut buf, data_len) + data_len;
|
||||
@@ -131,7 +139,7 @@ impl Container {
|
||||
}
|
||||
|
||||
offset += data_len;
|
||||
txn.save_object(YKPIV_OBJ_MSCMAP, &buf[..offset])
|
||||
txn.save_object(OBJ_MSCMAP, &buf[..offset])
|
||||
}
|
||||
|
||||
/// Parse a container record from a byte slice
|
||||
|
||||
@@ -59,6 +59,11 @@ use log::{error, warn};
|
||||
#[cfg(feature = "untested")]
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
const CB_ECC_POINTP256: usize = 65;
|
||||
#[cfg(feature = "untested")]
|
||||
const CB_ECC_POINTP384: usize = 97;
|
||||
|
||||
/// Slot identifiers.
|
||||
/// <https://developers.yubico.com/PIV/Introduction/Certificate_slots.html>
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ pub mod cccid;
|
||||
pub mod certificate;
|
||||
pub mod chuid;
|
||||
pub mod config;
|
||||
pub mod consts;
|
||||
mod consts;
|
||||
#[cfg(feature = "untested")]
|
||||
pub mod container;
|
||||
pub mod error;
|
||||
|
||||
+7
-4
@@ -35,6 +35,9 @@ use crate::{consts::*, error::Error, serialization::*, transaction::Transaction,
|
||||
#[cfg(feature = "untested")]
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
pub const OBJ_ADMIN_DATA: u32 = 0x005f_ff00;
|
||||
pub const OBJ_PRINTED: u32 = 0x005f_c109;
|
||||
|
||||
/// Get metadata item
|
||||
pub(crate) fn get_item(data: &[u8], tag: u8) -> Result<&[u8], Error> {
|
||||
let mut cb_temp: usize = 0;
|
||||
@@ -166,8 +169,8 @@ pub(crate) fn set_item(
|
||||
/// Read metadata
|
||||
pub(crate) fn read(txn: &Transaction<'_>, tag: u8) -> Result<Buffer, Error> {
|
||||
let obj_id = match tag {
|
||||
TAG_ADMIN => YKPIV_OBJ_ADMIN_DATA,
|
||||
TAG_PROTECTED => YKPIV_OBJ_PRINTED,
|
||||
TAG_ADMIN => OBJ_ADMIN_DATA,
|
||||
TAG_PROTECTED => OBJ_PRINTED,
|
||||
_ => return Err(Error::InvalidObject),
|
||||
};
|
||||
|
||||
@@ -203,8 +206,8 @@ pub(crate) fn write(txn: &Transaction<'_>, tag: u8, data: &[u8]) -> Result<(), E
|
||||
}
|
||||
|
||||
let obj_id = match tag {
|
||||
TAG_ADMIN => YKPIV_OBJ_ADMIN_DATA,
|
||||
TAG_PROTECTED => YKPIV_OBJ_PRINTED,
|
||||
TAG_ADMIN => OBJ_ADMIN_DATA,
|
||||
TAG_PROTECTED => OBJ_PRINTED,
|
||||
_ => return Err(Error::InvalidObject),
|
||||
};
|
||||
|
||||
|
||||
+15
-2
@@ -30,14 +30,14 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use crate::{consts::*, error::Error};
|
||||
use crate::error::Error;
|
||||
use getrandom::getrandom;
|
||||
use log::error;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use zeroize::{Zeroize, Zeroizing};
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::{metadata, yubikey::YubiKey};
|
||||
use crate::{consts::*, metadata, yubikey::YubiKey};
|
||||
#[cfg(feature = "untested")]
|
||||
use des::{
|
||||
block_cipher_trait::{generic_array::GenericArray, BlockCipher},
|
||||
@@ -50,11 +50,24 @@ use pbkdf2::pbkdf2;
|
||||
#[cfg(feature = "untested")]
|
||||
use sha1::Sha1;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
const CB_ADMIN_SALT: usize = 16;
|
||||
|
||||
/// Default MGM key configured on all YubiKeys
|
||||
const DEFAULT_MGM_KEY: [u8; DES_LEN_3DES] = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
];
|
||||
|
||||
/// Size of a DES key
|
||||
const DES_LEN_DES: usize = 8;
|
||||
|
||||
/// Size of a 3DES key
|
||||
pub(crate) const DES_LEN_3DES: usize = DES_LEN_DES * 3;
|
||||
|
||||
/// Number of PBKDF2 iterations to use when deriving from a password
|
||||
#[cfg(feature = "untested")]
|
||||
const ITER_MGM_PBKDF2: usize = 10000;
|
||||
|
||||
/// Management Key (MGM) key types (manual/derived/protected)
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum MgmType {
|
||||
|
||||
+13
-6
@@ -40,6 +40,15 @@
|
||||
use crate::{consts::*, error::Error, serialization::*, yubikey::YubiKey};
|
||||
use log::error;
|
||||
|
||||
const OBJ_MSROOTS1: u32 = 0x005f_ff11;
|
||||
#[allow(dead_code)]
|
||||
const OBJ_MSROOTS2: u32 = 0x005f_ff12;
|
||||
#[allow(dead_code)]
|
||||
const OBJ_MSROOTS3: u32 = 0x005f_ff13;
|
||||
#[allow(dead_code)]
|
||||
const OBJ_MSROOTS4: u32 = 0x005f_ff14;
|
||||
const OBJ_MSROOTS5: u32 = 0x005f_ff15;
|
||||
|
||||
/// `msroots` file: PKCS#7-formatted certificate store for enterprise trust roots
|
||||
pub struct MsRoots(Vec<u8>);
|
||||
|
||||
@@ -56,7 +65,7 @@ impl MsRoots {
|
||||
// allocate first page
|
||||
let mut data = Vec::with_capacity(CB_OBJ_MAX);
|
||||
|
||||
for object_id in YKPIV_OBJ_MSROOTS1..YKPIV_OBJ_MSROOTS5 {
|
||||
for object_id in OBJ_MSROOTS1..OBJ_MSROOTS5 {
|
||||
let buf = txn.fetch_object(object_id)?;
|
||||
let cb_buf = buf.len();
|
||||
|
||||
@@ -66,9 +75,7 @@ impl MsRoots {
|
||||
|
||||
let tag = buf[0];
|
||||
|
||||
if (TAG_MSROOTS_MID != tag || YKPIV_OBJ_MSROOTS5 == object_id)
|
||||
&& (TAG_MSROOTS_END != tag)
|
||||
{
|
||||
if (TAG_MSROOTS_MID != tag || OBJ_MSROOTS5 == object_id) && (TAG_MSROOTS_END != tag) {
|
||||
// the current object doesn't contain a valid part of a msroots file
|
||||
|
||||
// treat condition as object isn't found
|
||||
@@ -108,7 +115,7 @@ impl MsRoots {
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
|
||||
if data_len == 0 {
|
||||
return txn.save_object(YKPIV_OBJ_MSROOTS1, &[]);
|
||||
return txn.save_object(OBJ_MSROOTS1, &[]);
|
||||
}
|
||||
|
||||
// Calculate number of objects required to store blob
|
||||
@@ -138,7 +145,7 @@ impl MsRoots {
|
||||
buf[offset..].copy_from_slice(&data[data_offset..(data_offset + data_chunk)]);
|
||||
offset += data_chunk;
|
||||
|
||||
txn.save_object(YKPIV_OBJ_MSROOTS1 + i as u32, &buf[..offset])?;
|
||||
txn.save_object(OBJ_MSROOTS1 + i as u32, &buf[..offset])?;
|
||||
|
||||
data_offset += data_chunk;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use crate::{consts::*, ObjectId};
|
||||
use crate::ObjectId;
|
||||
|
||||
pub const OBJ_DISCOVERY: u32 = 0x7e;
|
||||
|
||||
// TODO(tarcieri): refactor these into better serializers/message builders
|
||||
|
||||
@@ -84,9 +86,9 @@ pub(crate) fn has_valid_length(buffer: &[u8], len: usize) -> bool {
|
||||
pub(crate) fn set_object(object_id: ObjectId, mut buffer: &mut [u8]) -> &mut [u8] {
|
||||
buffer[0] = 0x5c;
|
||||
|
||||
if object_id == YKPIV_OBJ_DISCOVERY {
|
||||
if object_id == OBJ_DISCOVERY {
|
||||
buffer[1] = 1;
|
||||
buffer[2] = YKPIV_OBJ_DISCOVERY as u8;
|
||||
buffer[2] = OBJ_DISCOVERY as u8;
|
||||
buffer = &mut buffer[3..];
|
||||
} else if object_id > 0xffff && object_id <= 0x00ff_ffff {
|
||||
buffer[1] = 3;
|
||||
|
||||
+5
-3
@@ -16,9 +16,11 @@ use zeroize::Zeroizing;
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::{
|
||||
key::{AlgorithmId, SlotId},
|
||||
mgm::MgmKey,
|
||||
mgm::{MgmKey, DES_LEN_3DES},
|
||||
};
|
||||
|
||||
const CB_PIN_MAX: usize = 8;
|
||||
|
||||
/// Exclusive transaction with the YubiKey's PC/SC card.
|
||||
pub(crate) struct Transaction<'tx> {
|
||||
inner: pcsc::Transaction<'tx>,
|
||||
@@ -227,8 +229,8 @@ impl<'tx> Transaction<'tx> {
|
||||
};
|
||||
|
||||
let mut data = [0u8; DES_LEN_3DES + 3];
|
||||
data[0] = YKPIV_ALGO_3DES;
|
||||
data[1] = YKPIV_KEY_CARDMGM;
|
||||
data[0] = ALGO_3DES;
|
||||
data[1] = KEY_CARDMGM;
|
||||
data[2] = DES_LEN_3DES as u8;
|
||||
data[3..3 + DES_LEN_3DES].copy_from_slice(new_key.as_ref());
|
||||
|
||||
|
||||
+30
-4
@@ -63,6 +63,32 @@ use std::{
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
/// 3DES authentication
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const ALGO_3DES: u8 = 0x03;
|
||||
|
||||
/// Card management key
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const CHREF_ACT_CHANGE_PIN: i32 = 0;
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const CHREF_ACT_UNBLOCK_PIN: i32 = 1;
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const CHREF_ACT_CHANGE_PUK: i32 = 2;
|
||||
|
||||
/// PIV Applet ID
|
||||
pub(crate) const PIV_AID: [u8; 5] = [0xa0, 0x00, 0x00, 0x03, 0x08];
|
||||
|
||||
/// MGMT Applet ID.
|
||||
/// <https://developers.yubico.com/PIV/Introduction/Admin_access.html>
|
||||
#[cfg(feature = "untested")]
|
||||
pub(crate) const MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17];
|
||||
|
||||
/// YubiKey OTP Applet ID. Needed to query serial on YK4.
|
||||
pub(crate) const YK_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01];
|
||||
|
||||
/// Cached YubiKey PIN
|
||||
pub type CachedPin = secrecy::SecretVec<u8>;
|
||||
|
||||
@@ -227,7 +253,7 @@ impl YubiKey {
|
||||
|
||||
// get a challenge from the card
|
||||
let challenge = APDU::new(Ins::Authenticate)
|
||||
.params(YKPIV_ALGO_3DES, YKPIV_KEY_CARDMGM)
|
||||
.params(ALGO_3DES, KEY_CARDMGM)
|
||||
.data(&[TAG_DYN_AUTH, 0x02, 0x80, 0x00])
|
||||
.transmit(&txn, 261)?;
|
||||
|
||||
@@ -256,7 +282,7 @@ impl YubiKey {
|
||||
challenge.copy_from_slice(&data[14..22]);
|
||||
|
||||
let authentication = APDU::new(Ins::Authenticate)
|
||||
.params(YKPIV_ALGO_3DES, YKPIV_KEY_CARDMGM)
|
||||
.params(ALGO_3DES, KEY_CARDMGM)
|
||||
.data(&data)
|
||||
.transmit(&txn, 261)?;
|
||||
|
||||
@@ -513,7 +539,7 @@ impl YubiKey {
|
||||
let txn = self.begin_transaction()?;
|
||||
|
||||
let response = APDU::new(Ins::Authenticate)
|
||||
.params(YKPIV_ALGO_3DES, YKPIV_KEY_CARDMGM)
|
||||
.params(ALGO_3DES, KEY_CARDMGM)
|
||||
.data(&[0x7c, 0x02, 0x81, 0x00])
|
||||
.transmit(&txn, 261)?;
|
||||
|
||||
@@ -538,7 +564,7 @@ impl YubiKey {
|
||||
|
||||
// send the response to the card and a challenge of our own.
|
||||
let status_words = APDU::new(Ins::Authenticate)
|
||||
.params(YKPIV_ALGO_3DES, YKPIV_KEY_CARDMGM)
|
||||
.params(ALGO_3DES, KEY_CARDMGM)
|
||||
.data(&data)
|
||||
.transmit(&txn, 261)?
|
||||
.status_words();
|
||||
|
||||
Reference in New Issue
Block a user