Table of Contents

Class KeyEntryData

Namespace
Yubico.YubiKey
Assembly
Yubico.YubiKey.dll

This class contains methods and data that describe the state of the process to provide keys, PINs, and other sensitive data to the SDK.

public sealed class KeyEntryData
Inheritance
object
KeyEntryData

Remarks

At times, the SDK will need the caller to provide keys, PINs, or other sensitive data. Generally, this will be done through a delegate (callback). The caller provides a method the SDK can call requesting the key, PIN, or whatever element is needed. This method will take as an argument an instance of this KeyEntryData class.

When the SDK calls the delegate, it will pass an instance of this class, which contains information the method can use to perform its operations. For example, the SDK, when calling the delegate, must describe what element it is requesting, and whether this is the first request, or a subsequent request because the previous data returned did not verify.

Constructors

KeyEntryData()

Create a new instance of the KeyEntryData class.

public KeyEntryData()

Remarks

Note that this class can contain sensitive data and it is a good idea to call the Clear method when done with it. The Clear is not called automatically, because this class does not implement IDisposable. Hence, if your code creates an instance of this class, you should make sure to call Clear as soon as possible.

Properties

IsRetry

Indicates if the current request for an item has already been tried and was incorrect. That is, is the current request the initial request or did a previous attempt fail and the SDK is requesting the KeyCollector try again? If true, the request is for a retry, if false, the request is the initial attempt.

public bool IsRetry { get; set; }

Property Value

bool

Remarks

Note that enrolling a fingerprint generally requires several samples, and each sample is not a retry, but rather more information the YubiKey uses to build a template. Hence, after each fingerprint sample, this property will not be true, even if the previous sample was considered a failure. Rather, look at the LastBioEnrollSampleResult property to get information about the previous attempt.

IsViolatingPinComplexity

Indicates if the current request for an item has violated PIN complexity.

public bool IsViolatingPinComplexity { get; set; }

Property Value

bool

LastBioEnrollSampleResult

This is the result of the last fingerprint sample. This will be null if the Request is for something other than EnrollFingerprint or if it is the first call to Enroll.

public BioEnrollSampleResult? LastBioEnrollSampleResult { get; set; }

Property Value

BioEnrollSampleResult

Remarks

When a caller wants to enroll a fingerprint, the SDK will call the KeyCollector with a Request of EnrollFingerprint. For the first call to the KeyCollector, there is no previous sample, so this will be null. For each subsequent call, the SDK will provide the result from the most recent sample. This includes the sample status (such as FpGood or FpPoorQuality), and the number of quality samples needed to complete the enrollment.

Your KeyCollector will have this information which you can pass on to the user. For example, one property in the BioEnrollSampleResult is the reason a fingerprint sample was not accepted. Letting the user know this reason could help them make a better sample next time.

Request

This indicates what the SDK is requesting.

public KeyEntryRequest Request { get; set; }

Property Value

KeyEntryRequest

Remarks

Note that a delegate MUST NEVER throw an exception if the Request is KeyEntryRequest.Release. The Release is called from inside a finally block, and it is a bad idea to throw exceptions from inside finally.

RetriesRemaining

This is the number of retries remaining before the element requested is blocked. This can be null if the element is one that is never blocked or the retries remaining count is not known yet because the KeyEntryData represents the initial request.

public int? RetriesRemaining { get; set; }

Property Value

int?

Remarks

For some elements there is a retry count. It is the number of times in a row a wrong value can be entered for verification before the element is blocked. Other elements have no limitation. For example, the PIV PIN starts out with a retry count of 3 (this count can be changed). If you try to verify the PIN but enter the wrong value, the retries remaining will be decremented to 2. Verify using the correct PIN and the retries remaining returns to 3. If it is decremented to 0, the PIN is blocked, and the YubiKey PIV application will not be able to perform operations that require the PIN, even if the correct PIN is entered later. Restore the PIN using the PUK.

There are some elements that have no limit. For example, the PIV management key is a triple-DES key, and you can try and fail to authenticate that key as many times as you want and it will never be blocked.

This property starts out as null because the number of retries remaining is not known until the YubiKey is contacted. If an attempt to verify an element that has a retry count is made, and the value is incorrect, the YubiKey will report the number of retries remaining. If that happens, this property will be set with the number.

If the correct value is given, the YubiKey will not report the retries remaining. If that happens, this property will be set to null.

If the item requested has no limited retry count, this will be null, even if a previous attempt made to authenticate it had failed.

