1 /* |
1 /* |
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
39 import java.security.cert.CertificateFactory; |
39 import java.security.cert.CertificateFactory; |
40 import java.security.cert.X509Certificate; |
40 import java.security.cert.X509Certificate; |
41 import java.security.cert.CertificateException; |
41 import java.security.cert.CertificateException; |
42 import java.security.spec.PKCS8EncodedKeySpec; |
42 import java.security.spec.PKCS8EncodedKeySpec; |
43 import java.util.*; |
43 import java.util.*; |
44 import java.math.*; |
|
45 |
44 |
46 import java.security.AlgorithmParameters; |
45 import java.security.AlgorithmParameters; |
47 import java.security.spec.AlgorithmParameterSpec; |
|
48 import javax.crypto.spec.PBEParameterSpec; |
46 import javax.crypto.spec.PBEParameterSpec; |
49 import javax.crypto.spec.PBEKeySpec; |
47 import javax.crypto.spec.PBEKeySpec; |
50 import javax.crypto.spec.SecretKeySpec; |
|
51 import javax.crypto.SecretKeyFactory; |
48 import javax.crypto.SecretKeyFactory; |
52 import javax.crypto.SecretKey; |
49 import javax.crypto.SecretKey; |
53 import javax.crypto.Cipher; |
50 import javax.crypto.Cipher; |
54 import javax.crypto.Mac; |
51 import javax.crypto.Mac; |
55 import javax.security.auth.x500.X500Principal; |
52 import javax.security.auth.x500.X500Principal; |
415 entry.alias = alias.toLowerCase(); |
412 entry.alias = alias.toLowerCase(); |
416 |
413 |
417 // add the entry |
414 // add the entry |
418 entries.put(alias.toLowerCase(), entry); |
415 entries.put(alias.toLowerCase(), entry); |
419 } catch (Exception nsae) { |
416 } catch (Exception nsae) { |
420 KeyStoreException ke = new KeyStoreException("Key protection " + |
417 throw new KeyStoreException("Key protection " + |
421 " algorithm not found: " + nsae); |
418 " algorithm not found: " + nsae, nsae); |
422 ke.initCause(nsae); |
|
423 throw ke; |
|
424 } |
419 } |
425 } |
420 } |
426 |
421 |
427 /** |
422 /** |
428 * Assigns the given key (that has already been protected) to the given |
423 * Assigns the given key (that has already been protected) to the given |
454 // key must be encoded as EncryptedPrivateKeyInfo |
449 // key must be encoded as EncryptedPrivateKeyInfo |
455 // as defined in PKCS#8 |
450 // as defined in PKCS#8 |
456 try { |
451 try { |
457 new EncryptedPrivateKeyInfo(key); |
452 new EncryptedPrivateKeyInfo(key); |
458 } catch (IOException ioe) { |
453 } catch (IOException ioe) { |
459 KeyStoreException ke = new KeyStoreException("Private key is not" |
454 throw new KeyStoreException("Private key is not stored" |
460 + " stored as PKCS#8 EncryptedPrivateKeyInfo: " + ioe); |
455 + " as PKCS#8 EncryptedPrivateKeyInfo: " + ioe, ioe); |
461 ke.initCause(ioe); |
|
462 throw ke; |
|
463 } |
456 } |
464 |
457 |
465 KeyEntry entry = new KeyEntry(); |
458 KeyEntry entry = new KeyEntry(); |
466 entry.date = new Date(); |
459 entry.date = new Date(); |
467 |
460 |
511 new PBEParameterSpec(getSalt(), iterationCount); |
504 new PBEParameterSpec(getSalt(), iterationCount); |
512 try { |
505 try { |
513 algParams = AlgorithmParameters.getInstance(algorithm); |
506 algParams = AlgorithmParameters.getInstance(algorithm); |
514 algParams.init(paramSpec); |
507 algParams.init(paramSpec); |
515 } catch (Exception e) { |
508 } catch (Exception e) { |
516 IOException ioe = |
509 throw new IOException("getAlgorithmParameters failed: " + |
517 new IOException("getAlgorithmParameters failed: " + |
510 e.getMessage(), e); |
518 e.getMessage()); |
|
519 ioe.initCause(e); |
|
520 throw ioe; |
|
521 } |
511 } |
522 return algParams; |
512 return algParams; |
523 } |
513 } |
524 |
514 |
525 /* |
515 /* |
542 if (params != null) { |
532 if (params != null) { |
543 algParams = AlgorithmParameters.getInstance("PBE"); |
533 algParams = AlgorithmParameters.getInstance("PBE"); |
544 algParams.init(params.toByteArray()); |
534 algParams.init(params.toByteArray()); |
545 } |
535 } |
546 } catch (Exception e) { |
536 } catch (Exception e) { |
547 IOException ioe = |
537 throw new IOException("parseAlgParameters failed: " + |
548 new IOException("parseAlgParameters failed: " + |
538 e.getMessage(), e); |
549 e.getMessage()); |
|
550 ioe.initCause(e); |
|
551 throw ioe; |
|
552 } |
539 } |
553 return algParams; |
540 return algParams; |
554 } |
541 } |
555 |
542 |
556 /* |
543 /* |
563 try { |
550 try { |
564 PBEKeySpec keySpec = new PBEKeySpec(password); |
551 PBEKeySpec keySpec = new PBEKeySpec(password); |
565 SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); |
552 SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); |
566 skey = skFac.generateSecret(keySpec); |
553 skey = skFac.generateSecret(keySpec); |
567 } catch (Exception e) { |
554 } catch (Exception e) { |
568 IOException ioe = new IOException("getSecretKey failed: " + |
555 throw new IOException("getSecretKey failed: " + |
569 e.getMessage()); |
556 e.getMessage(), e); |
570 ioe.initCause(e); |
|
571 throw ioe; |
|
572 } |
557 } |
573 return skey; |
558 return skey; |
574 } |
559 } |
575 |
560 |
576 /* |
561 /* |
864 iterationCount); |
847 iterationCount); |
865 DerOutputStream bytes = new DerOutputStream(); |
848 DerOutputStream bytes = new DerOutputStream(); |
866 bytes.write(macData.getEncoded()); |
849 bytes.write(macData.getEncoded()); |
867 mData = bytes.toByteArray(); |
850 mData = bytes.toByteArray(); |
868 } catch (Exception e) { |
851 } catch (Exception e) { |
869 IOException ioe = new IOException("calculateMac failed: " + e); |
852 throw new IOException("calculateMac failed: " + e, e); |
870 ioe.initCause(e); |
|
871 throw ioe; |
|
872 } |
853 } |
873 return mData; |
854 return mData; |
874 } |
855 } |
875 |
856 |
876 |
857 |
1147 Cipher cipher = Cipher.getInstance("PBEWithSHA1AndRC2_40"); |
1128 Cipher cipher = Cipher.getInstance("PBEWithSHA1AndRC2_40"); |
1148 cipher.init(Cipher.ENCRYPT_MODE, skey, algParams); |
1129 cipher.init(Cipher.ENCRYPT_MODE, skey, algParams); |
1149 encryptedData = cipher.doFinal(data); |
1130 encryptedData = cipher.doFinal(data); |
1150 |
1131 |
1151 } catch (Exception e) { |
1132 } catch (Exception e) { |
1152 IOException ioe = new IOException("Failed to encrypt" + |
1133 throw new IOException("Failed to encrypt" + |
1153 " safe contents entry: " + e); |
1134 " safe contents entry: " + e, e); |
1154 ioe.initCause(e); |
|
1155 throw ioe; |
|
1156 } |
1135 } |
1157 |
1136 |
1158 // create EncryptedContentInfo |
1137 // create EncryptedContentInfo |
1159 DerOutputStream bytes2 = new DerOutputStream(); |
1138 DerOutputStream bytes2 = new DerOutputStream(); |
1160 bytes2.putOID(ContentInfo.DATA_OID); |
1139 bytes2.putOID(ContentInfo.DATA_OID); |
1218 */ |
1197 */ |
1219 byte[] authSafeData; |
1198 byte[] authSafeData; |
1220 ContentInfo authSafe = new ContentInfo(s); |
1199 ContentInfo authSafe = new ContentInfo(s); |
1221 ObjectIdentifier contentType = authSafe.getContentType(); |
1200 ObjectIdentifier contentType = authSafe.getContentType(); |
1222 |
1201 |
1223 if (contentType.equals(ContentInfo.DATA_OID)) { |
1202 if (contentType.equals((Object)ContentInfo.DATA_OID)) { |
1224 authSafeData = authSafe.getData(); |
1203 authSafeData = authSafe.getData(); |
1225 } else /* signed data */ { |
1204 } else /* signed data */ { |
1226 throw new IOException("public key protected PKCS12 not supported"); |
1205 throw new IOException("public key protected PKCS12 not supported"); |
1227 } |
1206 } |
1228 |
1207 |
1244 |
1223 |
1245 sci = new DerInputStream(safeContentsArray[i].toByteArray()); |
1224 sci = new DerInputStream(safeContentsArray[i].toByteArray()); |
1246 safeContents = new ContentInfo(sci); |
1225 safeContents = new ContentInfo(sci); |
1247 contentType = safeContents.getContentType(); |
1226 contentType = safeContents.getContentType(); |
1248 safeContentsData = null; |
1227 safeContentsData = null; |
1249 if (contentType.equals(ContentInfo.DATA_OID)) { |
1228 if (contentType.equals((Object)ContentInfo.DATA_OID)) { |
1250 safeContentsData = safeContents.getData(); |
1229 safeContentsData = safeContents.getData(); |
1251 } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { |
1230 } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { |
1252 if (password == null) { |
1231 if (password == null) { |
1253 continue; |
1232 continue; |
1254 } |
1233 } |
1278 Cipher cipher = Cipher.getInstance(algOid.toString()); |
1257 Cipher cipher = Cipher.getInstance(algOid.toString()); |
1279 cipher.init(Cipher.DECRYPT_MODE, skey, algParams); |
1258 cipher.init(Cipher.DECRYPT_MODE, skey, algParams); |
1280 safeContentsData = cipher.doFinal(safeContentsData); |
1259 safeContentsData = cipher.doFinal(safeContentsData); |
1281 |
1260 |
1282 } catch (Exception e) { |
1261 } catch (Exception e) { |
1283 IOException ioe = new IOException("failed to decrypt safe" |
1262 throw new IOException("failed to decrypt safe" |
1284 + " contents entry: " + e); |
1263 + " contents entry: " + e, e); |
1285 ioe.initCause(e); |
|
1286 throw ioe; |
|
1287 } |
1264 } |
1288 } else { |
1265 } else { |
1289 throw new IOException("public key protected PKCS12" + |
1266 throw new IOException("public key protected PKCS12" + |
1290 " not supported"); |
1267 " not supported"); |
1291 } |
1268 } |
1317 if (!Arrays.equals(macData.getDigest(), macResult)) { |
1294 if (!Arrays.equals(macData.getDigest(), macResult)) { |
1318 throw new SecurityException("Failed PKCS12" + |
1295 throw new SecurityException("Failed PKCS12" + |
1319 " integrity checking"); |
1296 " integrity checking"); |
1320 } |
1297 } |
1321 } catch (Exception e) { |
1298 } catch (Exception e) { |
1322 IOException ioe = |
1299 throw new IOException("Integrity check failed: " + e, e); |
1323 new IOException("Integrity check failed: " + e); |
|
1324 ioe.initCause(e); |
|
1325 throw ioe; |
|
1326 } |
1300 } |
1327 } |
1301 } |
1328 |
1302 |
1329 /* |
1303 /* |
1330 * Match up private keys with certificate chains. |
1304 * Match up private keys with certificate chains. |
1400 if (!bagValue.isContextSpecific((byte)0)) { |
1374 if (!bagValue.isContextSpecific((byte)0)) { |
1401 throw new IOException("unsupported PKCS12 bag value type " |
1375 throw new IOException("unsupported PKCS12 bag value type " |
1402 + bagValue.tag); |
1376 + bagValue.tag); |
1403 } |
1377 } |
1404 bagValue = bagValue.data.getDerValue(); |
1378 bagValue = bagValue.data.getDerValue(); |
1405 if (bagId.equals(PKCS8ShroudedKeyBag_OID)) { |
1379 if (bagId.equals((Object)PKCS8ShroudedKeyBag_OID)) { |
1406 KeyEntry kEntry = new KeyEntry(); |
1380 KeyEntry kEntry = new KeyEntry(); |
1407 kEntry.protectedPrivKey = bagValue.toByteArray(); |
1381 kEntry.protectedPrivKey = bagValue.toByteArray(); |
1408 bagItem = kEntry; |
1382 bagItem = kEntry; |
1409 privateKeyCount++; |
1383 privateKeyCount++; |
1410 } else if (bagId.equals(CertBag_OID)) { |
1384 } else if (bagId.equals((Object)CertBag_OID)) { |
1411 DerInputStream cs = new DerInputStream(bagValue.toByteArray()); |
1385 DerInputStream cs = new DerInputStream(bagValue.toByteArray()); |
1412 DerValue[] certValues = cs.getSequence(2); |
1386 DerValue[] certValues = cs.getSequence(2); |
1413 ObjectIdentifier certId = certValues[0].getOID(); |
1387 ObjectIdentifier certId = certValues[0].getOID(); |
1414 if (!certValues[1].isContextSpecific((byte)0)) { |
1388 if (!certValues[1].isContextSpecific((byte)0)) { |
1415 throw new IOException("unsupported PKCS12 cert value type " |
1389 throw new IOException("unsupported PKCS12 cert value type " |
1451 valSet = vs.getSet(1); |
1425 valSet = vs.getSet(1); |
1452 } catch (IOException e) { |
1426 } catch (IOException e) { |
1453 throw new IOException("Attribute " + attrId + |
1427 throw new IOException("Attribute " + attrId + |
1454 " should have a value " + e.getMessage()); |
1428 " should have a value " + e.getMessage()); |
1455 } |
1429 } |
1456 if (attrId.equals(PKCS9FriendlyName_OID)) { |
1430 if (attrId.equals((Object)PKCS9FriendlyName_OID)) { |
1457 alias = valSet[0].getBMPString(); |
1431 alias = valSet[0].getBMPString(); |
1458 } else if (attrId.equals(PKCS9LocalKeyId_OID)) { |
1432 } else if (attrId.equals((Object)PKCS9LocalKeyId_OID)) { |
1459 keyId = valSet[0].getOctetString(); |
1433 keyId = valSet[0].getOctetString(); |
1460 } else { |
1434 } else { |
1461 // log error message for "unknown attr" |
1435 // log error message for "unknown attr" |
1462 } |
1436 } |
1463 } |
1437 } |