remove outdated documentation
This commit is contained in:
parent
fe8ecb2b03
commit
ca65db5c71
448
APPLICATION.MD
448
APPLICATION.MD
|
@ -1,448 +0,0 @@
|
|||
# Status Keycard Application
|
||||
|
||||
## Version
|
||||
|
||||
Version numbers are in the form major.minor. An major revision increment indicates the presence of breaking changes as
|
||||
compared to the previous released version. This is version 2.0 of the specs.
|
||||
|
||||
### Changes since 1.2
|
||||
* **BREAKING** Changed application AID
|
||||
* **BREAKING** Completely redefined the EXPORT KEY command
|
||||
* **BREAKING** Removed assisted key derivation
|
||||
* **BREAKING** Removed plain data signing, now only 32-byte long hashes can be signed
|
||||
* Added internal key generation (GENERATE KEY)
|
||||
* Added the ability to customize the NDEF response (SET NDEF)
|
||||
* Added DUPLICATE KEY command
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This application allows signing of transactions using ECDSA with a keyset stored on card. The keys are defined on the
|
||||
SECP256k1 curve. Signing is available only after PIN authentication.
|
||||
|
||||
The keyset used for signing is generated externally and loaded on card. This is also only available after PIN
|
||||
authentication.
|
||||
|
||||
Before any application command is processed, a Secure Channel session must be established as specified in the
|
||||
[SECURE_CHANNEL.MD](SECURE_CHANNEL.MD) document.
|
||||
|
||||
## INITIALIZATION
|
||||
|
||||
After installation, the applet is not ready to operate and is in a pre-initializaed state. In this state the applet can
|
||||
only process the SELECT and INIT command. The INIT command is used to personalize the PIN, PUK and pairing secret, which
|
||||
must be generated off-card.
|
||||
|
||||
## PIN
|
||||
|
||||
The PIN length is fixed at 6 digits. After 3 failed authentication attempts the PIN is blocked and authentication is not
|
||||
possible anymore. A blocked PIN can be replaced and unblocked using a PUK. The PUK is a 12-digit number. After 5 failed
|
||||
attempts to unblock the applet using the PUK, the PUK is blocked, meaning the wallet is lost.
|
||||
|
||||
After authentication, the user remains authenticated until the application is either deselected or the card is reset.
|
||||
Authentication with PIN is a requirement for most commands to succeed.
|
||||
|
||||
The PIN and PUK can be changed by the user after authentication.
|
||||
|
||||
## Keys & Signature
|
||||
|
||||
The application allows loading and replacing of a single EC keyset, defined on the SECP256k1 curve. The keyset can contain
|
||||
a 32-byte chain code to further derive keys according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
|
||||
specifications. This keyset is used to sign transactions. When the applet is first installed, no keyset is available so
|
||||
signing will fail. It is necessary to first load the keyset in order for the application to be fully operational.
|
||||
|
||||
Signing of transactions is done by uploading the data in blocks no larger than 255 bytes (including the overhead caused
|
||||
by the Secure Channel). Segmentation must be handled at the application protocol. Another option is to sign the hash
|
||||
of the transaction, with the hash being calculated off-card. Signing generally requires the PIN to be authenticated,
|
||||
however the user can set a special key path which requires no authentication.
|
||||
|
||||
## APDUs
|
||||
|
||||
These are the commands supported by the application. When a command has a precondition clause and these are not met the
|
||||
SW 0x6985 is returned. All tagged data structures are encoded in the [BER-TLV format](http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-d.aspx)
|
||||
|
||||
### SELECT
|
||||
|
||||
* CLA = 0x00
|
||||
* INS = 0xA4
|
||||
* P1 = 0x04
|
||||
* P2 = 0x00
|
||||
* Data = the instance AID
|
||||
* Response = Application Info Template or ECC public key.
|
||||
|
||||
Response Data format:
|
||||
- Tag 0xA4 = Application Info Template
|
||||
- Tag 0x8F = Instance UID (16 bytes)
|
||||
- Tag 0x80 = ECC public Key
|
||||
- Tag 0x02 = Application Version (2 bytes)
|
||||
- Tag 0x02 = Number of remaining pairing slots (1 byte)
|
||||
- Tag 0x8E = Key UID (0 or 32 bytes)
|
||||
|
||||
The SELECT command is documented in the ISO 7816-4 specifications and is used to select the application on the card,
|
||||
making it the active one. The data field is the AID of the application. The response is the Application Info template
|
||||
which contains the instance UID (which can be used by the client to keep track of multiple cards) and the public key
|
||||
which must be used by the client to establish the Secure Channel. Additionally it contains the version number of the
|
||||
application, formatted on two bytes. The first byte is the major version and the second is the minor version
|
||||
(e.g: version 1.1 is formatted as 0x0101). The number of remaining pairing slots is also included in the response.
|
||||
|
||||
The Key UID can be either empty (when no key is loaded on card) or the SHA-256 hash of the master public key.
|
||||
|
||||
When the applet is in pre-initializated state, it only returns the ECC public key, BER-TLV encoded with tag 0x80.
|
||||
|
||||
### INIT
|
||||
* CLA = 0x80
|
||||
* INS = 0xFE
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = EC public key (LV encoded) | IV | encrypted payload
|
||||
* Response SW = 0x9000 on success, 0x6D00 if the applet is already initialized, 0x6A80 if the data is invalid
|
||||
|
||||
This command is only available when the applet is in pre-initialized state and successful execution brings the applet in
|
||||
the initialized state. This command is needed to allow securely storing secrets on the applet at a different moment and
|
||||
place than installation is taking place. Currently these are the PIN, PUK and pairing password.
|
||||
|
||||
The client must take the public key received after the SELECT command, generate a random keypair and perform EC-DH to
|
||||
generate an AES key. It must then generate a random IV and encrypt the payload using AES-CBC with ISO/IEC 9797-1 Method
|
||||
2 padding.
|
||||
|
||||
They payload is the concatenation of the PIN (6 digits/bytes), PUK (12 digits/bytes) and pairing secret (32 bytes).
|
||||
|
||||
This scheme guarantees protection against passive MITM attacks. Since the applet has no "owner" before the execution of
|
||||
this command, protection against active MITM cannot be provided at this stage. However since the communication happens
|
||||
locally (either through NFC or contacted interface) the realization of such an attack at this point is unrealistic.
|
||||
|
||||
After successful execution, this command cannot be executed anymore. The regular SecureChannel (with pairing) is active
|
||||
and PIN and PUK are initialized.
|
||||
|
||||
### OPEN SECURE CHANNEL
|
||||
|
||||
The OPEN SECURE CHANNEL command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
|
||||
|
||||
### MUTUALLY AUTHENTICATE
|
||||
|
||||
The MUTUALLY AUTHENTICATE command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
|
||||
|
||||
### PAIR
|
||||
|
||||
The PAIR command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD). The shared secret is 32 bytes long. The
|
||||
way the secret is generated is not within the scope of this document because the applet accepts the already generated
|
||||
secret as an installation parameter. However the card issuer and clients must agree on the way it is generated for
|
||||
interoperability reasons.
|
||||
|
||||
If the code is meant to be input manually, a random, variable length alphanumeric password to be used in conjuction with
|
||||
an algorithm such as scrypt or PBKDF2 is suggested. If another input mechanism is foreseen (such as QR-code scanning),
|
||||
then the sequence should be composed of random bytes from a secure source of randomness.
|
||||
|
||||
### UNPAIR
|
||||
|
||||
The UNPAIR command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD). The user PIN must be verified for the
|
||||
command to work.
|
||||
|
||||
### GET STATUS
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xF2
|
||||
* P1 = 0x00 for application status, 0x01 for key path status
|
||||
* P2 = 0x00
|
||||
* Response SW = 0x9000 on success, 0x6A86 on undefined P1
|
||||
* Response Data = Application Status Template or Key Path
|
||||
* Preconditions: Secure Channel must be opened
|
||||
|
||||
Response Data format:
|
||||
if P1 = 0x00:
|
||||
- Tag 0xA3 = Application Status Template
|
||||
- Tag 0x02 = PIN retry count (1 byte)
|
||||
- Tag 0x02 = PUK retry count (1 byte)
|
||||
- Tag 0x01 = 0xff if key is initialized, 0 otherwise
|
||||
|
||||
if P1 = 0x01
|
||||
- a sequence of 32-bit numbers indicating the current key path. Empty if master key is selected.
|
||||
|
||||
### SET NDEF
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xF3
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = the data to store
|
||||
* Response SW = 0x9000 on success, 0x6A80 on invalid data
|
||||
* Preconditions: Secure Channel must be opened, PIN must be verified
|
||||
|
||||
Used to set the content of the data file owned by the NDEF applet. This allows changing the behavior of Android and other
|
||||
clients when tapping the card with no open client. As an example, it could be used to launch a specific wallet software.
|
||||
|
||||
The data is stored as is. A check is made that the first 2 bytes, read as a MSB first short, are equal to the Lc field
|
||||
minus 2 (the length of the field itself). This does not ensure that the NDEF record is valid, but ensures that no out
|
||||
of bound access happens.
|
||||
|
||||
### VERIFY PIN
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x20
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = the PIN to be verified
|
||||
* Response SW = 0x9000 on success, 0x63CX on failure, where X is the number of attempt remaining
|
||||
* Preconditions: Secure Channel must be opened
|
||||
|
||||
Used to verify the user PIN. On correct PIN entry the card returns 0x9000, the retry counter is reset and the PIN is
|
||||
marked as authenticated for the entire session (until the application is deselected or the card reset/teared). On
|
||||
error, the number of remaining retries is decreased and the SW 0x63CX, where X is the number of available retries is
|
||||
returned. When the number of remaining retries reaches 0 the PIN is blocked. When the PIN is blocked this command
|
||||
always returns 0x63C0, even if the PIN is inserted correctly.
|
||||
|
||||
### CHANGE PIN
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x21
|
||||
* P1 = PIN identifier
|
||||
* P2 = 0x00
|
||||
* Data = the new PIN
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the PIN format is invalid, 0x6A86 if P1 is invalid
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
Used to change a PIN or secret. In case of invalid format, the code 0x6A80 is returned. If the conditions match, the PIN
|
||||
or secret is updated. The no-error SW 0x9000 is returned.
|
||||
|
||||
P1:
|
||||
* 0x00: User PIN. Must be 6-digits. The updated PIN is authenticated for the rest of the session.
|
||||
* 0x01: Applet PUK. Must be 12-digits.
|
||||
* 0x02: Pairing secret. Must be 32-bytes long. Existing pairings are not broken, but new pairings will need to use the
|
||||
new secret.
|
||||
|
||||
### UNBLOCK PIN
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x22
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = the PUK followed by the new PIN
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be blocked
|
||||
|
||||
Used to unblock the user PIN. The data field must contain exactly 18 numeric digits, otherwise SW 0x6A80 is returned.
|
||||
The first 12 digits are the PUK and the last 6 are the new PIN. If the PUK is correct the PIN is changed to the supplied
|
||||
one, it is unblocked and authenticated for the rest of the session. The status code 0x9000 is returned. When the PUK is
|
||||
wrong, the number of remaining retries is decreased and the SW 0x63CX, where X is the number of available retries is
|
||||
returned. When the number of remaining retries reaches 0 the PUK is blocked. When the PUK is blocked this command
|
||||
always returns 0x63C0, even if the PUK is inserted correctly. In this case the wallet is effectively lost.
|
||||
|
||||
### LOAD KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD0
|
||||
* P1 = key type
|
||||
* P2 = 0x00
|
||||
* Data = the key data
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A86 if P1 is invalid
|
||||
* Response Data = the key UID, defined as the SHA-256 of the public key
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
P1:
|
||||
* 0x01 = ECC SECP256k1 keypair
|
||||
* 0x02 = ECC SECP256k1 extended keypair
|
||||
* 0x03 = Binary seed as defined in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
|
||||
|
||||
Data:
|
||||
|
||||
If P1 is 0x01 or 0x02
|
||||
- Tag 0xA1 = keypair template
|
||||
- Tag 0x80 = ECC public key component (can be omitted)
|
||||
- Tag 0x81 = ECC private key component
|
||||
- Tag 0x82 = chain code (if P1=0x02)
|
||||
|
||||
If P1 is 0x03 a 64 byte sequence generated according to the BIP39 specifications is expected. The master key will be
|
||||
generated according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) specifications. This
|
||||
is only supported if the hardware supports public key derivation.
|
||||
|
||||
This command is used to load or replace the keypair used for signing on the card. This command always aborts open
|
||||
signing sessions, if any. Unless a DERIVE KEY is sent, a subsequent SIGN command will use this keypair for signature.
|
||||
|
||||
### DERIVE KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD1
|
||||
* P1 = derivation options
|
||||
* P2 = 0x00
|
||||
* Data = a sequence of 32-bit integers (most significant byte first). Empty if the master key must be used.
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6984 if one of the components in the path
|
||||
generates an invalid key, 0x6B00 if derivation from parent keys is selected but no valid parent key is cached.
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified (if no PIN-less key is defined), an extended
|
||||
keyset must be loaded
|
||||
|
||||
This command is used before a signing session to generate a private key according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
|
||||
specifications. This command always aborts open signing sessions, if any. The generated key is used for all subsequent
|
||||
SIGN sessions. The maximum depth of derivation from the master key is 10. Any attempt to get deeper results in 0x6A80
|
||||
being returned. The BIP32 specifications define a few checks which must be performed on the derived keys. If these fail,
|
||||
the 0x6984 is returned and the invalid key is discarded. A client should perform a GET STATUS command to get the actual
|
||||
current key path and resume derivation using a different path.
|
||||
|
||||
The ability to start derivation from the parent keys allows to more efficiently switch between children of the same key.
|
||||
Note however that only the immediate parent of the current key is cached so you cannot use this to go back in the
|
||||
hierarchy. If no valid parent key is available the status code 0x6B00 will be returned.
|
||||
|
||||
P1:
|
||||
* bit 0-5 = reserved
|
||||
* bit 7-6:
|
||||
- 00 derive from master keys
|
||||
- 01 derive from parent keys
|
||||
- 10 derive from current keys
|
||||
- 11 reserved
|
||||
|
||||
### GENERATE MNEMONIC
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD2
|
||||
* P1 = checksum size (between 4 and 8)
|
||||
* P2 = 0x00
|
||||
* Response SW = 0x9000 on success. 0x6A86 if P1 is invalid.
|
||||
* Response Data = a sequence of 16-bit integers (most significant byte first).
|
||||
* Preconditions: Secure Channel must be opened
|
||||
|
||||
Used to generate a mnemonic according to the algorithm specified in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
|
||||
The returned data is a list of 16-byte integers which should be used as indexes in a wordlist to generate the
|
||||
human-readable mnemonic. Each integer can have a value from 0 to 2047.
|
||||
|
||||
### REMOVE KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD3
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Response SW = 0x9000 on success.
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
Removes the key from the card, bringing it back to an uninitialized state. No signing operation is possible after this
|
||||
command until a new LOAD KEY command is performed.
|
||||
|
||||
### GENERATE KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD4
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Response SW = 0x9000 on success.
|
||||
* Response Data = the key UID, defined as the SHA-256 of the public key
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
Generates and stores keys completely on card. The state of the card after execution is the same as if a LOAD KEY command
|
||||
had been performed.
|
||||
|
||||
### DUPLICATE KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xD5
|
||||
* P1 = subcommand
|
||||
* P2 = depends on subcommand
|
||||
* Data = depends on phase
|
||||
* Response SW = 0x9000 on success.
|
||||
* Response Data = depends on subcommand
|
||||
* Preconditions: depends on subcommand
|
||||
|
||||
P1:
|
||||
* 0x00: START DUPLICATE
|
||||
* 0x01: ADD ENTROPY
|
||||
* 0x02: EXPORT DUPLICATE
|
||||
* 0x03: IMPORT DUPLICATE
|
||||
|
||||
#### START DUPLICATE
|
||||
This is the first step to start duplication. Requires an open secure channel and user PIN must be verified. Aborts any
|
||||
on-going duplication session. P2 is the number of entropy pieces to expect in total (including this command). The data
|
||||
contain the first piece of entropy. Returns no data. Must be performed with exactly the same parameters and data on all
|
||||
cards taking part in the duplication.
|
||||
|
||||
#### ADD ENTROPY
|
||||
This command uses the same one-shot secure channel scheme as defined in the INIT command. P2 is 00. Requires an ongoing
|
||||
duplicate session started with the START DUPLICATE subcommand. Must be performed once per device taking part in the
|
||||
duplication process, for a total number of devices equaling the P2 parameter of the START DUPLICATE subcommand (counting
|
||||
the device which sent the START DUPLICATE command as the first device). The data is a random 256-bit number. The same
|
||||
data must be sent to all the cards taking part in the duplication process.
|
||||
|
||||
#### EXPORT DUPLICATE
|
||||
This command must be sent to the card which you wish to duplicate. Requires an open secure channel and authenticated
|
||||
PIN. Works only if a duplication session is active and ADD ENTROPY has been performed the required number of times.
|
||||
Returns the encrypted duplicate of the master key and terminates the duplication session for this card. The format is
|
||||
exactly the same as the one defined in the LOAD KEY (TLV) command with omitted public key. It is however prepended by a
|
||||
16-bytes IV and the entire TLV structure is encrypted.
|
||||
|
||||
#### IMPORT DUPLICATE
|
||||
This command must be sent to all the cards which are a target for duplication. The Data field must contain the output
|
||||
from the EXPORT DUPLICATE command performed on the source card. Returns the key UID. It follows exactly the same rules
|
||||
as the EXPORT DUPLICATE subcommand.
|
||||
|
||||
### SIGN
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xC0
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = the hash to sign
|
||||
* Response = public key and the signature
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the data is not 32-byte long
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified (or a PIN-less key must be active), a valid
|
||||
keypair must be loaded
|
||||
|
||||
Response Data format:
|
||||
- Tag 0xA0 = signature template
|
||||
- Tag 0x80 = ECC public key component
|
||||
- Tag 0x30 = ECDSA Signature
|
||||
- Tag 0x02 = R value
|
||||
- Tag 0x02 = S value
|
||||
|
||||
Returns the ECDSA signature of the hash. The hash can be calculated using any algorithm, but must be 32-bytes long. The
|
||||
signature is returned in a signature template, containing the public key associated to the signature and the signature
|
||||
itself. For usage on the blockchain, you will need to calculate the recovery ID in addition to extracting R and S.
|
||||
To calculate the recovery ID you need to apply the same algorithm used for public key recovery from a transaction starting
|
||||
with a recovery ID of 0. If the public key matches the one returned in the template, then you have found the recovery ID,
|
||||
otherwise you try again by incrementing the recovery ID.
|
||||
|
||||
### SET PINLESS PATH
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xC1
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = a sequence of 32-bit integers
|
||||
* Response SW = 0x9000 on success, 0x6A80 if data is invalid
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
Sets the given sequence of 32-bit integers as a PIN-less path. When the current derived key matches this path, SIGN
|
||||
will work even if no PIN authentication has been performed. An empty sequence means that no PIN-less path is defined.
|
||||
|
||||
### EXPORT KEY
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xC2
|
||||
* P1 = derivation options
|
||||
* P2 = export options
|
||||
* Response SW = 0x9000 on success, 0x6A86 if P1 or P2 are wrong
|
||||
* Data = a sequence of 32-bit integers (empty if P1=0x00)
|
||||
* Response Data = key pair template
|
||||
* Response SW = 0x9000 on success, 0x6985 if the private key cannot be exported, 0x6A80 if the path is malformed
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified
|
||||
|
||||
P1:
|
||||
0x00 = Current key
|
||||
0x01 = Derive
|
||||
0x02 = Derive and make current
|
||||
|
||||
P2:
|
||||
0x00 = private and public key
|
||||
0x01 = public key only
|
||||
|
||||
Response Data format:
|
||||
- Tag 0xA1 = keypair template
|
||||
- Tag 0x80 = ECC public key component (could be omitted)
|
||||
- Tag 0x81 = ECC private key component (if P2=0x00)
|
||||
|
||||
This command exports the requested public and private key. The public key can be always exported (P2=0x01), but the
|
||||
private key (P2=0x00) can be exported if and only if the requested key path is in the
|
||||
[EIP-1581](https://eips.ethereum.org/EIPS/eip-1581) subtree.
|
||||
|
||||
The P1 parameter indicates how to the derive the desired key. P1 = 0x00 indicates that the current key must be exported,
|
||||
and no derivation will be performed. P1 = 0x01 derives the path given in the data field without changing the current
|
||||
path of the card. P1 = 0x02 derives the path but also changes the current path of the card. The source for derivation
|
||||
can be set by OR'ing P1 with the constants defined in the DERIVE KEY command. This allows deriving from master, parent
|
||||
or current.
|
||||
|
||||
If the private key is being exported, the card could omit exporting the public key for performance reason. The public
|
||||
key can then be calculate off-card if needed.
|
139
CLIENT_NOTES.md
139
CLIENT_NOTES.md
|
@ -1,139 +0,0 @@
|
|||
# Notes for client implementation
|
||||
|
||||
This document should help client application developers to integrate support for the Status Keycard in their applications.
|
||||
|
||||
## Low-level communication
|
||||
|
||||
The Status Keycard is a JavaCard application and as such is deployed on ISO7816 compatible SmartCards. Communication
|
||||
will happen exchanging APDUs using either the T=0 or preferably the T=1 protocol. Most operating systems use an
|
||||
implementation of [this Microsoft API](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374731(v=vs.85).aspx#smart_card_functions)
|
||||
like [PCSC lite](http://pcsclite.alioth.debian.org/pcsclite.html). Your language of choice might provide bindings for
|
||||
this library or an higher-level API built on top of it.
|
||||
|
||||
A few things to keep in mind when communicating with SmartCards
|
||||
|
||||
1. The card can never initiate communication. The card only responds to commands sent from the client.
|
||||
2. When connecting to the card using SCardConnect, always use the SCARD_SHARE_EXCLUSIVE mode to avoid OS services
|
||||
messing with the card while you are using it.
|
||||
3. A SmartCard can have multiple applications installed. If using only the basic channel (recommended for our use-case)
|
||||
only a single application can be selected at the time. This must be done explicitly on each reset by issuing the
|
||||
SELECT command with the AID of the keycard application.
|
||||
4. Since we are not using extended APDUs, the maximum size of the data field of the APDU is 255 bytes.
|
||||
|
||||
## Wallet management and security
|
||||
|
||||
Before thinking about the application-specific communication (i.e: actually using the Keycard applet to derive keys and
|
||||
sign transactions) the client must be able to actually talk with the card using its [Secure Channel protocol](SECURE_CHANNEL.MD).
|
||||
|
||||
The first step, after an APDU channel is available is to [SELECT](APPLICATION.MD) the Keycard application on the card.
|
||||
The Keycard will return its Instance UID and public key for Secure Channel establishment. Although both values are unique,
|
||||
only use the Instance UID to identify the Keycard since only this value is guaranteed not to change over the lifetime of
|
||||
the card. If your application has already performed pairing with the Keycard with this Instance UID, you can establish
|
||||
a Secure Channel session (described later). Otherwise you should proceed with pairing.
|
||||
|
||||
For pairing, the client must show that it knows the pairing code. For this reason the user must be prompted
|
||||
to insert said code. The result of pairing is a secret value shared by both parties which is used during the session key
|
||||
generation on establishment of a Secure Channel. The client must permanently store the association of the Instance UID,
|
||||
the secret generated during pairing and the index which the card assigned to this client. Said index must be provided
|
||||
when opening a Secure Channel so that the card knows with which client it is speaking. Since the pairing secret is
|
||||
sensitive data, it should be stored as securely as possible, eventually with password protection. Losing this secret
|
||||
allows an attacker to pose either as the client to the card or as the card to the client. It does not allow however
|
||||
decrypting older communication and perform passive attacks.
|
||||
|
||||
Note that the card can only pair with a limited number of clients (currently 5). Unpairing allows to replace old clients
|
||||
with new ones.
|
||||
|
||||
When a card and a client are paired, they can establish a Secure Channel session. The Secure Channel provides the
|
||||
authentication, confidentiality and integrity guarantees which the plain APDU channel does not provide. This phase is
|
||||
divided in 2 steps:
|
||||
|
||||
1. Sending an OPEN SECURE CHANNEL APDU to generate session keys
|
||||
2. Sending a MUTUALLY AUTHENTICATE command to verify that both parties have the same keys.
|
||||
|
||||
After this happens, all further communication will be encrypted and with a MAC providing integrity and authentication
|
||||
for each APDU.
|
||||
|
||||
The card and client must abort the Secure Channel session at any time if MAC verification fails, since this means that
|
||||
the APDU has been corrupted, possibly as a result of an attack attempt. The card also resets the session when the
|
||||
application is (re-)selected or the card is reset (or on power loss).
|
||||
|
||||
Note that while pairing requires user input, opening a secure channel session does not.
|
||||
|
||||
## User authentication
|
||||
|
||||
Aside from the Secure Channel-related APDUs, the application also provides commands to authenticate the user (as opposed
|
||||
as authenticating the client) and to manage the user's authentication credentials. These are the VERIFY PIN, CHANGE PIN
|
||||
and UNBLOCK PIN commands. The client is not supposed to store the PIN and verification should always require user input.
|
||||
After verifying the PIN the card considers to the user to be authenticated for the entire application session. The
|
||||
application session ends on card reset, power loss or application re-selection. The client should keep track of whether
|
||||
the user has been authenticated or not in order to avoid repeatedly asking for the PIN. The card will respond with an
|
||||
error to any APDU requiring user authentication if the user has not been authenticated in the current application
|
||||
session.
|
||||
|
||||
## Keycard features and workflow
|
||||
|
||||
Now that the client can finally talk with the applet and provide user authentication facilities, it is time to look on
|
||||
how to actually use the Keycard. The Keycard applet allows management of a single HD wallet as described in the
|
||||
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) specifications. It provides the following features
|
||||
|
||||
1. Source of entropy to generate master seeds (GENERATE MNEMONIC). No PIN required (has no effect on card state).
|
||||
2. Loading of master key (LOAD KEY). PIN required. The same command can be used to replace the loaded master key.
|
||||
3. Set the key to be used for signing by deriving from the master key (DERIVE KEY). PIN required unless a PIN-less path
|
||||
is set.
|
||||
4. Sign hashes (SIGN). PIN required unless the current key path is set as PIN-less. Note that the Keccak-256 hash of the
|
||||
transaction is signed and must be generate off-card. The actual transaction data are not sent to the card.
|
||||
5. Setting/Unsetting a PIN-less path (SET PINLESS PATH). PIN required. It allows disabling PIN authentication for a
|
||||
specific key path.
|
||||
6. Exporting keys (EXPORT KEY). PIN required. Exporting the private key is only allowed for specific keys.
|
||||
|
||||
Additionally the GET STATUS command (no PIN required) allows retrieving information about the card status and the
|
||||
current key path.
|
||||
|
||||
The card is shipped with no keys on-board. In this state the SIGN and DERIVE KEY commands will not work. The client can
|
||||
detect when a card has no keys by issuing a GET STATUS command. In this case it could prompt the user to either enter a
|
||||
mnemonic passphrase or allow the card to generate a new one (GENERATE MNEMONIC is issued). In both cases, the mnemonic
|
||||
must be converted to a master key from the client and loaded to the card using the LOAD KEY command.
|
||||
|
||||
The card stores the master key permanently, until replaced. Additionally the card has the concept of current key and
|
||||
current key path. The current key is the one used during the SIGN command. The current key equals the master key when
|
||||
new keys are loaded and the current key path is empty. Using the DERIVE KEY command however, the client can move through
|
||||
the tree of the HD wallet. This command derives the key as described in BIP32 and sets both the current key and current
|
||||
key path according to its arguments and the results of key derivation. Using the GET STATUS command the client can
|
||||
always know the current key path and thus decide if further derivation is needed or not before issuing a SIGN command.
|
||||
The current key persists across application sessions (including in case of power loss). A flag in the DERIVE KEY command
|
||||
decides whether derivations restarts from the master key or is performed on the current key, extending the current path.
|
||||
The current maximum key path depth is 10 levels under the master key.
|
||||
|
||||
The SIGN command signs the Keccak-256 hash provided in the APDU's data field using the current key. The client must
|
||||
calculate the hash of the transaction off-card. The signature (r,s) and the public key used to verify it are both
|
||||
returned. The client must use this to calculate 'v' and format the signature as required by Ethereum (v,r,s) if it
|
||||
wishes to submit the transaction to the network.
|
||||
|
||||
Another feature is the ability to define a key path which requires no PIN authentication for signing. When a PIN-less
|
||||
path is set the DERIVE KEY command never requires a PIN (because there must be a PIN-less way to reach that path). Note
|
||||
that setting the PIN-less key path does not automatically set the current key path to the PIN-less one. You still need
|
||||
to use DERIVE KEY to get there. Only when the current key path matches the PIN-less one the SIGN command will not require
|
||||
PIN authentication. The master key can never be used without PIN.
|
||||
|
||||
Finally, some keys can be exported (after PIN authentication). The public key can be exported for any key, while the
|
||||
private one only for specific keys. The EXPORT KEY command does not automatically do key derivation. This means that you
|
||||
must use DERIVE KEY before exporting the desired key.
|
||||
|
||||
## Additional notes
|
||||
|
||||
1. The SIGN command also allows signing data directly instead of a precomputed hash (if P1 is 0x00 instead of 0x01),
|
||||
transmitted over several blocks if needed. This feature is never used because this signature uses SHA-256 instead of
|
||||
Keccak-256 (which is not available) making it useless. This mode of operation has been implemented before the current
|
||||
one with precomputed hashes. It remains because if we get hold of a hardware platform implementing Keccak-256, or we
|
||||
decide to implement it in software, we might want to operate this way.
|
||||
2. Communication has less overhead when using the T=1 protocol. However the card/reader/os combination I have seems to
|
||||
only work with T=0 (although all claim to support T=1). Contactless readers always emulate T=1 when operated through
|
||||
the PC/SC interface.
|
||||
3. You can refer to the tests for examples of communication with the card. The manual-only signTransactionTest test in
|
||||
particular generates a real transaction, signs it and submits it to the network.
|
||||
4. If you test your client against our fork of jCardSim instead of a real card, keep in mind that it supports unassisted
|
||||
key derivation, but you shouldn't use it because, as explained above, it wouldn't work on the card.
|
||||
5. If using jCardSim, only use our fork, since some of the needed algorithms are unsupported in the upstream version.
|
||||
6. The pairing code is a randomly generated password (using whatever password generation algorithm is desired). This
|
||||
password must be converted to a 256-bit key using PBKDF2 with the salt "Keycard Pairing Password Salt" and 50000 iterations.
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
# Secure Channel
|
||||
|
||||
## Overview
|
||||
A Secure Channel must be established to allow communication between the applet and the client. This secure channel has
|
||||
the concept of pairing with multiple devices (how many clients can be paired at the same time is defined by the applet).
|
||||
The SecureChannel guarantees protection from snooping, MITM, replay attacks and provides message integrity and
|
||||
authentication for each APDU.
|
||||
|
||||
A short description of establishing a session is as follows
|
||||
|
||||
1. The client selects the application on card. The application responds with a public EC key.
|
||||
2. The client sends an OPEN SECURE CHANNEL command with its public key and pairing index. The EC-DH algorithm is used by
|
||||
both parties to generate a shared 256-bit secret (more details below).
|
||||
3. The generated secret is concatenated with the pairing key and random data and hashed with SHA-512.
|
||||
4. The first half of the generated value is used as an AES key to encrypt all further communication. CBC mode is used
|
||||
with a random IV generated for each APDU and prepended to the APDU payload. The second half is used to MAC generation
|
||||
and verification. Both command and responses are encrypted.
|
||||
5. The client sends a MUTUALLY AUTHENTICATE command to verify that the keys are matching and thus the secure channel is
|
||||
successfully established.
|
||||
|
||||
The EC keyset used by the card for the EC-DH algorithm is generated on-card on applet installation and is not used
|
||||
for anything else. The EC keyset used by the client is generated every time a new secure channel session must be
|
||||
opened.
|
||||
|
||||
## APDU format
|
||||
|
||||
### OPEN SECURE CHANNEL
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x10
|
||||
* P1 = the pairing index
|
||||
* P2 = 0x00
|
||||
* Data = An EC-256 public key on the SECP256k1 curve encoded as an uncompressed point.
|
||||
* Response Data = A 256-bit salt and a 128-bit seed IV
|
||||
* Response SW = 0x9000 on success, 0x6A86 if P1 is invalid, 0x6A80 if the data is not a public key
|
||||
|
||||
This APDU is the first step to establish a Secure Channel session. A session is aborted when the application is
|
||||
deselected, either directly or because of a card reset/tear.
|
||||
|
||||
The card generates a random 256-bit salt which is sent to the client. Both the client and the card do the following
|
||||
for key derivation
|
||||
|
||||
1. Use their private key and the counterpart public key to generate a secret using the EC-DH algorithm.
|
||||
2. The generated secret, the pairing key and the salt are concatenated and the SHA-512 of the concatenated value is
|
||||
calculated.
|
||||
3. The output of the SHA-512 algorithm is split in two parts of 256-bit. The first part is used as the encryption key
|
||||
and the second part is used as the MAC key for further communication.
|
||||
|
||||
The seed IV is used by the client as the IV for the next encrypted APDU.
|
||||
|
||||
### MUTUALLY AUTHENTICATE
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x11
|
||||
* P1 = 0x00
|
||||
* P2 = 0x00
|
||||
* Data = 256-bit random number
|
||||
* Response Data = 256-bit random number
|
||||
* Response SW = 0x9000 on success, 0x6985 if the previous successfully executed APDU was not OPEN SECURE CHANNEL, 0x6982
|
||||
if authentication failed or the data is not 256-bit long
|
||||
|
||||
This APDU allows both parties to verify that the keys generated in the OPEN SECURE CHANNEL step are matching and thus
|
||||
guarantee authentication of the counterpart. The data sent by both parties is a 256-bit random number The APDU data is
|
||||
sent encrypted with the keys generated in the OPEN SECURE CHANNEL step. Each party must verify the MAC of the received
|
||||
APDU. If the MAC can be verified, it means that both parties are using the same keys. Only after this step has been
|
||||
executed the secure channel can be considered to be open and other commands can be sent. If the authentication fails
|
||||
the card must respond with 0x6982. In this case the OPEN SECURE CHANNEL command must be repeated to generate new keys.
|
||||
|
||||
### PAIR
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x12
|
||||
* P1 = pairing phase
|
||||
* P2 = 0x00
|
||||
* Data = see below
|
||||
* Response Data = see below
|
||||
* Response SW = 0x9000 on success, 0x6A80 if the data is in the wrong format, 0x6982 if client cryptogram verification
|
||||
fails, 0x6A84 if all available pairing slot are taken, 0x6A86 if P1 is invalid or is 0x01 but the first phase was not
|
||||
completed, 0x6985 if a secure channel is open
|
||||
|
||||
P1:
|
||||
* 0x00: First step
|
||||
* 0x01: Final step
|
||||
|
||||
Data:
|
||||
* On first step: a 256-bit random client challenge
|
||||
* On second step: the client cryptogram as SHA-256(shared secret, card challenge)
|
||||
|
||||
Response Data:
|
||||
* On first step: the card cryptogram as SHA-256(shared secret, client challenge) followed by a 256-bit card challenge
|
||||
* On second step: the pairing index followed by a 256-bit salt
|
||||
|
||||
This APDU is sent to pair a client. Pairing is performed with two commands which must be sent immediately one after the
|
||||
other.
|
||||
|
||||
In the first phase the client sends a random challenge to the card. The card replies with the SHA-256 hash of the
|
||||
challenge and the shared secret followed by its random challenge. The client is thus able to authenticate the card by
|
||||
verifying the card cryptogram (since the client can generate the same and verify that it matches).
|
||||
|
||||
In the second phase the client sends the client cryptogram which is the SHA-256 hash of the shared secret and the card
|
||||
challenge. The card verifies the cryptogram and thus authenticates the client. On success the card generates a random
|
||||
256-bit salt which is appended to the shared secret. The SHA-256 hash of the concatenated value is stored in the fist
|
||||
available pairing slot and will be further used to derive session keys. The card responds with the pairing index (which
|
||||
the client must send in all OPEN SECURE CHANNEL commands) and the salt used to generate the key, so that the client can
|
||||
generate and store the same key.
|
||||
|
||||
The shared secret is a 256-bit value which must be be known to both parts being paired. The exact means of how this
|
||||
happens depend on the specific applet.
|
||||
|
||||
### UNPAIR
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0x13
|
||||
* P1 = the index to unpair
|
||||
* P2 = 0x00
|
||||
* Response SW = 0x9000 on success, 0x6985 if security conditions are not met, 0x6A86 if the index is higher than the
|
||||
highest possible pairing index.
|
||||
|
||||
This APDU is sent to unpair a client. An existing secure channel session must be open. The application implementing this
|
||||
protocol may apply additional restrictions, such as the verification of a user PIN. On success the pairing slot at the
|
||||
given index will be freed and will be made available to pair other clients. If the index is already free nothing will
|
||||
happen.
|
||||
|
||||
### Encrypted APDUs
|
||||
|
||||
After a successful OPEN SECURE CHANNEL command all communication between card and client is encrypted. Note that only
|
||||
the data fields of C-APDU are encrypted, which means that CLA, INS, P1, P2 for C-APDU are plaintext. This means no
|
||||
sensitive data should be sent in these parameters. Additionally a MAC is calculated for the entire APDU, including
|
||||
the unencrypted fields.
|
||||
|
||||
Because R-APDU can only contain data if their SW is a success or warning status word (0x9000, 0x62XX, 0x63XX), when the
|
||||
secure channel is open all responses will have SW 0x9000. The actual SW is always appended at the end of the response
|
||||
data before encryption, which means the client must interpret the last two bytes of the plaintext response as the SW.
|
||||
An exception to this is SW 0x6982, which indicates that the SecureChannel has been aborted and as such is returned
|
||||
without any MAC.
|
||||
|
||||
To encrypt the data both the card and the client do the following:
|
||||
|
||||
1. The data is padded using the ISO/IEC 9797-1 Method 2 algorithm.
|
||||
2. The data is encrypted using AES in CBC mode using the session key.
|
||||
3. An AES CBC-MAC is calculated over the entire APDU data
|
||||
4. The data field of the APDU is set to the MAC followed by the encrypted data.
|
||||
|
||||
To decrypt the data both the card and the client do the following:
|
||||
|
||||
1. The first 16 bytes of the APDU data are the MAC to be verified
|
||||
2. The remaining data is decrypted using AES in CBC mode using the session key.
|
||||
3. The padding is removed.
|
||||
|
||||
The IV used for the encryption is the last seen MAC from the counterpart. This optimizes the number
|
||||
of transmitted bytes and guarantees protection from replay attacks. For the MAC generation, a zero IV is always used.
|
||||
|
||||
MAC generation for C-APDUs is calculated on the concatenation of CLA INS P1 P2 LC 00 00 00 00 00 00 00 00 00 00 00 and
|
||||
the encrypted data field. The 11-byte long padding does not become part of the data field and does not affect LC
|
||||
|
||||
MAC generation fo R-APDUs is calculated on the concatenation of Lr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 and
|
||||
the encrypted data field. The 15-byte long padding does not become part of the response field. Lr is the length of the
|
||||
encrypted response data field and is not transmitted.
|
||||
|
||||
Because AES in CBC mode requires the data field length in bytes to be a multiple of 16, the maximum effective APDU
|
||||
size becomes 240 bytes. Of these 16 bytes are used for the MAC and minimum of 1 byte for padding, making the maximum
|
||||
payload size in a single APDU 223 bytes, meaning about a 13,5% overhead.
|
||||
|
||||
### Error conditions
|
||||
|
||||
1. If a sensitive command is received without an active Secure Channel, the card shall respond with SW 0x6985 (
|
||||
SW_CONDITIONS_NOT_SATISFIED)
|
||||
2. If a MAC cannot be verified the card shall respond 0x6982 and the Secure Channel must be closed
|
100
UX_NOTES.md
100
UX_NOTES.md
|
@ -1,100 +0,0 @@
|
|||
# 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](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](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.
|
Loading…
Reference in New Issue