From 47ea358ddc1bc37b809f9f5b893a6b099cbb262b Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Mon, 12 Aug 2019 22:23:33 -0700 Subject: Update nitrokey crate to 0.4.0-alpha.3 This change updates the version of the nitrokey crate that we use to 0.4.0-alpha.3. This version is the supposedly last pre-release before 0.4.0, with no further major anticipated changes. In order to integrate with this new version we have to adjust the way we connect to a Nitrokey device by funneling those connection requests through a global manager object. The rationale behind that step being that the underlying libnitrokey actually cannot handle access of multiple devices at the same time, and so the manager object is used to prevent accidental wrong concurrent usage. Because a device object now effectively keeps a reference to the manager, we need to provide an additional lifetime to that and derived objects. Lastly, the use of a manager is also the reason why the tests had to be adjusted to no longer accept device objects in their signatures, but only the respective model for which to invoke the test. That is required because, as elaborated earlier on, having a device object implies having taken a reference to a manager (in that case owned by nitrokey-test), and that reference clashes with the nitrocli code itself attempting to take the manager. We side step this problem by merely accepting a Model object, which can be passed around independently of the manager itself, meaning that nitrokey-test does not need to hold such a reference while the test is run. Import subrepo nitrokey/:nitrokey at f150d59410eefdec2ae69b2422906a3d1d88aa07 Import subrepo nitrokey-sys/:nitrokey-sys at 8695e2c762807e033a86c8d03974b686d20cdd72 Import subrepo lazy-static/:lazy-static at b4b2b16aaa79dd7548e288455a0dbe4065bf4e1a --- nitrokey-sys/src/ffi.rs | 377 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 373 insertions(+), 4 deletions(-) (limited to 'nitrokey-sys/src') diff --git a/nitrokey-sys/src/ffi.rs b/nitrokey-sys/src/ffi.rs index 58879ad..a01eae8 100644 --- a/nitrokey-sys/src/ffi.rs +++ b/nitrokey-sys/src/ffi.rs @@ -1,5 +1,10 @@ /* automatically generated by rust-bindgen, manually modified */ +extern "C" { + #[link_name = "\u{1}NK_PWS_SLOT_COUNT"] + pub static mut NK_PWS_SLOT_COUNT: u8; +} +pub const MAXIMUM_STR_REPLY_LENGTH: ::std::os::raw::c_int = 8192; /// Use, if no supported device is connected pub const NK_device_model_NK_DISCONNECTED: NK_device_model = 0; /// Nitrokey Pro. @@ -8,6 +13,188 @@ pub const NK_device_model_NK_PRO: NK_device_model = 1; pub const NK_device_model_NK_STORAGE: NK_device_model = 2; /// The Nitrokey device models supported by the API. pub type NK_device_model = u32; +/// The connection info for a Nitrokey device as a linked list. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NK_device_info { + /// The model of the Nitrokey device. + pub model: NK_device_model, + /// The USB device path for NK_connect_with_path. + pub path: *mut ::std::os::raw::c_char, + /// The serial number. + pub serial_number: *mut ::std::os::raw::c_char, + /// The pointer to the next element of the linked list or null + /// if this is the last element in the list. + pub next: *mut NK_device_info, +} +#[test] +fn bindgen_test_layout_NK_device_info() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(NK_device_info)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(NK_device_info)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).model as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(NK_device_info), + "::", + stringify!(model) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).path as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(NK_device_info), + "::", + stringify!(path) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).serial_number as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(NK_device_info), + "::", + stringify!(serial_number) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).next as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(NK_device_info), + "::", + stringify!(next) + ) + ); +} +/// Stores the common device status for all Nitrokey devices. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NK_status { + /// The major firmware version, e. g. 0 in v0.40. + pub firmware_version_major: u8, + /// The minor firmware version, e. g. 40 in v0.40. + pub firmware_version_minor: u8, + /// The serial number of the smart card. + pub serial_number_smart_card: u32, + /// The HOTP slot to generate a password from if the numlock + /// key is pressed twice (slot 0-1, or any other value to + /// disable the function). + pub config_numlock: u8, + /// The HOTP slot to generate a password from if the capslock + /// key is pressed twice (slot 0-1, or any other value to + /// disable the function). + pub config_capslock: u8, + /// The HOTP slot to generate a password from if the scrolllock + /// key is pressed twice (slot 0-1, or any other value to + /// disable the function). + pub config_scrolllock: u8, + /// Indicates whether the user password is required to generate + /// an OTP value. + pub otp_user_password: bool, +} +#[test] +fn bindgen_test_layout_NK_status() { + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(NK_status)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(NK_status)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).firmware_version_major as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(firmware_version_major) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).firmware_version_minor as *const _ as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(firmware_version_minor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).serial_number_smart_card as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(serial_number_smart_card) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).config_numlock as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(config_numlock) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).config_capslock as *const _ as usize }, + 9usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(config_capslock) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).config_scrolllock as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(config_scrolllock) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).otp_user_password as *const _ as usize }, + 11usize, + concat!( + "Offset of field: ", + stringify!(NK_status), + "::", + stringify!(otp_user_password) + ) + ); +} /// Stores the status of a Storage device. #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -259,6 +446,54 @@ fn bindgen_test_layout_NK_storage_status() { ) ); } +/// Data about the usage of the SD card. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NK_SD_usage_data { + /// The minimum write level, as a percentage of the total card + /// size. + pub write_level_min: u8, + /// The maximum write level, as a percentage of the total card + /// size. + pub write_level_max: u8, +} +#[test] +fn bindgen_test_layout_NK_SD_usage_data() { + assert_eq!( + ::std::mem::size_of::(), + 2usize, + concat!("Size of: ", stringify!(NK_SD_usage_data)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(NK_SD_usage_data)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).write_level_min as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(NK_SD_usage_data), + "::", + stringify!(write_level_min) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).write_level_max as *const _ as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(NK_SD_usage_data), + "::", + stringify!(write_level_max) + ) + ); +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct NK_storage_ProductionTest { @@ -519,10 +754,29 @@ extern "C" { /// @return true if a device is connected and the out argument has been set pub fn NK_get_device_model() -> NK_device_model; } +extern "C" { + /// Return the debug status string. Debug purposes. This function is + /// deprecated in favor of NK_get_status_as_string. + /// @return string representation of the status or an empty string + /// if the command failed + #[deprecated(since = "3.5.0", note="use `NK_get_status_as_string` instead")] + pub fn NK_status() -> *mut ::std::os::raw::c_char; +} extern "C" { /// Return the debug status string. Debug purposes. + /// @return string representation of the status or an empty string + /// if the command failed + pub fn NK_get_status_as_string() -> *mut ::std::os::raw::c_char; +} +extern "C" { + /// Get the stick status common to all Nitrokey devices and return the + /// command processing error code. If the code is zero, i. e. the + /// command was successful, the storage status is written to the output + /// pointer's target. The output pointer must not be null. + /// + /// @param out the output pointer for the status /// @return command processing error code - pub fn NK_status() -> *mut ::std::os::raw::c_char; + pub fn NK_get_status(out: *mut NK_status) -> ::std::os::raw::c_int; } extern "C" { /// Return the device's serial number string in hex. @@ -760,6 +1014,7 @@ extern "C" { pub fn NK_totp_set_time_soft(time: u64) -> ::std::os::raw::c_int; } extern "C" { + #[deprecated(since = "3.4.0", note="use `NK_totp_set_time_soft` instead")] pub fn NK_totp_get_time() -> ::std::os::raw::c_int; } extern "C" { @@ -853,12 +1108,12 @@ extern "C" { extern "C" { /// Get device's major firmware version /// @return major part of the version number (e.g. 0 from 0.48, 0 from 0.7 etc.) - pub fn NK_get_major_firmware_version() -> ::std::os::raw::c_int; + pub fn NK_get_major_firmware_version() -> u8; } extern "C" { /// Get device's minor firmware version /// @return minor part of the version number (e.g. 7 from 0.7, 48 from 0.48 etc.) - pub fn NK_get_minor_firmware_version() -> ::std::os::raw::c_int; + pub fn NK_get_minor_firmware_version() -> u8; } extern "C" { /// Function to determine unencrypted volume PIN type @@ -1067,6 +1322,16 @@ extern "C" { /// @return command processing error code pub fn NK_get_status_storage(out: *mut NK_storage_status) -> ::std::os::raw::c_int; } +extern "C" { + /// Get SD card usage attributes. Usable during hidden volumes creation. + /// If the command was successful (return value 0), the usage data is + /// written to the output pointer’s target. The output pointer must + /// not be null. + /// Storage only + /// @param out the output pointer for the usage data + /// @return command processing error code + pub fn NK_get_SD_usage_data(out: *mut NK_SD_usage_data) -> ::std::os::raw::c_int; +} extern "C" { /// Get SD card usage attributes as string. /// Usable during hidden volumes creation. @@ -1077,7 +1342,8 @@ extern "C" { extern "C" { /// Get progress value of current long operation. /// Storage only - /// @return int in range 0-100 or -1 if device is not busy + /// @return int in range 0-100 or -1 if device is not busy or -2 if an + /// error occured pub fn NK_get_progress_bar_value() -> ::std::os::raw::c_int; } extern "C" { @@ -1096,6 +1362,18 @@ extern "C" { /// @return string delimited id's of connected devices pub fn NK_list_devices_by_cpuID() -> *mut ::std::os::raw::c_char; } +extern "C" { + /// Returns a linked list of all connected devices, or null if no devices + /// are connected or an error occured. The linked list must be freed by + /// calling NK_free_device_info. + /// @return a linked list of all connected devices + pub fn NK_list_devices() -> *mut NK_device_info; +} +extern "C" { + /// Free a linked list returned by NK_list_devices. + /// @param the linked list to free or null + pub fn NK_free_device_info(device_info: *mut NK_device_info); +} extern "C" { /// Connects to the device with given ID. ID's list could be created with NK_list_devices_by_cpuID. /// Requires calling to NK_list_devices_by_cpuID first. Connecting to arbitrary ID/USB path is not handled. @@ -1105,8 +1383,99 @@ extern "C" { /// @return 1 on successful connection, 0 otherwise pub fn NK_connect_with_ID(id: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } +extern "C" { + /// Connects to a device with the given path. The path is a USB device + /// path as returned by hidapi. + /// @param path the device path + /// @return 1 on successful connection, 0 otherwise + pub fn NK_connect_with_path(path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} extern "C" { /// Blink red and green LED alternatively and infinitely (until device is reconnected). /// @return command processing error code pub fn NK_wink() -> ::std::os::raw::c_int; } +extern "C" { + /// Enable update mode on Nitrokey Pro. + /// Supported from v0.11. + /// @param update_password 20 bytes update password + /// @return command processing error code + pub fn NK_enable_firmware_update_pro( + update_password: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + /// Change update-mode password on Nitrokey Pro. + /// Supported from v0.11. + /// @param current_firmware_password 20 bytes update password + /// @param new_firmware_password 20 bytes update password + /// @return command processing error code + pub fn NK_change_firmware_password_pro( + current_firmware_password: *const ::std::os::raw::c_char, + new_firmware_password: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ReadSlot_t { + pub slot_name: [u8; 15usize], + pub _slot_config: u8, + pub slot_token_id: [u8; 13usize], + pub slot_counter: u64, +} +#[test] +fn bindgen_test_layout_ReadSlot_t() { + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(ReadSlot_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ReadSlot_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).slot_name as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ReadSlot_t), + "::", + stringify!(slot_name) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::()))._slot_config as *const _ as usize }, + 15usize, + concat!( + "Offset of field: ", + stringify!(ReadSlot_t), + "::", + stringify!(_slot_config) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).slot_token_id as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(ReadSlot_t), + "::", + stringify!(slot_token_id) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).slot_counter as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(ReadSlot_t), + "::", + stringify!(slot_counter) + ) + ); +} +extern "C" { + pub fn NK_read_HOTP_slot(slot_num: u8, out: *mut ReadSlot_t) -> ::std::os::raw::c_int; +} -- cgit v1.2.3