oxidize: Fix second pass of compile errors and commented-out code
This commit gets the Rust code to compile! 🎉
Additionally, it fixes all of the commented out code that was failing
translation from C due to the use of unions, namely around the APDU
messages.
It does a fair amount of reformatting around branches, with the net
result hopefully being something actually a bit closer to the C code,
and a straightforward list of `if` statements.
It also removes all of the remaining externs that aren't supposed to be
externs, replacing them with a more straightforward usage of the module
system.
Finally it fixes all errors and warnings (relating to e.g. usage of
uninitialized memory), in addition to most clippy lints! (some have
been explicitly disabled)
All that said, it still doesn't do anything: it needs to be wired up to
a PCSC library first before that will be possible. But hey, it compiles!
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
Copyright (c) 2014-2019 Yubico AB, Tony Arcieri
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
|
|||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
//! Application Protocol Data Unit (APDU)
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
|
/// Application Protocol Data Unit (APDU).
|
||||||
|
///
|
||||||
|
/// These messages are packets used to communicate with the YubiKey using the
|
||||||
|
/// Chip Card Interface Device (CCID) protocol.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct APDU {
|
||||||
|
/// Instruction class - indicates the type of command, e.g. interindustry or proprietary
|
||||||
|
pub cla: u8,
|
||||||
|
|
||||||
|
/// Instruction code - indicates the specific command, e.g. "write data"
|
||||||
|
pub ins: u8,
|
||||||
|
|
||||||
|
/// Instruction parameter 1 for the command, e.g. offset into file at which to write the data
|
||||||
|
pub p1: u8,
|
||||||
|
|
||||||
|
/// Instruction parameter 2 for the command
|
||||||
|
pub p2: u8,
|
||||||
|
|
||||||
|
/// Length of command - encodes the number of bytes of command data to follow
|
||||||
|
pub lc: u8,
|
||||||
|
|
||||||
|
/// Command data
|
||||||
|
pub data: [u8; 255],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl APDU {
|
||||||
|
/// Get a const pointer to this APDU
|
||||||
|
// TODO(tarcieri): eliminate pointers and use all safe references
|
||||||
|
pub(crate) fn as_ptr(&self) -> *const APDU {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mut pointer to this APDU
|
||||||
|
// TODO(tarcieri): eliminate pointers and use all safe references
|
||||||
|
pub(crate) fn as_mut_ptr(&mut self) -> *mut APDU {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for APDU {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cla: 0,
|
||||||
|
ins: 0,
|
||||||
|
p1: 0,
|
||||||
|
p2: 0,
|
||||||
|
lc: 0,
|
||||||
|
data: [0u8; 255],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Zeroize for APDU {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.cla.zeroize();
|
||||||
|
self.ins.zeroize();
|
||||||
|
self.p1.zeroize();
|
||||||
|
self.p2.zeroize();
|
||||||
|
self.lc.zeroize();
|
||||||
|
self.data.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
+218
@@ -0,0 +1,218 @@
|
|||||||
|
//! Constant values
|
||||||
|
// TODO(tarcieri): refactor these into enums!
|
||||||
|
|
||||||
|
// Adapted from yubico-piv-tool:
|
||||||
|
// <https://github.com/Yubico/yubico-piv-tool/>
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Yubico AB
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// TODO(tarcieri): document these!
|
||||||
|
#![allow(missing_docs, non_upper_case_globals)]
|
||||||
|
|
||||||
|
pub const szLOG_SOURCE: &str = "yubikey-piv.rs";
|
||||||
|
|
||||||
|
pub const CB_OBJ_MAX: usize = 3063;
|
||||||
|
|
||||||
|
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_PIN_MAX: usize = 8;
|
||||||
|
pub const CB_ECC_POINTP256: usize = 65;
|
||||||
|
pub const CB_ECC_POINTP384: usize = 97;
|
||||||
|
|
||||||
|
pub const CHUID_GUID_OFFS: usize = 29;
|
||||||
|
|
||||||
|
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 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_NEO: u32 = 0x4E45_0000; //"NE"
|
||||||
|
pub const DEVTYPE_YK: u32 = 0x594B_0000; //"YK"
|
||||||
|
pub const DEVTYPE_NEOr3: u32 = (DEVTYPE_NEO | 0x0000_7233); //"r3"
|
||||||
|
pub const DEVTYPE_YK4: u32 = (DEVTYPE_YK | 0x0000_0034); // "4"
|
||||||
|
pub const DEVYTPE_YK5: u32 = (DEVTYPE_YK | 0x0000_0035); // "5"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
pub const TAG_ADMIN: u8 = 0x80;
|
||||||
|
pub const TAG_ADMIN_FLAGS_1: u8 = 0x81;
|
||||||
|
pub const TAG_ADMIN_SALT: u8 = 0x82;
|
||||||
|
pub const TAG_ADMIN_TIMESTAMP: u8 = 0x83;
|
||||||
|
pub const TAG_PROTECTED: u8 = 0x88;
|
||||||
|
pub const TAG_PROTECTED_FLAGS_1: u8 = 0x81;
|
||||||
|
pub const TAG_PROTECTED_MGM: u8 = 0x89;
|
||||||
|
pub const TAG_MSCMAP: u8 = 0x81;
|
||||||
|
pub const TAG_MSROOTS_END: u8 = 0x82;
|
||||||
|
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_TAG: u8 = 0x80;
|
||||||
|
pub const YKPIV_ALGO_3DES: u8 = 0x03;
|
||||||
|
pub const YKPIV_ALGO_RSA1024: u8 = 0x06;
|
||||||
|
pub const YKPIV_ALGO_RSA2048: u8 = 0x07;
|
||||||
|
pub const YKPIV_ALGO_ECCP256: u8 = 0x11;
|
||||||
|
pub const YKPIV_ALGO_ECCP384: u8 = 0x14;
|
||||||
|
|
||||||
|
pub const YKPIV_ATR_NEO_R3: &[u8] = b";\xFC\x13\0\0\x811\xFE\x15YubikeyNEOr3\xE1\0";
|
||||||
|
|
||||||
|
pub const YKPIV_CARDID_SIZE: usize = 16;
|
||||||
|
|
||||||
|
pub const YKPIV_CCCID_SIZE: usize = 14;
|
||||||
|
|
||||||
|
pub const YKPIV_CERTINFO_UNCOMPRESSED: u8 = 0;
|
||||||
|
pub const YKPIV_CERTINFO_GZIP: u8 = 1;
|
||||||
|
|
||||||
|
pub const YKPIV_INS_VERIFY: u8 = 0x20;
|
||||||
|
pub const YKPIV_INS_CHANGE_REFERENCE: u8 = 0x24;
|
||||||
|
pub const YKPIV_INS_RESET_RETRY: u8 = 0x2c;
|
||||||
|
pub const YKPIV_INS_GENERATE_ASYMMETRIC: u8 = 0x47;
|
||||||
|
pub const YKPIV_INS_AUTHENTICATE: u8 = 0x87;
|
||||||
|
pub const YKPIV_INS_GET_DATA: u8 = 0xcb;
|
||||||
|
pub const YKPIV_INS_PUT_DATA: u8 = 0xdb;
|
||||||
|
pub const YKPIV_INS_SELECT_APPLICATION: u8 = 0xa4;
|
||||||
|
pub const YKPIV_INS_GET_RESPONSE_APDU: u8 = 0xc0;
|
||||||
|
|
||||||
|
// Yubico vendor specific instructions
|
||||||
|
pub const YKPIV_INS_SET_MGMKEY: u8 = 0xff;
|
||||||
|
pub const YKPIV_INS_IMPORT_KEY: u8 = 0xfe;
|
||||||
|
pub const YKPIV_INS_GET_VERSION: u8 = 0xfd;
|
||||||
|
pub const YKPIV_INS_RESET: u8 = 0xfb;
|
||||||
|
pub const YKPIV_INS_SET_PIN_RETRIES: u8 = 0xfa;
|
||||||
|
pub const YKPIV_INS_ATTEST: u8 = 0xf9;
|
||||||
|
pub const YKPIV_INS_GET_SERIAL: u8 = 0xf8;
|
||||||
|
|
||||||
|
pub const YKPIV_KEY_AUTHENTICATION: u8 = 0x9a;
|
||||||
|
pub const YKPIV_KEY_CARDMGM: u8 = 0x9b;
|
||||||
|
pub const YKPIV_KEY_SIGNATURE: u8 = 0x9c;
|
||||||
|
pub const YKPIV_KEY_KEYMGM: u8 = 0x9d;
|
||||||
|
pub const YKPIV_KEY_CARDAUTH: u8 = 0x9e;
|
||||||
|
pub const YKPIV_KEY_RETIRED1: u8 = 0x82;
|
||||||
|
pub const YKPIV_KEY_RETIRED2: u8 = 0x83;
|
||||||
|
pub const YKPIV_KEY_RETIRED3: u8 = 0x84;
|
||||||
|
pub const YKPIV_KEY_RETIRED4: u8 = 0x85;
|
||||||
|
pub const YKPIV_KEY_RETIRED5: u8 = 0x86;
|
||||||
|
pub const YKPIV_KEY_RETIRED6: u8 = 0x87;
|
||||||
|
pub const YKPIV_KEY_RETIRED7: u8 = 0x88;
|
||||||
|
pub const YKPIV_KEY_RETIRED8: u8 = 0x89;
|
||||||
|
pub const YKPIV_KEY_RETIRED9: u8 = 0x8a;
|
||||||
|
pub const YKPIV_KEY_RETIRED10: u8 = 0x8b;
|
||||||
|
pub const YKPIV_KEY_RETIRED11: u8 = 0x8c;
|
||||||
|
pub const YKPIV_KEY_RETIRED12: u8 = 0x8d;
|
||||||
|
pub const YKPIV_KEY_RETIRED13: u8 = 0x8e;
|
||||||
|
pub const YKPIV_KEY_RETIRED14: u8 = 0x8f;
|
||||||
|
pub const YKPIV_KEY_RETIRED15: u8 = 0x90;
|
||||||
|
pub const YKPIV_KEY_RETIRED16: u8 = 0x91;
|
||||||
|
pub const YKPIV_KEY_RETIRED17: u8 = 0x92;
|
||||||
|
pub const YKPIV_KEY_RETIRED18: u8 = 0x93;
|
||||||
|
pub const YKPIV_KEY_RETIRED19: u8 = 0x94;
|
||||||
|
pub const YKPIV_KEY_RETIRED20: u8 = 0x95;
|
||||||
|
pub const YKPIV_KEY_ATTESTATION: u8 = 0xf9;
|
||||||
|
|
||||||
|
pub const YKPIV_OBJ_CAPABILITY: u32 = 0x005f_c107;
|
||||||
|
pub const YKPIV_OBJ_CHUID: u32 = 0x005f_c102;
|
||||||
|
pub const YKPIV_OBJ_AUTHENTICATION: u32 = 0x005f_c105; // cert for 9a key
|
||||||
|
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_SIGNATURE: u32 = 0x005f_c10a; // cert for 9c key
|
||||||
|
pub const YKPIV_OBJ_KEY_MANAGEMENT: u32 = 0x005f_c10b; // cert for 9d key
|
||||||
|
pub const YKPIV_OBJ_CARD_AUTH: u32 = 0x005f_c101; // cert for 9e key
|
||||||
|
pub const YKPIV_OBJ_DISCOVERY: u32 = 0x7e;
|
||||||
|
pub const YKPIV_OBJ_KEY_HISTORY: u32 = 0x005f_c10c;
|
||||||
|
pub const YKPIV_OBJ_IRIS: u32 = 0x005f_c121;
|
||||||
|
|
||||||
|
pub const YKPIV_OBJ_RETIRED1: u32 = 0x005f_c10d;
|
||||||
|
pub const YKPIV_OBJ_RETIRED2: u32 = 0x005f_c10e;
|
||||||
|
pub const YKPIV_OBJ_RETIRED3: u32 = 0x005f_c10f;
|
||||||
|
pub const YKPIV_OBJ_RETIRED4: u32 = 0x005f_c110;
|
||||||
|
pub const YKPIV_OBJ_RETIRED5: u32 = 0x005f_c111;
|
||||||
|
pub const YKPIV_OBJ_RETIRED6: u32 = 0x005f_c112;
|
||||||
|
pub const YKPIV_OBJ_RETIRED7: u32 = 0x005f_c113;
|
||||||
|
pub const YKPIV_OBJ_RETIRED8: u32 = 0x005f_c114;
|
||||||
|
pub const YKPIV_OBJ_RETIRED9: u32 = 0x005f_c115;
|
||||||
|
pub const YKPIV_OBJ_RETIRED10: u32 = 0x005f_c116;
|
||||||
|
pub const YKPIV_OBJ_RETIRED11: u32 = 0x005f_c117;
|
||||||
|
pub const YKPIV_OBJ_RETIRED12: u32 = 0x005f_c118;
|
||||||
|
pub const YKPIV_OBJ_RETIRED13: u32 = 0x005f_c119;
|
||||||
|
pub const YKPIV_OBJ_RETIRED14: u32 = 0x005f_c11a;
|
||||||
|
pub const YKPIV_OBJ_RETIRED15: u32 = 0x005f_c11b;
|
||||||
|
pub const YKPIV_OBJ_RETIRED16: u32 = 0x005f_c11c;
|
||||||
|
pub const YKPIV_OBJ_RETIRED17: u32 = 0x005f_c11d;
|
||||||
|
pub const YKPIV_OBJ_RETIRED18: u32 = 0x005f_c11e;
|
||||||
|
pub const YKPIV_OBJ_RETIRED19: u32 = 0x005f_c11f;
|
||||||
|
pub const YKPIV_OBJ_RETIRED20: u32 = 0x005f_c120;
|
||||||
|
|
||||||
|
// Internal object IDs
|
||||||
|
|
||||||
|
pub const YKPIV_OBJ_ADMIN_DATA: u32 = 0x005f_ff00;
|
||||||
|
pub const YKPIV_OBJ_ATTESTATION: u32 = 0x005f_ff01;
|
||||||
|
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;
|
||||||
|
|
||||||
|
pub const YKPIV_OBJ_MAX_SIZE: usize = 3072;
|
||||||
|
|
||||||
|
pub const YKPIV_PINPOLICY_TAG: u8 = 0xaa;
|
||||||
|
pub const YKPIV_PINPOLICY_DEFAULT: u8 = 0;
|
||||||
|
pub const YKPIV_PINPOLICY_NEVER: u8 = 1;
|
||||||
|
pub const YKPIV_PINPOLICY_ONCE: u8 = 2;
|
||||||
|
pub const YKPIV_PINPOLICY_ALWAYS: u8 = 3;
|
||||||
|
|
||||||
|
pub const YKPIV_TOUCHPOLICY_TAG: u8 = 0xab;
|
||||||
|
pub const YKPIV_TOUCHPOLICY_DEFAULT: u8 = 0;
|
||||||
|
pub const YKPIV_TOUCHPOLICY_NEVER: u8 = 1;
|
||||||
|
pub const YKPIV_TOUCHPOLICY_ALWAYS: u8 = 2;
|
||||||
|
pub const YKPIV_TOUCHPOLICY_CACHED: u8 = 3;
|
||||||
+96
-68
@@ -1,3 +1,5 @@
|
|||||||
|
//! Error types
|
||||||
|
|
||||||
// Adapted from yubico-piv-tool:
|
// Adapted from yubico-piv-tool:
|
||||||
// <https://github.com/Yubico/yubico-piv-tool/>
|
// <https://github.com/Yubico/yubico-piv-tool/>
|
||||||
//
|
//
|
||||||
@@ -30,73 +32,109 @@
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
/// Kinds of errors
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[repr(i32)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum ErrorKind {
|
pub enum ErrorKind {
|
||||||
YKPIV_OK = 0,
|
/// OK
|
||||||
YKPIV_MEMORY_ERROR = -1,
|
// TODO(tarcieri): replace this with proper result types
|
||||||
YKPIV_PCSC_ERROR = -2,
|
Ok,
|
||||||
YKPIV_SIZE_ERROR = -3,
|
|
||||||
YKPIV_APPLET_ERROR = -4,
|
/// Memory error
|
||||||
YKPIV_AUTHENTICATION_ERROR = -5,
|
MemoryError,
|
||||||
YKPIV_RANDOMNESS_ERROR = -6,
|
|
||||||
YKPIV_GENERIC_ERROR = -7,
|
/// PCSC error
|
||||||
YKPIV_KEY_ERROR = -8,
|
PcscError,
|
||||||
YKPIV_PARSE_ERROR = -9,
|
|
||||||
YKPIV_WRONG_PIN = -10,
|
/// Size error
|
||||||
YKPIV_INVALID_OBJECT = -11,
|
SizeError,
|
||||||
YKPIV_ALGORITHM_ERROR = -12,
|
|
||||||
YKPIV_PIN_LOCKED = -13,
|
/// Applet error
|
||||||
YKPIV_ARGUMENT_ERROR = -14,
|
AppletError,
|
||||||
YKPIV_RANGE_ERROR = -15,
|
|
||||||
YKPIV_NOT_SUPPORTED = -16,
|
/// Authentication error
|
||||||
|
AuthenticationError,
|
||||||
|
|
||||||
|
/// Randomness error
|
||||||
|
RandomnessError,
|
||||||
|
|
||||||
|
/// Generic error
|
||||||
|
GenericError,
|
||||||
|
|
||||||
|
/// Key error
|
||||||
|
KeyError,
|
||||||
|
|
||||||
|
/// Parse error
|
||||||
|
ParseError,
|
||||||
|
|
||||||
|
/// Wrong PIN
|
||||||
|
WrongPin,
|
||||||
|
|
||||||
|
/// Invalid object
|
||||||
|
InvalidObject,
|
||||||
|
|
||||||
|
/// Algorithm error
|
||||||
|
AlgorithmError,
|
||||||
|
|
||||||
|
/// PIN locked
|
||||||
|
PinLocked,
|
||||||
|
|
||||||
|
/// Argument error
|
||||||
|
ArgumentError,
|
||||||
|
|
||||||
|
/// Range error
|
||||||
|
RangeError,
|
||||||
|
|
||||||
|
/// Not supported
|
||||||
|
NotSupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorKind {
|
impl ErrorKind {
|
||||||
/// Name of the error
|
/// Name of the error.
|
||||||
|
///
|
||||||
|
/// These names map to the legacy names from the Yubico C library, to
|
||||||
|
/// assist in web searches for relevant information for these errors.
|
||||||
pub fn name(self) -> &'static str {
|
pub fn name(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
ErrorKind::YKPIV_OK => "YKPIV_OK",
|
ErrorKind::Ok => "YKPIV_OK",
|
||||||
ErrorKind::YKPIV_MEMORY_ERROR => "YKPIV_MEMORY_ERROR",
|
ErrorKind::MemoryError => "YKPIV_MEMORY_ERROR",
|
||||||
ErrorKind::YKPIV_PCSC_ERROR => "YKPIV_PCSC_ERROR",
|
ErrorKind::PcscError => "YKPIV_PCSC_ERROR",
|
||||||
ErrorKind::YKPIV_SIZE_ERROR => "YKPIV_SIZE_ERROR",
|
ErrorKind::SizeError => "YKPIV_SIZE_ERROR",
|
||||||
ErrorKind::YKPIV_APPLET_ERROR => "YKPIV_APPLET_ERROR",
|
ErrorKind::AppletError => "YKPIV_APPLET_ERROR",
|
||||||
ErrorKind::YKPIV_AUTHENTICATION_ERROR => "YKPIV_AUTHENTICATION_ERROR",
|
ErrorKind::AuthenticationError => "YKPIV_AUTHENTICATION_ERROR",
|
||||||
ErrorKind::YKPIV_RANDOMNESS_ERROR => "YKPIV_RANDOMNESS_ERROR",
|
ErrorKind::RandomnessError => "YKPIV_RANDOMNESS_ERROR",
|
||||||
ErrorKind::YKPIV_GENERIC_ERROR => "YKPIV_GENERIC_ERROR",
|
ErrorKind::GenericError => "YKPIV_GENERIC_ERROR",
|
||||||
ErrorKind::YKPIV_KEY_ERROR => "YKPIV_KEY_ERROR",
|
ErrorKind::KeyError => "YKPIV_KEY_ERROR",
|
||||||
ErrorKind::YKPIV_PARSE_ERROR => "YKPIV_PARSE_ERROR",
|
ErrorKind::ParseError => "YKPIV_PARSE_ERROR",
|
||||||
ErrorKind::YKPIV_WRONG_PIN => "YKPIV_WRONG_PIN",
|
ErrorKind::WrongPin => "YKPIV_WRONG_PIN",
|
||||||
ErrorKind::YKPIV_INVALID_OBJECT => "YKPIV_INVALID_OBJECT",
|
ErrorKind::InvalidObject => "YKPIV_INVALID_OBJECT",
|
||||||
ErrorKind::YKPIV_ALGORITHM_ERROR => "YKPIV_ALGORITHM_ERROR",
|
ErrorKind::AlgorithmError => "YKPIV_ALGORITHM_ERROR",
|
||||||
ErrorKind::YKPIV_PIN_LOCKED => "YKPIV_PIN_LOCKED",
|
ErrorKind::PinLocked => "YKPIV_PIN_LOCKED",
|
||||||
ErrorKind::YKPIV_ARGUMENT_ERROR => "YKPIV_ARGUMENT_ERROR",
|
ErrorKind::ArgumentError => "YKPIV_ARGUMENT_ERROR",
|
||||||
ErrorKind::YKPIV_RANGE_ERROR => "YKPIV_RANGE_ERROR",
|
ErrorKind::RangeError => "YKPIV_RANGE_ERROR",
|
||||||
ErrorKind::YKPIV_NOT_SUPPORTED => "YKPIV_NOT_SUPPORTED",
|
ErrorKind::NotSupported => "YKPIV_NOT_SUPPORTED",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error message
|
/// Error message
|
||||||
pub fn msg(self) -> &'static str {
|
pub fn msg(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
ErrorKind::YKPIV_OK => "OK",
|
ErrorKind::Ok => "OK",
|
||||||
ErrorKind::YKPIV_MEMORY_ERROR => "memory error",
|
ErrorKind::MemoryError => "memory error",
|
||||||
ErrorKind::YKPIV_PCSC_ERROR => "PCSC error",
|
ErrorKind::PcscError => "PCSC error",
|
||||||
ErrorKind::YKPIV_SIZE_ERROR => "size error",
|
ErrorKind::SizeError => "size error",
|
||||||
ErrorKind::YKPIV_APPLET_ERROR => "applet error",
|
ErrorKind::AppletError => "applet error",
|
||||||
ErrorKind::YKPIV_AUTHENTICATION_ERROR => "authentication error",
|
ErrorKind::AuthenticationError => "authentication error",
|
||||||
ErrorKind::YKPIV_RANDOMNESS_ERROR => "randomness error",
|
ErrorKind::RandomnessError => "randomness error",
|
||||||
ErrorKind::YKPIV_GENERIC_ERROR => "generic error",
|
ErrorKind::GenericError => "generic error",
|
||||||
ErrorKind::YKPIV_KEY_ERROR => "key error",
|
ErrorKind::KeyError => "key error",
|
||||||
ErrorKind::YKPIV_PARSE_ERROR => "parse error",
|
ErrorKind::ParseError => "parse error",
|
||||||
ErrorKind::YKPIV_WRONG_PIN => "wrong pin",
|
ErrorKind::WrongPin => "wrong pin",
|
||||||
ErrorKind::YKPIV_INVALID_OBJECT => "invalid object",
|
ErrorKind::InvalidObject => "invalid object",
|
||||||
ErrorKind::YKPIV_ALGORITHM_ERROR => "algorithm error",
|
ErrorKind::AlgorithmError => "algorithm error",
|
||||||
ErrorKind::YKPIV_PIN_LOCKED => "PIN locked",
|
ErrorKind::PinLocked => "PIN locked",
|
||||||
ErrorKind::YKPIV_ARGUMENT_ERROR => "argument error",
|
ErrorKind::ArgumentError => "argument error",
|
||||||
ErrorKind::YKPIV_RANGE_ERROR => "range error",
|
ErrorKind::RangeError => "range error",
|
||||||
ErrorKind::YKPIV_NOT_SUPPORTED => "not supported",
|
ErrorKind::NotSupported => "not supported",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,24 +147,14 @@ impl fmt::Display for ErrorKind {
|
|||||||
|
|
||||||
impl std::error::Error for ErrorKind {}
|
impl std::error::Error for ErrorKind {}
|
||||||
|
|
||||||
#[derive(Copy)]
|
/// Get a string representation of this error
|
||||||
#[repr(C)]
|
// TODO(tarcieri): completely replace this with `Display`
|
||||||
pub struct Error {
|
|
||||||
pub rc: ErrorKind,
|
|
||||||
pub name: *const u8,
|
|
||||||
pub description: *const u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Error {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ykpiv_strerror(err: ErrorKind) -> &'static str {
|
pub fn ykpiv_strerror(err: ErrorKind) -> &'static str {
|
||||||
err.msg()
|
err.msg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the name of this error
|
||||||
|
// TODO(tarcieri): completely replace this with debug
|
||||||
pub fn ykpiv_strerror_name(err: ErrorKind) -> &'static str {
|
pub fn ykpiv_strerror_name(err: ErrorKind) -> &'static str {
|
||||||
err.name()
|
err.name()
|
||||||
}
|
}
|
||||||
|
|||||||
+226
-460
@@ -1,3 +1,9 @@
|
|||||||
|
//! Internal functions (mostly 3DES)
|
||||||
|
|
||||||
|
// TODO(tarcieri): replace OpenSSL extern "C" invocations with `des` crate
|
||||||
|
// - crate: https://crates.io/crates/des
|
||||||
|
// - docs: https://docs.rs/des/0
|
||||||
|
|
||||||
// Adapted from yubico-piv-tool:
|
// Adapted from yubico-piv-tool:
|
||||||
// <https://github.com/Yubico/yubico-piv-tool/>
|
// <https://github.com/Yubico/yubico-piv-tool/>
|
||||||
//
|
//
|
||||||
@@ -28,23 +34,32 @@
|
|||||||
// (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.
|
||||||
|
|
||||||
|
// TODO(tarcieri): investigate and remove dead code
|
||||||
|
#![allow(non_upper_case_globals, dead_code)]
|
||||||
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
|
use crate::consts::*;
|
||||||
use libc::{
|
use libc::{
|
||||||
c_char, c_int, fclose, feof, fgets, fopen, free, getenv, malloc, memcpy, memset, strcasecmp,
|
c_char, c_int, fclose, feof, fgets, fopen, free, getenv, malloc, memcpy, memset, sscanf,
|
||||||
strcmp, strlen,
|
strcasecmp, strcmp,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
ffi::{CStr, CString},
|
||||||
|
mem,
|
||||||
|
os::raw::c_void,
|
||||||
};
|
};
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn DES_ecb3_encrypt(
|
fn DES_ecb3_encrypt(
|
||||||
input: *mut [u8; 8],
|
input: *mut [u8; 8],
|
||||||
output: *mut [u8; 8],
|
output: *mut [u8; 8],
|
||||||
ks1: *mut DES_ks,
|
ks1: *mut DesSubKey,
|
||||||
ks2: *mut DES_ks,
|
ks2: *mut DesSubKey,
|
||||||
ks3: *mut DES_ks,
|
ks3: *mut DesSubKey,
|
||||||
enc: i32,
|
enc: i32,
|
||||||
);
|
);
|
||||||
fn DES_is_weak_key(key: *mut [u8; 8]) -> i32;
|
fn DES_is_weak_key(key: *mut [u8; 8]) -> i32;
|
||||||
fn DES_set_key_unchecked(key: *mut [u8; 8], schedule: *mut DES_ks);
|
fn DES_set_key_unchecked(key: *mut [u8; 8], schedule: *mut DesSubKey);
|
||||||
fn PKCS5_PBKDF2_HMAC_SHA1(
|
fn PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
pass: *const u8,
|
pass: *const u8,
|
||||||
passlen: i32,
|
passlen: i32,
|
||||||
@@ -55,432 +70,211 @@ extern "C" {
|
|||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) -> i32;
|
) -> i32;
|
||||||
fn RAND_bytes(buf: *mut u8, num: i32) -> i32;
|
fn RAND_bytes(buf: *mut u8, num: i32) -> i32;
|
||||||
static mut _DefaultRuneLocale: Struct1;
|
|
||||||
fn __maskrune(arg1: i32, arg2: usize) -> i32;
|
|
||||||
fn __tolower(arg1: i32) -> i32;
|
|
||||||
fn __toupper(arg1: i32) -> i32;
|
|
||||||
fn snprintf(__str: *mut u8, __size: usize, __format: *const u8, ...) -> i32;
|
|
||||||
fn sscanf(arg1: *const u8, arg2: *const u8, ...) -> i32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isascii(mut _c: i32) -> i32 {
|
/// DES-related errors
|
||||||
(_c & !0x7fi32 == 0i32) as (i32)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Struct3 {
|
|
||||||
pub __min: i32,
|
|
||||||
pub __max: i32,
|
|
||||||
pub __map: i32,
|
|
||||||
pub __types: *mut u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Struct3 {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Struct2 {
|
|
||||||
pub __nranges: i32,
|
|
||||||
pub __ranges: *mut Struct3,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Struct2 {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Struct4 {
|
|
||||||
pub __name: [u8; 14],
|
|
||||||
pub __mask: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Struct4 {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Struct1 {
|
|
||||||
pub __magic: [u8; 8],
|
|
||||||
pub __encoding: [u8; 32],
|
|
||||||
pub __sgetrune: unsafe extern "C" fn(*const u8, usize, *mut *const u8) -> i32,
|
|
||||||
pub __sputrune: unsafe extern "C" fn(i32, *mut u8, usize, *mut *mut u8) -> i32,
|
|
||||||
pub __invalid_rune: i32,
|
|
||||||
pub __runetype: [u32; 256],
|
|
||||||
pub __maplower: [i32; 256],
|
|
||||||
pub __mapupper: [i32; 256],
|
|
||||||
pub __runetype_ext: Struct2,
|
|
||||||
pub __maplower_ext: Struct2,
|
|
||||||
pub __mapupper_ext: Struct2,
|
|
||||||
pub __variable: *mut ::std::os::raw::c_void,
|
|
||||||
pub __variable_len: i32,
|
|
||||||
pub __ncharclasses: i32,
|
|
||||||
pub __charclasses: *mut Struct4,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Struct1 {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __istype(mut _c: i32, mut _f: usize) -> i32 {
|
|
||||||
if isascii(_c) != 0 {
|
|
||||||
!(_DefaultRuneLocale.__runetype[_c as (usize)] as (usize) & _f == 0) as (i32)
|
|
||||||
} else {
|
|
||||||
!(__maskrune(_c, _f) == 0) as (i32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __isctype(mut _c: i32, mut _f: usize) -> i32 {
|
|
||||||
if _c < 0i32 || _c >= 256i32 {
|
|
||||||
0i32
|
|
||||||
} else {
|
|
||||||
!(_DefaultRuneLocale.__runetype[_c as (usize)] as (usize) & _f == 0) as (i32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __wcwidth(mut _c: i32) -> i32 {
|
|
||||||
let mut _x: u32;
|
|
||||||
if _c == 0i32 {
|
|
||||||
0i32
|
|
||||||
} else {
|
|
||||||
_x = __maskrune(_c, 0xe0000000usize | 0x40000usize) as (u32);
|
|
||||||
(if _x as (usize) & 0xe0000000usize != 0usize {
|
|
||||||
((_x as (usize) & 0xe0000000usize) >> 30i32) as (i32)
|
|
||||||
} else if _x as (usize) & 0x40000usize != 0usize {
|
|
||||||
1i32
|
|
||||||
} else {
|
|
||||||
-1i32
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isalnum(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, (0x100isize | 0x400isize) as (usize))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isalpha(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x100usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isblank(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x20000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iscntrl(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x200usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isdigit(mut _c: i32) -> i32 {
|
|
||||||
__isctype(_c, 0x400usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isgraph(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x800usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn islower(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x1000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isprint(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x40000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ispunct(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x2000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isspace(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x4000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isupper(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x8000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isxdigit(mut _c: i32) -> i32 {
|
|
||||||
__isctype(_c, 0x10000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn toascii(mut _c: i32) -> i32 {
|
|
||||||
_c & 0x7fi32
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tolower(mut _c: i32) -> i32 {
|
|
||||||
__tolower(_c)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn toupper(mut _c: i32) -> i32 {
|
|
||||||
__toupper(_c)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn digittoint(mut _c: i32) -> i32 {
|
|
||||||
__maskrune(_c, 0xfusize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ishexnumber(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x10000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isideogram(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x80000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isnumber(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x400usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isphonogram(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x200000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isrune(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0xfffffff0usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isspecial(mut _c: i32) -> i32 {
|
|
||||||
__istype(_c, 0x100000usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct __sbuf {
|
|
||||||
pub _base: *mut u8,
|
|
||||||
pub _size: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for __sbuf {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub static mut szLOG_SOURCE: *const u8 = (*b"YubiKey PIV Library\0").as_ptr();
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(i32)]
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub enum Enum5 {
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
DES_OK = 0i32,
|
#[repr(i32)]
|
||||||
DES_INVALID_PARAMETER = -1i32,
|
pub enum DesErrorKind {
|
||||||
DES_BUFFER_TOO_SMALL = -2i32,
|
/// Ok
|
||||||
DES_MEMORY_ERROR = -3i32,
|
Ok = 0,
|
||||||
DES_GENERAL_ERROR = -4i32,
|
|
||||||
|
/// Invalid parameter
|
||||||
|
InvalidParameter = -1,
|
||||||
|
|
||||||
|
/// Buffer too small
|
||||||
|
BufferTooSmall = -2,
|
||||||
|
|
||||||
|
/// Memory error
|
||||||
|
MemoryError = -3,
|
||||||
|
|
||||||
|
/// General error
|
||||||
|
GeneralError = -4,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy)]
|
/// 3DES subkeys
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DES_ks {
|
pub struct DesSubKey([u8; 16]);
|
||||||
pub ks: [u8; 16],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for DES_ks {
|
/// 3DES keys
|
||||||
fn clone(&self) -> Self {
|
#[derive(Copy, Clone)]
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct DesKey {
|
pub struct DesKey {
|
||||||
pub ks1: DES_ks,
|
/// subkey 1
|
||||||
pub ks2: DES_ks,
|
pub ks1: DesSubKey,
|
||||||
pub ks3: DES_ks,
|
|
||||||
|
/// subkey 2
|
||||||
|
pub ks2: DesSubKey,
|
||||||
|
|
||||||
|
/// subkey 3
|
||||||
|
pub ks3: DesSubKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for DesKey {
|
/// Import DES key
|
||||||
fn clone(&self) -> Self {
|
pub unsafe fn des_import_key(
|
||||||
*self
|
key_type: i32,
|
||||||
}
|
keyraw: *const u8,
|
||||||
}
|
|
||||||
|
|
||||||
pub fn des_import_key(
|
|
||||||
type_: i32,
|
|
||||||
mut keyraw: *const u8,
|
|
||||||
keyrawlen: usize,
|
keyrawlen: usize,
|
||||||
mut key: *mut *mut DesKey,
|
key: *mut *mut DesKey,
|
||||||
) -> Enum5 {
|
) -> DesErrorKind {
|
||||||
let mut _currentBlock;
|
let mut key_tmp = [0u8; 8];
|
||||||
let mut rc: Enum5 = Enum5::DES_OK;
|
let cb_expectedkey: usize;
|
||||||
let mut cb_expectedkey: usize = (8i32 * 3i32) as (usize);
|
let cb_keysize: usize;
|
||||||
let mut key_tmp: [u8; 8];
|
|
||||||
let mut cb_keysize: usize = 8usize;
|
if key_type != DES_TYPE_3DES as i32 {
|
||||||
if type_ == 1i32 {
|
return DesErrorKind::InvalidParameter;
|
||||||
|
}
|
||||||
|
|
||||||
cb_expectedkey = (8i32 * 3i32) as (usize);
|
cb_expectedkey = (8i32 * 3i32) as (usize);
|
||||||
cb_keysize = 8usize;
|
cb_keysize = 8usize;
|
||||||
if cb_keysize > ::std::mem::size_of::<[u8; 8]>() {
|
|
||||||
rc = Enum5::DES_MEMORY_ERROR;
|
if cb_keysize > 8 {
|
||||||
_currentBlock = 15;
|
return DesErrorKind::MemoryError;
|
||||||
} else if keyraw.is_null() {
|
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
|
||||||
_currentBlock = 15;
|
|
||||||
} else if keyrawlen != cb_expectedkey {
|
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
|
||||||
_currentBlock = 15;
|
|
||||||
} else if key.is_null() {
|
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
|
||||||
_currentBlock = 15;
|
|
||||||
} else if {
|
|
||||||
*key = malloc(::std::mem::size_of::<DesKey>()) as (*mut DesKey);
|
|
||||||
*key
|
|
||||||
}
|
}
|
||||||
.is_null()
|
|
||||||
{
|
if key.is_null() || keyraw.is_null() || keyrawlen != cb_expectedkey {
|
||||||
rc = Enum5::DES_MEMORY_ERROR;
|
return DesErrorKind::InvalidParameter;
|
||||||
_currentBlock = 15;
|
}
|
||||||
} else {
|
|
||||||
memset(
|
*key = malloc(mem::size_of::<DesKey>()) as (*mut DesKey);
|
||||||
*key as (*mut ::std::os::raw::c_void),
|
|
||||||
0i32,
|
if (*key).is_null() {
|
||||||
::std::mem::size_of::<DesKey>(),
|
return DesErrorKind::MemoryError;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
memset(*key as (*mut c_void), 0i32, mem::size_of::<DesKey>());
|
||||||
|
|
||||||
memcpy(
|
memcpy(
|
||||||
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
key_tmp.as_mut_ptr() as (*mut c_void),
|
||||||
keyraw as (*const ::std::os::raw::c_void),
|
keyraw as (*const c_void),
|
||||||
cb_keysize,
|
cb_keysize,
|
||||||
);
|
);
|
||||||
DES_set_key_unchecked(
|
|
||||||
&mut key_tmp as (*mut [u8; 8]),
|
DES_set_key_unchecked(&mut key_tmp, &mut (**key).ks1);
|
||||||
&mut (**key).ks1 as (*mut DES_ks),
|
|
||||||
);
|
|
||||||
memcpy(
|
memcpy(
|
||||||
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
key_tmp.as_mut_ptr() as (*mut c_void),
|
||||||
keyraw.offset(cb_keysize as (isize)) as (*const ::std::os::raw::c_void),
|
keyraw.add(cb_keysize) as (*const c_void),
|
||||||
cb_keysize,
|
cb_keysize,
|
||||||
);
|
);
|
||||||
DES_set_key_unchecked(
|
|
||||||
&mut key_tmp as (*mut [u8; 8]),
|
DES_set_key_unchecked(&mut key_tmp, &mut (**key).ks2);
|
||||||
&mut (**key).ks2 as (*mut DES_ks),
|
|
||||||
);
|
|
||||||
memcpy(
|
memcpy(
|
||||||
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
key_tmp.as_mut_ptr() as (*mut c_void),
|
||||||
keyraw.offset(2usize.wrapping_mul(cb_keysize) as (isize))
|
keyraw.add(2usize.wrapping_mul(cb_keysize)) as (*const c_void),
|
||||||
as (*const ::std::os::raw::c_void),
|
|
||||||
cb_keysize,
|
cb_keysize,
|
||||||
);
|
);
|
||||||
DES_set_key_unchecked(
|
|
||||||
&mut key_tmp as (*mut [u8; 8]),
|
DES_set_key_unchecked(&mut key_tmp, &mut (**key).ks3);
|
||||||
&mut (**key).ks3 as (*mut DES_ks),
|
|
||||||
);
|
DesErrorKind::Ok
|
||||||
_currentBlock = 17;
|
}
|
||||||
}
|
|
||||||
} else {
|
/// Destroy DES key
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
pub unsafe fn des_destroy_key(key: *mut DesKey) -> DesErrorKind {
|
||||||
_currentBlock = 15;
|
|
||||||
}
|
|
||||||
if _currentBlock == 15 {
|
|
||||||
if !key.is_null() {
|
if !key.is_null() {
|
||||||
des_destroy_key(*key);
|
free(key as (*mut c_void));
|
||||||
*key = 0i32 as (*mut ::std::os::raw::c_void) as (*mut DesKey);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
rc
|
DesErrorKind::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn des_destroy_key(mut key: *mut DesKey) -> Enum5 {
|
/// Encrypt with DES key
|
||||||
if !key.is_null() {
|
pub unsafe fn des_encrypt(
|
||||||
free(key as (*mut ::std::os::raw::c_void));
|
key: *mut DesKey,
|
||||||
|
input: *const u8,
|
||||||
|
inputlen: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
outlen: *mut usize,
|
||||||
|
) -> DesErrorKind {
|
||||||
|
if key.is_null() || outlen.is_null() || *outlen < inputlen || input.is_null() || out.is_null() {
|
||||||
|
return DesErrorKind::InvalidParameter;
|
||||||
}
|
}
|
||||||
Enum5::DES_OK
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn des_encrypt(
|
|
||||||
mut key: *mut DesKey,
|
|
||||||
mut in_: *const u8,
|
|
||||||
inlen: usize,
|
|
||||||
mut out: *mut u8,
|
|
||||||
mut outlen: *mut usize,
|
|
||||||
) -> Enum5 {
|
|
||||||
let mut rc: Enum5 = Enum5::DES_OK;
|
|
||||||
if key.is_null() || outlen.is_null() || *outlen < inlen || in_.is_null() || out.is_null() {
|
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
|
||||||
} else {
|
|
||||||
DES_ecb3_encrypt(
|
DES_ecb3_encrypt(
|
||||||
in_ as (*mut [u8; 8]),
|
input as *mut [u8; 8],
|
||||||
out as (*mut [u8; 8]),
|
out as *mut [u8; 8],
|
||||||
&mut (*key).ks1 as (*mut DES_ks),
|
&mut (*key).ks1,
|
||||||
&mut (*key).ks2 as (*mut DES_ks),
|
&mut (*key).ks2,
|
||||||
&mut (*key).ks3 as (*mut DES_ks),
|
&mut (*key).ks3,
|
||||||
1i32,
|
1,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
rc
|
DesErrorKind::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn des_decrypt(
|
/// Decrypt with DES key
|
||||||
mut key: *mut DesKey,
|
pub unsafe fn des_decrypt(
|
||||||
mut in_: *const u8,
|
key: *mut DesKey,
|
||||||
|
in_: *const u8,
|
||||||
inlen: usize,
|
inlen: usize,
|
||||||
mut out: *mut u8,
|
out: *mut u8,
|
||||||
mut outlen: *mut usize,
|
outlen: *mut usize,
|
||||||
) -> Enum5 {
|
) -> DesErrorKind {
|
||||||
let mut rc: Enum5 = Enum5::DES_OK;
|
|
||||||
if key.is_null() || outlen.is_null() || *outlen < inlen || in_.is_null() || out.is_null() {
|
if key.is_null() || outlen.is_null() || *outlen < inlen || in_.is_null() || out.is_null() {
|
||||||
rc = Enum5::DES_INVALID_PARAMETER;
|
return DesErrorKind::InvalidParameter;
|
||||||
} else {
|
|
||||||
DES_ecb3_encrypt(
|
|
||||||
in_ as (*mut [u8; 8]),
|
|
||||||
out as (*mut [u8; 8]),
|
|
||||||
&mut (*key).ks1 as (*mut DES_ks),
|
|
||||||
&mut (*key).ks2 as (*mut DES_ks),
|
|
||||||
&mut (*key).ks3 as (*mut DES_ks),
|
|
||||||
0i32,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
rc
|
|
||||||
|
DES_ecb3_encrypt(
|
||||||
|
in_ as *mut [u8; 8],
|
||||||
|
out as *mut [u8; 8],
|
||||||
|
&mut (*key).ks1,
|
||||||
|
&mut (*key).ks2,
|
||||||
|
&mut (*key).ks3,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
DesErrorKind::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yk_des_is_weak_key(mut key: *const u8, cb_key: usize) -> bool {
|
/// Is the given DES key weak?
|
||||||
cb_key;
|
pub unsafe fn yk_des_is_weak_key(key: *const u8, _cb_key: usize) -> bool {
|
||||||
DES_is_weak_key(key as (*mut [u8; 8])) != 0
|
DES_is_weak_key(key as (*mut [u8; 8])) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
/// PRNG errors/results
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
#[allow(non_camel_case_types)]
|
pub enum PRngErrorKind {
|
||||||
pub enum Enum7 {
|
/// Ok
|
||||||
PRNG_OK = 0i32,
|
Ok = 0,
|
||||||
PRNG_GENERAL_ERROR = -1i32,
|
|
||||||
|
/// General error
|
||||||
|
GeneralError = -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _ykpiv_prng_generate(mut buffer: *mut u8, cb_req: usize) -> Enum7 {
|
/// Generate bytes with the PRNG
|
||||||
let mut rc: Enum7 = Enum7::PRNG_OK;
|
pub unsafe fn _ykpiv_prng_generate(buffer: *mut u8, cb_req: usize) -> PRngErrorKind {
|
||||||
if -1i32 == RAND_bytes(buffer, cb_req as (i32)) {
|
if RAND_bytes(buffer, cb_req as (i32)) != -1 {
|
||||||
rc = Enum7::PRNG_GENERAL_ERROR;
|
PRngErrorKind::Ok
|
||||||
|
} else {
|
||||||
|
PRngErrorKind::GeneralError
|
||||||
}
|
}
|
||||||
rc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
/// PKCS#5 error types
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
#[allow(non_camel_case_types)]
|
pub enum Pkcs5ErrorKind {
|
||||||
pub enum Enum8 {
|
/// OK
|
||||||
PKCS5_OK = 0i32,
|
Ok = 0,
|
||||||
PKCS5_GENERAL_ERROR = -1i32,
|
|
||||||
|
/// General error
|
||||||
|
GeneralError = -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pkcs5_pbkdf2_sha1(
|
/// Decrypt a PKCS#5 key
|
||||||
mut password: *const u8,
|
pub unsafe fn pkcs5_pbkdf2_sha1(
|
||||||
|
password: *const u8,
|
||||||
cb_password: usize,
|
cb_password: usize,
|
||||||
mut salt: *const u8,
|
salt: *const u8,
|
||||||
cb_salt: usize,
|
cb_salt: usize,
|
||||||
mut iterations: usize,
|
iterations: usize,
|
||||||
mut key: *const u8,
|
key: *const u8,
|
||||||
cb_key: usize,
|
cb_key: usize,
|
||||||
) -> Enum8 {
|
) -> Pkcs5ErrorKind {
|
||||||
let mut rc: Enum8 = Enum8::PKCS5_OK;
|
|
||||||
PKCS5_PBKDF2_HMAC_SHA1(
|
PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
password,
|
password,
|
||||||
cb_password as (i32),
|
cb_password as (i32),
|
||||||
@@ -490,70 +284,55 @@ pub fn pkcs5_pbkdf2_sha1(
|
|||||||
cb_key as (i32),
|
cb_key as (i32),
|
||||||
key as (*mut u8),
|
key as (*mut u8),
|
||||||
);
|
);
|
||||||
rc
|
|
||||||
|
Pkcs5ErrorKind::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _strip_ws(mut sz: *mut c_char) -> *mut c_char {
|
/// Strip whitespace
|
||||||
let mut psz_head: *mut c_char = sz;
|
// TODO(tarcieri): implement this
|
||||||
let mut psz_tail: *mut c_char = sz
|
pub unsafe fn _strip_ws(sz: *mut c_char) -> *mut c_char {
|
||||||
.offset(strlen(sz as *const c_char) as (isize))
|
sz
|
||||||
.offset(-1isize);
|
|
||||||
'loop1: loop {
|
|
||||||
if isspace(*psz_head as i32) == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
psz_head = psz_head.offset(1isize);
|
|
||||||
}
|
|
||||||
'loop2: loop {
|
|
||||||
if !(psz_tail >= psz_head && (isspace(*psz_tail as (i32)) != 0)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*{
|
|
||||||
let _old = psz_tail;
|
|
||||||
psz_tail = psz_tail.offset(-1isize);
|
|
||||||
_old
|
|
||||||
} = 0;
|
|
||||||
}
|
|
||||||
psz_head
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Source of how a setting was configured
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SettingSource {
|
pub enum SettingSource {
|
||||||
SETTING_SOURCE_USER,
|
/// User-specified setting
|
||||||
SETTING_SOURCE_ADMIN,
|
User,
|
||||||
SETTING_SOURCE_DEFAULT,
|
|
||||||
|
/// Admin-specified setting
|
||||||
|
Admin,
|
||||||
|
|
||||||
|
/// Default setting
|
||||||
|
Default,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy)]
|
/// Setting booleans
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct SettingBool {
|
pub struct SettingBool {
|
||||||
|
/// Boolean value
|
||||||
pub value: bool,
|
pub value: bool,
|
||||||
|
|
||||||
|
/// Source of the configuration setting (user/admin/default)
|
||||||
pub source: SettingSource,
|
pub source: SettingSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for SettingBool {
|
/// Get a boolean config value
|
||||||
fn clone(&self) -> Self {
|
pub unsafe fn _get_bool_config(sz_setting: *const c_char) -> SettingBool {
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn _get_bool_config(mut sz_setting: *const c_char) -> SettingBool {
|
|
||||||
let mut setting: SettingBool = SettingBool {
|
let mut setting: SettingBool = SettingBool {
|
||||||
value: false,
|
value: false,
|
||||||
source: SettingSource::SETTING_SOURCE_DEFAULT,
|
source: SettingSource::Default,
|
||||||
};
|
};
|
||||||
let mut sz_line = [0u8; 256];
|
let mut sz_line = [0u8; 256];
|
||||||
let mut psz_name: *mut c_char = ptr::null_mut();
|
let mut psz_name: *mut c_char;
|
||||||
let mut psz_value: *mut c_char = ptr::null_mut();
|
let mut psz_value: *mut c_char;
|
||||||
let mut sz_name = [0u8; 256];
|
let mut sz_name = [0u8; 256];
|
||||||
let mut sz_value = [0u8; 256];
|
let mut sz_value = [0u8; 256];
|
||||||
|
|
||||||
let mut pf = unsafe {
|
let pf = fopen(
|
||||||
fopen(
|
|
||||||
b"/etc/yubico/yubikeypiv.conf\0".as_ptr() as *const c_char,
|
b"/etc/yubico/yubikeypiv.conf\0".as_ptr() as *const c_char,
|
||||||
b"r\0".as_ptr() as *const c_char,
|
b"r\0".as_ptr() as *const c_char,
|
||||||
)
|
);
|
||||||
};
|
|
||||||
|
|
||||||
if pf.is_null() {
|
if pf.is_null() {
|
||||||
return setting;
|
return setting;
|
||||||
@@ -582,78 +361,65 @@ pub unsafe fn _get_bool_config(mut sz_setting: *const c_char) -> SettingBool {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(sscanf(
|
if sscanf(
|
||||||
sz_line.as_mut_ptr(),
|
sz_line.as_ptr() as *const c_char,
|
||||||
(*b"%255[^=]=%255s\0").as_ptr(),
|
b"%255[^=]=%255s\0".as_ptr() as *const c_char,
|
||||||
sz_name.as_mut_ptr(),
|
sz_name.as_mut_ptr(),
|
||||||
sz_value.as_mut_ptr(),
|
sz_value.as_mut_ptr(),
|
||||||
) == 2)
|
) != 2
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
psz_name = _strip_ws(sz_name.as_mut_ptr() as *mut c_char);
|
psz_name = _strip_ws(sz_name.as_mut_ptr() as *mut c_char);
|
||||||
|
|
||||||
if !(strcasecmp(psz_name as *const c_char, sz_setting as *const c_char) == 0) {
|
if strcasecmp(psz_name, sz_setting) != 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
psz_value = _strip_ws(sz_value.as_mut_ptr() as *mut c_char);
|
psz_value = _strip_ws(sz_value.as_mut_ptr() as *mut c_char);
|
||||||
setting.source = SettingSource::SETTING_SOURCE_ADMIN;
|
setting.source = SettingSource::Admin;
|
||||||
setting.value = strcmp(psz_value as *const c_char, b"1\0".as_ptr() as *const c_char) == 0
|
setting.value = strcmp(psz_value, b"1\0".as_ptr() as *const c_char) == 0
|
||||||
|| strcasecmp(
|
|| strcasecmp(psz_value, b"true\0".as_ptr() as *const c_char) == 0;
|
||||||
psz_value as *const c_char,
|
|
||||||
b"true\0".as_ptr() as *const c_char,
|
|
||||||
) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pf);
|
fclose(pf);
|
||||||
setting
|
setting
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _get_bool_env(mut sz_setting: *const c_char) -> SettingBool {
|
/// Get a setting boolean from an environment variable
|
||||||
|
pub unsafe fn _get_bool_env(sz_setting: *const c_char) -> SettingBool {
|
||||||
let mut setting: SettingBool = SettingBool {
|
let mut setting: SettingBool = SettingBool {
|
||||||
value: false,
|
value: false,
|
||||||
source: SettingSource::SETTING_SOURCE_DEFAULT,
|
source: SettingSource::Default,
|
||||||
};
|
};
|
||||||
let mut psz_value: *mut c_char = ptr::null_mut();
|
|
||||||
let mut sz_name = [0u8; 256];
|
|
||||||
|
|
||||||
snprintf(
|
let sz_name = CString::new(format!(
|
||||||
sz_name.as_mut_ptr(),
|
"YUBIKEY_PIV_{}",
|
||||||
::std::mem::size_of::<[u8; 256]>().wrapping_sub(1usize),
|
CStr::from_ptr(sz_setting).to_string_lossy()
|
||||||
b"%s%s\0".as_ptr(),
|
))
|
||||||
b"YUBIKEY_PIV_\0".as_ptr(),
|
.unwrap();
|
||||||
sz_setting,
|
|
||||||
);
|
|
||||||
|
|
||||||
psz_value = getenv(sz_name.as_mut_ptr() as *const c_char);
|
let psz_value = getenv(sz_name.as_ptr());
|
||||||
|
|
||||||
if !psz_value.is_null() {
|
if !psz_value.is_null() {
|
||||||
setting.source = SettingSource::SETTING_SOURCE_USER;
|
setting.source = SettingSource::User;
|
||||||
setting.value = strcmp(psz_value as *const c_char, b"1\0".as_ptr() as *const c_char) == 0
|
setting.value = strcmp(psz_value, b"1\0".as_ptr() as *const c_char) == 0
|
||||||
|| strcasecmp(
|
|| strcasecmp(psz_value, b"true\0".as_ptr() as *const c_char) == 0;
|
||||||
psz_value as *const c_char,
|
|
||||||
b"true\0".as_ptr() as *const c_char,
|
|
||||||
) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setting
|
setting
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setting_get_bool(mut sz_setting: *const c_char, mut def: bool) -> SettingBool {
|
/// Get a setting boolean
|
||||||
let mut setting: SettingBool = SettingBool {
|
pub unsafe fn setting_get_bool(sz_setting: *const c_char, def: bool) -> SettingBool {
|
||||||
value: def,
|
let mut setting = _get_bool_config(sz_setting);
|
||||||
source: SettingSource::SETTING_SOURCE_DEFAULT,
|
|
||||||
};
|
|
||||||
|
|
||||||
setting = _get_bool_config(sz_setting);
|
if setting.source == SettingSource::Default {
|
||||||
|
|
||||||
if setting.source == SettingSource::SETTING_SOURCE_DEFAULT {
|
|
||||||
setting = _get_bool_env(sz_setting);
|
setting = _get_bool_env(sz_setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.source == SettingSource::SETTING_SOURCE_DEFAULT {
|
if setting.source == SettingSource::Default {
|
||||||
setting.value = def;
|
setting.value = def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
-3132
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -90,7 +90,7 @@ static ykpiv_rc _get_metadata_item(uint8_t *data, size_t cb_data, uint8_t tag, u
|
|||||||
static ykpiv_rc _set_metadata_item(uint8_t *data, size_t *pcb_data, size_t cb_data_max, uint8_t tag, uint8_t *p_item, size_t cb_item);
|
static ykpiv_rc _set_metadata_item(uint8_t *data, size_t *pcb_data, size_t cb_data_max, uint8_t tag, uint8_t *p_item, size_t cb_item);
|
||||||
|
|
||||||
static size_t _obj_size_max(ykpiv_state *state) {
|
static size_t _obj_size_max(ykpiv_state *state) {
|
||||||
return (state && state->isNEO) ? CB_OBJ_MAX_NEO : CB_OBJ_MAX;
|
return (state && state->is_neo) ? CB_OBJ_MAX_NEO : CB_OBJ_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -215,7 +215,7 @@ ykpiv_devmodel ykpiv_util_devicemodel(ykpiv_state *state) {
|
|||||||
if (!state || !state->context || (state->context == (uintptr_t)-1)) {
|
if (!state || !state->context || (state->context == (uintptr_t)-1)) {
|
||||||
return DEVTYPE_UNKNOWN;
|
return DEVTYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
return (state->isNEO ? DEVTYPE_NEOr3 : DEVTYPE_YK4);
|
return (state->is_neo ? DEVTYPE_NEOr3 : DEVTYPE_YK4);
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_util_list_keys(ykpiv_state *state, uint8_t *key_count, ykpiv_key **data, size_t *data_len) {
|
ykpiv_rc ykpiv_util_list_keys(ykpiv_state *state, uint8_t *key_count, ykpiv_key **data, size_t *data_len) {
|
||||||
|
|||||||
+1484
-1997
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -373,7 +373,7 @@ static ykpiv_rc _ykpiv_connect(ykpiv_state *state, uintptr_t context, uintptr_t
|
|||||||
return YKPIV_PCSC_ERROR;
|
return YKPIV_PCSC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->isNEO = (((sizeof(YKPIV_ATR_NEO_R3) - 1) == atr_len) && (0 == memcmp(YKPIV_ATR_NEO_R3, atr, atr_len)));
|
state->is_neo = (((sizeof(YKPIV_ATR_NEO_R3) - 1) == atr_len) && (0 == memcmp(YKPIV_ATR_NEO_R3, atr, atr_len)));
|
||||||
}
|
}
|
||||||
|
|
||||||
state->context = context;
|
state->context = context;
|
||||||
|
|||||||
+2549
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user