add GENERATE KEY command

This commit is contained in:
Michele Balistreri 2018-11-07 13:56:06 +03:00
parent f83c655524
commit 22b41ab781
5 changed files with 57 additions and 2 deletions

View File

@ -307,6 +307,19 @@ human-readable mnemonic. Each integer can have a value from 0 to 2047.
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.
### SIGN
* CLA = 0x80

View File

@ -27,7 +27,8 @@ javacard {
aid = '0x53:0x74:0x61:0x74:0x75:0x73:0x57:0x61:0x6c:0x6c:0x65:0x74:0x4e:0x46:0x43'
className = 'NDEFApplet'
}
version = '1.2'
version = '2.0'
}
}

View File

@ -1000,7 +1000,9 @@ public class WalletApplet extends Applet {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
crypto.random.generateData(apduBuffer, (short) 0, BIP39_SEED_SIZE);
apduBuffer[ISO7816.OFFSET_LC] = BIP39_SEED_SIZE;
crypto.random.generateData(apduBuffer, ISO7816.OFFSET_CDATA, BIP39_SEED_SIZE);
loadSeed(apduBuffer);
generateKeyUIDAndRespond(apdu, apduBuffer);
}

View File

@ -395,6 +395,17 @@ public class WalletAppletCommandSet {
return secureChannel.transmit(apduChannel, removeKey);
}
/**
* Sends a GENERATE KEY APDU.
*
* @return the raw card response
* @throws CardException communication error
*/
public ResponseAPDU generateKey() throws CardException {
CommandAPDU generateKey = secureChannel.protectedCommand(0x80, WalletApplet.INS_GENERATE_KEY, 0, 0, new byte[0]);
return secureChannel.transmit(apduChannel, generateKey);
}
/**
* Sends a SIGN APDU. The dataType is P1 as defined in the applet. The isFirst and isLast arguments are used to form
* the P2 parameter. The data is the data to sign, or part of it. Only when sending the last block a signature is

View File

@ -685,6 +685,34 @@ public class WalletAppletTest {
assertEquals(0, data[30 + data[21]]);
}
@Test
@DisplayName("GENERATE KEY command")
void generateKeyTest() throws Exception {
// Security condition violation: SecureChannel not open
ResponseAPDU response = cmdSet.generateKey();
assertEquals(0x6985, response.getSW());
cmdSet.autoOpenSecureChannel();
// Security condition violation: PIN not verified
response = cmdSet.generateKey();
assertEquals(0x6985, response.getSW());
response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSW());
// Good case
response = cmdSet.generateKey();
assertEquals(0x9000, response.getSW());
byte[] keyUID = response.getData();
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_ANY, true);
assertEquals(0x9000, response.getSW());
byte[] pubKey = response.getData();
verifyKeyUID(keyUID, Arrays.copyOfRange(pubKey, 4, pubKey.length));
}
@Test
@DisplayName("DERIVE KEY command")
void deriveKeyTest() throws Exception {