author | mbalao |
Tue, 15 Jan 2019 19:24:07 -0300 | |
changeset 53340 | 142b179dd60e |
parent 53257 | 5170dc2bcf64 |
child 54062 | 62ab0859e7e5 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.security.pkcs11; |
|
27 |
||
28 |
import java.util.*; |
|
29 |
||
30 |
import java.security.*; |
|
31 |
import java.security.spec.*; |
|
32 |
||
33 |
import javax.crypto.*; |
|
34 |
import javax.crypto.spec.*; |
|
35 |
||
36 |
import static sun.security.pkcs11.TemplateManager.*; |
|
37 |
import sun.security.pkcs11.wrapper.*; |
|
38 |
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; |
|
39 |
||
40 |
/** |
|
41 |
* SecretKeyFactory implementation class. This class currently supports |
|
42 |
* DES, DESede, AES, ARCFOUR, and Blowfish. |
|
43 |
* |
|
44 |
* @author Andreas Sterbenz |
|
45 |
* @since 1.5 |
|
46 |
*/ |
|
47 |
final class P11SecretKeyFactory extends SecretKeyFactorySpi { |
|
48 |
||
49 |
// token instance |
|
50 |
private final Token token; |
|
51 |
||
52 |
// algorithm name |
|
53 |
private final String algorithm; |
|
54 |
||
55 |
P11SecretKeyFactory(Token token, String algorithm) { |
|
56 |
super(); |
|
57 |
this.token = token; |
|
58 |
this.algorithm = algorithm; |
|
59 |
} |
|
60 |
||
61 |
private static final Map<String,Long> keyTypes; |
|
62 |
||
63 |
static { |
|
64 |
keyTypes = new HashMap<String,Long>(); |
|
65 |
addKeyType("RC4", CKK_RC4); |
|
66 |
addKeyType("ARCFOUR", CKK_RC4); |
|
67 |
addKeyType("DES", CKK_DES); |
|
68 |
addKeyType("DESede", CKK_DES3); |
|
69 |
addKeyType("AES", CKK_AES); |
|
70 |
addKeyType("Blowfish", CKK_BLOWFISH); |
|
71 |
||
72 |
// we don't implement RC2 or IDEA, but we want to be able to generate |
|
73 |
// keys for those SSL/TLS ciphersuites. |
|
74 |
addKeyType("RC2", CKK_RC2); |
|
75 |
addKeyType("IDEA", CKK_IDEA); |
|
76 |
||
77 |
addKeyType("TlsPremasterSecret", PCKK_TLSPREMASTER); |
|
78 |
addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER); |
|
79 |
addKeyType("TlsMasterSecret", PCKK_TLSMASTER); |
|
80 |
addKeyType("Generic", CKK_GENERIC_SECRET); |
|
81 |
} |
|
82 |
||
83 |
private static void addKeyType(String name, long id) { |
|
84 |
Long l = Long.valueOf(id); |
|
85 |
keyTypes.put(name, l); |
|
86 |
keyTypes.put(name.toUpperCase(Locale.ENGLISH), l); |
|
87 |
} |
|
88 |
||
89 |
static long getKeyType(String algorithm) { |
|
90 |
Long l = keyTypes.get(algorithm); |
|
91 |
if (l == null) { |
|
92 |
algorithm = algorithm.toUpperCase(Locale.ENGLISH); |
|
93 |
l = keyTypes.get(algorithm); |
|
94 |
if (l == null) { |
|
95 |
if (algorithm.startsWith("HMAC")) { |
|
96 |
return PCKK_HMAC; |
|
97 |
} else if (algorithm.startsWith("SSLMAC")) { |
|
98 |
return PCKK_SSLMAC; |
|
99 |
} |
|
100 |
} |
|
101 |
} |
|
102 |
return (l != null) ? l.longValue() : -1; |
|
103 |
} |
|
104 |
||
105 |
/** |
|
106 |
* Convert an arbitrary key of algorithm into a P11Key of provider. |
|
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
107 |
* Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init(). |
2 | 108 |
*/ |
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
109 |
static P11Key convertKey(Token token, Key key, String algo) |
2 | 110 |
throws InvalidKeyException { |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
111 |
return convertKey(token, key, algo, null); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
112 |
} |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
113 |
|
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
114 |
/** |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
115 |
* Convert an arbitrary key of algorithm w/ custom attributes into a |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
116 |
* P11Key of provider. |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
117 |
* Used in P11KeyStore.storeSkey. |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
118 |
*/ |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
119 |
static P11Key convertKey(Token token, Key key, String algo, |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
120 |
CK_ATTRIBUTE[] extraAttrs) |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
121 |
throws InvalidKeyException { |
2 | 122 |
token.ensureValid(); |
123 |
if (key == null) { |
|
124 |
throw new InvalidKeyException("Key must not be null"); |
|
125 |
} |
|
126 |
if (key instanceof SecretKey == false) { |
|
127 |
throw new InvalidKeyException("Key must be a SecretKey"); |
|
128 |
} |
|
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
129 |
long algoType; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
130 |
if (algo == null) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
131 |
algo = key.getAlgorithm(); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
132 |
algoType = getKeyType(algo); |
2 | 133 |
} else { |
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
134 |
algoType = getKeyType(algo); |
2 | 135 |
long keyAlgorithmType = getKeyType(key.getAlgorithm()); |
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
136 |
if (algoType != keyAlgorithmType) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
137 |
if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) { |
2 | 138 |
// ignore key algorithm for MACs |
139 |
} else { |
|
140 |
throw new InvalidKeyException |
|
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
141 |
("Key algorithm must be " + algo); |
2 | 142 |
} |
143 |
} |
|
144 |
} |
|
145 |
if (key instanceof P11Key) { |
|
146 |
P11Key p11Key = (P11Key)key; |
|
147 |
if (p11Key.token == token) { |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
148 |
if (extraAttrs != null) { |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
149 |
P11Key newP11Key = null; |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
150 |
Session session = null; |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
151 |
long p11KeyID = p11Key.getKeyID(); |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
152 |
try { |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
153 |
session = token.getObjSession(); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
154 |
long newKeyID = token.p11.C_CopyObject(session.id(), |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
155 |
p11KeyID, extraAttrs); |
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
156 |
newP11Key = (P11Key) (P11Key.secretKey(session, |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
157 |
newKeyID, p11Key.algorithm, p11Key.keyLength, |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
158 |
extraAttrs)); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
159 |
} catch (PKCS11Exception p11e) { |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
160 |
throw new InvalidKeyException |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
161 |
("Cannot duplicate the PKCS11 key", p11e); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
162 |
} finally { |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
163 |
p11Key.releaseKeyID(); |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
164 |
token.releaseSession(session); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
165 |
} |
53257
5170dc2bcf64
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents:
47216
diff
changeset
|
166 |
p11Key = newP11Key; |
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
167 |
} |
2 | 168 |
return p11Key; |
169 |
} |
|
170 |
} |
|
171 |
P11Key p11Key = token.secretCache.get(key); |
|
172 |
if (p11Key != null) { |
|
173 |
return p11Key; |
|
174 |
} |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
175 |
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) { |
2 | 176 |
throw new InvalidKeyException("Encoded format must be RAW"); |
177 |
} |
|
178 |
byte[] encoded = key.getEncoded(); |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
179 |
p11Key = createKey(token, encoded, algo, algoType, extraAttrs); |
2 | 180 |
token.secretCache.put(key, p11Key); |
181 |
return p11Key; |
|
182 |
} |
|
183 |
||
184 |
static void fixDESParity(byte[] key, int offset) { |
|
185 |
for (int i = 0; i < 8; i++) { |
|
186 |
int b = key[offset] & 0xfe; |
|
187 |
b |= (Integer.bitCount(b) & 1) ^ 1; |
|
188 |
key[offset++] = (byte)b; |
|
189 |
} |
|
190 |
} |
|
191 |
||
192 |
private static P11Key createKey(Token token, byte[] encoded, |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
193 |
String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs) |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
194 |
throws InvalidKeyException { |
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
195 |
int n = encoded.length << 3; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
196 |
int keyLength = n; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
197 |
try { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
198 |
switch ((int)keyType) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
199 |
case (int)CKK_DES: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
200 |
keyLength = |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
201 |
P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
202 |
fixDESParity(encoded, 0); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
203 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
204 |
case (int)CKK_DES3: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
205 |
keyLength = |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
206 |
P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
207 |
fixDESParity(encoded, 0); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
208 |
fixDESParity(encoded, 8); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
209 |
if (keyLength == 112) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
210 |
keyType = CKK_DES2; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
211 |
} else { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
212 |
keyType = CKK_DES3; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
213 |
fixDESParity(encoded, 16); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
214 |
} |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
215 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
216 |
case (int)CKK_AES: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
217 |
keyLength = |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
218 |
P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
219 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
220 |
case (int)CKK_RC4: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
221 |
keyLength = |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
222 |
P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
223 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
224 |
case (int)CKK_BLOWFISH: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
225 |
keyLength = |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
226 |
P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n, |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
227 |
token); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
228 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
229 |
case (int)CKK_GENERIC_SECRET: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
230 |
case (int)PCKK_TLSPREMASTER: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
231 |
case (int)PCKK_TLSRSAPREMASTER: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
232 |
case (int)PCKK_TLSMASTER: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
233 |
keyType = CKK_GENERIC_SECRET; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
234 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
235 |
case (int)PCKK_SSLMAC: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
236 |
case (int)PCKK_HMAC: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
237 |
if (n == 0) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
238 |
throw new InvalidKeyException |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
239 |
("MAC keys must not be empty"); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
240 |
} |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
241 |
keyType = CKK_GENERIC_SECRET; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
242 |
break; |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
243 |
default: |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
244 |
throw new InvalidKeyException("Unknown algorithm " + |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
245 |
algorithm); |
2 | 246 |
} |
290
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
247 |
} catch (InvalidAlgorithmParameterException iape) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
248 |
throw new InvalidKeyException("Invalid key for " + algorithm, |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
249 |
iape); |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
250 |
} catch (ProviderException pe) { |
519d4185fbe2
6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents:
2
diff
changeset
|
251 |
throw new InvalidKeyException("Could not create key", pe); |
2 | 252 |
} |
253 |
Session session = null; |
|
254 |
try { |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
255 |
CK_ATTRIBUTE[] attributes; |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
256 |
if (extraAttrs != null) { |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
257 |
attributes = new CK_ATTRIBUTE[3 + extraAttrs.length]; |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
258 |
System.arraycopy(extraAttrs, 0, attributes, 3, |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
259 |
extraAttrs.length); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
260 |
} else { |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
261 |
attributes = new CK_ATTRIBUTE[3]; |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
262 |
} |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
263 |
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
264 |
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType); |
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
265 |
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded); |
2 | 266 |
attributes = token.getAttributes |
267 |
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes); |
|
268 |
session = token.getObjSession(); |
|
269 |
long keyID = token.p11.C_CreateObject(session.id(), attributes); |
|
270 |
P11Key p11Key = (P11Key)P11Key.secretKey |
|
271 |
(session, keyID, algorithm, keyLength, attributes); |
|
272 |
return p11Key; |
|
273 |
} catch (PKCS11Exception e) { |
|
274 |
throw new InvalidKeyException("Could not create key", e); |
|
275 |
} finally { |
|
276 |
token.releaseSession(session); |
|
277 |
} |
|
278 |
} |
|
279 |
||
280 |
// see JCE spec |
|
281 |
protected SecretKey engineGenerateSecret(KeySpec keySpec) |
|
282 |
throws InvalidKeySpecException { |
|
283 |
token.ensureValid(); |
|
284 |
if (keySpec == null) { |
|
285 |
throw new InvalidKeySpecException("KeySpec must not be null"); |
|
286 |
} |
|
287 |
if (keySpec instanceof SecretKeySpec) { |
|
288 |
try { |
|
289 |
Key key = convertKey(token, (SecretKey)keySpec, algorithm); |
|
290 |
return (SecretKey)key; |
|
291 |
} catch (InvalidKeyException e) { |
|
292 |
throw new InvalidKeySpecException(e); |
|
293 |
} |
|
294 |
} else if (algorithm.equalsIgnoreCase("DES")) { |
|
295 |
if (keySpec instanceof DESKeySpec) { |
|
296 |
byte[] keyBytes = ((DESKeySpec)keySpec).getKey(); |
|
297 |
keySpec = new SecretKeySpec(keyBytes, "DES"); |
|
298 |
return engineGenerateSecret(keySpec); |
|
299 |
} |
|
300 |
} else if (algorithm.equalsIgnoreCase("DESede")) { |
|
301 |
if (keySpec instanceof DESedeKeySpec) { |
|
302 |
byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey(); |
|
303 |
keySpec = new SecretKeySpec(keyBytes, "DESede"); |
|
304 |
return engineGenerateSecret(keySpec); |
|
305 |
} |
|
306 |
} |
|
307 |
throw new InvalidKeySpecException |
|
308 |
("Unsupported spec: " + keySpec.getClass().getName()); |
|
309 |
} |
|
310 |
||
311 |
private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException { |
|
312 |
try { |
|
313 |
key = engineTranslateKey(key); |
|
291
be2e0a87d658
6599979: KeyStore.setEntry/setKeyEntry() do not override existing entry for secret key objects
valeriep
parents:
290
diff
changeset
|
314 |
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) { |
2 | 315 |
throw new InvalidKeySpecException |
316 |
("Could not obtain key bytes"); |
|
317 |
} |
|
318 |
byte[] k = key.getEncoded(); |
|
319 |
return k; |
|
320 |
} catch (InvalidKeyException e) { |
|
321 |
throw new InvalidKeySpecException(e); |
|
322 |
} |
|
323 |
} |
|
324 |
||
325 |
// see JCE spec |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
5506
diff
changeset
|
326 |
protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec) |
2 | 327 |
throws InvalidKeySpecException { |
328 |
token.ensureValid(); |
|
329 |
if ((key == null) || (keySpec == null)) { |
|
330 |
throw new InvalidKeySpecException |
|
331 |
("key and keySpec must not be null"); |
|
332 |
} |
|
333 |
if (SecretKeySpec.class.isAssignableFrom(keySpec)) { |
|
334 |
return new SecretKeySpec(getKeyBytes(key), algorithm); |
|
335 |
} else if (algorithm.equalsIgnoreCase("DES")) { |
|
336 |
try { |
|
337 |
if (DESKeySpec.class.isAssignableFrom(keySpec)) { |
|
338 |
return new DESKeySpec(getKeyBytes(key)); |
|
339 |
} |
|
340 |
} catch (InvalidKeyException e) { |
|
341 |
throw new InvalidKeySpecException(e); |
|
342 |
} |
|
343 |
} else if (algorithm.equalsIgnoreCase("DESede")) { |
|
344 |
try { |
|
345 |
if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { |
|
346 |
return new DESedeKeySpec(getKeyBytes(key)); |
|
347 |
} |
|
348 |
} catch (InvalidKeyException e) { |
|
349 |
throw new InvalidKeySpecException(e); |
|
350 |
} |
|
351 |
} |
|
352 |
throw new InvalidKeySpecException |
|
353 |
("Unsupported spec: " + keySpec.getName()); |
|
354 |
} |
|
355 |
||
356 |
// see JCE spec |
|
357 |
protected SecretKey engineTranslateKey(SecretKey key) |
|
358 |
throws InvalidKeyException { |
|
359 |
return (SecretKey)convertKey(token, key, algorithm); |
|
360 |
} |
|
361 |
||
362 |
} |