Table of Contents

Class KeyHistory

Namespace
Yubico.YubiKey.Piv.Objects
Assembly
Yubico.YubiKey.dll

Use this class to process the Key History data.

public sealed class KeyHistory : PivDataObject
Inheritance
object
KeyHistory
Inherited Members

Remarks

A Key History consists of three values:

  • Number of keys with on-card certificates
  • Number of keys with off-card certificates
  • Off-card certificate URL (if off-card or on-card certs value is greater than zero)

The YubiKey will not automatically set the number of on-card certs value. For example, suppose you call the method ImportCertificate(byte, X509Certificate2, bool) for a slot that has no cert. There is now one more key with an on-card cert. However, the YubiKey will not increment the value in the Key History storage area. If you want the Key History to reflect the number of keys with certs on the card, you must set this data object yourself.

The Off-card certificate URL is where the off-card certs can be found. This should be set if the number of off-card certs is greater than zero. If there are no off-card certs, this is generally null. However, the PIV standard allows for a non-null URL if either or both the number of on-card and off-card certs is not zero. That is, if the number of off-card certs is zero, but the number of on-card certs is not zero, then it is permissible to have an off-card cert URL.

This class will not check to make sure the values you set for the numbers of certificates matches the YubiKey contents. For example, suppose you have a YubiKey with only four private keys. Hence, the maximum OnCardCertificates is four. But there is nothing stopping you from creating a KeyHistory object and setting OnCardCertificates to 20, 30, or even 255.

If you create an instance of KeyHistory, it will be empty (IsEmpty will be true). Once you set one of the properties (OnCardCertificates or OffCardCertificates), the object will no longer be empty, even if you set those values to zero. If a PivDataObject is empty, the PivSession.WriteObject method will not write anything to the YubiKey. If the Data Object is not empty, the WriteObject method will write to the YubiKey. So if you want to write a Key History to the YubiKey that contains the information that there are no certs and no URL, then create a new KeyHistory object, set one of the properties to zero, and call the Write method.

If you create a new KeyHistory object by calling the constructor directly, then set the properties and call PivSession.WriteObject, that will, of course, overwrite the Key History on the YubiKey, if there is one. Because that might not be something you want to do, this is the most dangerous option.

See also the user's manual entry on PIV data objects.

Constructors

KeyHistory()

Build a new object. This will not get the Key History from any YubiKey, it will only build an "empty" object.

public KeyHistory()

Remarks

To read the Key History data out of a YubiKey, call the ReadObject<T>() method.

Properties

OffCardCertificateUrl

The URL where the Off-Card Certificates can be found. If there are no On-Card or Off-Card Certs, it can only be set to null.

public Uri? OffCardCertificateUrl { get; set; }

Property Value

Uri

Remarks

This class will use the AbsoluteUri property of the Uri class. Furthermore, it will "convert" it to bytes by using the UTF8 encoding. That is, you will build the Uri object, and when this class builds the encoded KeyHistory, it will extract the AbsoluteUri property and convert it into a byte array made up of the UTF8 encoding for the off-card cert URL portion.

The PIV standard specifies that this value be made up of 118 bytes or fewer. If the UTF8 encoding of the AbsoluteUri is greater than 118, this class will throw an exception.

If this property is set to something other than null, and the OnCardCertificates and OffCardCertificates properties are both zero, a call to Encode will throw an exception.

OffCardCertificates

Number of Keys with Off-Card Certificates. If you set this to zero, and the OnCardCertificates property is also zero, the OffCardCertificateUrl property will automatically be set to null.

public byte OffCardCertificates { get; set; }

Property Value

byte

OnCardCertificates

Number of Keys with On-Card Certificates. If you set this to zero, and the OffCardCertificates property is also zero, the OffCardCertificateUrl property will automatically be set to null.

public byte OnCardCertificates { get; set; }

Property Value

byte

Methods

Dispose(bool)

Releases any unmanaged resources and overwrites any sensitive data.

protected override void Dispose(bool disposing)

Parameters

disposing bool

Encode()

Build the encoding of the data.

public override byte[] Encode()

Returns

byte[]

A new byte array containing the encoded data object.

Remarks

Each data object has a defined format. See the User's Manual entry on GET DATA and GET vendor data for descriptions of the formats. This method will build a new byte array containing the data set in the object. This data will generally then be stored on the YubiKey.

Note that this method returns a new byte array, not a reference to an array inside the object. If this array contains any sensitive data, make sure you overwrite it when done with it.

If the object is empty (IsEmpty is true), then this method will return the encoding of no data, which is 0x53 00.

GetDefinedDataTag()

Get the defined data tag. This is the data tag that the PIV standard or Yubico defines to specify the given data object.

public override int GetDefinedDataTag()

Returns

int

The data tag defined for the data object.

Remarks

This is also called the default data tag. This method will always return the defined tag, regardless of what the DataTag property returns. That is, even if you change the DataTag this method will still return the original, defined tag.

TryDecode(ReadOnlyMemory<byte>)

Try to decode the data given according to the format specified for the data object. If successful, return true, otherwise, return false.

public override bool TryDecode(ReadOnlyMemory<byte> encodedData)

Parameters

encodedData ReadOnlyMemory<byte>

The data to parse.

Returns

bool

A boolean, true if the method successfully decodes, false otherwise.

Remarks

This will parse the encoding and set local properties with the data. The encodedData generally was retrieved from the YubiKey.

This will replace any data in the object.

If there is no data (encodedData.Length is 0) this method will set the object to the empty state (IsEmpty will be true and the contents of any data properties will be meaningless) and return true.

If the input is not encoded as expected, this method will set the object to the empty state and return false. This includes the fixed values. That is, there are some values in some data objects that are fixed for every YubiKey, and this method will expect the contents of the encodedData to contain those fixed values.

If the input is encoded as expected, yet the data in that encoding is invalid (e.g. some element is not the correct length), this method will return false.

Exceptions

ArgumentException

The data is not properly encoded for the data object.