diff -Nru ca-certificates-java-20130815ubuntu1/debian/changelog ca-certificates-java-20140324/debian/changelog --- ca-certificates-java-20130815ubuntu1/debian/changelog 2014-03-20 11:42:44.000000000 +0000 +++ ca-certificates-java-20140324/debian/changelog 2014-03-25 04:31:14.000000000 +0000 @@ -1,9 +1,16 @@ -ca-certificates-java (20130815ubuntu1) trusty; urgency=medium +ca-certificates-java (20140324) unstable; urgency=medium - * UpdatesCertificatesTest.java: Fix ftbfs by swapping out the no longer - shipped cacert.org certificate with a Thawte one. (LP: #1258286) + * Team upload. + * Fixed a test failure caused by the removal of the CAcert.org root + certificate from the ca-certificates package (Closes: #741755) + * Limit the memory used by java to 64M when updating the certificates + (Closes: #576453) + * Mavenized the project + * Code refactoring + * d/control: Standards-Version updated to 3.9.5 (no changes) + * Switch to debhelper level 9 - -- Marc Deslauriers Thu, 20 Mar 2014 07:41:31 -0400 + -- Emmanuel Bourg Mon, 24 Mar 2014 09:42:08 +0100 ca-certificates-java (20130815) unstable; urgency=low diff -Nru ca-certificates-java-20130815ubuntu1/debian/compat ca-certificates-java-20140324/debian/compat --- ca-certificates-java-20130815ubuntu1/debian/compat 2013-08-15 11:51:49.000000000 +0000 +++ ca-certificates-java-20140324/debian/compat 2014-03-25 04:31:14.000000000 +0000 @@ -1 +1 @@ -6 +9 diff -Nru ca-certificates-java-20130815ubuntu1/debian/control ca-certificates-java-20140324/debian/control --- ca-certificates-java-20130815ubuntu1/debian/control 2014-03-20 11:43:09.000000000 +0000 +++ ca-certificates-java-20140324/debian/control 2014-03-25 04:31:14.000000000 +0000 @@ -1,14 +1,13 @@ Source: ca-certificates-java Section: java Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Java Maintainers +Maintainer: Debian Java Maintainers Uploaders: Matthias Klose , Torsten Werner , Damien Raude-Morvan , James Page -Build-Depends: debhelper (>= 6), default-jdk, javahelper, junit4 -Standards-Version: 3.9.4 +Build-Depends: debhelper (>= 9), default-jdk, javahelper, junit4 +Standards-Version: 3.9.5 Vcs-Svn: svn://anonscm.debian.org/pkg-java/trunk/ca-certificates-java Vcs-Browser: http://anonscm.debian.org/viewvc/pkg-java/trunk/ca-certificates-java/ diff -Nru ca-certificates-java-20130815ubuntu1/debian/jks-keystore.hook.in ca-certificates-java-20140324/debian/jks-keystore.hook.in --- ca-certificates-java-20130815ubuntu1/debian/jks-keystore.hook.in 2013-08-15 11:55:57.000000000 +0000 +++ ca-certificates-java-20140324/debian/jks-keystore.hook.in 2014-03-25 04:31:14.000000000 +0000 @@ -79,7 +79,7 @@ fi } -if java -jar $JAR -storepass "$storepass"; then +if java -Xmx64m -jar $JAR -storepass "$storepass"; then do_cleanup else do_cleanup diff -Nru ca-certificates-java-20130815ubuntu1/debian/postinst.in ca-certificates-java-20140324/debian/postinst.in --- ca-certificates-java-20130815ubuntu1/debian/postinst.in 2013-08-15 11:56:03.000000000 +0000 +++ ca-certificates-java-20140324/debian/postinst.in 2014-03-25 04:31:14.000000000 +0000 @@ -50,7 +50,7 @@ # Forcibly remove diginotar cert (LP: #920758) if [ -n "$FIXOLD" ]; then echo -e "-diginotar_root_ca\n-diginotar_root_ca_pem" | \ - java -jar $JAR -storepass "$storepass" + java -Xmx64m -jar $JAR -storepass "$storepass" fi find /etc/ssl/certs -name \*.pem | \ @@ -63,7 +63,7 @@ fi echo "+${filename}" done | \ - java -jar $JAR -storepass "$storepass" + java -Xmx64m -jar $JAR -storepass "$storepass" echo "done." } diff -Nru ca-certificates-java-20130815ubuntu1/debian/rules ca-certificates-java-20140324/debian/rules --- ca-certificates-java-20130815ubuntu1/debian/rules 2013-08-15 11:51:49.000000000 +0000 +++ ca-certificates-java-20140324/debian/rules 2014-03-25 04:31:14.000000000 +0000 @@ -16,7 +16,7 @@ JAVA_HOME := /usr/lib/jvm/default-java export JAVA_HOME -OPTS := --no-javadoc --main=UpdateCertificates --javacopts="-source 1.6 -target 1.6" +OPTS := --no-javadoc --main=org.debian.security.UpdateCertificates --javacopts="-source 1.6 -target 1.6" CLASSPATH := /usr/share/java/junit4.jar export CLASSPATH @@ -29,11 +29,16 @@ build: build-stamp build-stamp: dh_testdir - jh_build $(OPTS) ca-certificates-java.jar . + mkdir target + jh_build $(OPTS) target/ca-certificates-java.jar src/main/java ifeq ($(do_junit),yes) - $(JAVA_HOME)/bin/java -cp /usr/share/java/junit4.jar:./ca-certificates-java.jar \ + jh_build --no-javadoc --javacopts="-source 1.6 -target 1.6 -cp target/ca-certificates-java.jar:${CLASSPATH}" \ + target/ca-certificates-java-tests.jar src/test/java + mkdir target/test-classes + cp -R src/test/resources/* target/test-classes + $(JAVA_HOME)/bin/java -cp /usr/share/java/junit4.jar:target/ca-certificates-java.jar:target/ca-certificates-java-tests.jar \ org.junit.runner.JUnitCore \ - UpdateCertificatesTest + org.debian.security.UpdateCertificatesTest org.debian.security.KeyStoreHandlerTest endif touch $@ @@ -41,7 +46,7 @@ dh_testdir dh_testroot jh_build --clean - $(RM) build-stamp + $(RM) -R build-stamp target dh_clean for f in debian/*.in; do \ f2=$$(echo $$f | sed ';s/\.in$$//'); \ @@ -66,7 +71,7 @@ $(d)/etc/ca-certificates/update.d/jks-keystore install -m600 debian/default \ $(d)/etc/default/cacerts - dh_install ca-certificates-java.jar /usr/share/ca-certificates-java/ + dh_install target/ca-certificates-java.jar /usr/share/ca-certificates-java/ # Build architecture-independent files here. binary-indep: build install diff -Nru ca-certificates-java-20130815ubuntu1/Exceptions.java ca-certificates-java-20140324/Exceptions.java --- ca-certificates-java-20130815ubuntu1/Exceptions.java 2013-08-15 11:51:49.000000000 +0000 +++ ca-certificates-java-20140324/Exceptions.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 Damien Raude-Morvan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/** - * Custom exceptions used by {@link UpdateCertificates} - * - * @author Damien Raude-Morvan - */ -public class Exceptions { - - /** - * Data send in stdin is invalid (neither "+" or "-" command). - */ - public static class UnknownInput extends Exception { - private static final long serialVersionUID = 5698253678856993527L; - public UnknownInput(final String message) { - super(message); - } - - } - - /** - * Unable to save keystore to provided location. - */ - public static class UnableToSaveKeystore extends Exception { - private static final long serialVersionUID = 3632154306237688490L; - public UnableToSaveKeystore(final String message, final Exception e) { - super(message, e); - } - - } - - /** - * Unable to open keystore from provided location (might be an invalid password - * or IO error). - */ - public static class InvalidKeystorePassword extends Exception { - private static final long serialVersionUID = 7004201816889107694L; - public InvalidKeystorePassword(final String message, final Exception e) { - super(message, e); - } - - } - -} diff -Nru ca-certificates-java-20130815ubuntu1/pom.xml ca-certificates-java-20140324/pom.xml --- ca-certificates-java-20130815ubuntu1/pom.xml 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/pom.xml 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,33 @@ + + 4.0.0 + + org.debian + ca-certificates-java + 20140324 + jar + ca-certificates-java + Common CA certificates + + + + junit + junit + 4.11 + test + + + + + + + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + + diff -Nru ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/InvalidKeystorePasswordException.java ca-certificates-java-20140324/src/main/java/org/debian/security/InvalidKeystorePasswordException.java --- ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/InvalidKeystorePasswordException.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/main/java/org/debian/security/InvalidKeystorePasswordException.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +/** + * Unable to open keystore from provided location (might be an invalid password + * or IO error). + */ +public class InvalidKeystorePasswordException extends Exception { + private static final long serialVersionUID = 7004201816889107694L; + + public InvalidKeystorePasswordException(String message, Exception e) { + super(message, e); + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/KeyStoreHandler.java ca-certificates-java-20140324/src/main/java/org/debian/security/KeyStoreHandler.java --- ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/KeyStoreHandler.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/main/java/org/debian/security/KeyStoreHandler.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011 Torsten Werner + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; + +/** + * Handles read/write operations on a keystore. + */ +class KeyStoreHandler { + + /** The path of the keystore */ + private String filename; + + /** The password of the keystore */ + private char[] password; + + private KeyStore ks; + + private CertificateFactory certFactory; + + KeyStoreHandler(String filename, char[] password) throws GeneralSecurityException, IOException, InvalidKeystorePasswordException { + this.filename = filename; + this.password = password; + this.certFactory = CertificateFactory.getInstance("X.509"); + + load(); + } + + /** + * Try to open an existing keystore or create an new one. + */ + public void load() throws GeneralSecurityException, IOException, InvalidKeystorePasswordException { + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + File file = new File(filename); + FileInputStream in = null; + if (file.canRead()) { + in = new FileInputStream(file); + } + try { + ks.load(in, password); + } catch (IOException e) { + throw new InvalidKeystorePasswordException("Cannot open Java keystore. Is the password correct?", e); + } finally { + if (in != null) { + in.close(); + } + } + this.ks = ks; + } + + /** + * Write actual keystore content to disk. + */ + public void save() throws GeneralSecurityException, UnableToSaveKeystoreException { + try { + FileOutputStream certOutputFile = new FileOutputStream(filename); + ks.store(certOutputFile, password); + certOutputFile.close(); + } catch (IOException e) { + throw new UnableToSaveKeystoreException("There was a problem saving the new Java keystore.", e); + } + } + + /** + * Add or replace existing cert in keystore with given alias. + */ + public void addAlias(String alias, String path) throws KeyStoreException { + Certificate cert = loadCertificate(path); + if (cert == null) { + return; + } + addAlias(alias, cert); + } + + /** + * Add or replace existing cert in keystore with given alias. + */ + public void addAlias(String alias, Certificate cert) throws KeyStoreException { + if (contains(alias)) { + System.out.println("Replacing " + alias); + ks.deleteEntry(alias); + } else { + System.out.println("Adding " + alias); + } + ks.setCertificateEntry(alias, cert); + } + + /** + * Delete cert in keystore at given alias. + */ + public void deleteAlias(String alias) throws GeneralSecurityException { + if (contains(alias)) { + System.out.println("Removing " + alias); + ks.deleteEntry(alias); + } + } + + /** + * Returns true when alias exist in keystore. + */ + public boolean contains(String alias) throws KeyStoreException { + return ks.containsAlias(alias); + } + + /** + * Try to load a certificate instance from given path. + */ + private Certificate loadCertificate(String path) { + Certificate certificate = null; + try { + FileInputStream in = new FileInputStream(path); + certificate = certFactory.generateCertificate(in); + in.close(); + } catch (Exception e) { + System.err.println("Warning: there was a problem reading the certificate file " + + path + ". Message:\n " + e.getMessage()); + } + return certificate; + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UnableToSaveKeystoreException.java ca-certificates-java-20140324/src/main/java/org/debian/security/UnableToSaveKeystoreException.java --- ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UnableToSaveKeystoreException.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/main/java/org/debian/security/UnableToSaveKeystoreException.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +/** + * Unable to save keystore to provided location. + */ +public class UnableToSaveKeystoreException extends Exception { + private static final long serialVersionUID = 3632154306237688490L; + + public UnableToSaveKeystoreException(String message, Exception e) { + super(message, e); + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UnknownInputException.java ca-certificates-java-20140324/src/main/java/org/debian/security/UnknownInputException.java --- ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UnknownInputException.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/main/java/org/debian/security/UnknownInputException.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +/** + * Data send in stdin is invalid (neither "+" or "-" command). + */ +public class UnknownInputException extends Exception { + private static final long serialVersionUID = 5698253678856993527L; + + public UnknownInputException(String message) { + super(message); + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UpdateCertificates.java ca-certificates-java-20140324/src/main/java/org/debian/security/UpdateCertificates.java --- ca-certificates-java-20130815ubuntu1/src/main/java/org/debian/security/UpdateCertificates.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/main/java/org/debian/security/UpdateCertificates.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2011 Torsten Werner + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.security.GeneralSecurityException; +import java.security.cert.Certificate; + +/** + * This code is a re-implementation of the idea from Ludwig Nussel found in + * https://github.com/openSUSE/ca-certificates/blob/41917f5a/keystore.java + * for the Debian operating system. It updates the global JVM keystore. + * + * @author Torsten Werner + * @author Damien Raude-Morvan + */ +public class UpdateCertificates { + + private KeyStoreHandler keystore; + + public static void main(String[] args) throws IOException, GeneralSecurityException { + String passwordString = "changeit"; + if (args.length == 2 && args[0].equals("-storepass")) { + passwordString = args[1]; + } else if (args.length > 0) { + System.err.println("Usage: java org.debian.security.UpdateCertificates [-storepass ]"); + System.exit(1); + } + + try { + UpdateCertificates uc = new UpdateCertificates("/etc/ssl/certs/java/cacerts", passwordString); + // Force reading of inputstream in UTF-8 + uc.processChanges(new InputStreamReader(System.in, "UTF8")); + uc.finish(); + } catch (InvalidKeystorePasswordException e) { + e.printStackTrace(System.err); + System.exit(1); + } catch (UnableToSaveKeystoreException e) { + e.printStackTrace(System.err); + System.exit(1); + } + } + + public UpdateCertificates(String keystoreFile, String password) throws IOException, GeneralSecurityException, InvalidKeystorePasswordException { + this.keystore = new KeyStoreHandler(keystoreFile, password.toCharArray()); + } + + /** + * Until reader EOF, try to read changes and send each to {@link #parseLine(String)}. + */ + protected void processChanges(Reader reader) throws IOException, GeneralSecurityException { + String line; + BufferedReader in = new BufferedReader(reader); + while ((line = in.readLine()) != null) { + try { + parseLine(line); + } catch (UnknownInputException e) { + System.err.println("Unknown input: " + line); + // Keep processing for others lines + } + } + } + + /** + * Parse given line to choose between {@link #addAlias(String, Certificate)} + * or {@link #deleteAlias(String)}. + */ + protected void parseLine(final String line) throws GeneralSecurityException, IOException, UnknownInputException { + String path = line.substring(1); + String filename = path.substring(path.lastIndexOf("/") + 1); + String alias = "debian:" + filename; + if (line.startsWith("+")) { + keystore.addAlias(alias, path); + } else if (line.startsWith("-")) { + keystore.deleteAlias(alias); + // Remove old non-prefixed aliases, too. This code should be + // removed after the release of Wheezy. + keystore.deleteAlias(filename); + } else { + throw new UnknownInputException(line); + } + } + + /** + * Write the pending changes to the keystore file. + */ + protected void finish() throws GeneralSecurityException, UnableToSaveKeystoreException { + keystore.save(); + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/test/java/org/debian/security/KeyStoreHandlerTest.java ca-certificates-java-20140324/src/test/java/org/debian/security/KeyStoreHandlerTest.java --- ca-certificates-java-20130815ubuntu1/src/test/java/org/debian/security/KeyStoreHandlerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/test/java/org/debian/security/KeyStoreHandlerTest.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +import java.io.File; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author Emmanuel Bourg + * @version $Revision: 17927 $, $Date: 2014-03-24 05:32:19 -0700 (Mon, 24 Mar 2014) $ + */ +public class KeyStoreHandlerTest { + + private String ksFilename = "./target/test-classes/tests-cacerts"; + private char[] ksPassword = "changeit".toCharArray(); + + /** + * Test a simple open then write without any modification. + */ + @Test + public void testNoop() throws Exception { + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword); + keystore.save(); + } + + /** + * Test a to open a keystore and write without any modification + * and then try to open it again with wrong password : will throw a + * InvalidKeystorePassword + */ + @Test + public void testWriteThenOpenWrongPwd() throws Exception { + try { + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword); + keystore.save(); + } catch (InvalidKeystorePasswordException e) { + fail(); + } + + try { + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, "wrongpassword".toCharArray()); + fail(); + keystore.save(); + } catch (InvalidKeystorePasswordException e) { + assertEquals("Cannot open Java keystore. Is the password correct?", e.getMessage()); + } + } + + /** + * Test a to open a keystore then remove its backing File (and replace it + * with a directory with the same name) and try to write in to disk : + * will throw an UnableToSaveKeystore + */ + @Test + public void testDeleteThenWrite() throws Exception { + try { + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword); + + // Replace actual file by a directory ! + File file = new File(ksFilename); + file.delete(); + file.mkdir(); + + // Will fail with some IOException + keystore.save(); + fail(); + } catch (UnableToSaveKeystoreException e) { + assertEquals("There was a problem saving the new Java keystore.", e.getMessage()); + } + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/test/java/org/debian/security/UpdateCertificatesTest.java ca-certificates-java-20140324/src/test/java/org/debian/security/UpdateCertificatesTest.java --- ca-certificates-java-20130815ubuntu1/src/test/java/org/debian/security/UpdateCertificatesTest.java 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/test/java/org/debian/security/UpdateCertificatesTest.java 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 Damien Raude-Morvan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.debian.security; + +import java.io.File; +import java.io.StringReader; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Tests for {@link UpdateCertificates}. + * + * @author Damien Raude-Morvan + */ +public class UpdateCertificatesTest { + + private static final String CERT_ALIAS = "debian:spi-cacert-2008.crt"; + private static final String CERT_PATH = "target/test-classes/spi-cacert-2008.crt"; + private static final String INVALID_CERT_CMD = "x" + CERT_PATH; + private static final String REMOVE_CERT_CMD = "-" + CERT_PATH; + private static final String ADD_CERT_CMD = "+" + CERT_PATH; + + private String ksFilename = "./target/test-classes/tests-cacerts"; + private String ksPassword = "changeit"; + + @Before + public void start() { + // Delete any previous file + File keystore = new File(ksFilename); + keystore.delete(); + } + + /** + * Try to send an invalid command ("x") in parseLine : throw UnknownInput + */ + @Test + public void testWrongCommand() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + try { + uc.parseLine(INVALID_CERT_CMD); + fail(); + } catch (UnknownInputException e) { + assertEquals(INVALID_CERT_CMD, e.getMessage()); + } + } + + /** + * Test to insert a valid certificate and then check if it's really in KS. + */ + @Test + public void testAdd() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.parseLine(ADD_CERT_CMD); + uc.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(true, keystore.contains(CERT_ALIAS)); + } + + /** + * Test to insert a invalide certificate : no exception, but check there + * is no alias created with that name + */ + @Test + public void testAddInvalidCert() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.parseLine("+/usr/share/ca-certificates/null.crt"); + uc.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(false, keystore.contains("debian:null.crt")); + } + + /** + * Test to insert a certificate with a comment (Bug #539283) + */ + @Test + public void testAddCertWithComment() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.parseLine("+target/test-classes/spi-cacert-2008-with-comment.crt"); + uc.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(true, keystore.contains("debian:spi-cacert-2008-with-comment.crt")); + } + + /** + * Try to add same certificate multiple time : we replace it and + * there is only one alias. + */ + @Test + public void testReplace() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.parseLine(ADD_CERT_CMD); + uc.parseLine(ADD_CERT_CMD); + uc.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(true, keystore.contains(CERT_ALIAS)); + } + + /** + * Try to remove a non-existant certificate : it's a no-op. + */ + @Test + public void testRemove() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.parseLine(REMOVE_CERT_CMD); + uc.finish(); + + // We start with empty KS, so it shouldn't do anything + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(false, keystore.contains(CERT_ALIAS)); + } + + /** + * Try to add cert, write to disk, then open keystore again and remove. + */ + @Test + public void testAddThenRemove() throws Exception { + UpdateCertificates ucAdd = new UpdateCertificates(ksFilename, ksPassword); + ucAdd.parseLine(ADD_CERT_CMD); + ucAdd.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(true, keystore.contains(CERT_ALIAS)); + + UpdateCertificates ucRemove = new UpdateCertificates(ksFilename, ksPassword); + ucRemove.parseLine(REMOVE_CERT_CMD); + ucRemove.finish(); + + keystore.load(); + assertEquals(false, keystore.contains(CERT_ALIAS)); + } + + @Test + public void testProcessChanges() throws Exception { + UpdateCertificates uc = new UpdateCertificates(ksFilename, ksPassword); + uc.processChanges(new StringReader(ADD_CERT_CMD + "\n" + INVALID_CERT_CMD + "\n" + REMOVE_CERT_CMD + "\n")); + uc.finish(); + + KeyStoreHandler keystore = new KeyStoreHandler(ksFilename, ksPassword.toCharArray()); + assertEquals(false, keystore.contains(CERT_ALIAS)); + } +} diff -Nru ca-certificates-java-20130815ubuntu1/src/test/resources/spi-cacert-2008.crt ca-certificates-java-20140324/src/test/resources/spi-cacert-2008.crt --- ca-certificates-java-20130815ubuntu1/src/test/resources/spi-cacert-2008.crt 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/test/resources/spi-cacert-2008.crt 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,46 @@ +-----BEGIN CERTIFICATE----- +MIIIDjCCBfagAwIBAgIJAOiOtsn4KhQoMA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UEBxMMSW5kaWFuYXBvbGlz +MSgwJgYDVQQKEx9Tb2Z0d2FyZSBpbiB0aGUgUHVibGljIEludGVyZXN0MRMwEQYD +VQQLEwpob3N0bWFzdGVyMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx +JTAjBgkqhkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDgwNTEz +MDgwNzU2WhcNMTgwNTExMDgwNzU2WjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh +cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEe +MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo +b3N0bWFzdGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA3DbmR0LCxFF1KYdAw9iOIQbSGE7r7yC9kDyFEBOMKVuUY/b0LfEGQpG5 +GcRCaQi/izZF6igFM0lIoCdDkzWKQdh4s/Dvs24t3dHLfer0dSbTPpA67tfnLAS1 +fOH1fMVO73e9XKKTM5LOfYFIz2u1IiwIg/3T1c87Lf21SZBb9q1NE8re06adU1Fx +Y0b4ShZcmO4tbZoWoXaQ4mBDmdaJ1mwuepiyCwMs43pPx93jzONKao15Uvr0wa8u +jyoIyxspgpJyQ7zOiKmqp4pRQ1WFmjcDeJPI8L20QcgHQprLNZd6ioFl3h1UCAHx +ZFy3FxpRvB7DWYd2GBaY7r/2Z4GLBjXFS21ZGcfSxki+bhQog0oQnBv1b7ypjvVp +/rLBVcznFMn5WxRTUQfqzj3kTygfPGEJ1zPSbqdu1McTCW9rXRTunYkbpWry9vjQ +co7qch8vNGopCsUK7BxAhRL3pqXTT63AhYxMfHMgzFMY8bJYTAH1v+pk1Vw5xc5s +zFNaVrpBDyXfa1C2x4qgvQLCxTtVpbJkIoRRKFauMe5e+wsWTUYFkYBE7axt8Feo ++uthSKDLG7Mfjs3FIXcDhB78rKNDCGOM7fkn77SwXWfWT+3Qiz5dW8mRvZYChD3F +TbxCP3T9PF2sXEg2XocxLxhsxGjuoYvJWdAY4wCAs1QnLpnwFVMCAwEAAaOCAg8w +ggILMB0GA1UdDgQWBBQ0cdE41xU2g0dr1zdkQjuOjVKdqzCB8QYDVR0jBIHpMIHm +gBQ0cdE41xU2g0dr1zdkQjuOjVKdq6GBwqSBvzCBvDELMAkGA1UEBhMCVVMxEDAO +BgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMf +U29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1h +c3RlcjEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcN +AQkBFhZob3N0bWFzdGVyQHNwaS1pbmMub3JnggkA6I62yfgqFCgwDwYDVR0TAQH/ +BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAAcwCQYDVR0SBAIwADAuBglghkgBhvhC +AQ0EIRYfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDAwBglghkgBhvhC +AQQEIxYhaHR0cHM6Ly9jYS5zcGktaW5jLm9yZy9jYS1jcmwucGVtMDIGCWCGSAGG ++EIBAwQlFiNodHRwczovL2NhLnNwaS1pbmMub3JnL2NlcnQtY3JsLnBlbTAhBgNV +HREEGjAYgRZob3N0bWFzdGVyQHNwaS1pbmMub3JnMA4GA1UdDwEB/wQEAwIBBjAN +BgkqhkiG9w0BAQUFAAOCAgEAtM294LnqsgMrfjLp3nI/yUuCXp3ir1UJogxU6M8Y +PCggHam7AwIvUjki+RfPrWeQswN/2BXja367m1YBrzXU2rnHZxeb1NUON7MgQS4M +AcRb+WU+wmHo0vBqlXDDxm/VNaSsWXLhid+hoJ0kvSl56WEq2dMeyUakCHhBknIP +qxR17QnwovBc78MKYiC3wihmrkwvLo9FYyaW8O4x5otVm6o6+YI5HYg84gd1GuEP +sTC8cTLSOv76oYnzQyzWcsR5pxVIBcDYLXIC48s9Fmq6ybgREOJJhcyWR2AFJS7v +dVkz9UcZFu/abF8HyKZQth3LZjQl/GaD68W2MEH4RkRiqMEMVObqTFoo5q7Gt/5/ +O5aoLu7HaD7dAD0prypjq1/uSSotxdz70cbT0ZdWUoa2lOvUYFG3/B6bzAKb1B+P ++UqPti4oOxfMxaYF49LTtcYDyeFIQpvLP+QX4P4NAZUJurgNceQJcHdC2E3hQqlg +g9cXiUPS1N2nGLar1CQlh7XU4vwuImm9rWgs/3K1mKoGnOcqarihk3bOsPN/nOHg +T7jYhkalMwIsJWE3KpLIrIF0aGOHM3a9BX9e1dUCbb2v/ypaqknsmHlHU5H2DjRa +yaXG67Ljxay2oHA1u8hRadDytaIybrw/oDc5fHE2pgXfDBLkFqfF1stjo5VwP+YE +o2A= +-----END CERTIFICATE----- diff -Nru ca-certificates-java-20130815ubuntu1/src/test/resources/spi-cacert-2008-with-comment.crt ca-certificates-java-20140324/src/test/resources/spi-cacert-2008-with-comment.crt --- ca-certificates-java-20130815ubuntu1/src/test/resources/spi-cacert-2008-with-comment.crt 1970-01-01 00:00:00.000000000 +0000 +++ ca-certificates-java-20140324/src/test/resources/spi-cacert-2008-with-comment.crt 2014-03-25 04:31:14.000000000 +0000 @@ -0,0 +1,151 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 16757532242060383272 (0xe88eb6c9f82a1428) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Indiana, L=Indianapolis, O=Software in the Public Interest, OU=hostmaster, CN=Certificate Authority/emailAddress=hostmaster@spi-inc.org + Validity + Not Before: May 13 08:07:56 2008 GMT + Not After : May 11 08:07:56 2018 GMT + Subject: C=US, ST=Indiana, L=Indianapolis, O=Software in the Public Interest, OU=hostmaster, CN=Certificate Authority/emailAddress=hostmaster@spi-inc.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:dc:36:e6:47:42:c2:c4:51:75:29:87:40:c3:d8: + 8e:21:06:d2:18:4e:eb:ef:20:bd:90:3c:85:10:13: + 8c:29:5b:94:63:f6:f4:2d:f1:06:42:91:b9:19:c4: + 42:69:08:bf:8b:36:45:ea:28:05:33:49:48:a0:27: + 43:93:35:8a:41:d8:78:b3:f0:ef:b3:6e:2d:dd:d1: + cb:7d:ea:f4:75:26:d3:3e:90:3a:ee:d7:e7:2c:04: + b5:7c:e1:f5:7c:c5:4e:ef:77:bd:5c:a2:93:33:92: + ce:7d:81:48:cf:6b:b5:22:2c:08:83:fd:d3:d5:cf: + 3b:2d:fd:b5:49:90:5b:f6:ad:4d:13:ca:de:d3:a6: + 9d:53:51:71:63:46:f8:4a:16:5c:98:ee:2d:6d:9a: + 16:a1:76:90:e2:60:43:99:d6:89:d6:6c:2e:7a:98: + b2:0b:03:2c:e3:7a:4f:c7:dd:e3:cc:e3:4a:6a:8d: + 79:52:fa:f4:c1:af:2e:8f:2a:08:cb:1b:29:82:92: + 72:43:bc:ce:88:a9:aa:a7:8a:51:43:55:85:9a:37: + 03:78:93:c8:f0:bd:b4:41:c8:07:42:9a:cb:35:97: + 7a:8a:81:65:de:1d:54:08:01:f1:64:5c:b7:17:1a: + 51:bc:1e:c3:59:87:76:18:16:98:ee:bf:f6:67:81: + 8b:06:35:c5:4b:6d:59:19:c7:d2:c6:48:be:6e:14: + 28:83:4a:10:9c:1b:f5:6f:bc:a9:8e:f5:69:fe:b2: + c1:55:cc:e7:14:c9:f9:5b:14:53:51:07:ea:ce:3d: + e4:4f:28:1f:3c:61:09:d7:33:d2:6e:a7:6e:d4:c7: + 13:09:6f:6b:5d:14:ee:9d:89:1b:a5:6a:f2:f6:f8: + d0:72:8e:ea:72:1f:2f:34:6a:29:0a:c5:0a:ec:1c: + 40:85:12:f7:a6:a5:d3:4f:ad:c0:85:8c:4c:7c:73: + 20:cc:53:18:f1:b2:58:4c:01:f5:bf:ea:64:d5:5c: + 39:c5:ce:6c:cc:53:5a:56:ba:41:0f:25:df:6b:50: + b6:c7:8a:a0:bd:02:c2:c5:3b:55:a5:b2:64:22:84: + 51:28:56:ae:31:ee:5e:fb:0b:16:4d:46:05:91:80: + 44:ed:ac:6d:f0:57:a8:fa:eb:61:48:a0:cb:1b:b3: + 1f:8e:cd:c5:21:77:03:84:1e:fc:ac:a3:43:08:63: + 8c:ed:f9:27:ef:b4:b0:5d:67:d6:4f:ed:d0:8b:3e: + 5d:5b:c9:91:bd:96:02:84:3d:c5:4d:bc:42:3f:74: + fd:3c:5d:ac:5c:48:36:5e:87:31:2f:18:6c:c4:68: + ee:a1:8b:c9:59:d0:18:e3:00:80:b3:54:27:2e:99: + f0:15:53 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 34:71:D1:38:D7:15:36:83:47:6B:D7:37:64:42:3B:8E:8D:52:9D:AB + X509v3 Authority Key Identifier: + keyid:34:71:D1:38:D7:15:36:83:47:6B:D7:37:64:42:3B:8E:8D:52:9D:AB + DirName:/C=US/ST=Indiana/L=Indianapolis/O=Software in the Public Interest/OU=hostmaster/CN=Certificate Authority/emailAddress=hostmaster@spi-inc.org + serial:E8:8E:B6:C9:F8:2A:14:28 + + X509v3 Basic Constraints: critical + CA:TRUE + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + X509v3 Issuer Alternative Name: + + + Netscape Comment: + Software in the Public Interest + Netscape CA Revocation Url: + https://ca.spi-inc.org/ca-crl.pem + Netscape Revocation Url: + https://ca.spi-inc.org/cert-crl.pem + X509v3 Subject Alternative Name: + email:hostmaster@spi-inc.org + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Signature Algorithm: sha1WithRSAEncryption + b4:cd:bd:e0:b9:ea:b2:03:2b:7e:32:e9:de:72:3f:c9:4b:82: + 5e:9d:e2:af:55:09:a2:0c:54:e8:cf:18:3c:28:20:1d:a9:bb: + 03:02:2f:52:39:22:f9:17:cf:ad:67:90:b3:03:7f:d8:15:e3: + 6b:7e:bb:9b:56:01:af:35:d4:da:b9:c7:67:17:9b:d4:d5:0e: + 37:b3:20:41:2e:0c:01:c4:5b:f9:65:3e:c2:61:e8:d2:f0:6a: + 95:70:c3:c6:6f:d5:35:a4:ac:59:72:e1:89:df:a1:a0:9d:24: + bd:29:79:e9:61:2a:d9:d3:1e:c9:46:a4:08:78:41:92:72:0f: + ab:14:75:ed:09:f0:a2:f0:5c:ef:c3:0a:62:20:b7:c2:28:66: + ae:4c:2f:2e:8f:45:63:26:96:f0:ee:31:e6:8b:55:9b:aa:3a: + f9:82:39:1d:88:3c:e2:07:75:1a:e1:0f:b1:30:bc:71:32:d2: + 3a:fe:fa:a1:89:f3:43:2c:d6:72:c4:79:a7:15:48:05:c0:d8: + 2d:72:02:e3:cb:3d:16:6a:ba:c9:b8:11:10:e2:49:85:cc:96: + 47:60:05:25:2e:ef:75:59:33:f5:47:19:16:ef:da:6c:5f:07: + c8:a6:50:b6:1d:cb:66:34:25:fc:66:83:eb:c5:b6:30:41:f8: + 46:44:62:a8:c1:0c:54:e6:ea:4c:5a:28:e6:ae:c6:b7:fe:7f: + 3b:96:a8:2e:ee:c7:68:3e:dd:00:3d:29:af:2a:63:ab:5f:ee: + 49:2a:2d:c5:dc:fb:d1:c6:d3:d1:97:56:52:86:b6:94:eb:d4: + 60:51:b7:fc:1e:9b:cc:02:9b:d4:1f:8f:f9:4a:8f:b6:2e:28: + 3b:17:cc:c5:a6:05:e3:d2:d3:b5:c6:03:c9:e1:48:42:9b:cb: + 3f:e4:17:e0:fe:0d:01:95:09:ba:b8:0d:71:e4:09:70:77:42: + d8:4d:e1:42:a9:60:83:d7:17:89:43:d2:d4:dd:a7:18:b6:ab: + d4:24:25:87:b5:d4:e2:fc:2e:22:69:bd:ad:68:2c:ff:72:b5: + 98:aa:06:9c:e7:2a:6a:b8:a1:93:76:ce:b0:f3:7f:9c:e1:e0: + 4f:b8:d8:86:46:a5:33:02:2c:25:61:37:2a:92:c8:ac:81:74: + 68:63:87:33:76:bd:05:7f:5e:d5:d5:02:6d:bd:af:ff:2a:5a: + aa:49:ec:98:79:47:53:91:f6:0e:34:5a:c9:a5:c6:eb:b2:e3: + c5:ac:b6:a0:70:35:bb:c8:51:69:d0:f2:b5:a2:32:6e:bc:3f: + a0:37:39:7c:71:36:a6:05:df:0c:12:e4:16:a7:c5:d6:cb:63: + a3:95:70:3f:e6:04:a3:60 +-----BEGIN CERTIFICATE----- +MIIIDjCCBfagAwIBAgIJAOiOtsn4KhQoMA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UEBxMMSW5kaWFuYXBvbGlz +MSgwJgYDVQQKEx9Tb2Z0d2FyZSBpbiB0aGUgUHVibGljIEludGVyZXN0MRMwEQYD +VQQLEwpob3N0bWFzdGVyMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx +JTAjBgkqhkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDgwNTEz +MDgwNzU2WhcNMTgwNTExMDgwNzU2WjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh +cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEe +MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo +b3N0bWFzdGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA3DbmR0LCxFF1KYdAw9iOIQbSGE7r7yC9kDyFEBOMKVuUY/b0LfEGQpG5 +GcRCaQi/izZF6igFM0lIoCdDkzWKQdh4s/Dvs24t3dHLfer0dSbTPpA67tfnLAS1 +fOH1fMVO73e9XKKTM5LOfYFIz2u1IiwIg/3T1c87Lf21SZBb9q1NE8re06adU1Fx +Y0b4ShZcmO4tbZoWoXaQ4mBDmdaJ1mwuepiyCwMs43pPx93jzONKao15Uvr0wa8u +jyoIyxspgpJyQ7zOiKmqp4pRQ1WFmjcDeJPI8L20QcgHQprLNZd6ioFl3h1UCAHx +ZFy3FxpRvB7DWYd2GBaY7r/2Z4GLBjXFS21ZGcfSxki+bhQog0oQnBv1b7ypjvVp +/rLBVcznFMn5WxRTUQfqzj3kTygfPGEJ1zPSbqdu1McTCW9rXRTunYkbpWry9vjQ +co7qch8vNGopCsUK7BxAhRL3pqXTT63AhYxMfHMgzFMY8bJYTAH1v+pk1Vw5xc5s +zFNaVrpBDyXfa1C2x4qgvQLCxTtVpbJkIoRRKFauMe5e+wsWTUYFkYBE7axt8Feo ++uthSKDLG7Mfjs3FIXcDhB78rKNDCGOM7fkn77SwXWfWT+3Qiz5dW8mRvZYChD3F +TbxCP3T9PF2sXEg2XocxLxhsxGjuoYvJWdAY4wCAs1QnLpnwFVMCAwEAAaOCAg8w +ggILMB0GA1UdDgQWBBQ0cdE41xU2g0dr1zdkQjuOjVKdqzCB8QYDVR0jBIHpMIHm +gBQ0cdE41xU2g0dr1zdkQjuOjVKdq6GBwqSBvzCBvDELMAkGA1UEBhMCVVMxEDAO +BgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMf +U29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1h +c3RlcjEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcN +AQkBFhZob3N0bWFzdGVyQHNwaS1pbmMub3JnggkA6I62yfgqFCgwDwYDVR0TAQH/ +BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAAcwCQYDVR0SBAIwADAuBglghkgBhvhC +AQ0EIRYfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDAwBglghkgBhvhC +AQQEIxYhaHR0cHM6Ly9jYS5zcGktaW5jLm9yZy9jYS1jcmwucGVtMDIGCWCGSAGG ++EIBAwQlFiNodHRwczovL2NhLnNwaS1pbmMub3JnL2NlcnQtY3JsLnBlbTAhBgNV +HREEGjAYgRZob3N0bWFzdGVyQHNwaS1pbmMub3JnMA4GA1UdDwEB/wQEAwIBBjAN +BgkqhkiG9w0BAQUFAAOCAgEAtM294LnqsgMrfjLp3nI/yUuCXp3ir1UJogxU6M8Y +PCggHam7AwIvUjki+RfPrWeQswN/2BXja367m1YBrzXU2rnHZxeb1NUON7MgQS4M +AcRb+WU+wmHo0vBqlXDDxm/VNaSsWXLhid+hoJ0kvSl56WEq2dMeyUakCHhBknIP +qxR17QnwovBc78MKYiC3wihmrkwvLo9FYyaW8O4x5otVm6o6+YI5HYg84gd1GuEP +sTC8cTLSOv76oYnzQyzWcsR5pxVIBcDYLXIC48s9Fmq6ybgREOJJhcyWR2AFJS7v +dVkz9UcZFu/abF8HyKZQth3LZjQl/GaD68W2MEH4RkRiqMEMVObqTFoo5q7Gt/5/ +O5aoLu7HaD7dAD0prypjq1/uSSotxdz70cbT0ZdWUoa2lOvUYFG3/B6bzAKb1B+P ++UqPti4oOxfMxaYF49LTtcYDyeFIQpvLP+QX4P4NAZUJurgNceQJcHdC2E3hQqlg +g9cXiUPS1N2nGLar1CQlh7XU4vwuImm9rWgs/3K1mKoGnOcqarihk3bOsPN/nOHg +T7jYhkalMwIsJWE3KpLIrIF0aGOHM3a9BX9e1dUCbb2v/ypaqknsmHlHU5H2DjRa +yaXG67Ljxay2oHA1u8hRadDytaIybrw/oDc5fHE2pgXfDBLkFqfF1stjo5VwP+YE +o2A= +-----END CERTIFICATE----- diff -Nru ca-certificates-java-20130815ubuntu1/UpdateCertificates.java ca-certificates-java-20140324/UpdateCertificates.java --- ca-certificates-java-20130815ubuntu1/UpdateCertificates.java 2013-08-15 11:51:49.000000000 +0000 +++ ca-certificates-java-20140324/UpdateCertificates.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2011 Torsten Werner - * Copyright (C) 2012 Damien Raude-Morvan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; - -/** - * This code is a re-implementation of the idea from Ludwig Nussel found in - * http://gitorious.org/opensuse/ca-certificates/blobs/master/keystore.java - * for the Debian operating system. It updates the global JVM keystore. - * - * @author Torsten Werner - * @author Damien Raude-Morvan - */ -public class UpdateCertificates { - - private char[] password = null; - - private String ksFilename = null; - - private KeyStore ks = null; - - private CertificateFactory certFactory = null; - - public static void main(String[] args) throws IOException, GeneralSecurityException { - String passwordString = "changeit"; - if (args.length == 2 && args[0].equals("-storepass")) { - passwordString = args[1]; - } - else if (args.length > 0) { - System.err.println("Usage: java UpdateCertificates [-storepass ]"); - System.exit(1); - } - - try { - UpdateCertificates uc = new UpdateCertificates(passwordString, "/etc/ssl/certs/java/cacerts"); - // Force reading of inputstream in UTF-8 - uc.processChanges(new InputStreamReader(System.in, "UTF8")); - uc.writeKeyStore(); - } catch (Exceptions.InvalidKeystorePassword e) { - e.printStackTrace(System.err); - System.exit(1); - } catch (Exceptions.UnableToSaveKeystore e) { - e.printStackTrace(System.err); - System.exit(1); - } - } - - public UpdateCertificates(final String passwordString, final String keystoreFile) throws IOException, GeneralSecurityException, Exceptions.InvalidKeystorePassword { - this.password = passwordString.toCharArray(); - this.ksFilename = keystoreFile; - this.ks = openKeyStore(); - this.certFactory = CertificateFactory.getInstance("X.509"); - } - - /** - * Try to open a existing keystore or create an new one. - */ - private KeyStore openKeyStore() throws GeneralSecurityException, IOException, Exceptions.InvalidKeystorePassword { - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - File certInputFile = new File(this.ksFilename); - FileInputStream certInputStream = null; - if (certInputFile.canRead()) { - certInputStream = new FileInputStream(certInputFile); - } - try { - ks.load(certInputStream, this.password); - } - catch (IOException e) { - throw new Exceptions.InvalidKeystorePassword("Cannot open Java keystore. Is the password correct?", e); - } - if (certInputStream != null) { - certInputStream.close(); - } - return ks; - } - - /** - * Until reader EOF, try to read changes and send each to {@link #parseLine(String)}. - */ - protected void processChanges(final Reader reader) - throws IOException, GeneralSecurityException { - String line; - BufferedReader bufferedStdinReader = new BufferedReader(reader); - while((line = bufferedStdinReader.readLine()) != null) { - try { - parseLine(line); - } catch (Exceptions.UnknownInput e) { - System.err.println("Unknown input: " + line); - // Keep processing for others lines - } - } - } - - /** - * Parse given line to choose between {@link #addAlias(String, Certificate)} - * or {@link #deleteAlias(String)}. - */ - protected void parseLine(final String line) - throws GeneralSecurityException, IOException, Exceptions.UnknownInput { - assert this.ks != null; - - String path = line.substring(1); - String filename = path.substring(path.lastIndexOf("/") + 1); - String alias = "debian:" + filename; - if(line.startsWith("+")) { - Certificate cert = loadCertificate(path); - if (cert == null) { - return; - } - addAlias(alias, cert); - } - else if (line.startsWith("-")) { - deleteAlias(alias); - // Remove old non-prefixed aliases, too. This code should be - // removed after the release of Wheezy. - deleteAlias(filename); - } - else { - throw new Exceptions.UnknownInput(line); - } - } - - /** - * Delete cert in keystore at given alias. - */ - private void deleteAlias(final String alias) throws GeneralSecurityException { - assert this.ks != null; - - if (contains(alias)) { - System.out.println("Removing " + alias); - this.ks.deleteEntry(alias); - } - } - - /** - * Add or replace existing cert in keystore with given alias. - */ - private void addAlias(final String alias, final Certificate cert) - throws KeyStoreException { - assert this.ks != null; - - if(contains(alias)) { - System.out.println("Replacing " + alias); - this.ks.deleteEntry(alias); - } - else { - System.out.println("Adding " + alias); - } - this.ks.setCertificateEntry(alias, cert); - } - - /** - * Returns true when alias exist in keystore. - */ - protected boolean contains(String alias) throws KeyStoreException { - assert this.ks != null; - - return this.ks.containsAlias(alias); - } - - /** - * Try to load a certificate instance from given path. - */ - private Certificate loadCertificate(final String path) { - assert this.certFactory != null; - - Certificate cert = null; - try { - FileInputStream certFile = new FileInputStream(path); - cert = this.certFactory.generateCertificate(certFile); - certFile.close(); - } - catch (Exception e) { - System.err.println("Warning: there was a problem reading the certificate file " + - path + ". Message:\n " + e.getMessage()); - } - return cert; - } - - /** - * Write actual keystore content to disk. - */ - protected void writeKeyStore() throws GeneralSecurityException, Exceptions.UnableToSaveKeystore { - assert this.ks != null; - - try { - FileOutputStream certOutputFile = new FileOutputStream(this.ksFilename); - this.ks.store(certOutputFile, this.password); - certOutputFile.close(); - } - catch (IOException e) { - throw new Exceptions.UnableToSaveKeystore("There was a problem saving the new Java keystore.", e); - } - } -} diff -Nru ca-certificates-java-20130815ubuntu1/UpdateCertificatesTest.java ca-certificates-java-20140324/UpdateCertificatesTest.java --- ca-certificates-java-20130815ubuntu1/UpdateCertificatesTest.java 2014-03-20 12:21:47.000000000 +0000 +++ ca-certificates-java-20140324/UpdateCertificatesTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 Damien Raude-Morvan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -import java.io.File; -import java.io.IOException; -import java.security.GeneralSecurityException; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; - -/** - * Tests for {@link UpdateCertificates}. - * - * @author Damien Raude-Morvan - */ -public class UpdateCertificatesTest { - - private static final String ALIAS_CACERT = "debian:thawte_Primary_Root_CA_-_G3.crt"; - private static final String INVALID_CACERT = "x/usr/share/ca-certificates/mozilla/thawte_Primary_Root_CA_-_G3.crt"; - private static final String REMOVE_CACERT = "-/usr/share/ca-certificates/mozilla/thawte_Primary_Root_CA_-_G3.crt"; - private static final String ADD_CACERT = "+/usr/share/ca-certificates/mozilla/thawte_Primary_Root_CA_-_G3.crt"; - - private String ksFilename = null; - private String ksPassword = null; - - @Before - public void start() { - this.ksFilename = "./tests-cacerts"; - this.ksPassword = "changeit"; - // Delete any previous file - File keystore = new File(this.ksFilename); - keystore.delete(); - } - - /** - * Test a simple open then write without any modification. - */ - @Test - public void testNoop() throws IOException, GeneralSecurityException, - Exceptions.InvalidKeystorePassword, Exceptions.UnableToSaveKeystore { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.writeKeyStore(); - } - - /** - * Test a to open a keystore and write without any modification - * and then try to open it again with wrong password : will throw a - * InvalidKeystorePassword - */ - @Test - public void testWriteThenOpenWrongPwd() throws IOException, - GeneralSecurityException, Exceptions.UnableToSaveKeystore { - try { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.writeKeyStore(); - } catch (Exceptions.InvalidKeystorePassword e) { - Assert.fail(); - } - - try { - UpdateCertificates uc = new UpdateCertificates("wrongpassword", - this.ksFilename); - Assert.fail(); - uc.writeKeyStore(); - } catch (Exceptions.InvalidKeystorePassword e) { - Assert.assertEquals( - "Cannot open Java keystore. Is the password correct?", - e.getMessage()); - } - } - - /** - * Test a to open a keystore then remove its backing File (and replace it - * with a directory with the same name) and try to write in to disk : - * will throw an UnableToSaveKeystore - */ - @Test - public void testDeleteThenWrite() throws IOException, - GeneralSecurityException, Exceptions.InvalidKeystorePassword { - try { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - - // Replace actual file by a directory ! - File keystore = new File(this.ksFilename); - keystore.delete(); - keystore.mkdir(); - - // Will fail with some IOException - uc.writeKeyStore(); - Assert.fail(); - } catch (Exceptions.UnableToSaveKeystore e) { - Assert.assertEquals( - "There was a problem saving the new Java keystore.", - e.getMessage()); - } - } - - /** - * Try to send an invalid command ("x") in parseLine : throw UnknownInput - */ - @Test - public void testWrongCommand() throws IOException, - GeneralSecurityException, Exceptions.InvalidKeystorePassword { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - try { - uc.parseLine(INVALID_CACERT); - Assert.fail(); - } catch (Exceptions.UnknownInput e) { - Assert.assertEquals(INVALID_CACERT, e.getMessage()); - } - } - - /** - * Test to insert a valid certificate and then check if it's really in KS. - */ - @Test - public void testAdd() throws IOException, GeneralSecurityException, - Exceptions.UnknownInput, Exceptions.InvalidKeystorePassword, - Exceptions.UnableToSaveKeystore { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.parseLine(ADD_CACERT); - uc.writeKeyStore(); - - Assert.assertEquals(true, uc.contains(ALIAS_CACERT)); - } - - /** - * Test to insert a invalide certificate : no exception, but check there - * is no alias created with that name - */ - @Test - public void testAddInvalidCert() throws IOException, - GeneralSecurityException, Exceptions.UnknownInput, - Exceptions.InvalidKeystorePassword, Exceptions.UnableToSaveKeystore { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.parseLine("+/usr/share/ca-certificates/null.crt"); - uc.writeKeyStore(); - - Assert.assertEquals(false, uc.contains("debian:null.crt")); - } - - /** - * Try to add same certificate multiple time : we replace it and - * there is only one alias. - */ - @Test - public void testReplace() throws IOException, GeneralSecurityException, - Exceptions.UnknownInput, Exceptions.InvalidKeystorePassword, - Exceptions.UnableToSaveKeystore { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.parseLine(ADD_CACERT); - uc.parseLine(ADD_CACERT); - uc.writeKeyStore(); - - Assert.assertEquals(true, uc.contains(ALIAS_CACERT)); - } - - /** - * Try to remove a non-existant certificate : it's a no-op. - */ - @Test - public void testRemove() throws IOException, GeneralSecurityException, - Exceptions.UnknownInput, Exceptions.InvalidKeystorePassword, - Exceptions.UnableToSaveKeystore { - UpdateCertificates uc = new UpdateCertificates(this.ksPassword, - this.ksFilename); - uc.parseLine(REMOVE_CACERT); - uc.writeKeyStore(); - - // We start with empty KS, so it shouldn't do anything - Assert.assertEquals(false, uc.contains(ALIAS_CACERT)); - } - - /** - * Try to add cert, write to disk, then open keystore again and remove. - */ - @Test - public void testAddThenRemove() throws IOException, - GeneralSecurityException, Exceptions.UnknownInput, - Exceptions.InvalidKeystorePassword, Exceptions.UnableToSaveKeystore { - UpdateCertificates ucAdd = new UpdateCertificates(this.ksPassword, - this.ksFilename); - ucAdd.parseLine(ADD_CACERT); - ucAdd.writeKeyStore(); - - Assert.assertEquals(true, ucAdd.contains(ALIAS_CACERT)); - - UpdateCertificates ucRemove = new UpdateCertificates(this.ksPassword, - this.ksFilename); - ucRemove.parseLine(REMOVE_CACERT); - ucRemove.writeKeyStore(); - - Assert.assertEquals(false, ucRemove.contains(ALIAS_CACERT)); - } - -}