mirror of
https://github.com/status-im/status-keycard.git
synced 2025-01-23 12:09:29 +00:00
add ability to SIGN precomputed hashes. Switch to ECDSA with SHA256 for
data sign
This commit is contained in:
parent
ac5929a9fe
commit
a78c5340c2
@ -127,13 +127,17 @@ signing sessions, if any.
|
||||
|
||||
* CLA = 0x80
|
||||
* INS = 0xC0
|
||||
* P1 = 0x00
|
||||
* P1 = data type
|
||||
* P2 = segment flag
|
||||
* Data = the data to sign
|
||||
* Response = if P2 indicates last segment, the signature is returned
|
||||
* Response SW = 0x9000 on success, 0x6A86 if P2 is invalid
|
||||
* Preconditions: Secure Channel must be opened, user PIN must be verified, a valid keypair must be loaded
|
||||
|
||||
P1:
|
||||
* 0x00 = transaction data
|
||||
* 0x01 = precomputed hash
|
||||
|
||||
P2:
|
||||
|
||||
* bit 0 = if 1 first block, if 0 other block
|
||||
@ -143,7 +147,7 @@ P2:
|
||||
Used to sign transactions. Since the maximum short APDU size is 255 bytes the transaction must be segmented before
|
||||
being sent if it is larger than that. The overhead from the Secure Channel must be also accounted for. When the last
|
||||
segment is sent, the card returns the calculated signature. The signature is an ECDSA signature calculated over the
|
||||
SHA-1 hash of the sent data.
|
||||
SHA-256 hash of the sent data.
|
||||
|
||||
The P2 parameter is used to manage the signing session and is treated as a bitmask. The rightmost bit indicates whether
|
||||
this block is the first one (1) or not (0). On the first block the card resets the signature state. The leftmost bit
|
||||
|
@ -36,8 +36,6 @@ im.status.gradle.gpshell.kvn=2
|
||||
|
||||
## Implementation notes
|
||||
|
||||
* This implementation will try to use only features available in JavaCard 2.2.2 for broader compatibility with existing
|
||||
hardware.
|
||||
* The class byte of the APDU is not checked since there are no conflicting INS code.
|
||||
* Automated tests using JUnit 5 are included. The test require the application to be already installed. The first
|
||||
card terminal found by Java will be used, to please disconnect all card terminals except the one to be used for
|
||||
|
@ -14,7 +14,7 @@ buildscript {
|
||||
}
|
||||
|
||||
javacard {
|
||||
sdkVersion = "2.2.2"
|
||||
sdkVersion = "3.0.4"
|
||||
|
||||
cap {
|
||||
aid = '0x53:0x74:0x61:0x74:0x75:0x73:0x57:0x61:0x6c:0x6c:0x65:0x74'
|
||||
|
@ -19,6 +19,9 @@ public class WalletApplet extends Applet {
|
||||
|
||||
static final byte LOAD_KEY_EC = 0x01;
|
||||
|
||||
static final byte SIGN_DATA = 0x00;
|
||||
static final byte SIGN_PRECOMPUTED_HASH = 0x01;
|
||||
|
||||
static final byte SIGN_FIRST_BLOCK_MASK = 0x01;
|
||||
static final byte SIGN_LAST_BLOCK_MASK = (byte) 0x80;
|
||||
|
||||
@ -56,7 +59,7 @@ public class WalletApplet extends Applet {
|
||||
ECCurves.setSECP256K1CurveParameters(publicKey);
|
||||
ECCurves.setSECP256K1CurveParameters(privateKey);
|
||||
|
||||
signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
|
||||
signature = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
|
||||
|
||||
register(bArray, (short) (bOffset + 1), bArray[bOffset]);
|
||||
}
|
||||
@ -215,7 +218,15 @@ public class WalletApplet extends Applet {
|
||||
|
||||
if ((apduBuffer[ISO7816.OFFSET_P2] & SIGN_LAST_BLOCK_MASK) == SIGN_LAST_BLOCK_MASK) {
|
||||
signInProgress = false;
|
||||
len = signature.sign(apduBuffer, ISO7816.OFFSET_CDATA, len, apduBuffer, SecureChannel.SC_OUT_OFFSET);
|
||||
|
||||
if ((apduBuffer[ISO7816.OFFSET_P1]) == SIGN_DATA) {
|
||||
len = signature.sign(apduBuffer, ISO7816.OFFSET_CDATA, len, apduBuffer, SecureChannel.SC_OUT_OFFSET);
|
||||
} else if ((apduBuffer[ISO7816.OFFSET_P1]) == SIGN_PRECOMPUTED_HASH) {
|
||||
len = signature.signPreComputedHash(apduBuffer, ISO7816.OFFSET_CDATA, len, apduBuffer, SecureChannel.SC_OUT_OFFSET);
|
||||
} else {
|
||||
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
|
||||
}
|
||||
|
||||
len = secureChannel.encryptAPDU(apduBuffer, len);
|
||||
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len);
|
||||
} else {
|
||||
|
@ -274,7 +274,7 @@ public class WalletAppletTest {
|
||||
|
||||
KeyPairGenerator g = keypairGenerator();
|
||||
KeyPair keyPair = keypairGenerator().generateKeyPair();
|
||||
Signature signature = Signature.getInstance("ECDSAwithSHA1", "BC");
|
||||
Signature signature = Signature.getInstance("ECDSAwithSHA256", "BC");
|
||||
signature.initVerify(keyPair.getPublic());
|
||||
|
||||
response = cmdSet.loadKey(keyPair);
|
||||
|
Loading…
x
Reference in New Issue
Block a user