oxidize: Initial corrode translation
Includes changes to the original C code needed for `corrode` to accept the input. There were a lot of problems with APDU fields. These need to be copied into the translated Rust code and fixed up manually. Code otherwise contains the raw `corrode` output.
This commit is contained in:
+1
-1
@@ -41,7 +41,7 @@ typedef struct
|
|||||||
const char *description;
|
const char *description;
|
||||||
} err_t;
|
} err_t;
|
||||||
|
|
||||||
static const err_t errors[] = {
|
static const err_t *errors = {
|
||||||
ERR (YKPIV_OK, "Successful return"),
|
ERR (YKPIV_OK, "Successful return"),
|
||||||
ERR (YKPIV_MEMORY_ERROR, "Error allocating memory"),
|
ERR (YKPIV_MEMORY_ERROR, "Error allocating memory"),
|
||||||
ERR (YKPIV_PCSC_ERROR, "Error in PCSC call"),
|
ERR (YKPIV_PCSC_ERROR, "Error in PCSC call"),
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum Enum2 {
|
||||||
|
YKPIV_OK = 0i32,
|
||||||
|
YKPIV_MEMORY_ERROR = -1i32,
|
||||||
|
YKPIV_PCSC_ERROR = -2i32,
|
||||||
|
YKPIV_SIZE_ERROR = -3i32,
|
||||||
|
YKPIV_APPLET_ERROR = -4i32,
|
||||||
|
YKPIV_AUTHENTICATION_ERROR = -5i32,
|
||||||
|
YKPIV_RANDOMNESS_ERROR = -6i32,
|
||||||
|
YKPIV_GENERIC_ERROR = -7i32,
|
||||||
|
YKPIV_KEY_ERROR = -8i32,
|
||||||
|
YKPIV_PARSE_ERROR = -9i32,
|
||||||
|
YKPIV_WRONG_PIN = -10i32,
|
||||||
|
YKPIV_INVALID_OBJECT = -11i32,
|
||||||
|
YKPIV_ALGORITHM_ERROR = -12i32,
|
||||||
|
YKPIV_PIN_LOCKED = -13i32,
|
||||||
|
YKPIV_ARGUMENT_ERROR = -14i32,
|
||||||
|
YKPIV_RANGE_ERROR = -15i32,
|
||||||
|
YKPIV_NOT_SUPPORTED = -16i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Struct1 {
|
||||||
|
pub rc : Enum2,
|
||||||
|
pub name : *const u8,
|
||||||
|
pub description : *const u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Struct1 {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut errors
|
||||||
|
: *const Struct1
|
||||||
|
= Enum2::YKPIV_OK as (*const Struct1);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn ykpiv_strerror(mut err : Enum2) -> *const u8 {
|
||||||
|
static mut unknown
|
||||||
|
: *const u8
|
||||||
|
= (*b"Unknown ykpiv error\0").as_ptr();
|
||||||
|
let mut p : *const u8;
|
||||||
|
if -(err as (i32)) < 0i32 || -(err as (i32)) >= ::std::mem::size_of::<*const Struct1>(
|
||||||
|
).wrapping_div(
|
||||||
|
::std::mem::size_of::<Struct1>()
|
||||||
|
) as (i32) {
|
||||||
|
unknown
|
||||||
|
} else {
|
||||||
|
p = (*errors.offset(-(err as (i32)) as (isize))).description;
|
||||||
|
if p.is_null() {
|
||||||
|
p = unknown;
|
||||||
|
}
|
||||||
|
p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn ykpiv_strerror_name(
|
||||||
|
mut err : Enum2
|
||||||
|
) -> *const u8 {
|
||||||
|
if -(err as (i32)) < 0i32 || -(err as (i32)) >= ::std::mem::size_of::<*const Struct1>(
|
||||||
|
).wrapping_div(
|
||||||
|
::std::mem::size_of::<Struct1>()
|
||||||
|
) as (i32) {
|
||||||
|
0i32 as (*mut ::std::os::raw::c_void) as (*const u8)
|
||||||
|
} else {
|
||||||
|
(*errors.offset(-(err as (i32)) as (isize))).name
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-113
@@ -122,7 +122,7 @@ setting_bool_t _get_bool_env(const char *sz_setting);
|
|||||||
|
|
||||||
/* log */
|
/* log */
|
||||||
|
|
||||||
const char szLOG_SOURCE[] = "YubiKey PIV Library";
|
const char *szLOG_SOURCE = "YubiKey PIV Library";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Methods
|
** Methods
|
||||||
@@ -533,16 +533,16 @@ setting_bool_t _get_bool_config(const char *sz_setting) {
|
|||||||
char sz_line[256];
|
char sz_line[256];
|
||||||
char *psz_name = 0;
|
char *psz_name = 0;
|
||||||
char *psz_value = 0;
|
char *psz_value = 0;
|
||||||
char sz_name[256] = { 0 };
|
char sz_name[256]; /* XXX REMEMBER TO ZERO */
|
||||||
char sz_value[256] = { 0 };
|
char sz_value[256]; /* XXX REMEMBER TO ZERO */
|
||||||
FILE *pf = 0;
|
FILE *pf = 0;
|
||||||
|
|
||||||
if ((pf = fopen(_CONFIG_FILE, "r"))) {
|
if ((pf = fopen(_CONFIG_FILE, "r"))) {
|
||||||
while (!feof(pf)) {
|
while (!feof(pf)) {
|
||||||
if (fgets(sz_line, sizeof(sz_line), pf)) {
|
if (fgets(sz_line, sizeof(sz_line), pf)) {
|
||||||
if (*sz_line == '#') continue;
|
if (sz_line[0] == '#') continue;
|
||||||
if (*sz_line == '\r') continue;
|
if (sz_line[0] == '\r') continue;
|
||||||
if (*sz_line == '\n') continue;
|
if (sz_line[0] == '\n') continue;
|
||||||
|
|
||||||
if (sscanf(sz_line, "%255[^=]=%255s", sz_name, sz_value) == 2) {
|
if (sscanf(sz_line, "%255[^=]=%255s", sz_name, sz_value) == 2) {
|
||||||
/* strip leading/trailing whitespace */
|
/* strip leading/trailing whitespace */
|
||||||
@@ -569,7 +569,7 @@ setting_bool_t _get_bool_config(const char *sz_setting) {
|
|||||||
setting_bool_t _get_bool_env(const char *sz_setting) {
|
setting_bool_t _get_bool_env(const char *sz_setting) {
|
||||||
setting_bool_t setting = { false, SETTING_SOURCE_DEFAULT };
|
setting_bool_t setting = { false, SETTING_SOURCE_DEFAULT };
|
||||||
char *psz_value = NULL;
|
char *psz_value = NULL;
|
||||||
char sz_name[256] = { 0 };
|
char sz_name[256]; /* XXX REMEMBER TO ZERO */
|
||||||
|
|
||||||
snprintf(sz_name, sizeof(sz_name) - 1, "%s%s", _ENV_PREFIX, sz_setting);
|
snprintf(sz_name, sizeof(sz_name) - 1, "%s%s", _ENV_PREFIX, sz_setting);
|
||||||
|
|
||||||
@@ -610,109 +610,3 @@ setting_bool_t setting_get_bool(const char *sz_setting, bool def) {
|
|||||||
|
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* logging */
|
|
||||||
|
|
||||||
void yc_log_event(uint32_t id, yc_log_level_t level, const char * sz_format, ...) {
|
|
||||||
char rgsz_message[4096];
|
|
||||||
va_list vl;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE hLog = NULL;
|
|
||||||
LPCSTR sz_message = rgsz_message;
|
|
||||||
WORD w_type = EVENTLOG_SUCCESS;
|
|
||||||
#else
|
|
||||||
int priority = LOG_INFO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
va_start(vl, sz_format);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case YC_LOG_LEVEL_ERROR:
|
|
||||||
w_type = EVENTLOG_ERROR_TYPE;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_WARN:
|
|
||||||
w_type = EVENTLOG_WARNING_TYPE;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_INFO:
|
|
||||||
w_type = EVENTLOG_INFORMATION_TYPE;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_VERBOSE:
|
|
||||||
w_type = EVENTLOG_INFORMATION_TYPE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case YC_LOG_LEVEL_DEBUG:
|
|
||||||
w_type = EVENTLOG_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(hLog = RegisterEventSourceA(NULL, szLOG_SOURCE))) {
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* format message */
|
|
||||||
|
|
||||||
if (FAILED(StringCbVPrintfA(
|
|
||||||
rgsz_message,
|
|
||||||
sizeof(rgsz_message),
|
|
||||||
sz_format,
|
|
||||||
vl))) {
|
|
||||||
goto Cleanup;
|
|
||||||
};
|
|
||||||
|
|
||||||
// write to the local event log
|
|
||||||
|
|
||||||
ReportEventA(
|
|
||||||
hLog,
|
|
||||||
w_type,
|
|
||||||
0,
|
|
||||||
(DWORD)id,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
(LPCSTR *)&sz_message,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case YC_LOG_LEVEL_ERROR:
|
|
||||||
priority = LOG_ERR;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_WARN:
|
|
||||||
priority = LOG_WARNING;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_INFO:
|
|
||||||
priority = LOG_NOTICE;
|
|
||||||
break;
|
|
||||||
case YC_LOG_LEVEL_VERBOSE:
|
|
||||||
priority = LOG_INFO;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case YC_LOG_LEVEL_DEBUG:
|
|
||||||
priority = LOG_DEBUG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vsnprintf(rgsz_message, sizeof(rgsz_message), sz_format, vl) < 0) {
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
openlog(szLOG_SOURCE, LOG_PID | LOG_NDELAY, LOG_USER);
|
|
||||||
syslog(priority, "%s", rgsz_message);
|
|
||||||
closelog();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Cleanup:
|
|
||||||
|
|
||||||
va_end(vl);
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (hLog) {
|
|
||||||
DeregisterEventSource(hLog);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-3
@@ -71,7 +71,7 @@ extern "C"
|
|||||||
// is CB_BUF_MAX - 9
|
// is CB_BUF_MAX - 9
|
||||||
#define CB_OBJ_MAX_NEO (CB_BUF_MAX_NEO - 9)
|
#define CB_OBJ_MAX_NEO (CB_BUF_MAX_NEO - 9)
|
||||||
#define CB_OBJ_MAX_YK4 (CB_BUF_MAX_YK4 - 9)
|
#define CB_OBJ_MAX_YK4 (CB_BUF_MAX_YK4 - 9)
|
||||||
#define CB_OBJ_MAX CB_OBJ_MAX_YK4
|
#define CB_OBJ_MAX 3063
|
||||||
|
|
||||||
#define CB_BUF_MAX_NEO 2048
|
#define CB_BUF_MAX_NEO 2048
|
||||||
#define CB_BUF_MAX_YK4 3072
|
#define CB_BUF_MAX_YK4 3072
|
||||||
@@ -236,8 +236,6 @@ typedef enum _yc_log_level_t {
|
|||||||
YC_LOG_LEVEL_DEBUG
|
YC_LOG_LEVEL_DEBUG
|
||||||
} yc_log_level_t;
|
} yc_log_level_t;
|
||||||
|
|
||||||
void yc_log_event(uint32_t id, yc_log_level_t level, const char *sz_format, ...);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define yc_memzero SecureZeroMemory
|
#define yc_memzero SecureZeroMemory
|
||||||
|
|||||||
+753
@@ -0,0 +1,753 @@
|
|||||||
|
extern {
|
||||||
|
fn DES_ecb3_encrypt(
|
||||||
|
input : *mut [u8; 8],
|
||||||
|
output : *mut [u8; 8],
|
||||||
|
ks1 : *mut DES_ks,
|
||||||
|
ks2 : *mut DES_ks,
|
||||||
|
ks3 : *mut DES_ks,
|
||||||
|
enc : 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 PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
|
pass : *const u8,
|
||||||
|
passlen : i32,
|
||||||
|
salt : *const u8,
|
||||||
|
saltlen : i32,
|
||||||
|
iter : i32,
|
||||||
|
keylen : i32,
|
||||||
|
out : *mut u8
|
||||||
|
) -> i32;
|
||||||
|
fn RAND_bytes(buf : *mut u8, num : i32) -> i32;
|
||||||
|
static mut _DefaultRuneLocale : Struct1;
|
||||||
|
fn __maskrune(arg1 : i32, arg2 : usize) -> i32;
|
||||||
|
fn __swbuf(arg1 : i32, arg2 : *mut __sFILE) -> i32;
|
||||||
|
fn __tolower(arg1 : i32) -> i32;
|
||||||
|
fn __toupper(arg1 : i32) -> i32;
|
||||||
|
fn fclose(arg1 : *mut __sFILE) -> i32;
|
||||||
|
fn feof(arg1 : *mut __sFILE) -> i32;
|
||||||
|
fn fgets(
|
||||||
|
arg1 : *mut u8, arg2 : i32, arg3 : *mut __sFILE
|
||||||
|
) -> *mut u8;
|
||||||
|
fn fopen(
|
||||||
|
__filename : *const u8, __mode : *const u8
|
||||||
|
) -> *mut __sFILE;
|
||||||
|
fn free(arg1 : *mut ::std::os::raw::c_void);
|
||||||
|
fn getenv(arg1 : *const u8) -> *mut u8;
|
||||||
|
fn malloc(__size : usize) -> *mut ::std::os::raw::c_void;
|
||||||
|
fn memcpy(
|
||||||
|
__dst : *mut ::std::os::raw::c_void,
|
||||||
|
__src : *const ::std::os::raw::c_void,
|
||||||
|
__n : usize
|
||||||
|
) -> *mut ::std::os::raw::c_void;
|
||||||
|
fn memset(
|
||||||
|
__b : *mut ::std::os::raw::c_void, __c : i32, __len : usize
|
||||||
|
) -> *mut ::std::os::raw::c_void;
|
||||||
|
fn snprintf(
|
||||||
|
__str : *mut u8, __size : usize, __format : *const u8, ...
|
||||||
|
) -> i32;
|
||||||
|
fn sscanf(arg1 : *const u8, arg2 : *const u8, ...) -> i32;
|
||||||
|
fn strcasecmp(arg1 : *const u8, arg2 : *const u8) -> i32;
|
||||||
|
fn strcmp(__s1 : *const u8, __s2 : *const u8) -> i32;
|
||||||
|
fn strlen(__s : *const u8) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Union6 {
|
||||||
|
}
|
||||||
|
|
||||||
|
enum __sFILEX {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isascii(mut _c : i32) -> i32 {
|
||||||
|
(_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 fn(*const u8, usize, *mut *const u8) -> i32,
|
||||||
|
pub __sputrune : unsafe extern 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 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isalnum(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,(0x100isize | 0x400isize) as (usize))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isalpha(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x100usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isblank(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x20000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn iscntrl(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x200usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isdigit(mut _c : i32) -> i32 {
|
||||||
|
__isctype(_c,0x400usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isgraph(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x800usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn islower(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x1000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isprint(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x40000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn ispunct(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x2000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isspace(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x4000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isupper(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x8000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isxdigit(mut _c : i32) -> i32 {
|
||||||
|
__isctype(_c,0x10000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn toascii(mut _c : i32) -> i32 { _c & 0x7fi32 }
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn tolower(mut _c : i32) -> i32 { __tolower(_c) }
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn toupper(mut _c : i32) -> i32 { __toupper(_c) }
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn digittoint(mut _c : i32) -> i32 {
|
||||||
|
__maskrune(_c,0xfusize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn ishexnumber(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x10000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isideogram(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x80000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isnumber(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x400usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isphonogram(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0x200000usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isrune(mut _c : i32) -> i32 {
|
||||||
|
__istype(_c,0xfffffff0usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern 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 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct __sFILE {
|
||||||
|
pub _p : *mut u8,
|
||||||
|
pub _r : i32,
|
||||||
|
pub _w : i32,
|
||||||
|
pub _flags : i16,
|
||||||
|
pub _file : i16,
|
||||||
|
pub _bf : __sbuf,
|
||||||
|
pub _lbfsize : i32,
|
||||||
|
pub _cookie : *mut ::std::os::raw::c_void,
|
||||||
|
pub _close : unsafe extern fn(*mut ::std::os::raw::c_void) -> i32,
|
||||||
|
pub _read : unsafe extern fn(*mut ::std::os::raw::c_void, *mut u8, i32) -> i32,
|
||||||
|
pub _seek : unsafe extern fn(*mut ::std::os::raw::c_void, isize, i32) -> isize,
|
||||||
|
pub _write : unsafe extern fn(*mut ::std::os::raw::c_void, *const u8, i32) -> i32,
|
||||||
|
pub _ub : __sbuf,
|
||||||
|
pub _extra : *mut __sFILEX,
|
||||||
|
pub _ur : i32,
|
||||||
|
pub _ubuf : [u8; 3],
|
||||||
|
pub _nbuf : [u8; 1],
|
||||||
|
pub _lb : __sbuf,
|
||||||
|
pub _blksize : i32,
|
||||||
|
pub _offset : isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for __sFILE {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn __sputc(
|
||||||
|
mut _c : i32, mut _p : *mut __sFILE
|
||||||
|
) -> i32 {
|
||||||
|
if {
|
||||||
|
(*_p)._w = (*_p)._w - 1;
|
||||||
|
(*_p)._w
|
||||||
|
} >= 0i32 || (*_p)._w >= (*_p)._lbfsize && (_c as (u8) as (i32) != b'\n' as (i32)) {
|
||||||
|
({
|
||||||
|
let _rhs = _c;
|
||||||
|
let _lhs
|
||||||
|
= &mut *{
|
||||||
|
let _old = (*_p)._p;
|
||||||
|
(*_p)._p = (*_p)._p.offset(1isize);
|
||||||
|
_old
|
||||||
|
};
|
||||||
|
*_lhs = _rhs as (u8);
|
||||||
|
*_lhs
|
||||||
|
}) as (i32)
|
||||||
|
} else {
|
||||||
|
__swbuf(_c,_p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub static mut szLOG_SOURCE
|
||||||
|
: *const u8
|
||||||
|
= (*b"YubiKey PIV Library\0").as_ptr();
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum Enum5 {
|
||||||
|
DES_OK = 0i32,
|
||||||
|
DES_INVALID_PARAMETER = -1i32,
|
||||||
|
DES_BUFFER_TOO_SMALL = -2i32,
|
||||||
|
DES_MEMORY_ERROR = -3i32,
|
||||||
|
DES_GENERAL_ERROR = -4i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct DES_ks {
|
||||||
|
pub ks : [Union6; 16],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for DES_ks {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct des_key {
|
||||||
|
pub ks1 : DES_ks,
|
||||||
|
pub ks2 : DES_ks,
|
||||||
|
pub ks3 : DES_ks,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for des_key {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn des_import_key(
|
||||||
|
type_ : i32,
|
||||||
|
mut keyraw : *const u8,
|
||||||
|
keyrawlen : usize,
|
||||||
|
mut key : *mut *mut des_key
|
||||||
|
) -> Enum5 {
|
||||||
|
let mut _currentBlock;
|
||||||
|
let mut rc : Enum5 = Enum5::DES_OK;
|
||||||
|
let mut cb_expectedkey : usize = (8i32 * 3i32) as (usize);
|
||||||
|
let mut key_tmp : [u8; 8];
|
||||||
|
let mut cb_keysize : usize = 8usize;
|
||||||
|
if type_ == 1i32 {
|
||||||
|
cb_expectedkey = (8i32 * 3i32) as (usize);
|
||||||
|
cb_keysize = 8usize;
|
||||||
|
if cb_keysize > ::std::mem::size_of::<[u8; 8]>() {
|
||||||
|
rc = Enum5::DES_MEMORY_ERROR;
|
||||||
|
_currentBlock = 15;
|
||||||
|
} 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::<des_key>()) as (*mut des_key);
|
||||||
|
*key
|
||||||
|
}.is_null(
|
||||||
|
) {
|
||||||
|
rc = Enum5::DES_MEMORY_ERROR;
|
||||||
|
_currentBlock = 15;
|
||||||
|
} else {
|
||||||
|
memset(
|
||||||
|
*key as (*mut ::std::os::raw::c_void),
|
||||||
|
0i32,
|
||||||
|
::std::mem::size_of::<des_key>()
|
||||||
|
);
|
||||||
|
memcpy(
|
||||||
|
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
||||||
|
keyraw as (*const ::std::os::raw::c_void),
|
||||||
|
cb_keysize
|
||||||
|
);
|
||||||
|
DES_set_key_unchecked(
|
||||||
|
&mut key_tmp as (*mut [u8; 8]),
|
||||||
|
&mut (**key).ks1 as (*mut DES_ks)
|
||||||
|
);
|
||||||
|
memcpy(
|
||||||
|
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
||||||
|
keyraw.offset(
|
||||||
|
cb_keysize as (isize)
|
||||||
|
) as (*const ::std::os::raw::c_void),
|
||||||
|
cb_keysize
|
||||||
|
);
|
||||||
|
DES_set_key_unchecked(
|
||||||
|
&mut key_tmp as (*mut [u8; 8]),
|
||||||
|
&mut (**key).ks2 as (*mut DES_ks)
|
||||||
|
);
|
||||||
|
memcpy(
|
||||||
|
key_tmp.as_mut_ptr() as (*mut ::std::os::raw::c_void),
|
||||||
|
keyraw.offset(
|
||||||
|
2usize.wrapping_mul(cb_keysize) as (isize)
|
||||||
|
) as (*const ::std::os::raw::c_void),
|
||||||
|
cb_keysize
|
||||||
|
);
|
||||||
|
DES_set_key_unchecked(
|
||||||
|
&mut key_tmp as (*mut [u8; 8]),
|
||||||
|
&mut (**key).ks3 as (*mut DES_ks)
|
||||||
|
);
|
||||||
|
_currentBlock = 17;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = Enum5::DES_INVALID_PARAMETER;
|
||||||
|
_currentBlock = 15;
|
||||||
|
}
|
||||||
|
if _currentBlock == 15 {
|
||||||
|
if !key.is_null() {
|
||||||
|
des_destroy_key(*key);
|
||||||
|
*key = 0i32 as (*mut ::std::os::raw::c_void) as (*mut des_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn des_destroy_key(mut key : *mut des_key) -> Enum5 {
|
||||||
|
if !key.is_null() {
|
||||||
|
free(key as (*mut ::std::os::raw::c_void));
|
||||||
|
}
|
||||||
|
Enum5::DES_OK
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn des_encrypt(
|
||||||
|
mut key : *mut des_key,
|
||||||
|
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(
|
||||||
|
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),
|
||||||
|
1i32
|
||||||
|
);
|
||||||
|
}
|
||||||
|
rc
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn des_decrypt(
|
||||||
|
mut key : *mut des_key,
|
||||||
|
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(
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn yk_des_is_weak_key(
|
||||||
|
mut key : *const u8, cb_key : usize
|
||||||
|
) -> bool {
|
||||||
|
cb_key;
|
||||||
|
DES_is_weak_key(key as (*mut [u8; 8])) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum Enum7 {
|
||||||
|
PRNG_OK = 0i32,
|
||||||
|
PRNG_GENERAL_ERROR = -1i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn _ykpiv_prng_generate(
|
||||||
|
mut buffer : *mut u8, cb_req : usize
|
||||||
|
) -> Enum7 {
|
||||||
|
let mut rc : Enum7 = Enum7::PRNG_OK;
|
||||||
|
if -1i32 == RAND_bytes(buffer,cb_req as (i32)) {
|
||||||
|
rc = Enum7::PRNG_GENERAL_ERROR;
|
||||||
|
}
|
||||||
|
rc
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum Enum8 {
|
||||||
|
PKCS5_OK = 0i32,
|
||||||
|
PKCS5_GENERAL_ERROR = -1i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn pkcs5_pbkdf2_sha1(
|
||||||
|
mut password : *const u8,
|
||||||
|
cb_password : usize,
|
||||||
|
mut salt : *const u8,
|
||||||
|
cb_salt : usize,
|
||||||
|
mut iterations : usize,
|
||||||
|
mut key : *const u8,
|
||||||
|
cb_key : usize
|
||||||
|
) -> Enum8 {
|
||||||
|
let mut rc : Enum8 = Enum8::PKCS5_OK;
|
||||||
|
PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
|
password,
|
||||||
|
cb_password as (i32),
|
||||||
|
salt,
|
||||||
|
cb_salt as (i32),
|
||||||
|
iterations as (i32),
|
||||||
|
cb_key as (i32),
|
||||||
|
key as (*mut u8)
|
||||||
|
);
|
||||||
|
rc
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn _strip_ws(mut sz : *mut u8) -> *mut u8 {
|
||||||
|
let mut psz_head : *mut u8 = sz;
|
||||||
|
let mut psz_tail
|
||||||
|
: *mut u8
|
||||||
|
= sz.offset(strlen(sz as (*const u8)) as (isize)).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
|
||||||
|
} = b'\0';
|
||||||
|
}
|
||||||
|
psz_head
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum _setting_source_t {
|
||||||
|
SETTING_SOURCE_USER,
|
||||||
|
SETTING_SOURCE_ADMIN,
|
||||||
|
SETTING_SOURCE_DEFAULT,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct _setting_bool_t {
|
||||||
|
pub value : bool,
|
||||||
|
pub source : _setting_source_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for _setting_bool_t {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn _get_bool_config(
|
||||||
|
mut sz_setting : *const u8
|
||||||
|
) -> _setting_bool_t {
|
||||||
|
let mut _currentBlock;
|
||||||
|
let mut setting
|
||||||
|
: _setting_bool_t
|
||||||
|
= _setting_bool_t {
|
||||||
|
value: false,
|
||||||
|
source: _setting_source_t::SETTING_SOURCE_DEFAULT
|
||||||
|
};
|
||||||
|
let mut sz_line : [u8; 256];
|
||||||
|
let mut psz_name : *mut u8 = 0i32 as (*mut u8);
|
||||||
|
let mut psz_value : *mut u8 = 0i32 as (*mut u8);
|
||||||
|
let mut sz_name : [u8; 256];
|
||||||
|
let mut sz_value : [u8; 256];
|
||||||
|
let mut pf : *mut __sFILE = 0i32 as (*mut __sFILE);
|
||||||
|
if !{
|
||||||
|
pf = fopen(
|
||||||
|
(*b"/etc/yubico/yubikeypiv.conf\0").as_ptr(),
|
||||||
|
(*b"r\0").as_ptr()
|
||||||
|
);
|
||||||
|
pf
|
||||||
|
}.is_null(
|
||||||
|
) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
} else {
|
||||||
|
_currentBlock = 10;
|
||||||
|
}
|
||||||
|
'loop1: loop {
|
||||||
|
if _currentBlock == 1 {
|
||||||
|
if feof(pf) == 0 {
|
||||||
|
if fgets(
|
||||||
|
sz_line.as_mut_ptr(),
|
||||||
|
::std::mem::size_of::<[u8; 256]>() as (i32),
|
||||||
|
pf
|
||||||
|
).is_null(
|
||||||
|
) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if sz_line[0usize] as (i32) == b'#' as (i32) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if sz_line[0usize] as (i32) == b'\r' as (i32) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if sz_line[0usize] as (i32) == b'\n' as (i32) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if !(sscanf(
|
||||||
|
sz_line.as_mut_ptr() as (*const u8),
|
||||||
|
(*b"%255[^=]=%255s\0").as_ptr(),
|
||||||
|
sz_name.as_mut_ptr(),
|
||||||
|
sz_value.as_mut_ptr()
|
||||||
|
) == 2i32) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
psz_name = _strip_ws(sz_name.as_mut_ptr());
|
||||||
|
if !(strcasecmp(psz_name as (*const u8),sz_setting) == 0) {
|
||||||
|
_currentBlock = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
psz_value = _strip_ws(sz_value.as_mut_ptr());
|
||||||
|
setting.source = _setting_source_t::SETTING_SOURCE_ADMIN;
|
||||||
|
setting.value = strcmp(
|
||||||
|
psz_value as (*const u8),
|
||||||
|
(*b"1\0").as_ptr()
|
||||||
|
) == 0 || strcasecmp(
|
||||||
|
psz_value as (*const u8),
|
||||||
|
(*b"true\0").as_ptr()
|
||||||
|
) == 0;
|
||||||
|
}
|
||||||
|
fclose(pf);
|
||||||
|
_currentBlock = 10;
|
||||||
|
} else {
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn _get_bool_env(
|
||||||
|
mut sz_setting : *const u8
|
||||||
|
) -> _setting_bool_t {
|
||||||
|
let mut setting
|
||||||
|
: _setting_bool_t
|
||||||
|
= _setting_bool_t {
|
||||||
|
value: false,
|
||||||
|
source: _setting_source_t::SETTING_SOURCE_DEFAULT
|
||||||
|
};
|
||||||
|
let mut psz_value
|
||||||
|
: *mut u8
|
||||||
|
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
|
||||||
|
let mut sz_name : [u8; 256];
|
||||||
|
snprintf(
|
||||||
|
sz_name.as_mut_ptr(),
|
||||||
|
::std::mem::size_of::<[u8; 256]>().wrapping_sub(1usize),
|
||||||
|
(*b"%s%s\0").as_ptr(),
|
||||||
|
(*b"YUBIKEY_PIV_\0").as_ptr(),
|
||||||
|
sz_setting
|
||||||
|
);
|
||||||
|
psz_value = getenv(sz_name.as_mut_ptr() as (*const u8));
|
||||||
|
if !psz_value.is_null() {
|
||||||
|
setting.source = _setting_source_t::SETTING_SOURCE_USER;
|
||||||
|
setting.value = strcmp(
|
||||||
|
psz_value as (*const u8),
|
||||||
|
(*b"1\0").as_ptr()
|
||||||
|
) == 0 || strcasecmp(
|
||||||
|
psz_value as (*const u8),
|
||||||
|
(*b"true\0").as_ptr()
|
||||||
|
) == 0;
|
||||||
|
}
|
||||||
|
setting
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn setting_get_bool(
|
||||||
|
mut sz_setting : *const u8, mut def : bool
|
||||||
|
) -> _setting_bool_t {
|
||||||
|
let mut setting
|
||||||
|
: _setting_bool_t
|
||||||
|
= _setting_bool_t {
|
||||||
|
value: def,
|
||||||
|
source: _setting_source_t::SETTING_SOURCE_DEFAULT
|
||||||
|
};
|
||||||
|
setting = _get_bool_config(sz_setting);
|
||||||
|
if setting.source as (i32) == _setting_source_t::SETTING_SOURCE_DEFAULT as (i32) {
|
||||||
|
setting = _get_bool_env(sz_setting);
|
||||||
|
}
|
||||||
|
if setting.source as (i32) == _setting_source_t::SETTING_SOURCE_DEFAULT as (i32) {
|
||||||
|
setting.value = def;
|
||||||
|
}
|
||||||
|
setting
|
||||||
|
}
|
||||||
+33
-29
@@ -41,6 +41,10 @@
|
|||||||
#define MAX(a,b) (a) > (b) ? (a) : (b)
|
#define MAX(a,b) (a) > (b) ? (a) : (b)
|
||||||
#define MIN(a,b) (a) < (b) ? (a) : (b)
|
#define MIN(a,b) (a) < (b) ? (a) : (b)
|
||||||
|
|
||||||
|
|
||||||
|
#define SIZEOF_CHUID_TMPL 59
|
||||||
|
#define SIZEOF_CCC_TMPL 51
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format defined in SP-800-73-4, Appendix A, Table 9
|
* Format defined in SP-800-73-4, Appendix A, Table 9
|
||||||
*
|
*
|
||||||
@@ -55,7 +59,7 @@
|
|||||||
* - 0x3e: Signature (hard-coded, empty)
|
* - 0x3e: Signature (hard-coded, empty)
|
||||||
* - 0xfe: Error Detection Code (hard-coded)
|
* - 0xfe: Error Detection Code (hard-coded)
|
||||||
*/
|
*/
|
||||||
const uint8_t CHUID_TMPL[] = {
|
const uint8_t *CHUID_TMPL = {
|
||||||
0x30, 0x19, 0xd4, 0xe7, 0x39, 0xda, 0x73, 0x9c, 0xed, 0x39, 0xce, 0x73, 0x9d,
|
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,
|
0x83, 0x68, 0x58, 0x21, 0x08, 0x42, 0x10, 0x84, 0x21, 0xc8, 0x42, 0x10, 0xc3,
|
||||||
0xeb, 0x34, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xeb, 0x34, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -69,7 +73,7 @@ const uint8_t CHUID_TMPL[] = {
|
|||||||
// - 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
|
||||||
const uint8_t CCC_TMPL[] = {
|
const uint8_t *CCC_TMPL = {
|
||||||
0xf0, 0x15, 0xa0, 0x00, 0x00, 0x01, 0x16, 0xff, 0x02, 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,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x01, 0x21,
|
||||||
0xf2, 0x01, 0x21, 0xf3, 0x00, 0xf4, 0x01, 0x00, 0xf5, 0x01, 0x10, 0xf6, 0x00,
|
0xf2, 0x01, 0x21, 0xf3, 0x00, 0xf4, 0x01, 0x00, 0xf5, 0x01, 0x10, 0xf6, 0x00,
|
||||||
@@ -105,7 +109,7 @@ ykpiv_rc ykpiv_util_get_cardid(ykpiv_state *state, ykpiv_cardid *cardid) {
|
|||||||
|
|
||||||
res = _ykpiv_fetch_object(state, YKPIV_OBJ_CHUID, buf, (unsigned long *)&len);
|
res = _ykpiv_fetch_object(state, YKPIV_OBJ_CHUID, buf, (unsigned long *)&len);
|
||||||
if (YKPIV_OK == res) {
|
if (YKPIV_OK == res) {
|
||||||
if (len != sizeof(CHUID_TMPL)) {
|
if (len != SIZEOF_CHUID_TMPL) {
|
||||||
res = YKPIV_GENERIC_ERROR;
|
res = YKPIV_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -122,7 +126,7 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_util_set_cardid(ykpiv_state *state, const ykpiv_cardid *cardid) {
|
ykpiv_rc ykpiv_util_set_cardid(ykpiv_state *state, const ykpiv_cardid *cardid) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t id[YKPIV_CARDID_SIZE];
|
uint8_t id[YKPIV_CARDID_SIZE];
|
||||||
uint8_t buf[sizeof(CHUID_TMPL)];
|
uint8_t buf[SIZEOF_CHUID_TMPL];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (!state) return YKPIV_GENERIC_ERROR;
|
if (!state) return YKPIV_GENERIC_ERROR;
|
||||||
@@ -139,9 +143,9 @@ ykpiv_rc ykpiv_util_set_cardid(ykpiv_state *state, const ykpiv_cardid *cardid) {
|
|||||||
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
||||||
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
||||||
|
|
||||||
memcpy(buf, CHUID_TMPL, sizeof(CHUID_TMPL));
|
memcpy(buf, CHUID_TMPL, SIZEOF_CHUID_TMPL);
|
||||||
memcpy(buf + CHUID_GUID_OFFS, id, sizeof(id));
|
memcpy(buf + CHUID_GUID_OFFS, id, sizeof(id));
|
||||||
len = sizeof(CHUID_TMPL);
|
len = SIZEOF_CHUID_TMPL;
|
||||||
|
|
||||||
res = _ykpiv_save_object(state, YKPIV_OBJ_CHUID, buf, len);
|
res = _ykpiv_save_object(state, YKPIV_OBJ_CHUID, buf, len);
|
||||||
|
|
||||||
@@ -163,7 +167,7 @@ ykpiv_rc ykpiv_util_get_cccid(ykpiv_state *state, ykpiv_cccid *ccc) {
|
|||||||
|
|
||||||
res = _ykpiv_fetch_object(state, YKPIV_OBJ_CAPABILITY, buf, (unsigned long *)&len);
|
res = _ykpiv_fetch_object(state, YKPIV_OBJ_CAPABILITY, buf, (unsigned long *)&len);
|
||||||
if (YKPIV_OK == res) {
|
if (YKPIV_OK == res) {
|
||||||
if (len != sizeof(CCC_TMPL)) {
|
if (len != SIZEOF_CCC_TMPL) {
|
||||||
res = YKPIV_GENERIC_ERROR;
|
res = YKPIV_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -180,7 +184,7 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_util_set_cccid(ykpiv_state *state, const ykpiv_cccid *ccc) {
|
ykpiv_rc ykpiv_util_set_cccid(ykpiv_state *state, const ykpiv_cccid *ccc) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t id[YKPIV_CCCID_SIZE];
|
uint8_t id[YKPIV_CCCID_SIZE];
|
||||||
uint8_t buf[sizeof(CCC_TMPL)];
|
uint8_t buf[SIZEOF_CCC_TMPL];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (!state) return YKPIV_GENERIC_ERROR;
|
if (!state) return YKPIV_GENERIC_ERROR;
|
||||||
@@ -197,7 +201,7 @@ ykpiv_rc ykpiv_util_set_cccid(ykpiv_state *state, const ykpiv_cccid *ccc) {
|
|||||||
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
||||||
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
||||||
|
|
||||||
len = sizeof(CCC_TMPL);
|
len = SIZEOF_CCC_TMPL;
|
||||||
memcpy(buf, CCC_TMPL, len);
|
memcpy(buf, CCC_TMPL, len);
|
||||||
memcpy(buf + CCC_ID_OFFS, id, YKPIV_CCCID_SIZE);
|
memcpy(buf + CCC_ID_OFFS, id, YKPIV_CCCID_SIZE);
|
||||||
res = _ykpiv_save_object(state, YKPIV_OBJ_CAPABILITY, buf, len);
|
res = _ykpiv_save_object(state, YKPIV_OBJ_CAPABILITY, buf, len);
|
||||||
@@ -228,7 +232,7 @@ ykpiv_rc ykpiv_util_list_keys(ykpiv_state *state, uint8_t *key_count, ykpiv_key
|
|||||||
|
|
||||||
const size_t CB_PAGE = 4096;
|
const size_t CB_PAGE = 4096;
|
||||||
|
|
||||||
const uint8_t SLOTS[] = {
|
const uint8_t *SLOTS = {
|
||||||
YKPIV_KEY_AUTHENTICATION,
|
YKPIV_KEY_AUTHENTICATION,
|
||||||
YKPIV_KEY_SIGNATURE,
|
YKPIV_KEY_SIGNATURE,
|
||||||
YKPIV_KEY_KEYMGM,
|
YKPIV_KEY_KEYMGM,
|
||||||
@@ -393,7 +397,7 @@ ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot) {
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state) {
|
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t puk[] = { 0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44 };
|
uint8_t *puk = { 0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44 };
|
||||||
int tries = -1;
|
int tries = -1;
|
||||||
uint8_t data[CB_BUF_MAX];
|
uint8_t data[CB_BUF_MAX];
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
@@ -716,7 +720,7 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
|
|||||||
unsigned char in_data[11];
|
unsigned char in_data[11];
|
||||||
unsigned char *in_ptr = in_data;
|
unsigned char *in_ptr = in_data;
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
unsigned char templ[] = { 0, YKPIV_INS_GENERATE_ASYMMETRIC, 0, 0 };
|
unsigned char *templ = { 0, YKPIV_INS_GENERATE_ASYMMETRIC, 0, 0 };
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
int sw;
|
int sw;
|
||||||
uint8_t *ptr_modulus = NULL;
|
uint8_t *ptr_modulus = NULL;
|
||||||
@@ -726,17 +730,17 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
|
|||||||
uint8_t *ptr_point = NULL;
|
uint8_t *ptr_point = NULL;
|
||||||
size_t cb_point = 0;
|
size_t cb_point = 0;
|
||||||
|
|
||||||
setting_bool_t setting_roca = { 0 };
|
setting_bool_t setting_roca; /* XXX was 0 */
|
||||||
const char sz_setting_roca[] = "Enable_Unsafe_Keygen_ROCA";
|
const char *sz_setting_roca = "Enable_Unsafe_Keygen_ROCA";
|
||||||
const char sz_roca_format[] = "YubiKey serial number %u is affected by vulnerability "
|
const char *sz_roca_format = "YubiKey serial number %u is affected by vulnerability "
|
||||||
"CVE-2017-15361 (ROCA) and should be replaced. On-chip key generation %s "
|
"CVE-2017-15361 (ROCA) and should be replaced. On-chip key generation %s "
|
||||||
"See YSA-2017-01 <https://www.yubico.com/support/security-advisories/ysa-2017-01/> "
|
"See YSA-2017-01 <https://www.yubico.com/support/security-advisories/ysa-2017-01/> "
|
||||||
"for additional information on device replacement and mitigation assistance.\n";
|
"for additional information on device replacement and mitigation assistance.\n";
|
||||||
const char sz_roca_allow_user[] = "was permitted by an end-user configuration setting, but is not recommended.";
|
const char *sz_roca_allow_user = "was permitted by an end-user configuration setting, but is not recommended.";
|
||||||
const char sz_roca_allow_admin[] = "was permitted by an administrator configuration setting, but is not recommended.";
|
const char *sz_roca_allow_admin = "was permitted by an administrator configuration setting, but is not recommended.";
|
||||||
const char sz_roca_block_user[] = "was blocked due to an end-user configuration setting.";
|
const char *sz_roca_block_user = "was blocked due to an end-user configuration setting.";
|
||||||
const char sz_roca_block_admin[] = "was blocked due to an administrator configuration setting.";
|
const char *sz_roca_block_admin = "was blocked due to an administrator configuration setting.";
|
||||||
const char sz_roca_default[] = "was permitted by default, but is not recommended. "
|
const char *sz_roca_default = "was permitted by default, but is not recommended. "
|
||||||
"The default behavior will change in a future Yubico release.";
|
"The default behavior will change in a future Yubico release.";
|
||||||
|
|
||||||
if (!state) return YKPIV_ARGUMENT_ERROR;
|
if (!state) return YKPIV_ARGUMENT_ERROR;
|
||||||
@@ -762,7 +766,7 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, sz_roca_format, state->serial, psz_msg);
|
fprintf(stderr, sz_roca_format, state->serial, psz_msg);
|
||||||
yc_log_event(1, setting_roca.value ? YC_LOG_LEVEL_WARN : YC_LOG_LEVEL_ERROR, sz_roca_format, state->serial, psz_msg);
|
//yc_log_event(1, setting_roca.value ? YC_LOG_LEVEL_WARN : YC_LOG_LEVEL_ERROR, sz_roca_format, state->serial, psz_msg);
|
||||||
|
|
||||||
if (!setting_roca.value) {
|
if (!setting_roca.value) {
|
||||||
return YKPIV_NOT_SUPPORTED;
|
return YKPIV_NOT_SUPPORTED;
|
||||||
@@ -974,7 +978,7 @@ Cleanup:
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_util_get_config(ykpiv_state *state, ykpiv_config *config) {
|
ykpiv_rc ykpiv_util_get_config(ykpiv_state *state, ykpiv_config *config) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t data[CB_BUF_MAX] = { 0 };
|
uint8_t data[CB_BUF_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
uint8_t *p_item = NULL;
|
uint8_t *p_item = NULL;
|
||||||
size_t cb_item = 0;
|
size_t cb_item = 0;
|
||||||
@@ -1052,7 +1056,7 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_util_set_pin_last_changed(ykpiv_state *state) {
|
ykpiv_rc ykpiv_util_set_pin_last_changed(ykpiv_state *state) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
ykpiv_rc ykrc = YKPIV_OK;
|
ykpiv_rc ykrc = YKPIV_OK;
|
||||||
uint8_t data[CB_BUF_MAX] = { 0 };
|
uint8_t data[CB_BUF_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
time_t tnow = 0;
|
time_t tnow = 0;
|
||||||
|
|
||||||
@@ -1087,7 +1091,7 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_util_get_derived_mgm(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, ykpiv_mgm *mgm) {
|
ykpiv_rc ykpiv_util_get_derived_mgm(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, ykpiv_mgm *mgm) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
pkcs5_rc p5rc = PKCS5_OK;
|
pkcs5_rc p5rc = PKCS5_OK;
|
||||||
uint8_t data[CB_BUF_MAX] = { 0 };
|
uint8_t data[CB_BUF_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
uint8_t *p_item = NULL;
|
uint8_t *p_item = NULL;
|
||||||
size_t cb_item = 0;
|
size_t cb_item = 0;
|
||||||
@@ -1123,7 +1127,7 @@ Cleanup:
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_util_get_protected_mgm(ykpiv_state *state, ykpiv_mgm *mgm) {
|
ykpiv_rc ykpiv_util_get_protected_mgm(ykpiv_state *state, ykpiv_mgm *mgm) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t data[CB_BUF_MAX] = { 0 };
|
uint8_t data[CB_BUF_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
uint8_t *p_item = NULL;
|
uint8_t *p_item = NULL;
|
||||||
size_t cb_item = 0;
|
size_t cb_item = 0;
|
||||||
@@ -1167,9 +1171,9 @@ ykpiv_rc ykpiv_util_set_protected_mgm(ykpiv_state *state, ykpiv_mgm *mgm) {
|
|||||||
ykpiv_rc ykrc = YKPIV_OK;
|
ykpiv_rc ykrc = YKPIV_OK;
|
||||||
prng_rc prngrc = PRNG_OK;
|
prng_rc prngrc = PRNG_OK;
|
||||||
bool fGenerate = false;
|
bool fGenerate = false;
|
||||||
uint8_t mgm_key[member_size(ykpiv_mgm, data)] = { 0 };
|
uint8_t mgm_key[24];
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
uint8_t data[CB_BUF_MAX] = { 0 };
|
uint8_t data[CB_BUF_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
size_t cb_data = sizeof(data);
|
size_t cb_data = sizeof(data);
|
||||||
uint8_t *p_item = NULL;
|
uint8_t *p_item = NULL;
|
||||||
size_t cb_item = 0;
|
size_t cb_item = 0;
|
||||||
@@ -1295,7 +1299,7 @@ Cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_util_reset(ykpiv_state *state) {
|
ykpiv_rc ykpiv_util_reset(ykpiv_state *state) {
|
||||||
unsigned char templ[] = {0, YKPIV_INS_RESET, 0, 0};
|
unsigned char *templ = {0, YKPIV_INS_RESET, 0, 0};
|
||||||
unsigned char data[0xff];
|
unsigned char data[0xff];
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
@@ -1645,7 +1649,7 @@ static ykpiv_rc _read_metadata(ykpiv_state *state, uint8_t tag, uint8_t* data, s
|
|||||||
*/
|
*/
|
||||||
static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data, size_t cb_data) {
|
static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data, size_t cb_data) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
uint8_t buf[CB_OBJ_MAX] = { 0 };
|
uint8_t buf[CB_OBJ_MAX]; /* XXX REMEMBER TO ZERO */
|
||||||
uint8_t *pTemp = buf;
|
uint8_t *pTemp = buf;
|
||||||
int obj_id = 0;
|
int obj_id = 0;
|
||||||
|
|
||||||
|
|||||||
+3214
File diff suppressed because it is too large
Load Diff
+169
@@ -0,0 +1,169 @@
|
|||||||
|
extern {
|
||||||
|
fn strcmp(__s1 : *const u8, __s2 : *const u8) -> i32;
|
||||||
|
fn strcspn(__s : *const u8, __charset : *const u8) -> usize;
|
||||||
|
fn strncmp(__s1 : *const u8, __s2 : *const u8, __n : usize) -> i32;
|
||||||
|
fn strspn(__s : *const u8, __charset : *const u8) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern fn my_strverscmp(
|
||||||
|
mut s1 : *const u8, mut s2 : *const u8
|
||||||
|
) -> i32 {
|
||||||
|
let mut _currentBlock;
|
||||||
|
static mut digits : *const u8 = (*b"0123456789\0").as_ptr();
|
||||||
|
let mut p1 : usize;
|
||||||
|
let mut p2 : usize;
|
||||||
|
p1 = strcspn(s1,digits);
|
||||||
|
p2 = strcspn(s2,digits);
|
||||||
|
'loop1: loop {
|
||||||
|
if !(p1 == p2 && (*s1.offset(
|
||||||
|
p1 as (isize)
|
||||||
|
) as (i32) != b'\0' as (i32)) && (*s2.offset(
|
||||||
|
p2 as (isize)
|
||||||
|
) as (i32) != b'\0' as (i32))) {
|
||||||
|
_currentBlock = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut ret : i32;
|
||||||
|
let mut lz1 : i32;
|
||||||
|
let mut lz2 : i32;
|
||||||
|
if {
|
||||||
|
ret = strncmp(s1,s2,p1);
|
||||||
|
ret
|
||||||
|
} != 0i32 {
|
||||||
|
_currentBlock = 37;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s1 = s1.offset(p1 as (isize));
|
||||||
|
s2 = s2.offset(p2 as (isize));
|
||||||
|
lz1 = {
|
||||||
|
lz2 = 0i32;
|
||||||
|
lz2
|
||||||
|
};
|
||||||
|
if *s1 as (i32) == b'0' as (i32) {
|
||||||
|
lz1 = 1i32;
|
||||||
|
}
|
||||||
|
if *s2 as (i32) == b'0' as (i32) {
|
||||||
|
lz2 = 1i32;
|
||||||
|
}
|
||||||
|
if lz1 > lz2 {
|
||||||
|
_currentBlock = 36;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if lz1 < lz2 {
|
||||||
|
_currentBlock = 35;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if lz1 == 1i32 {
|
||||||
|
_currentBlock = 11;
|
||||||
|
} else {
|
||||||
|
_currentBlock = 23;
|
||||||
|
}
|
||||||
|
'loop11: loop {
|
||||||
|
if _currentBlock == 11 {
|
||||||
|
if *s1 as (i32) == b'0' as (i32) && (*s2 as (i32) == b'0' as (i32)) {
|
||||||
|
s1 = s1.offset(1isize);
|
||||||
|
s2 = s2.offset(1isize);
|
||||||
|
_currentBlock = 11;
|
||||||
|
} else {
|
||||||
|
p1 = strspn(s1,digits);
|
||||||
|
p2 = strspn(s2,digits);
|
||||||
|
if p1 == 0usize && (p2 > 0usize) {
|
||||||
|
_currentBlock = 33;
|
||||||
|
break 'loop1;
|
||||||
|
}
|
||||||
|
if p2 == 0usize && (p1 > 0usize) {
|
||||||
|
_currentBlock = 32;
|
||||||
|
break 'loop1;
|
||||||
|
}
|
||||||
|
if *s1 as (i32) != *s2 as (i32) && (*s1 as (i32) != b'0' as (i32)) && (*s2 as (i32) != b'0' as (i32)) {
|
||||||
|
if p1 < p2 {
|
||||||
|
_currentBlock = 31;
|
||||||
|
break 'loop1;
|
||||||
|
}
|
||||||
|
if p1 > p2 {
|
||||||
|
_currentBlock = 30;
|
||||||
|
break 'loop1;
|
||||||
|
} else {
|
||||||
|
_currentBlock = 23;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if p1 < p2 {
|
||||||
|
ret = strncmp(s1,s2,p1);
|
||||||
|
} else if p1 > p2 {
|
||||||
|
ret = strncmp(s1,s2,p2);
|
||||||
|
}
|
||||||
|
if ret != 0i32 {
|
||||||
|
_currentBlock = 20;
|
||||||
|
break 'loop1;
|
||||||
|
} else {
|
||||||
|
_currentBlock = 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p1 = strspn(s1,digits);
|
||||||
|
p2 = strspn(s2,digits);
|
||||||
|
if p1 < p2 {
|
||||||
|
_currentBlock = 29;
|
||||||
|
break 'loop1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p1 > p2 {
|
||||||
|
_currentBlock = 28;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if {
|
||||||
|
ret = strncmp(s1,s2,p1);
|
||||||
|
ret
|
||||||
|
} != 0i32 {
|
||||||
|
_currentBlock = 27;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s1 = s1.offset(p1 as (isize));
|
||||||
|
s2 = s2.offset(p2 as (isize));
|
||||||
|
p1 = strcspn(s1,digits);
|
||||||
|
p2 = strcspn(s2,digits);
|
||||||
|
}
|
||||||
|
if _currentBlock == 2 {
|
||||||
|
strcmp(s1,s2)
|
||||||
|
} else if _currentBlock == 20 {
|
||||||
|
ret
|
||||||
|
} else if _currentBlock == 27 {
|
||||||
|
ret
|
||||||
|
} else if _currentBlock == 28 {
|
||||||
|
1i32
|
||||||
|
} else if _currentBlock == 29 {
|
||||||
|
-1i32
|
||||||
|
} else if _currentBlock == 30 {
|
||||||
|
-1i32
|
||||||
|
} else if _currentBlock == 31 {
|
||||||
|
1i32
|
||||||
|
} else if _currentBlock == 32 {
|
||||||
|
-1i32
|
||||||
|
} else if _currentBlock == 33 {
|
||||||
|
1i32
|
||||||
|
} else if _currentBlock == 35 {
|
||||||
|
1i32
|
||||||
|
} else if _currentBlock == 36 {
|
||||||
|
-1i32
|
||||||
|
} else {
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn ykpiv_check_version(
|
||||||
|
mut req_version : *const u8
|
||||||
|
) -> *const u8 {
|
||||||
|
if req_version.is_null() || my_strverscmp(
|
||||||
|
req_version,
|
||||||
|
(*b"@VERSION@\0").as_ptr()
|
||||||
|
) <= 0i32 {
|
||||||
|
(*b"@VERSION@\0").as_ptr()
|
||||||
|
} else {
|
||||||
|
0i32 as (*mut ::std::os::raw::c_void) as (*const u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef YKPIV_VERSION_H
|
||||||
|
#define YKPIV_VERSION_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YKPIV_VERSION_STRING
|
||||||
|
*
|
||||||
|
* Pre-processor symbol with a string that describe the header file
|
||||||
|
* version number. Used together with ykneomgr_check_version() to verify
|
||||||
|
* header file and run-time library consistency.
|
||||||
|
*/
|
||||||
|
#define YKPIV_VERSION_STRING "@VERSION@"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YKPIV_VERSION_NUMBER
|
||||||
|
*
|
||||||
|
* Pre-processor symbol with a hexadecimal value describing the header
|
||||||
|
* file version number. For example, when the header version is 1.2.3
|
||||||
|
* this symbol will have the value 0x01020300. The last two digits
|
||||||
|
* are only used between public releases, and will otherwise be 00.
|
||||||
|
*/
|
||||||
|
#define YKPIV_VERSION_NUMBER @YKPIV_VERSION_NUMBER@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YKPIV_VERSION_MAJOR
|
||||||
|
*
|
||||||
|
* Pre-processor symbol with a decimal value that describe the major
|
||||||
|
* level of the header file version number. For example, when the
|
||||||
|
* header version is 1.2.3 this symbol will be 1.
|
||||||
|
*/
|
||||||
|
#define YKPIV_VERSION_MAJOR @YKPIV_VERSION_MAJOR@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YKPIV_VERSION_MINOR
|
||||||
|
*
|
||||||
|
* Pre-processor symbol with a decimal value that describe the minor
|
||||||
|
* level of the header file version number. For example, when the
|
||||||
|
* header version is 1.2.3 this symbol will be 2.
|
||||||
|
*/
|
||||||
|
#define YKPIV_VERSION_MINOR @YKPIV_VERSION_MINOR@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YKPIV_VERSION_PATCH
|
||||||
|
*
|
||||||
|
* Pre-processor symbol with a decimal value that describe the patch
|
||||||
|
* level of the header file version number. For example, when the
|
||||||
|
* header version is 1.2.3 this symbol will be 3.
|
||||||
|
*/
|
||||||
|
#define YKPIV_VERSION_PATCH @YKPIV_VERSION_PATCH@
|
||||||
|
|
||||||
|
const char *ykpiv_check_version (const char *req_version);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
+78
-32
@@ -105,7 +105,7 @@ static ykpiv_rc _cache_pin(ykpiv_state *state, const char *pin, size_t len);
|
|||||||
static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool force);
|
static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool force);
|
||||||
static ykpiv_rc _ykpiv_get_version(ykpiv_state *state, ykpiv_version_t *p_version);
|
static ykpiv_rc _ykpiv_get_version(ykpiv_state *state, ykpiv_version_t *p_version);
|
||||||
|
|
||||||
static unsigned const char aid[] = {
|
static unsigned const char *aid = {
|
||||||
0xa0, 0x00, 0x00, 0x03, 0x08
|
0xa0, 0x00, 0x00, 0x03, 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -277,11 +277,14 @@ ykpiv_rc _ykpiv_select_application(ykpiv_state *state) {
|
|||||||
int sw;
|
int sw;
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
||||||
apdu.st.p1 = 0x04;
|
apdu.st.p1 = 0x04;
|
||||||
apdu.st.lc = sizeof(aid);
|
apdu.st.lc = sizeof(aid);
|
||||||
memcpy(apdu.st.data, aid, sizeof(aid));
|
memcpy(apdu.st.data, aid, sizeof(aid));
|
||||||
|
*/
|
||||||
|
|
||||||
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
@@ -591,6 +594,8 @@ ykpiv_rc _ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
|||||||
uint32_t recv_len = sizeof(data);
|
uint32_t recv_len = sizeof(data);
|
||||||
APDU apdu;
|
APDU apdu;
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||||
memcpy(apdu.raw, templ, 4);
|
memcpy(apdu.raw, templ, 4);
|
||||||
if(in_ptr + 0xff < in_data + in_len) {
|
if(in_ptr + 0xff < in_data + in_len) {
|
||||||
@@ -598,11 +603,15 @@ ykpiv_rc _ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
|||||||
} else {
|
} else {
|
||||||
this_size = (size_t)((in_data + in_len) - in_ptr);
|
this_size = (size_t)((in_data + in_len) - in_ptr);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if(state->verbose > 2) {
|
if(state->verbose > 2) {
|
||||||
fprintf(stderr, "Going to send %lu bytes in this go.\n", (unsigned long)this_size);
|
fprintf(stderr, "Going to send %lu bytes in this go.\n", (unsigned long)this_size);
|
||||||
}
|
}
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
apdu.st.lc = (unsigned char)this_size;
|
apdu.st.lc = (unsigned char)this_size;
|
||||||
memcpy(apdu.st.data, in_ptr, this_size);
|
memcpy(apdu.st.data, in_ptr, this_size);
|
||||||
|
*/
|
||||||
res = _send_data(state, &apdu, data, &recv_len, sw);
|
res = _send_data(state, &apdu, data, &recv_len, sw);
|
||||||
if(res != YKPIV_OK) {
|
if(res != YKPIV_OK) {
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
@@ -632,8 +641,11 @@ ykpiv_rc _ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
|||||||
fprintf(stderr, "The card indicates there is %d bytes more data for us.\n", *sw & 0xff);
|
fprintf(stderr, "The card indicates there is %d bytes more data for us.\n", *sw & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||||
apdu.st.ins = YKPIV_INS_GET_RESPONSE_APDU;
|
apdu.st.ins = YKPIV_INS_GET_RESPONSE_APDU;
|
||||||
|
*/
|
||||||
res = _send_data(state, &apdu, data, &recv_len, sw);
|
res = _send_data(state, &apdu, data, &recv_len, sw);
|
||||||
if(res != YKPIV_OK) {
|
if(res != YKPIV_OK) {
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
@@ -674,14 +686,17 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
|||||||
ykpiv_rc _send_data(ykpiv_state *state, APDU *apdu,
|
ykpiv_rc _send_data(ykpiv_state *state, APDU *apdu,
|
||||||
unsigned char *data, uint32_t *recv_len, int *sw) {
|
unsigned char *data, uint32_t *recv_len, int *sw) {
|
||||||
long rc;
|
long rc;
|
||||||
unsigned int send_len = (unsigned int)apdu->st.lc + 5;
|
unsigned int send_len = 0; /* XXX FIX THIS!!! (unsigned int)apdu->st.lc + 5; */
|
||||||
pcsc_word tmp_len = *recv_len;
|
pcsc_word tmp_len = *recv_len;
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
if(state->verbose > 1) {
|
if(state->verbose > 1) {
|
||||||
fprintf(stderr, "> ");
|
fprintf(stderr, "> ");
|
||||||
dump_hex(apdu->raw, send_len);
|
dump_hex(apdu->raw, send_len);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SCardTransmit(state->card, SCARD_PCI_T1, apdu->raw, send_len, NULL, data, &tmp_len);
|
rc = SCardTransmit(state->card, SCARD_PCI_T1, apdu->raw, send_len, NULL, data, &tmp_len);
|
||||||
if(rc != SCARD_S_SUCCESS) {
|
if(rc != SCARD_S_SUCCESS) {
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
@@ -689,6 +704,7 @@ ykpiv_rc _send_data(ykpiv_state *state, APDU *apdu,
|
|||||||
}
|
}
|
||||||
return YKPIV_PCSC_ERROR;
|
return YKPIV_PCSC_ERROR;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
*recv_len = (uint32_t)tmp_len;
|
*recv_len = (uint32_t)tmp_len;
|
||||||
|
|
||||||
if(state->verbose > 1) {
|
if(state->verbose > 1) {
|
||||||
@@ -732,11 +748,13 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get a challenge from the card */
|
/* get a challenge from the card */
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
||||||
apdu.st.p1 = YKPIV_ALGO_3DES; /* triple des */
|
apdu.st.p1 = YKPIV_ALGO_3DES; // triple des
|
||||||
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
|
apdu.st.p2 = YKPIV_KEY_CARDMGM; // management key
|
||||||
apdu.st.lc = 0x04;
|
apdu.st.lc = 0x04;
|
||||||
apdu.st.data[0] = 0x7c;
|
apdu.st.data[0] = 0x7c;
|
||||||
apdu.st.data[1] = 0x02;
|
apdu.st.data[1] = 0x02;
|
||||||
@@ -749,9 +767,11 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
|
|||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
memcpy(challenge, data + 4, 8);
|
memcpy(challenge, data + 4, 8);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
unsigned char *dataptr = apdu.st.data;
|
unsigned char *dataptr = apdu.st.data;
|
||||||
unsigned char response[8];
|
unsigned char response[8];
|
||||||
@@ -766,10 +786,10 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
|
|||||||
recv_len = sizeof(data);
|
recv_len = sizeof(data);
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
||||||
apdu.st.p1 = YKPIV_ALGO_3DES; /* triple des */
|
apdu.st.p1 = YKPIV_ALGO_3DES; // triple des
|
||||||
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
|
apdu.st.p2 = YKPIV_KEY_CARDMGM; // management key
|
||||||
*dataptr++ = 0x7c;
|
*dataptr++ = 0x7c;
|
||||||
*dataptr++ = 20; /* 2 + 8 + 2 +8 */
|
*dataptr++ = 20; // 2 + 8 + 2 +8
|
||||||
*dataptr++ = 0x80;
|
*dataptr++ = 0x80;
|
||||||
*dataptr++ = 8;
|
*dataptr++ = 8;
|
||||||
memcpy(dataptr, response, 8);
|
memcpy(dataptr, response, 8);
|
||||||
@@ -794,6 +814,7 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
|
|||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* compare the response from the card with our challenge */
|
/* compare the response from the card with our challenge */
|
||||||
{
|
{
|
||||||
@@ -848,6 +869,8 @@ ykpiv_rc ykpiv_set_mgmkey2(ykpiv_state *state, const unsigned char *new_key, con
|
|||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_SET_MGMKEY;
|
apdu.st.ins = YKPIV_INS_SET_MGMKEY;
|
||||||
apdu.st.p1 = 0xff;
|
apdu.st.p1 = 0xff;
|
||||||
@@ -867,6 +890,7 @@ ykpiv_rc ykpiv_set_mgmkey2(ykpiv_state *state, const unsigned char *new_key, con
|
|||||||
apdu.st.data[1] = YKPIV_KEY_CARDMGM;
|
apdu.st.data[1] = YKPIV_KEY_CARDMGM;
|
||||||
apdu.st.data[2] = DES_LEN_3DES;
|
apdu.st.data[2] = DES_LEN_3DES;
|
||||||
memcpy(apdu.st.data + 3, new_key, DES_LEN_3DES);
|
memcpy(apdu.st.data + 3, new_key, DES_LEN_3DES);
|
||||||
|
*/
|
||||||
|
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
@@ -882,7 +906,7 @@ Cleanup:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char hex_translate[] = "0123456789abcdef";
|
static char *hex_translate = "0123456789abcdef";
|
||||||
|
|
||||||
ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
|
ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
|
||||||
unsigned char *hex_out, size_t *out_len) {
|
unsigned char *hex_out, size_t *out_len) {
|
||||||
@@ -920,7 +944,7 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
|||||||
unsigned char indata[1024];
|
unsigned char indata[1024];
|
||||||
unsigned char *dataptr = indata;
|
unsigned char *dataptr = indata;
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
unsigned char templ[] = {0, YKPIV_INS_AUTHENTICATE, algorithm, key};
|
unsigned char *templ = {0, YKPIV_INS_AUTHENTICATE, algorithm, key};
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
size_t key_len = 0;
|
size_t key_len = 0;
|
||||||
int sw = 0;
|
int sw = 0;
|
||||||
@@ -1078,9 +1102,11 @@ static ykpiv_rc _ykpiv_get_version(ykpiv_state *state, ykpiv_version_t *p_versio
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get version from device */
|
/* get version from device */
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_GET_VERSION;
|
apdu.st.ins = YKPIV_INS_GET_VERSION;
|
||||||
|
*/
|
||||||
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
return res;
|
return res;
|
||||||
} else if(sw == SW_SUCCESS) {
|
} else if(sw == SW_SUCCESS) {
|
||||||
@@ -1128,7 +1154,7 @@ Cleanup:
|
|||||||
static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f_force) {
|
static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f_force) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
APDU apdu;
|
APDU apdu;
|
||||||
const uint8_t yk_applet[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01 };
|
const uint8_t *yk_applet = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01 };
|
||||||
unsigned char data[0xff];
|
unsigned char data[0xff];
|
||||||
uint32_t recv_len = sizeof(data);
|
uint32_t recv_len = sizeof(data);
|
||||||
int sw;
|
int sw;
|
||||||
@@ -1148,11 +1174,12 @@ static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f
|
|||||||
uint8_t temp[0xff];
|
uint8_t temp[0xff];
|
||||||
|
|
||||||
recv_len = sizeof(temp);
|
recv_len = sizeof(temp);
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
/* XXX FIX THIS!!! */
|
||||||
|
/*memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
||||||
apdu.st.p1 = 0x04;
|
apdu.st.p1 = 0x04;
|
||||||
apdu.st.lc = sizeof(yk_applet);
|
apdu.st.lc = sizeof(yk_applet);
|
||||||
memcpy(apdu.st.data, yk_applet, sizeof(yk_applet));
|
memcpy(apdu.st.data, yk_applet, sizeof(yk_applet));*/
|
||||||
|
|
||||||
if ((res = _send_data(state, &apdu, temp, &recv_len, &sw)) < YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, temp, &recv_len, &sw)) < YKPIV_OK) {
|
||||||
if (state->verbose) {
|
if (state->verbose) {
|
||||||
@@ -1169,10 +1196,13 @@ static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f
|
|||||||
}
|
}
|
||||||
|
|
||||||
recv_len = sizeof(data);
|
recv_len = sizeof(data);
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = 0x01;
|
apdu.st.ins = 0x01;
|
||||||
apdu.st.p1 = 0x10;
|
apdu.st.p1 = 0x10;
|
||||||
apdu.st.lc = 0x00;
|
apdu.st.lc = 0x00;
|
||||||
|
*/
|
||||||
|
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) < YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) < YKPIV_OK) {
|
||||||
if (state->verbose) {
|
if (state->verbose) {
|
||||||
@@ -1189,11 +1219,14 @@ static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f
|
|||||||
}
|
}
|
||||||
|
|
||||||
recv_len = sizeof(temp);
|
recv_len = sizeof(temp);
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
||||||
apdu.st.p1 = 0x04;
|
apdu.st.p1 = 0x04;
|
||||||
apdu.st.lc = (unsigned char)sizeof(aid);
|
apdu.st.lc = (unsigned char)sizeof(aid);
|
||||||
memcpy(apdu.st.data, aid, sizeof(aid));
|
memcpy(apdu.st.data, aid, sizeof(aid));
|
||||||
|
*/
|
||||||
|
|
||||||
if((res = _send_data(state, &apdu, temp, &recv_len, &sw)) < YKPIV_OK) {
|
if((res = _send_data(state, &apdu, temp, &recv_len, &sw)) < YKPIV_OK) {
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
@@ -1211,8 +1244,9 @@ static ykpiv_rc _ykpiv_get_serial(ykpiv_state *state, uint32_t *p_serial, bool f
|
|||||||
else {
|
else {
|
||||||
/* get serial from yk5 and later devices using the f8 command */
|
/* get serial from yk5 and later devices using the f8 command */
|
||||||
|
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
/* XXX FIX THIS!!! */
|
||||||
apdu.st.ins = YKPIV_INS_GET_SERIAL;
|
/*memset(apdu.raw, 0, sizeof(apdu));
|
||||||
|
apdu.st.ins = YKPIV_INS_GET_SERIAL;*/
|
||||||
|
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
@@ -1300,6 +1334,8 @@ static ykpiv_rc _verify(ykpiv_state *state, const char *pin, const size_t pin_le
|
|||||||
return YKPIV_SIZE_ERROR;
|
return YKPIV_SIZE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||||
apdu.st.ins = YKPIV_INS_VERIFY;
|
apdu.st.ins = YKPIV_INS_VERIFY;
|
||||||
apdu.st.p1 = 0x00;
|
apdu.st.p1 = 0x00;
|
||||||
@@ -1310,7 +1346,7 @@ static ykpiv_rc _verify(ykpiv_state *state, const char *pin, const size_t pin_le
|
|||||||
if (pin_len < CB_PIN_MAX) {
|
if (pin_len < CB_PIN_MAX) {
|
||||||
memset(apdu.st.data + pin_len, 0xff, CB_PIN_MAX - pin_len);
|
memset(apdu.st.data + pin_len, 0xff, CB_PIN_MAX - pin_len);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
res = _send_data(state, &apdu, data, &recv_len, &sw);
|
res = _send_data(state, &apdu, data, &recv_len, &sw);
|
||||||
yc_memzero(&apdu, sizeof(apdu));
|
yc_memzero(&apdu, sizeof(apdu));
|
||||||
@@ -1377,7 +1413,7 @@ ykpiv_rc ykpiv_get_pin_retries(ykpiv_state *state, int *tries) {
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_set_pin_retries(ykpiv_state *state, int pin_tries, int puk_tries) {
|
ykpiv_rc ykpiv_set_pin_retries(ykpiv_state *state, int pin_tries, int puk_tries) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_SET_PIN_RETRIES, 0, 0};
|
unsigned char *templ = {0, YKPIV_INS_SET_PIN_RETRIES, 0, 0};
|
||||||
unsigned char data[0xff];
|
unsigned char data[0xff];
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
int sw = 0;
|
int sw = 0;
|
||||||
@@ -1417,7 +1453,7 @@ Cleanup:
|
|||||||
|
|
||||||
static ykpiv_rc _ykpiv_change_pin(ykpiv_state *state, int action, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
static ykpiv_rc _ykpiv_change_pin(ykpiv_state *state, int action, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
||||||
int sw;
|
int sw;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80};
|
unsigned char *templ = {0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80};
|
||||||
unsigned char indata[0x10];
|
unsigned char indata[0x10];
|
||||||
unsigned char data[0xff];
|
unsigned char data[0xff];
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
@@ -1527,7 +1563,7 @@ ykpiv_rc _ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
|||||||
int sw;
|
int sw;
|
||||||
unsigned char indata[5];
|
unsigned char indata[5];
|
||||||
unsigned char *inptr = indata;
|
unsigned char *inptr = indata;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_GET_DATA, 0x3f, 0xff};
|
unsigned char *templ = {0, YKPIV_INS_GET_DATA, 0x3f, 0xff};
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
|
|
||||||
inptr = set_object(object_id, inptr);
|
inptr = set_object(object_id, inptr);
|
||||||
@@ -1587,7 +1623,7 @@ ykpiv_rc _ykpiv_save_object(
|
|||||||
size_t len) {
|
size_t len) {
|
||||||
unsigned char data[CB_BUF_MAX];
|
unsigned char data[CB_BUF_MAX];
|
||||||
unsigned char *dataptr = data;
|
unsigned char *dataptr = data;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
unsigned char *templ = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
||||||
int sw;
|
int sw;
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
unsigned long outlen = 0;
|
unsigned long outlen = 0;
|
||||||
@@ -1631,7 +1667,7 @@ ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, u
|
|||||||
|
|
||||||
unsigned char key_data[1024];
|
unsigned char key_data[1024];
|
||||||
unsigned char *in_ptr = key_data;
|
unsigned char *in_ptr = key_data;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
|
unsigned char *templ = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
|
||||||
unsigned char data[256];
|
unsigned char data[256];
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
unsigned elem_len;
|
unsigned elem_len;
|
||||||
@@ -1771,7 +1807,7 @@ Cleanup:
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_attest(ykpiv_state *state, const unsigned char key, unsigned char *data, size_t *data_len) {
|
ykpiv_rc ykpiv_attest(ykpiv_state *state, const unsigned char key, unsigned char *data, size_t *data_len) {
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_ATTEST, key, 0};
|
unsigned char *templ = {0, YKPIV_INS_ATTEST, key, 0};
|
||||||
int sw;
|
int sw;
|
||||||
unsigned long ul_data_len;
|
unsigned long ul_data_len;
|
||||||
|
|
||||||
@@ -1810,7 +1846,7 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, const size_t challenge_len) {
|
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, const size_t challenge_len) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
APDU apdu = { 0 };
|
APDU apdu = { 0 };
|
||||||
unsigned char data[261] = { 0 };
|
unsigned char data[261]; /* XXX ZERO THIS!!! */
|
||||||
uint32_t recv_len = sizeof(data);
|
uint32_t recv_len = sizeof(data);
|
||||||
int sw = 0;
|
int sw = 0;
|
||||||
|
|
||||||
@@ -1822,14 +1858,17 @@ ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, const s
|
|||||||
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
||||||
|
|
||||||
/* get a challenge from the card */
|
/* get a challenge from the card */
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
||||||
apdu.st.p1 = YKPIV_ALGO_3DES; /* triple des */
|
apdu.st.p1 = YKPIV_ALGO_3DES; // triple des
|
||||||
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
|
apdu.st.p2 = YKPIV_KEY_CARDMGM; // management key
|
||||||
apdu.st.lc = 0x04;
|
apdu.st.lc = 0x04;
|
||||||
apdu.st.data[0] = 0x7c;
|
apdu.st.data[0] = 0x7c;
|
||||||
apdu.st.data[1] = 0x02;
|
apdu.st.data[1] = 0x02;
|
||||||
apdu.st.data[2] = 0x81; //0x80;
|
apdu.st.data[2] = 0x81; //0x80;
|
||||||
|
*/
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
@@ -1848,10 +1887,10 @@ Cleanup:
|
|||||||
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, const size_t response_len) {
|
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, const size_t response_len) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
APDU apdu = { 0 };
|
APDU apdu = { 0 };
|
||||||
unsigned char data[261] = { 0 };
|
unsigned char data[261]; /* XXX ZERO THIS!!! */
|
||||||
uint32_t recv_len = sizeof(data);
|
uint32_t recv_len = sizeof(data);
|
||||||
int sw = 0;
|
int sw = 0;
|
||||||
unsigned char *dataptr = apdu.st.data;
|
unsigned char *dataptr = 0; /* XXX FIX THIS!!! apdu.st.data; */
|
||||||
|
|
||||||
if (NULL == state) return YKPIV_GENERIC_ERROR;
|
if (NULL == state) return YKPIV_GENERIC_ERROR;
|
||||||
if (NULL == response) return YKPIV_GENERIC_ERROR;
|
if (NULL == response) return YKPIV_GENERIC_ERROR;
|
||||||
@@ -1862,17 +1901,21 @@ ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, const
|
|||||||
|
|
||||||
/* send the response to the card and a challenge of our own. */
|
/* send the response to the card and a challenge of our own. */
|
||||||
recv_len = sizeof(data);
|
recv_len = sizeof(data);
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
|
||||||
apdu.st.p1 = YKPIV_ALGO_3DES; /* triple des */
|
apdu.st.p1 = YKPIV_ALGO_3DES; // triple des
|
||||||
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
|
apdu.st.p2 = YKPIV_KEY_CARDMGM; // management key
|
||||||
|
*/
|
||||||
*dataptr++ = 0x7c;
|
*dataptr++ = 0x7c;
|
||||||
*dataptr++ = 0x0a; /* 2 + 8 */
|
*dataptr++ = 0x0a; /* 2 + 8 */
|
||||||
*dataptr++ = 0x82;
|
*dataptr++ = 0x82;
|
||||||
*dataptr++ = 8;
|
*dataptr++ = 8;
|
||||||
memcpy(dataptr, response, response_len);
|
memcpy(dataptr, response, response_len);
|
||||||
dataptr += 8;
|
dataptr += 8;
|
||||||
apdu.st.lc = (unsigned char)(dataptr - apdu.st.data);
|
/* XXX FIX THIS!!! */
|
||||||
|
//apdu.st.lc = (unsigned char)(dataptr - apdu.st.data);
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
@@ -1888,7 +1931,7 @@ Cleanup:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t MGMT_AID[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 };
|
static const uint8_t *MGMT_AID = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 };
|
||||||
|
|
||||||
/* deauthenticates the user pin and mgm key */
|
/* deauthenticates the user pin and mgm key */
|
||||||
ykpiv_rc ykpiv_auth_deauthenticate(ykpiv_state *state) {
|
ykpiv_rc ykpiv_auth_deauthenticate(ykpiv_state *state) {
|
||||||
@@ -1905,11 +1948,14 @@ ykpiv_rc ykpiv_auth_deauthenticate(ykpiv_state *state) {
|
|||||||
/* this function does not use ykpiv_transfer_data because it selects a different app */
|
/* this function does not use ykpiv_transfer_data because it selects a different app */
|
||||||
if ((res = _ykpiv_begin_transaction(state)) < YKPIV_OK) return res;
|
if ((res = _ykpiv_begin_transaction(state)) < YKPIV_OK) return res;
|
||||||
|
|
||||||
|
/* XXX FIX THIS!!! */
|
||||||
|
/*
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
apdu.st.ins = YKPIV_INS_SELECT_APPLICATION;
|
||||||
apdu.st.p1 = 0x04;
|
apdu.st.p1 = 0x04;
|
||||||
apdu.st.lc = sizeof(MGMT_AID);
|
apdu.st.lc = sizeof(MGMT_AID);
|
||||||
memcpy(apdu.st.data, MGMT_AID, sizeof(MGMT_AID));
|
memcpy(apdu.st.data, MGMT_AID, sizeof(MGMT_AID));
|
||||||
|
*/
|
||||||
|
|
||||||
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) < YKPIV_OK) {
|
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) < YKPIV_OK) {
|
||||||
if (state->verbose) {
|
if (state->verbose) {
|
||||||
|
|||||||
+3250
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user