From 943dd6f14641f79ca6e2cfd3240a17961ebaf441 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 19 Nov 2019 20:22:20 +0000 Subject: [PATCH 01/17] Return Result<(), ErrorKind> from most APIs This commit modifies all public APIs where doing so wouldn't require modifying internal functions. --- src/util.rs | 261 ++++++++++++++++++++++++++++++++----------------- src/yubikey.rs | 218 ++++++++++++++++++++++++----------------- 2 files changed, 302 insertions(+), 177 deletions(-) diff --git a/src/util.rs b/src/util.rs index 1f13348..b97bc6b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -80,17 +80,20 @@ pub static mut CCC_TMPL: &[u8] = &[ pub struct CardId([u8; 16]); /// Get Card ID -pub unsafe fn ykpiv_util_get_cardid(state: *mut YubiKey, cardid: *mut CardId) -> ErrorKind { +pub unsafe fn ykpiv_util_get_cardid( + state: *mut YubiKey, + cardid: *mut CardId, +) -> Result<(), ErrorKind> { let mut buf = [0u8; CB_OBJ_MAX]; let mut len = buf.len(); let mut res: ErrorKind = ErrorKind::Ok; if cardid.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -110,22 +113,28 @@ pub unsafe fn ykpiv_util_get_cardid(state: *mut YubiKey, cardid: *mut CardId) -> } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Set Card ID -pub unsafe fn ykpiv_util_set_cardid(state: *mut YubiKey, cardid: *const CardId) -> ErrorKind { +pub unsafe fn ykpiv_util_set_cardid( + state: *mut YubiKey, + cardid: *const CardId, +) -> Result<(), ErrorKind> { let mut id = [0u8; YKPIV_CARDID_SIZE]; let mut buf = [0u8; CHUID_TMPL.len()]; let mut res = ErrorKind::Ok; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if cardid.is_null() { if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { - return ErrorKind::RandomnessError; + return Err(ErrorKind::RandomnessError); } } else { memcpy( @@ -136,7 +145,7 @@ pub unsafe fn ykpiv_util_set_cardid(state: *mut YubiKey, cardid: *const CardId) } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -161,7 +170,10 @@ pub unsafe fn ykpiv_util_set_cardid(state: *mut YubiKey, cardid: *const CardId) } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Cardholder Capability Container (CCC) Identifier @@ -169,17 +181,17 @@ pub unsafe fn ykpiv_util_set_cardid(state: *mut YubiKey, cardid: *const CardId) pub struct CCCID([u8; 14]); /// Get Cardholder Capability Container (CCC) ID -pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> ErrorKind { +pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut buf = [0u8; CB_OBJ_MAX]; let mut len = buf.len(); if ccc.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -193,7 +205,7 @@ pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> Erro if res == ErrorKind::Ok { if len != CCC_TMPL.len() { _ykpiv_end_transaction(state); - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } memcpy( @@ -204,23 +216,29 @@ pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> Erro } } - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get Cardholder Capability Container (CCC) ID -pub unsafe fn ykpiv_util_set_cccid(state: *mut YubiKey, ccc: *const CCCID) -> ErrorKind { +pub unsafe fn ykpiv_util_set_cccid( + state: *mut YubiKey, + ccc: *const CCCID, +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut id = [0u8; 14]; let mut buf = [0u8; 51]; let len: usize; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if ccc.is_null() { if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { - return ErrorKind::RandomnessError; + return Err(ErrorKind::RandomnessError); } } else { memcpy( @@ -231,7 +249,7 @@ pub unsafe fn ykpiv_util_set_cccid(state: *mut YubiKey, ccc: *const CCCID) -> Er } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -253,7 +271,10 @@ pub unsafe fn ykpiv_util_set_cccid(state: *mut YubiKey, ccc: *const CCCID) -> Er } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get YubiKey device model @@ -316,7 +337,7 @@ pub unsafe fn ykpiv_util_list_keys( key_count: *mut u8, data: *mut *mut YkPivKey, data_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res: ErrorKind = ErrorKind::Ok; let mut p_key: *mut YkPivKey; @@ -331,11 +352,11 @@ pub unsafe fn ykpiv_util_list_keys( let CB_PAGE: usize = 4096; if data.is_null() || data_len.is_null() || key_count.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -347,7 +368,7 @@ pub unsafe fn ykpiv_util_list_keys( if p_data.is_null() { _ykpiv_end_transaction(state); - return ErrorKind::MemoryError; + return Err(ErrorKind::MemoryError); } cb_data = CB_PAGE; @@ -439,7 +460,10 @@ pub unsafe fn ykpiv_util_list_keys( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Read certificate @@ -448,17 +472,17 @@ pub unsafe fn ykpiv_util_read_cert( slot: u8, data: *mut *mut u8, data_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_buf: usize = buf.len(); if data.is_null() || data_len.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -488,7 +512,10 @@ pub unsafe fn ykpiv_util_read_cert( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Write certificate @@ -498,11 +525,11 @@ pub unsafe fn ykpiv_util_write_cert( data: *mut u8, data_len: usize, certinfo: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -510,16 +537,19 @@ pub unsafe fn ykpiv_util_write_cert( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Delete certificate -pub unsafe fn ykpiv_util_delete_cert(state: *mut YubiKey, slot: u8) -> ErrorKind { +pub unsafe fn ykpiv_util_delete_cert(state: *mut YubiKey, slot: u8) -> Result<(), ErrorKind> { ykpiv_util_write_cert(state, slot, ptr::null_mut(), 0, 0) } /// Block PUK -pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res: ErrorKind = ErrorKind::Ok; let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44]; @@ -531,11 +561,11 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> ErrorKind { let mut flags: u8 = 0; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -629,7 +659,10 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> ErrorKind { } } else { _ykpiv_end_transaction(state); - return res; + return match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + }; } } } @@ -669,7 +702,7 @@ pub unsafe fn ykpiv_util_read_mscmap( state: *mut YubiKey, containers: *mut *mut YkPivContainer, n_containers: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_buf: usize = buf.len(); @@ -677,11 +710,12 @@ pub unsafe fn ykpiv_util_read_mscmap( let mut ptr: *mut u8; if containers.is_null() || n_containers.is_null() { + // TODO(str4d): Should this really continue on here? res = ErrorKind::GenericError; } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -697,14 +731,17 @@ pub unsafe fn ykpiv_util_read_mscmap( if res != ErrorKind::Ok { _ykpiv_end_transaction(state); - return res; + return match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + }; } ptr = buf.as_mut_ptr(); if cb_buf < CB_OBJ_TAG_MIN { _ykpiv_end_transaction(state); - return ErrorKind::Ok; + return Ok(()); } if *ptr == TAG_MSCMAP { @@ -713,7 +750,7 @@ pub unsafe fn ykpiv_util_read_mscmap( if len > cb_buf - (ptr as isize - buf.as_mut_ptr() as isize) as usize { _ykpiv_end_transaction(state); - return ErrorKind::Ok; + return Ok(()); } *containers = calloc(len, 1) as (*mut YkPivContainer); @@ -727,7 +764,10 @@ pub unsafe fn ykpiv_util_read_mscmap( } } - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get max object size @@ -744,14 +784,14 @@ pub unsafe fn ykpiv_util_write_mscmap( state: *mut YubiKey, containers: *mut YkPivContainer, n_containers: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; let mut buf = [0u8; CB_OBJ_MAX]; let mut offset: usize = 0; let data_len: usize = n_containers.wrapping_mul(mem::size_of::()); if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -763,14 +803,17 @@ pub unsafe fn ykpiv_util_write_mscmap( } _ykpiv_end_transaction(state); - return res; + return match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + }; } let req_len = 1 + _ykpiv_set_length(buf.as_mut_ptr(), data_len) + data_len; if req_len > _obj_size_max(state) { _ykpiv_end_transaction(state); - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } buf[offset] = 0x81; @@ -786,7 +829,10 @@ pub unsafe fn ykpiv_util_write_mscmap( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Read msroots @@ -794,7 +840,7 @@ pub unsafe fn ykpiv_util_read_msroots( state: *mut YubiKey, data: *mut *mut u8, data_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res = ErrorKind::Ok; let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; @@ -810,11 +856,11 @@ pub unsafe fn ykpiv_util_read_msroots( let mut offset: usize = 0; if data.is_null() || data_len.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -916,7 +962,10 @@ pub unsafe fn ykpiv_util_read_msroots( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Write msroots @@ -924,7 +973,7 @@ pub unsafe fn ykpiv_util_write_msroots( state: *mut YubiKey, data: *mut u8, data_len: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut buf = [0u8; CB_OBJ_MAX]; let mut offset: usize; @@ -934,7 +983,7 @@ pub unsafe fn ykpiv_util_write_msroots( let cb_obj_max = _obj_size_max(state); if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -946,14 +995,17 @@ pub unsafe fn ykpiv_util_write_msroots( } _ykpiv_end_transaction(state); - return res; + return match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + }; } n_objs = (data_len / (cb_obj_max - 4)) + 1; if n_objs > 5 { _ykpiv_end_transaction(state); - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } for i in 0..n_objs { @@ -998,7 +1050,10 @@ pub unsafe fn ykpiv_util_write_msroots( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } // Keygen messages @@ -1026,7 +1081,7 @@ pub unsafe fn ykpiv_util_generate_key( exp_len: *mut usize, point: *mut *mut u8, point_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut in_data = [0u8; 11]; let mut in_ptr = in_data.as_mut_ptr(); @@ -1043,7 +1098,7 @@ pub unsafe fn ykpiv_util_generate_key( let setting_roca: SettingBool; if state.is_null() { - return ErrorKind::ArgumentError; + return Err(ErrorKind::ArgumentError); } if ykpiv_util_devicemodel(state) == DEVTYPE_YK4 @@ -1082,7 +1137,7 @@ pub unsafe fn ykpiv_util_generate_key( ); if !setting_roca.value { - return ErrorKind::NotSupported; + return Err(ErrorKind::NotSupported); } } @@ -1092,7 +1147,7 @@ pub unsafe fn ykpiv_util_generate_key( if (*state).verbose != 0 { eprintln!("Invalid output parameter for ECC algorithm"); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } else { *point = ptr::null_mut(); *point_len = 0; @@ -1103,7 +1158,7 @@ pub unsafe fn ykpiv_util_generate_key( if (*state).verbose != 0 { eprintln!("Invalid output parameter for RSA algorithm",); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } else { *modulus = ptr::null_mut(); *modulus_len = 0; @@ -1116,12 +1171,12 @@ pub unsafe fn ykpiv_util_generate_key( eprintln!("Invalid algorithm specified"); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1384,7 +1439,10 @@ pub unsafe fn ykpiv_util_generate_key( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Config mgm type @@ -1422,7 +1480,10 @@ pub struct YkPivConfig { } /// Get config -pub unsafe fn ykpiv_util_get_config(state: *mut YubiKey, config: *mut YkPivConfig) -> ErrorKind { +pub unsafe fn ykpiv_util_get_config( + state: *mut YubiKey, + config: *mut YkPivConfig, +) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data: usize = mem::size_of::<[u8; YKPIV_OBJ_MAX_SIZE]>(); let mut p_item: *mut u8 = ptr::null_mut(); @@ -1430,7 +1491,7 @@ pub unsafe fn ykpiv_util_get_config(state: *mut YubiKey, config: *mut YkPivConfi let res = ErrorKind::Ok; if state.is_null() || config.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } (*config).protected_data_available = 0u8; @@ -1440,7 +1501,7 @@ pub unsafe fn ykpiv_util_get_config(state: *mut YubiKey, config: *mut YkPivConfi (*config).mgm_type = YkPivConfigMgmType::YKPIV_CONFIG_MGM_MANUAL; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1541,22 +1602,25 @@ pub unsafe fn ykpiv_util_get_config(state: *mut YubiKey, config: *mut YkPivConfi } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Set PIN last changed -pub unsafe fn ykpiv_util_set_pin_last_changed(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_util_set_pin_last_changed(state: *mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data = data.len(); let mut res = ErrorKind::Ok; let ykrc: ErrorKind; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1593,7 +1657,10 @@ pub unsafe fn ykpiv_util_set_pin_last_changed(state: *mut YubiKey) -> ErrorKind } } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Management key (MGM) @@ -1618,7 +1685,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( pin: *const u8, pin_len: usize, mgm: *mut YkPivMgm, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data: usize = data.len(); let mut p_item: *mut u8 = ptr::null_mut(); @@ -1626,15 +1693,15 @@ pub unsafe fn ykpiv_util_get_derived_mgm( let mut res: ErrorKind = ErrorKind::Ok; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if pin.is_null() || pin_len == 0 || mgm.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1682,11 +1749,17 @@ pub unsafe fn ykpiv_util_get_derived_mgm( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get protected management key (MGM) -pub unsafe fn ykpiv_util_get_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivMgm) -> ErrorKind { +pub unsafe fn ykpiv_util_get_protected_mgm( + state: *mut YubiKey, + mgm: *mut YkPivMgm, +) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data: usize = data.len(); let mut p_item: *mut u8 = ptr::null_mut(); @@ -1694,11 +1767,11 @@ pub unsafe fn ykpiv_util_get_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivM let mut res = ErrorKind::Ok; if state.is_null() || mgm.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1744,12 +1817,18 @@ pub unsafe fn ykpiv_util_get_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivM data.zeroize(); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Set protected management key (MGM) #[allow(clippy::cognitive_complexity)] -pub unsafe fn ykpiv_util_set_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivMgm) -> ErrorKind { +pub unsafe fn ykpiv_util_set_protected_mgm( + state: *mut YubiKey, + mgm: *mut YkPivMgm, +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res: ErrorKind = ErrorKind::Ok; let mut ykrc: ErrorKind = ErrorKind::Ok; @@ -1764,7 +1843,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivM let mut flags_1: u8 = 0; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if mgm.is_null() { @@ -1795,7 +1874,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivM } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1953,11 +2032,14 @@ pub unsafe fn ykpiv_util_set_protected_mgm(state: *mut YubiKey, mgm: *mut YkPivM mgm_key.zeroize(); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Reset -pub unsafe fn ykpiv_util_reset(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_util_reset(state: *mut YubiKey) -> Result<(), ErrorKind> { let templ = [0, YKPIV_INS_RESET, 0, 0]; let mut data = [0u8; 255]; let mut recv_len = data.len(); @@ -1973,10 +2055,9 @@ pub unsafe fn ykpiv_util_reset(state: *mut YubiKey) -> ErrorKind { &mut sw, ); - if res == ErrorKind::Ok && sw == SW_SUCCESS { - ErrorKind::Ok - } else { - ErrorKind::GenericError + match (res, sw) { + (ErrorKind::Ok, SW_SUCCESS) => Ok(()), + _ => Err(ErrorKind::GenericError), } } diff --git a/src/yubikey.rs b/src/yubikey.rs index 75b76ba..bafbfa2 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -178,15 +178,15 @@ pub(crate) unsafe fn _ykpiv_has_valid_length(buffer: *const u8, len: usize) -> b } /// Initialize YubiKey client instance -pub unsafe fn ykpiv_init(state: *mut *mut YubiKey, verbose: i32) -> ErrorKind { +pub unsafe fn ykpiv_init(state: *mut *mut YubiKey, verbose: i32) -> Result<(), ErrorKind> { if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } let s = malloc(mem::size_of::()) as (*mut YubiKey); if s.is_null() { - return ErrorKind::MemoryError; + return Err(ErrorKind::MemoryError); } memset(s as (*mut c_void), 0i32, mem::size_of::()); @@ -194,7 +194,7 @@ pub unsafe fn ykpiv_init(state: *mut *mut YubiKey, verbose: i32) -> ErrorKind { (*s).verbose = verbose; (*s).context = -1i32; *state = s; - ErrorKind::Ok + Ok(()) } /// Cleanup YubiKey session @@ -391,7 +391,7 @@ pub unsafe fn ykpiv_connect_with_external_card( } /// Connect to a YubiKey -pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> ErrorKind { +pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Result<(), ErrorKind> { let mut _currentBlock; let mut active_protocol: u32 = 0; let mut reader_buf: [c_char; 2048] = [0; 2048]; @@ -403,7 +403,7 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Error let mut ret: ErrorKind = ykpiv_list_readers(state, reader_buf.as_mut_ptr(), &mut num_readers); if ret != ErrorKind::Ok { - return ret; + return Err(ret); } reader_ptr = reader_buf.as_mut_ptr(); loop { @@ -494,9 +494,9 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Error SCardReleaseContext((*state).context); (*state).context = -1; - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } else { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } } @@ -504,12 +504,15 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Error // you may not want to select the applet when connecting to a card handle that // was supplied by an external library. if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } ret = _ykpiv_select_application(state); _ykpiv_end_transaction(state); - ret + match ret { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// List readers @@ -879,7 +882,7 @@ pub(crate) unsafe fn _send_data( pub const DEFAULT_AUTH_KEY: &[u8] = 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"; /// Authenticate to the card -pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> ErrorKind { +pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut challenge = [0u8; 8]; let mut recv_len = data.len() as u32; @@ -890,11 +893,11 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err let mut res = ErrorKind::Ok; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -911,7 +914,7 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err "didn't expect mgm key to be set by failing op!" ); _ykpiv_end_transaction(state); - return ErrorKind::AlgorithmError; + return Err(ErrorKind::AlgorithmError); } // get a challenge from the card @@ -928,12 +931,12 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err if res != ErrorKind::Ok { _ykpiv_end_transaction(state); - return res; + return Err(res); } if sw != SW_SUCCESS { _ykpiv_end_transaction(state); - return ErrorKind::AuthenticationError; + return Err(ErrorKind::AuthenticationError); } memcpy( @@ -956,7 +959,7 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err if drc != DesErrorKind::Ok { _ykpiv_end_transaction(state); - return ErrorKind::AuthenticationError; + return Err(ErrorKind::AuthenticationError); } recv_len = data.len() as u32; @@ -982,7 +985,7 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err } _ykpiv_end_transaction(state); - return ErrorKind::RandomnessError; + return Err(ErrorKind::RandomnessError); } memcpy( @@ -996,12 +999,12 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err if res != ErrorKind::Ok { _ykpiv_end_transaction(state); - return res; + return Err(res); } if sw != SW_SUCCESS { _ykpiv_end_transaction(state); - return ErrorKind::AuthenticationError; + return Err(ErrorKind::AuthenticationError); } // compare the response from the card with our challenge @@ -1034,7 +1037,10 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Err } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Set the management key (MGM) @@ -1247,13 +1253,13 @@ pub unsafe fn ykpiv_sign_data( out_len: *mut usize, algorithm: u8, key: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS @@ -1263,7 +1269,10 @@ pub unsafe fn ykpiv_sign_data( ); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Decrypt data using a PIV key @@ -1275,20 +1284,23 @@ pub unsafe fn ykpiv_decrypt_data( out_len: *mut usize, algorithm: u8, key: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS let res = _general_authenticate(state, input, input_len, out, out_len, algorithm, key, true); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get the version of the PIV application installed on the YubiKey @@ -1551,11 +1563,11 @@ pub(crate) unsafe fn _ykpiv_get_serial( } /// Get YubiKey device serial number -pub unsafe fn ykpiv_get_serial(state: *mut YubiKey, p_serial: *mut u32) -> ErrorKind { +pub unsafe fn ykpiv_get_serial(state: *mut YubiKey, p_serial: *mut u32) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1563,7 +1575,10 @@ pub unsafe fn ykpiv_get_serial(state: *mut YubiKey, p_serial: *mut u32) -> Error } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Cache PIN in memory @@ -1711,9 +1726,9 @@ pub unsafe fn ykpiv_verify_select( } /// Get the number of PIN retries -pub unsafe fn ykpiv_get_pin_retries(state: *mut YubiKey, tries: *mut i32) -> ErrorKind { +pub unsafe fn ykpiv_get_pin_retries(state: *mut YubiKey, tries: *mut i32) -> Result<(), ErrorKind> { if state.is_null() || tries.is_null() { - return ErrorKind::ArgumentError; + return Err(ErrorKind::ArgumentError); } // Force a re-select to unverify, because once verified the spec dictates that @@ -1722,16 +1737,15 @@ pub unsafe fn ykpiv_get_pin_retries(state: *mut YubiKey, tries: *mut i32) -> Err let res = _ykpiv_select_application(state); if res != ErrorKind::Ok { - return res; + return Err(res); } let ykrc = ykpiv_verify(state, ptr::null(), tries); // WRONG_PIN is expected on successful query. - if ykrc == ErrorKind::WrongPin { - ErrorKind::Ok - } else { - ykrc + match ykrc { + ErrorKind::Ok | ErrorKind::WrongPin => Ok(()), + e => Err(e), } } @@ -1740,7 +1754,7 @@ pub unsafe fn ykpiv_set_pin_retries( state: *mut YubiKey, pin_tries: i32, puk_tries: i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; let mut templ = [0, YKPIV_INS_SET_PIN_RETRIES, 0, 0]; let mut data = [0u8; 255]; @@ -1749,18 +1763,18 @@ pub unsafe fn ykpiv_set_pin_retries( // Special case: if either retry count is 0, it's a successful no-op if pin_tries == 0 || puk_tries == 0 { - return ErrorKind::Ok; + return Ok(()); } if pin_tries > 0xff || puk_tries > 0xff || pin_tries < 1 || puk_tries < 1 { - return ErrorKind::RangeError; + return Err(ErrorKind::RangeError); } templ[2] = pin_tries as (u8); templ[3] = puk_tries as (u8); if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1785,7 +1799,10 @@ pub unsafe fn ykpiv_set_pin_retries( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Change the PIN @@ -1890,11 +1907,11 @@ pub unsafe fn ykpiv_change_pin( new_pin: *const c_char, new_pin_len: usize, tries: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::GenericError; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1916,7 +1933,10 @@ pub unsafe fn ykpiv_change_pin( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Change the PIN Unblocking Key (PUK). PUKs are codes for resetting @@ -1965,11 +1985,11 @@ pub unsafe fn ykpiv_unblock_pin( new_pin: *const c_char, new_pin_len: usize, tries: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::GenericError; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1977,7 +1997,10 @@ pub unsafe fn ykpiv_unblock_pin( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Fetch an object from the YubiKey @@ -1986,11 +2009,11 @@ pub unsafe fn ykpiv_fetch_object( object_id: i32, data: *mut u8, len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -1998,7 +2021,10 @@ pub unsafe fn ykpiv_fetch_object( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Fetch an object @@ -2077,11 +2103,11 @@ pub unsafe fn ykpiv_save_object( object_id: i32, indata: *mut u8, len: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -2089,7 +2115,10 @@ pub unsafe fn ykpiv_save_object( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Save an object @@ -2184,7 +2213,7 @@ pub unsafe fn ykpiv_import_private_key( ec_data_len: u8, pin_policy: u8, touch_policy: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut key_data = [0u8; 1024]; let mut in_ptr: *mut u8 = key_data.as_mut_ptr(); let templ = [0, YKPIV_INS_IMPORT_KEY, algorithm, key]; @@ -2199,7 +2228,7 @@ pub unsafe fn ykpiv_import_private_key( let mut res = ErrorKind::Ok; if state.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if key == YKPIV_KEY_CARDMGM @@ -2207,7 +2236,7 @@ pub unsafe fn ykpiv_import_private_key( || key > YKPIV_KEY_RETIRED20 && (key < YKPIV_KEY_AUTHENTICATION) || key > YKPIV_KEY_CARDAUTH && (key != YKPIV_KEY_ATTESTATION) { - return ErrorKind::KeyError; + return Err(ErrorKind::KeyError); } if pin_policy != YKPIV_PINPOLICY_DEFAULT @@ -2215,7 +2244,7 @@ pub unsafe fn ykpiv_import_private_key( && (pin_policy != YKPIV_PINPOLICY_ONCE) && (pin_policy != YKPIV_PINPOLICY_ALWAYS) { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if touch_policy != YKPIV_TOUCHPOLICY_DEFAULT @@ -2223,13 +2252,13 @@ pub unsafe fn ykpiv_import_private_key( && (touch_policy != YKPIV_TOUCHPOLICY_ALWAYS) && (touch_policy != YKPIV_TOUCHPOLICY_CACHED) { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } match algorithm { YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => { if p_len + q_len + dp_len + dq_len + qinv_len >= 1024 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } else { if algorithm == YKPIV_ALGO_RSA1024 { elem_len = 64; @@ -2240,7 +2269,7 @@ pub unsafe fn ykpiv_import_private_key( } if p.is_null() || q.is_null() || dp.is_null() || dq.is_null() || qinv.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } params[0] = p; @@ -2259,7 +2288,7 @@ pub unsafe fn ykpiv_import_private_key( } YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => { if ec_data_len as (usize) >= key_data.len() { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } if algorithm == YKPIV_ALGO_ECCP256 { @@ -2269,7 +2298,7 @@ pub unsafe fn ykpiv_import_private_key( } if ec_data.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } params[0] = ec_data; @@ -2277,7 +2306,7 @@ pub unsafe fn ykpiv_import_private_key( param_tag = 0x6; n_params = 1; } - _ => return ErrorKind::AlgorithmError, + _ => return Err(ErrorKind::AlgorithmError), } for i in 0..n_params { @@ -2289,7 +2318,7 @@ pub unsafe fn ykpiv_import_private_key( let remaining = (key_data.as_mut_ptr() as usize) + 1024 - in_ptr as usize; if padding > remaining { - return ErrorKind::AlgorithmError; + return Err(ErrorKind::AlgorithmError); } memset(in_ptr as *mut c_void, 0, padding); @@ -2317,7 +2346,7 @@ pub unsafe fn ykpiv_import_private_key( } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } else if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { res = ykpiv_transfer_data( state, @@ -2339,7 +2368,10 @@ pub unsafe fn ykpiv_import_private_key( key_data.zeroize(); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Generate an attestation certificate for a stored key @@ -2348,20 +2380,20 @@ pub unsafe fn ykpiv_attest( key: u8, data: *mut u8, data_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut res = ErrorKind::GenericError; let templ = [0, YKPIV_INS_ATTEST, key, 0]; let mut sw: i32 = 0; let mut ul_data_len: usize; if state.is_null() || data.is_null() || data_len.is_null() { - return ErrorKind::ArgumentError; + return Err(ErrorKind::ArgumentError); } ul_data_len = *data_len; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -2390,7 +2422,10 @@ pub unsafe fn ykpiv_attest( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Get an auth challenge @@ -2398,22 +2433,22 @@ pub unsafe fn ykpiv_auth_getchallenge( state: *mut YubiKey, challenge: *mut u8, challenge_len: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; let mut res = ErrorKind::Ok; if state.is_null() || challenge.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if challenge_len != 8 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { @@ -2442,7 +2477,10 @@ pub unsafe fn ykpiv_auth_getchallenge( } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// Verify an auth response @@ -2450,22 +2488,22 @@ pub unsafe fn ykpiv_auth_verifyresponse( state: *mut YubiKey, response: *mut u8, response_len: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; let mut res: ErrorKind; if state.is_null() || response.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if response_len != 8 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } // send the response to the card and a challenge of our own. @@ -2494,27 +2532,30 @@ pub unsafe fn ykpiv_auth_verifyresponse( apdu.zeroize(); _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } /// MGMT Application ID(?) static mut MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17]; /// Deauthenticate -pub unsafe fn ykpiv_auth_deauthenticate(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_auth_deauthenticate(state: *mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; let mut res: ErrorKind; if state.is_null() { - return ErrorKind::ArgumentError; + return Err(ErrorKind::ArgumentError); } res = _ykpiv_begin_transaction(state); if res != ErrorKind::Ok { - return res; + return Err(res); } let mut apdu = APDU::default(); @@ -2545,5 +2586,8 @@ pub unsafe fn ykpiv_auth_deauthenticate(state: *mut YubiKey) -> ErrorKind { } _ykpiv_end_transaction(state); - res + match res { + ErrorKind::Ok => Ok(()), + e => Err(e), + } } From 5733d0b0af70ec1a20f55049f1b7f130188dccee Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 01:07:15 +0000 Subject: [PATCH 02/17] Convert Yubikey pointers into mutable references --- src/util.rs | 176 +++++++++++-------------- src/yubikey.rs | 348 ++++++++++++++++++++++--------------------------- 2 files changed, 228 insertions(+), 296 deletions(-) diff --git a/src/util.rs b/src/util.rs index b97bc6b..25999f5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -81,7 +81,7 @@ pub struct CardId([u8; 16]); /// Get Card ID pub unsafe fn ykpiv_util_get_cardid( - state: *mut YubiKey, + state: &mut YubiKey, cardid: *mut CardId, ) -> Result<(), ErrorKind> { let mut buf = [0u8; CB_OBJ_MAX]; @@ -121,17 +121,13 @@ pub unsafe fn ykpiv_util_get_cardid( /// Set Card ID pub unsafe fn ykpiv_util_set_cardid( - state: *mut YubiKey, + state: &mut YubiKey, cardid: *const CardId, ) -> Result<(), ErrorKind> { let mut id = [0u8; YKPIV_CARDID_SIZE]; let mut buf = [0u8; CHUID_TMPL.len()]; let mut res = ErrorKind::Ok; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if cardid.is_null() { if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { return Err(ErrorKind::RandomnessError); @@ -181,7 +177,7 @@ pub unsafe fn ykpiv_util_set_cardid( pub struct CCCID([u8; 14]); /// Get Cardholder Capability Container (CCC) ID -pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; let mut buf = [0u8; CB_OBJ_MAX]; let mut len = buf.len(); @@ -224,7 +220,7 @@ pub unsafe fn ykpiv_util_get_cccid(state: *mut YubiKey, ccc: *mut CCCID) -> Resu /// Get Cardholder Capability Container (CCC) ID pub unsafe fn ykpiv_util_set_cccid( - state: *mut YubiKey, + state: &mut YubiKey, ccc: *const CCCID, ) -> Result<(), ErrorKind> { let mut res: ErrorKind = ErrorKind::Ok; @@ -232,10 +228,6 @@ pub unsafe fn ykpiv_util_set_cccid( let mut buf = [0u8; 51]; let len: usize; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if ccc.is_null() { if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { return Err(ErrorKind::RandomnessError); @@ -278,10 +270,10 @@ pub unsafe fn ykpiv_util_set_cccid( } /// Get YubiKey device model -pub unsafe fn ykpiv_util_devicemodel(state: *mut YubiKey) -> u32 { - if state.is_null() || (*state).context == 0 || (*state).context == -1 { +pub unsafe fn ykpiv_util_devicemodel(state: &mut YubiKey) -> u32 { + if state.context == 0 || state.context == -1 { DEVTYPE_UNKNOWN - } else if (*state).is_neo { + } else if state.is_neo { DEVTYPE_NEOr3 } else { DEVTYPE_YK4 @@ -333,7 +325,7 @@ pub const SLOTS: [u8; 24] = [ // TODO(tarcieri): fix clippy alignment warnings #[allow(clippy::cast_ptr_alignment)] pub unsafe fn ykpiv_util_list_keys( - state: *mut YubiKey, + state: &mut YubiKey, key_count: *mut u8, data: *mut *mut YkPivKey, data_len: *mut usize, @@ -468,7 +460,7 @@ pub unsafe fn ykpiv_util_list_keys( /// Read certificate pub unsafe fn ykpiv_util_read_cert( - state: *mut YubiKey, + state: &mut YubiKey, slot: u8, data: *mut *mut u8, data_len: *mut usize, @@ -520,7 +512,7 @@ pub unsafe fn ykpiv_util_read_cert( /// Write certificate pub unsafe fn ykpiv_util_write_cert( - state: *mut YubiKey, + state: &mut YubiKey, slot: u8, data: *mut u8, data_len: usize, @@ -544,12 +536,12 @@ pub unsafe fn ykpiv_util_write_cert( } /// Delete certificate -pub unsafe fn ykpiv_util_delete_cert(state: *mut YubiKey, slot: u8) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_util_delete_cert(state: &mut YubiKey, slot: u8) -> Result<(), ErrorKind> { ykpiv_util_write_cert(state, slot, ptr::null_mut(), 0, 0) } /// Block PUK -pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res: ErrorKind = ErrorKind::Ok; let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44]; @@ -560,10 +552,6 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> let mut cb_item: usize = 0; let mut flags: u8 = 0; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { return Err(ErrorKind::PcscError); } @@ -621,7 +609,7 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> p_item as (*const c_void), cb_item, ); - } else if (*state).verbose != 0 { + } else if state.verbose != 0 { eprintln!("admin flags exist, but are incorrect size = {}", cb_item,); } } @@ -638,7 +626,7 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> 1, ) != ErrorKind::Ok { - if (*state).verbose == 0 { + if state.verbose == 0 { _currentBlock = 20; continue; } @@ -649,7 +637,7 @@ pub unsafe fn ykpiv_util_block_puk(state: *mut YubiKey) -> Result<(), ErrorKind> _currentBlock = 20; continue; } - if (*state).verbose == 0 { + if state.verbose == 0 { _currentBlock = 20; continue; } @@ -699,7 +687,7 @@ pub struct YkPivContainer { /// Read mscmap pub unsafe fn ykpiv_util_read_mscmap( - state: *mut YubiKey, + state: &mut YubiKey, containers: *mut *mut YkPivContainer, n_containers: *mut usize, ) -> Result<(), ErrorKind> { @@ -771,8 +759,8 @@ pub unsafe fn ykpiv_util_read_mscmap( } /// Get max object size -unsafe fn _obj_size_max(state: *mut YubiKey) -> usize { - if !state.is_null() && (*state).is_neo { +unsafe fn _obj_size_max(state: &mut YubiKey) -> usize { + if state.is_neo { 2048 - 9 } else { CB_OBJ_MAX @@ -781,7 +769,7 @@ unsafe fn _obj_size_max(state: *mut YubiKey) -> usize { /// Write mscmap pub unsafe fn ykpiv_util_write_mscmap( - state: *mut YubiKey, + state: &mut YubiKey, containers: *mut YkPivContainer, n_containers: usize, ) -> Result<(), ErrorKind> { @@ -837,7 +825,7 @@ pub unsafe fn ykpiv_util_write_mscmap( /// Read msroots pub unsafe fn ykpiv_util_read_msroots( - state: *mut YubiKey, + state: &mut YubiKey, data: *mut *mut u8, data_len: *mut usize, ) -> Result<(), ErrorKind> { @@ -970,7 +958,7 @@ pub unsafe fn ykpiv_util_read_msroots( /// Write msroots pub unsafe fn ykpiv_util_write_msroots( - state: *mut YubiKey, + state: &mut YubiKey, data: *mut u8, data_len: usize, ) -> Result<(), ErrorKind> { @@ -1070,7 +1058,7 @@ const SZ_ROCA_DEFAULT: &str = "was permitted by default, but is not recommended. /// Generate key #[allow(clippy::cognitive_complexity)] pub unsafe fn ykpiv_util_generate_key( - state: *mut YubiKey, + state: &mut YubiKey, slot: u8, algorithm: u8, pin_policy: u8, @@ -1097,14 +1085,10 @@ pub unsafe fn ykpiv_util_generate_key( let cb_point: usize; let setting_roca: SettingBool; - if state.is_null() { - return Err(ErrorKind::ArgumentError); - } - if ykpiv_util_devicemodel(state) == DEVTYPE_YK4 && (algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) - && (*state).ver.major == 4 - && ((*state).ver.minor < 3 || (*state).ver.minor == 3 && ((*state).ver.patch < 5)) + && state.ver.major == 4 + && (state.ver.minor < 3 || state.ver.minor == 3 && (state.ver.patch < 5)) { let setting_name = CString::new(SZ_SETTING_ROCA).unwrap(); setting_roca = setting_get_bool(setting_name.as_ptr(), true); @@ -1132,7 +1116,7 @@ pub unsafe fn ykpiv_util_generate_key( (ROCA) and should be replaced. On-chip key generation {} See \ YSA-2017-01 \ for additional information on device replacement and mitigation assistance", - (*state).serial, + state.serial, psz_msg ); @@ -1144,7 +1128,7 @@ pub unsafe fn ykpiv_util_generate_key( match algorithm { YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => { if point.is_null() || point_len.is_null() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Invalid output parameter for ECC algorithm"); } return Err(ErrorKind::GenericError); @@ -1155,7 +1139,7 @@ pub unsafe fn ykpiv_util_generate_key( } YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => { if modulus.is_null() || modulus_len.is_null() || exp.is_null() || exp_len.is_null() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Invalid output parameter for RSA algorithm",); } return Err(ErrorKind::GenericError); @@ -1167,7 +1151,7 @@ pub unsafe fn ykpiv_util_generate_key( } } _ => { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Invalid algorithm specified"); } @@ -1213,7 +1197,7 @@ pub unsafe fn ykpiv_util_generate_key( if in_data[4] == 0 { res = ErrorKind::AlgorithmError; - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Unexpected algorithm.\n"); } } else { @@ -1270,24 +1254,24 @@ pub unsafe fn ykpiv_util_generate_key( ); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to communicate."); } } else if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprint!("Failed to generate new key ("); } match sw { SW_ERR_INCORRECT_SLOT => { res = ErrorKind::KeyError; - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("incorrect slot)"); } } SW_ERR_INCORRECT_PARAM => { res = ErrorKind::AlgorithmError; - if (*state).verbose != 0 { + if state.verbose != 0 { if pin_policy as (i32) != 0i32 { eprintln!("pin policy not supported?)",); } else if touch_policy as (i32) != 0i32 { @@ -1299,13 +1283,13 @@ pub unsafe fn ykpiv_util_generate_key( } SW_ERR_SECURITY_STATUS => { res = ErrorKind::AuthenticationError; - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("not authenticated)"); } } _ => { res = ErrorKind::GenericError; - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error {:x})", sw); } } @@ -1314,7 +1298,7 @@ pub unsafe fn ykpiv_util_generate_key( let mut data_ptr: *mut u8 = data.as_mut_ptr().offset(5); let mut len: usize = 0; if *data_ptr != TAG_RSA_MODULUS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to parse public key structure (modulus)."); } res = ErrorKind::ParseError; @@ -1324,7 +1308,7 @@ pub unsafe fn ykpiv_util_generate_key( cb_modulus = len; ptr_modulus = calloc(cb_modulus, 1) as *mut u8; if ptr_modulus.is_null() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to allocate memory for modulus."); } res = ErrorKind::MemoryError; @@ -1336,7 +1320,7 @@ pub unsafe fn ykpiv_util_generate_key( ); data_ptr = data_ptr.add(len); if *data_ptr != TAG_RSA_EXP { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed to parse public key structure (public exponent)." ); @@ -1348,7 +1332,7 @@ pub unsafe fn ykpiv_util_generate_key( cb_exp = len; ptr_exp = calloc(cb_exp, 1) as *mut u8; if ptr_exp.is_null() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to allocate memory for public exponent."); } res = ErrorKind::MemoryError; @@ -1383,7 +1367,7 @@ pub unsafe fn ykpiv_util_generate_key( _old } != TAG_ECC_POINT { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to parse public key structure.\n",); } res = ErrorKind::ParseError; @@ -1394,7 +1378,7 @@ pub unsafe fn ykpiv_util_generate_key( } as (usize) != len { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Unexpected length.\n"); } res = ErrorKind::AlgorithmError; @@ -1402,7 +1386,7 @@ pub unsafe fn ykpiv_util_generate_key( cb_point = len; ptr_point = calloc(cb_point, 1) as (*mut u8); if ptr_point.is_null() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed to allocate memory for public point."); } res = ErrorKind::MemoryError; @@ -1418,7 +1402,7 @@ pub unsafe fn ykpiv_util_generate_key( } } } else { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Wrong algorithm."); } res = ErrorKind::AlgorithmError; @@ -1481,7 +1465,7 @@ pub struct YkPivConfig { /// Get config pub unsafe fn ykpiv_util_get_config( - state: *mut YubiKey, + state: &mut YubiKey, config: *mut YkPivConfig, ) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; @@ -1490,7 +1474,7 @@ pub unsafe fn ykpiv_util_get_config( let mut cb_item: usize = 0; let res = ErrorKind::Ok; - if state.is_null() || config.is_null() { + if config.is_null() { return Err(ErrorKind::GenericError); } @@ -1533,7 +1517,7 @@ pub unsafe fn ykpiv_util_get_config( if (*config).mgm_type as (i32) != YkPivConfigMgmType::YKPIV_CONFIG_MGM_MANUAL as (i32) { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("conflicting types of mgm key administration configured"); } } else { @@ -1550,7 +1534,7 @@ pub unsafe fn ykpiv_util_get_config( ) == ErrorKind::Ok { if cb_item != 4 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("pin timestamp in admin metadata is an invalid size"); } } else { @@ -1590,7 +1574,7 @@ pub unsafe fn ykpiv_util_get_config( if res == ErrorKind::Ok { if (*config).mgm_type != YkPivConfigMgmType::YKPIV_CONFIG_MGM_PROTECTED - && (*state).verbose != 0 + && state.verbose != 0 { eprintln!( "conflicting types of mgm key administration configured - protected mgm exists" @@ -1609,16 +1593,12 @@ pub unsafe fn ykpiv_util_get_config( } /// Set PIN last changed -pub unsafe fn ykpiv_util_set_pin_last_changed(state: *mut YubiKey) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_util_set_pin_last_changed(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data = data.len(); let mut res = ErrorKind::Ok; let ykrc: ErrorKind; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { return Err(ErrorKind::PcscError); } @@ -1646,12 +1626,12 @@ pub unsafe fn ykpiv_util_set_pin_last_changed(state: *mut YubiKey) -> Result<(), }; if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not set pin timestamp, err = {}\n", res as (i32),); } } else { res = _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data); - if res != ErrorKind::Ok && (*state).verbose != 0 { + if res != ErrorKind::Ok && state.verbose != 0 { eprintln!("could not write admin data, err = {}", res); } } @@ -1681,7 +1661,7 @@ impl Drop for YkPivMgm { /// Get derived management key (MGM) pub unsafe fn ykpiv_util_get_derived_mgm( - state: *mut YubiKey, + state: &mut YubiKey, pin: *const u8, pin_len: usize, mgm: *mut YkPivMgm, @@ -1692,10 +1672,6 @@ pub unsafe fn ykpiv_util_get_derived_mgm( let mut cb_item: usize = 0; let mut res: ErrorKind = ErrorKind::Ok; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if pin.is_null() || pin_len == 0 || mgm.is_null() { return Err(ErrorKind::GenericError); } @@ -1718,7 +1694,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( if res == ErrorKind::Ok { if cb_item != 16usize { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "derived mgm salt exists, but is incorrect size = {}", cb_item, @@ -1737,7 +1713,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( ); if p5rc != Pkcs5ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("pbkdf2 failure, err = {:?}", p5rc); } @@ -1757,7 +1733,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( /// Get protected management key (MGM) pub unsafe fn ykpiv_util_get_protected_mgm( - state: *mut YubiKey, + state: &mut YubiKey, mgm: *mut YkPivMgm, ) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; @@ -1766,7 +1742,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( let mut cb_item: usize = 0; let mut res = ErrorKind::Ok; - if state.is_null() || mgm.is_null() { + if mgm.is_null() { return Err(ErrorKind::GenericError); } @@ -1778,7 +1754,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( res = _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not read protected data, err = {:?}", res); } } else { @@ -1791,14 +1767,14 @@ pub unsafe fn ykpiv_util_get_protected_mgm( ); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "could not read protected mgm from metadata, err = {}", res as (i32), ); } } else if cb_item != (*mgm).0.len() { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "protected data contains mgm, but is the wrong size = {}", cb_item, @@ -1826,7 +1802,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( /// Set protected management key (MGM) #[allow(clippy::cognitive_complexity)] pub unsafe fn ykpiv_util_set_protected_mgm( - state: *mut YubiKey, + state: &mut YubiKey, mgm: *mut YkPivMgm, ) -> Result<(), ErrorKind> { let mut _currentBlock; @@ -1842,10 +1818,6 @@ pub unsafe fn ykpiv_util_set_protected_mgm( let mut cb_item: usize = 0; let mut flags_1: u8 = 0; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if mgm.is_null() { f_generate = true; } else { @@ -1927,7 +1899,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( ); if ykrc != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not set protected mgm item, err = {:?}", ykrc); _currentBlock = 26; } else { @@ -1936,7 +1908,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( } else { ykrc = _write_metadata(state, 0x88u8, data.as_mut_ptr(), cb_data); if ykrc != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not write protected data, err = {:?}", ykrc); _currentBlock = 51; } else { @@ -1962,7 +1934,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( &mut cb_item, ); - if ykrc != ErrorKind::Ok && (*state).verbose != 0 { + if ykrc != ErrorKind::Ok && state.verbose != 0 { eprintln!("admin data exists, but flags are not present",); } @@ -1974,7 +1946,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( p_item as (*const c_void), cb_item, ); - } else if (*state).verbose != 0 { + } else if state.verbose != 0 { eprintln!("admin data flags are an incorrect size = {}", cb_item,); } @@ -1987,7 +1959,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( 0, ); - if ykrc != ErrorKind::Ok && (*state).verbose != 0 { + if ykrc != ErrorKind::Ok && state.verbose != 0 { eprintln!("could not unset derived mgm salt, err = {}", ykrc); } } @@ -2003,24 +1975,24 @@ pub unsafe fn ykpiv_util_set_protected_mgm( ); if ykrc != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not set admin flags item, err = {}", ykrc); } } else { ykrc = _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data); - if ykrc != ErrorKind::Ok && (*state).verbose != 0 { + if ykrc != ErrorKind::Ok && state.verbose != 0 { eprintln!("could not write admin data, err = {}", ykrc); } } } } else if _currentBlock == 44 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not set new derived mgm key, err = {}", ykrc); } res = ykrc; } else { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("could not generate new mgm, err = {:?}", prngrc); } @@ -2039,7 +2011,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( } /// Reset -pub unsafe fn ykpiv_util_reset(state: *mut YubiKey) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_util_reset(state: &mut YubiKey) -> Result<(), ErrorKind> { let templ = [0, YKPIV_INS_RESET, 0, 0]; let mut data = [0u8; 255]; let mut recv_len = data.len(); @@ -2081,7 +2053,7 @@ pub fn ykpiv_util_slot_object(slot: u8) -> u32 { /// Read certificate unsafe fn _read_certificate( - state: *mut YubiKey, + state: &mut YubiKey, slot: u8, buf: *mut u8, buf_len: *mut usize, @@ -2125,7 +2097,7 @@ unsafe fn _read_certificate( /// Write certificate unsafe fn _write_certificate( - state: *mut YubiKey, + state: &mut YubiKey, slot: u8, data: *mut u8, data_len: usize, @@ -2337,7 +2309,7 @@ unsafe fn _set_metadata_item( /// Read metadata unsafe fn _read_metadata( - state: *mut YubiKey, + state: &mut YubiKey, tag: u8, data: *mut u8, pcb_data: *mut usize, @@ -2393,7 +2365,7 @@ unsafe fn _read_metadata( /// Write metadata unsafe fn _write_metadata( - state: *mut YubiKey, + state: &mut YubiKey, tag: u8, data: *mut u8, cb_data: usize, diff --git a/src/yubikey.rs b/src/yubikey.rs index bafbfa2..c421c49 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -178,64 +178,60 @@ pub(crate) unsafe fn _ykpiv_has_valid_length(buffer: *const u8, len: usize) -> b } /// Initialize YubiKey client instance -pub unsafe fn ykpiv_init(state: *mut *mut YubiKey, verbose: i32) -> Result<(), ErrorKind> { - if state.is_null() { - return Err(ErrorKind::GenericError); +pub fn ykpiv_init(verbose: i32) -> YubiKey { + YubiKey { + context: -1, + card: 0, + verbose, + pin: ptr::null_mut(), + is_neo: false, + ver: Version { + major: 0, + minor: 0, + patch: 0, + }, + serial: 0, } - - let s = malloc(mem::size_of::()) as (*mut YubiKey); - - if s.is_null() { - return Err(ErrorKind::MemoryError); - } - - memset(s as (*mut c_void), 0i32, mem::size_of::()); - (*s).pin = ptr::null_mut(); - (*s).verbose = verbose; - (*s).context = -1i32; - *state = s; - Ok(()) } /// Cleanup YubiKey session -pub(crate) unsafe fn _ykpiv_done(state: *mut YubiKey, disconnect: bool) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_done(state: &mut YubiKey, disconnect: bool) -> ErrorKind { if disconnect { ykpiv_disconnect(state); } _cache_pin(state, ptr::null(), 0); - free(state as *mut c_void); ErrorKind::Ok } /// Cleanup YubiKey session with external card upon completion // TODO(tarcieri): make this a `Drop` handler -pub unsafe fn ykpiv_done_with_external_card(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_done_with_external_card(state: &mut YubiKey) -> ErrorKind { _ykpiv_done(state, false) } /// Cleanup YubiKey session upon completion -pub unsafe fn ykpiv_done(state: *mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_done(state: &mut YubiKey) -> ErrorKind { _ykpiv_done(state, true) } /// Disconnect a YubiKey session -pub unsafe fn ykpiv_disconnect(state: *mut YubiKey) -> ErrorKind { - if (*state).card != 0 { - SCardDisconnect((*state).card, 0x1); - (*state).card = 0i32; +pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> ErrorKind { + if state.card != 0 { + SCardDisconnect(state.card, 0x1); + state.card = 0i32; } - if SCardIsValidContext((*state).context) == 0x0 { - SCardReleaseContext((*state).context); - (*state).context = -1i32; + if SCardIsValidContext(state.context) == 0x0 { + SCardReleaseContext(state.context); + state.context = -1i32; } ErrorKind::Ok } /// Select application -pub(crate) unsafe fn _ykpiv_select_application(state: *mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> ErrorKind { let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; let mut sw = 0i32; @@ -255,14 +251,14 @@ pub(crate) unsafe fn _ykpiv_select_application(state: *mut YubiKey) -> ErrorKind res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) ); } } else if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed selecting application: {:04x}", sw); } return ErrorKind::GenericError; @@ -277,14 +273,14 @@ pub(crate) unsafe fn _ykpiv_select_application(state: *mut YubiKey) -> ErrorKind // will result in another selection of the PIV applet. res = _ykpiv_get_version(state, ptr::null_mut()); - if res != ErrorKind::Ok && (*state).verbose != 0 { + if res != ErrorKind::Ok && state.verbose != 0 { eprintln!("Failed to retrieve version: \'{}\'", ykpiv_strerror(res)); } res = _ykpiv_get_serial(state, ptr::null_mut(), false); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed to retrieve serial number: \'{}\'", ykpiv_strerror(res) @@ -298,7 +294,7 @@ pub(crate) unsafe fn _ykpiv_select_application(state: *mut YubiKey) -> ErrorKind } /// Ensure an application is selected (presently noop) -pub(crate) unsafe fn _ykpiv_ensure_application_selected(_state: *mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_ensure_application_selected(_state: &mut YubiKey) -> ErrorKind { // TODO(tarcieri): ENABLE_APPLICATION_RESELECTION support? // // Original C code below: @@ -327,18 +323,14 @@ pub(crate) unsafe fn _ykpiv_ensure_application_selected(_state: *mut YubiKey) -> } /// Connect to the YubiKey -pub(crate) unsafe fn _ykpiv_connect(state: *mut YubiKey, context: usize, card: usize) -> ErrorKind { - if state.is_null() { - return ErrorKind::GenericError; - } - +pub(crate) unsafe fn _ykpiv_connect(state: &mut YubiKey, context: usize, card: usize) -> ErrorKind { // if the context has changed, and the new context is not valid, return an error - if context != (*state).context as (usize) && (0x0i32 != SCardIsValidContext(context as (i32))) { + if context != state.context as (usize) && (0x0i32 != SCardIsValidContext(context as (i32))) { return ErrorKind::PcscError; } // if card handle has changed, determine if handle is valid (less efficient, but complete) - if card != (*state).card as usize { + if card != state.card as usize { let mut reader = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut reader_len = reader.len() as u32; let mut atr = [0u8; 33]; @@ -359,7 +351,7 @@ pub(crate) unsafe fn _ykpiv_connect(state: *mut YubiKey, context: usize, card: u return ErrorKind::PcscError; } - (*state).is_neo = (atr_len as usize == YKPIV_ATR_NEO_R3.len() - 1) + state.is_neo = (atr_len as usize == YKPIV_ATR_NEO_R3.len() - 1) && (memcmp( YKPIV_ATR_NEO_R3.as_ptr() as *const c_void, atr.as_mut_ptr() as *const c_void, @@ -367,8 +359,8 @@ pub(crate) unsafe fn _ykpiv_connect(state: *mut YubiKey, context: usize, card: u ) == 0); } - (*state).context = context as i32; - (*state).card = card as i32; + state.context = context as i32; + state.card = card as i32; // Do not select the applet here, as we need to accommodate commands that are // sensitive to re-select (custom apdu/auth). All commands that can handle explicit @@ -383,7 +375,7 @@ pub(crate) unsafe fn _ykpiv_connect(state: *mut YubiKey, context: usize, card: u /// Connect to an external card pub unsafe fn ykpiv_connect_with_external_card( - state: *mut YubiKey, + state: &mut YubiKey, context: usize, card: usize, ) -> ErrorKind { @@ -391,7 +383,7 @@ pub unsafe fn ykpiv_connect_with_external_card( } /// Connect to a YubiKey -pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Result<(), ErrorKind> { let mut _currentBlock; let mut active_protocol: u32 = 0; let mut reader_buf: [c_char; 2048] = [0; 2048]; @@ -437,7 +429,7 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Resul found = true; } if found as (i32) == 0i32 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "skipping reader \'{}\' since it doesn\'t match \'{}\'.", CStr::from_ptr(reader_ptr).to_string_lossy(), @@ -454,14 +446,14 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Resul _currentBlock = 15; } if _currentBlock == 15 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "trying to connect to reader \'{}\'.", CStr::from_ptr(reader_ptr).to_string_lossy() ); } rc = SCardConnect( - (*state).context, + state.context, reader_ptr, 0x2u32, 0x2u32, @@ -469,13 +461,13 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Resul &mut active_protocol, ) as (isize); if rc != 0x0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("SCardConnect failed, rc={}", rc); } } else { // at this point, card should not equal state->card, // to allow _ykpiv_connect() to determine device type - let res = _ykpiv_connect(state, (*state).context as (usize), card as (usize)); + let res = _ykpiv_connect(state, state.context as (usize), card as (usize)); if res != ErrorKind::Ok { _currentBlock = 19; break; @@ -488,12 +480,12 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Resul if _currentBlock == 3 { if *reader_ptr == b'\0' as c_char { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: no usable reader found."); } - SCardReleaseContext((*state).context); - (*state).context = -1; + SCardReleaseContext(state.context); + state.context = -1; return Err(ErrorKind::PcscError); } else { return Err(ErrorKind::GenericError); @@ -517,18 +509,18 @@ pub unsafe fn ykpiv_connect(state: *mut YubiKey, wanted: *const c_char) -> Resul /// List readers pub unsafe fn ykpiv_list_readers( - state: *mut YubiKey, + state: &mut YubiKey, readers: *mut c_char, len: *mut usize, ) -> ErrorKind { let mut num_readers: u32 = 0u32; let mut rc: i32; - if SCardIsValidContext((*state).context) != 0 { - rc = SCardEstablishContext(0x2, ptr::null(), ptr::null(), &mut (*state).context); + if SCardIsValidContext(state.context) != 0 { + rc = SCardEstablishContext(0x2, ptr::null(), ptr::null(), &mut state.context); if rc != 0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: SCardEstablishContext failed, rc={}", rc); } return ErrorKind::PcscError; @@ -536,18 +528,18 @@ pub unsafe fn ykpiv_list_readers( } rc = SCardListReaders( - (*state).context, + state.context, ptr::null(), ptr::null_mut(), &mut num_readers, ); if rc != 0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: SCardListReaders failed, rc={}", rc); } - SCardReleaseContext((*state).context); - (*state).context = -1i32; + SCardReleaseContext(state.context); + state.context = -1i32; return ErrorKind::PcscError; } @@ -557,15 +549,15 @@ pub unsafe fn ykpiv_list_readers( *len = num_readers as (usize); } - rc = SCardListReaders((*state).context, ptr::null(), readers, &mut num_readers); + rc = SCardListReaders(state.context, ptr::null(), readers, &mut num_readers); if rc != 0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: SCardListReaders failed, rc={}", rc); } - SCardReleaseContext((*state).context); - (*state).context = -1i32; + SCardReleaseContext(state.context); + state.context = -1i32; return ErrorKind::PcscError; } @@ -574,18 +566,18 @@ pub unsafe fn ykpiv_list_readers( } /// Reconnect to a YubiKey -pub(crate) unsafe fn reconnect(state: *mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> ErrorKind { let mut active_protocol: u32 = 0; let mut tries: i32 = 0; - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("trying to reconnect to current reader."); } - let rc = SCardReconnect((*state).card, 0x2u32, 0x2u32, 0x1u32, &mut active_protocol); + let rc = SCardReconnect(state.card, 0x2u32, 0x2u32, 0x1u32, &mut active_protocol); if rc != 0x0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("SCardReconnect failed, rc={}", rc); } return ErrorKind::PcscError; @@ -597,16 +589,16 @@ pub(crate) unsafe fn reconnect(state: *mut YubiKey) -> ErrorKind { return res; } - if !(*state).pin.is_null() { - ykpiv_verify(state, (*state).pin as *const c_char, &mut tries) + if !state.pin.is_null() { + ykpiv_verify(state, state.pin as *const c_char, &mut tries) } else { ErrorKind::Ok } } /// Begin a transaction -pub(crate) unsafe fn _ykpiv_begin_transaction(state: *mut YubiKey) -> ErrorKind { - let mut rc = SCardBeginTransaction((*state).card); +pub(crate) unsafe fn _ykpiv_begin_transaction(state: &mut YubiKey) -> ErrorKind { + let mut rc = SCardBeginTransaction(state.card); if rc as usize & 0xffff_ffff == 0x8010_0068 { let res = reconnect(state); @@ -615,11 +607,11 @@ pub(crate) unsafe fn _ykpiv_begin_transaction(state: *mut YubiKey) -> ErrorKind return res; } - rc = SCardBeginTransaction((*state).card); + rc = SCardBeginTransaction(state.card); } if rc != 0 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: Failed to begin pcsc transaction, rc={}", rc); } @@ -630,10 +622,10 @@ pub(crate) unsafe fn _ykpiv_begin_transaction(state: *mut YubiKey) -> ErrorKind } /// End a transaction -pub(crate) unsafe fn _ykpiv_end_transaction(state: *mut YubiKey) -> ErrorKind { - let rc = SCardEndTransaction((*state).card, 0x0); +pub(crate) unsafe fn _ykpiv_end_transaction(state: &mut YubiKey) -> ErrorKind { + let rc = SCardEndTransaction(state.card, 0x0); - if rc != 0x0 && (*state).verbose != 0 { + if rc != 0x0 && state.verbose != 0 { eprintln!("error: Failed to end pcsc transaction, rc={}", rc); return ErrorKind::PcscError; } @@ -643,7 +635,7 @@ pub(crate) unsafe fn _ykpiv_end_transaction(state: *mut YubiKey) -> ErrorKind { /// Transfer data pub(crate) unsafe fn _ykpiv_transfer_data( - state: *mut YubiKey, + state: &mut YubiKey, templ: *const u8, in_data: *const u8, in_len: isize, @@ -676,7 +668,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( this_size = in_data.offset(in_len) as usize - in_ptr as usize; } - if (*state).verbose > 2 { + if state.verbose > 2 { eprintln!("Going to send {} bytes in this go.", this_size); } @@ -734,7 +726,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( let mut data = [0u8; 261]; recv_len = data.len() as u32; - if (*state).verbose > 2 { + if state.verbose > 2 { eprintln!( "The card indicates there is {} bytes more data for us.", *sw & 0xff @@ -773,7 +765,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( } if _currentBlock != 24 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Output buffer to small, wanted to write {}, max was {}.", (*out_len).wrapping_add(recv_len as usize).wrapping_sub(2), @@ -783,7 +775,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( res = ErrorKind::SizeError; } } else if _currentBlock == 21 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Output buffer to small, wanted to write {}, max was {}.", (*out_len).wrapping_add(recv_len as usize).wrapping_sub(2), @@ -797,7 +789,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( /// Transfer data pub unsafe fn ykpiv_transfer_data( - state: *mut YubiKey, + state: &mut YubiKey, templ: *const u8, in_data: *const u8, in_len: isize, @@ -827,7 +819,7 @@ pub(crate) unsafe fn dump_hex(buf: *const u8, len: u32) { /// Send data pub(crate) unsafe fn _send_data( - state: *mut YubiKey, + state: &mut YubiKey, apdu: *mut APDU, data: *mut u8, recv_len: *mut u32, @@ -836,14 +828,14 @@ pub(crate) unsafe fn _send_data( let send_len = (*apdu).lc as u32 + 5; let mut tmp_len = *recv_len; - if (*state).verbose > 1 { + if state.verbose > 1 { eprint!("> "); dump_hex((*apdu).as_ptr() as *const u8, send_len); eprintln!(); } let rc = SCardTransmit( - (*state).card, + state.card, SCARD_PCI_T1, (*apdu).as_mut_ptr() as *mut i8, send_len, @@ -853,7 +845,7 @@ pub(crate) unsafe fn _send_data( ); if rc != SCARD_S_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("error: SCardTransmit failed, rc={:08x}", rc); } @@ -862,7 +854,7 @@ pub(crate) unsafe fn _send_data( *recv_len = tmp_len; - if (*state).verbose > 1 { + if state.verbose > 1 { eprint!("< "); dump_hex(data, *recv_len); eprintln!(); @@ -882,7 +874,7 @@ pub(crate) unsafe fn _send_data( pub const DEFAULT_AUTH_KEY: &[u8] = 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"; /// Authenticate to the card -pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut challenge = [0u8; 8]; let mut recv_len = data.len() as u32; @@ -892,10 +884,6 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Res let mut out_len: usize; let mut res = ErrorKind::Ok; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { return Err(ErrorKind::PcscError); } @@ -980,7 +968,7 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Res apdu.data[13] = 8; if _ykpiv_prng_generate(data[14..20].as_mut_ptr(), 8) == PRngErrorKind::GeneralError { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed getting randomness for authentication."); } @@ -1044,13 +1032,13 @@ pub unsafe fn ykpiv_authenticate(state: *mut YubiKey, mut key: *const u8) -> Res } /// Set the management key (MGM) -pub unsafe fn ykpiv_set_mgmkey(state: *mut YubiKey, new_key: *const u8) -> ErrorKind { +pub unsafe fn ykpiv_set_mgmkey(state: &mut YubiKey, new_key: *const u8) -> ErrorKind { ykpiv_set_mgmkey2(state, new_key, 0) } /// Set the management key (MGM) pub(crate) unsafe fn ykpiv_set_mgmkey2( - state: *mut YubiKey, + state: &mut YubiKey, new_key: *const u8, touch: u8, ) -> ErrorKind { @@ -1066,7 +1054,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { if yk_des_is_weak_key(new_key, (8i32 * 3i32) as (usize)) { - if (*state).verbose != 0 { + if state.verbose != 0 { // TODO(tarcieri): format string eprint!("Won\'t set new key \'"); dump_hex(new_key, DES_LEN_3DES as u32); @@ -1110,7 +1098,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( /// Authenticate to the YubiKey pub(crate) unsafe fn _general_authenticate( - state: *mut YubiKey, + state: &mut YubiKey, sign_in: *const u8, in_len: usize, out: *mut u8, @@ -1191,14 +1179,14 @@ pub(crate) unsafe fn _general_authenticate( ); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Sign command failed to communicate."); } return res; } if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed sign command with code {:x}.\n\0", sw); } @@ -1211,7 +1199,7 @@ pub(crate) unsafe fn _general_authenticate( // skip the first 7c tag if data[0] != 0x7c { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed parsing signature reply."); } return ErrorKind::ParseError; @@ -1222,7 +1210,7 @@ pub(crate) unsafe fn _general_authenticate( // skip the 82 tag if *dataptr != 0x82 { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed parsing signature reply."); } @@ -1233,7 +1221,7 @@ pub(crate) unsafe fn _general_authenticate( dataptr = dataptr.add(_ykpiv_get_length(dataptr, &mut len)); if len > *out_len { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Wrong size on output buffer."); } return ErrorKind::SizeError; @@ -1246,7 +1234,7 @@ pub(crate) unsafe fn _general_authenticate( /// Sign data using a PIV key pub unsafe fn ykpiv_sign_data( - state: *mut YubiKey, + state: &mut YubiKey, raw_in: *const u8, in_len: usize, sign_out: *mut u8, @@ -1254,10 +1242,6 @@ pub unsafe fn ykpiv_sign_data( algorithm: u8, key: u8, ) -> Result<(), ErrorKind> { - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { return Err(ErrorKind::PcscError); } @@ -1277,7 +1261,7 @@ pub unsafe fn ykpiv_sign_data( /// Decrypt data using a PIV key pub unsafe fn ykpiv_decrypt_data( - state: *mut YubiKey, + state: &mut YubiKey, input: *const u8, input_len: usize, out: *mut u8, @@ -1285,10 +1269,6 @@ pub unsafe fn ykpiv_decrypt_data( algorithm: u8, key: u8, ) -> Result<(), ErrorKind> { - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { return Err(ErrorKind::PcscError); } @@ -1304,24 +1284,20 @@ pub unsafe fn ykpiv_decrypt_data( } /// Get the version of the PIV application installed on the YubiKey -pub(crate) unsafe fn _ykpiv_get_version(state: *mut YubiKey, p_version: *mut Version) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_get_version(state: &mut YubiKey, p_version: *mut Version) -> ErrorKind { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; let res: ErrorKind; - if state.is_null() { - return ErrorKind::ArgumentError; - } - // get version from state if already from device - if (*state).ver.major != 0 || (*state).ver.minor != 0 || (*state).ver.patch != 0 { + if state.ver.major != 0 || state.ver.minor != 0 || state.ver.patch != 0 { if !p_version.is_null() { // TODO(tarcieri): use real references instead of pointers and memcpy!!! #[allow(trivial_casts)] memcpy( p_version as *mut c_void, - &(*state).ver as *const Version as *const c_void, + &state.ver as *const Version as *const c_void, mem::size_of::(), ); } @@ -1347,16 +1323,16 @@ pub(crate) unsafe fn _ykpiv_get_version(state: *mut YubiKey, p_version: *mut Ver return ErrorKind::SizeError; } - (*state).ver.major = data[0]; - (*state).ver.minor = data[1]; - (*state).ver.patch = data[2]; + state.ver.major = data[0]; + state.ver.minor = data[1]; + state.ver.patch = data[2]; if !p_version.is_null() { // TODO(tarcieri): use real references instead of pointers and memcpy!!! #[allow(trivial_casts)] memcpy( p_version as *mut c_void, - &(*state).ver as (*const Version) as (*const c_void), + &state.ver as (*const Version) as (*const c_void), mem::size_of::(), ); } @@ -1365,7 +1341,7 @@ pub(crate) unsafe fn _ykpiv_get_version(state: *mut YubiKey, p_version: *mut Ver } /// Get the YubiKey's PIV application version as a string -pub unsafe fn ykpiv_get_version(state: *mut YubiKey) -> Result { +pub unsafe fn ykpiv_get_version(state: &mut YubiKey) -> Result { let mut ver: Version = Version { major: 0u8, minor: 0u8, @@ -1393,7 +1369,7 @@ pub unsafe fn ykpiv_get_version(state: *mut YubiKey) -> Result ErrorKind { @@ -1405,19 +1381,15 @@ pub(crate) unsafe fn _ykpiv_get_serial( let mut sw: i32 = 0; let p_temp: *mut u8; - if state.is_null() { - return ErrorKind::ArgumentError; - } - - if !f_force && (*state).serial != 0 { + if !f_force && state.serial != 0 { if !p_serial.is_null() { - *p_serial = (*state).serial; + *p_serial = state.serial; } return ErrorKind::Ok; } - if (*state).ver.major < 5 { + if state.ver.major < 5 { // get serial from neo/yk4 devices using the otp applet let mut temp = [0u8; 255]; recv_len = temp.len() as u32; @@ -1436,7 +1408,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) @@ -1447,7 +1419,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( } if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed selecting yk application: {:04x}", sw); } @@ -1463,7 +1435,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) @@ -1474,7 +1446,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( } if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed retrieving serial number: {:04x}", sw); } @@ -1496,7 +1468,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) @@ -1506,7 +1478,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( } if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed selecting application: {:04x}", sw); } return ErrorKind::GenericError; @@ -1521,7 +1493,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) @@ -1529,7 +1501,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( } return res; } else if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed retrieving serial number: {:04x}", sw); } return ErrorKind::GenericError; @@ -1546,7 +1518,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( // TODO(tarcieri): replace pointers and casts with proper references! #[allow(trivial_casts)] { - p_temp = &mut (*state).serial as (*mut u32) as (*mut u8); + p_temp = &mut state.serial as (*mut u32) as (*mut u8); } *p_temp = data[3]; @@ -1555,7 +1527,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( *p_temp.add(3) = data[0]; if !p_serial.is_null() { - *p_serial = (*state).serial; + *p_serial = state.serial; } } @@ -1563,7 +1535,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( } /// Get YubiKey device serial number -pub unsafe fn ykpiv_get_serial(state: *mut YubiKey, p_serial: *mut u32) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_get_serial(state: &mut YubiKey, p_serial: *mut u32) -> Result<(), ErrorKind> { let mut res = ErrorKind::Ok; if _ykpiv_begin_transaction(state) != ErrorKind::Ok { @@ -1583,41 +1555,37 @@ pub unsafe fn ykpiv_get_serial(state: *mut YubiKey, p_serial: *mut u32) -> Resul /// Cache PIN in memory // TODO(tarcieri): better security around the cached PIN -pub(crate) unsafe fn _cache_pin(state: *mut YubiKey, pin: *const c_char, len: usize) -> ErrorKind { - if state.is_null() { - return ErrorKind::ArgumentError; - } - - if !pin.is_null() && ((*state).pin as *const c_char == pin) { +pub(crate) unsafe fn _cache_pin(state: &mut YubiKey, pin: *const c_char, len: usize) -> ErrorKind { + if !pin.is_null() && (state.pin as *const c_char == pin) { return ErrorKind::Ok; } - if !(*state).pin.is_null() { + if !state.pin.is_null() { // Zeroize the old cached PIN - let old_len = strlen((*state).pin as *const c_char); - let pin_slice = slice::from_raw_parts_mut((*state).pin, old_len); + let old_len = strlen(state.pin as *const c_char); + let pin_slice = slice::from_raw_parts_mut(state.pin, old_len); pin_slice.zeroize(); - free((*state).pin as (*mut c_void)); - (*state).pin = ptr::null_mut(); + free(state.pin as (*mut c_void)); + state.pin = ptr::null_mut(); } if !pin.is_null() && len > 0 { - (*state).pin = malloc(len + 1) as (*mut u8); + state.pin = malloc(len + 1) as (*mut u8); - if (*state).pin.is_null() { + if state.pin.is_null() { return ErrorKind::MemoryError; } - memcpy((*state).pin as (*mut c_void), pin as (*const c_void), len); - *(*state).pin.add(len) = 0u8; + memcpy(state.pin as (*mut c_void), pin as (*const c_void), len); + *state.pin.add(len) = 0u8; } ErrorKind::Ok } /// Verify device PIN -pub unsafe fn ykpiv_verify(state: *mut YubiKey, pin: *const c_char, tries: *mut i32) -> ErrorKind { +pub unsafe fn ykpiv_verify(state: &mut YubiKey, pin: *const c_char, tries: *mut i32) -> ErrorKind { ykpiv_verify_select( state, pin, @@ -1629,7 +1597,7 @@ pub unsafe fn ykpiv_verify(state: *mut YubiKey, pin: *const c_char, tries: *mut /// Verify device PIN pub(crate) unsafe fn _verify( - state: *mut YubiKey, + state: &mut YubiKey, pin: *const c_char, pin_len: usize, tries: *mut i32, @@ -1701,7 +1669,7 @@ pub(crate) unsafe fn _verify( /// Verify and select application pub unsafe fn ykpiv_verify_select( - state: *mut YubiKey, + state: &mut YubiKey, pin: *const c_char, pin_len: usize, tries: *mut i32, @@ -1726,8 +1694,8 @@ pub unsafe fn ykpiv_verify_select( } /// Get the number of PIN retries -pub unsafe fn ykpiv_get_pin_retries(state: *mut YubiKey, tries: *mut i32) -> Result<(), ErrorKind> { - if state.is_null() || tries.is_null() { +pub unsafe fn ykpiv_get_pin_retries(state: &mut YubiKey, tries: *mut i32) -> Result<(), ErrorKind> { + if tries.is_null() { return Err(ErrorKind::ArgumentError); } @@ -1751,7 +1719,7 @@ pub unsafe fn ykpiv_get_pin_retries(state: *mut YubiKey, tries: *mut i32) -> Res /// Set the number of PIN retries pub unsafe fn ykpiv_set_pin_retries( - state: *mut YubiKey, + state: &mut YubiKey, pin_tries: i32, puk_tries: i32, ) -> Result<(), ErrorKind> { @@ -1807,7 +1775,7 @@ pub unsafe fn ykpiv_set_pin_retries( /// Change the PIN pub(crate) unsafe fn _ykpiv_change_pin( - state: *mut YubiKey, + state: &mut YubiKey, action: i32, current_pin: *const c_char, current_pin_len: usize, @@ -1886,7 +1854,7 @@ pub(crate) unsafe fn _ykpiv_change_pin( } else if sw == SW_ERR_AUTH_BLOCKED { return ErrorKind::PinLocked; } else { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed changing pin, token response code: {:x}.", sw); } @@ -1901,7 +1869,7 @@ pub(crate) unsafe fn _ykpiv_change_pin( /// /// The default PIN code is 123456 pub unsafe fn ykpiv_change_pin( - state: *mut YubiKey, + state: &mut YubiKey, current_pin: *const c_char, current_pin_len: usize, new_pin: *const c_char, @@ -1947,7 +1915,7 @@ pub unsafe fn ykpiv_change_pin( /// /// The default PUK code is 12345678. pub unsafe fn ykpiv_change_puk( - state: *mut YubiKey, + state: &mut YubiKey, current_puk: *const c_char, current_puk_len: usize, new_puk: *const c_char, @@ -1979,7 +1947,7 @@ pub unsafe fn ykpiv_change_puk( /// Unblock a Personal Identification Number (PIN) using a previously /// configured PIN Unblocking Key (PUK). pub unsafe fn ykpiv_unblock_pin( - state: *mut YubiKey, + state: &mut YubiKey, puk: *const c_char, puk_len: usize, new_pin: *const c_char, @@ -2005,7 +1973,7 @@ pub unsafe fn ykpiv_unblock_pin( /// Fetch an object from the YubiKey pub unsafe fn ykpiv_fetch_object( - state: *mut YubiKey, + state: &mut YubiKey, object_id: i32, data: *mut u8, len: *mut usize, @@ -2029,7 +1997,7 @@ pub unsafe fn ykpiv_fetch_object( /// Fetch an object pub(crate) unsafe fn _ykpiv_fetch_object( - state: *mut YubiKey, + state: &mut YubiKey, object_id: i32, data: *mut u8, len: *mut usize, @@ -2077,7 +2045,7 @@ pub(crate) unsafe fn _ykpiv_fetch_object( } if outlen.wrapping_add(offs).wrapping_add(1) != *len { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Invalid length indicated in object, total objlen is {}, indicated length is {}.", *len, outlen @@ -2099,7 +2067,7 @@ pub(crate) unsafe fn _ykpiv_fetch_object( /// Save an object pub unsafe fn ykpiv_save_object( - state: *mut YubiKey, + state: &mut YubiKey, object_id: i32, indata: *mut u8, len: usize, @@ -2123,7 +2091,7 @@ pub unsafe fn ykpiv_save_object( /// Save an object pub unsafe fn _ykpiv_save_object( - state: *mut YubiKey, + state: &mut YubiKey, object_id: i32, indata: *mut u8, len: usize, @@ -2196,7 +2164,7 @@ pub(crate) unsafe fn set_object(object_id: i32, mut buffer: *mut u8) -> *mut u8 /// Import a private encryption or signing key into the YubiKey pub unsafe fn ykpiv_import_private_key( - state: *mut YubiKey, + state: &mut YubiKey, key: u8, algorithm: u8, p: *const u8, @@ -2227,10 +2195,6 @@ pub unsafe fn ykpiv_import_private_key( let param_tag: i32; let mut res = ErrorKind::Ok; - if state.is_null() { - return Err(ErrorKind::GenericError); - } - if key == YKPIV_KEY_CARDMGM || key < YKPIV_KEY_RETIRED1 || key > YKPIV_KEY_RETIRED20 && (key < YKPIV_KEY_AUTHENTICATION) @@ -2376,7 +2340,7 @@ pub unsafe fn ykpiv_import_private_key( /// Generate an attestation certificate for a stored key pub unsafe fn ykpiv_attest( - state: *mut YubiKey, + state: &mut YubiKey, key: u8, data: *mut u8, data_len: *mut usize, @@ -2386,7 +2350,7 @@ pub unsafe fn ykpiv_attest( let mut sw: i32 = 0; let mut ul_data_len: usize; - if state.is_null() || data.is_null() || data_len.is_null() { + if data.is_null() || data_len.is_null() { return Err(ErrorKind::ArgumentError); } @@ -2430,7 +2394,7 @@ pub unsafe fn ykpiv_attest( /// Get an auth challenge pub unsafe fn ykpiv_auth_getchallenge( - state: *mut YubiKey, + state: &mut YubiKey, challenge: *mut u8, challenge_len: usize, ) -> Result<(), ErrorKind> { @@ -2439,7 +2403,7 @@ pub unsafe fn ykpiv_auth_getchallenge( let mut sw: i32 = 0; let mut res = ErrorKind::Ok; - if state.is_null() || challenge.is_null() { + if challenge.is_null() { return Err(ErrorKind::GenericError); } @@ -2485,7 +2449,7 @@ pub unsafe fn ykpiv_auth_getchallenge( /// Verify an auth response pub unsafe fn ykpiv_auth_verifyresponse( - state: *mut YubiKey, + state: &mut YubiKey, response: *mut u8, response_len: usize, ) -> Result<(), ErrorKind> { @@ -2494,7 +2458,7 @@ pub unsafe fn ykpiv_auth_verifyresponse( let mut sw: i32 = 0; let mut res: ErrorKind; - if state.is_null() || response.is_null() { + if response.is_null() { return Err(ErrorKind::GenericError); } @@ -2542,16 +2506,12 @@ pub unsafe fn ykpiv_auth_verifyresponse( static mut MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17]; /// Deauthenticate -pub unsafe fn ykpiv_auth_deauthenticate(state: *mut YubiKey) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_auth_deauthenticate(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; let mut res: ErrorKind; - if state.is_null() { - return Err(ErrorKind::ArgumentError); - } - res = _ykpiv_begin_transaction(state); if res != ErrorKind::Ok { @@ -2572,14 +2532,14 @@ pub unsafe fn ykpiv_auth_deauthenticate(state: *mut YubiKey) -> Result<(), Error res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res != ErrorKind::Ok { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!( "Failed communicating with card: \'{}\'", ykpiv_strerror(res) ); } } else if sw != SW_SUCCESS { - if (*state).verbose != 0 { + if state.verbose != 0 { eprintln!("Failed selecting mgmt application: {:04x}", sw); } res = ErrorKind::GenericError; From 6c03ea89ecebe8ddbdae0f2d9a9bd3ae0358ed16 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:09:59 +0000 Subject: [PATCH 03/17] Return Result<(), ErrorKind> from most internal APIs Started with _ykpiv_begin_transaction and kept going incrementally until it compiled again. --- src/util.rs | 459 ++++++++++++++++----------------------- src/yubikey.rs | 567 +++++++++++++++++++------------------------------ 2 files changed, 405 insertions(+), 621 deletions(-) diff --git a/src/util.rs b/src/util.rs index 25999f5..b2b4612 100644 --- a/src/util.rs +++ b/src/util.rs @@ -86,22 +86,20 @@ pub unsafe fn ykpiv_util_get_cardid( ) -> Result<(), ErrorKind> { let mut buf = [0u8; CB_OBJ_MAX]; let mut len = buf.len(); - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); if cardid.is_null() { return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_fetch_object(state, YKPIV_OBJ_CHUID as i32, buf.as_mut_ptr(), &mut len); - if res == ErrorKind::Ok { + if res.is_ok() { if len != CHUID_TMPL.len() { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } else { memcpy( (*cardid).0.as_mut_ptr() as (*mut c_void), @@ -113,10 +111,7 @@ pub unsafe fn ykpiv_util_get_cardid( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Set Card ID @@ -126,7 +121,7 @@ pub unsafe fn ykpiv_util_set_cardid( ) -> Result<(), ErrorKind> { let mut id = [0u8; YKPIV_CARDID_SIZE]; let mut buf = [0u8; CHUID_TMPL.len()]; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); if cardid.is_null() { if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { @@ -140,11 +135,9 @@ pub unsafe fn ykpiv_util_set_cardid( ); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { memcpy( buf.as_mut_ptr() as *mut c_void, CHUID_TMPL.as_ptr() as *const c_void, @@ -166,10 +159,7 @@ pub unsafe fn ykpiv_util_set_cardid( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Cardholder Capability Container (CCC) Identifier @@ -178,7 +168,7 @@ pub struct CCCID([u8; 14]); /// Get Cardholder Capability Container (CCC) ID pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; CB_OBJ_MAX]; let mut len = buf.len(); @@ -186,11 +176,9 @@ pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Resu return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_fetch_object( state, YKPIV_OBJ_CAPABILITY as i32, @@ -198,7 +186,7 @@ pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Resu &mut len, ); - if res == ErrorKind::Ok { + if res.is_ok() { if len != CCC_TMPL.len() { _ykpiv_end_transaction(state); return Err(ErrorKind::GenericError); @@ -212,10 +200,7 @@ pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Resu } } - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get Cardholder Capability Container (CCC) ID @@ -223,7 +208,7 @@ pub unsafe fn ykpiv_util_set_cccid( state: &mut YubiKey, ccc: *const CCCID, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut id = [0u8; 14]; let mut buf = [0u8; 51]; let len: usize; @@ -240,11 +225,9 @@ pub unsafe fn ykpiv_util_set_cccid( ); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { len = 51; memcpy( @@ -263,10 +246,7 @@ pub unsafe fn ykpiv_util_set_cccid( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get YubiKey device model @@ -347,11 +327,9 @@ pub unsafe fn ykpiv_util_list_keys( return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { *key_count = 0; *data = ptr::null_mut(); *data_len = 0; @@ -473,11 +451,9 @@ pub unsafe fn ykpiv_util_read_cert( return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { *data = ptr::null_mut(); *data_len = 0; res = _read_certificate(state, slot, buf.as_mut_ptr(), &mut cb_buf); @@ -518,21 +494,16 @@ pub unsafe fn ykpiv_util_write_cert( data_len: usize, certinfo: u8, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _write_certificate(state, slot, data, data_len, certinfo); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Delete certificate @@ -543,7 +514,7 @@ pub unsafe fn ykpiv_util_delete_cert(state: &mut YubiKey, slot: u8) -> Result<() /// Block PUK pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut _currentBlock; - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44]; let mut tries: i32 = -1; let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; @@ -552,11 +523,9 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> let mut cb_item: usize = 0; let mut flags: u8 = 0; - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { _currentBlock = 20; } else { _currentBlock = 3; @@ -574,24 +543,24 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> &mut tries, ); - if res == ErrorKind::Ok { + if res.is_ok() { let _rhs = 1; let mut _lhs = &mut puk[0]; *_lhs += _rhs; _currentBlock = 3; } else { - if res != ErrorKind::PinLocked { + if res != Err(ErrorKind::PinLocked) { _currentBlock = 3; continue; } tries = 0; - res = ErrorKind::Ok; + res = Ok(()); _currentBlock = 3; } } else { let res = _read_metadata(state, TAG_ADMIN, data.as_mut_ptr(), &mut cb_data); - if res == ErrorKind::Ok { + if res.is_ok() { let res = _get_metadata_item( data.as_mut_ptr(), cb_data, @@ -600,7 +569,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> &mut cb_item, ); - if res == ErrorKind::Ok { + if res.is_ok() { if cb_item == 1 { // TODO(tarcieri): get rid of memcpy and pointers, replace with slices! #[allow(trivial_casts)] @@ -624,7 +593,8 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> TAG_ADMIN_FLAGS_1, &mut flags, 1, - ) != ErrorKind::Ok + ) + .is_err() { if state.verbose == 0 { _currentBlock = 20; @@ -633,7 +603,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> eprintln!("could not set admin flags"); _currentBlock = 20; } else { - if _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data) == ErrorKind::Ok { + if _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data).is_ok() { _currentBlock = 20; continue; } @@ -647,10 +617,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> } } else { _ykpiv_end_transaction(state); - return match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - }; + return res; } } } @@ -691,7 +658,7 @@ pub unsafe fn ykpiv_util_read_mscmap( containers: *mut *mut YkPivContainer, n_containers: *mut usize, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_buf: usize = buf.len(); let mut len: usize = 0; @@ -699,14 +666,12 @@ pub unsafe fn ykpiv_util_read_mscmap( if containers.is_null() || n_containers.is_null() { // TODO(str4d): Should this really continue on here? - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { *containers = ptr::null_mut(); *n_containers = 0; @@ -717,12 +682,9 @@ pub unsafe fn ykpiv_util_read_mscmap( &mut cb_buf, ); - if res != ErrorKind::Ok { + if res.is_err() { _ykpiv_end_transaction(state); - return match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - }; + return res; } ptr = buf.as_mut_ptr(); @@ -744,7 +706,7 @@ pub unsafe fn ykpiv_util_read_mscmap( *containers = calloc(len, 1) as (*mut YkPivContainer); if (*containers).is_null() { - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { memcpy(*containers as (*mut c_void), ptr as (*const c_void), len); *n_containers = len.wrapping_div(mem::size_of::()); @@ -752,10 +714,7 @@ pub unsafe fn ykpiv_util_read_mscmap( } } - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get max object size @@ -773,28 +732,23 @@ pub unsafe fn ykpiv_util_write_mscmap( containers: *mut YkPivContainer, n_containers: usize, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; CB_OBJ_MAX]; let mut offset: usize = 0; let data_len: usize = n_containers.wrapping_mul(mem::size_of::()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { if containers.is_null() || n_containers == 0 { if !containers.is_null() || n_containers != 0 { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } else { res = _ykpiv_save_object(state, YKPIV_OBJ_MSCMAP as i32, ptr::null_mut(), 0); } _ykpiv_end_transaction(state); - return match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - }; + return res; } let req_len = 1 + _ykpiv_set_length(buf.as_mut_ptr(), data_len) + data_len; @@ -817,10 +771,7 @@ pub unsafe fn ykpiv_util_write_mscmap( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Read msroots @@ -830,7 +781,7 @@ pub unsafe fn ykpiv_util_read_msroots( data_len: *mut usize, ) -> Result<(), ErrorKind> { let mut _currentBlock; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_buf: usize; let mut len: usize = 0; @@ -847,18 +798,16 @@ pub unsafe fn ykpiv_util_read_msroots( return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { *data = ptr::null_mut(); *data_len = 0; cb_data = _obj_size_max(state); p_data = calloc(cb_data, 1) as (*mut u8); if p_data.is_null() { - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { object_id = YKPIV_OBJ_MSROOTS1 as i32; loop { @@ -870,7 +819,7 @@ pub unsafe fn ykpiv_util_read_msroots( res = _ykpiv_fetch_object(state, object_id, buf.as_mut_ptr(), &mut cb_buf); - if res != ErrorKind::Ok { + if res.is_err() { _currentBlock = 21; break; } @@ -936,11 +885,11 @@ pub unsafe fn ykpiv_util_read_msroots( *data = p_data; p_data = ptr::null_mut(); *data_len = offset; - res = ErrorKind::Ok; + res = Ok(()); } else if _currentBlock == 16 { - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { - res = ErrorKind::Ok; + res = Ok(()); } } } @@ -950,10 +899,7 @@ pub unsafe fn ykpiv_util_read_msroots( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Write msroots @@ -962,7 +908,7 @@ pub unsafe fn ykpiv_util_write_msroots( data: *mut u8, data_len: usize, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; CB_OBJ_MAX]; let mut offset: usize; let mut data_offset: usize = 0; @@ -970,23 +916,18 @@ pub unsafe fn ykpiv_util_write_msroots( let n_objs: usize; let cb_obj_max = _obj_size_max(state); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { if data.is_null() || data_len == 0 { if !data.is_null() || data_len != 0 { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } else { res = _ykpiv_save_object(state, YKPIV_OBJ_MSROOTS1 as i32, ptr::null_mut(), 0); } _ykpiv_end_transaction(state); - return match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - }; + return res; } n_objs = (data_len / (cb_obj_max - 4)) + 1; @@ -1029,7 +970,7 @@ pub unsafe fn ykpiv_util_write_msroots( offset, ); - if res != ErrorKind::Ok { + if res.is_err() { break; } @@ -1038,10 +979,7 @@ pub unsafe fn ykpiv_util_write_msroots( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } // Keygen messages @@ -1070,7 +1008,7 @@ pub unsafe fn ykpiv_util_generate_key( point: *mut *mut u8, point_len: *mut usize, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut in_data = [0u8; 11]; let mut in_ptr = in_data.as_mut_ptr(); let mut data = [0u8; 1024]; @@ -1116,8 +1054,7 @@ pub unsafe fn ykpiv_util_generate_key( (ROCA) and should be replaced. On-chip key generation {} See \ YSA-2017-01 \ for additional information on device replacement and mitigation assistance", - state.serial, - psz_msg + state.serial, psz_msg ); if !setting_roca.value { @@ -1159,11 +1096,9 @@ pub unsafe fn ykpiv_util_generate_key( } } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { templ[3] = slot; *{ let _old = in_ptr; @@ -1196,7 +1131,7 @@ pub unsafe fn ykpiv_util_generate_key( } = algorithm; if in_data[4] == 0 { - res = ErrorKind::AlgorithmError; + res = Err(ErrorKind::AlgorithmError); if state.verbose != 0 { eprintln!("Unexpected algorithm.\n"); } @@ -1253,7 +1188,7 @@ pub unsafe fn ykpiv_util_generate_key( &mut sw, ); - if res != ErrorKind::Ok { + if res.is_err() { if state.verbose != 0 { eprintln!("Failed to communicate."); } @@ -1264,13 +1199,13 @@ pub unsafe fn ykpiv_util_generate_key( match sw { SW_ERR_INCORRECT_SLOT => { - res = ErrorKind::KeyError; + res = Err(ErrorKind::KeyError); if state.verbose != 0 { eprintln!("incorrect slot)"); } } SW_ERR_INCORRECT_PARAM => { - res = ErrorKind::AlgorithmError; + res = Err(ErrorKind::AlgorithmError); if state.verbose != 0 { if pin_policy as (i32) != 0i32 { eprintln!("pin policy not supported?)",); @@ -1282,13 +1217,13 @@ pub unsafe fn ykpiv_util_generate_key( } } SW_ERR_SECURITY_STATUS => { - res = ErrorKind::AuthenticationError; + res = Err(ErrorKind::AuthenticationError); if state.verbose != 0 { eprintln!("not authenticated)"); } } _ => { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); if state.verbose != 0 { eprintln!("error {:x})", sw); } @@ -1301,7 +1236,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Failed to parse public key structure (modulus)."); } - res = ErrorKind::ParseError; + res = Err(ErrorKind::ParseError); } else { data_ptr = data_ptr.add(1); data_ptr = data_ptr.add(_ykpiv_get_length(data_ptr, &mut len)); @@ -1311,7 +1246,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Failed to allocate memory for modulus."); } - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { memcpy( ptr_modulus as *mut c_void, @@ -1325,7 +1260,7 @@ pub unsafe fn ykpiv_util_generate_key( "Failed to parse public key structure (public exponent)." ); } - res = ErrorKind::ParseError; + res = Err(ErrorKind::ParseError); } else { data_ptr = data_ptr.add(1); data_ptr = data_ptr.add(_ykpiv_get_length(data_ptr, &mut len)); @@ -1335,7 +1270,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Failed to allocate memory for public exponent."); } - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { memcpy( ptr_exp as (*mut c_void), @@ -1370,7 +1305,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Failed to parse public key structure.\n",); } - res = ErrorKind::ParseError; + res = Err(ErrorKind::ParseError); } else if *{ let _old = data_ptr; data_ptr = data_ptr.offset(1); @@ -1381,7 +1316,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Unexpected length.\n"); } - res = ErrorKind::AlgorithmError; + res = Err(ErrorKind::AlgorithmError); } else { cb_point = len; ptr_point = calloc(cb_point, 1) as (*mut u8); @@ -1389,7 +1324,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Failed to allocate memory for public point."); } - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { memcpy( ptr_point as (*mut c_void), @@ -1405,7 +1340,7 @@ pub unsafe fn ykpiv_util_generate_key( if state.verbose != 0 { eprintln!("Wrong algorithm."); } - res = ErrorKind::AlgorithmError; + res = Err(ErrorKind::AlgorithmError); } } } @@ -1423,10 +1358,7 @@ pub unsafe fn ykpiv_util_generate_key( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Config mgm type @@ -1484,19 +1416,18 @@ pub unsafe fn ykpiv_util_get_config( (*config).pin_last_changed = 0u32; (*config).mgm_type = YkPivConfigMgmType::YKPIV_CONFIG_MGM_MANUAL; - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { - if _read_metadata(state, 0x80u8, data.as_mut_ptr(), &mut cb_data) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { + if _read_metadata(state, 0x80u8, data.as_mut_ptr(), &mut cb_data).is_ok() { if _get_metadata_item( data.as_mut_ptr(), cb_data, 0x81u8, &mut p_item, &mut cb_item, - ) == ErrorKind::Ok + ) + .is_ok() { if *p_item & 0x1 != 0 { (*config).puk_blocked = 1u8; @@ -1512,7 +1443,8 @@ pub unsafe fn ykpiv_util_get_config( 0x82u8, &mut p_item, &mut cb_item, - ) == ErrorKind::Ok + ) + .is_ok() { if (*config).mgm_type as (i32) != YkPivConfigMgmType::YKPIV_CONFIG_MGM_MANUAL as (i32) @@ -1531,7 +1463,8 @@ pub unsafe fn ykpiv_util_get_config( 0x83u8, &mut p_item, &mut cb_item, - ) == ErrorKind::Ok + ) + .is_ok() { if cb_item != 4 { if state.verbose != 0 { @@ -1549,7 +1482,7 @@ pub unsafe fn ykpiv_util_get_config( } } cb_data = mem::size_of::<[u8; YKPIV_OBJ_MAX_SIZE]>(); - if _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data) == ErrorKind::Ok { + if _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data).is_ok() { (*config).protected_data_available = 1u8; let res = _get_metadata_item( @@ -1560,7 +1493,7 @@ pub unsafe fn ykpiv_util_get_config( &mut cb_item, ); - if res == ErrorKind::Ok && *p_item as (i32) & 0x1i32 != 0 { + if res.is_ok() && *p_item as (i32) & 0x1i32 != 0 { (*config).puk_noblock_on_upgrade = 1u8; } @@ -1572,7 +1505,7 @@ pub unsafe fn ykpiv_util_get_config( &mut cb_item, ); - if res == ErrorKind::Ok { + if res.is_ok() { if (*config).mgm_type != YkPivConfigMgmType::YKPIV_CONFIG_MGM_PROTECTED && state.verbose != 0 { @@ -1596,17 +1529,12 @@ pub unsafe fn ykpiv_util_get_config( pub unsafe fn ykpiv_util_set_pin_last_changed(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data = data.len(); - let mut res = ErrorKind::Ok; - let ykrc: ErrorKind; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { - ykrc = _read_metadata(state, 0x80, data.as_mut_ptr(), &mut cb_data); - - if ykrc != ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { + if _read_metadata(state, 0x80, data.as_mut_ptr(), &mut cb_data).is_err() { cb_data = 0; } @@ -1625,22 +1553,21 @@ pub unsafe fn ykpiv_util_set_pin_last_changed(state: &mut YubiKey) -> Result<(), ) }; - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!("could not set pin timestamp, err = {}\n", res as (i32),); + eprintln!("could not set pin timestamp, err = {}\n", e,); } } else { res = _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data); - if res != ErrorKind::Ok && state.verbose != 0 { - eprintln!("could not write admin data, err = {}", res); + if let Err(e) = res.as_ref() { + if state.verbose != 0 { + eprintln!("could not write admin data, err = {}", e); + } } } } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Management key (MGM) @@ -1670,20 +1597,18 @@ pub unsafe fn ykpiv_util_get_derived_mgm( let mut cb_data: usize = data.len(); let mut p_item: *mut u8 = ptr::null_mut(); let mut cb_item: usize = 0; - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); if pin.is_null() || pin_len == 0 || mgm.is_null() { return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _read_metadata(state, 0x80u8, data.as_mut_ptr(), &mut cb_data); - if res == ErrorKind::Ok { + if res.is_ok() { res = _get_metadata_item( data.as_mut_ptr(), cb_data, @@ -1692,7 +1617,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( &mut cb_item, ); - if res == ErrorKind::Ok { + if res.is_ok() { if cb_item != 16usize { if state.verbose != 0 { eprintln!( @@ -1700,7 +1625,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( cb_item, ); } - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } else { let p5rc = pkcs5_pbkdf2_sha1( pin, @@ -1717,7 +1642,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( eprintln!("pbkdf2 failure, err = {:?}", p5rc); } - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } } } @@ -1725,10 +1650,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get protected management key (MGM) @@ -1740,20 +1662,18 @@ pub unsafe fn ykpiv_util_get_protected_mgm( let mut cb_data: usize = data.len(); let mut p_item: *mut u8 = ptr::null_mut(); let mut cb_item: usize = 0; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); if mgm.is_null() { return Err(ErrorKind::GenericError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data); - if res != ErrorKind::Ok { + if res.is_err() { if state.verbose != 0 { eprintln!("could not read protected data, err = {:?}", res); } @@ -1766,12 +1686,9 @@ pub unsafe fn ykpiv_util_get_protected_mgm( &mut cb_item, ); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "could not read protected mgm from metadata, err = {}", - res as (i32), - ); + eprintln!("could not read protected mgm from metadata, err = {}", e,); } } else if cb_item != (*mgm).0.len() { if state.verbose != 0 { @@ -1780,7 +1697,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( cb_item, ); } - res = ErrorKind::AuthenticationError; + res = Err(ErrorKind::AuthenticationError); } else { memcpy( (*mgm).0.as_mut_ptr() as (*mut c_void), @@ -1793,10 +1710,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( data.zeroize(); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Set protected management key (MGM) @@ -1806,8 +1720,8 @@ pub unsafe fn ykpiv_util_set_protected_mgm( mgm: *mut YkPivMgm, ) -> Result<(), ErrorKind> { let mut _currentBlock; - let mut res: ErrorKind = ErrorKind::Ok; - let mut ykrc: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); + let mut ykrc = Ok(()); let mut prngrc: PRngErrorKind = PRngErrorKind::Ok; let mut f_generate: bool; let mut mgm_key = [0u8; 24]; @@ -1845,11 +1759,9 @@ pub unsafe fn ykpiv_util_set_protected_mgm( } } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { loop { if f_generate { prngrc = _ykpiv_prng_generate(mgm_key.as_mut_ptr(), mem::size_of::<[u8; 24]>()); @@ -1860,8 +1772,8 @@ pub unsafe fn ykpiv_util_set_protected_mgm( } ykrc = ykpiv_set_mgmkey(state, mgm_key.as_mut_ptr()); - if ykrc != ErrorKind::Ok { - if ErrorKind::KeyError as (i32) != ykrc as (i32) { + if ykrc.is_err() { + if Err(ErrorKind::KeyError) != ykrc { _currentBlock = 44; break; } @@ -1885,7 +1797,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( ykrc = _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data); - if ykrc != ErrorKind::Ok { + if ykrc.is_err() { cb_data = 0; } @@ -1898,7 +1810,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( mgm_key.len(), ); - if ykrc != ErrorKind::Ok { + if ykrc.is_err() { if state.verbose != 0 { eprintln!("could not set protected mgm item, err = {:?}", ykrc); _currentBlock = 26; @@ -1907,7 +1819,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( } } else { ykrc = _write_metadata(state, 0x88u8, data.as_mut_ptr(), cb_data); - if ykrc != ErrorKind::Ok { + if ykrc.is_err() { if state.verbose != 0 { eprintln!("could not write protected data, err = {:?}", ykrc); _currentBlock = 51; @@ -1923,7 +1835,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( cb_data = YKPIV_OBJ_MAX_SIZE; ykrc = _read_metadata(state, 0x80u8, data.as_mut_ptr(), &mut cb_data); - if ykrc != ErrorKind::Ok { + if ykrc.is_err() { cb_data = 0; } else { ykrc = _get_metadata_item( @@ -1934,7 +1846,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( &mut cb_item, ); - if ykrc != ErrorKind::Ok && state.verbose != 0 { + if ykrc.is_err() && state.verbose != 0 { eprintln!("admin data exists, but flags are not present",); } @@ -1959,8 +1871,10 @@ pub unsafe fn ykpiv_util_set_protected_mgm( 0, ); - if ykrc != ErrorKind::Ok && state.verbose != 0 { - eprintln!("could not unset derived mgm salt, err = {}", ykrc); + if let Err(e) = ykrc.as_ref() { + if state.verbose != 0 { + eprintln!("could not unset derived mgm salt, err = {}", e); + } } } flags_1 |= 0x2; @@ -1974,20 +1888,25 @@ pub unsafe fn ykpiv_util_set_protected_mgm( 1, ); - if ykrc != ErrorKind::Ok { + if let Err(e) = ykrc.as_ref() { if state.verbose != 0 { - eprintln!("could not set admin flags item, err = {}", ykrc); + eprintln!("could not set admin flags item, err = {}", e); } } else { ykrc = _write_metadata(state, 0x80u8, data.as_mut_ptr(), cb_data); - if ykrc != ErrorKind::Ok && state.verbose != 0 { - eprintln!("could not write admin data, err = {}", ykrc); + if let Err(e) = ykrc.as_ref() { + if state.verbose != 0 { + eprintln!("could not write admin data, err = {}", e); + } } } } } else if _currentBlock == 44 { if state.verbose != 0 { - eprintln!("could not set new derived mgm key, err = {}", ykrc); + eprintln!( + "could not set new derived mgm key, err = {}", + ykrc.as_ref().unwrap_err() + ); } res = ykrc; @@ -1996,7 +1915,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( eprintln!("could not generate new mgm, err = {:?}", prngrc); } - res = ErrorKind::RandomnessError; + res = Err(ErrorKind::RandomnessError); } } @@ -2004,10 +1923,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( mgm_key.zeroize(); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Reset @@ -2027,8 +1943,8 @@ pub unsafe fn ykpiv_util_reset(state: &mut YubiKey) -> Result<(), ErrorKind> { &mut sw, ); - match (res, sw) { - (ErrorKind::Ok, SW_SUCCESS) => Ok(()), + match (res.is_ok(), sw) { + (true, SW_SUCCESS) => Ok(()), _ => Err(ErrorKind::GenericError), } } @@ -2066,7 +1982,7 @@ unsafe fn _read_certificate( return ErrorKind::InvalidObject; } - if _ykpiv_fetch_object(state, object_id, buf, buf_len) == ErrorKind::Ok { + if _ykpiv_fetch_object(state, object_id, buf, buf_len).is_ok() { ptr = buf; if *buf_len < CB_OBJ_TAG_MIN { @@ -2102,19 +2018,19 @@ unsafe fn _write_certificate( data: *mut u8, data_len: usize, certinfo: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut buf = [0u8; CB_OBJ_MAX]; let object_id = ykpiv_util_slot_object(slot) as i32; let mut offset: usize = 0; let mut req_len: usize; if object_id == -1 { - return ErrorKind::InvalidObject; + return Err(ErrorKind::InvalidObject); } if data.is_null() || data_len == 0 { if !data.is_null() || data_len != 0 { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } return _ykpiv_save_object(state, object_id, ptr::null_mut(), 0); @@ -2125,7 +2041,7 @@ unsafe fn _write_certificate( req_len += data_len; if req_len < data_len || req_len > _obj_size_max(state) { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } buf[offset] = TAG_CERT; @@ -2163,13 +2079,13 @@ unsafe fn _get_metadata_item( tag: u8, pp_item: *mut *mut u8, pcb_item: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut p_temp: *mut u8 = data; let mut cb_temp: usize = 0; let mut tag_temp: u8; if data.is_null() || pp_item.is_null() || pcb_item.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } *pp_item = ptr::null_mut(); @@ -2180,7 +2096,7 @@ unsafe fn _get_metadata_item( p_temp = p_temp.add(1); if !_ykpiv_has_valid_length(p_temp, data.add(cb_data) as usize - p_temp as usize) { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } p_temp = p_temp.add(_ykpiv_get_length(p_temp, &mut cb_temp)); @@ -2196,9 +2112,9 @@ unsafe fn _get_metadata_item( *pp_item = p_temp; *pcb_item = cb_temp; - ErrorKind::Ok + Ok(()) } else { - ErrorKind::GenericError + Err(ErrorKind::GenericError) } } @@ -2221,7 +2137,7 @@ unsafe fn _set_metadata_item( tag: u8, p_item: *mut u8, cb_item: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut p_temp: *mut u8 = data; let mut cb_temp: usize = 0; let mut tag_temp: u8 = 0; @@ -2230,7 +2146,7 @@ unsafe fn _set_metadata_item( let cb_moved: isize; if data.is_null() || pcb_data.is_null() { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } while p_temp < data.add(*pcb_data) { @@ -2249,14 +2165,14 @@ unsafe fn _set_metadata_item( if tag_temp != tag { if cb_item == 0 { - return ErrorKind::Ok; + return Ok(()); } p_temp = data.add(*pcb_data); cb_len = _get_length_size(cb_item) as (usize); if (*pcb_data).wrapping_add(cb_len).wrapping_add(cb_item) > cb_data_max { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } *p_temp = tag; @@ -2266,12 +2182,12 @@ unsafe fn _set_metadata_item( memcpy(p_temp as (*mut c_void), p_item as (*const c_void), cb_item); *pcb_data += 1 + cb_len + cb_item; - return ErrorKind::Ok; + return Ok(()); } if cb_temp == cb_item { memcpy(p_temp as (*mut c_void), p_item as (*const c_void), cb_item); - return ErrorKind::Ok; + return Ok(()); } p_next = p_temp.add(cb_temp); @@ -2284,7 +2200,7 @@ unsafe fn _set_metadata_item( - cb_len as (isize)); if (*pcb_data + cb_moved as usize) > cb_data_max { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } memmove( @@ -2304,7 +2220,7 @@ unsafe fn _set_metadata_item( memcpy(p_temp as (*mut c_void), p_item as (*const c_void), cb_item); } - ErrorKind::Ok + Ok(()) } /// Read metadata @@ -2313,32 +2229,27 @@ unsafe fn _read_metadata( tag: u8, data: *mut u8, pcb_data: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut p_temp: *mut u8; let mut cb_temp: usize; - let res: ErrorKind; if data.is_null() || pcb_data.is_null() || YKPIV_OBJ_MAX_SIZE > *pcb_data { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } let obj_id = match tag { TAG_ADMIN => YKPIV_OBJ_ADMIN_DATA, TAG_PROTECTED => YKPIV_OBJ_PRINTED, - _ => return ErrorKind::InvalidObject, + _ => return Err(ErrorKind::InvalidObject), } as i32; cb_temp = *pcb_data; *pcb_data = 0; - res = _ykpiv_fetch_object(state, obj_id, data, &mut cb_temp); - - if res != ErrorKind::Ok { - return res; - } + _ykpiv_fetch_object(state, obj_id, data, &mut cb_temp)?; if cb_temp < CB_OBJ_TAG_MIN { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } p_temp = data; @@ -2349,18 +2260,18 @@ unsafe fn _read_metadata( _old } as (i32) { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } p_temp = p_temp.add(_ykpiv_get_length(p_temp, pcb_data)); if *pcb_data > cb_temp - (p_temp as isize - data as isize) as usize { *pcb_data = 0; - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } memmove(data as (*mut c_void), p_temp as (*const c_void), *pcb_data); - ErrorKind::Ok + Ok(()) } /// Write metadata @@ -2369,18 +2280,18 @@ unsafe fn _write_metadata( tag: u8, data: *mut u8, cb_data: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut buf = [0u8; CB_OBJ_MAX]; // XXX REMEMBER TO ZERO let mut p_temp: *mut u8 = buf.as_mut_ptr(); if cb_data > _obj_size_max(state) - CB_OBJ_TAG_MAX { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } let obj_id = match tag { TAG_ADMIN => YKPIV_OBJ_ADMIN_DATA, TAG_PROTECTED => YKPIV_OBJ_PRINTED, - _ => return ErrorKind::InvalidObject, + _ => return Err(ErrorKind::InvalidObject), } as i32; if data.is_null() || cb_data == 0 { diff --git a/src/yubikey.rs b/src/yubikey.rs index c421c49..3ecd546 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -36,7 +36,7 @@ use crate::{ apdu::APDU, consts::*, - error::{ykpiv_strerror, ErrorKind}, + error::ErrorKind, internal::{ des_decrypt, des_destroy_key, des_encrypt, des_import_key, yk_des_is_weak_key, DesErrorKind, DesKey, PRngErrorKind, _ykpiv_prng_generate, @@ -231,11 +231,10 @@ pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> ErrorKind { } /// Select application -pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; let mut sw = 0i32; - let mut res: ErrorKind; let mut apdu = APDU::default(); apdu.ins = YKPIV_INS_SELECT_APPLICATION; @@ -248,20 +247,17 @@ pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> ErrorKind AID.len(), ); - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); + let mut res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed selecting application: {:04x}", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } // now that the PIV application is selected, retrieve the version @@ -273,28 +269,29 @@ pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> ErrorKind // will result in another selection of the PIV applet. res = _ykpiv_get_version(state, ptr::null_mut()); - if res != ErrorKind::Ok && state.verbose != 0 { - eprintln!("Failed to retrieve version: \'{}\'", ykpiv_strerror(res)); + if let Err(e) = res.as_ref() { + if state.verbose != 0 { + eprintln!("Failed to retrieve version: \'{}\'", e); + } } res = _ykpiv_get_serial(state, ptr::null_mut(), false); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed to retrieve serial number: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed to retrieve serial number: \'{}\'", e); } - res = ErrorKind::Ok; + res = Ok(()); } res } /// Ensure an application is selected (presently noop) -pub(crate) unsafe fn _ykpiv_ensure_application_selected(_state: &mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_ensure_application_selected( + _state: &mut YubiKey, +) -> Result<(), ErrorKind> { // TODO(tarcieri): ENABLE_APPLICATION_RESELECTION support? // // Original C code below: @@ -319,7 +316,7 @@ pub(crate) unsafe fn _ykpiv_ensure_application_selected(_state: &mut YubiKey) -> // return res; // #endif - ErrorKind::Ok + Ok(()) } /// Connect to the YubiKey @@ -392,7 +389,7 @@ pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Resul let mut reader_ptr: *mut c_char; let mut card: i32 = -1i32; - let mut ret: ErrorKind = ykpiv_list_readers(state, reader_buf.as_mut_ptr(), &mut num_readers); + let ret: ErrorKind = ykpiv_list_readers(state, reader_buf.as_mut_ptr(), &mut num_readers); if ret != ErrorKind::Ok { return Err(ret); @@ -495,16 +492,11 @@ pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Resul // Select applet. This is done here instead of in _ykpiv_connect() because // you may not want to select the applet when connecting to a card handle that // was supplied by an external library. - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - ret = _ykpiv_select_application(state); + let res = _ykpiv_select_application(state); _ykpiv_end_transaction(state); - match ret { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// List readers @@ -566,7 +558,7 @@ pub unsafe fn ykpiv_list_readers( } /// Reconnect to a YubiKey -pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut active_protocol: u32 = 0; let mut tries: i32 = 0; @@ -580,32 +572,24 @@ pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> ErrorKind { if state.verbose != 0 { eprintln!("SCardReconnect failed, rc={}", rc); } - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } - let res = _ykpiv_select_application(state); - - if res != ErrorKind::Ok { - return res; - } + _ykpiv_select_application(state)?; if !state.pin.is_null() { ykpiv_verify(state, state.pin as *const c_char, &mut tries) } else { - ErrorKind::Ok + Ok(()) } } /// Begin a transaction -pub(crate) unsafe fn _ykpiv_begin_transaction(state: &mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_begin_transaction(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut rc = SCardBeginTransaction(state.card); if rc as usize & 0xffff_ffff == 0x8010_0068 { - let res = reconnect(state); - - if res != ErrorKind::Ok { - return res; - } + reconnect(state)?; rc = SCardBeginTransaction(state.card); } @@ -615,22 +599,22 @@ pub(crate) unsafe fn _ykpiv_begin_transaction(state: &mut YubiKey) -> ErrorKind eprintln!("error: Failed to begin pcsc transaction, rc={}", rc); } - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } - ErrorKind::Ok + Ok(()) } /// End a transaction -pub(crate) unsafe fn _ykpiv_end_transaction(state: &mut YubiKey) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_end_transaction(state: &mut YubiKey) -> Result<(), ErrorKind> { let rc = SCardEndTransaction(state.card, 0x0); if rc != 0x0 && state.verbose != 0 { eprintln!("error: Failed to end pcsc transaction, rc={}", rc); - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } - ErrorKind::Ok + Ok(()) } /// Transfer data @@ -642,11 +626,11 @@ pub(crate) unsafe fn _ykpiv_transfer_data( mut out_data: *mut u8, out_len: *mut usize, sw: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut in_ptr: *const u8 = in_data; let max_out = *out_len; - let mut res: ErrorKind; + let mut res: Result<(), ErrorKind>; let mut recv_len: u32; *out_len = 0; @@ -681,7 +665,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, sw); - if res != ErrorKind::Ok { + if res.is_err() { _currentBlock = 24; break; } @@ -737,7 +721,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( apdu.ins = YKPIV_INS_GET_RESPONSE_APDU; res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, sw); - if res != ErrorKind::Ok { + if res.is_err() { _currentBlock = 24; break; } @@ -772,7 +756,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( max_out ); } - res = ErrorKind::SizeError; + res = Err(ErrorKind::SizeError); } } else if _currentBlock == 21 { if state.verbose != 0 { @@ -782,7 +766,7 @@ pub(crate) unsafe fn _ykpiv_transfer_data( max_out ); } - res = ErrorKind::SizeError; + res = Err(ErrorKind::SizeError); } res } @@ -796,10 +780,10 @@ pub unsafe fn ykpiv_transfer_data( out_data: *mut u8, out_len: *mut usize, sw: *mut i32, -) -> ErrorKind { - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { +) -> Result<(), ErrorKind> { + if let Err(e) = _ykpiv_begin_transaction(state) { *out_len = 0; - return ErrorKind::PcscError; + return Err(e); } let res = _ykpiv_transfer_data(state, templ, in_data, in_len, out_data, out_len, sw); @@ -824,7 +808,7 @@ pub(crate) unsafe fn _send_data( data: *mut u8, recv_len: *mut u32, sw: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let send_len = (*apdu).lc as u32 + 5; let mut tmp_len = *recv_len; @@ -849,7 +833,7 @@ pub(crate) unsafe fn _send_data( eprintln!("error: SCardTransmit failed, rc={:08x}", rc); } - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } *recv_len = tmp_len; @@ -867,7 +851,7 @@ pub(crate) unsafe fn _send_data( *sw = 0; } - ErrorKind::Ok + Ok(()) } /// Default authentication key @@ -882,13 +866,11 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res let mut drc: DesErrorKind; let mut mgm_key: *mut DesKey = ptr::null_mut(); let mut out_len: usize; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { if key.is_null() { key = DEFAULT_AUTH_KEY.as_ptr(); } @@ -917,9 +899,9 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if res.is_err() { _ykpiv_end_transaction(state); - return Err(res); + return res; } if sw != SW_SUCCESS { @@ -985,9 +967,9 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if res.is_err() { _ykpiv_end_transaction(state); - return Err(res); + return res; } if sw != SW_SUCCESS { @@ -1014,9 +996,9 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res 8, ) == 0 { - res = ErrorKind::Ok; + res = Ok(()); } else { - res = ErrorKind::AuthenticationError; + res = Err(ErrorKind::AuthenticationError); } } @@ -1025,14 +1007,11 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Set the management key (MGM) -pub unsafe fn ykpiv_set_mgmkey(state: &mut YubiKey, new_key: *const u8) -> ErrorKind { +pub unsafe fn ykpiv_set_mgmkey(state: &mut YubiKey, new_key: *const u8) -> Result<(), ErrorKind> { ykpiv_set_mgmkey2(state, new_key, 0) } @@ -1041,18 +1020,16 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( state: &mut YubiKey, new_key: *const u8, touch: u8, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); let mut apdu = APDU::default(); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { if yk_des_is_weak_key(new_key, (8i32 * 3i32) as (usize)) { if state.verbose != 0 { // TODO(tarcieri): format string @@ -1060,7 +1037,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( dump_hex(new_key, DES_LEN_3DES as u32); eprintln!("\' since it\'s weak (with odd parity)."); } - res = ErrorKind::KeyError; + res = Err(ErrorKind::KeyError); apdu.ins = YKPIV_INS_SET_MGMKEY; apdu.p1 = 0xff; @@ -1069,7 +1046,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( 1 => 0xfe, _ => { _ykpiv_end_transaction(state); - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } }; @@ -1085,8 +1062,9 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( } else { res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok && sw != SW_SUCCESS { - res = ErrorKind::GenericError; + // TODO(str4d): Shouldn't this be res.is_ok()? + if res.is_err() && sw != SW_SUCCESS { + res = Err(ErrorKind::GenericError); } } } @@ -1106,7 +1084,7 @@ pub(crate) unsafe fn _general_authenticate( algorithm: u8, key: u8, decipher: bool, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut indata = [0u8; 1024]; let mut dataptr: *mut u8 = indata.as_mut_ptr(); @@ -1116,7 +1094,6 @@ pub(crate) unsafe fn _general_authenticate( let mut sw: i32 = 0; let bytes: usize; let mut len: usize = 0; - let res: ErrorKind; match algorithm { YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => { @@ -1127,7 +1104,7 @@ pub(crate) unsafe fn _general_authenticate( }; if in_len != key_len { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } else { _currentBlock = 16; } @@ -1140,10 +1117,10 @@ pub(crate) unsafe fn _general_authenticate( }; if (!decipher && (in_len > key_len)) || (decipher && (in_len != (key_len * 2) + 1)) { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } } - _ => return ErrorKind::AlgorithmError, + _ => return Err(ErrorKind::AlgorithmError), } if in_len < 0x80 { @@ -1168,7 +1145,7 @@ pub(crate) unsafe fn _general_authenticate( memcpy(dataptr as *mut c_void, sign_in as *const c_void, in_len); dataptr = dataptr.add(in_len); - res = ykpiv_transfer_data( + if let Err(e) = ykpiv_transfer_data( state, templ.as_ptr(), indata.as_mut_ptr(), @@ -1176,13 +1153,11 @@ pub(crate) unsafe fn _general_authenticate( data.as_mut_ptr(), &mut recv_len, &mut sw, - ); - - if res != ErrorKind::Ok { + ) { if state.verbose != 0 { eprintln!("Sign command failed to communicate."); } - return res; + return Err(e); } if sw != SW_SUCCESS { @@ -1191,9 +1166,9 @@ pub(crate) unsafe fn _general_authenticate( } if sw == SW_ERR_SECURITY_STATUS { - return ErrorKind::AuthenticationError; + return Err(ErrorKind::AuthenticationError); } else { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } } @@ -1202,7 +1177,7 @@ pub(crate) unsafe fn _general_authenticate( if state.verbose != 0 { eprintln!("Failed parsing signature reply."); } - return ErrorKind::ParseError; + return Err(ErrorKind::ParseError); } dataptr = data.as_mut_ptr().add(1); @@ -1214,7 +1189,7 @@ pub(crate) unsafe fn _general_authenticate( eprintln!("Failed parsing signature reply."); } - return ErrorKind::ParseError; + return Err(ErrorKind::ParseError); } dataptr = dataptr.add(1); @@ -1224,12 +1199,12 @@ pub(crate) unsafe fn _general_authenticate( if state.verbose != 0 { eprintln!("Wrong size on output buffer."); } - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } *out_len = len; memcpy(out as (*mut c_void), dataptr as (*const c_void), len); - ErrorKind::Ok + Ok(()) } /// Sign data using a PIV key @@ -1242,9 +1217,7 @@ pub unsafe fn ykpiv_sign_data( algorithm: u8, key: u8, ) -> Result<(), ErrorKind> { - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS @@ -1253,10 +1226,7 @@ pub unsafe fn ykpiv_sign_data( ); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Decrypt data using a PIV key @@ -1269,26 +1239,23 @@ pub unsafe fn ykpiv_decrypt_data( algorithm: u8, key: u8, ) -> Result<(), ErrorKind> { - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS let res = _general_authenticate(state, input, input_len, out, out_len, algorithm, key, true); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get the version of the PIV application installed on the YubiKey -pub(crate) unsafe fn _ykpiv_get_version(state: &mut YubiKey, p_version: *mut Version) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_get_version( + state: &mut YubiKey, + p_version: *mut Version, +) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let res: ErrorKind; // get version from state if already from device if state.ver.major != 0 || state.ver.minor != 0 || state.ver.patch != 0 { @@ -1302,25 +1269,21 @@ pub(crate) unsafe fn _ykpiv_get_version(state: &mut YubiKey, p_version: *mut Ver ); } - return ErrorKind::Ok; + return Ok(()); } // get version from device let mut apdu = APDU::default(); apdu.ins = YKPIV_INS_GET_VERSION; - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - - if res != ErrorKind::Ok { - return res; - } + _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw)?; if sw != SW_SUCCESS { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } if recv_len < 3 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } state.ver.major = data[0]; @@ -1337,7 +1300,7 @@ pub(crate) unsafe fn _ykpiv_get_version(state: &mut YubiKey, p_version: *mut Ver ); } - ErrorKind::Ok + Ok(()) } /// Get the YubiKey's PIV application version as a string @@ -1348,14 +1311,12 @@ pub unsafe fn ykpiv_get_version(state: &mut YubiKey) -> Result ErrorKind { +) -> Result<(), ErrorKind> { let mut _currentBlock; let mut res; let yk_applet: *const u8 = ptr::null(); @@ -1386,7 +1347,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( *p_serial = state.serial; } - return ErrorKind::Ok; + return Ok(()); } if state.ver.major < 5 { @@ -1407,12 +1368,9 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } return res; @@ -1423,7 +1381,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( eprintln!("Failed selecting yk application: {:04x}", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } recv_len = temp.len() as u32; @@ -1434,12 +1392,9 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } return res; @@ -1450,7 +1405,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( eprintln!("Failed retrieving serial number: {:04x}", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } recv_len = temp.len() as u32; @@ -1467,12 +1422,9 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } return res; } @@ -1481,7 +1433,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( if state.verbose != 0 { eprintln!("Failed selecting application: {:04x}", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } _currentBlock = 17; @@ -1492,19 +1444,16 @@ pub(crate) unsafe fn _ykpiv_get_serial( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } return res; } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed retrieving serial number: {:04x}", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } _currentBlock = 17; } @@ -1512,7 +1461,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( if _currentBlock == 17 { // check that we received enough data for the serial number if recv_len < 4 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } // TODO(tarcieri): replace pointers and casts with proper references! @@ -1536,21 +1485,16 @@ pub(crate) unsafe fn _ykpiv_get_serial( /// Get YubiKey device serial number pub unsafe fn ykpiv_get_serial(state: &mut YubiKey, p_serial: *mut u32) -> Result<(), ErrorKind> { - let mut res = ErrorKind::Ok; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_get_serial(state, p_serial, false); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Cache PIN in memory @@ -1585,7 +1529,11 @@ pub(crate) unsafe fn _cache_pin(state: &mut YubiKey, pin: *const c_char, len: us } /// Verify device PIN -pub unsafe fn ykpiv_verify(state: &mut YubiKey, pin: *const c_char, tries: *mut i32) -> ErrorKind { +pub unsafe fn ykpiv_verify( + state: &mut YubiKey, + pin: *const c_char, + tries: *mut i32, +) -> Result<(), ErrorKind> { ykpiv_verify_select( state, pin, @@ -1601,14 +1549,13 @@ pub(crate) unsafe fn _verify( pin: *const c_char, pin_len: usize, tries: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let res: ErrorKind; if pin_len > CB_PIN_MAX { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } let mut apdu = APDU::default(); @@ -1633,11 +1580,11 @@ pub(crate) unsafe fn _verify( } } - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); + let res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); apdu.zeroize(); - if res != ErrorKind::Ok { + if res.is_err() { return res; } @@ -1651,19 +1598,19 @@ pub(crate) unsafe fn _verify( if !tries.is_null() { *tries = sw & 0xf; } - ErrorKind::Ok + Ok(()) } else if sw >> 8 == 0x63 { if !tries.is_null() { *tries = sw & 0xf; } - ErrorKind::WrongPin + Err(ErrorKind::WrongPin) } else if sw == SW_ERR_AUTH_BLOCKED { if !tries.is_null() { *tries = 0; } - ErrorKind::WrongPin + Err(ErrorKind::WrongPin) } else { - ErrorKind::GenericError + Err(ErrorKind::GenericError) } } @@ -1674,18 +1621,16 @@ pub unsafe fn ykpiv_verify_select( pin_len: usize, tries: *mut i32, force_select: bool, -) -> ErrorKind { - let mut res = ErrorKind::Ok; +) -> Result<(), ErrorKind> { + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; - } + _ykpiv_begin_transaction(state)?; if force_select { res = _ykpiv_ensure_application_selected(state); } - if res == ErrorKind::Ok { + if res.is_ok() { res = _verify(state, pin, pin_len, tries); } @@ -1702,18 +1647,14 @@ pub unsafe fn ykpiv_get_pin_retries(state: &mut YubiKey, tries: *mut i32) -> Res // Force a re-select to unverify, because once verified the spec dictates that // subsequent verify calls will return a "verification not needed" instead of // the number of tries left... - let res = _ykpiv_select_application(state); - - if res != ErrorKind::Ok { - return Err(res); - } + _ykpiv_select_application(state)?; let ykrc = ykpiv_verify(state, ptr::null(), tries); // WRONG_PIN is expected on successful query. match ykrc { - ErrorKind::Ok | ErrorKind::WrongPin => Ok(()), - e => Err(e), + Ok(()) | Err(ErrorKind::WrongPin) => Ok(()), + e => e, } } @@ -1723,7 +1664,7 @@ pub unsafe fn ykpiv_set_pin_retries( pin_tries: i32, puk_tries: i32, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::Ok; + let mut res = Ok(()); let mut templ = [0, YKPIV_INS_SET_PIN_RETRIES, 0, 0]; let mut data = [0u8; 255]; let mut recv_len: usize = data.len(); @@ -1741,11 +1682,9 @@ pub unsafe fn ykpiv_set_pin_retries( templ[2] = pin_tries as (u8); templ[3] = puk_tries as (u8); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = ykpiv_transfer_data( state, templ.as_ptr(), @@ -1756,21 +1695,18 @@ pub unsafe fn ykpiv_set_pin_retries( &mut sw, ); - if res == ErrorKind::Ok { + if res.is_ok() { res = match sw { - SW_SUCCESS => ErrorKind::Ok, - SW_ERR_AUTH_BLOCKED => ErrorKind::AuthenticationError, - SW_ERR_SECURITY_STATUS => ErrorKind::AuthenticationError, - _ => ErrorKind::GenericError, + SW_SUCCESS => Ok(()), + SW_ERR_AUTH_BLOCKED => Err(ErrorKind::AuthenticationError), + SW_ERR_SECURITY_STATUS => Err(ErrorKind::AuthenticationError), + _ => Err(ErrorKind::GenericError), }; } } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Change the PIN @@ -1782,16 +1718,15 @@ pub(crate) unsafe fn _ykpiv_change_pin( new_pin: *const c_char, new_pin_len: usize, tries: *mut i32, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut sw: i32 = 0; let mut templ = [0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80]; let mut indata = [0u8; 16]; let mut data = [0u8; 255]; let mut recv_len: usize = data.len(); - let res: ErrorKind; if current_pin_len > 8 || new_pin_len > 8 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } if action == CHREF_ACT_UNBLOCK_PIN { @@ -1828,7 +1763,7 @@ pub(crate) unsafe fn _ykpiv_change_pin( ); } - res = ykpiv_transfer_data( + let res = ykpiv_transfer_data( state, templ.as_ptr(), indata.as_mut_ptr(), @@ -1840,7 +1775,7 @@ pub(crate) unsafe fn _ykpiv_change_pin( indata.zeroize(); - if res != ErrorKind::Ok { + if res.is_err() { return res; } @@ -1850,19 +1785,19 @@ pub(crate) unsafe fn _ykpiv_change_pin( *tries = sw & 0xf; } - return ErrorKind::WrongPin; + return Err(ErrorKind::WrongPin); } else if sw == SW_ERR_AUTH_BLOCKED { - return ErrorKind::PinLocked; + return Err(ErrorKind::PinLocked); } else { if state.verbose != 0 { eprintln!("Failed changing pin, token response code: {:x}.", sw); } - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } } - ErrorKind::Ok + Ok(()) } /// Change the Personal Identification Number (PIN). @@ -1876,13 +1811,11 @@ pub unsafe fn ykpiv_change_pin( new_pin_len: usize, tries: *mut i32, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::GenericError; + let mut res = Err(ErrorKind::GenericError); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_change_pin( state, 0, @@ -1893,7 +1826,7 @@ pub unsafe fn ykpiv_change_pin( tries, ); - if res == ErrorKind::Ok && !new_pin.is_null() { + if res.is_ok() && !new_pin.is_null() { // Intentionally ignore errors. If the PIN fails to save, it will only // be a problem if a reconnect is attempted. Failure deferred until then. _cache_pin(state, new_pin, new_pin_len); @@ -1901,10 +1834,7 @@ pub unsafe fn ykpiv_change_pin( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Change the PIN Unblocking Key (PUK). PUKs are codes for resetting @@ -1921,14 +1851,12 @@ pub unsafe fn ykpiv_change_puk( new_puk: *const c_char, new_puk_len: usize, tries: *mut i32, -) -> ErrorKind { - let mut res = ErrorKind::GenericError; +) -> Result<(), ErrorKind> { + let mut res = Err(ErrorKind::GenericError); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return ErrorKind::PcscError; - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_change_pin( state, 2, @@ -1954,21 +1882,16 @@ pub unsafe fn ykpiv_unblock_pin( new_pin_len: usize, tries: *mut i32, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::GenericError; + let mut res = Err(ErrorKind::GenericError); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_change_pin(state, 1, puk, puk_len, new_pin, new_pin_len, tries); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Fetch an object from the YubiKey @@ -1978,21 +1901,16 @@ pub unsafe fn ykpiv_fetch_object( data: *mut u8, len: *mut usize, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::Ok; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_fetch_object(state, object_id, data, len); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Fetch an object @@ -2001,20 +1919,19 @@ pub(crate) unsafe fn _ykpiv_fetch_object( object_id: i32, data: *mut u8, len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut sw: i32 = 0; let mut indata = [0u8; 5]; let mut inptr: *mut u8 = indata.as_mut_ptr(); let templ = [0, YKPIV_INS_GET_DATA, 0x3f, 0xff]; - let res: ErrorKind; inptr = set_object(object_id, inptr); if inptr.is_null() { - return ErrorKind::InvalidObject; + return Err(ErrorKind::InvalidObject); } - res = ykpiv_transfer_data( + ykpiv_transfer_data( state, templ.as_ptr(), indata.as_mut_ptr(), @@ -2022,26 +1939,22 @@ pub(crate) unsafe fn _ykpiv_fetch_object( data, len, &mut sw, - ); - - if res != ErrorKind::Ok { - return res; - } + )?; if sw != SW_SUCCESS { - return ErrorKind::GenericError; + return Err(ErrorKind::GenericError); } let mut outlen: usize = 0; if *len < 2 || !_ykpiv_has_valid_length(data.offset(1), (*len).wrapping_sub(1)) { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } let offs = _ykpiv_get_length(data.offset(1), &mut outlen); if offs == 0 { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } if outlen.wrapping_add(offs).wrapping_add(1) != *len { @@ -2052,7 +1965,7 @@ pub(crate) unsafe fn _ykpiv_fetch_object( ); } - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } memmove( @@ -2062,7 +1975,7 @@ pub(crate) unsafe fn _ykpiv_fetch_object( ); *len = outlen; - ErrorKind::Ok + Ok(()) } /// Save an object @@ -2072,21 +1985,16 @@ pub unsafe fn ykpiv_save_object( indata: *mut u8, len: usize, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::Ok; + let mut res = Ok(()); - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = _ykpiv_save_object(state, object_id, indata, len); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Save an object @@ -2095,22 +2003,21 @@ pub unsafe fn _ykpiv_save_object( object_id: i32, indata: *mut u8, len: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut dataptr: *mut u8 = data.as_mut_ptr(); let templ = [0, YKPIV_INS_PUT_DATA, 0x3f, 0xff]; let mut sw: i32 = 0; - let res: ErrorKind; let mut outlen: usize = 0usize; if len > CB_OBJ_MAX { - return ErrorKind::SizeError; + return Err(ErrorKind::SizeError); } dataptr = set_object(object_id, dataptr); if dataptr.is_null() { - return ErrorKind::InvalidObject; + return Err(ErrorKind::InvalidObject); } *{ let _old = dataptr; @@ -2122,7 +2029,7 @@ pub unsafe fn _ykpiv_save_object( memcpy(dataptr as (*mut c_void), indata as (*const c_void), len); dataptr = dataptr.add(len); - res = _ykpiv_transfer_data( + _ykpiv_transfer_data( state, templ.as_ptr(), data.as_mut_ptr(), @@ -2130,16 +2037,12 @@ pub unsafe fn _ykpiv_save_object( ptr::null_mut(), &mut outlen, &mut sw, - ); - - if res != ErrorKind::Ok { - return res; - } + )?; match sw { - SW_SUCCESS => ErrorKind::Ok, - SW_ERR_SECURITY_STATUS => ErrorKind::AuthenticationError, - _ => ErrorKind::GenericError, + SW_SUCCESS => Ok(()), + SW_ERR_SECURITY_STATUS => Err(ErrorKind::AuthenticationError), + _ => Err(ErrorKind::GenericError), } } @@ -2193,7 +2096,6 @@ pub unsafe fn ykpiv_import_private_key( let mut lens = [0usize; 5]; let n_params: u8; let param_tag: i32; - let mut res = ErrorKind::Ok; if key == YKPIV_KEY_CARDMGM || key < YKPIV_KEY_RETIRED1 @@ -2309,9 +2211,10 @@ pub unsafe fn ykpiv_import_private_key( in_ptr = in_ptr.add(3); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } else if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + _ykpiv_begin_transaction(state)?; + + let mut res = Ok(()); + if _ykpiv_ensure_application_selected(state).is_ok() { res = ykpiv_transfer_data( state, templ.as_ptr(), @@ -2322,20 +2225,17 @@ pub unsafe fn ykpiv_import_private_key( &mut sw, ); - if res == ErrorKind::Ok && sw != SW_SUCCESS { - res = ErrorKind::GenericError; + if res.is_ok() && sw != SW_SUCCESS { + res = Err(ErrorKind::GenericError); if sw == SW_ERR_SECURITY_STATUS { - res = ErrorKind::AuthenticationError; + res = Err(ErrorKind::AuthenticationError); } } } key_data.zeroize(); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Generate an attestation certificate for a stored key @@ -2345,7 +2245,7 @@ pub unsafe fn ykpiv_attest( data: *mut u8, data_len: *mut usize, ) -> Result<(), ErrorKind> { - let mut res = ErrorKind::GenericError; + let mut res = Err(ErrorKind::GenericError); let templ = [0, YKPIV_INS_ATTEST, key, 0]; let mut sw: i32 = 0; let mut ul_data_len: usize; @@ -2356,11 +2256,9 @@ pub unsafe fn ykpiv_attest( ul_data_len = *data_len; - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { res = ykpiv_transfer_data( state, templ.as_ptr(), @@ -2371,14 +2269,14 @@ pub unsafe fn ykpiv_attest( &mut sw, ); - if res == ErrorKind::Ok { + if res.is_ok() { if sw != SW_SUCCESS { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); if sw == SW_ERR_NOT_SUPPORTED { - res = ErrorKind::NotSupported; + res = Err(ErrorKind::NotSupported); } } else if *data as i32 != 0x30 { - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } else { *data_len = ul_data_len; } @@ -2386,10 +2284,7 @@ pub unsafe fn ykpiv_attest( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Get an auth challenge @@ -2401,7 +2296,7 @@ pub unsafe fn ykpiv_auth_getchallenge( let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let mut res = ErrorKind::Ok; + let mut res = Ok(()); if challenge.is_null() { return Err(ErrorKind::GenericError); @@ -2411,11 +2306,9 @@ pub unsafe fn ykpiv_auth_getchallenge( return Err(ErrorKind::SizeError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; - if _ykpiv_ensure_application_selected(state) == ErrorKind::Ok { + if _ykpiv_ensure_application_selected(state).is_ok() { let mut apdu = APDU::default(); apdu.ins = YKPIV_INS_AUTHENTICATE; apdu.p1 = YKPIV_ALGO_3DES; // triple des @@ -2427,9 +2320,9 @@ pub unsafe fn ykpiv_auth_getchallenge( res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if res.is_err() { if sw != SW_SUCCESS { - res = ErrorKind::AuthenticationError; + res = Err(ErrorKind::AuthenticationError); } else { memcpy( challenge as (*mut c_void), @@ -2441,10 +2334,7 @@ pub unsafe fn ykpiv_auth_getchallenge( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Verify an auth response @@ -2456,7 +2346,6 @@ pub unsafe fn ykpiv_auth_verifyresponse( let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let mut res: ErrorKind; if response.is_null() { return Err(ErrorKind::GenericError); @@ -2466,9 +2355,7 @@ pub unsafe fn ykpiv_auth_verifyresponse( return Err(ErrorKind::SizeError); } - if _ykpiv_begin_transaction(state) != ErrorKind::Ok { - return Err(ErrorKind::PcscError); - } + _ykpiv_begin_transaction(state)?; // send the response to the card and a challenge of our own. let mut apdu = APDU::default(); @@ -2488,18 +2375,15 @@ pub unsafe fn ykpiv_auth_verifyresponse( apdu.lc = 12; - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); + let mut res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res == ErrorKind::Ok && sw != SW_SUCCESS { - res = ErrorKind::AuthenticationError; + if res.is_ok() && sw != SW_SUCCESS { + res = Err(ErrorKind::AuthenticationError); } apdu.zeroize(); _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// MGMT Application ID(?) @@ -2510,13 +2394,8 @@ pub unsafe fn ykpiv_auth_deauthenticate(state: &mut YubiKey) -> Result<(), Error let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let mut res: ErrorKind; - res = _ykpiv_begin_transaction(state); - - if res != ErrorKind::Ok { - return Err(res); - } + _ykpiv_begin_transaction(state)?; let mut apdu = APDU::default(); apdu.ins = YKPIV_INS_SELECT_APPLICATION; @@ -2529,25 +2408,19 @@ pub unsafe fn ykpiv_auth_deauthenticate(state: &mut YubiKey) -> Result<(), Error MGMT_AID.len(), ); - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); + let mut res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - if res != ErrorKind::Ok { + if let Err(e) = res.as_ref() { if state.verbose != 0 { - eprintln!( - "Failed communicating with card: \'{}\'", - ykpiv_strerror(res) - ); + eprintln!("Failed communicating with card: \'{}\'", e); } } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed selecting mgmt application: {:04x}", sw); } - res = ErrorKind::GenericError; + res = Err(ErrorKind::GenericError); } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } From 7add9bfa41bd8ea7d8823ecab72a5074411fc835 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:16:44 +0000 Subject: [PATCH 04/17] Convert remaining APIs to Result<(), ErrorKind> --- src/util.rs | 45 +++++++++++++++++------------------------ src/yubikey.rs | 55 +++++++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/util.rs b/src/util.rs index b2b4612..e77bc06 100644 --- a/src/util.rs +++ b/src/util.rs @@ -311,7 +311,7 @@ pub unsafe fn ykpiv_util_list_keys( data_len: *mut usize, ) -> Result<(), ErrorKind> { let mut _currentBlock; - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut p_key: *mut YkPivKey; let mut p_data: *mut u8 = ptr::null_mut(); let mut p_temp: *mut u8; @@ -353,7 +353,7 @@ pub unsafe fn ykpiv_util_list_keys( cb_buf = buf.len(); res = _read_certificate(state, SLOTS[i], buf.as_mut_ptr(), &mut cb_buf); - if res == ErrorKind::Ok && (cb_buf > 0) { + if res.is_ok() && (cb_buf > 0) { cb_realloc = if mem::size_of::() .wrapping_add(cb_buf) .wrapping_sub(1) @@ -419,9 +419,9 @@ pub unsafe fn ykpiv_util_list_keys( if !data_len.is_null() { *data_len = offset; } - res = ErrorKind::Ok; + res = Ok(()); } else { - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } } @@ -430,10 +430,7 @@ pub unsafe fn ykpiv_util_list_keys( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Read certificate @@ -443,7 +440,7 @@ pub unsafe fn ykpiv_util_read_cert( data: *mut *mut u8, data_len: *mut usize, ) -> Result<(), ErrorKind> { - let mut res: ErrorKind = ErrorKind::Ok; + let mut res = Ok(()); let mut buf = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_buf: usize = buf.len(); @@ -457,7 +454,7 @@ pub unsafe fn ykpiv_util_read_cert( *data = ptr::null_mut(); *data_len = 0; res = _read_certificate(state, slot, buf.as_mut_ptr(), &mut cb_buf); - if res == ErrorKind::Ok { + if res.is_ok() { if cb_buf == 0 { *data = ptr::null_mut(); *data_len = 0; @@ -467,7 +464,7 @@ pub unsafe fn ykpiv_util_read_cert( } .is_null() { - res = ErrorKind::MemoryError; + res = Err(ErrorKind::MemoryError); } else { memcpy( *data as (*mut c_void), @@ -480,10 +477,7 @@ pub unsafe fn ykpiv_util_read_cert( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Write certificate @@ -1404,7 +1398,7 @@ pub unsafe fn ykpiv_util_get_config( let mut cb_data: usize = mem::size_of::<[u8; YKPIV_OBJ_MAX_SIZE]>(); let mut p_item: *mut u8 = ptr::null_mut(); let mut cb_item: usize = 0; - let res = ErrorKind::Ok; + let mut res = Ok(()); if config.is_null() { return Err(ErrorKind::GenericError); @@ -1485,7 +1479,7 @@ pub unsafe fn ykpiv_util_get_config( if _read_metadata(state, 0x88u8, data.as_mut_ptr(), &mut cb_data).is_ok() { (*config).protected_data_available = 1u8; - let res = _get_metadata_item( + res = _get_metadata_item( data.as_mut_ptr(), cb_data, 0x81u8, @@ -1497,7 +1491,7 @@ pub unsafe fn ykpiv_util_get_config( (*config).puk_noblock_on_upgrade = 1u8; } - let res = _get_metadata_item( + res = _get_metadata_item( data.as_mut_ptr(), cb_data, 0x89u8, @@ -1519,10 +1513,7 @@ pub unsafe fn ykpiv_util_get_config( } _ykpiv_end_transaction(state); - match res { - ErrorKind::Ok => Ok(()), - e => Err(e), - } + res } /// Set PIN last changed @@ -1973,13 +1964,13 @@ unsafe fn _read_certificate( slot: u8, buf: *mut u8, buf_len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut ptr: *mut u8; let object_id = ykpiv_util_slot_object(slot) as i32; let mut len: usize = 0; if object_id == -1 { - return ErrorKind::InvalidObject; + return Err(ErrorKind::InvalidObject); } if _ykpiv_fetch_object(state, object_id, buf, buf_len).is_ok() { @@ -1987,7 +1978,7 @@ unsafe fn _read_certificate( if *buf_len < CB_OBJ_TAG_MIN { *buf_len = 0; - return ErrorKind::Ok; + return Ok(()); } else if *{ let _old = ptr; ptr = ptr.offset(1); @@ -1998,7 +1989,7 @@ unsafe fn _read_certificate( if len > *buf_len - (ptr as isize - buf as isize) as usize { *buf_len = 0; - return ErrorKind::Ok; + return Ok(()); } else { memmove(buf as (*mut c_void), ptr as (*const c_void), len); *buf_len = len; @@ -2008,7 +1999,7 @@ unsafe fn _read_certificate( *buf_len = 0; } - ErrorKind::Ok + Ok(()) } /// Write certificate diff --git a/src/yubikey.rs b/src/yubikey.rs index 3ecd546..8bb07a4 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -195,28 +195,28 @@ pub fn ykpiv_init(verbose: i32) -> YubiKey { } /// Cleanup YubiKey session -pub(crate) unsafe fn _ykpiv_done(state: &mut YubiKey, disconnect: bool) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_done(state: &mut YubiKey, disconnect: bool) -> Result<(), ErrorKind> { if disconnect { ykpiv_disconnect(state); } _cache_pin(state, ptr::null(), 0); - ErrorKind::Ok + Ok(()) } /// Cleanup YubiKey session with external card upon completion // TODO(tarcieri): make this a `Drop` handler -pub unsafe fn ykpiv_done_with_external_card(state: &mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_done_with_external_card(state: &mut YubiKey) -> Result<(), ErrorKind> { _ykpiv_done(state, false) } /// Cleanup YubiKey session upon completion -pub unsafe fn ykpiv_done(state: &mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_done(state: &mut YubiKey) -> Result<(), ErrorKind> { _ykpiv_done(state, true) } /// Disconnect a YubiKey session -pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> ErrorKind { +pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { if state.card != 0 { SCardDisconnect(state.card, 0x1); state.card = 0i32; @@ -227,7 +227,7 @@ pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> ErrorKind { state.context = -1i32; } - ErrorKind::Ok + Ok(()) } /// Select application @@ -320,10 +320,14 @@ pub(crate) unsafe fn _ykpiv_ensure_application_selected( } /// Connect to the YubiKey -pub(crate) unsafe fn _ykpiv_connect(state: &mut YubiKey, context: usize, card: usize) -> ErrorKind { +pub(crate) unsafe fn _ykpiv_connect( + state: &mut YubiKey, + context: usize, + card: usize, +) -> Result<(), ErrorKind> { // if the context has changed, and the new context is not valid, return an error if context != state.context as (usize) && (0x0i32 != SCardIsValidContext(context as (i32))) { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } // if card handle has changed, determine if handle is valid (less efficient, but complete) @@ -345,7 +349,7 @@ pub(crate) unsafe fn _ykpiv_connect(state: &mut YubiKey, context: usize, card: u &mut atr_len, ) != 0 { - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } state.is_neo = (atr_len as usize == YKPIV_ATR_NEO_R3.len() - 1) @@ -367,7 +371,7 @@ pub(crate) unsafe fn _ykpiv_connect(state: &mut YubiKey, context: usize, card: u // The applet _is_ selected by ykpiv_connect(), but is not selected when bypassing // it with ykpiv_connect_with_external_card(). - ErrorKind::Ok + Ok(()) } /// Connect to an external card @@ -375,7 +379,7 @@ pub unsafe fn ykpiv_connect_with_external_card( state: &mut YubiKey, context: usize, card: usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { _ykpiv_connect(state, context, card) } @@ -389,11 +393,8 @@ pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Resul let mut reader_ptr: *mut c_char; let mut card: i32 = -1i32; - let ret: ErrorKind = ykpiv_list_readers(state, reader_buf.as_mut_ptr(), &mut num_readers); + ykpiv_list_readers(state, reader_buf.as_mut_ptr(), &mut num_readers)?; - if ret != ErrorKind::Ok { - return Err(ret); - } reader_ptr = reader_buf.as_mut_ptr(); loop { if *reader_ptr == b'\0' as c_char { @@ -465,7 +466,7 @@ pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Resul // at this point, card should not equal state->card, // to allow _ykpiv_connect() to determine device type let res = _ykpiv_connect(state, state.context as (usize), card as (usize)); - if res != ErrorKind::Ok { + if res.is_err() { _currentBlock = 19; break; } @@ -504,7 +505,7 @@ pub unsafe fn ykpiv_list_readers( state: &mut YubiKey, readers: *mut c_char, len: *mut usize, -) -> ErrorKind { +) -> Result<(), ErrorKind> { let mut num_readers: u32 = 0u32; let mut rc: i32; @@ -515,7 +516,7 @@ pub unsafe fn ykpiv_list_readers( if state.verbose != 0 { eprintln!("error: SCardEstablishContext failed, rc={}", rc); } - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } } @@ -532,7 +533,7 @@ pub unsafe fn ykpiv_list_readers( } SCardReleaseContext(state.context); state.context = -1i32; - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } if num_readers as (usize) > *len { @@ -550,11 +551,11 @@ pub unsafe fn ykpiv_list_readers( SCardReleaseContext(state.context); state.context = -1i32; - return ErrorKind::PcscError; + return Err(ErrorKind::PcscError); } *len = num_readers as usize; - ErrorKind::Ok + Ok(()) } /// Reconnect to a YubiKey @@ -1499,9 +1500,13 @@ pub unsafe fn ykpiv_get_serial(state: &mut YubiKey, p_serial: *mut u32) -> Resul /// Cache PIN in memory // TODO(tarcieri): better security around the cached PIN -pub(crate) unsafe fn _cache_pin(state: &mut YubiKey, pin: *const c_char, len: usize) -> ErrorKind { +pub(crate) unsafe fn _cache_pin( + state: &mut YubiKey, + pin: *const c_char, + len: usize, +) -> Result<(), ErrorKind> { if !pin.is_null() && (state.pin as *const c_char == pin) { - return ErrorKind::Ok; + return Ok(()); } if !state.pin.is_null() { @@ -1518,14 +1523,14 @@ pub(crate) unsafe fn _cache_pin(state: &mut YubiKey, pin: *const c_char, len: us state.pin = malloc(len + 1) as (*mut u8); if state.pin.is_null() { - return ErrorKind::MemoryError; + return Err(ErrorKind::MemoryError); } memcpy(state.pin as (*mut c_void), pin as (*const c_void), len); *state.pin.add(len) = 0u8; } - ErrorKind::Ok + Ok(()) } /// Verify device PIN From 4e710da32c45ee833b39061809a7260c8619e55f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:17:17 +0000 Subject: [PATCH 05/17] Remove ErrorKind::Ok --- src/error.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/error.rs b/src/error.rs index b867c98..9e23a0b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -35,10 +35,6 @@ use std::fmt; /// Kinds of errors #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ErrorKind { - /// OK - // TODO(tarcieri): replace this with proper result types - Ok, - /// Memory error MemoryError, @@ -95,7 +91,6 @@ impl ErrorKind { /// assist in web searches for relevant information for these errors. pub fn name(self) -> &'static str { match self { - ErrorKind::Ok => "YKPIV_OK", ErrorKind::MemoryError => "YKPIV_MEMORY_ERROR", ErrorKind::PcscError => "YKPIV_PCSC_ERROR", ErrorKind::SizeError => "YKPIV_SIZE_ERROR", @@ -118,7 +113,6 @@ impl ErrorKind { /// Error message pub fn msg(self) -> &'static str { match self { - ErrorKind::Ok => "OK", ErrorKind::MemoryError => "memory error", ErrorKind::PcscError => "PCSC error", ErrorKind::SizeError => "size error", From c394511c60569e1667defdb9ea919510e2e43d52 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:31:23 +0000 Subject: [PATCH 06/17] Convert APDU pointer into mutable reference --- src/yubikey.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 8bb07a4..37e1e6f 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -805,24 +805,24 @@ pub(crate) unsafe fn dump_hex(buf: *const u8, len: u32) { /// Send data pub(crate) unsafe fn _send_data( state: &mut YubiKey, - apdu: *mut APDU, + apdu: &mut APDU, data: *mut u8, recv_len: *mut u32, sw: *mut i32, ) -> Result<(), ErrorKind> { - let send_len = (*apdu).lc as u32 + 5; + let send_len = apdu.lc as u32 + 5; let mut tmp_len = *recv_len; if state.verbose > 1 { eprint!("> "); - dump_hex((*apdu).as_ptr() as *const u8, send_len); + dump_hex(apdu.as_ptr() as *const u8, send_len); eprintln!(); } let rc = SCardTransmit( state.card, SCARD_PCI_T1, - (*apdu).as_mut_ptr() as *mut i8, + apdu.as_mut_ptr() as *mut i8, send_len, ptr::null(), data, From 90bdda85cb878b9fc2c704344e11962ef42f27d2 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:39:58 +0000 Subject: [PATCH 07/17] fn _ykpiv_get_serial() -> Result --- src/yubikey.rs | 96 +++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 64 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 37e1e6f..497af4c 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -275,9 +275,7 @@ pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> Result<() } } - res = _ykpiv_get_serial(state, ptr::null_mut(), false); - - if let Err(e) = res.as_ref() { + if let Err(e) = _ykpiv_get_serial(state, false) { if state.verbose != 0 { eprintln!("Failed to retrieve serial number: \'{}\'", e); } @@ -1332,11 +1330,8 @@ pub unsafe fn ykpiv_get_version(state: &mut YubiKey) -> Result Result<(), ErrorKind> { - let mut _currentBlock; - let mut res; +) -> Result { let yk_applet: *const u8 = ptr::null(); let mut data = [0u8; 255]; let mut recv_len = data.len() as u32; @@ -1344,11 +1339,7 @@ pub(crate) unsafe fn _ykpiv_get_serial( let p_temp: *mut u8; if !f_force && state.serial != 0 { - if !p_serial.is_null() { - *p_serial = state.serial; - } - - return Ok(()); + return Ok(state.serial); } if state.ver.major < 5 { @@ -1367,17 +1358,13 @@ pub(crate) unsafe fn _ykpiv_get_serial( mem::size_of_val(&yk_applet), ); - res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); - - if let Err(e) = res.as_ref() { + if let Err(e) = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw) { if state.verbose != 0 { eprintln!("Failed communicating with card: \'{}\'", e); } - return res; - } - - if sw != SW_SUCCESS { + return Err(e); + } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed selecting yk application: {:04x}", sw); } @@ -1391,17 +1378,13 @@ pub(crate) unsafe fn _ykpiv_get_serial( apdu.p1 = 0x10; apdu.lc = 0x00; - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - - if let Err(e) = res.as_ref() { + if let Err(e) = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw) { if state.verbose != 0 { eprintln!("Failed communicating with card: \'{}\'", e); } - return res; - } - - if sw != SW_SUCCESS { + return Err(e); + } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed retrieving serial number: {:04x}", sw); } @@ -1421,77 +1404,62 @@ pub(crate) unsafe fn _ykpiv_get_serial( mem::size_of_val(&AID), ); - res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw); - - if let Err(e) = res.as_ref() { + if let Err(e) = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw) { if state.verbose != 0 { eprintln!("Failed communicating with card: \'{}\'", e); } - return res; - } - - if sw != SW_SUCCESS { + return Err(e); + } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed selecting application: {:04x}", sw); } return Err(ErrorKind::GenericError); } - - _currentBlock = 17; } else { // get serial from yk5 and later devices using the f8 command let mut apdu = APDU::default(); apdu.ins = YKPIV_INS_GET_SERIAL; - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - - if let Err(e) = res.as_ref() { + if let Err(e) = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw) { if state.verbose != 0 { eprintln!("Failed communicating with card: \'{}\'", e); } - return res; + return Err(e); } else if sw != SW_SUCCESS { if state.verbose != 0 { eprintln!("Failed retrieving serial number: {:04x}", sw); } return Err(ErrorKind::GenericError); } - _currentBlock = 17; } - if _currentBlock == 17 { - // check that we received enough data for the serial number - if recv_len < 4 { - return Err(ErrorKind::SizeError); - } - - // TODO(tarcieri): replace pointers and casts with proper references! - #[allow(trivial_casts)] - { - p_temp = &mut state.serial as (*mut u32) as (*mut u8); - } - - *p_temp = data[3]; - *p_temp.add(1) = data[2]; - *p_temp.add(2) = data[1]; - *p_temp.add(3) = data[0]; - - if !p_serial.is_null() { - *p_serial = state.serial; - } + // check that we received enough data for the serial number + if recv_len < 4 { + return Err(ErrorKind::SizeError); } - res + // TODO(tarcieri): replace pointers and casts with proper references! + #[allow(trivial_casts)] + { + p_temp = &mut state.serial as (*mut u32) as (*mut u8); + } + + *p_temp = data[3]; + *p_temp.add(1) = data[2]; + *p_temp.add(2) = data[1]; + *p_temp.add(3) = data[0]; + + Ok(state.serial) } /// Get YubiKey device serial number -pub unsafe fn ykpiv_get_serial(state: &mut YubiKey, p_serial: *mut u32) -> Result<(), ErrorKind> { - let mut res = Ok(()); +pub unsafe fn ykpiv_get_serial(state: &mut YubiKey) -> Result { + let mut res = Err(ErrorKind::GenericError); _ykpiv_begin_transaction(state)?; if _ykpiv_ensure_application_selected(state).is_ok() { - res = _ykpiv_get_serial(state, p_serial, false); + res = _ykpiv_get_serial(state, false); } _ykpiv_end_transaction(state); From 31ef465571a18ed6ffa51ceaa7475edaa102b5aa Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 11:44:13 +0000 Subject: [PATCH 08/17] fn _ykpiv_get_version() -> Result --- src/yubikey.rs | 47 +++++++---------------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 497af4c..42ccc2d 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -268,8 +268,7 @@ pub(crate) unsafe fn _ykpiv_select_application(state: &mut YubiKey) -> Result<() // can determine how to get the serial number, which for the NEO/Yk4 // will result in another selection of the PIV applet. - res = _ykpiv_get_version(state, ptr::null_mut()); - if let Err(e) = res.as_ref() { + if let Err(e) = _ykpiv_get_version(state) { if state.verbose != 0 { eprintln!("Failed to retrieve version: \'{}\'", e); } @@ -1248,27 +1247,14 @@ pub unsafe fn ykpiv_decrypt_data( } /// Get the version of the PIV application installed on the YubiKey -pub(crate) unsafe fn _ykpiv_get_version( - state: &mut YubiKey, - p_version: *mut Version, -) -> Result<(), ErrorKind> { +pub(crate) unsafe fn _ykpiv_get_version(state: &mut YubiKey) -> Result { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; // get version from state if already from device if state.ver.major != 0 || state.ver.minor != 0 || state.ver.patch != 0 { - if !p_version.is_null() { - // TODO(tarcieri): use real references instead of pointers and memcpy!!! - #[allow(trivial_casts)] - memcpy( - p_version as *mut c_void, - &state.ver as *const Version as *const c_void, - mem::size_of::(), - ); - } - - return Ok(()); + return Ok(state.ver); } // get version from device @@ -1289,40 +1275,21 @@ pub(crate) unsafe fn _ykpiv_get_version( state.ver.minor = data[1]; state.ver.patch = data[2]; - if !p_version.is_null() { - // TODO(tarcieri): use real references instead of pointers and memcpy!!! - #[allow(trivial_casts)] - memcpy( - p_version as *mut c_void, - &state.ver as (*const Version) as (*const c_void), - mem::size_of::(), - ); - } - - Ok(()) + Ok(state.ver) } /// Get the YubiKey's PIV application version as a string pub unsafe fn ykpiv_get_version(state: &mut YubiKey) -> Result { - let mut ver: Version = Version { - major: 0u8, - minor: 0u8, - patch: 0u8, - }; + let mut res = Err(ErrorKind::GenericError); _ykpiv_begin_transaction(state)?; if _ykpiv_ensure_application_selected(state).is_ok() { - let res = _ykpiv_get_version(state, &mut ver); - - if res.is_ok() { - _ykpiv_end_transaction(state); - return Ok(format!("{}.{}.{}", ver.major, ver.minor, ver.patch)); - } + res = _ykpiv_get_version(state); } _ykpiv_end_transaction(state); - Err(ErrorKind::GenericError) + res.map(|ver| format!("{}.{}.{}", ver.major, ver.minor, ver.patch)) } /// Get YubiKey device serial number From b750b9cbbb17c6dd6596c34880f9a855a793b09d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:06:49 +0000 Subject: [PATCH 09/17] Convert tries pointers into Result elements --- src/error.rs | 6 ++-- src/util.rs | 37 +++++++++++--------- src/yubikey.rs | 93 +++++++++++++++----------------------------------- 3 files changed, 52 insertions(+), 84 deletions(-) diff --git a/src/error.rs b/src/error.rs index 9e23a0b..e55178c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -63,7 +63,7 @@ pub enum ErrorKind { ParseError, /// Wrong PIN - WrongPin, + WrongPin { tries: i32 }, /// Invalid object InvalidObject, @@ -100,7 +100,7 @@ impl ErrorKind { ErrorKind::GenericError => "YKPIV_GENERIC_ERROR", ErrorKind::KeyError => "YKPIV_KEY_ERROR", ErrorKind::ParseError => "YKPIV_PARSE_ERROR", - ErrorKind::WrongPin => "YKPIV_WRONG_PIN", + ErrorKind::WrongPin { .. } => "YKPIV_WRONG_PIN", ErrorKind::InvalidObject => "YKPIV_INVALID_OBJECT", ErrorKind::AlgorithmError => "YKPIV_ALGORITHM_ERROR", ErrorKind::PinLocked => "YKPIV_PIN_LOCKED", @@ -122,7 +122,7 @@ impl ErrorKind { ErrorKind::GenericError => "generic error", ErrorKind::KeyError => "key error", ErrorKind::ParseError => "parse error", - ErrorKind::WrongPin => "wrong pin", + ErrorKind::WrongPin { .. } => "wrong pin", ErrorKind::InvalidObject => "invalid object", ErrorKind::AlgorithmError => "algorithm error", ErrorKind::PinLocked => "PIN locked", diff --git a/src/util.rs b/src/util.rs index e77bc06..f7bb6e9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -510,7 +510,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> let mut _currentBlock; let mut res = Ok(()); let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44]; - let mut tries: i32 = -1; + let mut tries_remaining: i32 = -1; let mut data = [0u8; YKPIV_OBJ_MAX_SIZE]; let mut cb_data: usize = data.len(); let mut p_item: *mut u8 = ptr::null_mut(); @@ -527,29 +527,34 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> loop { if _currentBlock == 3 { - if tries != 0 { - res = ykpiv_change_puk( + if tries_remaining != 0 { + match ykpiv_change_puk( state, puk.as_ptr(), mem::size_of::<*const c_char>(), puk.as_ptr(), mem::size_of::<*const c_char>(), - &mut tries, - ); - - if res.is_ok() { - let _rhs = 1; - let mut _lhs = &mut puk[0]; - *_lhs += _rhs; - _currentBlock = 3; - } else { - if res != Err(ErrorKind::PinLocked) { + ) { + Ok(()) => { + let _rhs = 1; + let mut _lhs = &mut puk[0]; + *_lhs += _rhs; + _currentBlock = 3; + } + Err(ErrorKind::WrongPin { tries }) => { + tries_remaining = tries; _currentBlock = 3; continue; } - tries = 0; - res = Ok(()); - _currentBlock = 3; + Err(e) => { + if res != Err(ErrorKind::PinLocked) { + _currentBlock = 3; + continue; + } + tries_remaining = 0; + res = Ok(()); + _currentBlock = 3; + } } } else { let res = _read_metadata(state, TAG_ADMIN, data.as_mut_ptr(), &mut cb_data); diff --git a/src/yubikey.rs b/src/yubikey.rs index 42ccc2d..95c404a 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -558,7 +558,6 @@ pub unsafe fn ykpiv_list_readers( /// Reconnect to a YubiKey pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { let mut active_protocol: u32 = 0; - let mut tries: i32 = 0; if state.verbose != 0 { eprintln!("trying to reconnect to current reader."); @@ -576,7 +575,7 @@ pub(crate) unsafe fn reconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { _ykpiv_select_application(state)?; if !state.pin.is_null() { - ykpiv_verify(state, state.pin as *const c_char, &mut tries) + ykpiv_verify(state, state.pin as *const c_char).map(|_| ()) } else { Ok(()) } @@ -1469,27 +1468,25 @@ pub(crate) unsafe fn _cache_pin( } /// Verify device PIN -pub unsafe fn ykpiv_verify( - state: &mut YubiKey, - pin: *const c_char, - tries: *mut i32, -) -> Result<(), ErrorKind> { +/// +/// Returns the number of tries remaining both on success and on a wrong PIN. +pub unsafe fn ykpiv_verify(state: &mut YubiKey, pin: *const c_char) -> Result { ykpiv_verify_select( state, pin, if !pin.is_null() { strlen(pin) } else { 0 }, - tries, false, ) } /// Verify device PIN +/// +/// Returns the number of tries remaining both on success and on a wrong PIN. pub(crate) unsafe fn _verify( state: &mut YubiKey, pin: *const c_char, pin_len: usize, - tries: *mut i32, -) -> Result<(), ErrorKind> { +) -> Result { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; @@ -1524,8 +1521,8 @@ pub(crate) unsafe fn _verify( apdu.zeroize(); - if res.is_err() { - return res; + if let Err(e) = res { + return Err(e); } if sw == SW_SUCCESS { @@ -1535,43 +1532,37 @@ pub(crate) unsafe fn _verify( _cache_pin(state, pin, pin_len); } - if !tries.is_null() { - *tries = sw & 0xf; - } - Ok(()) + Ok(sw & 0xf) } else if sw >> 8 == 0x63 { - if !tries.is_null() { - *tries = sw & 0xf; - } - Err(ErrorKind::WrongPin) + Err(ErrorKind::WrongPin { tries: sw & 0xf }) } else if sw == SW_ERR_AUTH_BLOCKED { - if !tries.is_null() { - *tries = 0; - } - Err(ErrorKind::WrongPin) + Err(ErrorKind::WrongPin { tries: 0 }) } else { Err(ErrorKind::GenericError) } } /// Verify and select application +/// +/// Returns the number of tries remaining both on success and on a wrong PIN. pub unsafe fn ykpiv_verify_select( state: &mut YubiKey, pin: *const c_char, pin_len: usize, - tries: *mut i32, force_select: bool, -) -> Result<(), ErrorKind> { - let mut res = Ok(()); +) -> Result { + let mut res = Ok(-1); _ykpiv_begin_transaction(state)?; if force_select { - res = _ykpiv_ensure_application_selected(state); + if let Err(e) = _ykpiv_ensure_application_selected(state) { + res = Err(e); + } } if res.is_ok() { - res = _verify(state, pin, pin_len, tries); + res = _verify(state, pin, pin_len); } _ykpiv_end_transaction(state); @@ -1579,22 +1570,18 @@ pub unsafe fn ykpiv_verify_select( } /// Get the number of PIN retries -pub unsafe fn ykpiv_get_pin_retries(state: &mut YubiKey, tries: *mut i32) -> Result<(), ErrorKind> { - if tries.is_null() { - return Err(ErrorKind::ArgumentError); - } - +pub unsafe fn ykpiv_get_pin_retries(state: &mut YubiKey) -> Result { // Force a re-select to unverify, because once verified the spec dictates that // subsequent verify calls will return a "verification not needed" instead of // the number of tries left... _ykpiv_select_application(state)?; - let ykrc = ykpiv_verify(state, ptr::null(), tries); + let ykrc = ykpiv_verify(state, ptr::null()); // WRONG_PIN is expected on successful query. match ykrc { - Ok(()) | Err(ErrorKind::WrongPin) => Ok(()), - e => e, + Ok(tries) | Err(ErrorKind::WrongPin { tries }) => Ok(tries), + Err(e) => Err(e), } } @@ -1657,7 +1644,6 @@ pub(crate) unsafe fn _ykpiv_change_pin( current_pin_len: usize, new_pin: *const c_char, new_pin_len: usize, - tries: *mut i32, ) -> Result<(), ErrorKind> { let mut sw: i32 = 0; let mut templ = [0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80]; @@ -1721,11 +1707,7 @@ pub(crate) unsafe fn _ykpiv_change_pin( if sw != SW_SUCCESS { if sw >> 8 == 0x63 { - if !tries.is_null() { - *tries = sw & 0xf; - } - - return Err(ErrorKind::WrongPin); + return Err(ErrorKind::WrongPin { tries: sw & 0xf }); } else if sw == SW_ERR_AUTH_BLOCKED { return Err(ErrorKind::PinLocked); } else { @@ -1749,22 +1731,13 @@ pub unsafe fn ykpiv_change_pin( current_pin_len: usize, new_pin: *const c_char, new_pin_len: usize, - tries: *mut i32, ) -> Result<(), ErrorKind> { let mut res = Err(ErrorKind::GenericError); _ykpiv_begin_transaction(state)?; if _ykpiv_ensure_application_selected(state).is_ok() { - res = _ykpiv_change_pin( - state, - 0, - current_pin, - current_pin_len, - new_pin, - new_pin_len, - tries, - ); + res = _ykpiv_change_pin(state, 0, current_pin, current_pin_len, new_pin, new_pin_len); if res.is_ok() && !new_pin.is_null() { // Intentionally ignore errors. If the PIN fails to save, it will only @@ -1790,22 +1763,13 @@ pub unsafe fn ykpiv_change_puk( current_puk_len: usize, new_puk: *const c_char, new_puk_len: usize, - tries: *mut i32, ) -> Result<(), ErrorKind> { let mut res = Err(ErrorKind::GenericError); _ykpiv_begin_transaction(state)?; if _ykpiv_ensure_application_selected(state).is_ok() { - res = _ykpiv_change_pin( - state, - 2, - current_puk, - current_puk_len, - new_puk, - new_puk_len, - tries, - ); + res = _ykpiv_change_pin(state, 2, current_puk, current_puk_len, new_puk, new_puk_len); } _ykpiv_end_transaction(state); @@ -1820,14 +1784,13 @@ pub unsafe fn ykpiv_unblock_pin( puk_len: usize, new_pin: *const c_char, new_pin_len: usize, - tries: *mut i32, ) -> Result<(), ErrorKind> { let mut res = Err(ErrorKind::GenericError); _ykpiv_begin_transaction(state)?; if _ykpiv_ensure_application_selected(state).is_ok() { - res = _ykpiv_change_pin(state, 1, puk, puk_len, new_pin, new_pin_len, tries); + res = _ykpiv_change_pin(state, 1, puk, puk_len, new_pin, new_pin_len); } _ykpiv_end_transaction(state); From 71a334a9b8771745c20de35488d39dee00be0e1b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:16:23 +0000 Subject: [PATCH 10/17] fn ykpiv_auth_getchallenge() -> Result<[u8; 8], ErrorKind> --- src/yubikey.rs | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 95c404a..55ac954 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -2191,23 +2191,12 @@ pub unsafe fn ykpiv_attest( } /// Get an auth challenge -pub unsafe fn ykpiv_auth_getchallenge( - state: &mut YubiKey, - challenge: *mut u8, - challenge_len: usize, -) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_auth_getchallenge(state: &mut YubiKey) -> Result<[u8; 8], ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - let mut res = Ok(()); - - if challenge.is_null() { - return Err(ErrorKind::GenericError); - } - - if challenge_len != 8 { - return Err(ErrorKind::SizeError); - } + // TODO(str4d): What should the default value be if the application is not selected? + let mut res = Ok([0; 8]); _ykpiv_begin_transaction(state)?; @@ -2221,18 +2210,14 @@ pub unsafe fn ykpiv_auth_getchallenge( apdu.data[1] = 0x02; apdu.data[2] = 0x81; //0x80; - res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); - - if res.is_err() { - if sw != SW_SUCCESS { - res = Err(ErrorKind::AuthenticationError); - } else { - memcpy( - challenge as (*mut c_void), - data.as_mut_ptr().offset(4isize) as (*const c_void), - 8usize, - ); - } + if let Err(e) = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw) { + res = Err(e) + } else if sw != SW_SUCCESS { + res = Err(ErrorKind::AuthenticationError); + } else { + let mut challenge = [0; 8]; + challenge.copy_from_slice(&data[4..12]); + res = Ok(challenge); } } From a43bddb531fbfbfd6bba6bba44c00b0f653368e1 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:21:42 +0000 Subject: [PATCH 11/17] Pointers -> refs in ykpiv_auth_verifyresponse --- src/yubikey.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 55ac954..3bff59d 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -2228,21 +2228,12 @@ pub unsafe fn ykpiv_auth_getchallenge(state: &mut YubiKey) -> Result<[u8; 8], Er /// Verify an auth response pub unsafe fn ykpiv_auth_verifyresponse( state: &mut YubiKey, - response: *mut u8, - response_len: usize, + response: &[u8; 8], ) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; let mut sw: i32 = 0; - if response.is_null() { - return Err(ErrorKind::GenericError); - } - - if response_len != 8 { - return Err(ErrorKind::SizeError); - } - _ykpiv_begin_transaction(state)?; // send the response to the card and a challenge of our own. @@ -2254,13 +2245,7 @@ pub unsafe fn ykpiv_auth_verifyresponse( apdu.data[1] = 0x0a; // 2 + 8 apdu.data[2] = 0x82; apdu.data[3] = 8; - - memcpy( - apdu.data.as_mut_ptr().add(4) as *mut c_void, - response as *const c_void, - response_len, - ); - + apdu.data[4..12].copy_from_slice(response); apdu.lc = 12; let mut res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); From 9252765940473d380c014fa8b39e7fbb9200bf44 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:25:23 +0000 Subject: [PATCH 12/17] Fix bug in ykpiv_util_block_puk Introduced in b750b9cbbb17c6dd6596c34880f9a855a793b09d. --- src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.rs b/src/util.rs index f7bb6e9..94f2786 100644 --- a/src/util.rs +++ b/src/util.rs @@ -547,7 +547,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> continue; } Err(e) => { - if res != Err(ErrorKind::PinLocked) { + if e != ErrorKind::PinLocked { _currentBlock = 3; continue; } From 6324f7a75d93719afb4ff751235f94a6209c89cf Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:26:33 +0000 Subject: [PATCH 13/17] Document tries field of ErrorKind::WrongPin --- src/error.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index e55178c..bdd526a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -63,7 +63,10 @@ pub enum ErrorKind { ParseError, /// Wrong PIN - WrongPin { tries: i32 }, + WrongPin { + /// Number of tries remaining + tries: i32, + }, /// Invalid object InvalidObject, From b23ed1d48af0ac35015ac7e32328175eb6884544 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:32:04 +0000 Subject: [PATCH 14/17] Pass response to ykpiv_auth_verifyresponse by value --- src/yubikey.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 3bff59d..3a3a8dd 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -2228,7 +2228,7 @@ pub unsafe fn ykpiv_auth_getchallenge(state: &mut YubiKey) -> Result<[u8; 8], Er /// Verify an auth response pub unsafe fn ykpiv_auth_verifyresponse( state: &mut YubiKey, - response: &[u8; 8], + response: [u8; 8], ) -> Result<(), ErrorKind> { let mut data = [0u8; 261]; let mut recv_len = data.len() as u32; @@ -2245,7 +2245,7 @@ pub unsafe fn ykpiv_auth_verifyresponse( apdu.data[1] = 0x0a; // 2 + 8 apdu.data[2] = 0x82; apdu.data[3] = 8; - apdu.data[4..12].copy_from_slice(response); + apdu.data[4..12].copy_from_slice(&response); apdu.lc = 12; let mut res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); From 88ec6bcb3268852a239caaae5e8188982620816a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:32:19 +0000 Subject: [PATCH 15/17] Remove redundant Result from ykpiv_disconnect --- src/yubikey.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 3a3a8dd..1e25ff4 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -216,7 +216,7 @@ pub unsafe fn ykpiv_done(state: &mut YubiKey) -> Result<(), ErrorKind> { } /// Disconnect a YubiKey session -pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { +pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) { if state.card != 0 { SCardDisconnect(state.card, 0x1); state.card = 0i32; @@ -226,8 +226,6 @@ pub unsafe fn ykpiv_disconnect(state: &mut YubiKey) -> Result<(), ErrorKind> { SCardReleaseContext(state.context); state.context = -1i32; } - - Ok(()) } /// Select application From ce55e08af87216e1da3ee107ee2d7ce14cb8b92d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:35:38 +0000 Subject: [PATCH 16/17] Explicitly ignore _cache_pin errors The only error that _cache_pin can return is a memory allocation failure which will likely be removed during the refactor. --- src/yubikey.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index 1e25ff4..25a1ef2 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -200,7 +200,7 @@ pub(crate) unsafe fn _ykpiv_done(state: &mut YubiKey, disconnect: bool) -> Resul ykpiv_disconnect(state); } - _cache_pin(state, ptr::null(), 0); + let _ = _cache_pin(state, ptr::null(), 0); Ok(()) } @@ -1527,7 +1527,7 @@ pub(crate) unsafe fn _verify( if !pin.is_null() && (pin_len != 0) { // Intentionally ignore errors. If the PIN fails to save, it will only // be a problem if a reconnect is attempted. Failure deferred until then. - _cache_pin(state, pin, pin_len); + let _ = _cache_pin(state, pin, pin_len); } Ok(sw & 0xf) @@ -1740,7 +1740,7 @@ pub unsafe fn ykpiv_change_pin( if res.is_ok() && !new_pin.is_null() { // Intentionally ignore errors. If the PIN fails to save, it will only // be a problem if a reconnect is attempted. Failure deferred until then. - _cache_pin(state, new_pin, new_pin_len); + let _ = _cache_pin(state, new_pin, new_pin_len); } } From 683e463824249fe8562149c29835ba2110490bcb Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 20 Nov 2019 12:38:38 +0000 Subject: [PATCH 17/17] Silence _ykpiv_end_transaction "unused Result" clippy warnings These calls will be replaced when the pcsc crate is introduced. --- src/util.rs | 50 ++++++++++++++++++++++---------------------- src/yubikey.rs | 56 +++++++++++++++++++++++++------------------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/util.rs b/src/util.rs index 94f2786..4d56fc2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -110,7 +110,7 @@ pub unsafe fn ykpiv_util_get_cardid( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -158,7 +158,7 @@ pub unsafe fn ykpiv_util_set_cardid( ); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -188,7 +188,7 @@ pub unsafe fn ykpiv_util_get_cccid(state: &mut YubiKey, ccc: *mut CCCID) -> Resu if res.is_ok() { if len != CCC_TMPL.len() { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::GenericError); } @@ -245,7 +245,7 @@ pub unsafe fn ykpiv_util_set_cccid( res = _ykpiv_save_object(state, YKPIV_OBJ_CAPABILITY as i32, buf.as_mut_ptr(), len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -337,7 +337,7 @@ pub unsafe fn ykpiv_util_list_keys( p_data = calloc(CB_PAGE, 1) as (*mut u8); if p_data.is_null() { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::MemoryError); } @@ -429,7 +429,7 @@ pub unsafe fn ykpiv_util_list_keys( free(p_data as (*mut c_void)); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -476,7 +476,7 @@ pub unsafe fn ykpiv_util_read_cert( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -496,7 +496,7 @@ pub unsafe fn ykpiv_util_write_cert( res = _write_certificate(state, slot, data, data_len, certinfo); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -615,7 +615,7 @@ pub unsafe fn ykpiv_util_block_puk(state: &mut YubiKey) -> Result<(), ErrorKind> } } } else { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } } @@ -682,14 +682,14 @@ pub unsafe fn ykpiv_util_read_mscmap( ); if res.is_err() { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } ptr = buf.as_mut_ptr(); if cb_buf < CB_OBJ_TAG_MIN { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Ok(()); } @@ -698,7 +698,7 @@ pub unsafe fn ykpiv_util_read_mscmap( ptr = ptr.add(_ykpiv_get_length(ptr, &mut len)); if len > cb_buf - (ptr as isize - buf.as_mut_ptr() as isize) as usize { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Ok(()); } @@ -746,14 +746,14 @@ pub unsafe fn ykpiv_util_write_mscmap( res = _ykpiv_save_object(state, YKPIV_OBJ_MSCMAP as i32, ptr::null_mut(), 0); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } let req_len = 1 + _ykpiv_set_length(buf.as_mut_ptr(), data_len) + data_len; if req_len > _obj_size_max(state) { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::SizeError); } @@ -769,7 +769,7 @@ pub unsafe fn ykpiv_util_write_mscmap( res = _ykpiv_save_object(state, YKPIV_OBJ_MSCMAP as i32, buf.as_mut_ptr(), offset); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -897,7 +897,7 @@ pub unsafe fn ykpiv_util_read_msroots( free(p_data as (*mut c_void)); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -925,14 +925,14 @@ pub unsafe fn ykpiv_util_write_msroots( res = _ykpiv_save_object(state, YKPIV_OBJ_MSROOTS1 as i32, ptr::null_mut(), 0); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } n_objs = (data_len / (cb_obj_max - 4)) + 1; if n_objs > 5 { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::SizeError); } @@ -977,7 +977,7 @@ pub unsafe fn ykpiv_util_write_msroots( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1356,7 +1356,7 @@ pub unsafe fn ykpiv_util_generate_key( free(ptr_exp as (*mut c_void)); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1517,7 +1517,7 @@ pub unsafe fn ykpiv_util_get_config( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1562,7 +1562,7 @@ pub unsafe fn ykpiv_util_set_pin_last_changed(state: &mut YubiKey) -> Result<(), } } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1645,7 +1645,7 @@ pub unsafe fn ykpiv_util_get_derived_mgm( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1705,7 +1705,7 @@ pub unsafe fn ykpiv_util_get_protected_mgm( } data.zeroize(); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1917,7 +1917,7 @@ pub unsafe fn ykpiv_util_set_protected_mgm( data.zeroize(); mgm_key.zeroize(); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } diff --git a/src/yubikey.rs b/src/yubikey.rs index 25a1ef2..7587121 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -491,7 +491,7 @@ pub unsafe fn ykpiv_connect(state: &mut YubiKey, wanted: *const c_char) -> Resul _ykpiv_begin_transaction(state)?; let res = _ykpiv_select_application(state); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -782,7 +782,7 @@ pub unsafe fn ykpiv_transfer_data( } let res = _ykpiv_transfer_data(state, templ, in_data, in_len, out_data, out_len, sw); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -878,7 +878,7 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res mgm_key.is_null(), "didn't expect mgm key to be set by failing op!" ); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::AlgorithmError); } @@ -895,12 +895,12 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res.is_err() { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } if sw != SW_SUCCESS { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::AuthenticationError); } @@ -923,7 +923,7 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res ); if drc != DesErrorKind::Ok { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::AuthenticationError); } @@ -949,7 +949,7 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res eprintln!("Failed getting randomness for authentication."); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::RandomnessError); } @@ -963,12 +963,12 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw); if res.is_err() { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return res; } if sw != SW_SUCCESS { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::AuthenticationError); } @@ -1001,7 +1001,7 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res des_destroy_key(mgm_key); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1040,7 +1040,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( 0 => 0xff, 1 => 0xfe, _ => { - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::GenericError); } }; @@ -1065,7 +1065,7 @@ pub(crate) unsafe fn ykpiv_set_mgmkey2( } apdu.zeroize(); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1220,7 +1220,7 @@ pub unsafe fn ykpiv_sign_data( state, raw_in, in_len, sign_out, out_len, algorithm, key, false, ); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1239,7 +1239,7 @@ pub unsafe fn ykpiv_decrypt_data( // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS let res = _general_authenticate(state, input, input_len, out, out_len, algorithm, key, true); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1285,7 +1285,7 @@ pub unsafe fn ykpiv_get_version(state: &mut YubiKey) -> Result Result { res = _ykpiv_get_serial(state, false); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1563,7 +1563,7 @@ pub unsafe fn ykpiv_verify_select( res = _verify(state, pin, pin_len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1630,7 +1630,7 @@ pub unsafe fn ykpiv_set_pin_retries( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1744,7 +1744,7 @@ pub unsafe fn ykpiv_change_pin( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1770,7 +1770,7 @@ pub unsafe fn ykpiv_change_puk( res = _ykpiv_change_pin(state, 2, current_puk, current_puk_len, new_puk, new_puk_len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1791,7 +1791,7 @@ pub unsafe fn ykpiv_unblock_pin( res = _ykpiv_change_pin(state, 1, puk, puk_len, new_pin, new_pin_len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1810,7 +1810,7 @@ pub unsafe fn ykpiv_fetch_object( res = _ykpiv_fetch_object(state, object_id, data, len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -1894,7 +1894,7 @@ pub unsafe fn ykpiv_save_object( res = _ykpiv_save_object(state, object_id, indata, len); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -2135,7 +2135,7 @@ pub unsafe fn ykpiv_import_private_key( } key_data.zeroize(); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -2184,7 +2184,7 @@ pub unsafe fn ykpiv_attest( } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -2219,7 +2219,7 @@ pub unsafe fn ykpiv_auth_getchallenge(state: &mut YubiKey) -> Result<[u8; 8], Er } } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -2253,7 +2253,7 @@ pub unsafe fn ykpiv_auth_verifyresponse( } apdu.zeroize(); - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res } @@ -2292,6 +2292,6 @@ pub unsafe fn ykpiv_auth_deauthenticate(state: &mut YubiKey) -> Result<(), Error res = Err(ErrorKind::GenericError); } - _ykpiv_end_transaction(state); + let _ = _ykpiv_end_transaction(state); res }