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), 217 privateKey.keyID, 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), 347 privateKey.keyID, 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(session, keyID, algorithm, 357 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 } |