# Hardware Key Usage

LicenseSpring allows users to bind licenses to a YubiKey hardware key dongle.

### Prerequisites

Make sure to set up a YubiKey on the LicenseSpring platform and the LicenseSpring Provisioning Application for Desktop. See [**Hardware Key Licensing**](https://docs.licensespring.com/sdks/tutorials/advanced-usage/broken-reference) for instructions.

#### C++ Platform-specific Library Placement

Since **C++ SDK v7.37.0**, we provide both LicenseSpring SDK libs that do link, and that don't link to [**libykpiv**](https://developers.yubico.com/yubico-piv-tool/). All samples also have multiple configurations, with and without linking to `libykpiv`.

* **Linux & macOS**
  * Shared libraries are located in `bin/shared_HardwareKey`
  * Static libraries are located in `bin/static_HardwareKey`
  * Note: The existing `bin/shared` and `bin/static` folders remain unchanged and do not link to `libykpiv`.
* **Linux ARM (i.e. ARM without hf support), ppc64le**
  * SDK builds targeting arm and ppc64le architectures do not link tl `libykpiv` (no hardware key support).
* **MSVC (Windows)**
  * Dynamic libraries are located in `bin/dynamic_HardwareKey`
  * Static linking to `libykpiv` is **not supported**.
  * The existing `bin/dynamic` folder remains unchanged and does not link to `libykpiv`.
* **MinGW**
  * We currently don't support hardware

{% hint style="info" %}
The `libykpiv` library has an external dependency which should be installed on user machines:

• Linux uses the pcsc backend (via pcsclite) to manage the YubiKey,\
• macOS uses the macscard backend (Apple’s built‑in PC/SC layer, pcsclite daemon),\
• Windows (MSVC targets) uses the winscard backend (Microsoft’s WinSCard API).
{% endhint %}

#### Usage samples

{% tabs %}
{% tab title="C++" %}

```cpp
#include <LicenseSpring/Configuration.h>
#include <LicenseSpring/ExtendedOptions.h>

// ...

// the following function returns an std::vector of all plugged YubiKeys' serials.
auto serials = LicenseSpring::HardwareKeyOptions::ListAvailableKeys();
if (!serials.empty()) {
    HardwareKeyOptions hwKeyOptions;
    hwKeyOptions.setTargetSerial(serials[0]); // query the user for the correct serial
    hwKeyOptions.setPin("123456"); // query the user for the pin

    ExtendedOptions options;
    options.setHardwareKeyOptions(hwKeyOptions);
}
```

{% endtab %}

{% tab title="Java" %}

```java
IdentityProvider identityProvider = config.getIdentityProvider();
String key = identityProvider.getKey();
```

{% endtab %}

{% tab title="C#" %}

```csharp
// the following function returns a list of all plugged YubiKeys' serials.
List<string> serials = LicenseSpring.HardwareKeyOptions.ListAvailableKeys();
if (serials.Count != 0)
{
    // query the user for the correct serial
    string serialNumber = serials.First();
    // query the user for the correct pin
    string pin = "123456"; 
    
    LicenseSpring.HardwareKeyOptions hardwareKeyOptions = new LicenseSpring.HardwareKeyOptions(serialNumber, pin);
    LicenseSpring.Configuration configuration = new LicenseSpring.Configuration();
}
```

{% endtab %}
{% endtabs %}

Calling `ExtendedOptions::setHardwareKeyOptions` automatically sets the machine hardware ID to the serial of the Yubikey.

Afterwards, all calls to the License API require that YubiKey to be plugged in, and `License::localCheck` will throw an appropriate `LicenseSpring::HardwareKeyException` exception in case the YubiKey is not plugged in.
