aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/security/KeyStores.java
diff options
context:
space:
mode:
Diffstat (limited to 'netx/net/sourceforge/jnlp/security/KeyStores.java')
-rw-r--r--netx/net/sourceforge/jnlp/security/KeyStores.java337
1 files changed, 337 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/security/KeyStores.java b/netx/net/sourceforge/jnlp/security/KeyStores.java
new file mode 100644
index 0000000..4c7a60a
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/KeyStores.java
@@ -0,0 +1,337 @@
+/* KeyStores.java
+ Copyright (C) 2010 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea 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, version 2.
+
+IcedTea 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 IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.Translator;
+
+/**
+ * The <code>KeyStores</code> class allows easily accessing the various KeyStores
+ * used.
+ */
+public final class KeyStores {
+
+ /* this gets turned into user-readable strings, see toUserReadableString */
+
+ public enum Level {
+ USER,
+ SYSTEM,
+ }
+
+ public enum Type {
+ CERTS,
+ JSSE_CERTS,
+ CA_CERTS,
+ JSSE_CA_CERTS,
+ CLIENT_CERTS,
+ }
+
+ private static final String KEYSTORE_TYPE = "JKS";
+ /** the default password used to protect the KeyStores */
+ private static final String DEFAULT_PASSWORD = "changeit";
+
+ public static final char[] getPassword() {
+ return DEFAULT_PASSWORD.toCharArray();
+ }
+
+ /**
+ * Returns a KeyStore corresponding to the appropriate level level (user or
+ * system) and type.
+ *
+ * @param level whether the KeyStore desired is a user-level or system-level
+ * KeyStore
+ * @param type the type of KeyStore desired
+ * @return a KeyStore containing certificates from the appropriate
+ */
+ public static final KeyStore getKeyStore(Level level, Type type) {
+ boolean create = false;
+ if (level == Level.USER) {
+ create = true;
+ } else {
+ create = false;
+ }
+ return getKeyStore(level, type, create);
+ }
+
+ /**
+ * Returns a KeyStore corresponding to the appropriate level level (user or
+ * system) and type.
+ *
+ * @param level whether the KeyStore desired is a user-level or system-level
+ * KeyStore
+ * @param type the type of KeyStore desired
+ * @return a KeyStore containing certificates from the appropriate
+ */
+ public static final KeyStore getKeyStore(Level level, Type type, boolean create) {
+ String location = getKeyStoreLocation(level, type);
+ KeyStore ks = null;
+ try {
+ ks = createKeyStoreFromFile(new File(location), create, DEFAULT_PASSWORD);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return ks;
+ }
+
+ /**
+ * Returns an array of KeyStore that contain certificates that are trusted.
+ * The KeyStores contain certificates from different sources.
+ *
+ * @return an array of KeyStore containing trusted Certificates
+ */
+ public static final KeyStore[] getCertKeyStores() {
+ List<KeyStore> result = new ArrayList<KeyStore>(10);
+ KeyStore ks = null;
+
+ /* System-level JSSE certificates */
+ ks = getKeyStore(Level.SYSTEM, Type.JSSE_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* System-level certificates */
+ ks = getKeyStore(Level.SYSTEM, Type.CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* User-level JSSE certificates */
+ ks = getKeyStore(Level.USER, Type.JSSE_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* User-level certificates */
+ ks = getKeyStore(Level.USER, Type.CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+
+ return result.toArray(new KeyStore[result.size()]);
+ }
+
+ /**
+ * Returns an array of KeyStore that contain trusted CA certificates.
+ *
+ * @return an array of KeyStore containing trusted CA certificates
+ */
+ public static final KeyStore[] getCAKeyStores() {
+ List<KeyStore> result = new ArrayList<KeyStore>(10);
+ KeyStore ks = null;
+
+ /* System-level JSSE CA certificates */
+ ks = getKeyStore(Level.SYSTEM, Type.JSSE_CA_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* System-level CA certificates */
+ ks = getKeyStore(Level.SYSTEM, Type.CA_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* User-level JSSE CA certificates */
+ ks = getKeyStore(Level.USER, Type.JSSE_CA_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+ /* User-level CA certificates */
+ ks = getKeyStore(Level.USER, Type.CA_CERTS);
+ if (ks != null) {
+ result.add(ks);
+ }
+
+ return result.toArray(new KeyStore[result.size()]);
+ }
+
+ /**
+ * Returns the location of a KeyStore corresponding to the given level and type.
+ * @param level
+ * @param type
+ * @return
+ */
+ public static final String getKeyStoreLocation(Level level, Type type) {
+ String configKey = null;
+ switch (level) {
+ case SYSTEM:
+ switch (type) {
+ case JSSE_CA_CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_JSSE_CA_CERTS;
+ break;
+ case CA_CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CA_CERTS;
+ break;
+ case JSSE_CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_JSSE_CERTS;
+ break;
+ case CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CERTS;
+ break;
+ case CLIENT_CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CLIENT_CERTS;
+ break;
+ }
+ break;
+ case USER:
+ switch (type) {
+ case JSSE_CA_CERTS:
+ configKey = DeploymentConfiguration.KEY_USER_TRUSTED_JSSE_CA_CERTS;
+ break;
+ case CA_CERTS:
+ configKey = DeploymentConfiguration.KEY_USER_TRUSTED_CA_CERTS;
+ break;
+ case JSSE_CERTS:
+ configKey = DeploymentConfiguration.KEY_USER_TRUSTED_JSSE_CERTS;
+ break;
+ case CERTS:
+ configKey = DeploymentConfiguration.KEY_USER_TRUSTED_CERTS;
+ break;
+ case CLIENT_CERTS:
+ configKey = DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CLIENT_CERTS;
+ break;
+ }
+ break;
+ }
+
+ if (configKey == null) {
+ throw new RuntimeException("Unspported");
+ }
+
+ return JNLPRuntime.getConfiguration().getProperty(configKey);
+ }
+
+ /**
+ * Returns a String that can be used as a translation key to create a
+ * user-visible representation of this KeyStore. Creates a string by
+ * concatenating a level and type, converting everything to Title Case and
+ * removing the _'s. (USER,CA_CERTS) becomes UserCaCerts.
+ *
+ * @param level
+ * @param type
+ * @return
+ */
+ public static final String toTranslatableString(Level level, Type type) {
+ StringBuilder response = new StringBuilder();
+
+ if (level != null) {
+ String levelString = level.toString();
+ response.append(levelString.substring(0, 1).toUpperCase());
+ response.append(levelString.substring(1).toLowerCase());
+ }
+
+ if (type != null) {
+ String typeString = type.toString();
+ StringTokenizer tokenizer = new StringTokenizer(typeString, "_");
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ response.append(token.substring(0, 1).toUpperCase());
+ response.append(token.substring(1).toLowerCase());
+ }
+ }
+
+ return response.toString();
+ }
+
+ /**
+ * Returns a human readable name for this KeyStore
+ *
+ * @param level the level of the KeyStore
+ * @param type the type of KeyStore
+ * @return a localized name for this KeyStore
+ */
+ public static String toDisplayableString(Level level, Type type) {
+ return Translator.R(toTranslatableString(level, type));
+ }
+
+ /**
+ * Reads the file (using the password) and uses it to create a new
+ * {@link KeyStore}. If the file does not exist and should not be created,
+ * it returns an empty but initialized KeyStore
+ *
+ * @param file the file to load information from
+ * @param password the password to unlock the KeyStore file.
+ * @return a KeyStore containing data from the file
+ */
+ private static final KeyStore createKeyStoreFromFile(File file, boolean createIfNotFound,
+ String password) throws IOException, KeyStoreException, NoSuchAlgorithmException,
+ CertificateException {
+ FileInputStream fis = null;
+ KeyStore ks = null;
+
+ try {
+ if (createIfNotFound && !file.exists()) {
+ File parent = file.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("unable to create " + parent);
+ }
+ ks = KeyStore.getInstance(KEYSTORE_TYPE);
+ ks.load(null, password.toCharArray());
+ FileOutputStream fos = new FileOutputStream(file);
+ ks.store(fos, password.toCharArray());
+ fos.close();
+ }
+
+ // TODO catch exception when password is incorrect and prompt user
+
+ if (file.exists()) {
+ fis = new FileInputStream(file);
+ ks = KeyStore.getInstance(KEYSTORE_TYPE);
+ ks.load(fis, password.toCharArray());
+ } else {
+ ks = KeyStore.getInstance(KEYSTORE_TYPE);
+ ks.load(null, password.toCharArray());
+ }
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
+ }
+
+ return ks;
+ }
+
+}