If the item requested has a limited retry count, and this is a call to get the item after a previous call failed, and this number is 0, that means the item is blocked.

If the element requested is one that has a retry account, and this is not null, then you know the request is a "retry", that the previous attempt failed. There is another property, isRetry, that specifically indicates if the call is a retry or not, and it is valid for all elements, those that have a retry count and those that do not. So you will likely use that property to determine if a request is a retry or not.

SignalUserCancel

For some operations, this property is an implementation of a delegate the KeyCollector can call to indicate the user is canceling the operation. If it is null, report cancellation normally, by having the KeyCollector return false. If it is not null, use the supplied delegate to report user cancellation.

public SignalUserCancel? SignalUserCancel { get; }

Property Value

SignalUserCancel

Remarks

Currently this is valid only when the Request is either TouchRequest, EnrollFingerprint, or VerifyFido2Uv. For all other requests, this will be null.

The normal way to indicate that a user is canceling an operation is to have the KeyCollector return false. However, for some operations, such as Touch and Fingerprint, the KeyCollector is called on a separate thread and the return is ignored. That is, it is an asynchronous call. The main thread performing the YubiKey operation will not see the KeyCollector's return. Hence, to indicate user cancellation in these cases, this delegate is provided.

Your KeyCollector is called with an instance of this KeyEntryData class. If this property is not null, you can save this delegate. Later on, if the user cancels, you can call the delegate. If the YubiKey has not completed the operation or timed out by the time it receives notification of user cancellation, the SDK can cancel. Note that generally, user cancellation results in an OperationCanceledException.

Methods

Clear()

Clear any sensitive data in the object.

public void Clear()

GetCurrentValue()

Return a reference to the submitted current value.

public ReadOnlyMemory<byte> GetCurrentValue()

Returns

ReadOnlyMemory<byte>

A reference to the byte array that is the value requested.

Remarks

There are two possible values: a current and new. For many case, there will only be a current. But for some operations (such as changing a PIV PIN), there will be both. To get the current value (e.g. the PIN if verifying the PIN, or the current PIN if changing the PIN), call this method. If you want to get the new value, call the GetNewValue method.

Note that this method returns a reference to the value, which means that the actual data returned will be overwritten after the call to Clear.

GetNewValue()

Return a reference to the submitted new value.

public ReadOnlyMemory<byte> GetNewValue()

Returns

ReadOnlyMemory<byte>

A reference to the byte array that is the value requested.

Remarks

There are two possible values: a current and new. For many case, there will only be a current. But for some operations (such as changing a PIV PIN), there will be both. To get the new value (e.g. the new PIN if changing the PIN), call this method. If you want to get the current value, call the GetCurrentValue method.

Note that this method returns a reference to the value, which means that the actual data returned will be overwritten after the call to Clear.

SubmitValue(ReadOnlySpan<byte>)

Submit the requested value, when there is only one value to submit.

public void SubmitValue(ReadOnlySpan<byte> value)

Parameters

value ReadOnlySpan<byte>

The actual key, PIN, password, or whatever was requested.

Remarks

When the KeyCollector delegate obtains the value to return (the key, PIN, password, or whatever was requested), it calls this method to load it into the KeyEntryData object. The code that called the KeyCollector will be able to get the data returned using the GetCurrentValue method.

Note that the KeyEntryData object will copy the value passed in (it will not simply copy a reference). Therefore, it is safe to overwrite the data once SubmitValue has completed.

This method will store the value submitted as the current value.

SubmitValues(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Submit the requested values, when there are two values to submit. This is generally used when changing or resetting a value.

public void SubmitValues(ReadOnlySpan<byte> currentValue, ReadOnlySpan<byte> newValue)

Parameters

currentValue ReadOnlySpan<byte>

The current key, PIN, password, or whatever was requested.

newValue ReadOnlySpan<byte>

A new key, PIN, password, or whatever was requested.

Remarks

When the KeyCollector delegate obtains the values to return (both the current and new keys, PINs, passwords, or whatever was requested), it calls this method to load them into the KeyEntryData object. The code that called the KeyCollector will be able to get the data returned using the appropriate GetValue methods.

Note that the KeyEntryData object will copy the values passed in (it will not simply copy references). Therefore, it is safe to overwrite the data once SubmitValues has completed.

For example, suppose the PIV PIN is being changed. The SDK will call the KeyCollector with the Request of ChangePivPin. The KeyCollector will collect the current PIN and a new PIN, then call SubmitValues with both of those values.