ca-certificates-java: convert PKCS12 cacerts keystore to JKS

Bug #1771363 reported by Tiago Stürmer Daitx on 2018-05-15
22
This bug affects 4 people
Affects Status Importance Assigned to Milestone
ca-certificates-java (Debian)
Fix Released
Unknown
ca-certificates-java (Ubuntu)
High
Unassigned
Bionic
High
Unassigned

Bug Description

[Impact]
Any user already affected by the issue described in bug 1739631 won't benefit from the fix as that fix only prevents the issue from happening in new installs.

[Cause]
Same as described in bug 1739631 and copied here.

The ca-certificate-java version 20170930 (or earlier) used the default keystore to create /etc/ssl/certs/java/cacerts - if the file already existed its contents were just updated without changing the keystore
type.

From openjdk-9 upwards the default keystore type changed from 'jks' to 'pkcs12' [1] by means of JEP 229 [2]. A JKS keystore can be read without supplying a password (or by supplying an empty one) while a PKCS12 keystore requires a password to be set.

Thus a /etc/ssl/certs/java/cacerts created in the pkcs12 format will fail to be loaded as, by default, the truststore password is empty - in order to avoid that the user must set -Djavax.net.ssl.trustStorePassword=<passwd> or define it in /etc/java-XX-openjdk/management/management.properties. A JKS keystore will work normally, as the certificates in it can be ready when the truststore password is empty.

Ubuntu does *not* set the javax.net.ssl.trustStorePassword by default
thus any user that got a cacerts generated in JKCS12 won't be able
to use any secure connections from java.

[Test Case]
Start on a new bionic install/chroot without openjdk

1. Install openjdk-11
$ sudo apt-get install openjdk-11-jdk

2. Test the keystore with an empty password (optional) and make sure it is a PKCS12
$ keytool -list -cacerts
Enter keystore password: <leave empty>
***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password. *
***************** WARNING WARNING WARNING *****************
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 0 entries

3. Test with the "changeit" password
$ keytool -list -cacerts
Enter keystore password: changeit
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 133 entries
<snipped various certs>

4. Create the java test file
$ cat <<EOF >HttpsTester.java
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class HttpsTester {
public static void main(String[] args) throws java.io.IOException {
HttpsURLConnection connection = (HttpsURLConnection) new URL("https://www.ubuntu.com").openConnection();
System.out.println("Response code: " + connection.getResponseCode());
System.out.println("It worked!");
}
}
EOF

5. Compile it
$ javac HttpsTester.java

6. Call it
$ /usr/lib/jvm/java-11-openjdk-amd64/bin/java HttpsTester

7. Call it again, this time set the store password
$ /usr/lib/jvm/java-11-openjdk-amd64/bin/java \
  -Djavax.net.ssl.trustStorePassword=changeit HttpsTester
Response code: 200
It worked!

8. Install the newer ca-certificates-java 20180516, it should
migrate cacerts from PKCS12 to JKS. Check that by running step #2
again
$ keytool -list -cacerts
Enter keystore password: <leave empty>
***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password. *
***************** WARNING WARNING WARNING *****************
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 133 entries
<snipped various certs>

9. The old keystore should be saved in
/etc/ssl/certs/java/cacerts.dpkg-old, test it exists:
$ keytool -list -keystore /etc/ssl/certs/java/cacerts.dpkg-old
Enter keystore password: <leave empty>
***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password. *
***************** WARNING WARNING WARNING *****************
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 0 entries

[Regression Potential]
* If a user has manually set his own JKCS12 cacerts and didn't update
/etc/default/cacerts to set "cacerts_updates=no" (from the default
of "cacerts_updates=yes") then his custom cacerts will be converted and overwritten. Still, a copy from the previous cacert is kept at
/etc/ssl/certs/java/cacerts.dpkg-old.

[Other Info]
The cacerts keystore fix is related to 2 bugs:
1) bug #1739631, fixed by ca-certificates-java-20180413, which changed the default keystore type generated by ca-certificates-java to JKS

[References]
[1] The default keystore is defined by the keystore.type in the
/etc/java-XX-openjdk/security/java.security file.
http://hg.openjdk.java.net/jdk-updates/jdk9u/jdk/annotate/46bd35a597eb/src/java.base/share/conf/security/java.security#l186

[2] JEP 229: Create PKCS12 Keystores by Default
http://openjdk.java.net/jeps/229

[Original bug description]
The fix for Debian #894979 and Ubuntu bug #1739631 which updated ca-certificates-java to generate
JKS keystores by default - instead OpenJDK's 9+ default of PKCS12 - only fixes new installs.

Any user already affected by that issue won't benefit from the fix, as the file /etc/ssl/certs/java/cacerts is at most updated by the jks-keystore hook. The only way to actually change it from the PKCS12 to the JKS format is to remove the cacerts file and then calling
'update-ca-certificates -f' - which is also accomplished by removing and then reinstalling the ca-certificates-java package.

Tiago Stürmer Daitx (tdaitx) wrote :

The attached patch fixes this behavior by:
1) Detecting if a PKCS12 cacert exists
2) Converting it to JKS and saving it to cacerts.dpkg-new

Finally, if, and only if, 'cacerts_updates' is set to 'yes':
3) Moving the old PKCS12 cacerts to a cacerts.dpkg-old and the dpkg-new into /etc/ssl/certs/java/cacerts.

Additionally, this the proposed debdiff also takes care of only setting JAVA_HOME if a jvm is found. Previously if none of the the jvms in the list were found the last one jvm was used - although that didn't cause any unexpected errors, it was wrong.

