# yubihsm.rs [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] [![Build Status][build-image]][build-link] [![Dependency Status][deps-image]][deps-link] ![Apache2/MIT licensed][license-image] ![MSRV][rustc-image] Pure Rust client for [YubiHSM 2] devices from [Yubico]. [Documentation][docs-link] ## About This is a pure-Rust client library for [YubiHSM 2] devices which implements most the functionality of the [libyubihsm] C library from Yubico's YubiHSM SDK. It provides two backends for communicating with YubiHSMs: - [HTTP][http-connector]: communicate with YubiHSM via the `yubihsm-connector` process from the Yubico SDK. - [USB][usb-connector]: communicate directly with the YubiHSM over USB using the [rusb] crate. The [yubihsm::Client] type provides access to [HSM commands][command]. This is **NOT** an official Yubico project and is in no way supported or endorsed by Yubico (although whoever runs their Twitter account [thinks it's awesome]). *NOTE: Looking for a YubiKey library instead of YubiHSM? Check out [yubikey-piv.rs] instead.* ## Minimum Supported Rust Version This crate requires Rust **1.57** or newer. ## Supported Commands **NOTE:** If there's a command on this list you'd like to use which isn't presently supported, please open an issue requesting support. | [Command] | Impl'd | [MockHSM] | Description | |--------------------------------|--------|-----------|-------------| | [Authenticate Session] | ✅ | ✅ | Authenticate to HSM with password or encryption key | | [Blink Device] | ✅ | ✅ | Blink the HSM's LEDs (to identify it) | | [Change Authentication Key] | ⛔ | ⛔ | Replace the authentication key used to create current session | | [Close Session] | ✅ | ✅ | Terminate an encrypted session with the HSM | | [Create OTP AEAD] | ⛔ | ⛔ | Create a Yubico OTP AEAD | | [Create Session] | ✅ | ✅ | Initiate a new encrypted session with the HSM | | [Decrypt OAEP] | ✅ | ⛔ | Decrypt data encrypted with RSA-OAEP | | [Decrypt OTP] | ⛔ | ⛔ | Decrypt a Yubico OTP, obtaining counters and timer info | | [Decrypt PKCS1] | ⛔ | ⛔ | Decrypt data encrypted with RSA-PKCS#1v1.5 | | [Delete Object] | ✅ | ✅ | Delete an object of the given ID and type | | [Derive ECDH] | ⚠️ | ⛔ | Compute Elliptic Curve Diffie-Hellman using HSM-backed key | | [Device Info] | ✅ | ✅ | Get information about the HSM | | [Echo] | ✅ | ✅ | Echo a message sent to the HSM | | [Export Wrapped] | ✅ | ✅ | Export an object from the HSM in encrypted form| | [Generate Asymmetric Key] | ✅ | ✅ | Randomly generate new asymmetric key in the HSM | | [Generate HMAC Key] | ✅ | ✅ | Randomly generate HMAC key in the HSM | | [Generate OTP AEAD Key] | ⛔ | ⛔ | Randomly generate AES key for Yubico OTP authentication | | [Generate Wrap Key] | ✅ | ✅ | Randomly generate AES key for exporting/importing objects | | [Get Log Entries] | ✅ | ✅ | Obtain the audit log for the HSM | | [Get Object Info] | ✅ | ✅ | Get information about an object | | [Get Opaque] | ✅ | ✅ | Get an opaque bytestring from the HSM | | [Get Option] | ✅ | ✅ | Get HSM auditing settings | | [Get Pseudo Random] | ✅ | ✅ | Get random data generated by the HSM's internal PRNG | | [Get Public key] | ✅ | ✅ | Get public key for an HSM-backed asymmetric private key | | [Get Storage Info] | ✅ | ✅ | Fetch information about currently free storage | | [Get SSH Template] | ✅ | ⛔ | Fetch SSH certificate template object from the HSM | | [Import Wrapped] | ✅ | ✅ | Import an encrypted key into the HSM | | [List Objects] | ✅ | ✅ | List objects visible from the current session | | [Put Asymmetric Key] | ✅ | ✅ | Put an existing asymmetric key into the HSM | | [Put Authentication Key] | ✅ | ✅ | Put YubiHSM authentication key into the HSM | | [Put HMAC Key] | ✅ | ✅ | Put an HMAC key into the HSM | | [Put Opaque] | ✅ | ✅ | Put an opaque bytestring into the HSM | | [Put OTP AEAD Key] | ✅ | ⛔ | Put a Yubico OTP key into the HSM | | [Put SSH Template] | ✅ | ⛔ | Put SSH certificate template object into the HSM | | [Put Wrap Key] | ✅ | ✅ | Put an AES keywrapping key into the HSM | | [Randomize OTP AEAD] | ⛔ | ⛔ | Randomly generate a Yubico OTP AEAD | | [Reset Device] | ✅ | ✅ | Reset the HSM back to factory default settings | | [Rewrap OTP AEAD] | ⛔ | ⛔ | Re-wrap a Yubico OTP AEAD from one key to another | | [Session Message] | ✅ | ✅ | Send an encrypted message to the HSM | | [Set Log Index] | ✅ | ✅ | Mark log messages in the HSM as consumed | | [Set Option] | ✅ | ✅ | Change HSM auditing settings | | [Sign Attestation Certificate] | ✅ | ⛔ | Create X.509 certificate for asymmetric key | | [Sign ECDSA] | ✅ | ✅ | Compute an ECDSA signature using HSM-backed key | | [Sign EdDSA] | ✅ | ✅ | Compute an Ed25519 signature using HSM-backed key | | [Sign HMAC] | ✅ | ✅ | Perform an HMAC operation using an HSM-backed key | | [Sign PKCS1] | ⚠️ | ⛔ | Compute an RSASSA-PKCS#1v1.5 signature using HSM-backed key | | [Sign PSS] | ⚠️ | ⛔ | Compute an RSASSA-PSS signature using HSM-backed key | | [Sign SSH Certificate] | ⚠️ | ⛔ | Sign an SSH certificate request | | [Unwrap Data] | ✅ | ⛔ | Decrypt data encrypted using a wrap key | | [Verify HMAC] | ✅ | ✅ | Verify that an HMAC tag for given data is valid | | [Wrap Data] | ✅ | ⛔ | Encrypt data using a wrap key | | | Status | |----|--------------------------| | ✅ | Supported | | ⚠️ | Partial/Untested Support | | ⛔ | Unsupported | NOTE: Commands marked ⚠️ have not been properly tested and may contain bugs or not work at all. They are disabled by default: to use them you must enable the `untested` cargo feature. If you do get them to work, please open an issue (or PR) reporting success so we can promote them to ✅. ## Testing This crate allows you to run the [integration test] suite in three different ways: - Live testing against a real YubiHSM2 device: - via HTTP - via USB - simulated testing using [MockHSM] which implements some YubiHSM2 functionality ### `cargo test`: test YubiHSM2 live over HTTP via `yubihsm-connector` This mode assumes you have a YubiHSM2 hardware device, have downloaded the [YubiHSM2 SDK] for your platform, and are running a **yubihsm-connector** process listening on localhost on the default port of 12345. The YubiHSM2 device should be in the default factory state. To reset it to this state, either use the [yubihsm-shell reset] command or press on the YubiHSM2 for 10 seconds immediately after inserting it. You can confirm the tests are running live against the YubiHSM2 by the LED blinking rapidly for 1 second. **NOTE THAT THESE TESTS ARE DESTRUCTIVE: DO NOT RUN THEM AGAINST A YUBIHSM2 WHICH CONTAINS KEYS YOU CARE ABOUT** ### `cargo test --features=usb`: test YubiHSM2 live via USB Adding the `usb` cargo feature builds in USB connector support in addition to HTTP connector, and also runs the test suite live via USB rather than using the `yubihsm-connector` process. **ALSO NOTE THAT THESE TESTS ARE DESTRUCTIVE: DO NOT RUN THEM AGAINST A YUBIHSM2 WHICH CONTAINS KEYS YOU CARE ABOUT** ### `cargo test --features=mockhsm`: simulated tests against a mock HSM This mode is useful for when you don't have access to physical YubiHSM2 hardware, such as CI environments. ## License **yubihsm.rs** is distributed under the terms of both the MIT license and the Apache License (Version 2.0). See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details. [//]: # (badges) [crate-image]: https://buildstats.info/crate/yubihsm [crate-link]: https://crates.io/crates/yubihsm [docs-image]: https://docs.rs/yubihsm/badge.svg [docs-link]: https://docs.rs/yubihsm/ [build-image]: https://github.com/iqlusioninc/yubihsm.rs/actions/workflows/ci.yml/badge.svg [build-link]: https://github.com/iqlusioninc/yubihsm.rs/actions/workflows/ci.yml [deps-image]: https://deps.rs/repo/github/iqlusioninc/yubihsm.rs/status.svg [deps-link]: https://deps.rs/repo/github/iqlusioninc/yubihsm.rs [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.67+-blue.svg [//]: # (general links) [libyubihsm]: https://github.com/Yubico/yubihsm-shell/blob/master/lib/README.adoc [YubiHSM 2]: https://www.yubico.com/products/yubihsm/ [Yubico]: https://www.yubico.com/ [yubihsm-connector]: https://developers.yubico.com/YubiHSM2/Component_Reference/yubihsm-connector/ [http-connector]: https://docs.rs/yubihsm/latest/yubihsm/connector/struct.Connector.html#method.http [usb-connector]: https://docs.rs/yubihsm/latest/yubihsm/connector/struct.Connector.html#method.usb [yubihsm::Client]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html [command]: https://developers.yubico.com/YubiHSM2/Commands/ [rusb]: https://github.com/a1ien/rusb [thinks it's awesome]: https://twitter.com/Yubico/status/971186516796915712 [yubikey-piv.rs]: https://github.com/iqlusioninc/yubikey-piv.rs [YubiHSM2 commands]: https://developers.yubico.com/YubiHSM2/Commands/ [Serde-based message parser]: https://github.com/iqlusioninc/yubihsm.rs/tree/main/src/serialization [commands]: https://github.com/iqlusioninc/yubihsm.rs/tree/main/src/command [integration test]: https://github.com/iqlusioninc/yubihsm.rs/blob/main/tests/integration.rs [MockHSM]: https://docs.rs/yubihsm/latest/yubihsm/mockhsm/struct.MockHsm.html [YubiHSM2 SDK]: https://developers.yubico.com/YubiHSM2/Releases/ [yubihsm-shell reset]: https://developers.yubico.com/YubiHSM2/Commands/Reset_Device.html [//]: # (YubiHSM2 commands) [Authenticate Session]: https://developers.yubico.com/YubiHSM2/Commands/Authenticate_Session.html [Blink Device]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.blink_device [Change Authentication Key]: https://developers.yubico.com/YubiHSM2/Commands/Change_Authentication_Key.html [Close Session]: https://developers.yubico.com/YubiHSM2/Commands/Close_Session.html [Create OTP AEAD]: https://developers.yubico.com/YubiHSM2/Commands/Create_Otp_Aead.html [Create Session]: https://developers.yubico.com/YubiHSM2/Commands/Create_Session.html [Derive ECDH]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.derive_ecdh [Decrypt OAEP]: https://developers.yubico.com/YubiHSM2/Commands/Decrypt_Oaep.html [Decrypt OTP]: https://developers.yubico.com/YubiHSM2/Commands/Decrypt_Otp.html [Decrypt PKCS1]: https://developers.yubico.com/YubiHSM2/Commands/Decrypt_Pkcs1.html [Delete Object]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.delete_object [Device Info]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.device_info [Echo]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.echo [Export Wrapped]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.export_wrapped [Generate Asymmetric Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.generate_asymmetric_key [Generate HMAC Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.generate_hmac_key [Generate OTP AEAD Key]: https://developers.yubico.com/YubiHSM2/Commands/Generate_Otp_Aead_Key.html [Generate Wrap Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.generate_wrap_key [Get Log Entries]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_log_entries [Get Object Info]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_object_info [Get Opaque]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_opaque [Get Option]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_command_audit_option [Get Pseudo Random]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_pseudo_random [Get Public Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_pubkey [Get Storage Info]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.storage_info [Get SSH Template]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.get_template [Import Wrapped]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.import_wrapped [List Objects]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.list_objects [Put Asymmetric Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_asymmetric_key [Put Authentication Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_auth_key [Put HMAC Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_hmac_key [Put Opaque]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_opaque [Put OTP AEAD Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_otp_aead_key [Put SSH Template]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_template [Put Wrap Key]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.put_wrap_key [Randomize OTP AEAD]: https://developers.yubico.com/YubiHSM2/Commands/Randomize_Otp_Aead.html [Reset Device]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.reset_device [Rewrap OTP AEAD]: https://developers.yubico.com/YubiHSM2/Commands/Rewrap_Otp_Aead.html [Session Message]: https://developers.yubico.com/YubiHSM2/Commands/Session_Message.html [Set Log Index]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.set_log_index [Set Option]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.set_audit_option [Sign Attestation Certificate]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_attestation_certificate [Sign ECDSA]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_ecdsa [Sign EdDSA]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_ed25519 [Sign HMAC]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_hmac [Sign PKCS1]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_rsa_pkcs1v15_sha256 [Sign PSS]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_rsa_pss_sha256 [Sign SSH Certificate]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.sign_ssh_certificate [Unwrap Data]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.unwrap_data [Verify HMAC]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.verify_hmac [Wrap Data]: https://docs.rs/yubihsm/latest/yubihsm/client/struct.Client.html#method.wrap_data