jdk/src/java.base/share/classes/java/security/KeyStore.java
changeset 28243 47080f9ae750
parent 27771 360714d431ab
child 28853 29df6c77d2b7
equal deleted inserted replaced
28242:0cbef7c46996 28243:47080f9ae750
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2014, 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
    90  * secret) keys. Smart cards or other integrated cryptographic engines
    90  * secret) keys. Smart cards or other integrated cryptographic engines
    91  * (SafeKeyper) are one option, and simpler mechanisms such as files may also
    91  * (SafeKeyper) are one option, and simpler mechanisms such as files may also
    92  * be used (in a variety of formats).
    92  * be used (in a variety of formats).
    93  *
    93  *
    94  * <p> Typical ways to request a KeyStore object include
    94  * <p> Typical ways to request a KeyStore object include
       
    95  * specifying an existing keystore file,
    95  * relying on the default type and providing a specific keystore type.
    96  * relying on the default type and providing a specific keystore type.
    96  *
    97  *
    97  * <ul>
    98  * <ul>
       
    99  * <li>To specify an existing keystore file:
       
   100  * <pre>
       
   101  *    // get keystore password
       
   102  *    char[] password = getPassword();
       
   103  *
       
   104  *    // probe the keystore file and load the keystore entries
       
   105  *    KeyStore ks = KeyStore.getInstance(new File("keyStoreName"), password);
       
   106  *</pre>
       
   107  * The system will probe the specified file to determine its keystore type
       
   108  * and return a keystore implementation with its entries already loaded.
       
   109  * When this approach is used there is no need to call the keystore's
       
   110  * {@link #load(java.io.InputStream, char[]) load} method.
       
   111  *
    98  * <li>To rely on the default type:
   112  * <li>To rely on the default type:
    99  * <pre>
   113  * <pre>
   100  *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   114  *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   101  * </pre>
   115  * </pre>
   102  * The system will return a keystore implementation for the default type.
   116  * The system will return a keystore implementation for the default type.
   108  * The system will return the most preferred implementation of the
   122  * The system will return the most preferred implementation of the
   109  * specified keystore type available in the environment. <p>
   123  * specified keystore type available in the environment. <p>
   110  * </ul>
   124  * </ul>
   111  *
   125  *
   112  * <p> Before a keystore can be accessed, it must be
   126  * <p> Before a keystore can be accessed, it must be
   113  * {@link #load(java.io.InputStream, char[]) loaded}.
   127  * {@link #load(java.io.InputStream, char[]) loaded}
       
   128  * (unless it was already loaded during instantiation).
   114  * <pre>
   129  * <pre>
   115  *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   130  *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   116  *
   131  *
   117  *    // get user password and file input stream
   132  *    // get user password and file input stream
   118  *    char[] password = getPassword();
   133  *    char[] password = getPassword();
   177  * @since 1.2
   192  * @since 1.2
   178  */
   193  */
   179 
   194 
   180 public class KeyStore {
   195 public class KeyStore {
   181 
   196 
       
   197     private static final Debug kdebug = Debug.getInstance("keystore");
   182     private static final Debug pdebug =
   198     private static final Debug pdebug =
   183                         Debug.getInstance("provider", "Provider");
   199                         Debug.getInstance("provider", "Provider");
   184     private static final boolean skipDebug =
   200     private static final boolean skipDebug =
   185         Debug.isOn("engine=") && !Debug.isOn("keystore");
   201         Debug.isOn("engine=") && !Debug.isOn("keystore");
   186 
   202 
  1592         }
  1608         }
  1593         return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
  1609         return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
  1594     }
  1610     }
  1595 
  1611 
  1596     /**
  1612     /**
       
  1613      * Returns a loaded keystore object of the appropriate keystore type.
       
  1614      * First the keystore type is determined by probing the specified file.
       
  1615      * Then a keystore object is instantiated and loaded using the data from
       
  1616      * that file.
       
  1617      * A password may be supplied to unlock the keystore data or perform an
       
  1618      * integrity check.
       
  1619      *
       
  1620      * <p>
       
  1621      * This method traverses the list of registered security {@link Providers},
       
  1622      * starting with the most preferred Provider.
       
  1623      * For each {@link KeyStoreSpi} implementation supported by a Provider,
       
  1624      * it invokes the {@link engineProbe} method to determine if it supports
       
  1625      * the specified keystore.
       
  1626      * A new KeyStore object is returned that encapsulates the KeyStoreSpi
       
  1627      * implementation from the first Provider that supports the specified file.
       
  1628      *
       
  1629      * <p> Note that the list of registered providers may be retrieved via
       
  1630      * the {@link Security#getProviders() Security.getProviders()} method.
       
  1631      *
       
  1632      * @param  file the keystore file
       
  1633      * @param  password the keystore password, which may be {@code null}
       
  1634      *
       
  1635      * @return a keystore object loaded with keystore data
       
  1636      *
       
  1637      * @throws KeyStoreException if no Provider supports a KeyStoreSpi
       
  1638      *             implementation for the specified keystore file.
       
  1639      * @throws IOException if there is an I/O or format problem with the
       
  1640      *             keystore data, if a password is required but not given,
       
  1641      *             or if the given password was incorrect. If the error is
       
  1642      *             due to a wrong password, the {@link Throwable#getCause cause}
       
  1643      *             of the {@code IOException} should be an
       
  1644      *             {@code UnrecoverableKeyException}.
       
  1645      * @throws NoSuchAlgorithmException if the algorithm used to check the
       
  1646      *             integrity of the keystore cannot be found.
       
  1647      * @throws CertificateException if any of the certificates in the
       
  1648      *             keystore could not be loaded.
       
  1649      * @throws IllegalArgumentException if file does not exist or does not
       
  1650      *             refer to a normal file.
       
  1651      * @throws NullPointerException if file is {@code null}.
       
  1652      * @throws SecurityException if a security manager exists and its
       
  1653      *             {@link java.lang.SecurityManager#checkRead} method denies
       
  1654      *             read access to the specified file.
       
  1655      *
       
  1656      * @see Provider
       
  1657      *
       
  1658      * @since 1.9
       
  1659      */
       
  1660     public static final KeyStore getInstance(File file, char[] password)
       
  1661         throws KeyStoreException, IOException, NoSuchAlgorithmException,
       
  1662             CertificateException {
       
  1663         return getInstance(file, password, null, true);
       
  1664     }
       
  1665 
       
  1666     /**
       
  1667      * Returns a loaded keystore object of the appropriate keystore type.
       
  1668      * First the keystore type is determined by probing the specified file.
       
  1669      * Then a keystore object is instantiated and loaded using the data from
       
  1670      * that file.
       
  1671      * A {@code LoadStoreParameter} may be supplied which specifies how to
       
  1672      * unlock the keystore data or perform an integrity check.
       
  1673      *
       
  1674      * <p>
       
  1675      * This method traverses the list of registered security {@link Providers},
       
  1676      * starting with the most preferred Provider.
       
  1677      * For each {@link KeyStoreSpi} implementation supported by a Provider,
       
  1678      * it invokes the {@link engineProbe} method to determine if it supports
       
  1679      * the specified keystore.
       
  1680      * A new KeyStore object is returned that encapsulates the KeyStoreSpi
       
  1681      * implementation from the first Provider that supports the specified file.
       
  1682      *
       
  1683      * <p> Note that the list of registered providers may be retrieved via
       
  1684      * the {@link Security#getProviders() Security.getProviders()} method.
       
  1685      *
       
  1686      * @param  file the keystore file
       
  1687      * @param  param the {@code LoadStoreParameter} that specifies how to load
       
  1688      *             the keystore, which may be {@code null}
       
  1689      *
       
  1690      * @return a keystore object loaded with keystore data
       
  1691      *
       
  1692      * @throws KeyStoreException if no Provider supports a KeyStoreSpi
       
  1693      *             implementation for the specified keystore file.
       
  1694      * @throws IOException if there is an I/O or format problem with the
       
  1695      *             keystore data. If the error is due to an incorrect
       
  1696      *             {@code ProtectionParameter} (e.g. wrong password)
       
  1697      *             the {@link Throwable#getCause cause} of the
       
  1698      *             {@code IOException} should be an
       
  1699      *             {@code UnrecoverableKeyException}.
       
  1700      * @throws NoSuchAlgorithmException if the algorithm used to check the
       
  1701      *             integrity of the keystore cannot be found.
       
  1702      * @throws CertificateException if any of the certificates in the
       
  1703      *             keystore could not be loaded.
       
  1704      * @throws IllegalArgumentException if file does not exist or does not
       
  1705      *             refer to a normal file, or if param is not recognized.
       
  1706      * @throws NullPointerException if file is {@code null}.
       
  1707      * @throws SecurityException if a security manager exists and its
       
  1708      *             {@link java.lang.SecurityManager#checkRead} method denies
       
  1709      *             read access to the specified file.
       
  1710      *
       
  1711      * @see Provider
       
  1712      *
       
  1713      * @since 1.9
       
  1714      */
       
  1715     public static final KeyStore getInstance(File file,
       
  1716         LoadStoreParameter param) throws KeyStoreException, IOException,
       
  1717             NoSuchAlgorithmException, CertificateException {
       
  1718         return getInstance(file, null, param, false);
       
  1719     }
       
  1720 
       
  1721     // Used by getInstance(File, char[]) & getInstance(File, LoadStoreParameter)
       
  1722     private static final KeyStore getInstance(File file, char[] password,
       
  1723         LoadStoreParameter param, boolean hasPassword)
       
  1724             throws KeyStoreException, IOException, NoSuchAlgorithmException,
       
  1725                 CertificateException {
       
  1726 
       
  1727         if (file == null) {
       
  1728             throw new NullPointerException();
       
  1729         }
       
  1730 
       
  1731         if (file.isFile() == false) {
       
  1732             throw new IllegalArgumentException(
       
  1733                 "File does not exist or it does not refer to a normal file: " +
       
  1734                     file);
       
  1735         }
       
  1736 
       
  1737         KeyStore keystore = null;
       
  1738 
       
  1739         try (DataInputStream dataStream =
       
  1740             new DataInputStream(
       
  1741                 new BufferedInputStream(
       
  1742                     new FileInputStream(file)))) {
       
  1743 
       
  1744             dataStream.mark(Integer.MAX_VALUE);
       
  1745 
       
  1746             // Detect the keystore type
       
  1747             for (String type : Security.getAlgorithms("KeyStore")) {
       
  1748                 Object[] objs = null;
       
  1749 
       
  1750                 try {
       
  1751                     objs = Security.getImpl(type, "KeyStore", (String)null);
       
  1752 
       
  1753                     KeyStoreSpi impl = (KeyStoreSpi)objs[0];
       
  1754                     if (impl.engineProbe(dataStream)) {
       
  1755 
       
  1756                         if (kdebug != null) {
       
  1757                             kdebug.println(type + " keystore detected: " +
       
  1758                                 file);
       
  1759                         }
       
  1760 
       
  1761                         keystore = new KeyStore(impl, (Provider)objs[1], type);
       
  1762                         break;
       
  1763                     }
       
  1764                 } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
       
  1765                     // ignore
       
  1766                     if (kdebug != null) {
       
  1767                         kdebug.println(type + " not found - " + e);
       
  1768                     }
       
  1769                 } catch (IOException e) {
       
  1770                     // ignore
       
  1771                     if (kdebug != null) {
       
  1772                         kdebug.println("I/O error in " + file + " - " + e);
       
  1773                     }
       
  1774                 }
       
  1775                 dataStream.reset(); // prepare the stream for the next probe
       
  1776             }
       
  1777 
       
  1778             // Load the keystore data
       
  1779             if (keystore != null) {
       
  1780                 if (hasPassword) {
       
  1781                     dataStream.reset(); // prepare the stream for loading
       
  1782                     keystore.load(dataStream, password);
       
  1783                 } else {
       
  1784                     keystore.load(param);
       
  1785                 }
       
  1786                 return keystore;
       
  1787             }
       
  1788         }
       
  1789 
       
  1790         throw new KeyStoreException("Unrecognized keystore format: " +
       
  1791             keystore);
       
  1792     }
       
  1793 
       
  1794     /**
  1597      * A description of a to-be-instantiated KeyStore object.
  1795      * A description of a to-be-instantiated KeyStore object.
  1598      *
  1796      *
  1599      * <p>An instance of this class encapsulates the information needed to
  1797      * <p>An instance of this class encapsulates the information needed to
  1600      * instantiate and initialize a KeyStore object. That process is
  1798      * instantiate and initialize a KeyStore object. That process is
  1601      * triggered when the {@linkplain #getKeyStore} method is called.
  1799      * triggered when the {@linkplain #getKeyStore} method is called.
  1711          * Otherwise, if {@code protection} is a
  1909          * Otherwise, if {@code protection} is a
  1712          * {@code CallbackHandlerProtection}, the password is obtained
  1910          * {@code CallbackHandlerProtection}, the password is obtained
  1713          * by invoking the CallbackHandler.
  1911          * by invoking the CallbackHandler.
  1714          *
  1912          *
  1715          * <p>Subsequent calls to {@link #getKeyStore} return the same object
  1913          * <p>Subsequent calls to {@link #getKeyStore} return the same object
  1716          * as the initial call. If the initial call to failed with a
  1914          * as the initial call. If the initial call failed with a
  1717          * KeyStoreException, subsequent calls also throw a
  1915          * KeyStoreException, subsequent calls also throw a
  1718          * KeyStoreException.
  1916          * KeyStoreException.
  1719          *
  1917          *
  1720          * <p>The KeyStore is instantiated from {@code provider} if
  1918          * <p>The KeyStore is instantiated from {@code provider} if
  1721          * non-null. Otherwise, all installed providers are searched.
  1919          * non-null. Otherwise, all installed providers are searched.
  1756                     ("File does not exist or it does not refer " +
  1954                     ("File does not exist or it does not refer " +
  1757                      "to a normal file: " + file);
  1955                      "to a normal file: " + file);
  1758             }
  1956             }
  1759             return new FileBuilder(type, provider, file, protection,
  1957             return new FileBuilder(type, provider, file, protection,
  1760                 AccessController.getContext());
  1958                 AccessController.getContext());
       
  1959         }
       
  1960 
       
  1961         /**
       
  1962          * Returns a new Builder object.
       
  1963          *
       
  1964          * <p>The first call to the {@link #getKeyStore} method on the returned
       
  1965          * builder will create a KeyStore using {@code file} to detect the
       
  1966          * keystore type and then call its {@link KeyStore#load load()} method.
       
  1967          * It uses the same algorithm to determine the keystore type as
       
  1968          * described in {@link KeyStore#getInstance(File, LoadStoreParameter)}.
       
  1969          * The {@code inputStream} argument is constructed from {@code file}.
       
  1970          * If {@code protection} is a {@code PasswordProtection}, the password
       
  1971          * is obtained by calling the {@code getPassword} method.
       
  1972          * Otherwise, if {@code protection} is a
       
  1973          * {@code CallbackHandlerProtection},
       
  1974          * the password is obtained by invoking the CallbackHandler.
       
  1975          *
       
  1976          * <p>Subsequent calls to {@link #getKeyStore} return the same object
       
  1977          * as the initial call. If the initial call failed with a
       
  1978          * KeyStoreException, subsequent calls also throw a KeyStoreException.
       
  1979          *
       
  1980          * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
       
  1981          * will return a {@link KeyStore.PasswordProtection PasswordProtection}
       
  1982          * object encapsulating the password that was used to invoke the
       
  1983          * {@code load} method.
       
  1984          *
       
  1985          * <p><em>Note</em> that the {@link #getKeyStore} method is executed
       
  1986          * within the {@link AccessControlContext} of the code invoking this
       
  1987          * method.
       
  1988          *
       
  1989          * @return a new Builder object
       
  1990          * @param file the File that contains the KeyStore data
       
  1991          * @param protection the ProtectionParameter securing the KeyStore data
       
  1992          * @throws NullPointerException if file or protection is null
       
  1993          * @throws IllegalArgumentException if protection is not an instance
       
  1994          *   of either PasswordProtection or CallbackHandlerProtection; or
       
  1995          *   if file does not exist or does not refer to a normal file
       
  1996          *
       
  1997          * @since 1.9
       
  1998          */
       
  1999         public static Builder newInstance(File file,
       
  2000             ProtectionParameter protection) {
       
  2001 
       
  2002             return newInstance("", null, file, protection);
  1761         }
  2003         }
  1762 
  2004 
  1763         private static final class FileBuilder extends Builder {
  2005         private static final class FileBuilder extends Builder {
  1764 
  2006 
  1765             private final String type;
  2007             private final String type;
  1815                             }
  2057                             }
  1816                         }
  2058                         }
  1817                     }
  2059                     }
  1818                     public KeyStore run0() throws Exception {
  2060                     public KeyStore run0() throws Exception {
  1819                         KeyStore ks;
  2061                         KeyStore ks;
  1820                         if (provider == null) {
  2062                         char[] password = null;
  1821                             ks = KeyStore.getInstance(type);
  2063 
       
  2064                         // Acquire keystore password
       
  2065                         if (protection instanceof PasswordProtection) {
       
  2066                             password =
       
  2067                                 ((PasswordProtection)protection).getPassword();
       
  2068                             keyProtection = protection;
  1822                         } else {
  2069                         } else {
  1823                             ks = KeyStore.getInstance(type, provider);
  2070                             CallbackHandler handler =
       
  2071                                 ((CallbackHandlerProtection)protection)
       
  2072                                     .getCallbackHandler();
       
  2073                             PasswordCallback callback = new PasswordCallback
       
  2074                                 ("Password for keystore " + file.getName(),
       
  2075                                     false);
       
  2076                             handler.handle(new Callback[] {callback});
       
  2077                             password = callback.getPassword();
       
  2078                             if (password == null) {
       
  2079                                 throw new KeyStoreException("No password" +
       
  2080                                                             " provided");
       
  2081                             }
       
  2082                             callback.clearPassword();
       
  2083                             keyProtection = new PasswordProtection(password);
  1824                         }
  2084                         }
  1825                         InputStream in = null;
  2085 
  1826                         char[] password = null;
  2086                         if (type.isEmpty()) {
  1827                         try {
  2087                             // Instantiate keystore and load keystore data
  1828                             in = new FileInputStream(file);
  2088                             ks = KeyStore.getInstance(file, password);
  1829                             if (protection instanceof PasswordProtection) {
  2089                         } else {
  1830                                 password =
  2090                             // Instantiate keystore
  1831                                 ((PasswordProtection)protection).getPassword();
  2091                             if (provider == null) {
  1832                                 keyProtection = protection;
  2092                                 ks = KeyStore.getInstance(type);
  1833                             } else {
  2093                             } else {
  1834                                 CallbackHandler handler =
  2094                                 ks = KeyStore.getInstance(type, provider);
  1835                                     ((CallbackHandlerProtection)protection)
       
  1836                                     .getCallbackHandler();
       
  1837                                 PasswordCallback callback = new PasswordCallback
       
  1838                                     ("Password for keystore " + file.getName(),
       
  1839                                     false);
       
  1840                                 handler.handle(new Callback[] {callback});
       
  1841                                 password = callback.getPassword();
       
  1842                                 if (password == null) {
       
  1843                                     throw new KeyStoreException("No password" +
       
  1844                                                                 " provided");
       
  1845                                 }
       
  1846                                 callback.clearPassword();
       
  1847                                 keyProtection = new PasswordProtection(password);
       
  1848                             }
  2095                             }
  1849                             ks.load(in, password);
  2096                             // Load keystore data
  1850                             return ks;
  2097                             try (InputStream in = new FileInputStream(file)) {
  1851                         } finally {
  2098                                 ks.load(in, password);
  1852                             if (in != null) {
       
  1853                                 in.close();
       
  1854                             }
  2099                             }
  1855                         }
  2100                         }
       
  2101                         return ks;
  1856                     }
  2102                     }
  1857                 };
  2103                 };
  1858                 try {
  2104                 try {
  1859                     keyStore = AccessController.doPrivileged(action, context);
  2105                     keyStore = AccessController.doPrivileged(action, context);
  1860                     return keyStore;
  2106                     return keyStore;
  1996 
  2242 
  1997         public ProtectionParameter getProtectionParameter() {
  2243         public ProtectionParameter getProtectionParameter() {
  1998             return protection;
  2244             return protection;
  1999         }
  2245         }
  2000     }
  2246     }
  2001 
       
  2002 }
  2247 }