src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java

Print this page




1041     }
1042 
1043     /**
1044      * Returns true if the entry identified by the given alias is a
1045      * <i>trusted certificate entry</i>, and false otherwise.
1046      *
1047      * @return true if the entry identified by the given alias is a
1048      * <i>trusted certificate entry</i>, false otherwise.
1049      */
1050     public boolean engineIsCertificateEntry(String alias) {
1051         Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
1052         if (entry != null && entry instanceof CertEntry &&
1053             ((CertEntry) entry).trustedKeyUsage != null) {
1054             return true;
1055         } else {
1056             return false;
1057         }
1058     }
1059 
1060     /**

































1061      * Returns the (alias) name of the first keystore entry whose certificate
1062      * matches the given certificate.
1063      *
1064      * <p>This method attempts to match the given certificate with each
1065      * keystore entry. If the entry being considered
1066      * is a <i>trusted certificate entry</i>, the given certificate is
1067      * compared to that entry's certificate. If the entry being considered is
1068      * a <i>key entry</i>, the given certificate is compared to the first
1069      * element of that entry's certificate chain (if a chain exists).
1070      *
1071      * @param cert the certificate to match with.
1072      *
1073      * @return the (alias) name of the first entry with matching certificate,
1074      * or null if no such entry exists in this keystore.
1075      */
1076     public String engineGetCertificateAlias(Certificate cert) {
1077         Certificate certElem = null;
1078 
1079         for (Enumeration<String> e = engineAliases(); e.hasMoreElements(); ) {
1080             String alias = e.nextElement();
1081             Entry entry = entries.get(alias);
1082             if (entry instanceof PrivateKeyEntry) {
1083                 if (((PrivateKeyEntry) entry).chain != null) {
1084                     certElem = ((PrivateKeyEntry) entry).chain[0];
1085                 }
1086             } else if (entry instanceof CertEntry &&
1087                     ((CertEntry) entry).trustedKeyUsage != null) {
1088                 certElem = ((CertEntry) entry).cert;
1089             } else {
1090                 continue;
1091             }
1092             if (certElem.equals(cert)) {
1093                 return alias;
1094             }
1095         }
1096         return null;
1097     }
1098 
1099     /**
1100      * Stores this keystore to the given output stream, and protects its
1101      * integrity with the given password.
1102      *
1103      * @param stream the output stream to which this keystore is written.
1104      * @param password the password to generate the keystore integrity check
1105      *
1106      * @exception IOException if there was an I/O problem with data
1107      * @exception NoSuchAlgorithmException if the appropriate data integrity
1108      * algorithm could not be found
1109      * @exception CertificateException if any of the certificates included in
1110      * the keystore data could not be stored
1111      */
1112     public synchronized void engineStore(OutputStream stream, char[] password)


