Class KeyHistory
Use this class to process the Key History data.
public sealed class KeyHistory : PivDataObject
- Inheritance
-
objectKeyHistory
- 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.
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.