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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
package applets;
import javacard.framework.ISO7816;
import javacard.framework.Util;
import javacard.security.CryptoException;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyPair;
/**
*
*/
public class ECKeyGenerator {
private KeyPair ecKeyPair = null;
private ECPrivateKey ecPrivateKey = null;
private ECPublicKey ecPublicKey = null;
public static final byte PARAMETER_FP = 1;
public static final byte PARAMETER_F2M_ONE = 2;
public static final byte PARAMETER_F2M_THREE = 3;
public static final byte PARAMETER_A = 4;
public static final byte PARAMETER_B = 5;
public static final byte PARAMETER_G = 6;
public static final byte PARAMETER_R = 7;
public static final byte PARAMETER_K = 8;
private static final byte PARAMETER_S = 9; //private key
private static final byte PARAMETER_W = 10;//public key
public static final byte KEY_PUBLIC = 0x1;
public static final byte KEY_PRIVATE = 0x2;
public static final byte KEY_BOTH = KEY_PUBLIC & KEY_PRIVATE;
public short allocatePair(byte algorithm, short keyLength) {
short result = ISO7816.SW_NO_ERROR;
try {
ecKeyPair = new KeyPair(algorithm, keyLength);
} catch (CryptoException ce) {
result = ce.getReason();
} catch (Exception e) {
result = ISO7816.SW_UNKNOWN;
}
return result;
}
public boolean isAlocated() {
return ecKeyPair != null && ecPrivateKey != null && ecPublicKey != null;
}
public short generatePair() {
short result = ISO7816.SW_NO_ERROR;
try {
ecKeyPair.genKeyPair();
ecPrivateKey = (ECPrivateKey) ecKeyPair.getPrivate(); //TODO, do I want to keep private and pubkey separate from the keypair?
ecPublicKey = (ECPublicKey) ecKeyPair.getPublic();
} catch (CryptoException ce) {
result = ce.getReason();
} catch (Exception e) {
result = ISO7816.SW_UNKNOWN;
}
return result;
}
public short setCustomCurve(byte keyClass, short keyLength) {
//TODO
return 0;
}
public short setCustomCurve(byte curve) {
//TODO
return 0;
}
public short setExternalParameter(byte key, byte param, byte[] data, short offset, short length) {
short result = ISO7816.SW_NO_ERROR;
try {
switch (param) {
case PARAMETER_FP:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setFieldFP(data, offset, length);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setFieldFP(data, offset, length);
break;
case PARAMETER_F2M_ONE:
if (length != 2) {
result = ISO7816.SW_UNKNOWN;
} else {
short i = Util.makeShort(data[offset], data[(short) (offset + 1)]);
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i);
}
break;
case PARAMETER_F2M_THREE:
if (length != 6) {
result = ISO7816.SW_UNKNOWN;
} else {
short i1 = Util.makeShort(data[offset], data[(short) (offset + 1)]);
short i2 = Util.makeShort(data[(short) (offset + 2)], data[(short) (offset + 3)]);
short i3 = Util.makeShort(data[(short) (offset + 4)], data[(short) (offset + 5)]);
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3);
}
break;
case PARAMETER_A:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setA(data, offset, length);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setA(data, offset, length);
break;
case PARAMETER_B:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setB(data, offset, length);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setB(data, offset, length);
break;
case PARAMETER_G:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setG(data, offset, length);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setG(data, offset, length);
break;
case PARAMETER_R:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setR(data, offset, length);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setR(data, offset, length);
break;
case PARAMETER_K:
if (length != 2) {
result = ISO7816.SW_UNKNOWN;
} else {
short k = Util.makeShort(data[offset], data[(short) (offset + 1)]);
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setK(k);
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setK(k);
}
break;
case PARAMETER_S:
if ((key & KEY_PRIVATE) != 0) ecPrivateKey.setS(data, offset, length);
break;
case PARAMETER_W:
if ((key & KEY_PUBLIC) != 0) ecPublicKey.setW(data, offset, length);
break;
default:
result = ISO7816.SW_UNKNOWN;
}
} catch (CryptoException ce) {
result = ce.getReason();
} catch (Exception e) {
result = ISO7816.SW_UNKNOWN;
}
return result;
}
public short exportParameter(byte key, byte param, byte[] outputBuffer, short outputOffset) {
if (key == KEY_BOTH) {
return ISO7816.SW_UNKNOWN;
}
short result = ISO7816.SW_NO_ERROR;
try {
switch(param){
case PARAMETER_FP:
break;
default:
}
} catch (CryptoException ce) {
} catch (Exception e) {
}
//TODO
return result;
}
public ECPrivateKey getPrivateKey() {
return ecPrivateKey;
}
public ECPublicKey getPublicKey() {
return ecPublicKey;
}
public KeyPair getKeyPair() {
return ecKeyPair;
}
}
|