From 5e8b2e0886049fe43d991fafa94bebcbde6a1f02 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 5 Dec 2017 23:35:06 +0100 Subject: Specialize test suites in reader package to classes. --- .../reader/test/CardInvalidCurvesSuite.java | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java (limited to 'src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java new file mode 100644 index 0000000..e4e55c9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -0,0 +1,70 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import javacard.security.KeyPair; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardInvalidCurvesSuite extends CardTestSuite { + + public CardInvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); + } + + @Override + public void setup(CardMngr cardManager) throws IOException { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + */ + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + List ecdhTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()); + ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + } + tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + } + } +} -- cgit v1.2.3-70-g09d2 From f40db310cdb28d39e1bb050e9adb920f4b35a8ed Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 27 Dec 2017 18:29:52 +0100 Subject: Cleanup the applet ECKA and Signature objects. --- src/cz/crcs/ectester/applet/ECKeyTester.java | 204 ++++++--------------- src/cz/crcs/ectester/applet/ECTesterApplet.java | 186 +++++++------------ src/cz/crcs/ectester/applet/EC_Consts.java | 7 - src/cz/crcs/ectester/common/ec/EC_KAResult.java | 18 +- .../ectester/common/output/BaseTextTestWriter.java | 2 +- src/cz/crcs/ectester/common/util/CardUtil.java | 52 ++++-- src/cz/crcs/ectester/data/EC_Store.java | 21 +-- src/cz/crcs/ectester/reader/ECTesterReader.java | 45 ++--- src/cz/crcs/ectester/reader/command/Command.java | 79 ++++---- src/cz/crcs/ectester/reader/response/Response.java | 59 +++--- .../reader/test/CardCompositeCurvesSuite.java | 3 +- .../ectester/reader/test/CardDefaultSuite.java | 2 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../crcs/ectester/reader/test/CardTestSuite.java | 14 +- .../ectester/reader/test/CardTestVectorSuite.java | 2 +- 15 files changed, 274 insertions(+), 422 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java') diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 0b3c1e0..732cb4c 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -3,7 +3,6 @@ package cz.crcs.ectester.applet; import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; -import javacard.framework.ISOException; import javacard.security.*; /** @@ -13,77 +12,35 @@ import javacard.security.*; * @author Jan Jancar johny@neuromancer.sk */ public class ECKeyTester { - - private KeyAgreement ecdhKeyAgreement = null; - private KeyAgreement ecdhcKeyAgreement = null; + private KeyAgreement ecKeyAgreement = null; + private short kaType = 0; private Signature ecdsaSignature = null; + private short sigType = 0; private short sw = ISO7816.SW_NO_ERROR; - public short allocateECDH(byte algorithm) { + public short allocateKA(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecdhKeyAgreement = KeyAgreement.getInstance(algorithm, false); + ecKeyAgreement = KeyAgreement.getInstance(algorithm, false); + kaType = algorithm; } catch (CardRuntimeException ce) { sw = ce.getReason(); } return sw; } - public short allocateECDHC(byte algorithm) { + public short allocateSig(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecdhcKeyAgreement = KeyAgreement.getInstance(algorithm, false); + ecdsaSignature = Signature.getInstance(algorithm, false); + sigType = algorithm; } catch (CardRuntimeException ce) { sw = ce.getReason(); } return sw; } - public short allocateECDSA() { - sw = ISO7816.SW_NO_ERROR; - try { - ecdsaSignature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); - } catch (CardRuntimeException ce) { - sw = ce.getReason(); - } - return sw; - } - - private short testKA(KeyAgreement ka, KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { - short length = 0; - try { - sw = AppletUtil.kaCheck(ka); - sw = AppletUtil.keypairCheck(privatePair); - sw = AppletUtil.keypairCheck(publicPair); - short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); - // reached ok - ka.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used - //ISOException.throwIt((short) 0x666); - - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); - length = ka.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); - } catch (CardRuntimeException ce) { - sw = ce.getReason(); - } - return length; - } - - private short testKA_direct(KeyAgreement ka, KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { - short length = 0; - try { - sw = AppletUtil.kaCheck(ka); - sw = AppletUtil.keypairCheck(privatePair); - - ka.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength); - length = ka.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); - } catch (CardRuntimeException ce) { - sw = ce.getReason(); - } - return length; - } - /** * Tests ECDH secret generation with keys from given {@code privatePair} and {@code publicPair}. * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. @@ -98,100 +55,48 @@ public class ECKeyTester { * @param corruption (EC_Consts.CORRUPTION_* | ...) * @return derived secret length **/ - public short testECDH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { - return testKA(ecdhKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); - } - - public short testECDH_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { - return testKA_direct(ecdhKeyAgreement, privatePair, pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset, corruption); - } - - /** - * Tests ECDHC secret generation with keys from given {@code privatePair} and {@code publicPair}. - * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. - * Output should equal to ECDH output. - * - * @param privatePair KeyPair from which the private key is used - * @param publicPair KeyPair from which the public key is used - * @param pubkeyBuffer buffer to be used for the public key - * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key - * @param outputBuffer buffer to be used for the secret output - * @param outputOffset offset into the outputBuffer - * @param corruption (EC_Consts.CORRUPTION_* | ...) - * @return derived secret length - */ - public short testECDHC(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { - return testKA(ecdhcKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); - } - - public short testECDHC_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { - return testKA_direct(ecdhcKeyAgreement, privatePair, pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset, corruption); - } - - /** - * @param privatePair KeyPair from which the private key is used - * @param publicPair KeyPair from which the public key is used - * @param pubkeyBuffer buffer to be used for the public key - * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key - * @param outputBuffer buffer to be used for the secret output - * @param outputOffset offset into the outputBuffer - * @param corruption (EC_Consts.CORRUPTION_* | ...) - * @return - */ - public short testBOTH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { - short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); - if (sw != ISO7816.SW_NO_ERROR) { - return ecdhLength; - } - short ecdhcLength = testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, (short) (outputOffset + ecdhLength), corruption); - short length = (short) (ecdhLength + ecdhcLength); - if (sw != ISO7816.SW_NO_ERROR) { - return length; - } - if (javacard.framework.Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short) (outputOffset + ecdhLength), ecdhLength) != 0) { - sw = ECTesterApplet.SW_DH_DHC_MISMATCH; - } - return length; - } + public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { + short length = 0; + try { + sw = AppletUtil.kaCheck(ecKeyAgreement); + sw = AppletUtil.keypairCheck(privatePair); + sw = AppletUtil.keypairCheck(publicPair); + short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); + // reached ok + ecKeyAgreement.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used + //ISOException.throwIt((short) 0x666); - public short testBOTH_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset, short corruption) { - short ecdhLength = testECDH_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption); - if (sw != ISO7816.SW_NO_ERROR) { - return ecdhLength; - } - short ecdhcLength = testECDHC_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption); - short length = (short) (ecdhLength + ecdhcLength); - if (sw != ISO7816.SW_NO_ERROR) { - return length; - } - if (javacard.framework.Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short) (outputOffset + ecdhLength), ecdhLength) != 0) { - sw = ECTesterApplet.SW_DH_DHC_MISMATCH; + pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); + length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); + } catch (CardRuntimeException ce) { + sw = ce.getReason(); } return length; } /** - * @param privatePair KeyPair from which the private key is used - * @param publicPair KeyPair from which the public key is used - * @param pubkeyBuffer buffer to be used for the public key - * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key - * @param outputBuffer buffer to be used for the secret output - * @param outputOffset offset into the outputBuffer - * @param corruption (EC_Consts.CORRUPTION_* | ...) + * @param privatePair + * @param pubkey + * @param pubkeyOffset + * @param pubkeyLength + * @param outpuBuffer + * @param outputOffset + * @param corruption * @return */ - public short testANY(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { - short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); - if (sw == ISO7816.SW_NO_ERROR) - return ecdhLength; - return testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); - } + public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { + short length = 0; + try { + sw = AppletUtil.kaCheck(ecKeyAgreement); + sw = AppletUtil.keypairCheck(privatePair); - public short testANY_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset, short corruption) { - short ecdhLength = testECDH_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption); - if (sw == ISO7816.SW_NO_ERROR) - return ecdhLength; - return testECDHC_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption); + ecKeyAgreement.init(privatePair.getPrivate()); + pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength); + length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; } /** @@ -227,32 +132,31 @@ public class ECKeyTester { return length; } - public KeyAgreement getECDH() { - return ecdhKeyAgreement; + public KeyAgreement getKA() { + return ecKeyAgreement; } - public KeyAgreement getECDHC() { - return ecdhcKeyAgreement; + public Signature getSig() { + return ecdsaSignature; } - public Signature getECDSA() { - return ecdsaSignature; + public boolean hasKA() { + return ecKeyAgreement != null; } - public boolean hasECDH() { - return ecdhKeyAgreement != null; + public boolean hasSig() { + return ecdsaSignature != null; } - public boolean hasECDHC() { - return ecdhcKeyAgreement != null; + public short getKaType() { + return kaType; } - public boolean hasECDSA() { - return ecdsaSignature != null; + public short getSigType() { + return sigType; } public short getSW() { return sw; } - } diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index deb3aae..870fb3d 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -26,11 +26,7 @@ package cz.crcs.ectester.applet; import javacard.framework.*; -import javacard.security.ECPrivateKey; -import javacard.security.ECPublicKey; -import javacard.security.KeyAgreement; -import javacard.security.KeyPair; -import javacard.security.RandomData; +import javacard.security.*; import javacardx.apdu.ExtendedLength; /** @@ -55,8 +51,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ECDH_DIRECT = (byte) 0x71; public static final byte INS_ECDSA = (byte) 0x72; public static final byte INS_CLEANUP = (byte) 0x73; - public static final byte INS_SUPPORT = (byte) 0x74; + //public static final byte INS_SUPPORT = (byte) 0x74; public static final byte INS_ALLOCATE_KA = (byte) 0x75; + public static final byte INS_ALLOCATE_SIG = (byte) 0x76; // PARAMETERS for P1 and P2 @@ -88,6 +85,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; public static final byte KeyAgreement_ALG_DH_PLAIN = 7; + // Class javacard.security.Signature + // javacard.security.Signature Fields: + public static final byte Signature_ALG_ECDSA_SHA = 17; + public static final byte Signature_ALG_ECDSA_SHA_256 = 33; + public static final byte Signature_ALG_ECDSA_SHA_384 = 34; + public static final byte Signature_ALG_ECDSA_SHA_224 = 37; + public static final byte Signature_ALG_ECDSA_SHA_512 = 38; private static final short ARRAY_LENGTH = (short) 0xff; private static final short APDU_MAX_LENGTH = (short) 1024; @@ -98,13 +102,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength { // PERSISTENT ARRAY IN EEPROM private byte[] dataArray = null; // unused - private RandomData randomData = null; private ECKeyTester keyTester = null; - private short ecdhSW; - private short ecdhcSW; - private short ecdsaSW; private ECKeyGenerator keyGenerator = null; private KeyPair localKeypair = null; private KeyPair remoteKeypair = null; @@ -133,11 +133,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { keyGenerator = new ECKeyGenerator(); keyTester = new ECKeyTester(); - ecdhSW = keyTester.allocateECDH(KeyAgreement.ALG_EC_SVDP_DH); - ecdhcSW = keyTester.allocateECDHC(KeyAgreement.ALG_EC_SVDP_DHC); - //ecdhSW = keyTester.allocateECDH((byte) 3); - //ecdhcSW = keyTester.allocateECDHC((byte) 4); - ecdsaSW = keyTester.allocateECDSA(); } register(); } @@ -166,6 +161,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_ALLOCATE_KA: length = insAllocateKA(apdu); break; + case INS_ALLOCATE_SIG: + length = insAllocateSig(apdu); + break; case INS_ALLOCATE: length = insAllocate(apdu); break; @@ -196,9 +194,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_CLEANUP: length = insCleanup(apdu); break; - case INS_SUPPORT: - length = insSupport(apdu); - break; default: // The INS code is not supported by the dispatcher ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); @@ -210,7 +205,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** - * Allocates KeyAgreement object. returns allocate SW + * Allocates KeyAgreement object, returns allocate SW. * * @param apdu DATA = byte KeyAgreementType * @return length of response @@ -218,35 +213,25 @@ public class ECTesterApplet extends Applet implements ExtendedLength { private short insAllocateKA(APDU apdu) { short cdata = apdu.getOffsetCdata(); byte kaType = apduArray[cdata]; -/* - short sw = SW_KA_UNSUPPORTED; - switch (kaType) { - case KeyAgreement_ALG_EC_SVDP_DH: // no break - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: - case KeyAgreement_ALG_EC_PACE_GM: - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: - sw = keyTester.allocateECDH(kaType); - break; - case KeyAgreement_ALG_EC_SVDP_DHC: - case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: - sw = keyTester.allocateECDHC(kaType); - break; - default: - sw = SW_KA_UNSUPPORTED; - break; - } -*/ - // Allocate given type into both DH and DHC objects - short sw = keyTester.allocateECDH(kaType); - short offset = 0; - Util.setShort(apdu.getBuffer(), offset, sw); - offset += 2; - - //sw = keyTester.allocateECDHC(kaType); - Util.setShort(apdu.getBuffer(), offset, sw); - offset += 2; - return offset; + short sw = keyTester.allocateKA(kaType); + Util.setShort(apdu.getBuffer(), (short) 0, sw); + return 2; } + + /** + * Allocates a Signature object, returns allocate SW. + * + * @param apdu DATA = byte SignatureType + * @return length of response + */ + private short insAllocateSig(APDU apdu) { + short cdata = apdu.getOffsetCdata(); + byte sigType = apduArray[cdata]; + short sw = keyTester.allocateSig(sigType); + Util.setShort(apdu.getBuffer(), (short) 0, sw); + return 2; + } + /** * Allocates local and remote keyPairs. * returns allocate SWs @@ -449,7 +434,8 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * * @param apdu P1 = byte keyPair (KEYPAIR_*) * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) - * DATA = short dataLength (00 = random data generated, !00 = data length) + * DATA = byte sigType + * short dataLength (00 = random data generated, !00 = data length) * byte[] data * @return length of response */ @@ -457,13 +443,14 @@ public class ECTesterApplet extends Applet implements ExtendedLength { byte keyPair = apduArray[ISO7816.OFFSET_P1]; byte export = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); + byte sigType = apduArray[cdata]; short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += ecdsa(localKeypair, export, apduArray, cdata, apdu.getBuffer(), (short) 0); + len += ecdsa(localKeypair, sigType, export, apduArray, cdata, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += ecdsa(remoteKeypair, export, apduArray, cdata, apdu.getBuffer(), len); + len += ecdsa(remoteKeypair, sigType, export, apduArray, cdata, apdu.getBuffer(), len); } return len; @@ -481,19 +468,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return cleanup(apdubuf, (short) 0); } - /** - * Returns data about card support for various EC related tasks collected on applet - * install. - * - * @param apdu no data - * @return length of response - */ - private short insSupport(APDU apdu) { - byte[] apdubuf = apdu.getBuffer(); - - return support(apdubuf, (short) 0); - } - /** * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) * @param keyLength key length to set @@ -625,7 +599,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret * @param corruption whether to invalidate the pubkey before ECDH - * @param type KeyAgreement type to test (EC_Consts.KA_* || ...) + * @param type KeyAgreement type to test * @param outBuffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} * @param outOffset output offset in buffer * @return length of data written to the buffer @@ -637,23 +611,14 @@ public class ECTesterApplet extends Applet implements ExtendedLength { KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; short secretLength = 0; - switch (type) { - case EC_Consts.KA_ECDH: - secretLength = keyTester.testECDH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); - break; - case EC_Consts.KA_ECDHC: - secretLength = keyTester.testECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); - break; - case EC_Consts.KA_BOTH: - secretLength = keyTester.testBOTH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); - break; - case EC_Consts.KA_ANY: - secretLength = keyTester.testANY(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); - break; - default: - ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); + if (keyTester.getKaType() == type) { + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + } else { + short allocateSW = keyTester.allocateKA(type); + if (allocateSW == ISO7816.SW_NO_ERROR) { + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + } } - Util.setShort(outBuffer, outOffset, keyTester.getSW()); length += 2; @@ -673,21 +638,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength { KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; short secretLength = 0; - switch (type) { - case EC_Consts.KA_ECDH: - secretLength = keyTester.testECDH_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption); - break; - case EC_Consts.KA_ECDHC: - secretLength = keyTester.testECDHC_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption); - break; - case EC_Consts.KA_BOTH: - secretLength = keyTester.testBOTH_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption); - break; - case EC_Consts.KA_ANY: - secretLength = keyTester.testANY_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption); - break; - default: - ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); + if (keyTester.getKaType() == type) { + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + } else { + short allocateSW = keyTester.allocateKA(type); + if (allocateSW == ISO7816.SW_NO_ERROR) { + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + } } Util.setShort(outBuffer, outOffset, keyTester.getSW()); @@ -704,6 +661,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { /** * @param sign keyPair to use for signing and verification + * @param sigType Signature type to use * @param export whether to export ECDSA signature * @param inBuffer buffer to read dataLength and data to sign from * @param inOffset input offset in buffer @@ -711,7 +669,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short ecdsa(KeyPair sign, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + private short ecdsa(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { short length = 0; short dataLength = Util.getShort(inBuffer, inOffset); @@ -723,7 +681,15 @@ public class ECTesterApplet extends Applet implements ExtendedLength { Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); } - short signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + short signatureLength = 0; + if (keyTester.getSigType() == sigType) { + signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } + } Util.setShort(outBuffer, outOffset, keyTester.getSW()); length += 2; @@ -755,30 +721,4 @@ public class ECTesterApplet extends Applet implements ExtendedLength { Util.setShort(buffer, offset, sw); return 2; } - - /** - * @param buffer buffer to write sw to - * @param offset output offset in buffer - * @return length of data written to the buffer - */ - private short support(byte[] buffer, short offset) { - - if (keyTester.hasECDH()) { - Util.setShort(buffer, offset, ecdhSW); - } else { - Util.setShort(buffer, offset, ISO7816.SW_FUNC_NOT_SUPPORTED); - } - if (keyTester.hasECDHC()) { - Util.setShort(buffer, (short) (offset + 2), ecdhcSW); - } else { - Util.setShort(buffer, (short) (offset + 2), ISO7816.SW_FUNC_NOT_SUPPORTED); - } - if (keyTester.hasECDSA()) { - Util.setShort(buffer, (short) (offset + 4), ecdsaSW); - } else { - Util.setShort(buffer, (short) (offset + 4), ISO7816.SW_FUNC_NOT_SUPPORTED); - } - - return 6; - } } diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 04cd55e..15cb7fa 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -59,13 +59,6 @@ public class EC_Consts { public static final byte KEY_PRIVATE = 0x02; public static final byte KEY_BOTH = KEY_PUBLIC | KEY_PRIVATE; - - // Key Agreement test identifiers - public static final byte KA_ECDH = 0x01; - public static final byte KA_ECDHC = 0x02; - public static final byte KA_BOTH = KA_ECDH | KA_ECDHC; - public static final byte KA_ANY = 0x04; - public static RandomData randomData = null; // secp112r1 diff --git a/src/cz/crcs/ectester/common/ec/EC_KAResult.java b/src/cz/crcs/ectester/common/ec/EC_KAResult.java index a7b3cd5..8a5fcb4 100644 --- a/src/cz/crcs/ectester/common/ec/EC_KAResult.java +++ b/src/cz/crcs/ectester/common/ec/EC_KAResult.java @@ -8,15 +8,14 @@ import cz.crcs.ectester.common.util.CardUtil; * @author Jan Jancar johny@neuromancer.sk */ public class EC_KAResult extends EC_Data { - - private byte ka; + private String ka; private String curve; private String oneKey; private String otherKey; private String desc; - public EC_KAResult(byte ka, String curve, String oneKey, String otherKey) { + public EC_KAResult(String ka, String curve, String oneKey, String otherKey) { super(1); this.ka = ka; this.curve = curve; @@ -24,20 +23,24 @@ public class EC_KAResult extends EC_Data { this.otherKey = otherKey; } - public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey) { + public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey) { this(ka, curve, oneKey, otherKey); this.id = id; } - public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey, String desc) { + public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey, String desc) { this(id, ka, curve, oneKey, otherKey); this.desc = desc; } - public byte getKA() { + public String getKA() { return ka; } + public byte getJavaCardKA() { + return CardUtil.getKA(ka); + } + public String getCurve() { return curve; } @@ -56,8 +59,7 @@ public class EC_KAResult extends EC_Data { @Override public String toString() { - String algo = CardUtil.getKA(ka); - return "<" + getId() + "> " + algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); + return "<" + getId() + "> " + ka + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); } } diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java index 9635d0c..7e0e1a3 100644 --- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -10,7 +10,7 @@ import java.io.PrintStream; public abstract class BaseTextTestWriter implements TestWriter { private PrintStream output; - public static int BASE_WIDTH = 76; + public static int BASE_WIDTH = 80; public BaseTextTestWriter(PrintStream output) { this.output = output; diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index edcb510..55c4277 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -12,6 +12,18 @@ import static cz.crcs.ectester.applet.ECTesterApplet.*; * @author Jan Jancar johny@neuromancer.sk */ public class CardUtil { + public static byte getKA(String name) { + switch (name) { + case "DH": + case "ECDH": + return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + case "DHC": + case "ECDHC": + return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC; + } + return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + } + public static String getSWSource(short sw) { switch (sw) { case ISO7816.SW_NO_ERROR: @@ -214,22 +226,6 @@ public class CardUtil { return corrupt; } - public static String getKA(byte ka) { - String algo = ""; - if ((ka & EC_Consts.KA_ECDH) != 0 || ka == EC_Consts.KA_ANY) { - algo += "ECDH"; - } - if (ka == EC_Consts.KA_BOTH) { - algo += "+"; - } else if (ka == EC_Consts.KA_ANY) { - algo += "/"; - } - if ((ka & EC_Consts.KA_ECDHC) != 0 || ka == EC_Consts.KA_ANY) { - algo += "ECDHC"; - } - return algo; - } - public static String getKATypeString(byte kaType) { String kaTypeString; switch (kaType) { @@ -256,4 +252,28 @@ public class CardUtil { } return kaTypeString; } + + public static String getSigTypeString(byte sigType) { + String sigTypeString; + switch (sigType) { + case Signature_ALG_ECDSA_SHA: + sigTypeString = "ALG_ECDSA_SHA"; + break; + case Signature_ALG_ECDSA_SHA_224: + sigTypeString = "ALG_ECDSA_SHA_224"; + break; + case Signature_ALG_ECDSA_SHA_256: + sigTypeString = "ALG_ECDSA_SHA_256"; + break; + case Signature_ALG_ECDSA_SHA_384: + sigTypeString = "ALG_ECDSA_SHA_384"; + break; + case Signature_ALG_ECDSA_SHA_512: + sigTypeString = "ALG_ECDSA_SHA_512"; + break; + default: + sigTypeString = "unknown"; + } + return sigTypeString; + } } diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index 3103c1d..c25be4e 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.data; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; +import cz.crcs.ectester.common.util.CardUtil; import javacard.security.KeyPair; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -217,25 +218,7 @@ public class EC_Store { descs = descc.item(0).getTextContent(); } - byte kab = EC_Consts.KA_ANY; - switch (ka.getTextContent()) { - case "DH": - case "ECDH": - kab = EC_Consts.KA_ECDH; - break; - case "DHC": - case "ECDHC": - kab = EC_Consts.KA_ECDHC; - break; - case "ANY": - kab = EC_Consts.KA_ANY; - break; - case "BOTH": - kab = EC_Consts.KA_BOTH; - break; - } - - EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); + EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), ka.getTextContent(), curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); InputStream csv = parseDataElement(dir, elem); if (!kaResult.readCSV(csv)) { diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index f566c9c..4e62f3f 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -47,6 +47,7 @@ import java.nio.file.Files; import java.util.*; import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; +import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. @@ -218,8 +219,7 @@ public class ECTesterReader { * -e / --export * -g / --generate [amount] * -t / --test [test_suite] - * -dh / --ecdh [count] - * -dhc / --ecdhc [count] + * -dh / --ecdh [count]] * -dsa / --ecdsa [count] * -ln / --list-named [obj] * @@ -253,6 +253,7 @@ public class ECTesterReader { * -s / --simulate * -y / --yes * -ka/ --ka-type + * -sig/--sig-type */ OptionGroup actions = new OptionGroup(); actions.setRequired(true); @@ -262,8 +263,7 @@ public class ECTesterReader { actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); - actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build()); - actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [count] times.").hasArg().argName("count").optionalArg(true).build()); + actions.addOption(Option.builder("ka").longOpt("ecka").desc("Do EC KeyAgreement (ECDH...), [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build()); opts.addOptionGroup(actions); @@ -308,6 +308,7 @@ public class ECTesterReader { opts.addOption(Option.builder("y").longOpt("yes").desc("Accept all warnings and prompts.").build()); opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build()); + opts.addOption(Option.builder("sig").longOpt("sig-type").desc("Set Signature object [type], corresponds to JC.Signature constants.").hasArg().argName("type").optionalArg(true).build()); CommandLineParser parser = new DefaultParser(); return parser.parse(opts, args); @@ -464,7 +465,7 @@ public class ECTesterReader { private void ecdh() throws IOException, CardException { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List prepare = new LinkedList<>(); - prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.kaType).send()); // Prepare KeyAgreement or required type + prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send()); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); if (curve != null) @@ -491,10 +492,10 @@ public class ECTesterReader { int retry = 0; int done = 0; - while (done < cfg.ECDHCount) { + while (done < cfg.ECKACount) { List ecdh = Command.sendAll(generate); - Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); + Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECKAType).send(); ecdh.add(perform); for (Response r : ecdh) { respWriter.outputResponse(r); @@ -550,6 +551,7 @@ public class ECTesterReader { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List prepare = new LinkedList<>(); + prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send()); prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send()); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); if (curve != null) @@ -571,7 +573,7 @@ public class ECTesterReader { List ecdsa = new LinkedList<>(); ecdsa.add(generate.send()); - Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); + Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.ECDSAType, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); for (Response r : ecdsa) { respWriter.outputResponse(r); @@ -612,7 +614,7 @@ public class ECTesterReader { public boolean all; public boolean primeField = false; public boolean binaryField = false; - public byte kaType = KeyAgreement_ALG_EC_SVDP_DH; + public String namedCurve; public String curveFile; @@ -646,9 +648,10 @@ public class ECTesterReader { public String listNamed; public String testSuite; public int generateAmount; - public int ECDHCount; - public byte ECDHKA; + public int ECKACount; + public byte ECKAType = KeyAgreement_ALG_EC_SVDP_DH; public int ECDSACount; + public byte ECDSAType = Signature_ALG_ECDSA_SHA; /** * Reads and validates options, also sets defaults. @@ -661,7 +664,7 @@ public class ECTesterReader { all = cli.hasOption("all"); primeField = cli.hasOption("fp"); binaryField = cli.hasOption("f2m"); - kaType = Byte.parseByte(cli.getOptionValue("ka-type", "1")); + namedCurve = cli.getOptionValue("named-curve"); customCurve = cli.hasOption("custom"); @@ -779,7 +782,7 @@ public class ECTesterReader { return false; } - } else if (cli.hasOption("ecdh") || cli.hasOption("ecdhc")) { + } else if (cli.hasOption("ecka")) { if (primeField == binaryField) { System.err.print("Need to specify field with -fp or -f2m. (not both)"); return false; @@ -789,18 +792,14 @@ public class ECTesterReader { return false; } - if (cli.hasOption("ecdh")) { - ECDHCount = Integer.parseInt(cli.getOptionValue("ecdh", "1")); - ECDHKA = EC_Consts.KA_ECDH; - } else if (cli.hasOption("ecdhc")) { - ECDHCount = Integer.parseInt(cli.getOptionValue("ecdhc", "1")); - ECDHKA = EC_Consts.KA_ECDHC; - } - if (ECDHCount <= 0) { - System.err.println("ECDH count cannot be <= 0."); + ECKACount = Integer.parseInt(cli.getOptionValue("ecka", "1")); + if (ECKACount <= 0) { + System.err.println("ECKA count cannot be <= 0."); return false; } + ECKAType = Byte.parseByte(cli.getOptionValue("ka-type", "1")); + } else if (cli.hasOption("ecdsa")) { if (primeField == binaryField) { System.err.print("Need to specify field with -fp or -f2m. (but not both)"); @@ -821,6 +820,8 @@ public class ECTesterReader { System.err.println("ECDSA count cannot be <= 0."); return false; } + + ECDSAType = Byte.parseByte(cli.getOptionValue("sig-type", "17")); } return true; } diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 922a33a..5a6906c 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -252,7 +252,40 @@ public abstract class Command { public String toString() { return "AllocateKeyAgreement"; } - } + } + + /** + * + */ + public static class AllocateSignature extends Command { + private byte sigType; + + /** + * Creates the INS_ALLOCATE_SIG instruction. + * + * @param cardManager cardManager to send APDU through + * @param sigType which type of Signature to use + */ + public AllocateSignature(CardMngr cardManager, byte sigType) { + super(cardManager); + this.sigType = sigType; + byte[] data = new byte[]{sigType}; + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_SIG, 0x00, 0x00, data); + } + + @Override + public Response.AllocateSignature send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.AllocateSignature(response, elapsed, sigType); + } + + @Override + public String toString() { + return "AllocateSignature"; + } + } /** * @@ -518,7 +551,7 @@ public abstract class Command { * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) - * @param type ECDH algorithm type (EC_Consts.KA_* | ...) + * @param type EC KeyAgreement type * @param pubkey pubkey data to do ECDH with. */ public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { @@ -553,6 +586,7 @@ public abstract class Command { public static class ECDSA extends Command { private byte keyPair; + private byte sigType; private byte export; private byte[] raw; @@ -561,20 +595,23 @@ public abstract class Command { * * @param cardManager cardManager to send APDU through * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param sigType Signature type to use * @param export whether to export ECDSA signature * @param raw data to sign, can be null, in which case random data is signed. */ - public ECDSA(CardMngr cardManager, byte keyPair, byte export, byte[] raw) { + public ECDSA(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { super(cardManager); this.keyPair = keyPair; + this.sigType = sigType; this.export = export; this.raw = raw; int len = raw != null ? raw.length : 0; - byte[] data = new byte[2 + len]; - ByteUtil.setShort(data, 0, (short) len); + byte[] data = new byte[3 + len]; + data[0] = sigType; + ByteUtil.setShort(data, 1, (short) len); if (raw != null) { - System.arraycopy(raw, 0, data, 2, len); + System.arraycopy(raw, 0, data, 3, len); } this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); @@ -585,7 +622,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDSA(response, elapsed, keyPair, export, raw); + return new Response.ECDSA(response, elapsed, keyPair, sigType, export, raw); } @Override @@ -621,33 +658,5 @@ public abstract class Command { return "Cleanup"; } } - - /** - * - */ - public static class Support extends Command { - - /** - * @param cardManager cardManager to send APDU through - */ - public Support(CardMngr cardManager) { - super(cardManager); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SUPPORT, 0, 0); - } - - @Override - public Response.Support send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Support(response, elapsed); - } - - @Override - public String toString() { - return "Support"; - } - } } diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 3b5d98b..cbed3b2 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -133,24 +133,44 @@ public abstract class Response { * */ public static class AllocateKeyAgreement extends Response { - byte kaType; + private byte kaType; public AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) { super(response, time); this.kaType = kaType; - parse(2, 0); + parse(1, 0); } @Override public String getDescription() { return String.format("Allocated KeyAgreement(%s) object", CardUtil.getKATypeString(this.kaType)); } + } + + /** + * + */ + public static class AllocateSignature extends Response { + private byte sigType; + + public AllocateSignature(ResponseAPDU response, long time, byte sigType) { + super(response, time); + this.sigType = sigType; + parse(1, 0); + } + + @Override + public String getDescription() { + return String.format("Allocated Signature(%s) object", CardUtil.getSigTypeString(this.sigType)); + } } + /** + * + */ public static class Allocate extends Response { - private byte keyPair; private short keyLength; private byte keyClass; @@ -184,7 +204,6 @@ public abstract class Response { * */ public static class Clear extends Response { - private byte keyPair; public Clear(ResponseAPDU response, long time, byte keyPair) { @@ -213,7 +232,6 @@ public abstract class Response { * */ public static class Set extends Response { - private byte keyPair; private byte curve; private short parameters; @@ -271,7 +289,6 @@ public abstract class Response { * */ public static class Corrupt extends Response { - private byte keyPair; private byte key; private short params; @@ -309,7 +326,6 @@ public abstract class Response { * */ public static class Generate extends Response { - private byte keyPair; public Generate(ResponseAPDU response, long time, byte keyPair) { @@ -339,7 +355,6 @@ public abstract class Response { * */ public static class Export extends Response { - private byte keyPair; private byte key; private short parameters; @@ -448,7 +463,6 @@ public abstract class Response { * */ public static class ECDH extends Response { - private byte pubkey; private byte privkey; private byte export; @@ -480,7 +494,7 @@ public abstract class Response { @Override public String getDescription() { - String algo = CardUtil.getKA(type); + String algo = CardUtil.getKATypeString(type); String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; @@ -499,14 +513,15 @@ public abstract class Response { * */ public static class ECDSA extends Response { - private byte keyPair; + private byte sigType; private byte export; private byte[] raw; - public ECDSA(ResponseAPDU response, long time, byte keyPair, byte export, byte[] raw) { + public ECDSA(ResponseAPDU response, long time, byte keyPair, byte sigType, byte export, byte[] raw) { super(response, time); this.keyPair = keyPair; + this.sigType = sigType; this.export = export; this.raw = raw; @@ -523,9 +538,10 @@ public abstract class Response { @Override public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String data = raw == null ? "random" : "provided"; - return String.format("ECDSA with %s keypair(%s data)", key, data); + return String.format("%s with %s keypair(%s data)", algo, key, data); } } @@ -546,21 +562,4 @@ public abstract class Response { } } - - /** - * - */ - public static class Support extends Response { - - public Support(ResponseAPDU response, long time) { - super(response, time); - - parse(3, 0); - } - - @Override - public String getDescription() { - return "Support of ECDH, ECDHC, ECDSA allocation"; - } - } } diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 930a0d0..08e45ac 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -8,6 +8,7 @@ import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.ec.EC_Key; +import javacard.security.KeyAgreement; import javacard.security.KeyPair; import java.util.Map; @@ -44,7 +45,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite { tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()); + Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); tests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index 06818d4..eb46de0 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -23,7 +23,7 @@ public class CardDefaultSuite extends CardTestSuite { @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); + //tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); if (cfg.namedCurve != null) { String desc = "Default tests over the " + cfg.namedCurve + " curve category."; if (cfg.primeField) { diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index e4e55c9..00e3a46 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -60,7 +60,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java index 3da5158..5d34a13 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -47,13 +47,13 @@ public abstract class CardTestSuite extends TestSuite { List tests = new LinkedList<>(); tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ecdhExpected)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ecdhExpected)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE)); + tests.add(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return CompoundTest.function((testArray) -> { Function shouldHave = (expected) -> { diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index 72e3cce..e1c499c 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -67,7 +67,7 @@ public class CardTestVectorSuite extends CardTestSuite { //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), new TestCallback() { + testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { @Override public Result apply(CommandTestable testable) { Response.ECDH dh = (Response.ECDH) testable.getResponse(); -- cgit v1.2.3-70-g09d2 From 67c963266711f863a024bd6d7ff6e6da5d7b08b8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Dec 2017 00:51:41 +0100 Subject: Hide the Cleanup command in test suites. --- .../ectester/common/output/BaseYAMLTestWriter.java | 4 +-- src/cz/crcs/ectester/common/test/BaseRunnable.java | 31 ++++++++++++++++++++++ src/cz/crcs/ectester/common/test/Runnable.java | 18 +++++++++++++ src/cz/crcs/ectester/common/test/TestRunner.java | 6 +++-- src/cz/crcs/ectester/common/test/TestSuite.java | 13 +++++++-- src/cz/crcs/ectester/common/test/Testable.java | 15 +---------- src/cz/crcs/ectester/reader/ECTesterReader.java | 4 +-- .../reader/test/CardCompositeCurvesSuite.java | 16 +++++------ .../ectester/reader/test/CardDefaultSuite.java | 19 ++++++------- .../reader/test/CardInvalidCurvesSuite.java | 13 ++++----- .../crcs/ectester/reader/test/CardTestSuite.java | 14 +++++----- .../ectester/reader/test/CardTestVectorSuite.java | 12 +++------ .../ectester/reader/test/CardWrongCurvesSuite.java | 10 +++---- .../standalone/test/StandaloneDefaultSuite.java | 10 +++---- 14 files changed, 114 insertions(+), 71 deletions(-) create mode 100644 src/cz/crcs/ectester/common/test/BaseRunnable.java create mode 100644 src/cz/crcs/ectester/common/test/Runnable.java (limited to 'src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java') diff --git a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java index af76927..955a144 100644 --- a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java @@ -33,7 +33,7 @@ public abstract class BaseYAMLTestWriter implements TestWriter { testSuite.put("desc", suite.getDescription()); testRun.put("suite", testSuite); - testRun.put("tests", tests); + testRun.put("run", tests); } abstract protected Map testableObject(Testable t); @@ -48,7 +48,7 @@ public abstract class BaseYAMLTestWriter implements TestWriter { for (Test innerTest : test.getTests()) { innerTests.add(testObject(innerTest)); } - testObj.put("tests", innerTests); + testObj.put("run", innerTests); } else { SimpleTest test = (SimpleTest) t; testObj = testableObject(test.getTestable()); diff --git a/src/cz/crcs/ectester/common/test/BaseRunnable.java b/src/cz/crcs/ectester/common/test/BaseRunnable.java new file mode 100644 index 0000000..3e18208 --- /dev/null +++ b/src/cz/crcs/ectester/common/test/BaseRunnable.java @@ -0,0 +1,31 @@ +package cz.crcs.ectester.common.test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class BaseRunnable implements Runnable { + private boolean hasRun = false; + private Func runImplicit; + + public BaseRunnable(Func runImplicit) { + this.runImplicit = runImplicit; + } + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public void run() throws TestException { + if (!hasRun) { + runImplicit.run(); + } + hasRun = true; + } + + @FunctionalInterface + public interface Func { + void run() throws TestException; + } +} diff --git a/src/cz/crcs/ectester/common/test/Runnable.java b/src/cz/crcs/ectester/common/test/Runnable.java new file mode 100644 index 0000000..6f0efb0 --- /dev/null +++ b/src/cz/crcs/ectester/common/test/Runnable.java @@ -0,0 +1,18 @@ +package cz.crcs.ectester.common.test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface Runnable { + /** + * @return Whether this runnable was run. + */ + boolean hasRun(); + + /** + * Run this Runnable. + * + * @throws TestException + */ + void run() throws TestException; +} diff --git a/src/cz/crcs/ectester/common/test/TestRunner.java b/src/cz/crcs/ectester/common/test/TestRunner.java index ef448c2..cd71bcd 100644 --- a/src/cz/crcs/ectester/common/test/TestRunner.java +++ b/src/cz/crcs/ectester/common/test/TestRunner.java @@ -16,10 +16,12 @@ public class TestRunner { public void run() throws TestException { writer.begin(suite); - for (Test t : suite.getTests()) { + for (Runnable t : suite.getRunnables()) { if (!t.hasRun()) { t.run(); - writer.outputTest(t); + if (t instanceof Test) { + writer.outputTest((Test) t); + } } } writer.end(); diff --git a/src/cz/crcs/ectester/common/test/TestSuite.java b/src/cz/crcs/ectester/common/test/TestSuite.java index 74a24af..1a7c914 100644 --- a/src/cz/crcs/ectester/common/test/TestSuite.java +++ b/src/cz/crcs/ectester/common/test/TestSuite.java @@ -5,6 +5,7 @@ import cz.crcs.ectester.data.EC_Store; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; /** * @author Jan Jancar johny@neuromancer.sk @@ -12,7 +13,7 @@ import java.util.List; public abstract class TestSuite { protected String name; protected String description; - protected List tests = new LinkedList<>(); + protected List run = new LinkedList<>(); protected EC_Store dataStore; public TestSuite(EC_Store dataStore, String name, String description) { @@ -21,8 +22,16 @@ public abstract class TestSuite { this.description = description; } + public List getRunnables() { + return Collections.unmodifiableList(run); + } + + @SuppressWarnings("unchecked") public List getTests() { - return Collections.unmodifiableList(tests); + return Collections.unmodifiableList((List)(List) run + .stream() + .filter(runnable -> (runnable instanceof Test)) + .collect(Collectors.toList())); } public String getName() { diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java index 001121b..cc7a5de 100644 --- a/src/cz/crcs/ectester/common/test/Testable.java +++ b/src/cz/crcs/ectester/common/test/Testable.java @@ -3,20 +3,7 @@ package cz.crcs.ectester.common.test; /** * @author Jan Jancar johny@neuromancer.sk */ -public interface Testable { - - /** - * @return Whether this testable was run. - */ - boolean hasRun(); - - /** - * Run this Testable. - * - * @throws TestException - */ - void run() throws TestException; - +public interface Testable extends Runnable { /** * @return Whether this Testable was OK. */ diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index c9d083c..4699c96 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -425,9 +425,9 @@ public class ECTesterReader { suite = new CardTestVectorSuite(dataStore, cfg); break; default: - // These tests are dangerous, prompt before them. + // These run are dangerous, prompt before them. System.out.println("The test you selected (" + cfg.testSuite + ") is potentially dangerous."); - System.out.println("Some of these tests have caused temporary DoS of some cards."); + System.out.println("Some of these run have caused temporary DoS of some cards."); if (!cfg.yes) { System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 08e45ac..2c2ba26 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -2,13 +2,13 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.test.BaseRunnable; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.ec.EC_Key; -import javacard.security.KeyAgreement; import javacard.security.KeyPair; import java.util.Map; @@ -21,12 +21,12 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardCompositeCurvesSuite extends CardTestSuite { public CardCompositeCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "composite", "The composite suite tests ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); + super(dataStore, cfg, "composite", "The composite suite run ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); } @Override public void setup(CardMngr cardManager) { - /* Do the default tests with the public keys set to provided smallorder keys + /* Do the default run with the public keys set to provided smallorder keys * over composite order curves. Essentially small subgroup attacks. * These should fail, the curves aren't safe so that if the computation with * a small order public key succeeds the private key modulo the public key order @@ -42,12 +42,12 @@ public class CardCompositeCurvesSuite extends CardTestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); - tests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + run.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); + run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index eb46de0..7e7adbb 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.test.BaseRunnable; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; @@ -18,19 +19,19 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardDefaultSuite extends CardTestSuite { public CardDefaultSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "default", "The default test suite tests basic support of ECDH and ECDSA."); + super(dataStore, cfg, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override public void setup(CardMngr cardManager) throws IOException { - //tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); + //run.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); if (cfg.namedCurve != null) { - String desc = "Default tests over the " + cfg.namedCurve + " curve category."; + String desc = "Default run over the " + cfg.namedCurve + " curve category."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); } } else { if (cfg.all) { @@ -59,11 +60,11 @@ public class CardDefaultSuite extends CardTestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); + run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(CommandTest.expect(curve, ExpectedValue.SUCCESS)); - tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + run.add(CommandTest.expect(curve, ExpectedValue.SUCCESS)); + run.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default run.")); + run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 00e3a46..3c0795b 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.test.BaseRunnable; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; @@ -26,7 +27,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardInvalidCurvesSuite extends CardTestSuite { public CardInvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); + super(dataStore, cfg, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); } @Override @@ -55,16 +56,16 @@ public class CardInvalidCurvesSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } - tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java index 5d34a13..7035ca2 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -3,10 +3,8 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestSuite; +import cz.crcs.ectester.common.test.*; +import cz.crcs.ectester.common.test.Runnable; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; @@ -98,10 +96,10 @@ public abstract class CardTestSuite extends TestSuite { * @param ecdhCompressedExpected expected result of the ECDH command with a compressed point. * @param ecdsaExpected expected result of the ordinary ECDSA command * @param description compound test description - * @return tests to run + * @return run to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { - List tests = new LinkedList<>(); + List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { + List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) return tests; @@ -111,7 +109,7 @@ public abstract class CardTestSuite extends TestSuite { tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index e1c499c..025cbe0 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -3,10 +3,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestCallback; +import cz.crcs.ectester.common.test.*; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; @@ -64,7 +61,7 @@ public class CardTestVectorSuite extends CardTestSuite { testVector.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + //run.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { @@ -82,9 +79,8 @@ public class CardTestVectorSuite extends CardTestSuite { return new Result(Value.SUCCESS); } })); - tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); - + run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 4c529da..8c21aef 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -15,20 +15,20 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardWrongCurvesSuite extends CardTestSuite { public CardWrongCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); + super(dataStore, cfg, "wrong", "The wrong curve suite run whether the card rejects domain parameters which are not curves."); } @Override public void setup(CardMngr cardManager) throws IOException { - /* Just do the default tests on the wrong curves. + /* Just do the default run on the wrong curves. * These should generally fail, the curves aren't curves. */ - String desc = "Default tests over wrong curve params."; + String desc = "Default run over wrong curve params."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); } } } diff --git a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java index 7056d69..b24244e 100644 --- a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java +++ b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java @@ -21,7 +21,7 @@ import java.security.spec.ECParameterSpec; public class StandaloneDefaultSuite extends StandaloneTestSuite { public StandaloneDefaultSuite(EC_Store dataStore, ECTesterStandalone.Config cfg, TreeCommandLine cli) { - super(dataStore, cfg, cli, "default", "The default test suite tests basic support of ECDH and ECDSA."); + super(dataStore, cfg, cli, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override @@ -57,19 +57,19 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg); } - tests.add(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); - tests.add(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); + run.add(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); + run.add(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.contains(kaAlgo)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - tests.add(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); + run.add(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); } } for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.contains(sigAlgo)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - tests.add(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); + run.add(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); } } } -- cgit v1.2.3-70-g09d2 From 94e441b522069d3fed4b88a4823b91c1593bac68 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 9 Jan 2018 13:46:29 +0100 Subject: Simplify test suites. --- src/cz/crcs/ectester/applet/ECTesterApplet.java | 1 - src/cz/crcs/ectester/applet/EC_Consts.java | 23 +++++- src/cz/crcs/ectester/common/cli/TreeParser.java | 8 +++ src/cz/crcs/ectester/common/test/BaseRunnable.java | 31 --------- src/cz/crcs/ectester/common/test/Runnable.java | 18 ----- src/cz/crcs/ectester/common/test/TestRunner.java | 29 -------- src/cz/crcs/ectester/common/test/TestSuite.java | 35 ++++++---- src/cz/crcs/ectester/common/test/Testable.java | 13 +++- src/cz/crcs/ectester/data/EC_Store.java | 16 +++-- src/cz/crcs/ectester/reader/ECTesterReader.java | 77 ++++++++++---------- .../reader/test/CardCompositeCurvesSuite.java | 31 ++++----- .../ectester/reader/test/CardDefaultSuite.java | 81 ++++++++++------------ .../reader/test/CardInvalidCurvesSuite.java | 34 ++++----- .../crcs/ectester/reader/test/CardTestSuite.java | 33 ++++----- .../ectester/reader/test/CardTestVectorSuite.java | 39 +++++------ .../ectester/reader/test/CardWrongCurvesSuite.java | 48 +++++++++---- .../ectester/standalone/ECTesterStandalone.java | 17 ++--- .../standalone/test/StandaloneDefaultSuite.java | 18 ++--- .../standalone/test/StandaloneTestSuite.java | 7 +- 19 files changed, 265 insertions(+), 294 deletions(-) delete mode 100644 src/cz/crcs/ectester/common/test/BaseRunnable.java delete mode 100644 src/cz/crcs/ectester/common/test/Runnable.java delete mode 100644 src/cz/crcs/ectester/common/test/TestRunner.java (limited to 'src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java') diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 870fb3d..71d9d56 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -83,7 +83,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; - public static final byte KeyAgreement_ALG_DH_PLAIN = 7; // Class javacard.security.Signature // javacard.security.Signature Fields: diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 15cb7fa..4581fd6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -1002,7 +1002,7 @@ public class EC_Consts { public static final byte CURVE_default = (byte) 0; public static final byte CURVE_external = (byte) 0xff; - // SECP recommended curves over FP + // SECG recommended curves over FP public static final byte CURVE_secp112r1 = (byte) 1; public static final byte CURVE_secp128r1 = (byte) 2; public static final byte CURVE_secp160r1 = (byte) 3; @@ -1014,7 +1014,7 @@ public class EC_Consts { public static final byte FP_CURVES = (byte) 8; - // SECP recommended curves over F2M + // SECG recommended curves over F2M public static final byte CURVE_sect163r1 = (byte) 9; public static final byte CURVE_sect233r1 = (byte) 10; public static final byte CURVE_sect283r1 = (byte) 11; @@ -1026,6 +1026,25 @@ public class EC_Consts { public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521}; public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571}; + public static final byte[] KA_TYPES = new byte[]{ + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, + //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC, + //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN, + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, + ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM, + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY + }; + + public static final byte[] SIG_TYPES = new byte[]{ + ECTesterApplet.Signature_ALG_ECDSA_SHA, + ECTesterApplet.Signature_ALG_ECDSA_SHA_224, + ECTesterApplet.Signature_ALG_ECDSA_SHA_256, + ECTesterApplet.Signature_ALG_ECDSA_SHA_384, + ECTesterApplet.Signature_ALG_ECDSA_SHA_512 + }; + public static byte getCurve(short keyLength, byte keyClass) { if (keyClass == KeyPair.ALG_EC_FP) { switch (keyLength) { diff --git a/src/cz/crcs/ectester/common/cli/TreeParser.java b/src/cz/crcs/ectester/common/cli/TreeParser.java index 77cce30..f1a1980 100644 --- a/src/cz/crcs/ectester/common/cli/TreeParser.java +++ b/src/cz/crcs/ectester/common/cli/TreeParser.java @@ -86,6 +86,7 @@ public class TreeParser implements CommandLineParser { } } + int maxArgs = args.size(); long requiredArgs = args.stream().filter(Argument::isRequired).count(); String reqArgs = String.join(" ", args.stream().filter(Argument::isRequired).map(Argument::getName).collect(Collectors.toList())); @@ -99,6 +100,8 @@ public class TreeParser implements CommandLineParser { if (lastCli.getArgs().length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (lastCli.getArgs().length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } subTreeCli.setName(sub); @@ -106,6 +109,8 @@ public class TreeParser implements CommandLineParser { } else if (subCli != null) { if (subCli.getArgs().length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (subCli.getArgs().length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } TreeCommandLine subTreeCli = new TreeCommandLine(sub, subCli, null); @@ -113,7 +118,10 @@ public class TreeParser implements CommandLineParser { } else { if (cliArgs.length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (cliArgs.length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } + return new TreeCommandLine(cli, null); } } diff --git a/src/cz/crcs/ectester/common/test/BaseRunnable.java b/src/cz/crcs/ectester/common/test/BaseRunnable.java deleted file mode 100644 index 3e18208..0000000 --- a/src/cz/crcs/ectester/common/test/BaseRunnable.java +++ /dev/null @@ -1,31 +0,0 @@ -package cz.crcs.ectester.common.test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class BaseRunnable implements Runnable { - private boolean hasRun = false; - private Func runImplicit; - - public BaseRunnable(Func runImplicit) { - this.runImplicit = runImplicit; - } - - @Override - public boolean hasRun() { - return hasRun; - } - - @Override - public void run() throws TestException { - if (!hasRun) { - runImplicit.run(); - } - hasRun = true; - } - - @FunctionalInterface - public interface Func { - void run() throws TestException; - } -} diff --git a/src/cz/crcs/ectester/common/test/Runnable.java b/src/cz/crcs/ectester/common/test/Runnable.java deleted file mode 100644 index 6f0efb0..0000000 --- a/src/cz/crcs/ectester/common/test/Runnable.java +++ /dev/null @@ -1,18 +0,0 @@ -package cz.crcs.ectester.common.test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public interface Runnable { - /** - * @return Whether this runnable was run. - */ - boolean hasRun(); - - /** - * Run this Runnable. - * - * @throws TestException - */ - void run() throws TestException; -} diff --git a/src/cz/crcs/ectester/common/test/TestRunner.java b/src/cz/crcs/ectester/common/test/TestRunner.java deleted file mode 100644 index cd71bcd..0000000 --- a/src/cz/crcs/ectester/common/test/TestRunner.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.crcs.ectester.common.test; - -import cz.crcs.ectester.common.output.TestWriter; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TestRunner { - private TestSuite suite; - private TestWriter writer; - - public TestRunner(TestSuite suite, TestWriter writer) { - this.suite = suite; - this.writer = writer; - } - - public void run() throws TestException { - writer.begin(suite); - for (Runnable t : suite.getRunnables()) { - if (!t.hasRun()) { - t.run(); - if (t instanceof Test) { - writer.outputTest((Test) t); - } - } - } - writer.end(); - } -} diff --git a/src/cz/crcs/ectester/common/test/TestSuite.java b/src/cz/crcs/ectester/common/test/TestSuite.java index 1a7c914..f4f30ee 100644 --- a/src/cz/crcs/ectester/common/test/TestSuite.java +++ b/src/cz/crcs/ectester/common/test/TestSuite.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.common.test; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.data.EC_Store; import java.util.Collections; @@ -13,27 +14,37 @@ import java.util.stream.Collectors; public abstract class TestSuite { protected String name; protected String description; - protected List run = new LinkedList<>(); - protected EC_Store dataStore; + protected TestWriter writer; - public TestSuite(EC_Store dataStore, String name, String description) { - this.dataStore = dataStore; + public TestSuite(TestWriter writer, String name, String description) { + this.writer = writer; this.name = name; this.description = description; } - public List getRunnables() { - return Collections.unmodifiableList(run); + public void run() throws TestException { + writer.begin(this); + try { + runTests(); + } catch (Exception e) { + throw new TestException(e); + } + writer.end(); } - @SuppressWarnings("unchecked") - public List getTests() { - return Collections.unmodifiableList((List)(List) run - .stream() - .filter(runnable -> (runnable instanceof Test)) - .collect(Collectors.toList())); + protected Test runTest(Test t) throws TestException { + t.run(); + return t; } + protected Test doTest(Test t) throws TestException { + t.run(); + writer.outputTest(t); + return t; + } + + protected abstract void runTests() throws Exception; + public String getName() { return name; } diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java index cc7a5de..3627075 100644 --- a/src/cz/crcs/ectester/common/test/Testable.java +++ b/src/cz/crcs/ectester/common/test/Testable.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.common.test; /** * @author Jan Jancar johny@neuromancer.sk */ -public interface Testable extends Runnable { +public interface Testable { /** * @return Whether this Testable was OK. */ @@ -13,4 +13,15 @@ public interface Testable extends Runnable { * @return Whether an error happened. */ boolean error(); + /** + * @return Whether this runnable was run. + */ + boolean hasRun(); + + /** + * Run this Runnable. + * + * @throws TestException + */ + void run() throws TestException; } diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index c25be4e..e4ba40c 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -1,8 +1,6 @@ package cz.crcs.ectester.data; -import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; -import cz.crcs.ectester.common.util.CardUtil; import javacard.security.KeyPair; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -31,12 +29,11 @@ import java.util.TreeMap; * @author Jan Jancar johny@neuromancer.sk */ public class EC_Store { - private DocumentBuilder db; - private Map categories; + private static EC_Store instance; - public EC_Store() throws IOException { + private EC_Store() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { @@ -85,7 +82,7 @@ public class EC_Store { }); parse(); - } catch (ParserConfigurationException | SAXException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } @@ -322,4 +319,11 @@ public class EC_Store { return getObject(objClass, query.substring(0, split), query.substring(split + 1)); } + public static EC_Store getInstance() { + if (instance == null) { + instance = new EC_Store(); + } + return instance; + } + } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index d4b95ed..ff0f403 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -28,7 +28,6 @@ import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.output.OutputLogger; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.data.EC_Store; @@ -64,9 +63,7 @@ import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; public class ECTesterReader { private CardMngr cardManager; private OutputLogger logger; - private TestWriter testWriter; private ResponseWriter respWriter; - private EC_Store dataStore; private Config cfg; private Options opts = new Options(); @@ -100,10 +97,9 @@ public class ECTesterReader { return; } - dataStore = new EC_Store(); //if list, print and quit if (cli.hasOption("list-named")) { - CLITools.listNamed(dataStore, cli.getOptionValue("list-named")); + CLITools.listNamed(EC_Store.getInstance(), cli.getOptionValue("list-named")); return; } @@ -126,22 +122,7 @@ public class ECTesterReader { // Setup logger, testWriter and respWriter logger = new OutputLogger(true, cfg.log); - if (cfg.format == null) { - testWriter = new TextTestWriter(logger.getPrintStream()); - } else { - switch (cfg.format) { - case "text": - testWriter = new TextTestWriter(logger.getPrintStream()); - break; - case "xml": - testWriter = new XMLTestWriter(logger.getOutputStream()); - break; - case "yaml": - case "yml": - testWriter = new YAMLTestWriter(logger.getPrintStream()); - break; - } - } + respWriter = new ResponseWriter(logger.getPrintStream()); //do action @@ -363,9 +344,9 @@ public class ECTesterReader { private void generate() throws CardException, IOException { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send(); - respWriter.outputResponse(allocate); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); + Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send(); + respWriter.outputResponse(allocate); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); FileWriter keysFile = new FileWriter(cfg.output); keysFile.write("index;time;pubW;privS\n"); @@ -414,15 +395,33 @@ public class ECTesterReader { * @throws CardException if APDU transmission fails * @throws IOException if an IO error occurs when writing to key file. */ - private void test() throws IOException, TestException { + private void test() throws IOException, TestException, ParserConfigurationException { + TestWriter writer = null; + if (cfg.format == null) { + writer = new TextTestWriter(logger.getPrintStream()); + } else { + switch (cfg.format) { + case "text": + writer = new TextTestWriter(logger.getPrintStream()); + break; + case "xml": + writer = new XMLTestWriter(logger.getOutputStream()); + break; + case "yaml": + case "yml": + writer = new YAMLTestWriter(logger.getPrintStream()); + break; + } + } + CardTestSuite suite; switch (cfg.testSuite) { case "default": - suite = new CardDefaultSuite(dataStore, cfg); + suite = new CardDefaultSuite(writer, cfg, cardManager); break; case "test-vectors": - suite = new CardTestVectorSuite(dataStore, cfg); + suite = new CardTestVectorSuite(writer, cfg, cardManager); break; default: // These run are dangerous, prompt before them. @@ -437,17 +436,15 @@ public class ECTesterReader { } in.close(); } - - switch (cfg.testSuite) { case "wrong": - suite = new CardWrongCurvesSuite(dataStore, cfg); + suite = new CardWrongCurvesSuite(writer, cfg, cardManager); break; case "composite": - suite = new CardCompositeCurvesSuite(dataStore, cfg); + suite = new CardCompositeCurvesSuite(writer, cfg, cardManager); break; case "invalid": - suite = new CardInvalidCurvesSuite(dataStore, cfg); + suite = new CardInvalidCurvesSuite(writer, cfg, cardManager); break; default: System.err.println("Unknown test suite."); @@ -456,9 +453,7 @@ public class ECTesterReader { break; } - TestRunner runner = new TestRunner(suite, testWriter); - suite.setup(cardManager); - runner.run(); + suite.run(); } /** @@ -472,7 +467,7 @@ public class ECTesterReader { List prepare = new LinkedList<>(); prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send()); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); if (curve != null) prepare.add(curve.send()); @@ -486,7 +481,7 @@ public class ECTesterReader { List generate = new LinkedList<>(); generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); if (cfg.anyPublicKey || cfg.anyPrivateKey || cfg.anyKey) { - generate.add(Command.prepareKey(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_REMOTE)); + generate.add(Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_REMOTE)); } FileWriter out = null; @@ -554,7 +549,7 @@ public class ECTesterReader { Command generate; if (cfg.anyKeypart) { - generate = Command.prepareKey(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL); + generate = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL); } else { generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); } @@ -563,7 +558,7 @@ public class ECTesterReader { List prepare = new LinkedList<>(); prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send()); prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send()); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); if (curve != null) prepare.add(curve.send()); @@ -620,7 +615,7 @@ public class ECTesterReader { public static class Config { //Options - public int bits; + public short bits; public boolean all; public boolean primeField = false; public boolean binaryField = false; @@ -670,7 +665,7 @@ public class ECTesterReader { * @return whether the options are valid. */ boolean readOptions(CommandLine cli) { - bits = Integer.parseInt(cli.getOptionValue("bit-size", "0")); + bits = Short.parseShort(cli.getOptionValue("bit-size", "0")); all = cli.hasOption("all"); primeField = cli.hasOption("fp"); binaryField = cli.hasOption("f2m"); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 2c2ba26..a53806c 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -2,13 +2,13 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import javacard.security.KeyPair; import java.util.Map; @@ -20,34 +20,31 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardCompositeCurvesSuite extends CardTestSuite { - public CardCompositeCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "composite", "The composite suite run ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); + public CardCompositeCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "composite", "The composite suite run ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); } @Override - public void setup(CardMngr cardManager) { + protected void runTests() throws Exception { /* Do the default run with the public keys set to provided smallorder keys * over composite order curves. Essentially small subgroup attacks. * These should fail, the curves aren't safe so that if the computation with * a small order public key succeeds the private key modulo the public key order * is revealed. */ - Map keys = dataStore.getObjects(EC_Key.class, "composite"); + Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); for (EC_Key key : keys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); - run.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + doTest(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index 7e7adbb..9de741c 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -2,15 +2,15 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; -import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; import javacard.security.KeyPair; -import java.io.IOException; - import static cz.crcs.ectester.common.test.Result.ExpectedValue; /** @@ -18,53 +18,46 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardDefaultSuite extends CardTestSuite { - public CardDefaultSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "default", "The default test suite run basic support of ECDH and ECDSA."); + public CardDefaultSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override - public void setup(CardMngr cardManager) throws IOException { - //run.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); - if (cfg.namedCurve != null) { - String desc = "Default run over the " + cfg.namedCurve + " curve category."; - if (cfg.primeField) { - run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); - } - if (cfg.binaryField) { - run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + protected void runTests() throws Exception { + if (cfg.primeField) { + runDefault(KeyPair.ALG_EC_FP); + } + if (cfg.binaryField) { + runDefault(KeyPair.ALG_EC_F2M); + } + } + + private void runDefault(byte field) throws Exception { + for (short keyLength : EC_Consts.FP_SIZES) { + Test key = doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); + if (!key.ok()) { + continue; } - } else { - if (cfg.all) { - if (cfg.primeField) { - //iterate over prime curve sizes used: EC_Consts.FP_SIZES - for (short keyLength : EC_Consts.FP_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); - } + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + for (byte kaType : EC_Consts.KA_TYPES) { + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + allocate.run(); + if (allocate.ok()) { + Test ka = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), ExpectedValue.SUCCESS); + ka.run(); + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, kaType), ExpectedValue.SUCCESS); + kaCompressed.run(); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement.", allocate, ka, kaCompressed)); } - if (cfg.binaryField) { - //iterate over binary curve sizes used: EC_Consts.F2M_SIZES - for (short keyLength : EC_Consts.F2M_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); - } - } - } else { - if (cfg.primeField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); - } - - if (cfg.binaryField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); + } + for (byte sigType : EC_Consts.SIG_TYPES) { + Test allocate = doTest(CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS)); + if (allocate.ok()) { + doTest(CommandTest.expect(new Command.ECDSA(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, ECTesterApplet.EXPORT_FALSE, null), ExpectedValue.SUCCESS)); } } } } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); - if (curve != null) - run.add(CommandTest.expect(curve, ExpectedValue.SUCCESS)); - run.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default run.")); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); - } } diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 3c0795b..0572a66 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -2,18 +2,17 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import javacard.security.KeyPair; -import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -26,22 +25,19 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardInvalidCurvesSuite extends CardTestSuite { - public CardInvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); + public CardInvalidCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Set original curves (secg/nist/brainpool). Generate local. * Try ECDH with invalid public keys of increasing (or decreasing) order. */ - Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); Map> curves = new HashMap<>(); for (EC_Key.Public key : pubkeys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); if (curve.getBits() != cfg.bits && !cfg.all) { continue; } @@ -56,16 +52,16 @@ public class CardInvalidCurvesSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); - ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } - run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java index 7035ca2..e12a588 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -3,14 +3,16 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.test.*; -import cz.crcs.ectester.common.test.Runnable; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -24,14 +26,14 @@ import static cz.crcs.ectester.common.test.Result.Value; */ public abstract class CardTestSuite extends TestSuite { ECTesterReader.Config cfg; + CardMngr card; - CardTestSuite(EC_Store dataStore, ECTesterReader.Config cfg, String name, String description) { - super(dataStore, name, description); + CardTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager, String name, String description) { + super(writer, name, description); + this.card = cardManager; this.cfg = cfg; } - public abstract void setup(CardMngr cardManager) throws IOException; - /** * @param cardManager cardManager to send APDU through * @param generateExpected expected result of the Generate command @@ -98,21 +100,20 @@ public abstract class CardTestSuite extends TestSuite { * @param description compound test description * @return run to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { - List tests = new LinkedList<>(); - Map curves = dataStore.getObjects(EC_Curve.class, category); + List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { + Map curves = EC_Store.getInstance().getObjects(EC_Curve.class, category); if (curves == null) - return tests; + return null; for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + //tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); + //tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + //tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); + //run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } - return tests; + return null; } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index 025cbe0..73c6621 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.*; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; @@ -25,46 +26,42 @@ import static cz.crcs.ectester.common.test.Result.Value; */ public class CardTestVectorSuite extends CardTestSuite { - public CardTestVectorSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); + public CardTestVectorSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. * Do ECDH both ways, export and verify that the result is correct. */ - Map results = dataStore.getObjects(EC_KAResult.class, "test"); + Map results = EC_Store.getInstance().getObjects(EC_KAResult.class, "test"); for (EC_KAResult result : results.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); - if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { - continue; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, result.getCurve()); if (curve.getBits() != cfg.bits && !cfg.all) { continue; } if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { continue; } - EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + EC_Params onekey = EC_Store.getInstance().getObject(EC_Keypair.class, result.getOneKey()); if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + onekey = EC_Store.getInstance().getObject(EC_Key.Private.class, result.getOneKey()); } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + EC_Params otherkey = EC_Store.getInstance().getObject(EC_Keypair.class, result.getOtherKey()); if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + otherkey = EC_Store.getInstance().getObject(EC_Key.Public.class, result.getOtherKey()); } if (onekey == null || otherkey == null) { throw new IOException("Test vector keys couldn't be located."); } List testVector = new LinkedList<>(); - testVector.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - //run.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { + testVector.add(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { @Override public Result apply(CommandTestable testable) { Response.ECDH dh = (Response.ECDH) testable.getResponse(); @@ -74,13 +71,13 @@ public class CardTestVectorSuite extends CardTestSuite { return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) { int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength()); - return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); + return new Result(Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + String.valueOf(firstDiff) + "."); } return new Result(Value.SUCCESS); } })); - run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 8c21aef..3a350c2 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -1,34 +1,58 @@ package cz.crcs.ectester.reader.test; +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; import javacard.security.KeyPair; -import java.io.IOException; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; +import java.util.Map; /** * @author Jan Jancar johny@neuromancer.sk */ public class CardWrongCurvesSuite extends CardTestSuite { - public CardWrongCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "wrong", "The wrong curve suite run whether the card rejects domain parameters which are not curves."); + public CardWrongCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "wrong", "The wrong curve suite run whether the card rejects domain parameters which are not curves."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Just do the default run on the wrong curves. * These should generally fail, the curves aren't curves. */ - String desc = "Default run over wrong curve params."; - if (cfg.primeField) { - run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); - } - if (cfg.binaryField) { - run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + Map curves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); + for (Map.Entry e : curves.entrySet()) { + EC_Curve curve = e.getValue(); + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + Test key = doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); + if (!key.ok()) { + continue; + } + Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS)); + Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS)); + doTest(CompoundTest.any(Result.ExpectedValue.FAILURE, "Set wrong curve and generate keypairs, should fail." ,set, generate)); + + for (byte kaType : EC_Consts.KA_TYPES) { + Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS)); + if (allocate.ok()) { + Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), Result.ExpectedValue.FAILURE)); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Allocate and perform KA, should fail.", allocate, ka)); + } + } } } } diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index b1b71a5..f5361c3 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -4,7 +4,6 @@ import cz.crcs.ectester.common.cli.*; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.ECUtil; import cz.crcs.ectester.data.EC_Store; @@ -44,7 +43,6 @@ import java.util.stream.Collectors; */ public class ECTesterStandalone { private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib()}; - private EC_Store dataStore; private Config cfg; private Options opts = new Options(); @@ -76,12 +74,11 @@ public class ECTesterStandalone { if (!cfg.readOptions(cli)) { return; } - dataStore = new EC_Store(); if (cli.isNext("list-libs")) { listLibraries(); } else if (cli.isNext("list-data")) { - CLITools.listNamed(dataStore, cli.getNext().getArg(0)); + CLITools.listNamed(EC_Store.getInstance(), cli.getNext().getArg(0)); } else if (cli.isNext("ecdh")) { ecdh(); } else if (cli.isNext("ecdsa")) { @@ -238,7 +235,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("ecdh.named-curve")) { String curveName = cli.getOptionValue("ecdh.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -324,7 +321,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("ecdsa.named-curve")) { String curveName = cli.getOptionValue("ecdsa.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -386,7 +383,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("generate.named-curve")) { String curveName = cli.getOptionValue("generate.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -429,10 +426,8 @@ public class ECTesterStandalone { break; } - StandaloneTestSuite suite = new StandaloneDefaultSuite(dataStore, cfg, cli); - TestRunner runner = new TestRunner(suite, writer); - suite.setup(); - runner.run(); + StandaloneTestSuite suite = new StandaloneDefaultSuite(writer, cfg, cli); + suite.run(); } /** diff --git a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java index b24244e..42d2e54 100644 --- a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java +++ b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.cli.TreeCommandLine; import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; @@ -11,7 +12,6 @@ import cz.crcs.ectester.standalone.consts.SignatureIdent; import javax.crypto.KeyAgreement; import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.spec.ECParameterSpec; @@ -20,12 +20,12 @@ import java.security.spec.ECParameterSpec; */ public class StandaloneDefaultSuite extends StandaloneTestSuite { - public StandaloneDefaultSuite(EC_Store dataStore, ECTesterStandalone.Config cfg, TreeCommandLine cli) { - super(dataStore, cfg, cli, "default", "The default test suite run basic support of ECDH and ECDSA."); + public StandaloneDefaultSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) { + super(writer, cfg, cli, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override - public void setup() throws NoSuchAlgorithmException { + protected void runTests() throws Exception { String kpgAlgo = cli.getOptionValue("test.kpg-type", "EC"); String kaAlgo = cli.getOptionValue("test.ka-type"); String sigAlgo = cli.getOptionValue("test.sig-type"); @@ -44,7 +44,7 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg, bits); } else if (cli.hasOption("test.named-curve")) { String curveName = cli.getOptionValue("test.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -57,19 +57,19 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg); } - run.add(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); - run.add(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); + doTest(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); + doTest(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.contains(kaAlgo)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - run.add(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); + doTest(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); } } for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.contains(sigAlgo)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - run.add(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); + doTest(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); } } } diff --git a/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java b/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java index 5682cd5..ad404c8 100644 --- a/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java +++ b/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.cli.TreeCommandLine; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; @@ -14,11 +15,9 @@ public abstract class StandaloneTestSuite extends TestSuite { TreeCommandLine cli; ECTesterStandalone.Config cfg; - public StandaloneTestSuite(EC_Store dataStore, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String description) { - super(dataStore, name, description); + public StandaloneTestSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String description) { + super(writer, name, description); this.cfg = cfg; this.cli = cli; } - - public abstract void setup() throws NoSuchAlgorithmException; } -- cgit v1.2.3-70-g09d2 From 87ee30fdf73db49cc538985a3937b8a792c2b30f Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 19 Jan 2018 18:06:23 +0100 Subject: Add quadratic twist tests into their own test suite. --- src/cz/crcs/ectester/data/twist/nist/b163.xml | 12 ++--- src/cz/crcs/ectester/data/twist/nist/b233.xml | 14 ++--- src/cz/crcs/ectester/data/twist/nist/b283.xml | 14 ++--- src/cz/crcs/ectester/data/twist/nist/k163.xml | 10 ++-- src/cz/crcs/ectester/data/twist/nist/k233.xml | 12 ++--- src/cz/crcs/ectester/data/twist/nist/k283.xml | 4 +- src/cz/crcs/ectester/data/twist/nist/p192.xml | 6 +-- src/cz/crcs/ectester/data/twist/nist/p224.xml | 14 ++--- src/cz/crcs/ectester/data/twist/nist/p256.xml | 10 ++-- src/cz/crcs/ectester/data/twist/nist/p384.xml | 2 +- src/cz/crcs/ectester/data/twist/nist/p521.xml | 10 ++-- src/cz/crcs/ectester/reader/ECTesterReader.java | 7 ++- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTwistTestSuite.java | 62 ++++++++++++++++++++++ 14 files changed, 122 insertions(+), 57 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java (limited to 'src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java') diff --git a/src/cz/crcs/ectester/data/twist/nist/b163.xml b/src/cz/crcs/ectester/data/twist/nist/b163.xml index 89ee6a4..03690ac 100644 --- a/src/cz/crcs/ectester/data/twist/nist/b163.xml +++ b/src/cz/crcs/ectester/data/twist/nist/b163.xml @@ -2,36 +2,36 @@ b163/0 0x000000000000000000000000000000000000000000,0x02c25b85badf8927593d21c366da89c03969f34da5 - nist/b163 + nist/B-163 twist order = 0x2 b163/1 0x03a98eb9fc1007f0a2b0e8de7da23cc6a7f7dd76b1,0x019971752926a2aca5407bffbf2a73f3f884b97127 - nist/b163 + nist/B-163 twist order = 0x1f b163/2 0x023ae22e69bac70ca24078fdf63753eaf6cb89e857,0x03674a33443dc657c24685eb761ab7efbb63a8adbc - nist/b163 + nist/B-163 twist order = 0x38b b163/3 0x04feb095cf083a783cac4107305889efa9f401cc27,0x0403abb00aa4712e4b9120391d59745e9fbad39db3 - nist/b163 + nist/B-163 twist order = 0x1208485 b163/4 0x00a72a640e05acc0e6c6956ab5be24240b92623add,0x031dfc8af709b3db0a05126f17a7b4d703de503475 - nist/b163 + nist/B-163 twist order = 0xb78fc77 b163/5 0x031b5fc734d73023a06e4fe1b7921811221c6d1b2a,0x05432357b4a42a7b8f51b04dfab95a5ecf03547500 - nist/b163 + nist/B-163 twist order = 0x5c4bf9b1205a07afbe718429 diff --git a/src/cz/crcs/ectester/data/twist/nist/b233.xml b/src/cz/crcs/ectester/data/twist/nist/b233.xml index 51768d3..7a0b579 100644 --- a/src/cz/crcs/ectester/data/twist/nist/b233.xml +++ b/src/cz/crcs/ectester/data/twist/nist/b233.xml @@ -2,42 +2,42 @@ b233/0 0x000000000000000000000000000000000000000000000000000000000000,0x0187f85627b97874e747ee31e06d71caaeea52f21253e5f946d061da9138 - nist/b233 + nist/B-233 twist order = 0x2 b233/1 0x01143eef5ed49cf4b4c552259589988a019e98418c012194a255e9186870,0x01f8070b0ef657563e5d584ce23fc58ef70265d4178d78717c6acebb8c78 - nist/b233 + nist/B-233 twist order = 0x5 b233/2 0x01c8185b4f7d07a7eca7deb9f2adcd3c9402461f8679cbc9618ad1d82be3,0x002d17d4fa7eafbf4f6238b94ddc95f6a56384a4028f50e7de1838c21c8c - nist/b233 + nist/B-233 twist order = 0x11b b233/3 0x01af53fdcb81b561803cb01ba4d384fa3ef7633b1c0dfb35f0e437ffc201,0x012a092d0b600cc59c2234ae65261513eee7a085428b2b42e96253b1143e - nist/b233 + nist/B-233 twist order = 0x21d b233/4 0x01f4b2e29d7a3796e3aa4a6b3ff40805d322292acefd80149ff954d75e04,0x00df2f3258674f799c4dcc8cef118abb4c00abf0c1f10144b47af7a6f41b - nist/b233 + nist/B-233 twist order = 0x22dba0b9 b233/5 0x01b6b9ce48a1428cb554a76a3f659d8b443ebee6b5619c88100bf3f83bb1,0x00dcafc85dfc3758e99736abe5ed2c4f03cbed5a3b478c9e233b976f7258 - nist/b233 + nist/B-233 twist order = 0x2a7504c0fda95a2311 b233/6 0x015cc90c0fdc2fc5fefddf1e9890627f87250b74fbaacd77feb761085d59,0x00059ccb49d156720dd3bcd75438225df9f9e84e7ffc0fc0dda02a647613 - nist/b233 + nist/B-233 twist order = 0x1e53fa33649df4ef97d6b29ded5a7 diff --git a/src/cz/crcs/ectester/data/twist/nist/b283.xml b/src/cz/crcs/ectester/data/twist/nist/b283.xml index bf6d1e6..7f57585 100644 --- a/src/cz/crcs/ectester/data/twist/nist/b283.xml +++ b/src/cz/crcs/ectester/data/twist/nist/b283.xml @@ -2,42 +2,42 @@ b283/0 0x000000000000000000000000000000000000000000000000000000000000000000000000,0x072bcc9c5792b1ebe81983089fb6f835a2fd220a304424ca17c082ae17442aede9b9b3f6 - nist/b283 + nist/B-283 twist order = 0x2 b283/1 0x0297e6d1f2b857a79f5dc85c2f1259d5d801c61a4d0a4312a04f65f09a887a7b93cf7ae1,0x051963c38ac61f05fef93707abcfbda7bc0f39eacddb2bdd3077f19c0e65c8be66ecb30e - nist/b283 + nist/B-283 twist order = 0x7 b283/2 0x022b522e9e120300e74563dee496f8feb64209b858abd5da50f31c92ae4a1eee751c92d6,0x012647d0d771016622e899c2a54afad773907e42e15d45e1db3e4fb0ae6a6df2934dba63 - nist/b283 + nist/B-283 twist order = 0x13 b283/3 0x02597a5336d18d9effde2820bed7352dccc8824abc81cde80914ea3cd072da55e9f91368,0x04a6d2c92a1ee699cda25dafa88191ef34218e9ea5c996d37e9ce507c318e7649b3b02d9 - nist/b283 + nist/B-283 twist order = 0x1623ab619 b283/4 0x01b011689cef74d9b2be4e8fb548eeabe31a678f560fc7b893c330b3939da9451a0cff78,0x022fd9ba4762f742a18e299f035a837b0525d7030e6b061eaa9242237d0767e7c28b608d - nist/b283 + nist/B-283 twist order = 0x2a4aa67aaaf5413fb b283/5 0x06ac85dce72aa795b5b90d43849dec9d4ee0ffc4d41f87fe8d48de2ac3cf84dfc5c20263,0x008e5147dba15ff3cb287457b3f41d32ca6c074df014f85033368d982c1670907d6afa05 - nist/b283 + nist/B-283 twist order = 0x25a8cdb1f2e470f3ac1ba7 b283/6 0x0132803a996ebd53ffa3553fc994b583cdb9514e4476c79336acf72f82ac36add519e655,0x004d30604436960af06b2eab63027ca8f59ca105f505afcd3413e1e72f5fb9c0f29d3a20 - nist/b283 + nist/B-283 twist order = 0x606749a9c147da03ad3f37 diff --git a/src/cz/crcs/ectester/data/twist/nist/k163.xml b/src/cz/crcs/ectester/data/twist/nist/k163.xml index 12e0f8e..31040c0 100644 --- a/src/cz/crcs/ectester/data/twist/nist/k163.xml +++ b/src/cz/crcs/ectester/data/twist/nist/k163.xml @@ -2,30 +2,30 @@ k163/0 0x000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000001 - nist/k163 + nist/K-163 twist order = 0x2 k163/1 0x04410857858628f16bd3ef77fce6732525d6d75f6c,0x00c51e38c5eb613ff4c8b594d754a218f30e8b1c39 - nist/k163 + nist/K-163 twist order = 0x28d k163/2 0x004c291913c2e75103b38481fbda3830850ee4c026,0x0403ff8ccadf20f12e10e40b8eed4872d4c128aaa2 - nist/k163 + nist/K-163 twist order = 0x1979 k163/3 0x03868f9f75e8d0056c6e1aabed4a3df1437a56b386,0x07473bb4e85044c95af468d5374da860c4e563159c - nist/k163 + nist/K-163 twist order = 0x7926bec180108d k163/4 0x0162deb07d5848fc45fd580549a6f17fecea1b7497,0x0297440c5cfd9e8fe781004db92f9f106b9d33235f - nist/k163 + nist/K-163 twist order = 0x10a6989de57d15c65ba229 diff --git a/src/cz/crcs/ectester/data/twist/nist/k233.xml b/src/cz/crcs/ectester/data/twist/nist/k233.xml index 2367e25..6354ff9 100644 --- a/src/cz/crcs/ectester/data/twist/nist/k233.xml +++ b/src/cz/crcs/ectester/data/twist/nist/k233.xml @@ -2,36 +2,36 @@ k233/0 0x000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000001 - nist/k233 + nist/K-233 twist order = 0x2 k233/1 0x01f5c35c89f8294442218a24a7e62ce3dac66c3ee5e9d2b70aaf51f520b2,0x001328eb45743dd96c4deaaa299b5394abfec9852e73a1e051a745fa95d8 - nist/k233 + nist/K-233 twist order = 0x1686d k233/2 0x00959e63a797bf3b2ea48d328ea3a9985da6bc95f296d1fc5e8cf17c257c,0x0070034f2e503a97be8766dd6db086870eea2e3fcb02260e9fcc0df8704c - nist/k233 + nist/K-233 twist order = 0x6d8a417 k233/3 0x00103cf39b9ffa6da7ef9f19f601daf698148663f6e0ae3b4ae2dca53782,0x013c1241644b61fb8c811287c2277c863eb0c31287e30d57d99169b1f509 - nist/k233 + nist/K-233 twist order = 0x7c02977 k233/4 0x003d84c97077988af52d6d825080c0c79276fc168e092260d67b5d4ca3a3,0x01d3fa5b63a25a8f08828117edb78a1ab31724ecfc74d4fc2c4b7ea00703 - nist/k233 + nist/K-233 twist order = 0x46403a035013f70d k233/5 0x01a053f3903f7b9e7e5c8784b01e43fd427b7264781b1e6c7a8755065a38,0x01ed5e24cd66d3d42b4a869aee65bff9506a8cdbc9f3c3c86543ba14db12 - nist/k233 + nist/K-233 twist order = 0xc7cb3894752e561e6abf871db diff --git a/src/cz/crcs/ectester/data/twist/nist/k283.xml b/src/cz/crcs/ectester/data/twist/nist/k283.xml index d27fad9..48a2dd9 100644 --- a/src/cz/crcs/ectester/data/twist/nist/k283.xml +++ b/src/cz/crcs/ectester/data/twist/nist/k283.xml @@ -2,12 +2,12 @@ k283/0 0x000000000000000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000000000000000001 - nist/k283 + nist/K-283 twist order = 0x2 k283/1 0x02707778aaa47f7a075be036522a6c2998ce118bf7e6314f342ba399dbc3572750791e4d,0x0568810a78107353690d1429cb7f4f408650cbf112d096907f563971baafad1b36436ec2 - nist/k283 + nist/K-283 twist order = 0x400000000000000000000000000000000002ca3a25f1511b3440100d775c3f3c3d3873f diff --git a/src/cz/crcs/ectester/data/twist/nist/p192.xml b/src/cz/crcs/ectester/data/twist/nist/p192.xml index ddb547e..d1fdf49 100644 --- a/src/cz/crcs/ectester/data/twist/nist/p192.xml +++ b/src/cz/crcs/ectester/data/twist/nist/p192.xml @@ -2,18 +2,18 @@ p192/0 0x489ba2a146ac0e7bb9f008fb780005e48d3588893c7ebca9,0x7caac0b203223010fb59940946a12e35d227fcb3ee6c9afc - nist/p192 + nist/P-192 twist order = 0x17 p192/1 0xfaebaecd2737a6c22b5023d236ad48ab9acacb2cac075379,0x43810e9a10dabc2f835af837ac83fc4f0225773f3a84103f - nist/p192 + nist/P-192 twist order = 0x231acce82af76d32ca5d526f p192/2 0x7af6e161dcb8cd7852d5102ab42974af5179706d4616cce0,0xa3177747f0de49227575d2afc449187ab546e9ab827fcac9 - nist/p192 + nist/P-192 twist order = 0x512b1bfde874086edba50007 diff --git a/src/cz/crcs/ectester/data/twist/nist/p224.xml b/src/cz/crcs/ectester/data/twist/nist/p224.xml index 693b2f8..3ae34ff 100644 --- a/src/cz/crcs/ectester/data/twist/nist/p224.xml +++ b/src/cz/crcs/ectester/data/twist/nist/p224.xml @@ -2,42 +2,42 @@ p224/0 0x90427f4a141f94c26f98d40060292350fcace2356961ef27dda08d7b,0x58877d4992c377c33459aa0caeb0526881326f201beb519fc11aadc8 - nist/p224 + nist/P-224 twist order = 0x3 p224/1 0x7f87c1db4213f1032c251a514e324f4360390476e0f7cd025547df58,0x2498f43e46af6fa0ad6480cfd61fb40caa78e349db0766a8760ff021 - nist/p224 + nist/P-224 twist order = 0xb p224/2 0x2a2d61174fd561e9da2f279b96f7a69ae50a78d87f09674f465c9184,0xc9c7232ca8a50587181d8c96204c1eec6e976bcbd58e3c7181dbb2a7 - nist/p224 + nist/P-224 twist order = 0x2f p224/3 0x15da8f68bfe51bc75f0cd892f7400c3d5ce5a9c6da126171527767cc,0x0cee3612475887d31963b62c69580191d1158df3f0c0305765175c9c - nist/p224 + nist/P-224 twist order = 0x2e0273 p224/4 0xbd813fcdea2281a452733516e4e2625fac96573c41f3b37c56d0d1d7,0x351de92e6b06928fec37ee0ffd03606fecc5022edc1a72453c433ef4 - nist/p224 + nist/P-224 twist order = 0x268160f p224/5 0x2a379d972d016116067b5bf2c23937b6182b4dc6bf8aa0625eb58b9f,0xb9ec1e372728d3334a762e5d64faca1e0cd47f46c3e5402ff14cb140 - nist/p224 + nist/P-224 twist order = 0xf3bac7aa52cf p224/6 0xc5e229bfc9f4e0992ecf51a3c354e6aac1a4673056bee9a673beae5a,0x73a2e7d530b13c281d460ea2d2c3bddb49a8eb3446b9308ec64d5a70 - nist/p224 + nist/P-224 twist order = 0x22340ff0f7eba57b33ac73e28a14d1 diff --git a/src/cz/crcs/ectester/data/twist/nist/p256.xml b/src/cz/crcs/ectester/data/twist/nist/p256.xml index fd7854c..2e1c55e 100644 --- a/src/cz/crcs/ectester/data/twist/nist/p256.xml +++ b/src/cz/crcs/ectester/data/twist/nist/p256.xml @@ -2,30 +2,30 @@ p256/0 0x92787586fc8a5d065a2a754e229a66ea3c845c8d5f7120792ee3aacee88ca01c,0xee95a42047d9eae3bb007aa7aed3a87ee6986df813f6c76d8f19866a1b1f9c20 - nist/p256 + nist/P-256 twist order = 0x3 p256/1 0x40d27c77cf9fb36e49a850b1ae7357c9ab3f1d917d52ba3edb648bd33354d3da,0xd30662382d8440919f4decbc58c6d9ca8745d39cdd71c26063fd2fa8bcbb69f7 - nist/p256 + nist/P-256 twist order = 0x5 p256/2 0x33961ae81d08958d1dbc42bdadb05e7cb7bdda383b1c49e18c3a2f5908c833a2,0xc4a96d4f905a1d7e32d4c82d6e79f1ef7047d09bf1d1518be2c65d13815306fe - nist/p256 + nist/P-256 twist order = 0xd p256/3 0x21fa3bf4b7d23dea73a1751d3b02dd8724a2a5a0ae9b28fdd98b8ef18bb610f5,0x7d933ab51ac8bc7e5d3c5a44d9875c64a080eba393c6492e4e5ce2367f133dd1 - nist/p256 + nist/P-256 twist order = 0xb3 p256/4 0x3819da45c7b025be543fd40ec49b2613891c12f2ae2daf014396c70270eff92c,0xbec84d62254dbc67864ced51966d4f419ad5b1ec9ee1d72cce291a8a034518da - nist/p256 + nist/P-256 twist order = 0x1e0a75640070a738557cc30f68bd56eaea65c94f98411d17ac4e16ece1a47 diff --git a/src/cz/crcs/ectester/data/twist/nist/p384.xml b/src/cz/crcs/ectester/data/twist/nist/p384.xml index eef02b8..8e0d2b6 100644 --- a/src/cz/crcs/ectester/data/twist/nist/p384.xml +++ b/src/cz/crcs/ectester/data/twist/nist/p384.xml @@ -2,6 +2,6 @@ p384/0 0x77e3431a4d6b9d63985798eb41188f9af7eb6c0f38745d360bf82b5c2c162cb8393adf2dbc4d5531c49322d9c7b4c9cd,0x2b38ea158d3c980e9b3618cfe42599dd9d78e630ac83c66673949121ca6c8997fbf5e08c060076f3fa60d6dec8ac8624 - nist/p384 + nist/P-384 twist order = 0x1000000000000000000000000000000000000000000000000389cb27e0bc8d21ea7e5f24bb74f58851313e697333ad68d diff --git a/src/cz/crcs/ectester/data/twist/nist/p521.xml b/src/cz/crcs/ectester/data/twist/nist/p521.xml index 82eb773..1564c80 100644 --- a/src/cz/crcs/ectester/data/twist/nist/p521.xml +++ b/src/cz/crcs/ectester/data/twist/nist/p521.xml @@ -2,30 +2,30 @@ p521/0 0x01a0c6f0e5b2c6948218fb8d1e913d750ace27674e59ec0a45f8f5883518c65c401af5a2275b7c2c74e717f5b64c48056f1440de1d48ef0825086f12db4f862e4467,0x00c93c77edf1cac8bab534a28c49446113a22833e05658b69f73658d7867b43c94f58d52e17b726e3f6d0b5847d91980509250210c4e1c73eeec72e185529c1450b0 - nist/p521 + nist/P-521 twist order = 0x5 p521/1 0x00e84fb16849133c2e4c24e7efc4df752ed9f01204aa692342bc619a8a9ccdd1b058996f3896790d0ee1b7c480cb117cc0b9272c116c6f544b99dca9d441976c69c0,0x00e6d2c8adb57c81db0bead3d225ee900c81e049d0e36bf20bf421f5620449b1638f2b1998f3e1ffbee369a74bc4833d01f45b46388755ba16abf67c5f7f53ac9110 - nist/p521 + nist/P-521 twist order = 0x7 p521/2 0x0161cb810a7d7f9092d518ed483208f202cf5a984e98ff50f94b13e04bf94be942c91a007cff215d55bf124912b8620312bc94e813d7956e3821b45da439f0b0e8e7,0x005194f315423bcacf38ea558ff344daedf9a51a81b0a9ef27f1d687c8d1b6952b60b6486fc2c3d394749fb00e4921a5cfced55c1fe821e8b80279f6cec89ba1ac1f - nist/p521 + nist/P-521 twist order = 0x4277ffb p521/3 0x01c133c394ad86829a9252e4d5e266c3d2830eb9b899e2cb16b815a5c7050c3bc53c415296339d33427087bdef04c0ae2d8f7d63d4a41176bd76d3c07cbd1ecfd1ee,0x01fee0c7535c40e01f2c12ee2a6ae1e54cafc147c3b491602da1f278b46c6ae3c04705b3bb3c72af70aaf3d4c684411ede8694d7a21b3734ce43ecc2b4a1ee2efee7 - nist/p521 + nist/P-521 twist order = 0x25e6d2cd p521/4 0x01232e18498e6cafe2572ec0b511376cf0d4844ec3b94472fb53346d7d9611726065cc922b3d2132117c99bce0ff8bc7f51bb30c6909a53b7c8a88e81807c31a1999,0x0112ada376c25bdc96440e0e2bf936377b287e885a08e6e1b5aa54f9b269cce4ed6ca6e6e44bd6d8e092e4864b278951648e897682096488e2a36036e989b1af7b24 - nist/p521 + nist/P-521 twist order = 0x17c8b8fa594c0fc63a5c0043ab498c1762d92f18fdfe2fea8f074695615d886d81bf930a0ac77d01bf9dd8c1a1ae121dab4e860c5dc18e265de3 diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index ff0f403..4097d81 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -247,7 +247,7 @@ public class ECTesterReader { actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build()); actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); - actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- twist:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do EC KeyAgreement (ECDH...), [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build()); @@ -446,6 +446,9 @@ public class ECTesterReader { case "invalid": suite = new CardInvalidCurvesSuite(writer, cfg, cardManager); break; + case "twist": + suite = new CardTwistTestSuite(writer, cfg, cardManager); + break; default: System.err.println("Unknown test suite."); return; @@ -780,7 +783,7 @@ public class ECTesterReader { } testSuite = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong"}; + String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong", "twist"}; if (!Arrays.asList(tests).contains(testSuite)) { System.err.println("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)); return false; diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 0572a66..8424d45 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -26,7 +26,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardInvalidCurvesSuite extends CardTestSuite { public CardInvalidCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); + super(writer, cfg, cardManager, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); } @Override diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java new file mode 100644 index 0000000..c43b234 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -0,0 +1,62 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; +import javacard.security.KeyPair; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardTwistTestSuite extends CardTestSuite { + public CardTwistTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "twist", "The twist test suite tests whether the card correctly rejects points on the quadratic twist of the curve during ECDH."); + } + + @Override + protected void runTests() throws Exception { + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS)); + List ecdhTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); + } + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); + } + } +} -- cgit v1.2.3-70-g09d2