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;
1877 /**
1878 * Compute the CKA_ID and/or CKA_NETSCAPE_DB attributes that should be
1879 * used for this private key. It uses the same algorithm to calculate the
1880 * values as NSS. The public and private keys MUST match for the result to
1881 * be correct.
1882 *
1883 * It returns a 2 element array with CKA_ID at index 0 and CKA_NETSCAPE_DB
1884 * at index 1. The boolean flags determine what is to be calculated.
1885 * If false or if we could not calculate the value, that element is null.
1886 *
1887 * NOTE that we currently do not use the CKA_ID value calculated by this
1888 * method.
1889 */
1890 private CK_ATTRIBUTE[] getIdAttributes(PrivateKey privateKey,
1891 PublicKey publicKey, boolean id, boolean netscapeDb) {
1892 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[2];
1893 if ((id || netscapeDb) == false) {
1894 return attrs;
1895 }
1896 String alg = privateKey.getAlgorithm();
1897 if (id && alg.equals("RSA") && (publicKey instanceof RSAPublicKey)) {
1898 // CKA_NETSCAPE_DB not needed for RSA public keys
1899 BigInteger n = ((RSAPublicKey)publicKey).getModulus();
1900 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(n)));
1901 } else if (alg.equals("DSA") && (publicKey instanceof DSAPublicKey)) {
1902 BigInteger y = ((DSAPublicKey)publicKey).getY();
1903 if (id) {
1904 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
1905 }
1906 if (netscapeDb) {
1907 attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
1908 }
1909 } else if (alg.equals("DH") && (publicKey instanceof DHPublicKey)) {
1910 BigInteger y = ((DHPublicKey)publicKey).getY();
1911 if (id) {
1912 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
1913 }
1914 if (netscapeDb) {
1915 attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
1916 }
1917 } else if (alg.equals("EC") && (publicKey instanceof ECPublicKey)) {
1918 ECPublicKey ecPub = (ECPublicKey)publicKey;
1919 ECPoint point = ecPub.getW();
1920 ECParameterSpec params = ecPub.getParams();
|
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 false);
1296 }
1297
1298 private PrivateKey loadPkey(Session session, long oHandle)
1299 throws PKCS11Exception, KeyStoreException {
1300
1301 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1302 new CK_ATTRIBUTE(CKA_KEY_TYPE) };
1303 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1304 long kType = attrs[0].getLong();
1305 String keyType = null;
1306 int keyLength = 0;
1307
1308 if (kType == CKK_RSA) {
1309
1310 keyType = "RSA";
1311
1312 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS) };
1313 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1314 BigInteger modulus = attrs[0].getBigInteger();
1315 keyLength = modulus.bitLength();
1316
1317 // This check will combine our "don't care" values here
1318 // with the system-wide min/max values.
1319 try {
1320 RSAKeyFactory.checkKeyLengths(keyLength, null,
1321 -1, Integer.MAX_VALUE);
1322 } catch (InvalidKeyException e) {
1323 throw new KeyStoreException(e.getMessage());
1324 }
1325
1326 return P11Key.privateKey(session,
1327 oHandle,
1328 keyType,
1329 keyLength,
1330 null,
1331 false);
1332
1333 } else if (kType == CKK_DSA) {
1334
1335 keyType = "DSA";
1336
1337 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1338 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1339 BigInteger prime = attrs[0].getBigInteger();
1340 keyLength = prime.bitLength();
1341
1342 return P11Key.privateKey(session,
1343 oHandle,
1344 keyType,
1345 keyLength,
1346 null,
1347 false);
1348
1349 } else if (kType == CKK_DH) {
1350
1351 keyType = "DH";
1352
1353 attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
1354 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1355 BigInteger prime = attrs[0].getBigInteger();
1356 keyLength = prime.bitLength();
1357
1358 return P11Key.privateKey(session,
1359 oHandle,
1360 keyType,
1361 keyLength,
1362 null,
1363 false);
1364
1365 } else if (kType == CKK_EC) {
1366
1367 attrs = new CK_ATTRIBUTE[] {
1368 new CK_ATTRIBUTE(CKA_EC_PARAMS),
1369 };
1370 token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
1371 byte[] encodedParams = attrs[0].getByteArray();
1372 try {
1373 ECParameterSpec params =
1374 ECUtil.getECParameterSpec(null, encodedParams);
1375 keyLength = params.getCurve().getField().getFieldSize();
1376 } catch (IOException e) {
1377 // we do not want to accept key with unsupported parameters
1378 throw new KeyStoreException("Unsupported parameters", e);
1379 }
1380
1381 return P11Key.privateKey(session, oHandle, "EC", keyLength, null,
1382 false);
1383
1384 } else {
1385 if (debug != null) {
1386 debug.println("unknown key type [" + kType + "]");
1387 }
1388 throw new KeyStoreException("unknown key type");
1389 }
1390 }
1391
1392
1393 /**
1394 * XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key
1395 * it not only changes the CKA_ID of the private key,
1396 * it changes the CKA_ID of the corresponding cert too.
1397 * And vice versa.
1398 *
1399 * XXX On ibutton, CKR_DEVICE_ERROR if you C_SetAttribute(CKA_ID)
1400 * for a private key, and then try to delete the corresponding cert.
1401 * So this code reverses the order.
1402 * After the cert is first destroyed (if necessary),
1488 } finally {
1489 token.releaseSession(session);
1490 }
1491 }
1492
1493 private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
1494 throws PKCS11Exception {
1495
1496 // if token key, update alias.
1497 // if session key, convert to token key.
1498
1499 Session session = null;
1500 try {
1501 session = token.getOpSession();
1502 if (key.tokenObject == true) {
1503
1504 // token key - set new CKA_ID
1505
1506 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1507 new CK_ATTRIBUTE(CKA_ID, alias) };
1508 key.makeNativeKeyPersistent();
1509 token.p11.C_SetAttributeValue
1510 (session.id(), key.keyID, attrs);
1511 if (debug != null) {
1512 debug.println("updateP11Pkey set new alias [" +
1513 alias +
1514 "] for key entry");
1515 }
1516 } else {
1517
1518 // session key - convert to token key and set CKA_ID
1519
1520 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1521 ATTR_TOKEN_TRUE,
1522 new CK_ATTRIBUTE(CKA_ID, alias),
1523 };
1524 if (attribute != null) {
1525 attrs = addAttribute(attrs, attribute);
1526 }
1527 key.incNativeKeyRef();
1528 try {
1529 token.p11.C_CopyObject(session.id(), key.keyID, attrs);
1530 } finally {
1531 key.decNativeKeyRef();
1532 }
1533 if (debug != null) {
1534 debug.println("updateP11Pkey copied private session key " +
1535 "for [" +
1536 alias +
1537 "] to token entry");
1538 }
1539 }
1540 } finally {
1541 token.releaseSession(session);
1542 }
1543 }
1544
1545 private void storeCert(String alias, X509Certificate cert)
1546 throws PKCS11Exception, CertificateException {
1547
1548 ArrayList<CK_ATTRIBUTE> attrList = new ArrayList<CK_ATTRIBUTE>();
1549 attrList.add(ATTR_TOKEN_TRUE);
1550 attrList.add(ATTR_CLASS_CERT);
1551 attrList.add(ATTR_X509_CERT_TYPE);
1552 attrList.add(new CK_ATTRIBUTE(CKA_SUBJECT,
1620 } else if (debug != null) {
1621 debug.println("ignoring duplicate CA cert for [" +
1622 chain[i].getSubjectX500Principal() +
1623 "]");
1624 }
1625 }
1626 }
1627
1628 private void storeSkey(String alias, KeyStore.SecretKeyEntry ske)
1629 throws PKCS11Exception, KeyStoreException {
1630
1631 SecretKey skey = ske.getSecretKey();
1632 // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
1633 // they are handled in P11SecretKeyFactory.createKey() method.
1634 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
1635 ATTR_SKEY_TOKEN_TRUE,
1636 ATTR_PRIVATE_TRUE,
1637 new CK_ATTRIBUTE(CKA_LABEL, alias),
1638 };
1639 try {
1640 P11Key k = P11SecretKeyFactory.convertKey(token, skey, null, attrs);
1641 k.makeNativeKeyPersistent();
1642 } catch (InvalidKeyException ike) {
1643 // re-throw KeyStoreException to match javadoc
1644 throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
1645 }
1646
1647 // update global alias map
1648 aliasMap.put(alias, new AliasInfo(alias));
1649
1650 if (debug != null) {
1651 debug.println("storeSkey created token secret key for [" +
1652 alias + "]");
1653 }
1654 }
1655
1656 private static CK_ATTRIBUTE[] addAttribute(CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE attr) {
1657 int n = attrs.length;
1658 CK_ATTRIBUTE[] newAttrs = new CK_ATTRIBUTE[n + 1];
1659 System.arraycopy(attrs, 0, newAttrs, 0, n);
1660 newAttrs[n] = attr;
1661 return newAttrs;
1889 /**
1890 * Compute the CKA_ID and/or CKA_NETSCAPE_DB attributes that should be
1891 * used for this private key. It uses the same algorithm to calculate the
1892 * values as NSS. The public and private keys MUST match for the result to
1893 * be correct.
1894 *
1895 * It returns a 2 element array with CKA_ID at index 0 and CKA_NETSCAPE_DB
1896 * at index 1. The boolean flags determine what is to be calculated.
1897 * If false or if we could not calculate the value, that element is null.
1898 *
1899 * NOTE that we currently do not use the CKA_ID value calculated by this
1900 * method.
1901 */
1902 private CK_ATTRIBUTE[] getIdAttributes(PrivateKey privateKey,
1903 PublicKey publicKey, boolean id, boolean netscapeDb) {
1904 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[2];
1905 if ((id || netscapeDb) == false) {
1906 return attrs;
1907 }
1908 String alg = privateKey.getAlgorithm();
1909 if (alg.equals("RSA") && (publicKey instanceof RSAPublicKey)) {
1910 if (id) {
1911 BigInteger n = ((RSAPublicKey)publicKey).getModulus();
1912 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(n)));
1913 }
1914 // CKA_NETSCAPE_DB not needed for RSA public keys
1915 } else if (alg.equals("DSA") && (publicKey instanceof DSAPublicKey)) {
1916 BigInteger y = ((DSAPublicKey)publicKey).getY();
1917 if (id) {
1918 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
1919 }
1920 if (netscapeDb) {
1921 attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
1922 }
1923 } else if (alg.equals("DH") && (publicKey instanceof DHPublicKey)) {
1924 BigInteger y = ((DHPublicKey)publicKey).getY();
1925 if (id) {
1926 attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
1927 }
1928 if (netscapeDb) {
1929 attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
1930 }
1931 } else if (alg.equals("EC") && (publicKey instanceof ECPublicKey)) {
1932 ECPublicKey ecPub = (ECPublicKey)publicKey;
1933 ECPoint point = ecPub.getW();
1934 ECParameterSpec params = ecPub.getParams();
|