tags: added: bionic cosmic patch
Changed in ca-certificates-java (Debian):
status: Unknown → New
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in ca-certificates-java (Ubuntu):
status: New → Confirmed
Changed in ca-certificates-java (Ubuntu):
importance: Undecided → High
Changed in ca-certificates-java (Ubuntu Bionic):
importance: Undecided → High
status: New → Triaged
Changed in ca-certificates-java (Ubuntu):
status: Confirmed → Triaged
Changed in ca-certificates-java (Ubuntu):
status: Triaged → In Progress
status: In Progress → Fix Committed
Changed in ca-certificates-java (Debian):
status: New → Fix Released
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package ca-certificates-java - 20180516ubuntu1

---------------
ca-certificates-java (20180516ubuntu1) cosmic; urgency=low

  * Merge from Debian unstable (LP: #1771815). Remaining changes:
    - debian/control: Bump javahelper build dependency.
    - debian/rules:
      + Explicitly depend on openjdk-11-jre-headless, needed to configure.
      + Replace javac arguments '-source 1.7 -target 1.7' with '--release 7'
        as, per JEP-247, it also takes care of setting the right -bootclasspath
        argument.

ca-certificates-java (20180516) unstable; urgency=medium

  * Team upload.

  [ Tiago Stürmer Daitx ]
  * debian/jks-keystore.hook.in: don't create a jvm-*.cfg file, a default file
    with the right configuration is already supplied by the openjdk packages.
  * debian/jks-keystore.hook.in, debian/postinst.in: Only export JAVA_HOME
    and update PATH if a known jvm was found.
  * debian/postinst.in: Detect PKCS12 cacert keystore generated by
    previous ca-certificates-java and convert them to JKS. (Closes: #898678)
    (LP: #1771363)

  [ Matthias Klose ]
  * debian/rules: Explicitly depend on openjdk-11-jre-headless, needed to
    configure.

  [ Emmanuel Bourg ]
  * Use salsa.debian.org Vcs-* URLs

 -- Tiago Stürmer Daitx <email address hidden> Thu, 17 May 2018 13:03:29 +0000

Changed in ca-certificates-java (Ubuntu):
status: Fix Committed → Fix Released
description: updated

Hello Tiago, or anyone else affected,

Accepted ca-certificates-java into bionic-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/ca-certificates-java/20180516ubuntu1~18.04.1 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed.Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-bionic to verification-done-bionic. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-bionic. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance!

Changed in ca-certificates-java (Ubuntu Bionic):
status: Triaged → Fix Committed
tags: added: verification-needed verification-needed-bionic
tags: added: verification-done-bionic
removed: verification-needed verification-needed-bionic
Tiago Stürmer Daitx (tdaitx) wrote :

Using the tested I confirm that a previous PKCS12 keystore cacerts was successfully converted to a JKS format. Other users reported the same in bug 1770553.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package ca-certificates-java - 20180516ubuntu1~18.04.1

---------------
ca-certificates-java (20180516ubuntu1~18.04.1) bionic; urgency=medium

  * Backport from Cosmic. (LP: #1770553)

ca-certificates-java (20180516ubuntu1) cosmic; urgency=low

  * Merge from Debian unstable (LP: #1771815). Remaining changes:
    - debian/control: Bump javahelper build dependency.
    - debian/rules:
      + Explicitly depend on openjdk-11-jre-headless, needed to configure.
      + Replace javac arguments '-source 1.7 -target 1.7' with '--release 7'
        as, per JEP-247, it also takes care of setting the right -bootclasspath
        argument.

ca-certificates-java (20180516) unstable; urgency=medium

  * Team upload.

  [ Tiago Stürmer Daitx ]
  * debian/jks-keystore.hook.in: don't create a jvm-*.cfg file, a default file
    with the right configuration is already supplied by the openjdk packages.
  * debian/jks-keystore.hook.in, debian/postinst.in: Only export JAVA_HOME
    and update PATH if a known jvm was found.
  * debian/postinst.in: Detect PKCS12 cacert keystore generated by
    previous ca-certificates-java and convert them to JKS. (Closes: #898678)
    (LP: #1771363)

  [ Matthias Klose ]
  * debian/rules: Explicitly depend on openjdk-11-jre-headless, needed to
    configure.

  [ Emmanuel Bourg ]
  * Use salsa.debian.org Vcs-* URLs

ca-certificates-java (20180413ubuntu1) cosmic; urgency=medium

  * Merge from debian unstable. Remaining changes: (LP: #1769013,
    LP: #1739631)
    + debian/control: Bump javahelper build dependency.
    + debian/rules:
      - Explicitly depend on openjdk-11-jre-headless, needed to configure.
      - Replace javac arguments '-source 1.7 -target 1.7' with '--release 7'
        as, per JEP-247, it also takes care of setting the right -bootclasspath
        argument.
  * debian/jks-keystore.hook.in: don't create a jvm-*.cfg file, a default file
    with the right configuration is already supplied by the openjdk packages.

ca-certificates-java (20180413) unstable; urgency=medium

  * Team upload.
  * Always generate a JKS keystore instead of using the default format
    (Closes: #894979)
  * Look for Java 10 and Java 11 when detecting the JRE
  * Removed Damien Raude-Morvan from the uploaders (Closes: #889412)
  * Standards-Version updated to 4.1.4
  * Switch to debhelper level 11

 -- Tiago Stürmer Daitx <email address hidden> Thu, 17 May 2018 14:10:59 +0000

Changed in ca-certificates-java (Ubuntu Bionic):
status: Fix Committed → Fix Released

The verification of the Stable Release Update for ca-certificates-java has completed successfully and the package has now been released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.