jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
changeset 10336 0bb1999251f8
parent 5973 b48e1702532e
child 10369 e9d2e59e53f0
equal deleted inserted replaced
10335:3c7eda3ab2f5 10336:0bb1999251f8
     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     /*
   824         try {
   809         try {
   825             MessageDigest md = MessageDigest.getInstance("SHA1");
   810             MessageDigest md = MessageDigest.getInstance("SHA1");
   826             md.update(data);
   811             md.update(data);
   827             digest = md.digest();
   812             digest = md.digest();
   828         } catch (Exception e) {
   813         } catch (Exception e) {
   829             IOException ioe = new IOException("generateHash failed: " + e);
   814             throw new IOException("generateHash failed: " + e, e);
   830             ioe.initCause(e);
       
   831             throw ioe;
       
   832         }
   815         }
   833         return digest;
   816         return digest;
   834     }
   817     }
   835 
   818 
   836 
   819 
   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                 }