Table of Contents

Class ChangeReferenceDataCommand

Namespace
Yubico.YubiKey.Piv.Commands
Assembly
Yubico.YubiKey.dll

Change the PIN or PUK.

public sealed class ChangeReferenceDataCommand : IYubiKeyCommand<ChangeReferenceDataResponse>
Inheritance
object
ChangeReferenceDataCommand
Implements

Remarks

The partner Response class is ChangeReferenceDataResponse.

The PIN starts out as a default value: "123456", which in ASCII is the 6-byte sequence 0x31 32 33 34 35 36. The PUK (PIN Unblocking Key) starts out as a default value as well: "12345678", which in ASCII is the 8-byte sequence 0x31 32 33 34 35 36 37 38. Generally, the first thing done when a YubiKey is initialized for PIV is to change the PIN and PUK (along with the management key). The PIN and PUK are both allowed to be 6 to 8 characters/bytes. The PIN can be any ASCII character. For YubiKeys with firmware versions prior to 5.7, the PUK is allowed to be any character in the 0x00 - 0xFF range for a total length of 6-8 bytes. For YubiKeys with firmware version 5.7 and above, the PUK is allowed to be any character in the 0x00 - 0x7F range for a total length of 6-8 Unicode code points. Since the PIN and PUK are generally input from a keyboard, they are usually made up of ASCII characters.

When you pass a PIN or PUK to this class (the PIN or PUK to change, along with the new value), the class will copy a reference to the object passed in, it will not copy the value. Because of this, you cannot overwrite the PIN until this object is done with it. It will be safe to overwrite the PIN after calling connection.SendCommand. See the User's Manual entry on sensitive data for more information on this topic.

Example:

using System.Security.Cryptography;
/* This example assumes the application has a method to collect a
 * PIN/PUK.
 */
byte[] oldPuk;
byte[] newPuk;

IYubiKeyConnection connection = key.Connect(YubiKeyApplication.Piv);
oldPuk = CollectPuk();
newPuk = CollectNewPuk();
var changeReferenceDataCommand =
    new ChangeReferenceDataCommand(PivSlot.Puk, oldPuk, newPuk);
ChangeReferenceDataResponse changeReferenceDataResponse =
    connection.SendCommand(changeReferenceDataCommand);
if (changeReferenceDataResponse.Status != ResponseStatus.Success)
{
  if (resetRetryResponse.Status == ResponseStatus.AuthenticationRequired)
  {
      int retryCount = resetRetryResponse.GetData();
      /* report the retry count */
  }
  else
  {
      // Handle error
  }
}

CryptographicOperations.ZeroMemory(puk);
CryptographicOperations.ZeroMemory(newPuk);

Note: YubiKey Bio Multi-protocol Edition (MPE) keys do not have a PUK.

Constructors

ChangeReferenceDataCommand(byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>)

Build a new Command object to "change reference data", which means to change a PIN or PUK.

public ChangeReferenceDataCommand(byte slotNumber, ReadOnlyMemory<byte> currentValue, ReadOnlyMemory<byte> newValue)

Parameters

slotNumber byte

Which element to change, the PIN or PUK. Use PivSlot.Pin or PivSlot.Puk

currentValue ReadOnlyMemory<byte>

The current PIN or PUK, the value to change.

newValue ReadOnlyMemory<byte>

The new PIN or PUK.

Remarks

In order to change a PIN or PUK, the caller must supply the old and new PIN or PUK. In this class, the PINs and PUKs are supplied as ReadOnlyMemory<byte>. It is possible to pass a byte[], because it will be automatically cast.

This class will copy references to the PINs and PUKs (not the values). This means that you can overwrite the PIN or PUK in your byte array only after this class is done with it. It will no longer need the PIN or PUK after calling connection.SendCommand.

The PIN and PUK are both allowed to be 6 to 8 characters/bytes. The PIN can be any ASCII character. For YubiKeys with firmware versions prior to 5.7, the PUK is allowed to be any character in the 0x00 - 0xFF range for a total length of 6-8 bytes. For YubiKeys with firmware version 5.7 and above, the PUK is allowed to be any character in the 0x00 - 0x7F range for a total length of 6-8 Unicode code points.

Exceptions

ArgumentException

The PIN or PUK is an incorrect length.

Properties

Application

Gets the YubiKeyApplication to which this command belongs. For this command it's PIV.

public YubiKeyApplication Application { get; }

Property Value

YubiKeyApplication

YubiKeyApplication.Piv

SlotNumber

The slot for the PIN or PUK.

public byte SlotNumber { get; set; }

Property Value

byte

The slot number, see PivSlot

Exceptions

ArgumentException

The slot specified is not valid for changing reference data.

Methods

CreateCommandApdu()

Creates a well-formed CommandApdu to send to the YubiKey.

public CommandApdu CreateCommandApdu()

Returns

CommandApdu

A valid CommandApdu that is ready to be sent to the YubiKey, or passed along to additional encoders for further processing.

Remarks

This method will first perform validation on all of the parameters and data provided to it. The CommandAPDU it creates should contain all of the data payload for the command, even if it exceeds 65,535 bytes as specified by the ISO 7816-4 specification. The APDU will be properly chained by the device connection prior to being sent to the YubiKey, and the responses will collapsed into a single result.

CreateResponseForApdu(ResponseApdu)

Creates the corresponding IYubiKeyResponse implementation for the current command.

public ChangeReferenceDataResponse CreateResponseForApdu(ResponseApdu responseApdu)

Parameters

responseApdu ResponseApdu

The ResponseApdu returned by the YubiKey.

Returns

ChangeReferenceDataResponse

The implementation of IYubiKeyResponse that parses and presents ths response APDU.