Files
yubikey.rs/lib/util.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

3215 lines
131 KiB
Rust

extern {
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 _ykpiv_alloc(
state : *mut ykpiv_state, size : usize
) -> *mut ::std::os::raw::c_void;
fn _ykpiv_begin_transaction(state : *mut ykpiv_state) -> Enum5;
fn _ykpiv_end_transaction(state : *mut ykpiv_state) -> Enum5;
fn _ykpiv_ensure_application_selected(
state : *mut ykpiv_state
) -> Enum5;
fn _ykpiv_fetch_object(
state : *mut ykpiv_state,
object_id : i32,
data : *mut u8,
len : *mut usize
) -> Enum5;
fn _ykpiv_free(
state : *mut ykpiv_state, data : *mut ::std::os::raw::c_void
);
fn _ykpiv_get_length(buffer : *const u8, len : *mut usize) -> u32;
fn _ykpiv_has_valid_length(
buffer : *const u8, len : usize
) -> bool;
fn _ykpiv_prng_generate(buffer : *mut u8, cb_req : usize) -> Enum7;
fn _ykpiv_realloc(
state : *mut ykpiv_state,
address : *mut ::std::os::raw::c_void,
size : usize
) -> *mut ::std::os::raw::c_void;
fn _ykpiv_save_object(
state : *mut ykpiv_state,
object_id : i32,
indata : *mut u8,
len : usize
) -> Enum5;
fn _ykpiv_set_length(buffer : *mut u8, length : usize) -> u32;
fn _ykpiv_transfer_data(
state : *mut ykpiv_state,
templ : *const u8,
in_data : *const u8,
in_len : isize,
out_data : *mut u8,
out_len : *mut usize,
sw : *mut i32
) -> Enum5;
fn fprintf(arg1 : *mut __sFILE, arg2 : *const u8, ...) -> 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_s(
__s : *mut ::std::os::raw::c_void,
__smax : usize,
__c : i32,
__n : usize
) -> i32;
fn pkcs5_pbkdf2_sha1(
password : *const u8,
cb_password : usize,
salt : *const u8,
cb_salt : usize,
iterations : usize,
key : *const u8,
cb_key : usize
) -> Enum11;
fn setting_get_bool(
sz_setting : *const u8, f_default : bool
) -> _setting_bool_t;
fn time(arg1 : *mut isize) -> isize;
fn ykpiv_change_puk(
state : *mut ykpiv_state,
current_puk : *const u8,
current_puk_len : usize,
new_puk : *const u8,
new_puk_len : usize,
tries : *mut i32
) -> Enum5;
fn ykpiv_set_mgmkey(
state : *mut ykpiv_state, new_key : *const u8
) -> Enum5;
fn ykpiv_transfer_data(
state : *mut ykpiv_state,
templ : *const u8,
in_data : *const u8,
in_len : isize,
out_data : *mut u8,
out_len : *mut usize,
sw : *mut i32
) -> Enum5;
}
enum __sFILEX {
}
#[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)
}
#[no_mangle]
pub static mut CHUID_TMPL : *const u8 = 0x30i32 as (*const u8);
#[no_mangle]
pub static mut CCC_TMPL : *const u8 = 0xf0i32 as (*const u8);
#[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,
}
#[derive(Copy)]
#[repr(C)]
pub struct Struct6 {
pub data : [u8; 16],
}
impl Clone for Struct6 {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_get_cardid(
mut state : *mut ykpiv_state, mut cardid : *mut Struct6
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3063];
let mut len : usize = ::std::mem::size_of::<[u8; 3063]>();
if cardid.is_null() {
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)) {
res = _ykpiv_fetch_object(
state,
0x5fc102i32,
buf.as_mut_ptr(),
&mut len as (*mut usize)
);
if Enum5::YKPIV_OK as (i32) == res as (i32) {
if len != 59usize {
res = Enum5::YKPIV_GENERIC_ERROR;
} else {
memcpy(
(*cardid).data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
buf.as_mut_ptr().offset(
29isize
) as (*const ::std::os::raw::c_void),
16usize
);
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[derive(Clone, Copy)]
#[repr(i32)]
pub enum Enum7 {
PRNG_OK = 0i32,
PRNG_GENERAL_ERROR = -1i32,
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_set_cardid(
mut state : *mut ykpiv_state, mut cardid : *const Struct6
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut id : [u8; 16];
let mut buf : [u8; 59];
let mut len : usize = 0usize;
if state.is_null() {
Enum5::YKPIV_GENERIC_ERROR
} else {
if cardid.is_null() {
if Enum7::PRNG_OK as (i32) != _ykpiv_prng_generate(
id.as_mut_ptr(),
::std::mem::size_of::<[u8; 16]>()
) as (i32) {
return Enum5::YKPIV_RANDOMNESS_ERROR;
}
} else {
memcpy(
id.as_mut_ptr() as (*mut ::std::os::raw::c_void),
(*cardid).data.as_mut_ptr() as (*const ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 16]>()
);
}
(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)) {
memcpy(
buf.as_mut_ptr() as (*mut ::std::os::raw::c_void),
CHUID_TMPL as (*const ::std::os::raw::c_void),
59usize
);
memcpy(
buf.as_mut_ptr().offset(29isize) as (*mut ::std::os::raw::c_void),
id.as_mut_ptr() as (*const ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 16]>()
);
len = 59usize;
res = _ykpiv_save_object(state,0x5fc102i32,buf.as_mut_ptr(),len);
}
_ykpiv_end_transaction(state);
res
})
}
}
#[derive(Copy)]
#[repr(C)]
pub struct Struct8 {
pub data : [u8; 14],
}
impl Clone for Struct8 {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_get_cccid(
mut state : *mut ykpiv_state, mut ccc : *mut Struct8
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3063];
let mut len : usize = ::std::mem::size_of::<[u8; 3063]>();
if ccc.is_null() {
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)) {
res = _ykpiv_fetch_object(
state,
0x5fc107i32,
buf.as_mut_ptr(),
&mut len as (*mut usize)
);
if Enum5::YKPIV_OK as (i32) == res as (i32) {
if len != 51usize {
res = Enum5::YKPIV_GENERIC_ERROR;
} else {
memcpy(
(*ccc).data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
buf.as_mut_ptr().offset(9isize) as (*const ::std::os::raw::c_void),
14usize
);
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_set_cccid(
mut state : *mut ykpiv_state, mut ccc : *const Struct8
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut id : [u8; 14];
let mut buf : [u8; 51];
let mut len : usize = 0usize;
if state.is_null() {
Enum5::YKPIV_GENERIC_ERROR
} else {
if ccc.is_null() {
if Enum7::PRNG_OK as (i32) != _ykpiv_prng_generate(
id.as_mut_ptr(),
::std::mem::size_of::<[u8; 14]>()
) as (i32) {
return Enum5::YKPIV_RANDOMNESS_ERROR;
}
} else {
memcpy(
id.as_mut_ptr() as (*mut ::std::os::raw::c_void),
(*ccc).data.as_mut_ptr() as (*const ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 14]>()
);
}
(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)) {
len = 51usize;
memcpy(
buf.as_mut_ptr() as (*mut ::std::os::raw::c_void),
CCC_TMPL as (*const ::std::os::raw::c_void),
len
);
memcpy(
buf.as_mut_ptr().offset(9isize) as (*mut ::std::os::raw::c_void),
id.as_mut_ptr() as (*const ::std::os::raw::c_void),
14usize
);
res = _ykpiv_save_object(state,0x5fc107i32,buf.as_mut_ptr(),len);
}
_ykpiv_end_transaction(state);
res
})
}
}
#[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 }
}
#[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_util_devicemodel(
mut state : *mut ykpiv_state
) -> u32 {
if state.is_null(
) || (*state).context == 0 || (*state).context as (usize) == -1i32 as (usize) {
0x0u32
} else {
(if (*state).isNEO {
0x4e450000i32 | 0x7233i32
} else {
0x594b0000i32 | 0x34i32
}) as (u32)
}
}
#[derive(Copy)]
#[repr(C)]
pub struct _ykpiv_key {
pub slot : u8,
pub cert_len : u16,
pub cert : [u8; 1],
}
impl Clone for _ykpiv_key {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_list_keys(
mut state : *mut ykpiv_state,
mut key_count : *mut u8,
mut data : *mut *mut _ykpiv_key,
mut data_len : *mut usize
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut pKey
: *mut _ykpiv_key
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_key);
let mut pData
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut pTemp
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cbData : usize = 0usize;
let mut offset : usize = 0usize;
let mut buf : [u8; 3072];
let mut cbBuf : usize = 0usize;
let mut i : usize = 0usize;
let mut cbRealloc : usize = 0usize;
let CB_PAGE : usize = 4096usize;
let mut SLOTS : *const u8 = 0x9ai32 as (*const u8);
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut *mut _ykpiv_key) == data || 0i32 as (*mut ::std::os::raw::c_void) as (*mut usize) == data_len || 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == key_count {
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)) {
*key_count = 0u8;
*data = 0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_key);
*data_len = 0usize;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == {
pData = _ykpiv_alloc(
state,
CB_PAGE
) as (*mut u8);
pData
} {
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
cbData = CB_PAGE;
i = 0usize;
'loop5: loop {
if !(i < ::std::mem::size_of::<*const u8>()) {
_currentBlock = 6;
break;
}
cbBuf = ::std::mem::size_of::<[u8; 3072]>();
res = _read_certificate(
state,
*SLOTS.offset(i as (isize)),
buf.as_mut_ptr(),
&mut cbBuf as (*mut usize)
);
if res as (i32) == Enum5::YKPIV_OK as (i32) && (cbBuf > 0usize) {
cbRealloc = if ::std::mem::size_of::<_ykpiv_key>().wrapping_add(
cbBuf
).wrapping_sub(
1usize
) > cbData.wrapping_sub(offset) {
(if ::std::mem::size_of::<_ykpiv_key>().wrapping_add(
cbBuf
).wrapping_sub(
1usize
).wrapping_sub(
cbData.wrapping_sub(offset)
) > CB_PAGE {
::std::mem::size_of::<_ykpiv_key>().wrapping_add(
cbBuf
).wrapping_sub(
1usize
).wrapping_sub(
cbData.wrapping_sub(offset)
)
} else {
CB_PAGE
})
} else {
0usize
};
if 0usize != cbRealloc {
if {
pTemp = _ykpiv_realloc(
state,
pData as (*mut ::std::os::raw::c_void),
cbData.wrapping_add(cbRealloc)
) as (*mut u8);
pTemp
}.is_null(
) {
_currentBlock = 15;
break;
}
pData = pTemp;
pTemp = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
}
cbData = cbData.wrapping_add(cbRealloc);
pKey = pData.offset(offset as (isize)) as (*mut _ykpiv_key);
(*pKey).slot = *SLOTS.offset(i as (isize));
(*pKey).cert_len = cbBuf as (u16);
memcpy(
(*pKey).cert.as_mut_ptr() as (*mut ::std::os::raw::c_void),
buf.as_mut_ptr() as (*const ::std::os::raw::c_void),
cbBuf
);
offset = offset.wrapping_add(
::std::mem::size_of::<_ykpiv_key>().wrapping_add(
cbBuf
).wrapping_sub(
1usize
)
);
*key_count = (*key_count as (i32) + 1) as (u8);
}
i = i.wrapping_add(1usize);
}
if _currentBlock == 6 {
*data = pData as (*mut _ykpiv_key);
pData = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
if !data_len.is_null() {
*data_len = offset;
}
res = Enum5::YKPIV_OK;
} else {
res = Enum5::YKPIV_MEMORY_ERROR;
}
}
}
if !pData.is_null() {
_ykpiv_free(state,pData as (*mut ::std::os::raw::c_void));
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_free(
mut state : *mut ykpiv_state,
mut data : *mut ::std::os::raw::c_void
) -> Enum5 {
if data.is_null() {
Enum5::YKPIV_OK
} else if state.is_null() || (*state).allocator.pfn_free == 0 {
Enum5::YKPIV_GENERIC_ERROR
} else {
_ykpiv_free(state,data);
Enum5::YKPIV_OK
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_read_cert(
mut state : *mut ykpiv_state,
mut slot : u8,
mut data : *mut *mut u8,
mut data_len : *mut usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3072];
let mut cbBuf : usize = ::std::mem::size_of::<[u8; 3072]>();
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut *mut u8) == data || 0i32 as (*mut ::std::os::raw::c_void) as (*mut usize) == data_len {
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)) {
*data = 0i32 as (*mut u8);
*data_len = 0usize;
if Enum5::YKPIV_OK as (i32) == {
res = _read_certificate(
state,
slot,
buf.as_mut_ptr(),
&mut cbBuf as (*mut usize)
);
res
} as (i32) {
if cbBuf == 0usize {
*data = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*data_len = 0usize;
} else if {
*data = _ykpiv_alloc(state,cbBuf) as (*mut u8);
*data
}.is_null(
) {
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
*data as (*mut ::std::os::raw::c_void),
buf.as_mut_ptr() as (*const ::std::os::raw::c_void),
cbBuf
);
*data_len = cbBuf;
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_write_cert(
mut state : *mut ykpiv_state,
mut slot : u8,
mut data : *mut u8,
mut data_len : usize,
mut certinfo : u8
) -> Enum5 {
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)) {
res = _write_certificate(state,slot,data,data_len,certinfo);
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_delete_cert(
mut state : *mut ykpiv_state, mut slot : u8
) -> Enum5 {
ykpiv_util_write_cert(
state,
slot,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize,
0u8
)
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_block_puk(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut puk : *mut u8 = 0x30i32 as (*mut u8);
let mut tries : i32 = -1i32;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut p_item
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_item : usize = 0usize;
let mut flags : u8 = 0u8;
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) {
_currentBlock = 20;
} else {
_currentBlock = 3;
}
'loop3: loop {
if _currentBlock == 3 {
if tries != 0i32 {
if Enum5::YKPIV_OK as (i32) == {
res = ykpiv_change_puk(
state,
puk as (*const u8),
::std::mem::size_of::<*mut u8>(),
puk as (*const u8),
::std::mem::size_of::<*mut u8>(),
&mut tries as (*mut i32)
);
res
} as (i32) {
let _rhs = 1;
let _lhs = &mut *puk.offset(0isize);
*_lhs = (*_lhs as (i32) + _rhs) as (u8);
_currentBlock = 3;
} else {
if !(Enum5::YKPIV_PIN_LOCKED as (i32) == res as (i32)) {
_currentBlock = 3;
continue;
}
tries = 0i32;
res = Enum5::YKPIV_OK;
_currentBlock = 3;
}
} else {
if Enum5::YKPIV_OK as (i32) == _read_metadata(
state,
0x80u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
) as (i32) {
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x81u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if ::std::mem::size_of::<u8>() == cb_item {
memcpy(
&mut flags as (*mut u8) as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
} else if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"admin flags exist, but are incorrect size = %lu\0").as_ptr(
),
cb_item
);
}
}
}
flags = (flags as (i32) | 0x1i32) as (u8);
if Enum5::YKPIV_OK as (i32) != _set_metadata_item(
data.as_mut_ptr(),
&mut cb_data as (*mut usize),
3063usize,
0x81u8,
&mut flags as (*mut u8),
::std::mem::size_of::<u8>()
) as (i32) {
if (*state).verbose == 0 {
_currentBlock = 20;
continue;
}
fprintf(__stderrp,(*b"could not set admin flags\0").as_ptr());
_currentBlock = 20;
} else {
if !(Enum5::YKPIV_OK as (i32) != _write_metadata(
state,
0x80u8,
data.as_mut_ptr(),
cb_data
) as (i32)) {
_currentBlock = 20;
continue;
}
if (*state).verbose == 0 {
_currentBlock = 20;
continue;
}
fprintf(__stderrp,(*b"could not write admin metadata\0").as_ptr());
_currentBlock = 20;
}
}
} else {
_ykpiv_end_transaction(state);
return res;
}
}
}
}
#[derive(Copy)]
#[repr(C)]
pub struct _ykpiv_container {
pub name : [i32; 40],
pub slot : u8,
pub key_spec : u8,
pub key_size_bits : u16,
pub flags : u8,
pub pin_id : u8,
pub associated_echd_container : u8,
pub cert_fingerprint : [u8; 20],
}
impl Clone for _ykpiv_container {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_read_mscmap(
mut state : *mut ykpiv_state,
mut containers : *mut *mut _ykpiv_container,
mut n_containers : *mut usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3072];
let mut cbBuf : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut len : usize = 0usize;
let mut ptr
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut *mut _ykpiv_container) == containers || 0i32 as (*mut ::std::os::raw::c_void) as (*mut usize) == n_containers {
res = Enum5::YKPIV_GENERIC_ERROR;
} else 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)) {
*containers = 0i32 as (*mut _ykpiv_container);
*n_containers = 0usize;
if Enum5::YKPIV_OK as (i32) == {
res = _ykpiv_fetch_object(
state,
0x5fff10i32,
buf.as_mut_ptr(),
&mut cbBuf as (*mut usize)
);
res
} as (i32) {
ptr = buf.as_mut_ptr();
if cbBuf < 2usize {
res = Enum5::YKPIV_OK;
} else if *{
let _old = ptr;
ptr = ptr.offset(1isize);
_old
} as (i32) == 0x81i32 {
ptr = ptr.offset(
_ykpiv_get_length(
ptr as (*const u8),
&mut len as (*mut usize)
) as (usize) as (isize)
);
if len > cbBuf.wrapping_sub(
((ptr as (isize)).wrapping_sub(
buf.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
) {
res = Enum5::YKPIV_OK;
} else if 0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_container) == {
*containers = _ykpiv_alloc(
state,
len
) as (*mut _ykpiv_container);
*containers
} {
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
*containers as (*mut ::std::os::raw::c_void),
ptr as (*const ::std::os::raw::c_void),
len
);
*n_containers = len.wrapping_div(
::std::mem::size_of::<_ykpiv_container>()
);
}
}
}
}
_ykpiv_end_transaction(state);
res
}
unsafe extern fn _obj_size_max(
mut state : *mut ykpiv_state
) -> usize {
(if !state.is_null() && (*state).isNEO {
2048i32 - 9i32
} else {
3063i32
}) as (usize)
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_write_mscmap(
mut state : *mut ykpiv_state,
mut containers : *mut _ykpiv_container,
mut n_containers : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3063];
let mut offset : usize = 0usize;
let mut req_len : usize = 0usize;
let mut data_len
: usize
= n_containers.wrapping_mul(
::std::mem::size_of::<_ykpiv_container>()
);
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 (*mut _ykpiv_container) == containers || 0usize == n_containers {
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_container) != containers || 0usize != n_containers {
res = Enum5::YKPIV_GENERIC_ERROR;
} else {
res = _ykpiv_save_object(
state,
0x5fff10i32,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize
);
}
} else {
req_len = 1usize.wrapping_add(
_ykpiv_set_length(buf.as_mut_ptr(),data_len) as (usize)
).wrapping_add(
data_len
);
if req_len > _obj_size_max(state) {
res = Enum5::YKPIV_SIZE_ERROR;
} else {
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0x81u8;
offset = offset.wrapping_add(
_ykpiv_set_length(
buf.as_mut_ptr().offset(offset as (isize)),
data_len
) as (usize)
);
memcpy(
buf.as_mut_ptr().offset(
offset as (isize)
) as (*mut ::std::os::raw::c_void),
containers as (*mut u8) as (*const ::std::os::raw::c_void),
data_len
);
offset = offset.wrapping_add(data_len);
res = _ykpiv_save_object(
state,
0x5fff10i32,
buf.as_mut_ptr(),
offset
);
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_read_msroots(
mut state : *mut ykpiv_state,
mut data : *mut *mut u8,
mut data_len : *mut usize
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3072];
let mut cbBuf : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut len : usize = 0usize;
let mut ptr
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut object_id : i32 = 0i32;
let mut tag : u8 = 0u8;
let mut pData
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut pTemp
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cbData : usize = 0usize;
let mut cbRealloc : usize = 0usize;
let mut offset : usize = 0usize;
if data.is_null() || data_len.is_null() {
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)) {
*data = 0i32 as (*mut u8);
*data_len = 0usize;
cbData = _obj_size_max(state);
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == {
pData = _ykpiv_alloc(
state,
cbData
) as (*mut u8);
pData
} {
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
object_id = 0x5fff11i32;
'loop5: loop {
if !(object_id <= 0x5fff15i32) {
_currentBlock = 15;
break;
}
cbBuf = ::std::mem::size_of::<[u8; 3072]>();
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_fetch_object(
state,
object_id,
buf.as_mut_ptr(),
&mut cbBuf as (*mut usize)
);
res
} as (i32) {
_currentBlock = 21;
break;
}
ptr = buf.as_mut_ptr();
if cbBuf < 2usize {
_currentBlock = 19;
break;
}
tag = *{
let _old = ptr;
ptr = ptr.offset(1isize);
_old
};
if 0x83i32 != tag as (i32) && (0x82i32 != tag as (i32)) || 0x5fff15i32 == object_id && (0x82i32 != tag as (i32)) {
_currentBlock = 18;
break;
}
ptr = ptr.offset(
_ykpiv_get_length(
ptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
if len > cbBuf.wrapping_sub(
((ptr as (isize)).wrapping_sub(
buf.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
) {
_currentBlock = 17;
break;
}
cbRealloc = if len > cbData.wrapping_sub(offset) {
len.wrapping_sub(cbData.wrapping_sub(offset))
} else {
0usize
};
if 0usize != cbRealloc {
if {
pTemp = _ykpiv_realloc(
state,
pData as (*mut ::std::os::raw::c_void),
cbData.wrapping_add(cbRealloc)
) as (*mut u8);
pTemp
}.is_null(
) {
_currentBlock = 16;
break;
}
pData = pTemp;
pTemp = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
}
cbData = cbData.wrapping_add(cbRealloc);
memcpy(
pData.offset(offset as (isize)) as (*mut ::std::os::raw::c_void),
ptr as (*const ::std::os::raw::c_void),
len
);
offset = offset.wrapping_add(len);
if 0x82i32 == tag as (i32) {
_currentBlock = 15;
break;
}
object_id = object_id + 1;
}
if _currentBlock == 21 {
} else if _currentBlock == 15 {
*data = pData;
pData = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*data_len = offset;
res = Enum5::YKPIV_OK;
} else if _currentBlock == 16 {
res = Enum5::YKPIV_MEMORY_ERROR;
} else if _currentBlock == 17 {
res = Enum5::YKPIV_OK;
} else if _currentBlock == 18 {
res = Enum5::YKPIV_OK;
} else {
res = Enum5::YKPIV_OK;
}
}
}
if !pData.is_null() {
_ykpiv_free(state,pData as (*mut ::std::os::raw::c_void));
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_write_msroots(
mut state : *mut ykpiv_state,
mut data : *mut u8,
mut data_len : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3063];
let mut offset : usize = 0usize;
let mut data_offset : usize = 0usize;
let mut data_chunk : usize = 0usize;
let mut n_objs : usize = 0usize;
let mut i : u32 = 0u32;
let mut cb_obj_max : usize = _obj_size_max(state);
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 (*mut u8) == data || 0usize == data_len {
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) != data || 0usize != data_len {
res = Enum5::YKPIV_GENERIC_ERROR;
} else {
res = _ykpiv_save_object(
state,
0x5fff11i32,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize
);
}
} else {
n_objs = data_len.wrapping_div(
cb_obj_max.wrapping_sub((2i32 + 2i32) as (usize))
).wrapping_add(
1usize
);
if n_objs > 5usize {
res = Enum5::YKPIV_SIZE_ERROR;
} else {
i = 0u32;
'loop5: loop {
if !(i as (usize) < n_objs) {
break;
}
offset = 0usize;
data_chunk = if cb_obj_max.wrapping_sub(
(2i32 + 2i32) as (usize)
) < data_len.wrapping_sub(data_offset) {
cb_obj_max.wrapping_sub((2i32 + 2i32) as (usize))
} else {
data_len.wrapping_sub(data_offset)
};
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = if i as (usize) == n_objs.wrapping_sub(1usize) {
0x82i32
} else {
0x83i32
} as (u8);
offset = offset.wrapping_add(
_ykpiv_set_length(
buf.as_mut_ptr().offset(offset as (isize)),
data_chunk
) as (usize)
);
memcpy(
buf.as_mut_ptr().offset(
offset as (isize)
) as (*mut ::std::os::raw::c_void),
data.offset(
data_offset as (isize)
) as (*const ::std::os::raw::c_void),
data_chunk
);
offset = offset.wrapping_add(data_chunk);
res = _ykpiv_save_object(
state,
0x5fff11u32.wrapping_add(i) as (i32),
buf.as_mut_ptr(),
offset
);
if Enum5::YKPIV_OK as (i32) != res as (i32) {
break;
}
data_offset = data_offset.wrapping_add(data_chunk);
i = i.wrapping_add(1u32);
}
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[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 ykpiv_util_generate_key(
mut state : *mut ykpiv_state,
mut slot : u8,
mut algorithm : u8,
mut pin_policy : u8,
mut touch_policy : u8,
mut modulus : *mut *mut u8,
mut modulus_len : *mut usize,
mut exp : *mut *mut u8,
mut exp_len : *mut usize,
mut point : *mut *mut u8,
mut point_len : *mut usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut in_data : [u8; 11];
let mut in_ptr : *mut u8 = in_data.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 sw : i32;
let mut ptr_modulus
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_modulus : usize = 0usize;
let mut ptr_exp
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_exp : usize = 0usize;
let mut ptr_point
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_point : usize = 0usize;
let mut setting_roca : _setting_bool_t;
let mut sz_setting_roca
: *const u8
= (*b"Enable_Unsafe_Keygen_ROCA\0").as_ptr();
let mut sz_roca_format
: *const u8
= (*b"YubiKey serial number %u is affected by vulnerability 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/> for additional information on device replacement and mitigation assistance.\n\0").as_ptr(
);
let mut sz_roca_allow_user
: *const u8
= (*b"was permitted by an end-user configuration setting, but is not recommended.\0").as_ptr(
);
let mut sz_roca_allow_admin
: *const u8
= (*b"was permitted by an administrator configuration setting, but is not recommended.\0").as_ptr(
);
let mut sz_roca_block_user
: *const u8
= (*b"was blocked due to an end-user configuration setting.\0").as_ptr(
);
let mut sz_roca_block_admin
: *const u8
= (*b"was blocked due to an administrator configuration setting.\0").as_ptr(
);
let mut sz_roca_default
: *const u8
= (*b"was permitted by default, but is not recommended. The default behavior will change in a future Yubico release.\0").as_ptr(
);
if state.is_null() {
Enum5::YKPIV_ARGUMENT_ERROR
} else {
if ykpiv_util_devicemodel(
state
) == (0x594b0000i32 | 0x34i32) as (u32) && (algorithm as (i32) == 0x6i32 || algorithm as (i32) == 0x7i32) {
if (*state).ver.major as (i32) == 4i32 && ((*state).ver.minor as (i32) < 3i32 || (*state).ver.minor as (i32) == 3i32 && ((*state).ver.patch as (i32) < 5i32)) {
let mut psz_msg
: *const u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*const u8);
setting_roca = setting_get_bool(sz_setting_roca,true);
let switch9 = setting_roca.source;
if switch9 as (i32) == _setting_source_t::SETTING_SOURCE_USER as (i32) {
psz_msg = if setting_roca.value {
sz_roca_allow_user
} else {
sz_roca_block_user
};
} else if switch9 as (i32) == _setting_source_t::SETTING_SOURCE_ADMIN as (i32) {
psz_msg = if setting_roca.value {
sz_roca_allow_admin
} else {
sz_roca_block_admin
};
} else {
psz_msg = sz_roca_default;
}
fprintf(__stderrp,sz_roca_format,(*state).serial,psz_msg);
if !setting_roca.value {
return Enum5::YKPIV_NOT_SUPPORTED;
}
}
}
if algorithm as (i32) == 0x14i32 || algorithm as (i32) == 0x11i32 {
if point.is_null() || point_len.is_null() {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Invalid output parameter for ECC algorithm\0").as_ptr()
);
}
return Enum5::YKPIV_GENERIC_ERROR;
} else {
*point = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*point_len = 0usize;
}
} else if algorithm as (i32) == 0x7i32 || algorithm as (i32) == 0x6i32 {
if modulus.is_null() || modulus_len.is_null() || exp.is_null(
) || exp_len.is_null() {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Invalid output parameter for RSA algorithm\0").as_ptr()
);
}
return Enum5::YKPIV_GENERIC_ERROR;
} else {
*modulus = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*modulus_len = 0usize;
*exp = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*exp_len = 0usize;
}
} else {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Invalid algorithm specified\0").as_ptr());
}
return 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)) {
*templ.offset(3isize) = slot;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0xacu8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 3u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0x80u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 1u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = algorithm;
if in_data[4usize] as (i32) == 0i32 {
res = Enum5::YKPIV_ALGORITHM_ERROR;
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Unexpected algorithm.\n\0").as_ptr());
}
} else {
if pin_policy as (i32) != 0i32 {
let _rhs = 3i32;
let _lhs = &mut in_data[1usize];
*_lhs = (*_lhs as (i32) + _rhs) as (u8);
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0xaau8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 1u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = pin_policy;
}
if touch_policy as (i32) != 0i32 {
let _rhs = 3i32;
let _lhs = &mut in_data[1usize];
*_lhs = (*_lhs as (i32) + _rhs) as (u8);
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 0xabu8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = 1u8;
*{
let _old = in_ptr;
in_ptr = in_ptr.offset(1isize);
_old
} = touch_policy;
}
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_transfer_data(
state,
templ as (*const u8),
in_data.as_mut_ptr(
) as (*const u8),
(in_ptr as (isize)).wrapping_sub(
in_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) {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Failed to communicate.\n\0").as_ptr());
}
} else if sw != 0x9000i32 {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Failed to generate new key (\0").as_ptr());
}
if sw == 0x6b00i32 {
res = Enum5::YKPIV_KEY_ERROR;
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"incorrect slot)\n\0").as_ptr());
}
} else if sw == 0x6a80i32 {
res = Enum5::YKPIV_ALGORITHM_ERROR;
if (*state).verbose != 0 {
if pin_policy as (i32) != 0i32 {
fprintf(
__stderrp,
(*b"pin policy not supported?)\n\0").as_ptr()
);
} else if touch_policy as (i32) != 0i32 {
fprintf(
__stderrp,
(*b"touch policy not supported?)\n\0").as_ptr()
);
} else {
fprintf(
__stderrp,
(*b"algorithm not supported?)\n\0").as_ptr()
);
}
}
} else if sw == 0x6982i32 {
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"not authenticated)\n\0").as_ptr());
}
} else {
res = Enum5::YKPIV_GENERIC_ERROR;
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"error %x)\n\0").as_ptr(),sw);
}
}
} else if 0x6i32 == algorithm as (i32) || 0x7i32 == algorithm as (i32) {
let mut data_ptr : *mut u8 = data.as_mut_ptr().offset(5isize);
let mut len : usize = 0usize;
if *data_ptr as (i32) != 0x81i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to parse public key structure (modulus).\n\0").as_ptr(
)
);
}
res = Enum5::YKPIV_PARSE_ERROR;
} else {
data_ptr = data_ptr.offset(1isize);
data_ptr = data_ptr.offset(
_ykpiv_get_length(
data_ptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
cb_modulus = len;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == {
ptr_modulus = _ykpiv_alloc(
state,
cb_modulus
) as (*mut u8);
ptr_modulus
} {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to allocate memory for modulus.\n\0").as_ptr()
);
}
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
ptr_modulus as (*mut ::std::os::raw::c_void),
data_ptr as (*const ::std::os::raw::c_void),
cb_modulus
);
data_ptr = data_ptr.offset(len as (isize));
if *data_ptr as (i32) != 0x82i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to parse public key structure (public exponent).\n\0").as_ptr(
)
);
}
res = Enum5::YKPIV_PARSE_ERROR;
} else {
data_ptr = data_ptr.offset(1isize);
data_ptr = data_ptr.offset(
_ykpiv_get_length(
data_ptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
cb_exp = len;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == {
ptr_exp = _ykpiv_alloc(
state,
cb_exp
) as (*mut u8);
ptr_exp
} {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to allocate memory for public exponent.\n\0").as_ptr(
)
);
}
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
ptr_exp as (*mut ::std::os::raw::c_void),
data_ptr as (*const ::std::os::raw::c_void),
cb_exp
);
*modulus = ptr_modulus;
ptr_modulus = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*modulus_len = cb_modulus;
*exp = ptr_exp;
ptr_exp = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*exp_len = cb_exp;
}
}
}
}
} else if 0x11i32 == algorithm as (i32) || 0x14i32 == algorithm as (i32) {
let mut data_ptr : *mut u8 = data.as_mut_ptr().offset(3isize);
let mut len : usize;
if 0x11i32 == algorithm as (i32) {
len = 65usize;
} else {
len = 97usize;
}
if *{
let _old = data_ptr;
data_ptr = data_ptr.offset(1isize);
_old
} as (i32) != 0x86i32 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to parse public key structure.\n\0").as_ptr()
);
}
res = Enum5::YKPIV_PARSE_ERROR;
} else if *{
let _old = data_ptr;
data_ptr = data_ptr.offset(1isize);
_old
} as (usize) != len {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Unexpected length.\n\0").as_ptr());
}
res = Enum5::YKPIV_ALGORITHM_ERROR;
} else {
cb_point = len;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == {
ptr_point = _ykpiv_alloc(
state,
cb_point
) as (*mut u8);
ptr_point
} {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"Failed to allocate memory for public point.\n\0").as_ptr(
)
);
}
res = Enum5::YKPIV_MEMORY_ERROR;
} else {
memcpy(
ptr_point as (*mut ::std::os::raw::c_void),
data_ptr as (*const ::std::os::raw::c_void),
cb_point
);
*point = ptr_point;
ptr_point = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*point_len = cb_point;
}
}
} else {
if (*state).verbose != 0 {
fprintf(__stderrp,(*b"Wrong algorithm.\n\0").as_ptr());
}
res = Enum5::YKPIV_ALGORITHM_ERROR;
}
}
}
if !ptr_modulus.is_null() {
_ykpiv_free(state,modulus as (*mut ::std::os::raw::c_void));
}
if !ptr_exp.is_null() {
_ykpiv_free(state,ptr_exp as (*mut ::std::os::raw::c_void));
}
if !ptr_point.is_null() {
_ykpiv_free(state,ptr_exp as (*mut ::std::os::raw::c_void));
}
_ykpiv_end_transaction(state);
res
})
}
}
#[derive(Clone, Copy)]
#[repr(i32)]
pub enum Enum10 {
YKPIV_CONFIG_MGM_MANUAL = 0i32,
YKPIV_CONFIG_MGM_DERIVED = 1i32,
YKPIV_CONFIG_MGM_PROTECTED = 2i32,
}
#[derive(Copy)]
#[repr(C)]
pub struct _ykpiv_config {
pub protected_data_available : u8,
pub puk_blocked : u8,
pub puk_noblock_on_upgrade : u8,
pub pin_last_changed : u32,
pub mgm_type : Enum10,
}
impl Clone for _ykpiv_config {
fn clone(&self) -> Self { *self }
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_get_config(
mut state : *mut ykpiv_state, mut config : *mut _ykpiv_config
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut p_item
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_item : usize = 0usize;
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 _ykpiv_config) == config {
Enum5::YKPIV_GENERIC_ERROR
} else {
(*config).protected_data_available = 0u8;
(*config).puk_blocked = 0u8;
(*config).puk_noblock_on_upgrade = 0u8;
(*config).pin_last_changed = 0u32;
(*config).mgm_type = Enum10::YKPIV_CONFIG_MGM_MANUAL;
(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 Enum5::YKPIV_OK as (i32) == _read_metadata(
state,
0x80u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
) as (i32) {
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x81u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if *p_item as (i32) & 0x1i32 != 0 {
(*config).puk_blocked = 1u8;
}
if *p_item as (i32) & 0x2i32 != 0 {
(*config).mgm_type = Enum10::YKPIV_CONFIG_MGM_PROTECTED;
}
}
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x82u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if (*config).mgm_type as (i32) != Enum10::YKPIV_CONFIG_MGM_MANUAL as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"conflicting types of mgm key administration configured\n\0").as_ptr(
)
);
}
} else {
(*config).mgm_type = Enum10::YKPIV_CONFIG_MGM_DERIVED;
}
}
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x83u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if 4usize != cb_item {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"pin timestamp in admin metadata is an invalid size\0").as_ptr(
)
);
}
} else {
memcpy(
&mut (*config).pin_last_changed as (*mut u32) as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
}
}
}
cb_data = ::std::mem::size_of::<[u8; 3072]>();
if Enum5::YKPIV_OK as (i32) == _read_metadata(
state,
0x88u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
) as (i32) {
(*config).protected_data_available = 1u8;
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x81u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if *p_item as (i32) & 0x1i32 != 0 {
(*config).puk_noblock_on_upgrade = 1u8;
}
}
if Enum5::YKPIV_OK as (i32) == _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x89u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
) as (i32) {
if (*config).mgm_type as (i32) != Enum10::YKPIV_CONFIG_MGM_PROTECTED as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"conflicting types of mgm key administration configured - protected mgm exists\n\0").as_ptr(
)
);
}
}
(*config).mgm_type = Enum10::YKPIV_CONFIG_MGM_PROTECTED;
}
}
}
_ykpiv_end_transaction(state);
res
})
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_set_pin_last_changed(
mut state : *mut ykpiv_state
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut ykrc : Enum5 = Enum5::YKPIV_OK;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut tnow : isize = 0isize;
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 Enum5::YKPIV_OK as (i32) != {
ykrc = _read_metadata(
state,
0x80u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
);
ykrc
} as (i32) {
cb_data = 0usize;
}
tnow = time(0i32 as (*mut ::std::os::raw::c_void) as (*mut isize));
if Enum5::YKPIV_OK as (i32) != {
res = _set_metadata_item(
data.as_mut_ptr(),
&mut cb_data as (*mut usize),
3063usize,
0x83u8,
&mut tnow as (*mut isize) as (*mut u8),
4usize
);
res
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not set pin timestamp, err = %d\n\0").as_ptr(),
res as (i32)
);
}
} else if Enum5::YKPIV_OK as (i32) != {
res = _write_metadata(
state,
0x80u8,
data.as_mut_ptr(),
cb_data
);
res
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not write admin data, err = %d\n\0").as_ptr(),
res as (i32)
);
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[derive(Copy)]
#[repr(C)]
pub struct _ykpiv_mgm {
pub data : [u8; 24],
}
impl Clone for _ykpiv_mgm {
fn clone(&self) -> Self { *self }
}
#[derive(Clone, Copy)]
#[repr(i32)]
pub enum Enum11 {
PKCS5_OK = 0i32,
PKCS5_GENERAL_ERROR = -1i32,
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_get_derived_mgm(
mut state : *mut ykpiv_state,
mut pin : *const u8,
pin_len : usize,
mut mgm : *mut _ykpiv_mgm
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut p5rc : Enum11 = Enum11::PKCS5_OK;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut p_item
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_item : usize = 0usize;
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 (*const u8) == pin || 0usize == pin_len || 0i32 as (*mut ::std::os::raw::c_void) as (*mut _ykpiv_mgm) == mgm {
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 Enum5::YKPIV_OK as (i32) == {
res = _read_metadata(
state,
0x80u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
);
res
} as (i32) {
if Enum5::YKPIV_OK as (i32) == {
res = _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x82u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
);
res
} as (i32) {
if cb_item != 16usize {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"derived mgm salt exists, but is incorrect size = %lu\n\0").as_ptr(
),
cb_item
);
}
res = Enum5::YKPIV_GENERIC_ERROR;
} else if Enum11::PKCS5_OK as (i32) != {
p5rc = pkcs5_pbkdf2_sha1(
pin,
pin_len,
p_item as (*const u8),
cb_item,
10000usize,
(*mgm).data.as_mut_ptr(
) as (*const u8),
::std::mem::size_of::<[u8; 24]>(
)
);
p5rc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"pbkdf2 failure, err = %d\n\0").as_ptr(),
p5rc as (i32)
);
}
res = Enum5::YKPIV_GENERIC_ERROR;
}
}
}
}
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_get_protected_mgm(
mut state : *mut ykpiv_state, mut mgm : *mut _ykpiv_mgm
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut p_item
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_item : usize = 0usize;
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 _ykpiv_mgm) == mgm {
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 Enum5::YKPIV_OK as (i32) != {
res = _read_metadata(
state,
0x88u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
);
res
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not read protected data, err = %d\n\0").as_ptr(),
res as (i32)
);
}
} else if Enum5::YKPIV_OK as (i32) != {
res = _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x89u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
);
res
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not read protected mgm from metadata, err = %d\n\0").as_ptr(
),
res as (i32)
);
}
} else if cb_item != ::std::mem::size_of::<[u8; 24]>() {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"protected data contains mgm, but is the wrong size = %lu\n\0").as_ptr(
),
cb_item
);
}
res = Enum5::YKPIV_AUTHENTICATION_ERROR;
} else {
memcpy(
(*mgm).data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
}
}
memset_s(
data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 3072]>(),
0i32,
::std::mem::size_of::<[u8; 3072]>()
);
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_set_protected_mgm(
mut state : *mut ykpiv_state, mut mgm : *mut _ykpiv_mgm
) -> Enum5 {
let mut _currentBlock;
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut ykrc : Enum5 = Enum5::YKPIV_OK;
let mut prngrc : Enum7 = Enum7::PRNG_OK;
let mut fGenerate : bool = false;
let mut mgm_key : [u8; 24];
let mut i : usize = 0usize;
let mut data : [u8; 3072];
let mut cb_data : usize = ::std::mem::size_of::<[u8; 3072]>();
let mut p_item
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_item : usize = 0usize;
let mut flags_1 : u8 = 0u8;
if 0i32 as (*mut ::std::os::raw::c_void) as (*mut ykpiv_state) == state {
Enum5::YKPIV_GENERIC_ERROR
} else {
if mgm.is_null() {
fGenerate = true;
} else {
fGenerate = true;
memcpy(
mgm_key.as_mut_ptr() as (*mut ::std::os::raw::c_void),
(*mgm).data.as_mut_ptr() as (*const ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 24]>()
);
i = 0usize;
'loop3: loop {
if !(i < ::std::mem::size_of::<[u8; 24]>()) {
_currentBlock = 8;
break;
}
if mgm_key[i] as (i32) != 0i32 {
_currentBlock = 6;
break;
}
i = i.wrapping_add(1usize);
}
if _currentBlock == 8 {
} else {
fGenerate = false;
}
}
if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_begin_transaction(state);
res
} as (i32) {
res = Enum5::YKPIV_PCSC_ERROR;
} else if !(Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_ensure_application_selected(state);
res
} as (i32)) {
'loop10: loop {
if fGenerate {
if Enum7::PRNG_OK as (i32) != {
prngrc = _ykpiv_prng_generate(
mgm_key.as_mut_ptr(),
::std::mem::size_of::<[u8; 24]>()
);
prngrc
} as (i32) {
_currentBlock = 47;
break;
}
}
if Enum5::YKPIV_OK as (i32) != {
ykrc = ykpiv_set_mgmkey(
state,
mgm_key.as_mut_ptr() as (*const u8)
);
ykrc
} as (i32) {
if Enum5::YKPIV_KEY_ERROR as (i32) != ykrc as (i32) {
_currentBlock = 44;
break;
}
} else {
fGenerate = false;
}
if !fGenerate {
_currentBlock = 16;
break;
}
}
if _currentBlock == 16 {
if !mgm.is_null() {
memcpy(
(*mgm).data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
mgm_key.as_mut_ptr() as (*const ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 24]>()
);
}
if Enum5::YKPIV_OK as (i32) != {
ykrc = _read_metadata(
state,
0x88u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
);
ykrc
} as (i32) {
cb_data = 0usize;
}
if Enum5::YKPIV_OK as (i32) != {
ykrc = _set_metadata_item(
data.as_mut_ptr(),
&mut cb_data as (*mut usize),
3063usize,
0x89u8,
mgm_key.as_mut_ptr(),
::std::mem::size_of::<[u8; 24]>()
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not set protected mgm item, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
_currentBlock = 26;
} else {
_currentBlock = 26;
}
} else if Enum5::YKPIV_OK as (i32) != {
ykrc = _write_metadata(
state,
0x88u8,
data.as_mut_ptr(),
cb_data
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not write protected data, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
_currentBlock = 51;
} else {
_currentBlock = 51;
}
} else {
_currentBlock = 26;
}
if _currentBlock == 51 {
} else {
cb_data = ::std::mem::size_of::<[u8; 3072]>();
if Enum5::YKPIV_OK as (i32) != {
ykrc = _read_metadata(
state,
0x80u8,
data.as_mut_ptr(),
&mut cb_data as (*mut usize)
);
ykrc
} as (i32) {
cb_data = 0usize;
} else {
if Enum5::YKPIV_OK as (i32) != {
ykrc = _get_metadata_item(
data.as_mut_ptr(),
cb_data,
0x81u8,
&mut p_item as (*mut *mut u8),
&mut cb_item as (*mut usize)
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"admin data exists, but flags are not present\n\0").as_ptr()
);
}
}
if cb_item == ::std::mem::size_of::<u8>() {
memcpy(
&mut flags_1 as (*mut u8) as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
} else if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"admin data flags are an incorrect size = %lu\n\0").as_ptr(),
cb_item
);
}
if Enum5::YKPIV_OK as (i32) != {
ykrc = _set_metadata_item(
data.as_mut_ptr(),
&mut cb_data as (*mut usize),
3063usize,
0x82u8,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not unset derived mgm salt, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
}
}
}
flags_1 = (flags_1 as (i32) | 0x2i32) as (u8);
if Enum5::YKPIV_OK as (i32) != {
ykrc = _set_metadata_item(
data.as_mut_ptr(),
&mut cb_data as (*mut usize),
3063usize,
0x81u8,
&mut flags_1 as (*mut u8),
::std::mem::size_of::<u8>()
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not set admin flags item, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
}
} else if Enum5::YKPIV_OK as (i32) != {
ykrc = _write_metadata(
state,
0x80u8,
data.as_mut_ptr(),
cb_data
);
ykrc
} as (i32) {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not write admin data, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
}
}
}
} else if _currentBlock == 44 {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not set new derived mgm key, err = %d\n\0").as_ptr(),
ykrc as (i32)
);
}
res = ykrc;
} else {
if (*state).verbose != 0 {
fprintf(
__stderrp,
(*b"could not generate new mgm, err = %d\n\0").as_ptr(),
prngrc as (i32)
);
}
res = Enum5::YKPIV_RANDOMNESS_ERROR;
}
}
memset_s(
data.as_mut_ptr() as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 3072]>(),
0i32,
::std::mem::size_of::<[u8; 3072]>()
);
memset_s(
mgm_key.as_mut_ptr() as (*mut ::std::os::raw::c_void),
::std::mem::size_of::<[u8; 24]>(),
0i32,
::std::mem::size_of::<[u8; 24]>()
);
_ykpiv_end_transaction(state);
res
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_reset(
mut state : *mut ykpiv_state
) -> Enum5 {
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 res : Enum5;
let mut sw : 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) && (0x9000i32 == sw) {
Enum5::YKPIV_OK
} else {
Enum5::YKPIV_GENERIC_ERROR
}
}
#[no_mangle]
pub unsafe extern fn ykpiv_util_slot_object(mut slot : u8) -> u32 {
let mut object_id : i32 = -1i32;
if slot as (i32) == 0xf9i32 {
object_id = 0x5fff01i32;
} else if slot as (i32) == 0x9ei32 {
object_id = 0x5fc101i32;
} else if slot as (i32) == 0x9di32 {
object_id = 0x5fc10bi32;
} else if slot as (i32) == 0x9ci32 {
object_id = 0x5fc10ai32;
} else if slot as (i32) == 0x9ai32 {
object_id = 0x5fc105i32;
} else if slot as (i32) >= 0x82i32 && (slot as (i32) <= 0x95i32) {
object_id = 0x5fc10di32 + (slot as (i32) - 0x82i32);
}
object_id as (u32)
}
unsafe extern fn _read_certificate(
mut state : *mut ykpiv_state,
mut slot : u8,
mut buf : *mut u8,
mut buf_len : *mut usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut ptr
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut object_id : i32 = ykpiv_util_slot_object(slot) as (i32);
let mut len : usize = 0usize;
if -1i32 == object_id {
Enum5::YKPIV_INVALID_OBJECT
} else {
if Enum5::YKPIV_OK as (i32) == {
res = _ykpiv_fetch_object(state,object_id,buf,buf_len);
res
} as (i32) {
ptr = buf;
if *buf_len < 2usize {
*buf_len = 0usize;
return Enum5::YKPIV_OK;
} else if *{
let _old = ptr;
ptr = ptr.offset(1isize);
_old
} as (i32) == 0x70i32 {
ptr = ptr.offset(
_ykpiv_get_length(
ptr as (*const u8),
&mut len as (*mut usize)
) as (isize)
);
if len > (*buf_len).wrapping_sub(
((ptr as (isize)).wrapping_sub(
buf as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
) {
*buf_len = 0usize;
return Enum5::YKPIV_OK;
} else {
memmove(
buf as (*mut ::std::os::raw::c_void),
ptr as (*const ::std::os::raw::c_void),
len
);
*buf_len = len;
}
}
} else {
*buf_len = 0usize;
}
res
}
}
unsafe extern fn _write_certificate(
mut state : *mut ykpiv_state,
mut slot : u8,
mut data : *mut u8,
mut data_len : usize,
mut certinfo : u8
) -> Enum5 {
let mut buf : [u8; 3063];
let mut object_id : i32 = ykpiv_util_slot_object(slot) as (i32);
let mut offset : usize = 0usize;
let mut req_len : usize = 0usize;
if -1i32 == object_id {
Enum5::YKPIV_INVALID_OBJECT
} else if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) == data || 0usize == data_len {
(if 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) != data || 0usize != data_len {
Enum5::YKPIV_GENERIC_ERROR
} else {
_ykpiv_save_object(
state,
object_id,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize
)
})
} else {
req_len = (1i32 + 3i32 + 2i32) as (usize);
req_len = req_len.wrapping_add(
_ykpiv_set_length(buf.as_mut_ptr(),data_len) as (usize)
);
req_len = req_len.wrapping_add(data_len);
(if req_len < data_len {
Enum5::YKPIV_SIZE_ERROR
} else if req_len > _obj_size_max(state) {
Enum5::YKPIV_SIZE_ERROR
} else {
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0x70u8;
offset = offset.wrapping_add(
_ykpiv_set_length(
buf.as_mut_ptr().offset(offset as (isize)),
data_len
) as (usize)
);
memcpy(
buf.as_mut_ptr().offset(
offset as (isize)
) as (*mut ::std::os::raw::c_void),
data as (*const ::std::os::raw::c_void),
data_len
);
offset = offset.wrapping_add(data_len);
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0x71u8;
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0x1u8;
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = if certinfo as (i32) == 1i32 {
0x1i32
} else {
0x0i32
} as (u8);
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0xfeu8;
buf[
{
let _old = offset;
offset = offset.wrapping_add(1usize);
_old
}
] = 0o0u8;
_ykpiv_save_object(state,object_id,buf.as_mut_ptr(),offset)
})
}
}
unsafe extern fn _get_metadata_item(
mut data : *mut u8,
mut cb_data : usize,
mut tag : u8,
mut pp_item : *mut *mut u8,
mut pcb_item : *mut usize
) -> Enum5 {
let mut _currentBlock;
let mut p_temp : *mut u8 = data;
let mut cb_temp : usize = 0usize;
let mut tag_temp : u8 = 0u8;
if data.is_null() || pp_item.is_null() || pcb_item.is_null() {
Enum5::YKPIV_GENERIC_ERROR
} else {
*pp_item = 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
*pcb_item = 0usize;
'loop2: loop {
if !(p_temp < data.offset(cb_data as (isize))) {
_currentBlock = 6;
break;
}
tag_temp = *{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
};
if !_ykpiv_has_valid_length(
p_temp as (*const u8),
((data.offset(cb_data as (isize)) as (isize)).wrapping_sub(
p_temp as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
) {
_currentBlock = 9;
break;
}
p_temp = p_temp.offset(
_ykpiv_get_length(
p_temp as (*const u8),
&mut cb_temp as (*mut usize)
) as (isize)
);
if tag_temp as (i32) == tag as (i32) {
_currentBlock = 6;
break;
}
p_temp = p_temp.offset(cb_temp as (isize));
}
(if _currentBlock == 6 {
(if p_temp < data.offset(cb_data as (isize)) {
*pp_item = p_temp;
*pcb_item = cb_temp;
Enum5::YKPIV_OK
} else {
Enum5::YKPIV_GENERIC_ERROR
})
} else {
Enum5::YKPIV_SIZE_ERROR
})
}
}
unsafe extern fn _get_length_size(mut length : usize) -> i32 {
if length < 0x80usize {
1i32
} else if length < 0xffusize {
2i32
} else {
3i32
}
}
unsafe extern fn _set_metadata_item(
mut data : *mut u8,
mut pcb_data : *mut usize,
mut cb_data_max : usize,
mut tag : u8,
mut p_item : *mut u8,
mut cb_item : usize
) -> Enum5 {
let mut _currentBlock;
let mut p_temp : *mut u8 = data;
let mut cb_temp : usize = 0usize;
let mut tag_temp : u8 = 0u8;
let mut cb_len : usize = 0usize;
let mut p_next
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_moved : isize = 0isize;
if data.is_null() || pcb_data.is_null() {
Enum5::YKPIV_GENERIC_ERROR
} else {
'loop1: loop {
if !(p_temp < data.offset(*pcb_data as (isize))) {
_currentBlock = 2;
break;
}
tag_temp = *{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
};
cb_len = _ykpiv_get_length(
p_temp as (*const u8),
&mut cb_temp as (*mut usize)
) as (usize);
p_temp = p_temp.offset(cb_len as (isize));
if tag_temp as (i32) == tag as (i32) {
_currentBlock = 9;
break;
}
p_temp = p_temp.offset(cb_temp as (isize));
}
(if _currentBlock == 2 {
(if cb_item == 0usize {
Enum5::YKPIV_OK
} else {
p_temp = data.offset(*pcb_data as (isize));
cb_len = _get_length_size(cb_item) as (usize);
(if (*pcb_data).wrapping_add(cb_len).wrapping_add(
cb_item
) > cb_data_max {
Enum5::YKPIV_GENERIC_ERROR
} else {
*{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} = tag;
p_temp = p_temp.offset(
_ykpiv_set_length(p_temp,cb_item) as (isize)
);
memcpy(
p_temp as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
*pcb_data = (*pcb_data).wrapping_add(
1usize.wrapping_add(cb_len).wrapping_add(cb_item)
);
Enum5::YKPIV_OK
})
})
} else if cb_temp == cb_item {
memcpy(
p_temp as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
Enum5::YKPIV_OK
} else {
p_next = p_temp.offset(cb_temp as (isize));
cb_moved = cb_item as (isize) - cb_temp as (isize) + (if cb_item != 0usize {
_get_length_size(cb_item)
} else {
-1i32
} as (isize) - cb_len as (isize));
(if (*pcb_data).wrapping_add(cb_moved as (usize)) > cb_data_max {
Enum5::YKPIV_GENERIC_ERROR
} else {
memmove(
p_next.offset(cb_moved) as (*mut ::std::os::raw::c_void),
p_next as (*const ::std::os::raw::c_void),
(*pcb_data).wrapping_sub(
((p_next as (isize)).wrapping_sub(
data as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
)
);
*pcb_data = (*pcb_data).wrapping_add(cb_moved as (usize));
if cb_item != 0usize {
p_temp = p_temp.offset(-(cb_len as (isize)));
p_temp = p_temp.offset(
_ykpiv_set_length(p_temp,cb_item) as (isize)
);
memcpy(
p_temp as (*mut ::std::os::raw::c_void),
p_item as (*const ::std::os::raw::c_void),
cb_item
);
}
Enum5::YKPIV_OK
})
})
}
}
unsafe extern fn _read_metadata(
mut state : *mut ykpiv_state,
mut tag : u8,
mut data : *mut u8,
mut pcb_data : *mut usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut p_temp
: *mut u8
= 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8);
let mut cb_temp : usize = 0usize;
let mut obj_id : i32 = 0i32;
if data.is_null() || pcb_data.is_null() || 3072usize > *pcb_data {
Enum5::YKPIV_GENERIC_ERROR
} else {
if tag as (i32) == 0x88i32 {
obj_id = 0x5fc109i32;
} else if tag as (i32) == 0x80i32 {
obj_id = 0x5fff00i32;
} else {
return Enum5::YKPIV_INVALID_OBJECT;
}
cb_temp = *pcb_data;
*pcb_data = 0usize;
(if Enum5::YKPIV_OK as (i32) != {
res = _ykpiv_fetch_object(
state,
obj_id,
data,
&mut cb_temp as (*mut usize)
);
res
} as (i32) {
res
} else if cb_temp < 2usize {
Enum5::YKPIV_GENERIC_ERROR
} else {
p_temp = data;
(if tag as (i32) != *{
let _old = p_temp;
p_temp = p_temp.offset(1isize);
_old
} as (i32) {
Enum5::YKPIV_GENERIC_ERROR
} else {
p_temp = p_temp.offset(
_ykpiv_get_length(p_temp as (*const u8),pcb_data) as (isize)
);
(if *pcb_data > cb_temp.wrapping_sub(
((p_temp as (isize)).wrapping_sub(
data as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
) {
*pcb_data = 0usize;
Enum5::YKPIV_GENERIC_ERROR
} else {
memmove(
data as (*mut ::std::os::raw::c_void),
p_temp as (*const ::std::os::raw::c_void),
*pcb_data
);
Enum5::YKPIV_OK
})
})
})
}
}
unsafe extern fn _write_metadata(
mut state : *mut ykpiv_state,
mut tag : u8,
mut data : *mut u8,
mut cb_data : usize
) -> Enum5 {
let mut res : Enum5 = Enum5::YKPIV_OK;
let mut buf : [u8; 3063];
let mut pTemp : *mut u8 = buf.as_mut_ptr();
let mut obj_id : i32 = 0i32;
if cb_data > _obj_size_max(state).wrapping_sub(
(2i32 + 2i32) as (usize)
) {
Enum5::YKPIV_GENERIC_ERROR
} else {
if tag as (i32) == 0x88i32 {
obj_id = 0x5fc109i32;
} else if tag as (i32) == 0x80i32 {
obj_id = 0x5fff00i32;
} else {
return Enum5::YKPIV_INVALID_OBJECT;
}
if data.is_null() || 0usize == cb_data {
res = _ykpiv_save_object(
state,
obj_id,
0i32 as (*mut ::std::os::raw::c_void) as (*mut u8),
0usize
);
} else {
*{
let _old = pTemp;
pTemp = pTemp.offset(1isize);
_old
} = tag;
pTemp = pTemp.offset(_ykpiv_set_length(pTemp,cb_data) as (isize));
memcpy(
pTemp as (*mut ::std::os::raw::c_void),
data as (*const ::std::os::raw::c_void),
cb_data
);
pTemp = pTemp.offset(cb_data as (isize));
res = _ykpiv_save_object(
state,
obj_id,
buf.as_mut_ptr(),
((pTemp as (isize)).wrapping_sub(
buf.as_mut_ptr() as (isize)
) / ::std::mem::size_of::<u8>() as (isize)) as (usize)
);
}
res
}
}