1915          */
1916         for (int i = 0; i < count; i++) {
1917             byte[] safeContentsData;
1918             ContentInfo safeContents;
1919             DerInputStream sci;
1920             byte[] eAlgId = null;
1921 
1922             sci = new DerInputStream(safeContentsArray[i].toByteArray());
1923             safeContents = new ContentInfo(sci);
1924             contentType = safeContents.getContentType();
1925             safeContentsData = null;
1926             if (contentType.equals((Object)ContentInfo.DATA_OID)) {
1927 
1928                 if (debug != null) {
1929                     debug.println("Loading PKCS#7 data content-type");
1930                 }
1931 
1932                 safeContentsData = safeContents.getData();
1933             } else if (contentType.equals((Object)ContentInfo.ENCRYPTED_DATA_OID)) {
1934                 if (password == null) {





1935                    continue;
1936                 }
1937 
1938                 if (debug != null) {
1939                     debug.println("Loading PKCS#7 encryptedData content-type");
1940                 }
1941 
1942                 DerInputStream edi =
1943                                 safeContents.getContent().toDerInputStream();
1944                 int edVersion = edi.getInteger();
1945                 DerValue[] seq = edi.getSequence(2);
1946                 ObjectIdentifier edContentType = seq[0].getOID();
1947                 eAlgId = seq[1].toByteArray();
1948                 if (!seq[2].isContextSpecific((byte)0)) {
1949                    throw new IOException("encrypted content not present!");
1950                 }
1951                 byte newTag = DerValue.tag_OctetString;
1952                 if (seq[2].isConstructed())
1953                    newTag |= 0x20;
1954                 seq[2].resetTag(newTag);


1957                 // parse Algorithm parameters
1958                 DerInputStream in = seq[1].toDerInputStream();
1959                 ObjectIdentifier algOid = in.getOID();
1960                 AlgorithmParameters algParams = parseAlgParameters(algOid, in);
1961 
1962                 while (true) {
1963                     try {
1964                         // Use JCE
1965                         SecretKey skey = getPBEKey(password);
1966                         Cipher cipher = Cipher.getInstance(algOid.toString());
1967                         cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
1968                         safeContentsData = cipher.doFinal(safeContentsData);
1969                         break;
1970                     } catch (Exception e) {
1971                         if (password.length == 0) {
1972                             // Retry using an empty password
1973                             // without a NULL terminator.
1974                             password = new char[1];
1975                             continue;
1976                         }
1977                         throw new IOException(
1978                             "failed to decrypt safe contents entry: " + e, e);

1979                     }
1980                 }
1981             } else {
1982                 throw new IOException("public key protected PKCS12" +
1983                                         " not supported");
1984             }
1985             DerInputStream sc = new DerInputStream(safeContentsData);
1986             loadSafeContents(sc, password);
1987         }
1988 
1989         // The MacData is optional.
1990         if (password != null && s.available() > 0) {
1991            MacData macData = new MacData(s);
1992            try {
1993                 String algName =
1994                         macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
1995 
1996                 // Change SHA-1 to SHA1
1997                 algName = algName.replace("-", "");
1998 




1041     }
1042 
1043     /**
1044      * Returns true if the entry identified by the given alias is a
1045      * <i>trusted certificate entry</i>, and false otherwise.
1046      *
1047      * @return true if the entry identified by the given alias is a
1048      * <i>trusted certificate entry</i>, false otherwise.
1049      */
1050     public boolean engineIsCertificateEntry(String alias) {
1051         Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
1052         if (entry != null && entry instanceof CertEntry &&
1053             ((CertEntry) entry).trustedKeyUsage != null) {
1054             return true;
1055         } else {
1056             return false;
1057         }
1058     }
1059 
1060     /**
1061      * Determines if the keystore {@code Entry} for the specified
1062      * {@code alias} is an instance or subclass of the specified
1063      * {@code entryClass}.
1064      *
1065      * @param alias the alias name
1066      * @param entryClass the entry class
1067      *
1068      * @return true if the keystore {@code Entry} for the specified
1069      *          {@code alias} is an instance or subclass of the
1070      *          specified {@code entryClass}, false otherwise
1071      *
1072      * @since 1.5
1073      */
1074     @Override
1075     public boolean
1076         engineEntryInstanceOf(String alias,
1077                               Class<? extends KeyStore.Entry> entryClass)
1078     {
1079         if (entryClass == KeyStore.TrustedCertificateEntry.class) {
1080             return engineIsCertificateEntry(alias);
1081         }
1082 
1083         Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
1084         if (entryClass == KeyStore.PrivateKeyEntry.class) {
1085             return (entry != null && entry instanceof PrivateKeyEntry);
1086         }
1087         if (entryClass == KeyStore.SecretKeyEntry.class) {
1088             return (entry != null && entry instanceof SecretKeyEntry);
1089         }
1090         return false;
1091     }
1092 
1093     /**
1094      * Returns the (alias) name of the first keystore entry whose certificate
1095      * matches the given certificate.
1096      *
1097      * <p>This method attempts to match the given certificate with each
1098      * keystore entry. If the entry being considered
1099      * is a <i>trusted certificate entry</i>, the given certificate is
1100      * compared to that entry's certificate. If the entry being considered is
1101      * a <i>key entry</i>, the given certificate is compared to the first
1102      * element of that entry's certificate chain (if a chain exists).
1103      *
1104      * @param cert the certificate to match with.
1105      *
1106      * @return the (alias) name of the first entry with matching certificate,
1107      * or null if no such entry exists in this keystore.
1108      */
1109     public String engineGetCertificateAlias(Certificate cert) {
1110         Certificate certElem = null;
1111 
1112         for (Enumeration<String> e = engineAliases(); e.hasMoreElements(); ) {
1113             String alias = e.nextElement();
1114             Entry entry = entries.get(alias);
1115             if (entry instanceof PrivateKeyEntry) {
1116                 if (((PrivateKeyEntry) entry).chain != null) {
1117                     certElem = ((PrivateKeyEntry) entry).chain[0];
1118                 }
1119             } else if (entry instanceof CertEntry &&
1120                     ((CertEntry) entry).trustedKeyUsage != null) {
1121                 certElem = ((CertEntry) entry).cert;
1122             } else {
1123                 continue;
1124             }
1125             if (certElem != null && certElem.equals(cert)) {
1126                 return alias;
1127             }
1128         }
1129         return null;
1130     }
1131 
1132     /**
1133      * Stores this keystore to the given output stream, and protects its
1134      * integrity with the given password.
1135      *
1136      * @param stream the output stream to which this keystore is written.
1137      * @param password the password to generate the keystore integrity check
1138      *
1139      * @exception IOException if there was an I/O problem with data
1140      * @exception NoSuchAlgorithmException if the appropriate data integrity
1141      * algorithm could not be found
1142      * @exception CertificateException if any of the certificates included in
1143      * the keystore data could not be stored
1144      */
1145     public synchronized void engineStore(OutputStream stream, char[] password)


1948          */
1949         for (int i = 0; i < count; i++) {
1950             byte[] safeContentsData;
1951             ContentInfo safeContents;
1952             DerInputStream sci;
1953             byte[] eAlgId = null;
1954 
1955             sci = new DerInputStream(safeContentsArray[i].toByteArray());
1956             safeContents = new ContentInfo(sci);
1957             contentType = safeContents.getContentType();
1958             safeContentsData = null;
1959             if (contentType.equals((Object)ContentInfo.DATA_OID)) {
1960 
1961                 if (debug != null) {
1962                     debug.println("Loading PKCS#7 data content-type");
1963                 }
1964 
1965                 safeContentsData = safeContents.getData();
1966             } else if (contentType.equals((Object)ContentInfo.ENCRYPTED_DATA_OID)) {
1967                 if (password == null) {
1968 
1969                     if (debug != null) {
1970                         debug.println("Warning: skipping PKCS#7 encryptedData" +
1971                             " content-type - no password was supplied");
1972                     }
1973                     continue;
1974                 }
1975 
1976                 if (debug != null) {
1977                     debug.println("Loading PKCS#7 encryptedData content-type");
1978                 }
1979 
1980                 DerInputStream edi =
1981                                 safeContents.getContent().toDerInputStream();
1982                 int edVersion = edi.getInteger();
1983                 DerValue[] seq = edi.getSequence(2);
1984                 ObjectIdentifier edContentType = seq[0].getOID();
1985                 eAlgId = seq[1].toByteArray();
1986                 if (!seq[2].isContextSpecific((byte)0)) {
1987                    throw new IOException("encrypted content not present!");
1988                 }
1989                 byte newTag = DerValue.tag_OctetString;
1990                 if (seq[2].isConstructed())
1991                    newTag |= 0x20;
1992                 seq[2].resetTag(newTag);


1995                 // parse Algorithm parameters
1996                 DerInputStream in = seq[1].toDerInputStream();
1997                 ObjectIdentifier algOid = in.getOID();
1998                 AlgorithmParameters algParams = parseAlgParameters(algOid, in);
1999 
2000                 while (true) {
2001                     try {
2002                         // Use JCE
2003                         SecretKey skey = getPBEKey(password);
2004                         Cipher cipher = Cipher.getInstance(algOid.toString());
2005                         cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
2006                         safeContentsData = cipher.doFinal(safeContentsData);
2007                         break;
2008                     } catch (Exception e) {
2009                         if (password.length == 0) {
2010                             // Retry using an empty password
2011                             // without a NULL terminator.
2012                             password = new char[1];
2013                             continue;
2014                         }
2015                         throw new IOException("keystore password was incorrect",
2016                             new UnrecoverableKeyException(
2017                                 "failed to decrypt safe contents entry: " + e));
2018                     }
2019                 }
2020             } else {
2021                 throw new IOException("public key protected PKCS12" +
2022                                         " not supported");
2023             }
2024             DerInputStream sc = new DerInputStream(safeContentsData);
2025             loadSafeContents(sc, password);
2026         }
2027 
2028         // The MacData is optional.
2029         if (password != null && s.available() > 0) {
2030            MacData macData = new MacData(s);
2031            try {
2032                 String algName =
2033                         macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
2034 
2035                 // Change SHA-1 to SHA1
2036                 algName = algName.replace("-", "");
2037