Fix Version/s: None
Compatibility Risk Description:The cacerts file is still located in the same directory with the same name, and is still loadable with `KeyStore.getInstance("JKS").load(fileStream, null or anything)` just like today. Read more in the compatibility description on the specification.
Interface Kind:File or wire format
Create a new CACERTS
KeyStore type and file format.
JDK stores out-of-box root CA certificates in
lib/security/cacerts and it's using a proprietary keystore format JKS.
- It's not standard.
- It requires a password to check for integrity. This password must be publicized and therefore provides no security protection. On the other hand, including a hardcoded password is not a good security practice.
- People might change the password and this could break existing applications that uses the hardcoded password.
- We've already changed the default keystore type from JKS to PKCS12 in JDK 9 and we are warning people to migrate from JKS in keytool warnings now.
- There are almost 100 certificates in this file and loading it spends quite some time
Hardcode all builtin CA certificates into OpenJDK code, and migrate the cacerts file into an ASCII file that allows users to add their own CA certs or shadow builtin ones. The new keystore type will be named "CACERTS".
Builtin CA certs
All (93) CA certificates that are currently inside the
lib/security/cacerts file are moved into an internal class inside the
java.base module. This class will be generated at build time using the same certificate files in
The CACERTS file format
# CACERTS # DO NOT REMOVE THE LINE ABOVE # # Remove a CA cert by its alias @remove-alias: <a CA alias name> # # Remove all CA certs @remove-all # # Add a new CA cert with @alias: newaliasname -----BEGIN CERTIFICATE----- ..... -----END CERTIFICATE-----
- The first line must be
@remove-aliasdirective can be used to remove a CA cert by its alias. Users can call
keytool -cacerts -listto find out the aliases for all builtin CA certificates.
@remove-alldirective can be used to remove all CA certs.
@aliasdirective following a BASE64 encoded X.509 certificate can be used to add a new CA cert with this alias.
- This file format will be used by the new CACERTS keystore type below.
- When parsing starts, all hardcoded builtin CA certs are loaded (the current list).
- All directives are processed in their appearance order in the file. For example: Users can add
@remove-allas the first directive in a CACERTS file to remove all builtin CA certs and then add their own ones. Or, they can add a
@remove-alias: verisignclass2g2ca [jdk]directive to remove this single builtin CA cert and then (optionally) add their own ones. Please note that if
@remove-allis on the last time, it will empty the whole list including newly added CA certs.
- If a BASE64 encoded X.509 certificate appears without a leading
@aliasdirective, its SHA-256 fingerprint will be used as its alias.
- Unknown directives (other lines starting with
@) will be treated as an error.
- All other lines are ignored (as comments).
- The out-of-box
lib/security/cacertswill be all comment lines except for the first line. All existing (93) cacerts have been hardcoded inside OpenJDK using the same aliases as before.
The CACERTS keystore type
- When using
KeyStore.getInstance(File, password)to load a file starting with the
# CACERTSline, it will be probed as a CACERTS keystore.
- The store password is ignored in
- When calling
KeyStore.load(null, password), the system-default CACERTS keystore at
- The creation time of a certificate inside a CACERTS keystore is not defined but it will not be null.
KeyStore.setKeyEntryon a CACERTS keystore is allowed and the new entry is visible in the keystore object (but see below).
KeyStore.store(OutputStream, password)will write out a CACERTS keystore to the output stream. All key entries are ignored. The password is ignored. Loading a keystore from a CACERTS file and storing it back to the same file will not retain the comments or the order of directives. The output stream cannot be null (i.e. one cannot write into the system-default CACERTS keystore by using a null output stream).
This new keystore type name will be added into the "Java Security Standard Algorithm Names" and the "JDK Providers Documentation" in the Java SE Security Guide.
Compatibility with existing keystore types
- A CACERTS file can be loaded as a JKS or PKCS12 keystore, and the load password is ignored. When
KeyStore.storeis called on such a keystore, a CACERTS file will be written, and key entries will be ignored. This makes sure the current programs that is using "JKS" to load/store the
cacertsfile can work with the new file format.
- One can load a JKS keystore with the CACERTS store type. This makes sure that if a user has replaced the system-default cacerts file with a JKS keystore, it can still be loaded as a CACERTS keystore. When calling
KeyStore.storeon such a keystore, a JKS keystore will be written, if any key entry was added into the
KeyStoreobject it will be stored, the store password will be used.
- The CACERTS
KeyStoretype and the CACERTS file format can be separated. We can forsee in the future that the system-default root CA certs list to be stored in a different way but they can still be loaded with