Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
41154 views
1
/*
2
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.security.pkcs11;
27
28
import java.io.IOException;
29
import java.math.BigInteger;
30
31
import java.security.*;
32
import java.security.interfaces.*;
33
import java.security.spec.*;
34
35
import static sun.security.pkcs11.TemplateManager.*;
36
import sun.security.pkcs11.wrapper.*;
37
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
38
39
import sun.security.util.DerValue;
40
import sun.security.util.ECUtil;
41
42
/**
43
* EC KeyFactory implementation.
44
*
45
* @author Andreas Sterbenz
46
* @since 1.6
47
*/
48
final class P11ECKeyFactory extends P11KeyFactory {
49
private static Provider sunECprovider;
50
51
private static Provider getSunECProvider() {
52
if (sunECprovider == null) {
53
sunECprovider = Security.getProvider("SunEC");
54
if (sunECprovider == null) {
55
throw new RuntimeException("Cannot load SunEC provider");
56
}
57
}
58
59
return sunECprovider;
60
}
61
62
P11ECKeyFactory(Token token, String algorithm) {
63
super(token, algorithm);
64
}
65
66
static ECParameterSpec getECParameterSpec(String name) {
67
return ECUtil.getECParameterSpec(getSunECProvider(), name);
68
}
69
70
static ECParameterSpec getECParameterSpec(int keySize) {
71
return ECUtil.getECParameterSpec(getSunECProvider(), keySize);
72
}
73
74
// Check that spec is a known supported curve and convert it to our
75
// ECParameterSpec subclass. If not possible, return null.
76
static ECParameterSpec getECParameterSpec(ECParameterSpec spec) {
77
return ECUtil.getECParameterSpec(getSunECProvider(), spec);
78
}
79
80
static ECParameterSpec decodeParameters(byte[] params) throws IOException {
81
return ECUtil.getECParameterSpec(getSunECProvider(), params);
82
}
83
84
static byte[] encodeParameters(ECParameterSpec params) {
85
return ECUtil.encodeECParameterSpec(getSunECProvider(), params);
86
}
87
88
static ECPoint decodePoint(byte[] encoded, EllipticCurve curve) throws IOException {
89
return ECUtil.decodePoint(encoded, curve);
90
}
91
92
// Used by ECDH KeyAgreement
93
static byte[] getEncodedPublicValue(PublicKey key) throws InvalidKeyException {
94
if (key instanceof ECPublicKey) {
95
ECPublicKey ecKey = (ECPublicKey)key;
96
ECPoint w = ecKey.getW();
97
ECParameterSpec params = ecKey.getParams();
98
return ECUtil.encodePoint(w, params.getCurve());
99
} else {
100
// should never occur
101
throw new InvalidKeyException
102
("Key class not yet supported: " + key.getClass().getName());
103
}
104
}
105
106
PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
107
try {
108
if (key instanceof ECPublicKey) {
109
ECPublicKey ecKey = (ECPublicKey)key;
110
return generatePublic(
111
ecKey.getW(),
112
ecKey.getParams()
113
);
114
} else if ("X.509".equals(key.getFormat())) {
115
// let Sun provider parse for us, then recurse
116
byte[] encoded = key.getEncoded();
117
118
try {
119
key = ECUtil.decodeX509ECPublicKey(encoded);
120
} catch (InvalidKeySpecException ikse) {
121
throw new InvalidKeyException(ikse);
122
}
123
124
return implTranslatePublicKey(key);
125
} else {
126
throw new InvalidKeyException("PublicKey must be instance "
127
+ "of ECPublicKey or have X.509 encoding");
128
}
129
} catch (PKCS11Exception e) {
130
throw new InvalidKeyException("Could not create EC public key", e);
131
}
132
}
133
134
PrivateKey implTranslatePrivateKey(PrivateKey key)
135
throws InvalidKeyException {
136
try {
137
if (key instanceof ECPrivateKey) {
138
ECPrivateKey ecKey = (ECPrivateKey)key;
139
return generatePrivate(
140
ecKey.getS(),
141
ecKey.getParams()
142
);
143
} else if ("PKCS#8".equals(key.getFormat())) {
144
// let Sun provider parse for us, then recurse
145
byte[] encoded = key.getEncoded();
146
147
try {
148
key = ECUtil.decodePKCS8ECPrivateKey(encoded);
149
} catch (InvalidKeySpecException ikse) {
150
throw new InvalidKeyException(ikse);
151
}
152
153
return implTranslatePrivateKey(key);
154
} else {
155
throw new InvalidKeyException("PrivateKey must be instance "
156
+ "of ECPrivateKey or have PKCS#8 encoding");
157
}
158
} catch (PKCS11Exception e) {
159
throw new InvalidKeyException("Could not create EC private key", e);
160
}
161
}
162
163
// see JCA spec
164
protected PublicKey engineGeneratePublic(KeySpec keySpec)
165
throws InvalidKeySpecException {
166
token.ensureValid();
167
if (keySpec instanceof X509EncodedKeySpec) {
168
try {
169
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
170
PublicKey key = ECUtil.decodeX509ECPublicKey(encoded);
171
return implTranslatePublicKey(key);
172
} catch (InvalidKeyException e) {
173
throw new InvalidKeySpecException
174
("Could not create EC public key", e);
175
}
176
}
177
if (keySpec instanceof ECPublicKeySpec == false) {
178
throw new InvalidKeySpecException("Only ECPublicKeySpec and "
179
+ "X509EncodedKeySpec supported for EC public keys");
180
}
181
try {
182
ECPublicKeySpec ec = (ECPublicKeySpec)keySpec;
183
return generatePublic(
184
ec.getW(),
185
ec.getParams()
186
);
187
} catch (PKCS11Exception e) {
188
throw new InvalidKeySpecException
189
("Could not create EC public key", e);
190
}
191
}
192
193
// see JCA spec
194
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
195
throws InvalidKeySpecException {
196
token.ensureValid();
197
if (keySpec instanceof PKCS8EncodedKeySpec) {
198
try {
199
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
200
PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded);
201
return implTranslatePrivateKey(key);
202
} catch (GeneralSecurityException e) {
203
throw new InvalidKeySpecException
204
("Could not create EC private key", e);
205
}
206
}
207
if (keySpec instanceof ECPrivateKeySpec == false) {
208
throw new InvalidKeySpecException("Only ECPrivateKeySpec and "
209
+ "PKCS8EncodedKeySpec supported for EC private keys");
210
}
211
try {
212
ECPrivateKeySpec ec = (ECPrivateKeySpec)keySpec;
213
return generatePrivate(
214
ec.getS(),
215
ec.getParams()
216
);
217
} catch (PKCS11Exception e) {
218
throw new InvalidKeySpecException
219
("Could not create EC private key", e);
220
}
221
}
222
223
private PublicKey generatePublic(ECPoint point, ECParameterSpec params)
224
throws PKCS11Exception {
225
byte[] encodedParams =
226
ECUtil.encodeECParameterSpec(getSunECProvider(), params);
227
byte[] encodedPoint =
228
ECUtil.encodePoint(point, params.getCurve());
229
230
// Check whether the X9.63 encoding of an EC point shall be wrapped
231
// in an ASN.1 OCTET STRING
232
if (!token.config.getUseEcX963Encoding()) {
233
try {
234
encodedPoint =
235
new DerValue(DerValue.tag_OctetString, encodedPoint)
236
.toByteArray();
237
} catch (IOException e) {
238
throw new
239
IllegalArgumentException("Could not DER encode point", e);
240
}
241
}
242
243
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
244
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
245
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
246
new CK_ATTRIBUTE(CKA_EC_POINT, encodedPoint),
247
new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
248
};
249
attributes = token.getAttributes
250
(O_IMPORT, CKO_PUBLIC_KEY, CKK_EC, attributes);
251
Session session = null;
252
try {
253
session = token.getObjSession();
254
long keyID = token.p11.C_CreateObject(session.id(), attributes);
255
return P11Key.publicKey
256
(session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
257
} finally {
258
token.releaseSession(session);
259
}
260
}
261
262
private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params)
263
throws PKCS11Exception {
264
byte[] encodedParams =
265
ECUtil.encodeECParameterSpec(getSunECProvider(), params);
266
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
267
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
268
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
269
new CK_ATTRIBUTE(CKA_VALUE, s),
270
new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
271
};
272
attributes = token.getAttributes
273
(O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attributes);
274
Session session = null;
275
try {
276
session = token.getObjSession();
277
long keyID = token.p11.C_CreateObject(session.id(), attributes);
278
return P11Key.privateKey
279
(session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
280
} finally {
281
token.releaseSession(session);
282
}
283
}
284
285
<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
286
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
287
if (keySpec.isAssignableFrom(ECPublicKeySpec.class)) {
288
session[0] = token.getObjSession();
289
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
290
new CK_ATTRIBUTE(CKA_EC_POINT),
291
new CK_ATTRIBUTE(CKA_EC_PARAMS),
292
};
293
long keyID = key.getKeyID();
294
try {
295
token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);
296
ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
297
ECPoint point;
298
299
if (!token.config.getUseEcX963Encoding()) {
300
point = decodePoint(new DerValue(attributes[0].getByteArray()).getOctetString(), params.getCurve());
301
} else {
302
point = decodePoint(attributes[0].getByteArray(), params.getCurve());
303
}
304
return keySpec.cast(new ECPublicKeySpec(point, params));
305
} catch (IOException e) {
306
throw new InvalidKeySpecException("Could not parse key", e);
307
} finally {
308
key.releaseKeyID();
309
}
310
} else { // X.509 handled in superclass
311
throw new InvalidKeySpecException("Only ECPublicKeySpec and "
312
+ "X509EncodedKeySpec supported for EC public keys");
313
}
314
}
315
316
<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
317
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
318
if (keySpec.isAssignableFrom(ECPrivateKeySpec.class)) {
319
session[0] = token.getObjSession();
320
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
321
new CK_ATTRIBUTE(CKA_VALUE),
322
new CK_ATTRIBUTE(CKA_EC_PARAMS),
323
};
324
long keyID = key.getKeyID();
325
try {
326
token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);
327
ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
328
return keySpec.cast(
329
new ECPrivateKeySpec(attributes[0].getBigInteger(), params));
330
} catch (IOException e) {
331
throw new InvalidKeySpecException("Could not parse key", e);
332
} finally {
333
key.releaseKeyID();
334
}
335
} else { // PKCS#8 handled in superclass
336
throw new InvalidKeySpecException("Only ECPrivateKeySpec "
337
+ "and PKCS8EncodedKeySpec supported for EC private keys");
338
}
339
}
340
341
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
342
return KeyFactory.getInstance("EC", getSunECProvider());
343
}
344
345
}
346
347