192
193 // see JCE spec
194 protected byte[] engineGenerateSecret() throws IllegalStateException {
195 if (multiPartyAgreement != null) {
196 byte[] val = multiPartyAgreement.generateSecret();
197 multiPartyAgreement = null;
198 return val;
199 }
200 if ((privateKey == null) || (publicValue == null)) {
201 throw new IllegalStateException("Not initialized correctly");
202 }
203 Session session = null;
204 try {
205 session = token.getOpSession();
206 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
207 new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
208 new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
209 };
210 attributes = token.getAttributes
211 (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
212 long keyID = token.p11.C_DeriveKey(session.id(),
213 new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
214 attributes);
215 attributes = new CK_ATTRIBUTE[] {
216 new CK_ATTRIBUTE(CKA_VALUE)
217 };
218 token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
219 byte[] secret = attributes[0].getByteArray();
220 token.p11.C_DestroyObject(session.id(), keyID);
221 // Some vendors, e.g. NSS, trim off the leading 0x00 byte(s) from
222 // the generated secret. Thus, we need to check the secret length
223 // and trim/pad it so the returned value has the same length as
224 // the modulus size
225 if (secret.length == secretLen) {
226 return secret;
227 } else {
228 if (secret.length > secretLen) {
229 // Shouldn't happen; but check just in case
230 throw new ProviderException("generated secret is out-of-range");
231 }
232 byte[] newSecret = new byte[secretLen];
233 System.arraycopy(secret, 0, newSecret, secretLen - secret.length,
234 secret.length);
316 }
317 return new SecretKeySpec(secret, 0, keyLen, algorithm);
318 }
319
320 private SecretKey nativeGenerateSecret(String algorithm)
321 throws IllegalStateException, NoSuchAlgorithmException,
322 InvalidKeyException {
323 if ((privateKey == null) || (publicValue == null)) {
324 throw new IllegalStateException("Not initialized correctly");
325 }
326 long keyType = CKK_GENERIC_SECRET;
327 Session session = null;
328 try {
329 session = token.getObjSession();
330 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
331 new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
332 new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
333 };
334 attributes = token.getAttributes
335 (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
336 long keyID = token.p11.C_DeriveKey(session.id(),
337 new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
338 attributes);
339 CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
340 new CK_ATTRIBUTE(CKA_VALUE_LEN),
341 };
342 token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
343 int keyLen = (int)lenAttributes[0].getLong();
344 SecretKey key = P11Key.secretKey
345 (session, keyID, algorithm, keyLen << 3, attributes);
346 if ("RAW".equals(key.getFormat())) {
347 // Workaround for Solaris bug 6318543.
348 // Strip leading zeroes ourselves if possible (key not sensitive).
349 // This should be removed once the Solaris fix is available
350 // as here we always retrieve the CKA_VALUE even for tokens
351 // that do not have that bug.
352 byte[] keyBytes = key.getEncoded();
353 byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
354 if (keyBytes != newBytes) {
355 key = new SecretKeySpec(newBytes, algorithm);
356 }
357 }
358 return key;
359 } catch (PKCS11Exception e) {
360 throw new InvalidKeyException("Could not derive key", e);
361 } finally {
362 publicValue = null;
363 token.releaseSession(session);
364 }
365 }
|
192
193 // see JCE spec
194 protected byte[] engineGenerateSecret() throws IllegalStateException {
195 if (multiPartyAgreement != null) {
196 byte[] val = multiPartyAgreement.generateSecret();
197 multiPartyAgreement = null;
198 return val;
199 }
200 if ((privateKey == null) || (publicValue == null)) {
201 throw new IllegalStateException("Not initialized correctly");
202 }
203 Session session = null;
204 try {
205 session = token.getOpSession();
206 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
207 new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
208 new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
209 };
210 attributes = token.getAttributes
211 (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
212 privateKey.incNativeKeyRef();
213 long keyID;
214 try {
215 keyID = token.p11.C_DeriveKey(session.id(),
216 new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
217 attributes);
218 } finally {
219 privateKey.decNativeKeyRef();
220 }
221 attributes = new CK_ATTRIBUTE[] {
222 new CK_ATTRIBUTE(CKA_VALUE)
223 };
224 token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
225 byte[] secret = attributes[0].getByteArray();
226 token.p11.C_DestroyObject(session.id(), keyID);
227 // Some vendors, e.g. NSS, trim off the leading 0x00 byte(s) from
228 // the generated secret. Thus, we need to check the secret length
229 // and trim/pad it so the returned value has the same length as
230 // the modulus size
231 if (secret.length == secretLen) {
232 return secret;
233 } else {
234 if (secret.length > secretLen) {
235 // Shouldn't happen; but check just in case
236 throw new ProviderException("generated secret is out-of-range");
237 }
238 byte[] newSecret = new byte[secretLen];
239 System.arraycopy(secret, 0, newSecret, secretLen - secret.length,
240 secret.length);
322 }
323 return new SecretKeySpec(secret, 0, keyLen, algorithm);
324 }
325
326 private SecretKey nativeGenerateSecret(String algorithm)
327 throws IllegalStateException, NoSuchAlgorithmException,
328 InvalidKeyException {
329 if ((privateKey == null) || (publicValue == null)) {
330 throw new IllegalStateException("Not initialized correctly");
331 }
332 long keyType = CKK_GENERIC_SECRET;
333 Session session = null;
334 try {
335 session = token.getObjSession();
336 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
337 new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
338 new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
339 };
340 attributes = token.getAttributes
341 (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
342 privateKey.incNativeKeyRef();
343 long keyID;
344 try {
345 keyID = token.p11.C_DeriveKey(session.id(),
346 new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
347 attributes);
348 } finally {
349 privateKey.decNativeKeyRef();
350 }
351 CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
352 new CK_ATTRIBUTE(CKA_VALUE_LEN),
353 };
354 token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
355 int keyLen = (int)lenAttributes[0].getLong();
356 SecretKey key = P11Key.secretKey
357 (session, keyID, algorithm, keyLen << 3, attributes, true);
358 if ("RAW".equals(key.getFormat())) {
359 // Workaround for Solaris bug 6318543.
360 // Strip leading zeroes ourselves if possible (key not sensitive).
361 // This should be removed once the Solaris fix is available
362 // as here we always retrieve the CKA_VALUE even for tokens
363 // that do not have that bug.
364 byte[] keyBytes = key.getEncoded();
365 byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
366 if (keyBytes != newBytes) {
367 key = new SecretKeySpec(newBytes, algorithm);
368 }
369 }
370 return key;
371 } catch (PKCS11Exception e) {
372 throw new InvalidKeyException("Could not derive key", e);
373 } finally {
374 publicValue = null;
375 token.releaseSession(session);
376 }
377 }
|