add ability to SIGN precomputed hashes. Switch to ECDSA with SHA256 for

data sign
This commit is contained in:
Michele Balistreri 2017-10-04 15:10:59 +03:00
parent ac5929a9fe
commit a78c5340c2
5 changed files with 21 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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 {

View File

@ -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);