Class YubiHsmAuthSession
- Namespace
- Yubico.YubiKey.YubiHsmAuth
- Assembly
- Yubico.YubiKey.dll
The main entry-point for all YubiHSM Auth related operations.
public sealed class YubiHsmAuthSession : ApplicationSession
- Inheritance
-
objectYubiHsmAuthSession
- Inherited Members
Constructors
YubiHsmAuthSession(IYubiKeyDevice, ScpKeyParameters?)
Create an instance of YubiHsmAuthSession
class, the object
that represents the YubiHSM Auth application on the YubiKey.
public YubiHsmAuthSession(IYubiKeyDevice yubiKey, ScpKeyParameters? keyParameters = null)
Parameters
yubiKey
IYubiKeyDeviceThe object that represents the actual YubiKey which will perform the operations.
keyParameters
ScpKeyParametersIf supplied, the parameters used open the SCP connection.
Remarks
The YubiHSM Auth application is available in YubiKey firmware version 5.4.3 and later. You can check if the application is available by using HasFeature(IYubiKeyDevice, YubiKeyFeature), and see if it's enabled over the desired interface by checking EnabledUsbCapabilities or EnabledNfcCapabilities.
Because this class implements IDisposable
, use the
using
keyword. For example,
IYubiKeyDevice yubiKeyToUse = SelectYubiKey();
using (var yubiHsmAuth = new YubiHsmAuthSession(yubiKeyToUse))
{
/* Perform YubiHSM Auth operations. */
}
Exceptions
- ArgumentNullException
The
yubiKey
argument is null.- NotSupportedException
Failed to connect to the YubiHSM Auth application.
Properties
KeyCollector
The delegate this class will call when it needs a management key or credential password.
public Func<KeyEntryData, bool>? KeyCollector { get; set; }
Property Value
- Func<KeyEntryData, bool>
Remarks
The delegate provided will read the KeyEntryData which
contains the information needed to determine what to collect and
methods to submit what was collected. The delegate will return
true
for success or false
for "cancel". Cancellation
usually happens when the user has clicked a "Cancel" button. That is
often the case when the user has entered the wrong value a number of
times, and they would like to stop trying before the application is
blocked.
Note that the SDK will call the KeyCollector
with a
Request of
Release when the process completes. In
this case, the KeyCollector
MUST NOT throw an exception. The
Release
is called from inside a finally
block, and it
is a bad idea to throw exceptions from inside finally
.
Methods
AddCredential(ReadOnlyMemory<byte>, CredentialWithSecrets)
Add a credential.
public void AddCredential(ReadOnlyMemory<byte> managementKey, CredentialWithSecrets credentialWithSecrets)
Parameters
managementKey
ReadOnlyMemory<byte>The secret used to authenticate to the application prior to adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength).
credentialWithSecrets
CredentialWithSecretsThe credential to be added.
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- InvalidOperationException
Either a credential with that label already exists, or there is no space to add the credential.
- SecurityException
Authentication with the management key failed.
ChangeManagementKey(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>)
Change the management key, throw an exception if the operation failed.
public void ChangeManagementKey(ReadOnlyMemory<byte> currentManagementKey, ReadOnlyMemory<byte> newManagementKey)
Parameters
currentManagementKey
ReadOnlyMemory<byte>The current value of the management key. It must be exactly 16 bytes long (see ValidManagementKeyLength). The default value is all zeros.
newManagementKey
ReadOnlyMemory<byte>The new value of the management key. It must be exactly 16 bytes long (see ValidManagementKeyLength).
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- SecurityException
The
currentManagementKey
was incorrect.
DeleteCredential(ReadOnlyMemory<byte>, string)
Remove a credential.
public void DeleteCredential(ReadOnlyMemory<byte> managementKey, string label)
Parameters
managementKey
ReadOnlyMemory<byte>The secret used to authenticate to the application prior to adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength).
label
stringThe label of the credential to be deleted. The string must meet the same requirements as Label.
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- InvalidOperationException
The credential was not found.
- SecurityException
Authentication with the management key failed.
GetAes128SessionKeys(string, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>)
Calculate session keys from an AES-128 credential. These session keys are used to establish a secure session with a YubiHSM 2 device.
public SessionKeys GetAes128SessionKeys(string credentialLabel, ReadOnlyMemory<byte> credentialPassword, ReadOnlyMemory<byte> hostChallenge, ReadOnlyMemory<byte> hsmDeviceChallenge)
Parameters
credentialLabel
stringThe label of the credential for calculating the session keys. The string must meet the same requirements as Label.
credentialPassword
ReadOnlyMemory<byte>The password of the credential for calculating the session keys. It must meet the same requirements as CredentialPassword.
hostChallenge
ReadOnlyMemory<byte>The 8 byte challenge generated by the host.
hsmDeviceChallenge
ReadOnlyMemory<byte>The 8 byte challenge generated by the YubiHSM 2 device.
Returns
- SessionKeys
Session keys are used to establish an encrypted and authenticated session with a YubiHSM 2 device. The secure session is based on the Global Platform Secure Channel Protocol '03' (SCP03).
Remarks
Some steps must be performed prior to calling this command. First, generate an 8-byte "host challenge" using a random or pseudorandom method. Next, send the host challenge to the YubiHSM 2 device using the yh_begin_create_session_ext method of the libyubihsm library, where the YubiHSM 2 device responds with an 8-byte "HSM device challenge". Both of these challenges are then used to construct this command.
There is a limit of 8 attempts to authenticate with the credential's password before the credential is deleted. Once the credential is deleted, it cannot be recovered. Supplying the correct password before the credential is deleted will reset the retry counter to 8.
If the credential requires touch (see TouchRequired), then the user must also touch the YubiKey as part of the authentication procedure. A System.TimeoutException will be thrown if touch is not supplied in time.
The secure session protocol is based on Secure Channel Protocol 3 (SCP03). The session keys returned by the application are the Session Secure Channel Encryption Key (S-ENC), Secure Channel Message Authentication Code Key for Command (S-MAC), and Secure Channel Message Authentication Code Key for Response (S-RMAC). These session-specific keys are used to encrypt and authenticate commands and responses with a YubiHSM 2 device during a single session. The session keys are discarded afterwards.
Exceptions
- InvalidOperationException
The credential could not be found.
- SecurityException
The credential password was incorrect, or touch was required but not supplied.
- TimeoutException
The operation timed out waiting for touch.
GetApplicationVersion()
Get the version of the YubiHSM Auth application.
public ApplicationVersion GetApplicationVersion()
Returns
- ApplicationVersion
The application version as a major, minor, and patch value.
Exceptions
- InvalidOperationException
The command to get the application version failed.
GetManagementKeyRetries()
Get the number of retries remaining for the management key.
public int GetManagementKeyRetries()
Returns
- int
The number of retries, as an integer.
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- InvalidOperationException
The command to retrieve the number of retries failed.
ListCredentials()
Get the public properties of all Credentials in the YubiHSM Auth application, along with the number of retries remaining for each.
public IReadOnlyList<CredentialRetryPair> ListCredentials()
Returns
- IReadOnlyList<CredentialRetryPair>
A list of credentials and the number of retries remaining for each credential's password.
Exceptions
- InvalidOperationException
Failed to retrieve the list of credentials present in the application.
ResetApplication()
Reset the YubiHSM Auth application, which will delete all credentials, reset the management key to its default value (all zeros), and reset the management key retry counter to 8.
public void ResetApplication()
Exceptions
- InvalidOperationException
The command to reset the application failed.
TryAddCredential(ReadOnlyMemory<byte>, CredentialWithSecrets, out int?)
Add a credential.
public bool TryAddCredential(ReadOnlyMemory<byte> managementKey, CredentialWithSecrets credentialWithSecrets, out int? managementKeyRetries)
Parameters
managementKey
ReadOnlyMemory<byte>The secret used to authenticate to the application prior to adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength).
credentialWithSecrets
CredentialWithSecretsThe credential to be added.
managementKeyRetries
int?When the command fails to authenticate the management key, this value gives the number of retries remaining.
Returns
- bool
True, when the credential has been added successfully. False, when authentication with the management key failed. When this method returns false,
managementKeyRetries
gives the number of retries remaining to authenticate with the management key.
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- InvalidOperationException
Either a credential with that label already exists, or there is no space to add the credential.
TryAddCredential(CredentialWithSecrets)
Add a credential. This method uses the KeyCollector to retrieve the management key and will retry authentication while there are retries remaining.
public bool TryAddCredential(CredentialWithSecrets credentialWithSecrets)
Parameters
credentialWithSecrets
CredentialWithSecretsThe credential to be added.
Returns
- bool
True
when the credential was successfully added.False
when theKeyCollector
returnsfalse
(usually indicating user cancellation).
Remarks
Compared to TryAddCredential(ReadOnlyMemory<byte>, CredentialWithSecrets, out int?) and AddCredential(ReadOnlyMemory<byte>, CredentialWithSecrets) which only attempt authentication once, this method automatically retries authentication while there are retries remaining.
The management key is used to authenticate to the application prior to operations such as adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength). There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
When the management key is needed, the KeyCollector is
called with Request set to
AuthenticateYubiHsmAuthManagementKey.
The KeyCollector
gets the management key from the user,
saves it using SubmitValue(ReadOnlySpan<byte>),
and returns true
. If the command succeeds (the credential is
removed), this method returns true
.
If authentication fails and there are retries remaining, the
KeyCollector
will be called again with the same Request
,
but IsRetry will be true
and
RetriesRemaining will be set appropriately.
When there are no retries remaining, a System.Security.SecurityException
will be thrown.
The only time this method returns false
is when the
KeyCollector
cancels the operation by returning false
.
Cancellation usually happens when the user has clicked a "Cancel"
button.
In all situations, when this method ends, it will tell the
KeyCollector
it is done by calling it with the Request
set to Release.
TryChangeManagementKey()
Change the management key, using the KeyCollector to retrieve the current and new management keys.
public bool TryChangeManagementKey()
Returns
- bool
True
, when the management key has been changed successfully.False
when theKeyCollector
returnsfalse
(usually indicating user cancellation).
Remarks
Compared to TryChangeManagementKey(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, out int?) which only attempts authentication once, this method automatically retries authentication while there are retries remaining.
The management key is 16 bytes long, and is required when performing operations that add or delete credentials ( AddCredentialCommand and DeleteCredentialCommand, respectively).
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
When the current and new management keys are needed, the
KeyCollector is called with Request
set to ChangeYubiHsmAuthManagementKey.
The KeyCollector
gets the current and new management keys from the
user, saves them using
SubmitValues(ReadOnlySpan<byte>, ReadOnlySpan<byte>),
and returns true
. Each key must be exactly 16 bytes long (see
ValidManagementKeyLength). If the
command succeeds (the management key is changed), this method returns
true
.
If authentication with the current management key fails and there are
retries remaining, the KeyCollector
will be called again with
the same Request
, but IsRetry will
be true
and RetriesRemaining will be
set appropriately. When there are no retries remaining, a
System.Security.SecurityException will be thrown.
The only time this method returns false
is when the
KeyCollector
cancels the operation by returning false
.
Cancellation usually happens when the user has clicked a "Cancel"
button.
In all situations, when this method ends, it will tell the
KeyCollector
it is done by calling it with the Request
set to Release.
Exceptions
- SecurityException
Authentication failed and there are no retries remaining.
- InvalidOperationException
A key collector was not supplied (KeyCollector was null).
- ArgumentException
Thrown when a management key has an invalid length.
TryChangeManagementKey(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, out int?)
Change the management key.
public bool TryChangeManagementKey(ReadOnlyMemory<byte> currentManagementKey, ReadOnlyMemory<byte> newManagementKey, out int? retriesRemaining)
Parameters
currentManagementKey
ReadOnlyMemory<byte>The current value of the management key. It must be exactly 16 bytes long (see ValidManagementKeyLength). The default value is all zeros.
newManagementKey
ReadOnlyMemory<byte>The new value of the management key. It must be exactly 16 bytes long (see ValidManagementKeyLength).
retriesRemaining
int?When the command fails to authenticate the management key, this value gives the number of retries remaining.
Returns
- bool
True, when the management key has been changed successfully. False, when authentication failed and the management key was not changed. When this method returns false,
retriesRemaining
gives the number of retries remaining to authenticate with the management key.
Remarks
The management key is 16 bytes long, and is required when performing operations that add or delete credentials ( AddCredentialCommand and DeleteCredentialCommand, respectively).
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
The caller is responsible for controlling the buffers which hold the management keys and should overwrite the data after the command is sent. The user's manual entry "Sensitive Data" has further details and recommendations for handling this kind of data.
Exceptions
- ArgumentException
Thrown when a management key has an invalid length.
TryDeleteCredential(ReadOnlyMemory<byte>, string, out int?)
Remove a credential.
public bool TryDeleteCredential(ReadOnlyMemory<byte> managementKey, string label, out int? managementKeyRetries)
Parameters
managementKey
ReadOnlyMemory<byte>The secret used to authenticate to the application prior to adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength).
label
stringThe label of the credential to be deleted. The string must meet the same requirements as Label.
managementKeyRetries
int?When the command fails to authenticate the management key, this value gives the number of retries remaining.
Returns
- bool
Remarks
There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
Exceptions
- InvalidOperationException
The credential was not found.
TryDeleteCredential(string)
Remove a credential. This method uses the KeyCollector to retrieve the management key, and will retry authentication while there are retries remaining.
public bool TryDeleteCredential(string label)
Parameters
label
stringThe label of the credential to be deleted. The string must meet the same requirements as Label.
Returns
- bool
True
when the credential was successfully removed.False
when theKeyCollector
returnsfalse
(usually indicating user cancellation).
Remarks
Compared to TryDeleteCredential(ReadOnlyMemory<byte>, string, out int?) and DeleteCredential(ReadOnlyMemory<byte>, string) which only attempt authentication once, this method automatically retries authentication while there are retries remaining.
The management key is used to authenticate to the application prior to operations such as adding or removing credentials. It must be exactly 16 bytes long (see ValidManagementKeyLength). There is a limit of 8 attempts to authenticate with the management key before the management key is blocked. Once the management key is blocked, the application must be reset before performing operations which require authentication with the management key (such as adding credentials, deleting credentials, and changing the management key). To reset the application, see ResetApplication(). Supplying the correct management key before the management key is blocked will reset the retry counter to 8.
When the management key is needed, the KeyCollector is
called with Request set to
AuthenticateYubiHsmAuthManagementKey.
The KeyCollector
gets the management key from the user,
saves it using SubmitValue(ReadOnlySpan<byte>),
and returns true
. If the command succeeds (the credential is
removed), this method returns true
.
If authentication fails and there are retries remaining, the
KeyCollector
will be called again with the same Request
,
but IsRetry will be true
and
RetriesRemaining will be set appropriately.
When there are no retries remaining, a System.Security.SecurityException
will be thrown.
The only time this method returns false
is when the
KeyCollector
cancels the operation by returning false
.
Cancellation usually happens when the user has clicked a "Cancel"
button.
In all situations, when this method ends, it will tell the
KeyCollector
it is done by calling it with the Request
set to Release.
Exceptions
- InvalidOperationException
The KeyCollector is
null
or the credential was not found.- SecurityException
Authentication failed and there are no retries remaining.
TryGetAes128SessionKeys(string, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, out SessionKeys?)
Calculate session keys from an AES-128 credential, using the KeyCollector to retrieve the credential password and prompt for touch when required. These session keys are used to establish a secure session with a YubiHSM 2 device.
public bool TryGetAes128SessionKeys(string credentialLabel, ReadOnlyMemory<byte> hostChallenge, ReadOnlyMemory<byte> hsmDeviceChallenge, out SessionKeys? sessionKeys)
Parameters
credentialLabel
stringThe label of the credential for calculating the session keys. The string must meet the same requirements as Label.
hostChallenge
ReadOnlyMemory<byte>The 8 byte challenge generated by the host.
hsmDeviceChallenge
ReadOnlyMemory<byte>The 8 byte challenge generated by the YubiHSM 2 device.
sessionKeys
SessionKeysSession keys are used to establish an encrypted and authenticated session with a YubiHSM 2 device. The secure session is based on the Global Platform Secure Channel Protocol '03' (SCP03).
Returns
- bool
True
, when the management key has been changed successfully.False
when theKeyCollector
returnsfalse
(usually indicating user cancellation).
Remarks
Some steps must be performed prior to calling this command. First, generate an 8-byte "host challenge" using a random or pseudorandom method. Next, send the host challenge to the YubiHSM 2 device using the yh_begin_create_session_ext method of the libyubihsm library, where the YubiHSM 2 device responds with an 8-byte "HSM device challenge". Both of these challenges are then used to construct this command.
There is a limit of 8 attempts to authenticate with the credential's password before the credential is deleted. Once the credential is deleted, it cannot be recovered. Supplying the correct password before the credential is deleted will reset the retry counter to 8.
When the credential password is needed, the KeyCollector
is called with Request set to
AuthenticateYubiHsmAuthCredentialPassword.
The KeyCollector
gets the credential password from the user,
stores it using SubmitValue(ReadOnlySpan<byte>),
and returns true
.
Next, if the credential requires touch (see
TouchRequired), the KeyCollector
is called with Request set to
TouchRequest. Typically, you will want
to react to this request by alerting your user that they need to
physically touch the YubiKey. Additionally, the return value will be
ignored. That is, it is not possible to cancel the operation once
this TouchRequest
is sent. Ideally, you should not block this
call. However, to ensure the proper function of the SDK, this request
will be issued on a separate thread from the one that originated this
call.
If the user does not touch the YubiKey in time, a System.TimeoutException will be thrown. Failing to touch the YubiKey does not change the credential's retry count.
The secure session protocol is based on Secure Channel Protocol 3 (SCP03). The session keys returned by the application are the Session Secure Channel Encryption Key (S-ENC), Secure Channel Message Authentication Code Key for Command (S-MAC), and Secure Channel Message Authentication Code Key for Response (S-RMAC). These session-specific keys are used to encrypt and authenticate commands and responses with a YubiHSM 2 device during a single session. The session keys are discarded afterwards.
Exceptions
- InvalidOperationException
The credential could not be found.
- TimeoutException
The operation timed out waiting for touch.