aboutsummaryrefslogtreecommitdiff
path: root/src/cz
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz')
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyGenerator.java2
-rw-r--r--src/cz/crcs/ectester/reader/Command.java14
-rw-r--r--src/cz/crcs/ectester/reader/ECTester.java17
-rw-r--r--src/cz/crcs/ectester/reader/Test.java3
-rw-r--r--src/cz/crcs/ectester/reader/TestSuite.java118
5 files changed, 75 insertions, 79 deletions
diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java
index a602ab1..f8cbf87 100644
--- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java
+++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java
@@ -177,7 +177,7 @@ public class ECKeyGenerator {
short i3 = Util.makeShort(data[(short) (offset + 6)], data[(short) (offset + 7)]);
// if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3);
// if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3);
- // TODO fix this
+ // TODO: fix this, ^^ fails on jcardsim, but is up to spec
if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i3, i2, i1);
if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i3, i2, i1);
} else {
diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java
index 1063767..4e210ed 100644
--- a/src/cz/crcs/ectester/reader/Command.java
+++ b/src/cz/crcs/ectester/reader/Command.java
@@ -47,16 +47,15 @@ public abstract class Command {
* @param keyPair which keyPair/s (local/remote) to set curve domain parameters on
* @param keyLength key length to choose
* @param keyClass key class to choose
- * @return a list of Commands to send in order to prepare the curve on the keypairs.
+ * @return a Command to send in order to prepare the curve on the keypairs.
* @throws IOException if curve file cannot be found/opened
*/
- public static List<Command> prepareCurve(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair, short keyLength, byte keyClass) throws IOException {
- List<Command> commands = new ArrayList<>();
+ public static Command prepareCurve(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair, short keyLength, byte keyClass) throws IOException {
if (cfg.customCurve) {
// Set custom curve (one of the SECG curves embedded applet-side)
short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M;
- commands.add(new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null));
+ return new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null);
} else if (cfg.namedCurve != null) {
// Set a named curve.
// parse cfg.namedCurve -> cat / id | cat | id
@@ -72,7 +71,7 @@ public abstract class Command {
if (external == null) {
throw new IOException("Couldn't read named curve data.");
}
- commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external));
+ return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external);
} else if (cfg.curveFile != null) {
// Set curve loaded from a file
EC_Curve curve = new EC_Curve(null, keyLength, keyClass);
@@ -85,7 +84,7 @@ public abstract class Command {
if (external == null) {
throw new IOException("Couldn't read the curve file correctly.");
}
- commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external));
+ return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external);
} else {
// Set default curve
/* This command was generally causing problems for simulating on jcardsim.
@@ -93,9 +92,8 @@ public abstract class Command {
* This might break some other stuff.. But should not.
*/
//commands.add(new Command.Clear(cardManager, keyPair));
+ return null;
}
-
- return commands;
}
diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java
index 33d1b7f..217b9ef 100644
--- a/src/cz/crcs/ectester/reader/ECTester.java
+++ b/src/cz/crcs/ectester/reader/ECTester.java
@@ -47,7 +47,6 @@ public class ECTester {
private DirtyLogger systemOutLogger;
private EC_Store dataStore;
private Config cfg;
- private TestSuite[] testSuites;
private Options opts = new Options();
private static final String CLI_HEADER = "\nECTester, a javacard Elliptic Curve Cryptograhy support tester/utility.\n\n";
@@ -209,7 +208,7 @@ public class ECTester {
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- nonprime:\n- smallpub:\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- wrong:\n- nonprime:\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("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build());
@@ -333,7 +332,7 @@ public class ECTester {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send();
- List<Command> curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass);
+ Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass);
FileWriter keysFile = new FileWriter(cfg.output);
keysFile.write("index;time;pubW;privS\n");
@@ -341,8 +340,8 @@ public class ECTester {
int generated = 0;
int retry = 0;
while (generated < cfg.generateAmount || cfg.generateAmount == 0) {
- if (cfg.fresh || generated == 0) {
- Command.sendAll(curve);
+ if ((cfg.fresh || generated == 0) && curve != null) {
+ curve.send();
}
Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL);
@@ -429,7 +428,9 @@ public class ECTester {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send());
- prepare.addAll(Command.sendAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass)));
+ Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass);
+ if (curve != null)
+ prepare.add(curve.send());
systemOutLogger.println(Response.toString(prepare));
@@ -506,7 +507,9 @@ public class ECTester {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send());
- prepare.addAll(Command.sendAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass)));
+ Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass);
+ if (curve != null)
+ prepare.add(curve.send());
systemOutLogger.println(Response.toString(prepare));
diff --git a/src/cz/crcs/ectester/reader/Test.java b/src/cz/crcs/ectester/reader/Test.java
index 78efef5..651274d 100644
--- a/src/cz/crcs/ectester/reader/Test.java
+++ b/src/cz/crcs/ectester/reader/Test.java
@@ -29,9 +29,6 @@ public class Test {
}
public Response getResponse() {
- if (!hasRun) {
- return null;
- }
return response;
}
diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java
index c7c3b21..c2ccb54 100644
--- a/src/cz/crcs/ectester/reader/TestSuite.java
+++ b/src/cz/crcs/ectester/reader/TestSuite.java
@@ -21,7 +21,7 @@ public abstract class TestSuite {
EC_Store dataStore;
ECTester.Config cfg;
String name;
- boolean hasRun;
+ boolean hasRun = false;
List<Test> tests = new LinkedList<>();
TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) {
@@ -30,7 +30,7 @@ public abstract class TestSuite {
this.name = name;
}
- public List<Test> run(CardMngr cardManager) throws IOException, CardException {
+ public List<Test> run(CardMngr cardManager) throws CardException, IOException {
for (Test t : tests) {
t.run();
System.out.println(t);
@@ -52,44 +52,53 @@ public abstract class TestSuite {
}
/**
- * @return
- * @throws IOException if an IO error occurs when writing to key file.
+ * @param cardManager cardManager to send APDU through
+ * @param generateExpected expected result of the Generate command
+ * @param ecdhExpected expected result of the ordinary ECDH command
+ * @param ecdsaExpected expected result of the ordinary ECDSA command
+ * @return tests to run
*/
- List<Command> testCurve(CardMngr cardManager) throws IOException {
- List<Command> commands = new LinkedList<>();
- commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH));
- commands.add(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null));
- return commands;
+ List<Test> testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) {
+ List<Test> tests = new LinkedList<>();
+
+ tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));
+
+ return tests;
}
/**
- * @param category
- * @param field
- * @return
- * @throws IOException if an IO error occurs when writing to key file.
+ * @param cardManager cardManager to send APDU through
+ * @param category category to test
+ * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M)
+ * @param setExpected expected result of the Set (curve) command
+ * @param generateExpected expected result of the Generate command
+ * @param ecdhExpected expected result of the ordinary ECDH command
+ * @param ecdsaExpected expected result of the ordinary ECDSA command
+ * @return tests to run
*/
- List<Command> testCurves(CardMngr cardManager, String category, byte field) throws IOException {
- List<Command> commands = new LinkedList<>();
+ List<Test> testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) {
+ List<Test> tests = new LinkedList<>();
Map<String, EC_Curve> curves = dataStore.getObjects(EC_Curve.class, category);
if (curves == null)
- return commands;
+ return tests;
for (Map.Entry<String, EC_Curve> entry : curves.entrySet()) {
EC_Curve curve = entry.getValue();
if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) {
- commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field));
- commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()));
- commands.addAll(testCurve(cardManager));
- commands.add(new Command.Cleanup(cardManager));
+ tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS));
+ tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected));
+ tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected));
+ tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY));
}
}
- return commands;
+ return tests;
}
public static class Default extends TestSuite {
@@ -100,55 +109,48 @@ public abstract class TestSuite {
@Override
public List<Test> run(CardMngr cardManager) throws IOException, CardException {
- //TODO: Convert TestSuire.Default to Tests
- List<Command> commands = new LinkedList<>();
- commands.add(new Command.Support(cardManager));
+ tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY));
if (cfg.namedCurve != null) {
if (cfg.primeField) {
- commands.addAll(testCurves(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP));
+ tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS));
}
if (cfg.binaryField) {
- commands.addAll(testCurves(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M));
+ tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS));
}
} else {
if (cfg.all) {
if (cfg.primeField) {
//iterate over prime curve sizes used: EC_Consts.FP_SIZES
for (short keyLength : EC_Consts.FP_SIZES) {
- commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP));
- commands.addAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP));
- commands.addAll(testCurve(cardManager));
- commands.add(new Command.Cleanup(cardManager));
+ defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP);
}
}
if (cfg.binaryField) {
//iterate over binary curve sizes used: EC_Consts.F2M_SIZES
for (short keyLength : EC_Consts.F2M_SIZES) {
- commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M));
- commands.addAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M));
- commands.addAll(testCurve(cardManager));
- commands.add(new Command.Cleanup(cardManager));
+ defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M);
}
}
} else {
if (cfg.primeField) {
- commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_FP));
- commands.addAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_FP));
- commands.addAll(testCurve(cardManager));
- commands.add(new Command.Cleanup(cardManager));
+ defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP);
}
if (cfg.binaryField) {
- commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_F2M));
- commands.addAll(Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_F2M));
- commands.addAll(testCurve(cardManager));
- commands.add(new Command.Cleanup(cardManager));
+ defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M);
}
}
}
- List<Response> test = Command.sendAll(commands);
- System.out.println(Response.toString(test));
- return null;
+ return super.run(cardManager);
+ }
+
+ private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException {
+ tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS));
+ Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType);
+ if (curve != null)
+ tests.add(new Test(curve, Test.Result.SUCCESS));
+ tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS));
+ tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY));
}
}
@@ -243,7 +245,7 @@ public abstract class TestSuite {
}
@Override
- public List<Test> run(CardMngr cardManager) throws IOException, CardException {
+ public List<Test> run(CardMngr cardManager) throws CardException, IOException {
/* Set original curves (secg/nist/brainpool). Generate local.
* Try ECDH with invalid public keys of increasing (or decreasing) order.
*/
@@ -274,21 +276,17 @@ public abstract class TestSuite {
}
@Override
- public List<Test> run(CardMngr cardManager) throws IOException, CardException {
+ public List<Test> run(CardMngr cardManager) throws CardException, IOException {
/* Just do the default tests on the wrong curves.
* These should generally fail, the curves aren't curves.
*/
- //TODO: Convert TestSuire.Wrong to Tests
- List<Command> commands = new LinkedList<>();
if (cfg.primeField) {
- commands.addAll(testCurves(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP));
+ tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE));
}
if (cfg.binaryField) {
- commands.addAll(testCurves(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M));
+ tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE));
}
- List<Response> test = Command.sendAll(commands);
- System.out.println(Response.toString(test));
- return null;
+ return super.run(cardManager);
}
}
}