Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyFactory.java
41161 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.ec;
27
28
import java.security.*;
29
import java.security.interfaces.*;
30
import java.security.spec.*;
31
import java.util.Arrays;
32
33
/**
34
* KeyFactory for EC keys. Keys must be instances of PublicKey or PrivateKey
35
* and getAlgorithm() must return "EC". For such keys, it supports conversion
36
* between the following:
37
*
38
* For public keys:
39
* . PublicKey with an X.509 encoding
40
* . ECPublicKey
41
* . ECPublicKeySpec
42
* . X509EncodedKeySpec
43
*
44
* For private keys:
45
* . PrivateKey with a PKCS#8 encoding
46
* . ECPrivateKey
47
* . ECPrivateKeySpec
48
* . PKCS8EncodedKeySpec
49
*
50
* @since 1.6
51
* @author Andreas Sterbenz
52
*/
53
public final class ECKeyFactory extends KeyFactorySpi {
54
55
// Used by translateKey()
56
private static KeyFactory instance;
57
58
private static KeyFactory getInstance() {
59
if (instance == null) {
60
try {
61
instance = KeyFactory.getInstance("EC", "SunEC");
62
} catch (NoSuchProviderException e) {
63
throw new RuntimeException(e);
64
} catch (NoSuchAlgorithmException e) {
65
throw new RuntimeException(e);
66
}
67
}
68
69
return instance;
70
}
71
72
public ECKeyFactory() {
73
// empty
74
}
75
76
/**
77
* Static method to convert Key into a useable instance of
78
* ECPublicKey or ECPrivateKey. Check the key and convert it
79
* to a Sun key if necessary. If the key is not an EC key
80
* or cannot be used, throw an InvalidKeyException.
81
*
82
* The difference between this method and engineTranslateKey() is that
83
* we do not convert keys of other providers that are already an
84
* instance of ECPublicKey or ECPrivateKey.
85
*
86
* To be used by future Java ECDSA and ECDH implementations.
87
*/
88
public static ECKey toECKey(Key key) throws InvalidKeyException {
89
if (key instanceof ECKey) {
90
ECKey ecKey = (ECKey)key;
91
checkKey(ecKey);
92
return ecKey;
93
} else {
94
/*
95
* We don't call the engineTranslateKey method directly
96
* because KeyFactory.translateKey adds code to loop through
97
* all key factories.
98
*/
99
return (ECKey)getInstance().translateKey(key);
100
}
101
}
102
103
/**
104
* Check that the given EC key is valid.
105
*/
106
private static void checkKey(ECKey key) throws InvalidKeyException {
107
// check for subinterfaces, omit additional checks for our keys
108
if (key instanceof ECPublicKey) {
109
if (key instanceof ECPublicKeyImpl) {
110
return;
111
}
112
} else if (key instanceof ECPrivateKey) {
113
if (key instanceof ECPrivateKeyImpl) {
114
return;
115
}
116
} else {
117
throw new InvalidKeyException("Neither a public nor a private key");
118
}
119
// ECKey does not extend Key, so we need to do a cast
120
String keyAlg = ((Key)key).getAlgorithm();
121
if (keyAlg.equals("EC") == false) {
122
throw new InvalidKeyException("Not an EC key: " + keyAlg);
123
}
124
// XXX further sanity checks about whether this key uses supported
125
// fields, point formats, etc. would go here
126
}
127
128
/**
129
* Translate an EC key into a Sun EC key. If conversion is
130
* not possible, throw an InvalidKeyException.
131
* See also JCA doc.
132
*/
133
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
134
if (key == null) {
135
throw new InvalidKeyException("Key must not be null");
136
}
137
String keyAlg = key.getAlgorithm();
138
if (keyAlg.equals("EC") == false) {
139
throw new InvalidKeyException("Not an EC key: " + keyAlg);
140
}
141
if (key instanceof PublicKey) {
142
return implTranslatePublicKey((PublicKey)key);
143
} else if (key instanceof PrivateKey) {
144
return implTranslatePrivateKey((PrivateKey)key);
145
} else {
146
throw new InvalidKeyException("Neither a public nor a private key");
147
}
148
}
149
150
// see JCA doc
151
protected PublicKey engineGeneratePublic(KeySpec keySpec)
152
throws InvalidKeySpecException {
153
try {
154
return implGeneratePublic(keySpec);
155
} catch (InvalidKeySpecException e) {
156
throw e;
157
} catch (GeneralSecurityException e) {
158
throw new InvalidKeySpecException(e);
159
}
160
}
161
162
// see JCA doc
163
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
164
throws InvalidKeySpecException {
165
try {
166
return implGeneratePrivate(keySpec);
167
} catch (InvalidKeySpecException e) {
168
throw e;
169
} catch (GeneralSecurityException e) {
170
throw new InvalidKeySpecException(e);
171
}
172
}
173
174
// internal implementation of translateKey() for public keys. See JCA doc
175
private PublicKey implTranslatePublicKey(PublicKey key)
176
throws InvalidKeyException {
177
if (key instanceof ECPublicKey) {
178
if (key instanceof ECPublicKeyImpl) {
179
return key;
180
}
181
ECPublicKey ecKey = (ECPublicKey)key;
182
return new ECPublicKeyImpl(
183
ecKey.getW(),
184
ecKey.getParams()
185
);
186
} else if ("X.509".equals(key.getFormat())) {
187
byte[] encoded = key.getEncoded();
188
return new ECPublicKeyImpl(encoded);
189
} else {
190
throw new InvalidKeyException("Public keys must be instance "
191
+ "of ECPublicKey or have X.509 encoding");
192
}
193
}
194
195
// internal implementation of translateKey() for private keys. See JCA doc
196
private PrivateKey implTranslatePrivateKey(PrivateKey key)
197
throws InvalidKeyException {
198
if (key instanceof ECPrivateKey) {
199
if (key instanceof ECPrivateKeyImpl) {
200
return key;
201
}
202
ECPrivateKey ecKey = (ECPrivateKey)key;
203
return new ECPrivateKeyImpl(
204
ecKey.getS(),
205
ecKey.getParams()
206
);
207
} else if ("PKCS#8".equals(key.getFormat())) {
208
byte[] encoded = key.getEncoded();
209
try {
210
return new ECPrivateKeyImpl(encoded);
211
} finally {
212
Arrays.fill(encoded, (byte)0);
213
}
214
} else {
215
throw new InvalidKeyException("Private keys must be instance "
216
+ "of ECPrivateKey or have PKCS#8 encoding");
217
}
218
}
219
220
// internal implementation of generatePublic. See JCA doc
221
private PublicKey implGeneratePublic(KeySpec keySpec)
222
throws GeneralSecurityException {
223
if (keySpec instanceof X509EncodedKeySpec) {
224
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
225
return new ECPublicKeyImpl(x509Spec.getEncoded());
226
} else if (keySpec instanceof ECPublicKeySpec) {
227
ECPublicKeySpec ecSpec = (ECPublicKeySpec)keySpec;
228
return new ECPublicKeyImpl(
229
ecSpec.getW(),
230
ecSpec.getParams()
231
);
232
} else {
233
throw new InvalidKeySpecException("Only ECPublicKeySpec "
234
+ "and X509EncodedKeySpec supported for EC public keys");
235
}
236
}
237
238
// internal implementation of generatePrivate. See JCA doc
239
private PrivateKey implGeneratePrivate(KeySpec keySpec)
240
throws GeneralSecurityException {
241
if (keySpec instanceof PKCS8EncodedKeySpec) {
242
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
243
byte[] encoded = pkcsSpec.getEncoded();
244
try {
245
return new ECPrivateKeyImpl(encoded);
246
} finally {
247
Arrays.fill(encoded, (byte) 0);
248
}
249
} else if (keySpec instanceof ECPrivateKeySpec) {
250
ECPrivateKeySpec ecSpec = (ECPrivateKeySpec)keySpec;
251
return new ECPrivateKeyImpl(ecSpec.getS(), ecSpec.getParams());
252
} else {
253
throw new InvalidKeySpecException("Only ECPrivateKeySpec "
254
+ "and PKCS8EncodedKeySpec supported for EC private keys");
255
}
256
}
257
258
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
259
throws InvalidKeySpecException {
260
try {
261
// convert key to one of our keys
262
// this also verifies that the key is a valid EC key and ensures
263
// that the encoding is X.509/PKCS#8 for public/private keys
264
key = engineTranslateKey(key);
265
} catch (InvalidKeyException e) {
266
throw new InvalidKeySpecException(e);
267
}
268
if (key instanceof ECPublicKey) {
269
ECPublicKey ecKey = (ECPublicKey)key;
270
if (keySpec.isAssignableFrom(ECPublicKeySpec.class)) {
271
return keySpec.cast(new ECPublicKeySpec(
272
ecKey.getW(),
273
ecKey.getParams()
274
));
275
} else if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)) {
276
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));
277
} else {
278
throw new InvalidKeySpecException
279
("KeySpec must be ECPublicKeySpec or "
280
+ "X509EncodedKeySpec for EC public keys");
281
}
282
} else if (key instanceof ECPrivateKey) {
283
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) {
284
byte[] encoded = key.getEncoded();
285
try {
286
return keySpec.cast(new PKCS8EncodedKeySpec(encoded));
287
} finally {
288
Arrays.fill(encoded, (byte)0);
289
}
290
} else if (keySpec.isAssignableFrom(ECPrivateKeySpec.class)) {
291
ECPrivateKey ecKey = (ECPrivateKey)key;
292
return keySpec.cast(new ECPrivateKeySpec(
293
ecKey.getS(),
294
ecKey.getParams()
295
));
296
} else {
297
throw new InvalidKeySpecException
298
("KeySpec must be ECPrivateKeySpec or "
299
+ "PKCS8EncodedKeySpec for EC private keys");
300
}
301
} else {
302
// should not occur, caught in engineTranslateKey()
303
throw new InvalidKeySpecException("Neither public nor private key");
304
}
305
}
306
}
307
308