Class PinUvAuthProtocolBase
- Namespace
- Yubico.YubiKey.Fido2.PinProtocols
- Assembly
- Yubico.YubiKey.dll
Base class for FIDO2 PIN/UV auth protocol implementations.
public abstract class PinUvAuthProtocolBase
- Inheritance
-
objectPinUvAuthProtocolBase
- Derived
Remarks
A PIN/UV auth protocol is a set of methods defined by the FIDO2 CTAP specification. The abstract interface is defined in section 6.5.4. As of FIDO 2.1, there are only two PIN protocols defined: protocol one and protocol two. These two implementations share some common code. The abstract interface as well as any shared code is defined by this class.
Properties
AuthenticationKey
Gets the authentication key derived from the shared value computed during the call to Encapsulate(CoseKey). This can be the same as the EncryptionKey.
public ReadOnlyMemory<byte>? AuthenticationKey { get; protected set; }
Property Value
- ReadOnlyMemory<byte>?
Remarks
This will be null until the Encapsulate method is
called.
AuthenticatorPublicKey
The public key returned by the YubiKey.
public CoseKey? AuthenticatorPublicKey { get; protected set; }
Property Value
Remarks
The caller will obtain the YubiKey's public key using the GetKeyAgreementCommand and pass it to the Encapsulate(CoseKey) method. A reference to the key passed into that method will be stored in this property.
A call to Initialize() will set this to null. That
is, a new public key must be obtained for each PIN/UV authentication
session with the YubiKey. Even if the new session is initiated with
the previously-used YubiKey, the public key must be obtained, because
the YubiKey might generate a new public key.
EncryptionKey
Gets the encryption key derived from the shared value computed during the call to Encapsulate(CoseKey). This can be the same as the AuthenticationKey.
public ReadOnlyMemory<byte>? EncryptionKey { get; protected set; }
Property Value
- ReadOnlyMemory<byte>?
Remarks
This will be null until the Encapsulate method is
called.
PlatformPublicKey
Gets the public key generated during the call to Encapsulate(CoseKey).
public CoseKey? PlatformPublicKey { get; protected set; }
Property Value
Remarks
This will be null until the Encapsulate method is
called.
Protocol
Gets the identifier of the PIN / UV authentication protocol that this instance implements.
public PinUvAuthProtocol Protocol { get; protected set; }
Property Value
Methods
Authenticate(byte[])
Returns the result of computing HMAC-SHA-256 on the given message using the AuthenticationKey. With protocol 1, the result is the first 16 bytes of the HMAC, and with protocol 2 it is the entire 32-byte result.
public abstract byte[] Authenticate(byte[] message)
Parameters
messagebyte[]The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Exceptions
- ArgumentNullException
The
messageargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
Authenticate(byte[], byte[])
Returns the result of computing HMAC-SHA-256 on the given message
using the provided keyData. With protocol 1, the result is the
first 16 bytes of the HMAC, and with protocol 2 it is the entire
32-byte result.
public abstract byte[] Authenticate(byte[] keyData, byte[] message)
Parameters
keyDatabyte[]The key to use to authenticate.
messagebyte[]The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Exceptions
- ArgumentNullException
The
keyDataormessageargument is null.
Authenticate(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>)
Returns the result of computing HMAC-SHA-256 on the given message
using the provided keyData. With protocol 1, the result is the
first 16 bytes of the HMAC, and with protocol 2 it is the entire
32-byte result.
public abstract byte[] Authenticate(ReadOnlyMemory<byte> keyData, ReadOnlyMemory<byte> message)
Parameters
keyDataReadOnlyMemory<byte>The key to use to authenticate.
messageReadOnlyMemory<byte>The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Exceptions
- ArgumentNullException
The
keyDataormessageargument is null.
AuthenticateUsingPinToken(byte[], byte[])
Returns the result of computing HMAC-SHA-256 on the given message
using the pinToken as the key. With protocol 1, the result is
the first 16 bytes of the HMAC, and with protocol 2 it is the entire
32-byte result.
public byte[] AuthenticateUsingPinToken(byte[] pinToken, byte[] message)
Parameters
pinTokenbyte[]The PIN token returned by the YubiKey. This is the encrypted value, do not decrypt it.
messagebyte[]The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Remarks
It is possible to obtain the PIN token by calling the command GetPinTokenCommand. The YubiKey will return the PIN token encrypted using the shared secret.
Pass that encrypted PIN token to this method as the first argument.
This method will decrypt the PIN token using the EncryptionKey
and then perform the authentication on the message.
Exceptions
- ArgumentNullException
The
pinTokenormessageargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
AuthenticateUsingPinToken(byte[], int, int, byte[])
Returns the result of computing HMAC-SHA-256 on the given message
using the pinToken as the key. With protocol 1, the result is
the first 16 bytes of the HMAC, and with protocol 2 it is the entire
32-byte result.
public virtual byte[] AuthenticateUsingPinToken(byte[] pinToken, int offset, int length, byte[] message)
Parameters
pinTokenbyte[]The PIN token returned by the YubiKey. This is the encrypted value, do not decrypt it.
offsetintThe offset into
pinTokenbuffer where the data begins.lengthintThe length, in bytes, of the pin token.
messagebyte[]The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Remarks
This is the same as AuthenticateUsingPinToken(byte[], byte[]),
except this specifies an offset and length of the pinToken
argument.
Exceptions
- ArgumentNullException
The
pinTokenormessageargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
AuthenticateUsingPinToken(ReadOnlyMemory<byte>, ReadOnlyMemory<byte>)
Returns the result of computing HMAC-SHA-256 on the given message
using the pinToken as the key. With protocol 1, the result is
the first 16 bytes of the HMAC, and with protocol 2 it is the entire
32-byte result.
public byte[] AuthenticateUsingPinToken(ReadOnlyMemory<byte> pinToken, ReadOnlyMemory<byte> message)
Parameters
pinTokenReadOnlyMemory<byte>The PIN token returned by the YubiKey. This is the encrypted value, do not decrypt it.
messageReadOnlyMemory<byte>The data to be authenticated.
Returns
- byte[]
A new byte array containing the authentication result.
Remarks
It is possible to obtain the PIN token by calling the command GetPinTokenCommand. The YubiKey will return the PIN token encrypted using the shared secret.
Pass that encrypted PIN token to this method as the first argument.
This method will decrypt the PIN token using the EncryptionKey
and then perform the authentication on the message.
Exceptions
- ArgumentNullException
The
pinTokenormessageargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
Decrypt(byte[], int, int)
Returns the AES-256-CBC decryption of ciphertext using an IV specified
by the protocol and the EncryptionKey. With protocol 1
the IV is all 00 bytes. With protocol 2, it is the first block size
bytes of ciphertext.
public abstract byte[] Decrypt(byte[] ciphertext, int offset, int length)
Parameters
ciphertextbyte[]The data to decrypt.
offsetintThe offset in
ciphertextwhere the method will begin decrypting.lengthintThe number of bytes to decrypt.
Returns
- byte[]
A new byte array containing the decrypted data.
Remarks
Note that this method will verify that the input buffer, offset, and length are valid.
Exceptions
- ArgumentNullException
The
ciphertextargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
- ArgumentException
The length of the
ciphertextis not a multiple of the AES block size (16 bytes).
Decrypt(ReadOnlyMemory<byte>)
Returns the AES-256-CBC decryption of ciphertext using an IV specified
by the protocol and the EncryptionKey. With protocol 1
the IV is all 00 bytes. With protocol 2, it is the first block size
bytes of ciphertext.
public abstract byte[] Decrypt(ReadOnlyMemory<byte> ciphertext)
Parameters
ciphertextReadOnlyMemory<byte>The data to decrypt.
Returns
- byte[]
A new byte array containing the decrypted data.
Remarks
Note that this method will verify that the input buffer, offset, and length are valid.
Exceptions
- ArgumentNullException
The
ciphertextargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
- ArgumentException
The length of the
ciphertextis not a multiple of the AES block size (16 bytes).
DeriveKeys(byte[])
The key derivation function to run while performing ECDH. This will derive both the EncryptionKey and the AuthenticationKey.
protected abstract void DeriveKeys(byte[] sharedSecret)
Parameters
sharedSecretbyte[]The shared value computed by ECDH.
Exceptions
- ArgumentNullException
The
bufferargument is null.- InvalidOperationException
The HMAC with SHA-256 provider failed.
Dispose()
Release resources, overwrite sensitive data.
public void Dispose()
Dispose(bool)
Release resources, overwrite sensitive data.
protected virtual void Dispose(bool disposing)
Parameters
disposingbool
Encapsulate(CoseKey)
Generates a new platform key pair and uses the private key along with the peerPublicKey to compute the shared value. It then derives the shared keys (encryption and authentication) from the shared value.
public virtual void Encapsulate(CoseKey authenticatorPublicKey)
Parameters
authenticatorPublicKeyCoseKeyThe YubiKey's public key obtained by calling the GetKeyAgreementCommand.
Remarks
This will generate a new public and private key, compute the shared value, and discard the private key. The resulting public key will be found in the PlatformPublicKey property, and the derived keys will be found in the EncryptionKey and AuthenticationKey properties.
This method can be called only after instantiation or a call to Initialize(). Otherwise, this method will throw an exception.
Exceptions
- ArgumentNullException
The
authenticatorPublicKeyargument is null.- ArgumentException
The
authenticatorPublicKeyargument is not an appropriate key object (e.g. wrong algorithm).- InvalidOperationException
The object is not available for
Encapsulatebecause it still contains data from a previous operation. It is necessary to callInitializebefore reusing a Protocol object.
Encrypt(byte[], int, int)
Returns the AES-256-CBC encryption of plaintext using an IV specified by the protocol and the EncryptionKey. With protocol 1 the IV is all 00 bytes. With protocol 2, it is a new, random value.
public abstract byte[] Encrypt(byte[] plaintext, int offset, int length)
Parameters
plaintextbyte[]The data to encrypt.
offsetintThe offset in
plaintextwhere the method will begin encrypting.lengthintThe number of bytes to encrypt.
Returns
- byte[]
A new byte array containing the encrypted data. With protocol 2, the ciphertext is actually the concatenation of the IV and the encrypted data.
Exceptions
- ArgumentNullException
The
plaintextargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
- ArgumentException
The length of the
plaintextis not a multiple of the AES block size (16 bytes).
Encrypt(ReadOnlyMemory<byte>)
Returns the AES-256-CBC encryption of plaintext using an IV specified by the protocol and the EncryptionKey. With protocol 1 the IV is all 00 bytes. With protocol 2, it is a new, random value.
public abstract byte[] Encrypt(ReadOnlyMemory<byte> plaintext)
Parameters
plaintextReadOnlyMemory<byte>The data to encrypt.
Returns
- byte[]
A new byte array containing the encrypted data. With protocol 2, the ciphertext is actually the concatenation of the IV and the encrypted data.
Exceptions
- ArgumentNullException
The
plaintextargument is null.- InvalidOperationException
The object has been created or initialized, but the Encapsulate(CoseKey) method has not been called.
- ArgumentException
The length of the
plaintextis not a multiple of the AES block size (16 bytes).
Initialize()
This is run by the platform when starting a series of transactions with a specific authenticator.
public virtual void Initialize()
Remarks
This will reset the internal state of the object to the same as immediately after instantiation. Any data acquired, generated, or computed during operations in a session of PIN/UV Authentication with a specific authenticator will be lost.
Generally you will create an instance of one of the protocols and use
it to perform the appropriate PIN/UV authentication operations with
an authenticator. Then, to operate on a different authenticator (or
the same authenticator in a new session), create a new instance of
the protocol or reuse an existing object but call Initialize
before beginning operations.