aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/reader/test/TestSuite.java
blob: c0e8e91b23d92efeca1a681cc168a2b9eed5b8db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package cz.crcs.ectester.reader.test;

import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTester;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.ec.EC_Curve;

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * @author Jan Jancar johny@neuromancer.sk
 */
public abstract class TestSuite {
    EC_Store dataStore;
    ECTester.Config cfg;
    String name;
    String description;
    List<Test> tests = new LinkedList<>();

    TestSuite(EC_Store dataStore, ECTester.Config cfg, String name, String description) {
        this.dataStore = dataStore;
        this.cfg = cfg;
        this.name = name;
        this.description = description;
    }

    public abstract void setup(CardMngr cardManager) throws IOException;

    public List<Test> getTests() {
        return Collections.unmodifiableList(tests);
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    /**
     * @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 ecdhCompressExpected expected result of ECDH with a compressed point
     * @param ecdsaExpected        expected result of the ordinary ECDSA command
     * @param description          compound test description
     * @return test to run
     */
    Test defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressExpected, Result.Value ecdsaExpected, String description) {
        List<Test> tests = new LinkedList<>();

        tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected));
        tests.add(new Test.Simple(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.Simple(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.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Result.Value.FAILURE));
        tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Result.Value.FAILURE));
        tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Result.Value.FAILURE));
        tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE));
        tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));

        return Test.Compound.function((testArray) -> {
            Function<Result.Value, String> shouldHave = (expected) -> {
                switch (expected) {
                    case SUCCESS:
                        return "been successful";
                    case FAILURE:
                        return "failed";
                    case ANY:
                    default:
                        return "";
                }
            };

            for (int i = 0; i < testArray.length; ++i) {
                Test t = testArray[i];
                if (t.getResultValue() != Result.Value.SUCCESS) {
                    if (i == 0) { // generate
                        return new Result(Result.Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not.");
                    } else if (i == 2) { // ecdh compress
                        return new Result(Result.Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not.");
                    } else if (i == 1) { // ecdh normal
                        return new Result(Result.Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not.");
                    } else if (i <= 6) { // ecdh wrong, should fail
                        return new Result(Result.Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not.");
                    } else { // ecdsa
                        return new Result(Result.Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not.");
                    }
                }
            }
            return new Result(Result.Value.SUCCESS);
        }, description, tests.toArray(new Test[0]));
    }

    /**
     * @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 ecdhCompressedExpected
     * @param ecdsaExpected          expected result of the ordinary ECDSA command
     * @param description            compound test description
     * @return tests to run
     */
    List<Test> defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressedExpected, Result.Value ecdsaExpected, String description) {
        List<Test> tests = new LinkedList<>();
        Map<String, EC_Curve> curves = dataStore.getObjects(EC_Curve.class, category);
        if (curves == null)
            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)) {
                tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS));
                tests.add(new Test.Simple(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(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY));
            }
        }

        return tests;
    }
}