Files
yubikey.rs/lib/ykpiv.rs
T
Tony Arcieri 45ba342f57 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.
2019-08-10 10:48:02 -07:00

3251 lines
104 KiB
Rust

extern {
fn SCardBeginTransaction(hCard : i32) -> i32;
fn SCardConnect(
hContext : i32,
szReader : *const u8,
dwShareMode : u32,
dwPreferredProtocols : u32,
phCard : *mut i32,
pdwActiveProtocol : *mut u32
) -> i32;
fn SCardDisconnect(hCard : i32, dwDisposition : u32) -> i32;
fn SCardEndTransaction(hCard : i32, dwDisposition : u32) -> i32;
fn SCardEstablishContext(
dwScope : u32,
pvReserved1 : *const ::std::os::raw::c_void,
pvReserved2 : *const ::std::os::raw::c_void,
phContext : *mut i32
) -> i32;
fn SCardIsValidContext(hContext : i32) -> i32;
fn SCardListReaders(
hContext : i32,
mszGroups : *const u8,
mszReaders : *mut u8,
pcchReaders : *mut u32
) -> i32;
fn SCardReconnect(
hCard : i32,
dwShareMode : u32,
dwPreferredProtocols : u32,
dwInitialization : u32,
pdwActiveProtocol : *mut u32
) -> i32;
fn SCardReleaseContext(hContext : i32) -> i32;
fn SCardStatus(
hCard : i32,
mszReaderNames : *mut u8,
pcchReaderLen : *mut u32,
pdwState : *mut u32,
pdwProtocol : *mut u32,
pbAtr : *mut u8,
pcbAtrLen : *mut u32
) -> i32;
static mut _DefaultRuneLocale : Struct1;
fn __maskrune(arg1 : i32, arg2 : usize) -> i32;
static mut __stderrp : *mut __sFILE;
fn __swbuf(arg1 : i32, arg2 : *mut __sFILE) -> i32;
fn __tolower(arg1 : i32) -> i32;
fn __toupper(arg1 : i32) -> i32;
fn calloc(
__count : usize, __size : usize
) -> *mut ::std::os::raw::c_void;
fn des_destroy_key(key : *mut des_key) -> Enum6;
fn des_encrypt(
key : *mut des_key,
in_ : *const u8,
inlen : usize,
out : *mut u8,
outlen : *mut usize
) -> Enum6;
fn des_import_key(
type_ : i32,
keyraw : *const u8,
keyrawlen : usize,
key : *mut *mut des_key
) -> Enum6;
fn fprintf(arg1 : *mut __sFILE, arg2 : *const u8, ...) -> i32;
fn free(arg1 : *mut ::std::os::raw::c_void);
fn memcmp(
__s1 : *const ::std::os::raw::c_void,
__s2 : *const ::std::os::raw::c_void,
__n : usize
) -> i32;
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 memmove(
__dst : *mut ::std::os::raw::c_void,
__src : *const ::std::os::raw::c_void,
__len : 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 memset_s(
__s : *mut ::std::os::raw::c_void,
__smax : usize,
__c : i32,
__n : usize
) -> i32;
fn realloc(
__ptr : *mut ::std::os::raw::c_void, __size : usize
) -> *mut ::std::os::raw::c_void;
fn snprintf(
__str : *mut u8, __size : usize, __format : *const u8, ...
) -> i32;
fn strchr(__s : *const u8, __c : i32) -> *mut u8;
fn strlen(__s : *const u8) -> usize;
fn strncasecmp(
arg1 : *const u8, arg2 : *const u8, arg3 : usize
) -> i32;
fn strnlen(__s1 : *const u8, __n : usize) -> usize;
fn yk_des_is_weak_key(key : *const u8, cb_key : usize) -> bool;
fn ykpiv_strerror(err : Enum5) -> *const u8;
}
enum __sFILEX {
}
enum des_key {
}
enum u_APDU {
}
#[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 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)
}
static mut aid : *const u8 = 0xa0i32 as (*const u8);
#[derive(Copy)]
#[repr(C)]
pub struct ykpiv_allocator {
pub pfn_alloc : unsafe extern fn(*mut ::std::os::raw::c_void, usize) -> *mut ::std::os::raw::c_void,
pub pfn_realloc : unsafe extern fn(*mut ::std::os::raw::c_void, *mut ::std::os::raw::c_void, usize) -> *mut ::std::os::raw::c_void,
pub pfn_free : unsafe extern fn(*mut ::std::os::raw::c_void, *mut ::std::os::raw::c_void),
pub alloc_data : *mut ::std::os::raw::c_void,
}
impl Clone for ykpiv_allocator {
fn clone(&self) -> Self { *self }
}
unsafe extern fn _default_alloc(
mut data : *mut ::std::os::raw::c_void, mut cb : usize
) -> *mut ::std::os::raw::c_void {
data;
calloc(cb,1usize)
}
unsafe extern fn _default_realloc(
mut data : *mut ::std::os::raw::c_void,
mut p : *mut ::std::os::raw::c_void,
mut cb : usize
) -> *mut ::std::os::raw::c_void {
data;
realloc(p,cb)
}
unsafe extern fn _default_free(
mut data : *mut ::std::os::raw::c_void,
mut p : *mut ::std::os::raw::c_void
) {
data;
free(p);
}
#[no_mangle]
pub static mut _default_allocator
: ykpiv_allocator
= ykpiv_allocator {
pfn_alloc: _default_alloc,
pfn_realloc: _default_realloc,
pfn_free: _default_free,
alloc_data: 0i32 as (*mut ::std::os::raw::c_void)
};
#[derive(Copy)]
#[repr(C)]
pub struct _ykpiv_version_t {
pub major : u8,
pub minor : u8,
pub patch : u8,
}
impl Clone for _ykpiv_version_t {
fn clone(&self) -> Self { *self }
}
#[derive(Copy)]
#[repr(C)]
pub struct ykpiv_state {
pub context : i32,
pub card : i32,
pub verbose : i32,
pub pin : *mut u8,
pub allocator : ykpiv_allocator,
pub isNEO : bool,
pub ver : _ykpiv_version_t,
pub serial : u32,
}
impl Clone for ykpiv_state {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn _ykpiv_alloc(
mut state : *mut ykpiv_state, mut size : usize
) -> *mut ::std::os::raw::c_void {
if state.is_null() || (*state).allocator.pfn_alloc == 0 {
0i32 as (*mut ::std::os::raw::c_void)
} else {
((*state).allocator.pfn_alloc)((*state).allocator.alloc_data,size)
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_realloc(
mut state : *mut ykpiv_state,
mut address : *mut ::std::os::raw::c_void,
mut size : usize
) -> *mut ::std::os::raw::c_void {
if state.is_null() || (*state).allocator.pfn_realloc == 0 {
0i32 as (*mut ::std::os::raw::c_void)
} else {
((*state).allocator.pfn_realloc)(
(*state).allocator.alloc_data,
address,
size
)
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_free(
mut state : *mut ykpiv_state,
mut data : *mut ::std::os::raw::c_void
) { if data.is_null() || state.is_null(
) || (*state).allocator.pfn_free == 0 {
} else {
((*state).allocator.pfn_free)((*state).allocator.alloc_data,data);
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_set_length(
mut buffer : *mut u8, mut length : usize
) -> u32 {
if length < 0x80usize {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = length as (u8);
1u32
} else if length < 0x100usize {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 0x81u8;
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = length as (u8);
2u32
} else {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 0x82u8;
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = (length >> 8i32 & 0xffusize) as (u8);
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = (length as (u8) as (i32) & 0xffi32) as (u8);
3u32
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_get_length(
mut buffer : *const u8, mut len : *mut usize
) -> u32 {
if *buffer.offset(0isize) as (i32) < 0x81i32 {
*len = *buffer.offset(0isize) as (usize);
1u32
} else if *buffer as (i32) & 0x7fi32 == 1i32 {
*len = *buffer.offset(1isize) as (usize);
2u32
} else if *buffer as (i32) & 0x7fi32 == 2i32 {
let mut tmp : usize = *buffer.offset(1isize) as (usize);
*len = (tmp << 8i32).wrapping_add(
*buffer.offset(2isize) as (usize)
);
3u32
} else {
0u32
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_has_valid_length(
mut buffer : *const u8, mut len : usize
) -> bool {
if *buffer.offset(0isize) as (i32) < 0x81i32 && (len > 0usize) {
true
} else if *buffer as (i32) & 0x7fi32 == 1i32 && (len > 1usize) {
true
} else if *buffer as (i32) & 0x7fi32 == 2i32 && (len > 2usize) {
true
} else {
false
}
}
#[derive(Clone, Copy)]
#[repr(i32)]
pub enum Enum5 {
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,
}
#[no_mangle]
pub unsafe extern fn ykpiv_init_with_allocator(
mut state : *mut *mut ykpiv_state,
mut verbose : i32,
mut allocator : *const ykpiv_allocator
) -> Enum5 {
let mut s : *mut ykpiv_state;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut *mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if 0i32 as (*mut ::std::os::raw::c_void) as (*const ykpiv_allocator) == allocator || (*allocator).pfn_alloc == 0 || (*allocator).pfn_realloc == 0 || (*allocator).pfn_free == 0 {
Enum5::YKPIV_MEMORY_ERROR
} else {
s = ((*allocator).pfn_alloc)(
(*allocator).alloc_data,
::std::mem::size_of::<ykpiv_state>()
) as (*mut ykpiv_state);
(if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == s {
Enum5::YKPIV_MEMORY_ERROR
} else {
memset(
s as (*mut ::std::os::raw::c_void),
0i32,
::std::mem::size_of::<ykpiv_state>()
);
(*s).pin = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
(*s).allocator = *allocator;
(*s).verbose = verbose;
(*s).context = -1i32;
*state = s;
Enum5::YKPIV_OK
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_init(
mut state : *mut *mut ykpiv_state, mut verbose : i32
) -> Enum5 {
ykpiv_init_with_allocator(
state,
verbose,
&mut _default_allocator as (*mut ykpiv_allocator) as (*const ykpiv_allocator)
)
}
unsafe extern fn _ykpiv_done(
mut state : *mut ykpiv_state, mut disconnect : bool
) -> Enum5 {
if disconnect {
ykpiv_disconnect(state);
}
_cache_pin(
state,
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
0usize
);
_ykpiv_free(state,state as (*mut ::std::os::raw::c_void));
Enum5::YKPIV_OK
}
#[no_mangle]
pub unsafe extern fn ykpiv_done_with_external_card(
mut state : *mut ykpiv_state
) -> Enum5 {
_ykpiv_done(state,false)
}
#[no_mangle]
pub unsafe extern fn ykpiv_done(
mut state : *mut ykpiv_state
) -> Enum5 {
_ykpiv_done(state,true)
}
#[no_mangle]
pub unsafe extern fn ykpiv_disconnect(
mut state : *mut ykpiv_state
) -> Enum5 {
if (*state).card != 0 {
SCardDisconnect((*state).card,0x1u32);
(*state).card = 0i32;
}
if SCardIsValidContext((*state).context) == 0x0i32 {
SCardReleaseContext((*state).context);
(*state).context = -1i32;
}
Enum5::YKPIV_OK
}
#[no_mangle]
pub unsafe extern fn _ykpiv_select_application(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut apdu : u_APDU;
let mut data : [u8; 255];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 255]>() as (u32);
let mut sw : i32;
let mut res : Enum5 = Enum5::YKPIV_OK;
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
res
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed selecting application: %04x\n\0").as_ptr(),
sw
);
}
Enum5::YKPIV_GENERIC_ERROR
} else {
res = _ykpiv_get_version(
state,
0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_version_t)
);
if res as (i32) != Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to retrieve version: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
}
res = _ykpiv_get_serial(
state,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u32),
false
);
if res as (i32) != Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to retrieve serial number: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
res = Enum5::YKPIV_OK;
}
res
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_ensure_application_selected(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
state;
res
}
unsafe extern fn _ykpiv_connect(
mut state : *mut ykpiv_state, mut context : usize, mut card : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if context != (*state).context as (usize) && (0x0i32 != SCardIsValidContext(
context as (i32)
)) {
Enum5::YKPIV_PCSC_ERROR
} else {
if card != (*state).card as (usize) {
let mut reader : [u8; 3072];
let mut reader_len
: u32
= ::std::mem::size_of::<[u8; 3072]>() as (u32);
let mut atr : [u8; 33];
let mut atr_len : u32 = ::std::mem::size_of::<[u8; 33]>() as (u32);
if 0x0i32 != SCardStatus(
card as (i32),
reader.as_mut_ptr(),
&mut reader_len as (*mut u32),
0i32 as (*mut ::std::os::raw::c_void) as (*mut u32),
0i32 as (*mut ::std::os::raw::c_void) as (*mut u32),
atr.as_mut_ptr(),
&mut atr_len as (*mut u32)
) {
return Enum5::YKPIV_PCSC_ERROR;
} else {
(*state).isNEO = ::std::mem::size_of::<[u8; 23]>().wrapping_sub(
1usize
) == atr_len as (usize) && (0i32 == memcmp(
(*b";\xFC\x13\0\0\x811\xFE\x15YubikeyNEOr3\xE1\0").as_ptr(
) as (*const ::std::os::raw::c_void),
atr.as_mut_ptr(
) as (*const ::std::os::raw::c_void),
atr_len as (usize)
));
}
}
(*state).context = context as (i32);
(*state).card = card as (i32);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_connect_with_external_card(
mut state : *mut ykpiv_state, mut context : usize, mut card : usize
) -> Enum5 {
_ykpiv_connect(state,context,card)
}
#[no_mangle]
pub unsafe extern fn ykpiv_connect(
mut state : *mut ykpiv_state, mut wanted : *const u8
) -> Enum5 {
let mut _currentBlock;
let mut active_protocol : u32;
let mut reader_buf : [u8; 2048];
let mut num_readers : usize = ::std::mem::size_of::<[u8; 2048]>();
let mut rc : isize;
let mut reader_ptr : *mut u8;
let mut card : i32 = -1i32;
let mut ret
: Enum5
= ykpiv_list_readers(
state,
reader_buf.as_mut_ptr(),
&mut num_readers as (*mut usize)
);
if ret as (i32) != Enum5::YKPIV_OK as (i32) {
ret
} else {
reader_ptr = reader_buf.as_mut_ptr();
'loop2: loop {
if !(*reader_ptr as (i32) != b'\0' as (i32)) {
_currentBlock = 3;
break;
}
if !wanted.is_null() {
let mut ptr : *mut u8 = reader_ptr;
let mut found : bool = false;
'loop10: loop {
if strlen(ptr as (*const u8)) < strlen(wanted) {
_currentBlock = 14;
break;
}
if strncasecmp(ptr as (*const u8),wanted,strlen(wanted)) == 0i32 {
_currentBlock = 13;
break;
}
if *{
let _old = ptr;
ptr = ptr.offset(1isize);
_old
} == 0 {
_currentBlock = 14;
break;
}
}
if _currentBlock == 13 {
found = true;
}
if found as (i32) == 0i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"skipping reader \'%s\' since it doesn\'t match \'%s\'.\n\0").as_ptr(
),
reader_ptr,
wanted
);
_currentBlock = 26;
} else {
_currentBlock = 26;
}
} else {
_currentBlock = 15;
}
} else {
_currentBlock = 15;
}
if _currentBlock == 15 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"trying to connect to reader \'%s\'.\n\0").as_ptr(),
reader_ptr
);
}
rc = SCardConnect(
(*state).context,
reader_ptr as (*const u8),
0x2u32,
0x2u32,
&mut card as (*mut i32),
&mut active_protocol as (*mut u32)
) as (isize);
if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"SCardConnect failed, rc=%08lx\n\0").as_ptr(),
rc
);
}
} else if Enum5::YKPIV_OK as (i32) == _ykpiv_connect(
state,
(*state).context as (usize),
card as (usize)
) as (i32) {
_currentBlock = 19;
break;
}
}
reader_ptr = reader_ptr.offset(
strlen(reader_ptr as (*const u8)).wrapping_add(1usize) as (isize)
);
}
(if _currentBlock == 3 {
(if *reader_ptr as (i32) == b'\0' as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"error: no usable reader found.\n\0").as_ptr()
);
}
SCardReleaseContext((*state).context);
(*state).context = -1i32;
Enum5::YKPIV_PCSC_ERROR
} else {
Enum5::YKPIV_GENERIC_ERROR
})
} else if Enum5::YKPIV_OK as (i32) != {
ret = _ykpiv_begin_transaction(state);
ret
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
ret = _ykpiv_select_application(state);
_ykpiv_end_transaction(state);
ret
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_list_readers(
mut state : *mut ykpiv_state,
mut readers : *mut u8,
mut len : *mut usize
) -> Enum5 {
let mut num_readers : u32 = 0u32;
let mut rc : isize;
if SCardIsValidContext((*state).context) != 0x0i32 {
rc = SCardEstablishContext(
0x2u32,
0i32 as (*mut ::std::os::raw::c_void) as (*const ::std::os::raw::c_void),
0i32 as (*mut ::std::os::raw::c_void) as (*const ::std::os::raw::c_void),
&mut (*state).context as (*mut i32)
) as (isize);
if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"error: SCardEstablishContext failed, rc=%08lx\n\0").as_ptr(),
rc
);
}
return Enum5::YKPIV_PCSC_ERROR;
}
}
rc = SCardListReaders(
(*state).context,
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
&mut num_readers as (*mut u32)
) as (isize);
if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"error: SCardListReaders failed, rc=%08lx\n\0").as_ptr(),
rc
);
}
SCardReleaseContext((*state).context);
(*state).context = -1i32;
Enum5::YKPIV_PCSC_ERROR
} else {
if num_readers as (usize) > *len {
num_readers = *len as (u32);
} else if num_readers as (usize) < *len {
*len = num_readers as (usize);
}
rc = SCardListReaders(
(*state).context,
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
readers,
&mut num_readers as (*mut u32)
) as (isize);
(if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"error: SCardListReaders failed, rc=%08lx\n\0").as_ptr(),
rc
);
}
SCardReleaseContext((*state).context);
(*state).context = -1i32;
Enum5::YKPIV_PCSC_ERROR
} else {
*len = num_readers as (usize);
Enum5::YKPIV_OK
})
}
}
unsafe extern fn reconnect(mut state : *mut ykpiv_state) -> Enum5 {
let mut active_protocol : u32 = 0u32;
let mut rc : isize;
let mut res : Enum5;
let mut tries : i32;
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"trying to reconnect to current reader.\n\0").as_ptr()
);
}
rc = SCardReconnect(
(*state).card,
0x2u32,
0x2u32,
0x1u32,
&mut active_protocol as (*mut u32)
) as (isize);
if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"SCardReconnect failed, rc=%08lx\n\0").as_ptr(),
rc
);
}
Enum5::YKPIV_PCSC_ERROR
} else if {
res = _ykpiv_select_application(state);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else if !(*state).pin.is_null() {
ykpiv_verify(
state,
(*state).pin as (*const u8),
&mut tries as (*mut i32)
)
} else {
Enum5::YKPIV_OK
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_begin_transaction(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut rc : isize;
rc = SCardBeginTransaction((*state).card) as (isize);
if (rc as (usize) & 0xffffffffusize) as (isize) as (usize) == 0x80100068usize {
let mut res : Enum5 = Enum5::YKPIV_OK;
if {
res = reconnect(state);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
return res;
} else {
rc = SCardBeginTransaction((*state).card) as (isize);
}
}
if rc != 0x0isize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"error: Failed to begin pcsc transaction, rc=%08lx\n\0").as_ptr(
),
rc
);
}
Enum5::YKPIV_PCSC_ERROR
} else {
Enum5::YKPIV_OK
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_end_transaction(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut rc
: isize
= SCardEndTransaction((*state).card,0x0u32) as (isize);
if rc != 0x0isize && ((*state).verbose != 0) {
fprintf(
__stderrp,
(*b"error: Failed to end pcsc transaction, rc=%08lx\n\0").as_ptr(),
rc
);
Enum5::YKPIV_PCSC_ERROR
} else {
Enum5::YKPIV_OK
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_transfer_data(
mut state : *mut ykpiv_state,
mut templ : *const u8,
mut in_data : *const u8,
mut in_len : isize,
mut out_data : *mut u8,
mut out_len : *mut usize,
mut sw : *mut i32
) -> Enum5 {
let mut _currentBlock;
let mut in_ptr : *const u8 = in_data;
let mut max_out : usize = *out_len;
let mut res : Enum5;
*out_len = 0usize;
'loop1: loop {
let mut this_size : usize = 0xffusize;
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut apdu : u_APDU;
if (*state).verbose > 2i32 {
fprintf(
__stderrp,
(*b"Going to send %lu bytes in this go.\n\0").as_ptr(),
this_size
);
}
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
sw
);
if res as (i32) != Enum5::YKPIV_OK as (i32) {
_currentBlock = 24;
break;
}
if *sw != 0x9000i32 && (*sw >> 8i32 != 0x61i32) {
_currentBlock = 24;
break;
}
if (*out_len).wrapping_add(recv_len as (usize)).wrapping_sub(
2usize
) > max_out {
_currentBlock = 21;
break;
}
if !out_data.is_null() {
memcpy(
out_data as (*mut ::std::os::raw::c_void),
data.as_mut_ptr() as (*const ::std::os::raw::c_void),
recv_len.wrapping_sub(2u32) as (usize)
);
out_data = out_data.offset(recv_len.wrapping_sub(2u32) as (isize));
*out_len = (*out_len).wrapping_add(
recv_len.wrapping_sub(2u32) as (usize)
);
}
in_ptr = in_ptr.offset(this_size as (isize));
if !(in_ptr < in_data.offset(in_len)) {
_currentBlock = 10;
break;
}
}
if _currentBlock == 10 {
'loop10: loop {
if !(*sw >> 8i32 == 0x61i32) {
_currentBlock = 24;
break;
}
let mut apdu : u_APDU;
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
if (*state).verbose > 2i32 {
fprintf(
__stderrp,
(*b"The card indicates there is %d bytes more data for us.\n\0").as_ptr(
),
*sw & 0xffi32
);
}
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
sw
);
if res as (i32) != Enum5::YKPIV_OK as (i32) {
_currentBlock = 24;
break;
}
if *sw != 0x9000i32 && (*sw >> 8i32 != 0x61i32) {
_currentBlock = 24;
break;
}
if (*out_len).wrapping_add(recv_len as (usize)).wrapping_sub(
2usize
) > max_out {
_currentBlock = 18;
break;
}
if out_data.is_null() {
continue;
}
memcpy(
out_data as (*mut ::std::os::raw::c_void),
data.as_mut_ptr() as (*const ::std::os::raw::c_void),
recv_len.wrapping_sub(2u32) as (usize)
);
out_data = out_data.offset(recv_len.wrapping_sub(2u32) as (isize));
*out_len = (*out_len).wrapping_add(
recv_len.wrapping_sub(2u32) as (usize)
);
}
if _currentBlock == 24 {
} else {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Output buffer to small, wanted to write %lu, max was %lu.\0").as_ptr(
),
(*out_len).wrapping_add(recv_len as (usize)).wrapping_sub(2usize),
max_out
);
}
res = Enum5::YKPIV_SIZE_ERROR;
}
} else if _currentBlock == 21 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Output buffer to small, wanted to write %lu, max was %lu.\n\0").as_ptr(
),
(*out_len).wrapping_add(recv_len as (usize)).wrapping_sub(2usize),
max_out
);
}
res = Enum5::YKPIV_SIZE_ERROR;
}
res
}
#[no_mangle]
pub unsafe extern fn ykpiv_transfer_data(
mut state : *mut ykpiv_state,
mut templ : *const u8,
mut in_data : *const u8,
mut in_len : isize,
mut out_data : *mut u8,
mut out_len : *mut usize,
mut sw : *mut i32
) -> Enum5 {
let mut res : Enum5;
if {
res = _ykpiv_begin_transaction(state);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
*out_len = 0usize;
Enum5::YKPIV_PCSC_ERROR
} else {
res = _ykpiv_transfer_data(
state,
templ,
in_data,
in_len,
out_data,
out_len,
sw
);
_ykpiv_end_transaction(state);
res
}
}
unsafe extern fn dump_hex(mut buf : *const u8, mut len : u32) {
let mut i : u32;
i = 0u32;
'loop1: loop {
if !(i < len) {
break;
}
fprintf(
__stderrp,
(*b"%02x \0").as_ptr(),
*buf.offset(i as (isize)) as (i32)
);
i = i.wrapping_add(1u32);
}
}
#[no_mangle]
pub unsafe extern fn _send_data(
mut state : *mut ykpiv_state,
mut apdu : *mut u_APDU,
mut data : *mut u8,
mut recv_len : *mut u32,
mut sw : *mut i32
) -> Enum5 {
let mut rc : isize;
let mut send_len : u32 = 0u32;
let mut tmp_len : u32 = *recv_len;
*recv_len = tmp_len;
if (*state).verbose > 1i32 {
fprintf(__stderrp,(*b"< \0").as_ptr());
dump_hex(data as (*const u8),*recv_len);
fprintf(__stderrp,(*b"\n\0").as_ptr());
}
if *recv_len >= 2u32 {
*sw = *data.offset(
(*recv_len).wrapping_sub(2u32) as (isize)
) as (i32) << 8i32 | *data.offset(
(*recv_len).wrapping_sub(1u32) as (isize)
) as (i32);
} else {
*sw = 0i32;
}
Enum5::YKPIV_OK
}
#[derive(Clone, Copy)]
#[repr(i32)]
pub enum Enum6 {
DES_OK = 0i32,
DES_INVALID_PARAMETER = -1i32,
DES_BUFFER_TOO_SMALL = -2i32,
DES_MEMORY_ERROR = -3i32,
DES_GENERAL_ERROR = -4i32,
}
#[no_mangle]
pub unsafe extern fn ykpiv_authenticate(
mut state : *mut ykpiv_state, mut key : *const u8
) -> Enum5 {
let mut apdu : u_APDU;
let mut data : [u8; 261];
let mut challenge : [u8; 8];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32;
let mut res : Enum5;
let mut drc : Enum6 = Enum6::DES_OK;
let mut mgm_key
: *mut des_key
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut des_key);
let mut out_len : usize = 0usize;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
if 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) == key {
key = (*b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\0").as_ptr(
);
}
if Enum6::DES_OK as (i32) != des_import_key(
1i32,
key,
(8i32 * 3i32) as (usize),
&mut mgm_key as (*mut *mut des_key)
) as (i32) {
res = Enum5::YKPIV_ALGORITHM_ERROR;
} else {
let mut response : [u8; 8];
out_len = ::std::mem::size_of::<[u8; 8]>();
drc = des_encrypt(
mgm_key,
challenge.as_mut_ptr() as (*const u8),
::std::mem::size_of::<[u8; 8]>(),
response.as_mut_ptr(),
&mut out_len as (*mut usize)
);
if drc as (i32) != Enum6::DES_OK as (i32) {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
} else if memcmp(
response.as_mut_ptr() as (*const ::std::os::raw::c_void),
data.as_mut_ptr().offset(
4isize
) as (*const ::std::os::raw::c_void),
8usize
) == 0i32 {
res = Enum5::YKPIV_OK;
} else {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
}
}
}
if !mgm_key.is_null() {
des_destroy_key(mgm_key);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_set_mgmkey(
mut state : *mut ykpiv_state, mut new_key : *const u8
) -> Enum5 {
ykpiv_set_mgmkey2(state,new_key,0u8)
}
#[no_mangle]
pub unsafe extern fn ykpiv_set_mgmkey2(
mut state : *mut ykpiv_state, mut new_key : *const u8, touch : u8
) -> Enum5 {
let mut apdu : u_APDU;
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32;
let mut res : Enum5 = Enum5::YKPIV_OK;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
if yk_des_is_weak_key(new_key,(8i32 * 3i32) as (usize)) {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Won\'t set new key \'\0").as_ptr());
dump_hex(new_key,(8i32 * 3i32) as (u32));
fprintf(
__stderrp,
(*b"\' since it\'s weak (with odd parity).\n\0").as_ptr()
);
}
res = Enum5::YKPIV_KEY_ERROR;
} else if !({
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
if !(sw == 0x9000i32) {
res = Enum5::YKPIV_GENERIC_ERROR;
}
}
}
memset_s(
&mut apdu as (*mut u_APDU) as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<u_APDU>(),
0i32,
::std::mem::size_of::<u_APDU>()
);
_ykpiv_end_transaction(state);
res
}
}
static mut hex_translate
: *mut u8
= (*b"0123456789abcdef\0").as_ptr() as (*mut u8);
#[no_mangle]
pub unsafe extern fn ykpiv_hex_decode(
mut hex_in : *const u8,
mut in_len : usize,
mut hex_out : *mut u8,
mut out_len : *mut usize
) -> Enum5 {
let mut _currentBlock;
let mut i : usize;
let mut first : bool = true;
if *out_len < in_len.wrapping_div(2usize) {
Enum5::YKPIV_SIZE_ERROR
} else if in_len.wrapping_rem(2usize) != 0usize {
Enum5::YKPIV_SIZE_ERROR
} else {
*out_len = in_len.wrapping_div(2usize);
i = 0usize;
'loop3: loop {
if !(i < in_len) {
_currentBlock = 4;
break;
}
let mut ind_ptr
: *mut u8
= strchr(
hex_translate as (*const u8),
tolower(
*{
let _old = hex_in;
hex_in = hex_in.offset(1isize);
_old
} as (i32)
)
);
let mut index : i32 = 0i32;
if ind_ptr.is_null() {
_currentBlock = 6;
break;
}
index = ((ind_ptr as (isize)).wrapping_sub(
hex_translate as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (i32);
if first {
*hex_out = (index << 4i32) as (u8);
} else {
let _rhs = index;
let _lhs
= &mut *{
let _old = hex_out;
hex_out = hex_out.offset(1isize);
_old
};
*_lhs = (*_lhs as (i32) | _rhs) as (u8);
}
first = !first;
i = i.wrapping_add(1usize);
}
(if _currentBlock == 4 {
Enum5::YKPIV_OK
} else {
Enum5::YKPIV_PARSE_ERROR
})
}
}
unsafe extern fn _general_authenticate(
mut state : *mut ykpiv_state,
mut sign_in : *const u8,
mut in_len : usize,
mut out : *mut u8,
mut out_len : *mut usize,
mut algorithm : u8,
mut key : u8,
mut decipher : bool
) -> Enum5 {
let mut _currentBlock;
let mut indata : [u8; 1024];
let mut dataptr : *mut u8 = indata.as_mut_ptr();
let mut data : [u8; 1024];
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut recv_len : usize = ::std::mem::size_of::<[u8; 1024]>();
let mut key_len : usize = 0usize;
let mut sw : i32 = 0i32;
let mut bytes : usize;
let mut len : usize = 0usize;
let mut res : Enum5;
if algorithm as (i32) == 0x14i32 {
_currentBlock = 12;
} else if algorithm as (i32) == 0x11i32 {
key_len = 32usize;
_currentBlock = 12;
} else {
if !(algorithm as (i32) == 0x7i32) {
if algorithm as (i32) == 0x6i32 {
key_len = 128usize;
} else {
return Enum5::YKPIV_ALGORITHM_ERROR;
}
}
if key_len == 0usize {
key_len = 256usize;
}
if in_len != key_len {
return Enum5::YKPIV_SIZE_ERROR;
} else {
_currentBlock = 16;
}
}
if _currentBlock == 12 {
if key_len == 0usize {
key_len = 48usize;
}
if !decipher && (in_len > key_len) {
return Enum5::YKPIV_SIZE_ERROR;
} else if decipher && (in_len != key_len.wrapping_mul(
2usize
).wrapping_add(
1usize
)) {
return Enum5::YKPIV_SIZE_ERROR;
}
}
if in_len < 0x80usize {
bytes = 1usize;
} else if in_len < 0xffusize {
bytes = 2usize;
} else {
bytes = 3usize;
}
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x7cu8;
dataptr = dataptr.offset(
_ykpiv_set_length(
dataptr,
in_len.wrapping_add(bytes).wrapping_add(3usize)
) as (isize)
);
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x82u8;
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x0u8;
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = if (algorithm as (i32) == 0x11i32 || algorithm as (i32) == 0x14i32) && decipher {
0x85i32
} else {
0x81i32
} as (u8);
dataptr = dataptr.offset(
_ykpiv_set_length(dataptr,in_len) as (isize)
);
memcpy(
dataptr as (*mut ::std::os::raw::c_void),
sign_in as (*const ::std::os::raw::c_void),
in_len
);
dataptr = dataptr.offset(in_len as (isize));
if {
res = ykpiv_transfer_data(
state,
templ as (*const u8),
indata.as_mut_ptr() as (*const u8),
(dataptr as (isize)).wrapping_sub(
indata.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize),
data.as_mut_ptr(),
&mut recv_len as (*mut usize),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Sign command failed to communicate.\n\0").as_ptr()
);
}
res
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed sign command with code %x.\n\0").as_ptr(),
sw
);
}
(if sw == 0x6982i32 {
Enum5::YKPIV_AUTHENTICATION_ERROR
} else {
Enum5::YKPIV_GENERIC_ERROR
})
} else if data[0usize] as (i32) != 0x7ci32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed parsing signature reply.\n\0").as_ptr()
);
}
Enum5::YKPIV_PARSE_ERROR
} else {
dataptr = data.as_mut_ptr().offset(1isize);
dataptr = dataptr.offset(
_ykpiv_get_length(
dataptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
(if *dataptr as (i32) != 0x82i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed parsing signature reply.\n\0").as_ptr()
);
}
Enum5::YKPIV_PARSE_ERROR
} else {
dataptr = dataptr.offset(1isize);
dataptr = dataptr.offset(
_ykpiv_get_length(
dataptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
(if len > *out_len {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Wrong size on output buffer.\n\0").as_ptr());
}
Enum5::YKPIV_SIZE_ERROR
} else {
*out_len = len;
memcpy(
out as (*mut ::std::os::raw::c_void),
dataptr as (*const ::std::os::raw::c_void),
len
);
Enum5::YKPIV_OK
})
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_sign_data(
mut state : *mut ykpiv_state,
mut raw_in : *const u8,
mut in_len : usize,
mut sign_out : *mut u8,
mut out_len : *mut usize,
mut algorithm : u8,
mut key : u8
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
res = _general_authenticate(
state,
raw_in,
in_len,
sign_out,
out_len,
algorithm,
key,
false
);
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_decipher_data(
mut state : *mut ykpiv_state,
mut in_ : *const u8,
mut in_len : usize,
mut out : *mut u8,
mut out_len : *mut usize,
mut algorithm : u8,
mut key : u8
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
res = _general_authenticate(
state,
in_,
in_len,
out,
out_len,
algorithm,
key,
true
);
_ykpiv_end_transaction(state);
res
}
}
unsafe extern fn _ykpiv_get_version(
mut state : *mut ykpiv_state, mut p_version : *mut _ykpiv_version_t
) -> Enum5 {
let mut apdu : u_APDU;
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32;
let mut res : Enum5;
if state.is_null() {
Enum5::YKPIV_ARGUMENT_ERROR
} else if (*state).ver.major != 0 || (*state).ver.minor != 0 || (*state).ver.patch != 0 {
if !p_version.is_null() {
memcpy(
p_version as (*mut ::std::os::raw::c_void),
&mut (*state).ver as (*mut _ykpiv_version_t) as (*const ::std::os::raw::c_void),
::std::mem::size_of::<_ykpiv_version_t>()
);
}
Enum5::YKPIV_OK
} else if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else {
if sw == 0x9000i32 {
if recv_len < 3u32 {
return Enum5::YKPIV_SIZE_ERROR;
} else {
(*state).ver.major = data[0usize];
(*state).ver.minor = data[1usize];
(*state).ver.patch = data[2usize];
if !p_version.is_null() {
memcpy(
p_version as (*mut ::std::os::raw::c_void),
&mut (*state).ver as (*mut _ykpiv_version_t) as (*const ::std::os::raw::c_void),
::std::mem::size_of::<_ykpiv_version_t>()
);
}
}
} else {
res = Enum5::YKPIV_GENERIC_ERROR;
}
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_get_version(
mut state : *mut ykpiv_state,
mut version : *mut u8,
mut len : usize
) -> Enum5 {
let mut res : Enum5;
let mut result : i32 = 0i32;
let mut ver
: _ykpiv_version_t
= _ykpiv_version_t { major: 0u8, minor: 0u8, patch: 0u8 };
if {
res = _ykpiv_begin_transaction(state);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !({
res = _ykpiv_ensure_application_selected(state);
res
} as (i32) < Enum5::YKPIV_OK as (i32)) {
if {
res = _ykpiv_get_version(
state,
&mut ver as (*mut _ykpiv_version_t)
);
res
} as (i32) >= Enum5::YKPIV_OK as (i32) {
result = snprintf(
version,
len,
(*b"%d.%d.%d\0").as_ptr(),
ver.major as (i32),
ver.minor as (i32),
ver.patch as (i32)
);
if result < 0i32 {
res = Enum5::YKPIV_SIZE_ERROR;
}
}
}
_ykpiv_end_transaction(state);
res
}
}
unsafe extern fn _ykpiv_get_serial(
mut state : *mut ykpiv_state,
mut p_serial : *mut u32,
mut f_force : bool
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut apdu : u_APDU;
let mut yk_applet : *const u8 = 0xa0i32 as (*const u8);
let mut data : [u8; 255];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 255]>() as (u32);
let mut sw : i32;
let mut p_temp
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
if state.is_null() {
Enum5::YKPIV_ARGUMENT_ERROR
} else if !f_force && ((*state).serial != 0u32) {
if !p_serial.is_null() {
*p_serial = (*state).serial;
}
Enum5::YKPIV_OK
} else {
if (*state).ver.major as (i32) < 5i32 {
let mut temp : [u8; 255];
recv_len = ::std::mem::size_of::<[u8; 255]>() as (u32);
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
temp.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
_currentBlock = 37;
} else {
_currentBlock = 37;
}
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed selecting yk application: %04x\n\0").as_ptr(),
sw
);
}
res = Enum5::YKPIV_GENERIC_ERROR;
_currentBlock = 37;
} else {
recv_len = ::std::mem::size_of::<[u8; 255]>() as (u32);
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
_currentBlock = 37;
} else {
_currentBlock = 37;
}
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed retrieving serial number: %04x\n\0").as_ptr(),
sw
);
}
res = Enum5::YKPIV_GENERIC_ERROR;
_currentBlock = 37;
} else {
recv_len = ::std::mem::size_of::<[u8; 255]>() as (u32);
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
temp.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
return res;
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed selecting application: %04x\n\0").as_ptr(),
sw
);
}
return Enum5::YKPIV_GENERIC_ERROR;
}
_currentBlock = 17;
}
}
} else {
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
return res;
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed retrieving serial number: %04x\n\0").as_ptr(),
sw
);
}
return Enum5::YKPIV_GENERIC_ERROR;
}
_currentBlock = 17;
}
if _currentBlock == 17 {
if recv_len < 4u32 {
return Enum5::YKPIV_SIZE_ERROR;
} else {
p_temp = &mut (*state).serial as (*mut u32) as (*mut u8);
*{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} = data[3usize];
*{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} = data[2usize];
*{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} = data[1usize];
*{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} = data[0usize];
if !p_serial.is_null() {
*p_serial = (*state).serial;
}
}
}
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_get_serial(
mut state : *mut ykpiv_state, mut p_serial : *mut u32
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
if {
res = _ykpiv_begin_transaction(state);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !({
res = _ykpiv_ensure_application_selected(state);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
res = _ykpiv_get_serial(state,p_serial,false);
}
_ykpiv_end_transaction(state);
res
}
}
unsafe extern fn _cache_pin(
mut state : *mut ykpiv_state, mut pin : *const u8, mut len : usize
) -> Enum5 {
if state.is_null() {
Enum5::YKPIV_ARGUMENT_ERROR
} else if !pin.is_null() && ((*state).pin as (*const u8) == pin) {
Enum5::YKPIV_OK
} else {
if !(*state).pin.is_null() {
memset_s(
(*state).pin as (*mut ::std::os::raw::c_void),
strnlen((*state).pin as (*const u8),8usize),
0i32,
strnlen((*state).pin as (*const u8),8usize)
);
_ykpiv_free(state,(*state).pin as (*mut ::std::os::raw::c_void));
(*state).pin = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
}
if !pin.is_null() && (len > 0usize) {
(*state).pin = _ykpiv_alloc(
state,
len.wrapping_mul(::std::mem::size_of::<u8>()).wrapping_add(1usize)
) as (*mut u8);
if (*state).pin == 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) {
return Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
(*state).pin as (*mut ::std::os::raw::c_void),
pin as (*const ::std::os::raw::c_void),
len
);
*(*state).pin.offset(len as (isize)) = 0u8;
}
}
Enum5::YKPIV_OK
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_verify(
mut state : *mut ykpiv_state,
mut pin : *const u8,
mut tries : *mut i32
) -> Enum5 {
ykpiv_verify_select(
state,
pin,
if !pin.is_null() { strlen(pin) } else { 0usize },
tries,
false
)
}
unsafe extern fn _verify(
mut state : *mut ykpiv_state,
mut pin : *const u8,
pin_len : usize,
mut tries : *mut i32
) -> Enum5 {
let mut apdu : u_APDU;
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32;
let mut res : Enum5;
if pin_len > 8usize {
Enum5::YKPIV_SIZE_ERROR
} else {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
memset_s(
&mut apdu as (*mut u_APDU) as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<u_APDU>(),
0i32,
::std::mem::size_of::<u_APDU>()
);
(if res as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else if sw == 0x9000i32 {
if !pin.is_null() && (pin_len != 0) {
_cache_pin(state,pin,pin_len);
}
if !tries.is_null() {
*tries = sw & 0xfi32;
}
Enum5::YKPIV_OK
} else if sw >> 8i32 == 0x63i32 {
if !tries.is_null() {
*tries = sw & 0xfi32;
}
Enum5::YKPIV_WRONG_PIN
} else if sw == 0x6983i32 {
if !tries.is_null() {
*tries = 0i32;
}
Enum5::YKPIV_WRONG_PIN
} else {
Enum5::YKPIV_GENERIC_ERROR
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_verify_select(
mut state : *mut ykpiv_state,
mut pin : *const u8,
pin_len : usize,
mut tries : *mut i32,
mut force_select : bool
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if force_select {
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32) {
_currentBlock = 4;
} else {
_currentBlock = 3;
}
} else {
_currentBlock = 3;
}
if _currentBlock == 3 {
res = _verify(state,pin,pin_len,tries);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_get_pin_retries(
mut state : *mut ykpiv_state, mut tries : *mut i32
) -> Enum5 {
let mut res : Enum5;
let mut ykrc : Enum5;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state || 0i32 as (*mut ::std::os::raw::c_void) as (*mut i32) == tries {
Enum5::YKPIV_ARGUMENT_ERROR
} else {
res = _ykpiv_select_application(state);
(if res as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else {
ykrc = ykpiv_verify(
state,
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
tries
);
(if ykrc as (i32) == Enum5::YKPIV_WRONG_PIN as (i32) {
Enum5::YKPIV_OK as (i32)
} else {
ykrc as (i32)
}) as (Enum5)
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_set_pin_retries(
mut state : *mut ykpiv_state,
mut pin_tries : i32,
mut puk_tries : i32
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut data : [u8; 255];
let mut recv_len : usize = ::std::mem::size_of::<[u8; 255]>();
let mut sw : i32 = 0i32;
if pin_tries == 0i32 || puk_tries == 0i32 {
Enum5::YKPIV_OK
} else if pin_tries > 0xffi32 || puk_tries > 0xffi32 || pin_tries < 1i32 || puk_tries < 1i32 {
Enum5::YKPIV_RANGE_ERROR
} else {
*templ.offset(2isize) = pin_tries as (u8);
*templ.offset(3isize) = puk_tries as (u8);
(if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = ykpiv_transfer_data(
state,
templ as (*const u8),
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
0isize,
data.as_mut_ptr(),
&mut recv_len as (*mut usize),
&mut sw as (*mut i32)
);
if Enum5::YKPIV_OK as (i32) == res as (i32) {
if !(0x9000i32 == sw) {
if sw == 0x6983i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
} else if sw == 0x6982i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
} else {
res = Enum5::YKPIV_GENERIC_ERROR;
}
}
}
}
_ykpiv_end_transaction(state);
res
})
}
}
unsafe extern fn _ykpiv_change_pin(
mut state : *mut ykpiv_state,
mut action : i32,
mut current_pin : *const u8,
mut current_pin_len : usize,
mut new_pin : *const u8,
mut new_pin_len : usize,
mut tries : *mut i32
) -> Enum5 {
let mut sw : i32;
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut indata : [u8; 16];
let mut data : [u8; 255];
let mut recv_len : usize = ::std::mem::size_of::<[u8; 255]>();
let mut res : Enum5;
if current_pin_len > 8usize {
Enum5::YKPIV_SIZE_ERROR
} else if new_pin_len > 8usize {
Enum5::YKPIV_SIZE_ERROR
} else {
if action == 1i32 {
*templ.offset(1isize) = 0x2cu8;
} else if action == 2i32 {
*templ.offset(3isize) = 0x81u8;
}
memcpy(
indata.as_mut_ptr() as (*mut ::std::os::raw::c_void),
current_pin as (*const ::std::os::raw::c_void),
current_pin_len
);
if current_pin_len < 8usize {
memset(
indata.as_mut_ptr().offset(
current_pin_len as (isize)
) as (*mut ::std::os::raw::c_void),
0xffi32,
8usize.wrapping_sub(current_pin_len)
);
}
memcpy(
indata.as_mut_ptr().offset(
8isize
) as (*mut ::std::os::raw::c_void),
new_pin as (*const ::std::os::raw::c_void),
new_pin_len
);
if new_pin_len < 8usize {
memset(
indata.as_mut_ptr().offset(8isize).offset(
new_pin_len as (isize)
) as (*mut ::std::os::raw::c_void),
0xffi32,
8usize.wrapping_sub(new_pin_len)
);
}
res = ykpiv_transfer_data(
state,
templ as (*const u8),
indata.as_mut_ptr() as (*const u8),
::std::mem::size_of::<[u8; 16]>() as (isize),
data.as_mut_ptr(),
&mut recv_len as (*mut usize),
&mut sw as (*mut i32)
);
memset_s(
indata.as_mut_ptr() as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 16]>(),
0i32,
::std::mem::size_of::<[u8; 16]>()
);
(if res as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else if sw != 0x9000i32 {
(if sw >> 8i32 == 0x63i32 {
if !tries.is_null() {
*tries = sw & 0xfi32;
}
Enum5::YKPIV_WRONG_PIN
} else if sw == 0x6983i32 {
Enum5::YKPIV_PIN_LOCKED
} else {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed changing pin, token response code: %x.\n\0").as_ptr(),
sw
);
}
Enum5::YKPIV_GENERIC_ERROR
})
} else {
Enum5::YKPIV_OK
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_change_pin(
mut state : *mut ykpiv_state,
mut current_pin : *const u8,
mut current_pin_len : usize,
mut new_pin : *const u8,
mut new_pin_len : usize,
mut tries : *mut i32
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_GENERIC_ERROR;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = _ykpiv_change_pin(
state,
0i32,
current_pin,
current_pin_len,
new_pin,
new_pin_len,
tries
);
if res as (i32) == Enum5::YKPIV_OK as (i32) && (new_pin != 0i32 as (*mut ::std::os::raw::c_void) as (*const u8)) {
_cache_pin(state,new_pin,new_pin_len);
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_change_puk(
mut state : *mut ykpiv_state,
mut current_puk : *const u8,
mut current_puk_len : usize,
mut new_puk : *const u8,
mut new_puk_len : usize,
mut tries : *mut i32
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_GENERIC_ERROR;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = _ykpiv_change_pin(
state,
2i32,
current_puk,
current_puk_len,
new_puk,
new_puk_len,
tries
);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_unblock_pin(
mut state : *mut ykpiv_state,
mut puk : *const u8,
mut puk_len : usize,
mut new_pin : *const u8,
mut new_pin_len : usize,
mut tries : *mut i32
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_GENERIC_ERROR;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = _ykpiv_change_pin(
state,
1i32,
puk,
puk_len,
new_pin,
new_pin_len,
tries
);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_fetch_object(
mut state : *mut ykpiv_state,
mut object_id : i32,
mut data : *mut u8,
mut len : *mut usize
) -> Enum5 {
let mut res : Enum5;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = _ykpiv_fetch_object(state,object_id,data,len);
}
_ykpiv_end_transaction(state);
res
}
}
unsafe extern fn set_object(
mut object_id : i32, mut buffer : *mut u8
) -> *mut u8 {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 0x5cu8;
if object_id == 0x7ei32 {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 1u8;
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 0x7eu8;
} else if object_id > 0xffffi32 && (object_id <= 0xffffffi32) {
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = 3u8;
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = (object_id >> 16i32 & 0xffi32) as (u8);
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = (object_id >> 8i32 & 0xffi32) as (u8);
*{
let _old = buffer;
buffer = buffer.offset(1isize);
_old
} = (object_id & 0xffi32) as (u8);
}
buffer
}
#[no_mangle]
pub unsafe extern fn _ykpiv_fetch_object(
mut state : *mut ykpiv_state,
mut object_id : i32,
mut data : *mut u8,
mut len : *mut usize
) -> Enum5 {
let mut sw : i32;
let mut indata : [u8; 5];
let mut inptr : *mut u8 = indata.as_mut_ptr();
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut res : Enum5;
inptr = set_object(object_id,inptr);
if inptr == 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) {
Enum5::YKPIV_INVALID_OBJECT
} else if {
res = ykpiv_transfer_data(
state,
templ as (*const u8),
indata.as_mut_ptr() as (*const u8),
(inptr as (isize)).wrapping_sub(
indata.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize),
data,
len,
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else if sw == 0x9000i32 {
let mut outlen : usize = 0usize;
let mut offs : u32 = 0u32;
(if *len < 2usize || !_ykpiv_has_valid_length(
data.offset(1isize) as (*const u8),
(*len).wrapping_sub(1usize)
) {
Enum5::YKPIV_SIZE_ERROR
} else {
offs = _ykpiv_get_length(
data.offset(1isize) as (*const u8),
&mut outlen as (*mut usize)
);
(if offs == 0u32 {
Enum5::YKPIV_SIZE_ERROR
} else if outlen.wrapping_add(offs as (usize)).wrapping_add(
1usize
) != *len {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Invalid length indicated in object, total objlen is %lu, indicated length is %lu.\0").as_ptr(
),
*len,
outlen
);
}
Enum5::YKPIV_SIZE_ERROR
} else {
memmove(
data as (*mut ::std::os::raw::c_void),
data.offset(1isize).offset(
offs as (isize)
) as (*const ::std::os::raw::c_void),
outlen
);
*len = outlen;
Enum5::YKPIV_OK
})
})
} else {
Enum5::YKPIV_GENERIC_ERROR
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_save_object(
mut state : *mut ykpiv_state,
mut object_id : i32,
mut indata : *mut u8,
mut len : usize
) -> Enum5 {
let mut res : Enum5;
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
res = _ykpiv_save_object(state,object_id,indata,len);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn _ykpiv_save_object(
mut state : *mut ykpiv_state,
mut object_id : i32,
mut indata : *mut u8,
mut len : usize
) -> Enum5 {
let mut data : [u8; 3072];
let mut dataptr : *mut u8 = data.as_mut_ptr();
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut sw : i32;
let mut res : Enum5;
let mut outlen : usize = 0usize;
if len > ::std::mem::size_of::<[u8; 3072]>().wrapping_sub(9usize) {
Enum5::YKPIV_SIZE_ERROR
} else {
dataptr = set_object(object_id,dataptr);
(if dataptr == 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) {
Enum5::YKPIV_INVALID_OBJECT
} else {
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x53u8;
dataptr = dataptr.offset(
_ykpiv_set_length(dataptr,len) as (isize)
);
memcpy(
dataptr as (*mut ::std::os::raw::c_void),
indata as (*const ::std::os::raw::c_void),
len
);
dataptr = dataptr.offset(len as (isize));
(if {
res = _ykpiv_transfer_data(
state,
templ as (*const u8),
data.as_mut_ptr() as (*const u8),
(dataptr as (isize)).wrapping_sub(
data.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize),
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
&mut outlen as (*mut usize),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32) {
res
} else if 0x9000i32 == sw {
Enum5::YKPIV_OK
} else if 0x6982i32 == sw {
Enum5::YKPIV_AUTHENTICATION_ERROR
} else {
Enum5::YKPIV_GENERIC_ERROR
})
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_import_private_key(
mut state : *mut ykpiv_state,
key : u8,
mut algorithm : u8,
mut p : *const u8,
mut p_len : usize,
mut q : *const u8,
mut q_len : usize,
mut dp : *const u8,
mut dp_len : usize,
mut dq : *const u8,
mut dq_len : usize,
mut qinv : *const u8,
mut qinv_len : usize,
mut ec_data : *const u8,
mut ec_data_len : u8,
pin_policy : u8,
touch_policy : u8
) -> Enum5 {
let mut _currentBlock;
let mut key_data : [u8; 1024];
let mut in_ptr : *mut u8 = key_data.as_mut_ptr();
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut data : [u8; 256];
let mut recv_len : usize = ::std::mem::size_of::<[u8; 256]>();
let mut elem_len : u32;
let mut sw : i32;
let mut params : [*const u8; 5];
let mut lens : [usize; 5];
let mut padding : usize;
let mut n_params : u8;
let mut i : i32;
let mut param_tag : i32;
let mut res : Enum5;
if state == 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) {
Enum5::YKPIV_GENERIC_ERROR
} else if key as (i32) == 0x9bi32 || key as (i32) < 0x82i32 || key as (i32) > 0x95i32 && (key as (i32) < 0x9ai32) || key as (i32) > 0x9ei32 && (key as (i32) != 0xf9i32) {
Enum5::YKPIV_KEY_ERROR
} else if pin_policy as (i32) != 0i32 && (pin_policy as (i32) != 1i32) && (pin_policy as (i32) != 2i32) && (pin_policy as (i32) != 3i32) {
Enum5::YKPIV_GENERIC_ERROR
} else if touch_policy as (i32) != 0i32 && (touch_policy as (i32) != 1i32) && (touch_policy as (i32) != 2i32) && (touch_policy as (i32) != 3i32) {
Enum5::YKPIV_GENERIC_ERROR
} else {
if algorithm as (i32) == 0x6i32 || algorithm as (i32) == 0x7i32 {
if p_len.wrapping_add(q_len).wrapping_add(dp_len).wrapping_add(
dq_len
).wrapping_add(
qinv_len
) >= ::std::mem::size_of::<[u8; 1024]>() {
return Enum5::YKPIV_SIZE_ERROR;
} else {
if algorithm as (i32) == 0x6i32 {
elem_len = 64u32;
}
if algorithm as (i32) == 0x7i32 {
elem_len = 128u32;
}
if p == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) || q == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) || dp == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) || dq == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) || qinv == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) {
return Enum5::YKPIV_GENERIC_ERROR;
} else {
params[0usize] = p;
lens[0usize] = p_len;
params[1usize] = q;
lens[1usize] = q_len;
params[2usize] = dp;
lens[2usize] = dp_len;
params[3usize] = dq;
lens[3usize] = dq_len;
params[4usize] = qinv;
lens[4usize] = qinv_len;
param_tag = 0x1i32;
n_params = 5u8;
}
}
} else if algorithm as (i32) == 0x11i32 || algorithm as (i32) == 0x14i32 {
if ec_data_len as (usize) >= ::std::mem::size_of::<[u8; 1024]>() {
return Enum5::YKPIV_SIZE_ERROR;
} else {
if algorithm as (i32) == 0x11i32 {
elem_len = 32u32;
}
if algorithm as (i32) == 0x14i32 {
elem_len = 48u32;
}
if ec_data == 0i32 as (*mut ::std::os::raw::c_void) as (*const u8) {
return Enum5::YKPIV_GENERIC_ERROR;
} else {
params[0usize] = ec_data;
lens[0usize] = ec_data_len as (usize);
param_tag = 0x6i32;
n_params = 1u8;
}
}
} else {
return Enum5::YKPIV_ALGORITHM_ERROR;
}
i = 0i32;
'loop24: loop {
if !(i < n_params as (i32)) {
_currentBlock = 25;
break;
}
let mut remaining : usize;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = (param_tag + i) as (u8);
in_ptr = in_ptr.offset(
_ykpiv_set_length(in_ptr,elem_len as (usize)) as (isize)
);
padding = (elem_len as (usize)).wrapping_sub(lens[i as (usize)]);
remaining = (key_data.as_mut_ptr() as (usize)).wrapping_add(
::std::mem::size_of::<[u8; 1024]>()
).wrapping_sub(
in_ptr as (usize)
);
if padding > remaining {
_currentBlock = 39;
break;
}
memset(in_ptr as (*mut ::std::os::raw::c_void),0i32,padding);
in_ptr = in_ptr.offset(padding as (isize));
memcpy(
in_ptr as (*mut ::std::os::raw::c_void),
params[i as (usize)] as (*const ::std::os::raw::c_void),
lens[i as (usize)]
);
in_ptr = in_ptr.offset(lens[i as (usize)] as (isize));
i = i + 1;
}
if _currentBlock == 25 {
if pin_policy as (i32) != 0i32 {
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0xaau8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0x1u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = pin_policy;
}
if touch_policy as (i32) != 0i32 {
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0xabu8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0x1u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = touch_policy;
}
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
return Enum5::YKPIV_PCSC_ERROR;
} else if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(
state
);
res
} as (i32)) {
if !({
res = ykpiv_transfer_data(
state,
templ as (*const u8),
key_data.as_mut_ptr() as (*const u8),
(in_ptr as (isize)).wrapping_sub(
key_data.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize),
data.as_mut_ptr(),
&mut recv_len as (*mut usize),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
if 0x9000i32 != sw {
res = Enum5::YKPIV_GENERIC_ERROR;
if sw == 0x6982i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
}
}
}
}
} else {
res = Enum5::YKPIV_ALGORITHM_ERROR;
}
memset_s(
key_data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 1024]>(),
0i32,
::std::mem::size_of::<[u8; 1024]>()
);
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_attest(
mut state : *mut ykpiv_state,
key : u8,
mut data : *mut u8,
mut data_len : *mut usize
) -> Enum5 {
let mut res : Enum5;
let mut templ : *mut u8 = 0i32 as (*mut u8);
let mut sw : i32;
let mut ul_data_len : usize;
if state == 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) || data == 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) || data_len == 0i32 as (*mut ::std::os::raw::c_void) as (*mut usize) {
Enum5::YKPIV_ARGUMENT_ERROR
} else {
ul_data_len = *data_len;
(if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
if !({
res = ykpiv_transfer_data(
state,
templ as (*const u8),
0i32 as (*mut ::std::os::raw::c_void) as (*const u8),
0isize,
data,
&mut ul_data_len as (*mut usize),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
if 0x9000i32 != sw {
res = Enum5::YKPIV_GENERIC_ERROR;
if 0x6d00i32 == sw {
res = Enum5::YKPIV_NOT_SUPPORTED;
}
} else if *data.offset(0isize) as (i32) != 0x30i32 {
res = Enum5::YKPIV_GENERIC_ERROR;
} else {
*data_len = ul_data_len;
}
}
}
_ykpiv_end_transaction(state);
res
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_auth_getchallenge(
mut state : *mut ykpiv_state,
mut challenge : *mut u8,
challenge_len : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut apdu : u_APDU = 0i32 as (u_APDU);
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32 = 0i32;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == challenge {
Enum5::YKPIV_GENERIC_ERROR
} else if 8usize != challenge_len {
Enum5::YKPIV_SIZE_ERROR
} else if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
if !({
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
if sw != 0x9000i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
} else {
memcpy(
challenge as (*mut ::std::os::raw::c_void),
data.as_mut_ptr().offset(
4isize
) as (*const ::std::os::raw::c_void),
8usize
);
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_auth_verifyresponse(
mut state : *mut ykpiv_state,
mut response : *mut u8,
response_len : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut apdu : u_APDU = 0i32 as (u_APDU);
let mut data : [u8; 261];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 261]>() as (u32);
let mut sw : i32 = 0i32;
let mut dataptr : *mut u8 = 0i32 as (*mut u8);
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == response {
Enum5::YKPIV_GENERIC_ERROR
} else if 8usize != response_len {
Enum5::YKPIV_SIZE_ERROR
} else if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
Enum5::YKPIV_PCSC_ERROR
} else {
recv_len = ::std::mem::size_of::<[u8; 261]>() as (u32);
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x7cu8;
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0xau8;
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 0x82u8;
*{
let _old = dataptr;
dataptr = dataptr.offset(1isize);
_old
} = 8u8;
memcpy(
dataptr as (*mut ::std::os::raw::c_void),
response as (*const ::std::os::raw::c_void),
response_len
);
dataptr = dataptr.offset(8isize);
if !({
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) != Enum5::YKPIV_OK as (i32)) {
if sw != 0x9000i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
}
}
memset_s(
&mut apdu as (*mut u_APDU) as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<u_APDU>(),
0i32,
::std::mem::size_of::<u_APDU>()
);
_ykpiv_end_transaction(state);
res
}
}
static mut MGMT_AID : *const u8 = 0xa0i32 as (*const u8);
#[no_mangle]
pub unsafe extern fn ykpiv_auth_deauthenticate(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut apdu : u_APDU;
let mut data : [u8; 255];
let mut recv_len
: u32
= ::std::mem::size_of::<[u8; 255]>() as (u32);
let mut sw : i32;
if state.is_null() {
Enum5::YKPIV_ARGUMENT_ERROR
} else if {
res = _ykpiv_begin_transaction(state);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
res
} else {
if {
res = _send_data(
state,
&mut apdu as (*mut u_APDU),
data.as_mut_ptr(),
&mut recv_len as (*mut u32),
&mut sw as (*mut i32)
);
res
} as (i32) < Enum5::YKPIV_OK as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed communicating with card: \'%s\'\n\0").as_ptr(),
ykpiv_strerror(res)
);
}
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed selecting mgmt application: %04x\n\0").as_ptr(),
sw
);
}
res = Enum5::YKPIV_GENERIC_ERROR;
}
_ykpiv_end_transaction(state);
res
}
}