1274 keyType = "ARCFOUR";
1275 } else {
1276 if (debug != null) {
1277 debug.println("unknown key type [" +
1278 kType +
1279 "] - using 'Generic Secret'");
1280 }
1281 keyType = "Generic Secret";
1282 }
1283
1284 // XXX NSS problem CKR_ATTRIBUTE_TYPE_INVALID?
1285 if (NSS_TEST) {
1286 keyLength = 128;
1287 } else {
1288 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE_LEN) };
1289 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1290 keyLength = (int)attrs[0].getLong();
1291 }
1292 }
1293
1294 return P11Key.secretKey(session, oHandle, keyType, keyLength, null);
1295 }
1296
1297 private PrivateKey loadPkey(Session session, long oHandle)
1298 throws PKCS11Exception, KeyStoreException {
1299
1300 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1301 new CK_ATTRIBUTE(CKA_KEY_TYPE) };
1302 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1303 long kType = attrs[0].getLong();
1304 String keyType = null;
1305 int keyLength = 0;
1306
1307 if (kType == CKK_RSA) {
1308
1309 keyType = "RSA";
1310
1311 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS) };
1312 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1313 BigInteger modulus = attrs[0].getBigInteger();
1314 keyLength = modulus.bitLength();
1315
1316 // This check will combine our "don't care" values here
1317 // with the system-wide min/max values.
1318 try {
1319 RSAKeyFactory.checkKeyLengths(keyLength, null,
1320 -1, Integer.MAX_VALUE);
1321 } catch (InvalidKeyException e) {
1322 throw new KeyStoreException(e.getMessage());
1323 }
1324
1325 return P11Key.privateKey(session,
1326 oHandle,
1327 keyType,
1328 keyLength,
1329 null);
1330
1331 } else if (kType == CKK_DSA) {
1332
1333 keyType = "DSA";
1334
1335 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1336 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1337 BigInteger prime = attrs[0].getBigInteger();
1338 keyLength = prime.bitLength();
1339
1340 return P11Key.privateKey(session,
1341 oHandle,
1342 keyType,
1343 keyLength,
1344 null);
1345
1346 } else if (kType == CKK_DH) {
1347
1348 keyType = "DH";
1349
1350 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1351 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1352 BigInteger prime = attrs[0].getBigInteger();
1353 keyLength = prime.bitLength();
1354
1355 return P11Key.privateKey(session,
1356 oHandle,
1357 keyType,
1358 keyLength,
1359 null);
1360
1361 } else if (kType == CKK_EC) {
1362
1363 attrs = new CK_ATTRIBUTE[] {
1364 new CK_ATTRIBUTE(CKA_EC_PARAMS),
1365 };
1366 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1367 byte[] encodedParams = attrs[0].getByteArray();
1368 try {
1369 ECParameterSpec params =
1370 ECUtil.getECParameterSpec(null, encodedParams);
1371 keyLength = params.getCurve().getField().getFieldSize();
1372 } catch (IOException e) {
1373 // we do not want to accept key with unsupported parameters
1374 throw new KeyStoreException("Unsupported parameters", e);
1375 }
1376
1377 return P11Key.privateKey(session, oHandle, "EC", keyLength, null);
1378
1379 } else {
1380 if (debug != null) {
1381 debug.println("unknown key type [" + kType + "]");
1382 }
1383 throw new KeyStoreException("unknown key type");
1384 }
1385 }
1386
1387
1388 /**
1389 * XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key
1390 * it not only changes the CKA_ID of the private key,
1391 * it changes the CKA_ID of the corresponding cert too.
1392 * And vice versa.
1393 *
1394 * XXX On ibutton, CKR_DEVICE_ERROR if you C_SetAttribute(CKA_ID)
1395 * for a private key, and then try to delete the corresponding cert.
1396 * So this code reverses the order.
1397 * After the cert is first destroyed (if necessary),
1483 } finally {
1484 token.releaseSession(session);
1485 }
1486 }
1487
1488 private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
1489 throws PKCS11Exception {
1490
1491 // if token key, update alias.
1492 // if session key, convert to token key.
1493
1494 Session session = null;
1495 try {
1496 session = token.getOpSession();
1497 if (key.tokenObject == true) {
1498
1499 // token key - set new CKA_ID
1500
1501 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1502 new CK_ATTRIBUTE(CKA_ID, alias) };
1503 token.p11.C_SetAttributeValue
1504 (session.id(), key.keyID, attrs);
1505 if (debug != null) {
1506 debug.println("updateP11Pkey set new alias [" +
1507 alias +
1508 "] for key entry");
1509 }
1510 } else {
1511
1512 // session key - convert to token key and set CKA_ID
1513
1514 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1515 ATTR_TOKEN_TRUE,
1516 new CK_ATTRIBUTE(CKA_ID, alias),
1517 };
1518 if (attribute != null) {
1519 attrs = addAttribute(attrs, attribute);
1520 }
1521 token.p11.C_CopyObject(session.id(), key.keyID, attrs);
1522 if (debug != null) {
1523 debug.println("updateP11Pkey copied private session key " +
1524 "for [" +
1525 alias +
1526 "] to token entry");
1527 }
1528 }
1529 } finally {
1530 token.releaseSession(session);
1531 }
1532 }
1533
1534 private void storeCert(String alias, X509Certificate cert)
1535 throws PKCS11Exception, CertificateException {
1536
1537 ArrayList<CK_ATTRIBUTE> attrList = new ArrayList<CK_ATTRIBUTE>();
1538 attrList.add(ATTR_TOKEN_TRUE);
1539 attrList.add(ATTR_CLASS_CERT);
1540 attrList.add(ATTR_X509_CERT_TYPE);
1541 attrList.add(new CK_ATTRIBUTE(CKA_SUBJECT,
1609 } else if (debug != null) {
1610 debug.println("ignoring duplicate CA cert for [" +
1611 chain[i].getSubjectX500Principal() +
1612 "]");
1613 }
1614 }
1615 }
1616
1617 private void storeSkey(String alias, KeyStore.SecretKeyEntry ske)
1618 throws PKCS11Exception, KeyStoreException {
1619
1620 SecretKey skey = ske.getSecretKey();
1621 // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
1622 // they are handled in P11SecretKeyFactory.createKey() method.
1623 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1624 ATTR_SKEY_TOKEN_TRUE,
1625 ATTR_PRIVATE_TRUE,
1626 new CK_ATTRIBUTE(CKA_LABEL, alias),
1627 };
1628 try {
1629 P11SecretKeyFactory.convertKey(token, skey, null, attrs);
1630 } catch (InvalidKeyException ike) {
1631 // re-throw KeyStoreException to match javadoc
1632 throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
1633 }
1634
1635 // update global alias map
1636 aliasMap.put(alias, new AliasInfo(alias));
1637
1638 if (debug != null) {
1639 debug.println("storeSkey created token secret key for [" +
1640 alias + "]");
1641 }
1642 }
1643
1644 private static CK_ATTRIBUTE[] addAttribute(CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE attr) {
1645 int n = attrs.length;
1646 CK_ATTRIBUTE[] newAttrs = new CK_ATTRIBUTE[n + 1];
1647 System.arraycopy(attrs, 0, newAttrs, 0, n);
1648 newAttrs[n] = attr;
1649 return newAttrs;
|
1274 keyType = "ARCFOUR";
1275 } else {
1276 if (debug != null) {
1277 debug.println("unknown key type [" +
1278 kType +
1279 "] - using 'Generic Secret'");
1280 }
1281 keyType = "Generic Secret";
1282 }
1283
1284 // XXX NSS problem CKR_ATTRIBUTE_TYPE_INVALID?
1285 if (NSS_TEST) {
1286 keyLength = 128;
1287 } else {
1288 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE_LEN) };
1289 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1290 keyLength = (int)attrs[0].getLong();
1291 }
1292 }
1293
1294 return P11Key.secretKey(session, oHandle, keyType, keyLength, null, false);
1295 }
1296
1297 private PrivateKey loadPkey(Session session, long oHandle)
1298 throws PKCS11Exception, KeyStoreException {
1299
1300 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1301 new CK_ATTRIBUTE(CKA_KEY_TYPE) };
1302 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1303 long kType = attrs[0].getLong();
1304 String keyType = null;
1305 int keyLength = 0;
1306
1307 if (kType == CKK_RSA) {
1308
1309 keyType = "RSA";
1310
1311 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS) };
1312 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1313 BigInteger modulus = attrs[0].getBigInteger();
1314 keyLength = modulus.bitLength();
1315
1316 // This check will combine our "don't care" values here
1317 // with the system-wide min/max values.
1318 try {
1319 RSAKeyFactory.checkKeyLengths(keyLength, null,
1320 -1, Integer.MAX_VALUE);
1321 } catch (InvalidKeyException e) {
1322 throw new KeyStoreException(e.getMessage());
1323 }
1324
1325 return P11Key.privateKey(session,
1326 oHandle,
1327 keyType,
1328 keyLength,
1329 null,
1330 false);
1331
1332 } else if (kType == CKK_DSA) {
1333
1334 keyType = "DSA";
1335
1336 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1337 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1338 BigInteger prime = attrs[0].getBigInteger();
1339 keyLength = prime.bitLength();
1340
1341 return P11Key.privateKey(session,
1342 oHandle,
1343 keyType,
1344 keyLength,
1345 null,
1346 false);
1347
1348 } else if (kType == CKK_DH) {
1349
1350 keyType = "DH";
1351
1352 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1353 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1354 BigInteger prime = attrs[0].getBigInteger();
1355 keyLength = prime.bitLength();
1356
1357 return P11Key.privateKey(session,
1358 oHandle,
1359 keyType,
1360 keyLength,
1361 null,
1362 false);
1363
1364 } else if (kType == CKK_EC) {
1365
1366 attrs = new CK_ATTRIBUTE[] {
1367 new CK_ATTRIBUTE(CKA_EC_PARAMS),
1368 };
1369 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1370 byte[] encodedParams = attrs[0].getByteArray();
1371 try {
1372 ECParameterSpec params =
1373 ECUtil.getECParameterSpec(null, encodedParams);
1374 keyLength = params.getCurve().getField().getFieldSize();
1375 } catch (IOException e) {
1376 // we do not want to accept key with unsupported parameters
1377 throw new KeyStoreException("Unsupported parameters", e);
1378 }
1379
1380 return P11Key.privateKey(session, oHandle, "EC", keyLength, null, false);
1381
1382 } else {
1383 if (debug != null) {
1384 debug.println("unknown key type [" + kType + "]");
1385 }
1386 throw new KeyStoreException("unknown key type");
1387 }
1388 }
1389
1390
1391 /**
1392 * XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key
1393 * it not only changes the CKA_ID of the private key,
1394 * it changes the CKA_ID of the corresponding cert too.
1395 * And vice versa.
1396 *
1397 * XXX On ibutton, CKR_DEVICE_ERROR if you C_SetAttribute(CKA_ID)
1398 * for a private key, and then try to delete the corresponding cert.
1399 * So this code reverses the order.
1400 * After the cert is first destroyed (if necessary),
1486 } finally {
1487 token.releaseSession(session);
1488 }
1489 }
1490
1491 private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
1492 throws PKCS11Exception {
1493
1494 // if token key, update alias.
1495 // if session key, convert to token key.
1496
1497 Session session = null;
1498 try {
1499 session = token.getOpSession();
1500 if (key.tokenObject == true) {
1501
1502 // token key - set new CKA_ID
1503
1504 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1505 new CK_ATTRIBUTE(CKA_ID, alias) };
1506 key.makeNativeKeyPersistent();
1507 token.p11.C_SetAttributeValue
1508 (session.id(), key.keyID, attrs);
1509 if (debug != null) {
1510 debug.println("updateP11Pkey set new alias [" +
1511 alias +
1512 "] for key entry");
1513 }
1514 } else {
1515
1516 // session key - convert to token key and set CKA_ID
1517
1518 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1519 ATTR_TOKEN_TRUE,
1520 new CK_ATTRIBUTE(CKA_ID, alias),
1521 };
1522 if (attribute != null) {
1523 attrs = addAttribute(attrs, attribute);
1524 }
1525 key.incNativeKeyRef();
1526 try {
1527 token.p11.C_CopyObject(session.id(), key.keyID, attrs);
1528 } finally {
1529 key.decNativeKeyRef();
1530 }
1531 if (debug != null) {
1532 debug.println("updateP11Pkey copied private session key " +
1533 "for [" +
1534 alias +
1535 "] to token entry");
1536 }
1537 }
1538 } finally {
1539 token.releaseSession(session);
1540 }
1541 }
1542
1543 private void storeCert(String alias, X509Certificate cert)
1544 throws PKCS11Exception, CertificateException {
1545
1546 ArrayList<CK_ATTRIBUTE> attrList = new ArrayList<CK_ATTRIBUTE>();
1547 attrList.add(ATTR_TOKEN_TRUE);
1548 attrList.add(ATTR_CLASS_CERT);
1549 attrList.add(ATTR_X509_CERT_TYPE);
1550 attrList.add(new CK_ATTRIBUTE(CKA_SUBJECT,
1618 } else if (debug != null) {
1619 debug.println("ignoring duplicate CA cert for [" +
1620 chain[i].getSubjectX500Principal() +
1621 "]");
1622 }
1623 }
1624 }
1625
1626 private void storeSkey(String alias, KeyStore.SecretKeyEntry ske)
1627 throws PKCS11Exception, KeyStoreException {
1628
1629 SecretKey skey = ske.getSecretKey();
1630 // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
1631 // they are handled in P11SecretKeyFactory.createKey() method.
1632 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1633 ATTR_SKEY_TOKEN_TRUE,
1634 ATTR_PRIVATE_TRUE,
1635 new CK_ATTRIBUTE(CKA_LABEL, alias),
1636 };
1637 try {
1638 P11Key k = P11SecretKeyFactory.convertKey(token, skey, null, attrs);
1639 k.makeNativeKeyPersistent();
1640 } catch (InvalidKeyException ike) {
1641 // re-throw KeyStoreException to match javadoc
1642 throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
1643 }
1644
1645 // update global alias map
1646 aliasMap.put(alias, new AliasInfo(alias));
1647
1648 if (debug != null) {
1649 debug.println("storeSkey created token secret key for [" +
1650 alias + "]");
1651 }
1652 }
1653
1654 private static CK_ATTRIBUTE[] addAttribute(CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE attr) {
1655 int n = attrs.length;
1656 CK_ATTRIBUTE[] newAttrs = new CK_ATTRIBUTE[n + 1];
1657 System.arraycopy(attrs, 0, newAttrs, 0, n);
1658 newAttrs[n] = attr;
1659 return newAttrs;
|