6.7 KiB
Status Keycard UX guidelines
The scope of this document is to describe the interactions between the keycard, the user and client applications. Technical details about the commands mentioned here are to be found in the APPLICATION.MD file.
Physical interaction
The applet is installed on a regular Smart Card (plastic card) with contacted and/or contactless interface. Since the card does not have any user input or output devices, all input and output happens through the host device. The host device needs a card reader to interface with the card.
Each card will have a uniquely generated 12-digits PUK code (used to unblock the PIN) and a unique pairing code. The pairing code is a password which must be converted to a 256-bit secret as defined in CLIENT_NOTES.md.
The initial PIN of the card can be set to "000000" or can be chosen by the user. The length is always 6 digits. The user has 3 attempts to insert the correct PIN, after which it is blocked. The PIN can be reset by using the PUK. The user has 5 attempts to insert the correct PUK.
PIN, PUK and pairing password can be changed at any time by the user, after authenticating with the current PIN.
Application selection
When the client detects a SmartCard, it should try to select the Status Keycard application by sending a selection command. The applet will respond providing details useful for the next steps.
PIN sessions
Many operations require the PIN to be authenticated. PIN entry scheme is the same as the one used for SIM-cards and follows the rules described above. Once a PIN is authenticated, it remains authenticated until the card is reset, loses powers or the application is re-selected. Since the card does not have a clock, if the client wants to reset PIN verification status after a specific time/inactivity interval, it should keep track of the time itself and reset the session as described above.
Pairing
A card can pair with up to 5 devices. The number of remaining pairing slot is given as a response to application selection. The client will also receive an identifier, so it can recognize if it already paired with this card. Pairing must only be done once and requires user interaction in form of pairing code entry. Keeping the generated pairing key secret is critical to guarantee secure communication between card and client. However pairing alone does not give any access to the keys stored on card or any other sensitive functionality, so the pairing code itself is not as sensitive.
Unpairing
Unpairing allows to recover a pairing slot. An authenticated device can unpair itself or any other paired device. This step requires PIN authorization. Since the card does not provide a list of paired devices, from a UI perspective the only two options that make sense are "Unpair this device" and "Unpair all others".
Initialization
When the card is delivered, it does not contain any secret so it is not able to operate properly. In this state only the INIT command will work, which allows setting the initial PIN, PUK and pairing password using a temporary secure channel.
After this first initialization, a master key must be stored on the card. It can be recovered from a mnemonic phrase, generated ex-novo using BIP39 or internally on the card.
The GET STATUS command can be used to determine if the card is ready to be used for signing or not.
The card is able to generate the mnemonic phrase internally and send it to the client as a sequence of 16-bit numbers which are the indexes in the word dictionary. The actual key generation must happen off-card however, because the applet does not implement PBKDF-2 to convert the phrase in a BIP-39 binary seed. The applet supports loading either the full master keypair (private and public) or the binary seed. However the second option only works if the card supports public key derivation and these are hard to get, since this function has been added to the JavaCard standard only in revision 3.0.5. It is critical that the client destroys all copies of the key immediately after loading them to the card by explicitly clearing the memory areas used to store them.
Initialization requires the PIN to be authenticated so it would be better if, upon detecting a new card, the client would first prompt to change PIN (a step which includes PIN verification) and only after this step generates key.
The process of generating and loading new keys can also be repeated on an already initialized card. This step does not reset the PIN to factory condition but permanently destroys the currently stored keys, so a fat huge warning must be issued.
As with all HD-wallets, the client should show the mnemonic phrase to the user and prompt them to write down the words. This will allow recovering the keys in case the card is lost, permanently blocked or re-initialized. Although the mnemonic phrase could be generated by the client itself, it is safer to use the card facilities since their RNG is certified.
Signing transactions
The main function of the card is indeed signing transactions (thus authorizing them). Signing requires the PIN to be authenticated (except in a case mentioned below). All transaction details will be shown on the client, because of the physical limitations of the card. The card support BIP32 HD wallets, but the key derivation (used to navigate the wallet hierarchy) and sign steps are separate from each other. The key derivation step also requires PIN authentication (except in a case mentioned below) but since both steps are likely to happen in the same session, this only needs to be done once. The user does not need to interact in this key derivation step, but depending on the depth of the selected wallet it might take a while (up to 2 seconds). Signing itself can also take a while, so it is a good idea to show a waiting indicator during this step.
The card signs the hash of the transaction provided by client, so it can actually be used to sign any 256-bit value, making it flexible to eventually use it contexts other than Ethereum transactions.
The card also support defining a wallet path which is PIN-less. This path can be changed but can only be one at a given time and cannot be the master wallet. Transactions using this wallet will not require PIN entry. Setting a PIN-less path requires PIN authorization, but the setting is retained across sessions.
The GET STATUS command can be used to query the currently selected wallet. This allows skipping the key derivation step if the needed wallet is selected already. The selected wallet is also retained across sessions.
Exporting keys
Exporting the private key is not allowed, except for specific key paths. This step requires PIN authorization. Public keys can be exported for any path.