Show / Hide Table of Contents

FIDO2 credential management

The credential management operations allow you to obtain information about the credentials on a YubiKey without getting an assertion. Note that you can get information only for discoverable credentials. Remember that to make a credential discoverable, when you make it (see MakeCredential), set the "rk" option to true

    var makeCredentialParameters = new MakeCredentialParameters(relyingParty, userEntity)
    {
        ClientDataHash = clientDataHash,
    };
    makeCredParams.AddOption(AuthenticatorOptions.rk, true);
    MakeCredentialData credentialData = fido2Session.MakeCredential(makeCredentialParameters);

These are the credential management operations:

  • Get Metadata
  • Enumerate Relying Parties
  • Enumerate Credentials
  • Delete Credential
  • Update User Information

Support in the YubiKey

Not all YubiKeys support CredentialManagement. To find out if a particular YubiKey can perform these operations, check for the "credMgmt" options.

    using (fido2Session = new Fido2Session(yubiKeyDevice))
    {
        if (fido2Session.AuthenticatorInfo.GetOptionValue("credMgmt") == OptionValue.True)
        {
            . . .
        }
    }

Commands and Fido2Session methods

In the SDK, there are two ways to perform a CredentialManagement operation:

  • Commands
  • Fido2Session methods

The commands are

  • GetCredentialMetadataCommand
  • EnumerateRpsBeginCommand
  • EnumerateRpsGetNextCommand
  • EnumerateCredentialsBeginCommand
  • EnumerateCredentialsGetNextCommand
  • DeleteCredentialCommand
  • UpdateUserInfoCommand

Some of the commands require a PinToken. You will be responsible for building a PinToken (see next section).

The Fido2Session methods are

  • GetCredentialMetadata
  • EnumerateRelyingParties
  • EnumerateCredentialsForRelyingParty
  • DeleteCredential
  • UpdateUserInfoForCredential

If you use these methods, the SDK will build the proper PinToken if needed.

PIN/UV Auth Param

In order to perform some credential management operations, it is necessary to compute a PIN/UV Auth Param. The SDK will build the PIN/UV Auth Param, you do not need to supply it. The PIN/UV Auth Param is built using an AuthToken. If you use the Fido2Session methods, the SDK will also obtain the AuthToken.

See the User's Manual entry on AuthTokens for a detailed discussion on how they work.

Get metadata

This returns the number of discoverable credentials and the number of "empty" slots. For example, suppose the YubiKey has space for 25 credentials. Currently there are three discoverable credentials and two non-discoverable. The return from the credential management operation of get metadata would be 3 and 22. The number of remaining credential count of 22 means that it is possible to store 22 more discoverable credentials. The YubiKey stores no information on non-discoverable credentials, so the two non-discoverable credentials in this example have no effect on the number of spaces available. See also the User's Manual entry on credentials for more information on non-discoverable credentials.

The return is a Tuple of 2 integers:

    (int residentCredentialCount, int remainingCredentialCount) = fido2Session.GetCredentialMetadata();

    // In the example above, residentCredentialCount would be 3 and
    // remainingCredentialCount would be 22.

Enumerate relying parties

This helps you to build a list of all the relying parties represented among all the credentials on the YubiKey.

If you use Fido2Session.EnumerateRelyingParties, the SDK will return an array of RelyingParty objects.

If you use the commands, you will need to use the EnumerateRpsBeginCommand command to obtain the first relying party and the total count of relying parties represented, and then the EnumerateRpsGetNextCommand to get each successive relying party.

    var enumBeginCmd = new EnumerateRpsBeginCommand(pinToken, protocol);
    EnumerateRpsBeginResponse enumBeginRsp = connection.SendCommand(enumBeginCmd);

    (int rpCount, RelyingParty firstRp) = enumBeginRsp.GetData();

    for (int index = 1; index < rpCount; index++)
    {
        var getNextCmd = new EnumerateRpsGetNextCommand();
        EnumerateRpsGetNextResponse credMgmtRsp = connection.SendCommand(getNextCmd);
        RelyingParty nextRp = getNextRsp.GetData();
    }

