pub struct Handle<T: PcscHal> { /* private fields */ }
Expand description
A Handle representing a connection to an underlying PC/SC device. This struct is parameterized on a PcscHal implementation, so the underlying hardware implementation can be swapped out as long as it is “compatible” with the PC/SC library, in some sense.
Users of this struct must connect
before calling most API functions.
Many API functions also require authentication. The authentication secrets can either be passed in, or alternatively will be prompted for on stdin. The following table denotes which functions require which kind of authentication:
Function | MGM Key | PIN | PUK | Notes |
---|---|---|---|---|
list_readers | ||||
connect | ||||
disconnect | ||||
get_version | ||||
get_serial | ||||
change_pin | X | |||
unblock_pin | X | |||
change_puk | X | |||
reset | PIN + PUK must be blocked. | |||
set_retries | X | X | ||
set_management_key | X | |||
set_chuid | X | |||
set_ccc | X | |||
read_object | ||||
write_object | X | |||
generate | X | |||
import_key | X | |||
attest | ||||
read_certificate | ||||
encrypt | ||||
decrypt | X |
Implementations§
source§impl<T: PcscHal> Handle<T>
impl<T: PcscHal> Handle<T>
pub fn new() -> Result<Self>
pub fn new_with_hal(hal: T) -> Self
pub fn get_hal(&self) -> &T
pub fn get_hal_mut(&mut self) -> &mut T
sourcepub fn list_readers(&self) -> Result<Vec<String>>
pub fn list_readers(&self) -> Result<Vec<String>>
This function returns the list of valid reader strings which can be passed to State::new.
sourcepub fn connect(&mut self, reader: Option<&str>) -> Result<()>
pub fn connect(&mut self, reader: Option<&str>) -> Result<()>
Connect to the PC/SC reader which matches the given reader string (or DEFAULT_READER, if one was not provided). The first reader which includes the given string as a substring will be used.
sourcepub fn disconnect(&mut self)
pub fn disconnect(&mut self)
Disconnect from the currently connected PC/SC reader. This is only necessary if you want to re-use this State to interact with a different reader.
sourcepub fn get_version(&self) -> Result<Version>
pub fn get_version(&self) -> Result<Version>
This function returns the version number the connected reader reports. Note that connect() must be called before this function, or an error will be returned.
sourcepub fn get_serial(&self) -> Result<Serial>
pub fn get_serial(&self) -> Result<Serial>
This function returns the serial number of the connected reader. This is a number which uniquely identifes this device from others of the same model. Note that connect() must be called before this function, or an error will be returned.
sourcepub fn change_pin(
&mut self,
old_pin: Option<&str>,
new_pin: Option<&str>
) -> Result<()>
pub fn change_pin( &mut self, old_pin: Option<&str>, new_pin: Option<&str> ) -> Result<()>
This function allows the user to change the Yubikey’s PIN, given that the user knows the existing PIN. The old and new PINs can be provided as function arguments. If they are not provided, this function will prompt for them on stdin.
When prompting for a PIN, this function will automatically retry if PIN verification fails, until there are no more available retries. At that point, the PIN can be unblocked using the PUK.
sourcepub fn unblock_pin(
&mut self,
puk: Option<&str>,
new_pin: Option<&str>
) -> Result<()>
pub fn unblock_pin( &mut self, puk: Option<&str>, new_pin: Option<&str> ) -> Result<()>
This function allows the user to reset the Yubikey’s PIN using the PUK, after the user has exhausted their allotted tries to enter the PIN correctly. The PUK and new PIN can be provided as function arguments. If they are not provided, this function will prompt for them on stdin.
When prompting for a PUK, this function will automatically retry if PUK verification fails, until there are no more available retries. At that point, the Yubiey can be reset to factory defaults using the reset function.
sourcepub fn change_puk(
&mut self,
old_puk: Option<&str>,
new_puk: Option<&str>
) -> Result<()>
pub fn change_puk( &mut self, old_puk: Option<&str>, new_puk: Option<&str> ) -> Result<()>
This function allows the user to change the Yubikey’s PUK, given that the user knows the existing PUK. The old and new PUKs can be provided as function arguments. If they are not provided, this function will prompt for them on stdin.
When prompting for a PUK, this function will automatically retry if PUK verification fails, until there are no more available retries. At that point, the PIN and PUK can both be unblocked using the reset function.
sourcepub fn reset(&mut self) -> Result<()>
pub fn reset(&mut self) -> Result<()>
This function resets the PIN, PUK, and management key to their factory default values, as well as delete any stored certificates and keys. The default values for the PIN and PUK are 123456 and 12345678, respectively.
Note that this function will return an error unless the tries to verify the PIN and PUK have both been fully exhausted (e.g., the Yubikey is now unusable). Otherwise, the change_pin, unblock_pin, and change_puk functions should be used instead of this function.
sourcepub fn force_reset(&mut self) -> Result<()>
pub fn force_reset(&mut self) -> Result<()>
This function is similar to reset, except it first ensures that all of the PIN and PUK retries have been exhausted first (by intentionally exhausting them with known-bad values).
sourcepub fn set_retries(
&mut self,
mgm_key: Option<&str>,
pin: Option<&str>,
pin_retries: u8,
puk_retries: u8
) -> Result<()>
pub fn set_retries( &mut self, mgm_key: Option<&str>, pin: Option<&str>, pin_retries: u8, puk_retries: u8 ) -> Result<()>
This function sets the number of retries available for PIN or PUK verification. This also resets the PIN and PUK back to their factory default values, 123456 and 12345678, respectively.
Note that this function is slightly strange compared to the rest of the API, in that both the management key and the current PIN are required.
sourcepub fn set_management_key(
&mut self,
old_mgm_key: Option<&str>,
new_mgm_key: Option<&str>,
touch: bool
) -> Result<()>
pub fn set_management_key( &mut self, old_mgm_key: Option<&str>, new_mgm_key: Option<&str>, touch: bool ) -> Result<()>
This function changes the management key stored on the device. This is the key used to authenticate() for administrative / management access.
sourcepub fn set_chuid(&mut self, mgm_key: Option<&str>) -> Result<()>
pub fn set_chuid(&mut self, mgm_key: Option<&str>) -> Result<()>
This function writes a new, randomly-generated Card Holder Unique Identifier (CHUID) to the device. Some systems (Windows) require a CHUID to be present before they will recognize the Yubikey. This data object is not present on Yubikeys by default (from the factory).
Also note that, according to the Yubikey docs, the card contents are aggressively cached on Windows. In order to invalidate the cached data, e.g. after changing stored certificates, the CHUID must also be changed.
sourcepub fn set_ccc(&mut self, mgm_key: Option<&str>) -> Result<()>
pub fn set_ccc(&mut self, mgm_key: Option<&str>) -> Result<()>
This function writes a new, randomly-generated Card Capability Container (CCC) to the device. Some systems (MacOS) require a CCC to be present before they will recognize the Yubikey. This data object is not present on Yubikeys by default (from the factory).
sourcepub fn read_object(&self, id: Object) -> Result<Vec<u8>>
pub fn read_object(&self, id: Object) -> Result<Vec<u8>>
Read a data object from the Yubikey, returning the byte contents.
sourcepub fn write_object(
&mut self,
mgm_key: Option<&str>,
id: Object,
buffer: Vec<u8>
) -> Result<()>
pub fn write_object( &mut self, mgm_key: Option<&str>, id: Object, buffer: Vec<u8> ) -> Result<()>
Write a data object to the Yubikey. This function takes ownership of the data, because upstream’s API requires a mutable data buffer.
sourcepub fn generate(
&mut self,
mgm_key: Option<&str>,
slot: Key,
algorithm: Algorithm,
pin_policy: PinPolicy,
touch_policy: TouchPolicy
) -> Result<PublicKey>
pub fn generate( &mut self, mgm_key: Option<&str>, slot: Key, algorithm: Algorithm, pin_policy: PinPolicy, touch_policy: TouchPolicy ) -> Result<PublicKey>
Generate a new private / public key pair, using the underlying hardware’s generation capability. Store the private key in the given key slot, and return the public key. The specified PIN and touch policies will be enforced whenever this key is used in the future.
sourcepub fn import_key<P: AsRef<Path>>(
&mut self,
mgm_key: Option<&str>,
input: P,
slot: Key,
encrypted: bool,
passphrase: Option<&str>,
pin_policy: PinPolicy,
touch_policy: TouchPolicy
) -> Result<PublicKey>
pub fn import_key<P: AsRef<Path>>( &mut self, mgm_key: Option<&str>, input: P, slot: Key, encrypted: bool, passphrase: Option<&str>, pin_policy: PinPolicy, touch_policy: TouchPolicy ) -> Result<PublicKey>
Import an RSA or EC private key into the given key slot. The provided input key must be a PEM-encoded private key file. The caller must indicate if the private key is encrypted or not. If the key is encrypted, and no passphrase is provided, one will be prompted for. The specified PIN and touch policies will be enforced whenever this key is used in the future.
sourcepub fn attest(&self, slot: Key) -> Result<PublicKeyCertificate>
pub fn attest(&self, slot: Key) -> Result<PublicKeyCertificate>
Attest returns an X.509 certificate signed with the private key in the given slot if and only if the private key was generated on the device rather than imported. Note that this feature is only supported by some newer hardware devices. For details, see: https://developers.yubico.com/yubico-piv-tool/Attestation.html
pub fn read_certificate(&self, slot: Key) -> Result<PublicKeyCertificate>
sourcepub fn encrypt(
&self,
public_key: &PublicKey,
plaintext: &[u8]
) -> Result<(Algorithm, Vec<u8>)>
pub fn encrypt( &self, public_key: &PublicKey, plaintext: &[u8] ) -> Result<(Algorithm, Vec<u8>)>
Encrypts the given data with the given public key. It is assumed that the matching private key is stored on the device, in which case the returned encrypted data can later be deciphered using the hardware device.
Note that the given input key must be an RSA key in PEM format.
Refer to piv::pkey::PublicKey::encrypt
for more details.
sourcepub fn decrypt(
&mut self,
pin: Option<&str>,
ciphertext: &[u8],
slot: Key,
algorithm: Algorithm
) -> Result<Vec<u8>>
pub fn decrypt( &mut self, pin: Option<&str>, ciphertext: &[u8], slot: Key, algorithm: Algorithm ) -> Result<Vec<u8>>
Decrypts the given ciphertext with the private key in the given key
slot. The specified key must be an RSA key, and the cipertext must
have been encrypted with padding as per the encrypt
function.