Enumerate credentials

This helps you to build a list of all the credentials on the YubiKey.

If you use Fido2Session.EnumerateCredentialsForRelyingParty, the SDK will return an array of CredentialUserInfo objects, each one containing the User, CredentialId, CredentialPublicKey, CredProtectPolicy, and the LargeBlobKey (if there is one) for each credential found on the YubiKey associated with the specified relying party. You specify which relying party you are interested in by supplying the RelyingParty object, which you likely retrieved during a call to obtain a list of relying parties.

If you use the commands, you will need to use the EnumerateCredentialsBeginCommand command to obtain the first credential and the total count of credentials available, and then the EnumerateCredentialsGetNextCommand to get each successive credential.

    var enumBeginCmd = new EnumerateCredentialsBeginCommand(relyingParty.RelyingPartyIdHash, pinToken, protocol);
    EnumerateCredentialsBeginResponse enumBeginRsp = connection.SendCommand(enumBeginCmd);

    (int credCount, CredentialUserInfo userInfo) = enumBeginRsp.GetData();

    for (int index = 1; index < credCount; index++)
    {
        var getNextCmd = new EnumerateCredentialsGetNextCommand();
        EnumerateCredentialsGetNextResponse getNextRsp = connection.SendCommand(getNextCmd);
        userInfo = getNextRsp.GetData();
    }

Delete credential

This allows you to remove one credential from the YubiKey.

Whether you use the command or the Fido2Session method, you must supply the CredentialId. This tells the YubiKey which credential to remove. You will likely use the Enumerate commands or the Fido2Session.EnumerateCredentialsForRelyingParty method to obtain a list of CredentialUserInfo objects, and choose the credential to delete from that list. Finally, you can use the CredentialId property in the object as the input to the delete call.

This operation needs the PIN/UV Auth Param.

It is possible that there is some large blob data stored against the credential you are deleting. If so, you will likely want to delete that data as well. If you use the commands to delete, it is your responsibility to delete the large blob data. The Fido2Session method will delete it for you.

Update user information

Each credential contains user information, represented as an instance of the UserEntity class. You can change what user information is stored on the YubiKey in that credential.

The way to change the user information is to create a new UserEntity object, and then call the command or the Fido2Session method. This replaces the information on the YubiKey, it does not "edit" it.

For example,

    // Find the relying party of interest by enumerating all RPs and selecting from the list.
    IReadOnlyList<RelyingParty> rpList = fido2Session.EnumerateRelyingParties();
    int index = ChooseRelyingParty(rpList);

    // Find the credential of interest by enumerating all the credentials associated with
    // the relying party of intereset and selecting from the list.
    IReadOnlyList<CredentialUserInfo> credList =
        fido2Session.EnumerateCredentialsForRelyingParty(rpList[index]);
    index = ChooseCredential(credList);

    // Create a new UserEntity based on the current.
    var updatedUserInfo = new UserEntity(credArray[index].User.Id)
    {
        Name = credArray[index].User.Name,
        DisplayName = "Jane Doe",
    };

    fido2Session.UpdateUserInfoForCredential(credArray[index].CredentialId, updatedUserInfo);

Suppose the original user information was the following:

  • Id = 0x3A 67 ... E9
  • Name = jdoe
  • DisplayName = J Doe

In the sample, the display name was changed to "Jane Doe". It built a new UserEntity object with the following:

  • Id = 0x3A 67 ... E9
  • Name = jdoe
  • DisplayName = Jane Doe

Then it called the update method.

If it had supplied a UserEntity object with only the display name (because that is all it needed to change), then after the update, the YubiKey would have contained an entry for a user with no Id and no Name, just a DisplayName.

You must supply all the user information in the updated object. That is, the object you provide as the update must include all the info that does not change as well as the info that does.

  • Improve this Doc
In this article
Back to top Generated by DocFX