Add the ability to specify keystores with trustedCaCerts to main and
subsequently, pass it to the framework in order to enable digitally
signed bundles (FELIX-22).
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@434387 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/main/src/main/java/org/apache/felix/main/Main.java b/main/src/main/java/org/apache/felix/main/Main.java
index cb03a8f..4aeee72 100644
--- a/main/src/main/java/org/apache/felix/main/Main.java
+++ b/main/src/main/java/org/apache/felix/main/Main.java
@@ -19,6 +19,7 @@
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.*;
import java.util.*;
import org.apache.felix.framework.Felix;
@@ -58,6 +59,21 @@
**/
public static final String CONFIG_PROPERTIES_FILE_VALUE = "config.properties";
+ public static final String KEYSTORE_FILE_PROP = "felix.keystore";
+
+ public static final String KEYSTORE_FILE_VALUE = System.getProperty("java.home") +
+ File.separatorChar + "lib" + File.separatorChar + "security" +
+ File.separatorChar + "cacerts" + File.pathSeparatorChar + System.getProperty("user.home") +
+ File.separatorChar + ".keystore";
+
+ public static final String KEYSTORE_TYPE_PROP = "felix.keystore.type";
+
+ public static final String KEYSTORE_TYPE_VALUE = "JKS" + File.pathSeparatorChar + "JKS";
+
+ public static final String KEYSTORE_PASS_PROP = "felix.keystore.pass";
+
+ public static final String KEYSTORE_PASS_VALUE = "changeit" + File.pathSeparatorChar + "changeit";
+
private static Felix m_felix = null;
/**
@@ -189,7 +205,7 @@
m_felix = new Felix();
m_felix.start(
new MutablePropertyResolverImpl(new StringMap(configProps, false)),
- null);
+ null, (System.getSecurityManager() == null) ? null : new TrustManager(configProps));
}
catch (Exception ex)
{
@@ -451,10 +467,10 @@
{
cycleMap = new HashMap();
}
-
+
// Put the current key in the cycle map.
cycleMap.put(currentKey, currentKey);
-
+
// Assume we have a value that is something like:
// "leading ${foo.${bar}} middle ${baz} trailing"
@@ -540,4 +556,119 @@
// Return the value.
return val;
}
+
+ private static class TrustManager extends AbstractCollection
+ {
+ private String[] m_keystores = null;
+ private String[] m_passwds = null;
+ private String[] m_types = null;
+ private ArrayList m_stores = null;
+
+ TrustManager(Properties config)
+ {
+ StringTokenizer tok = new StringTokenizer(System.getProperty(KEYSTORE_FILE_PROP,
+ config.getProperty(KEYSTORE_FILE_PROP, KEYSTORE_FILE_VALUE)), File.pathSeparator);
+
+ m_keystores = new String[tok.countTokens()];
+
+ for (int i = 0;tok.hasMoreTokens();i++)
+ {
+ m_keystores[i] = tok.nextToken();
+ }
+
+ tok = new StringTokenizer(System.getProperty(KEYSTORE_PASS_PROP,
+ config.getProperty(KEYSTORE_PASS_PROP, KEYSTORE_PASS_VALUE)), File.pathSeparator);
+
+ m_passwds = new String[tok.countTokens()];
+
+ for (int i = 0;tok.hasMoreTokens();i++)
+ {
+ m_passwds[i] = tok.nextToken();
+ }
+
+ tok = new StringTokenizer(System.getProperty(KEYSTORE_TYPE_PROP,
+ config.getProperty(KEYSTORE_TYPE_PROP, KEYSTORE_TYPE_VALUE)), File.pathSeparator);
+
+ m_types = new String[tok.countTokens()];
+
+ for (int i = 0;tok.hasMoreTokens();i++)
+ {
+ m_types[i] = tok.nextToken();
+ }
+ }
+
+ public synchronized Iterator iterator()
+ {
+ if (m_stores == null)
+ {
+ loadStores();
+ }
+
+ return m_stores.iterator();
+ }
+
+ public synchronized int size()
+ {
+ if (m_stores == null)
+ {
+ loadStores();
+ }
+
+ return m_stores.size();
+ }
+
+ private void loadStores()
+ {
+ m_stores = new ArrayList();
+
+ if ((m_keystores.length == m_passwds.length) && (m_passwds.length == m_types.length)
+ && (System.getSecurityManager() != null))
+ {
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ List certs = new ArrayList();
+
+ for (int i = 0;i < m_keystores.length;i++)
+ {
+
+ try
+ {
+ KeyStore ks = KeyStore.getInstance(m_types[i]);
+ ks.load(new FileInputStream(m_keystores[i]), m_passwds[i].toCharArray());
+ for (Enumeration enum = ks.aliases();enum.hasMoreElements();)
+ {
+ String alias = (String) enum.nextElement();
+ if (ks.isCertificateEntry(alias))
+ {
+ certs.add(ks.getCertificate(alias));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ certs.clear();
+ ex.printStackTrace(System.err);
+
+ System.err.println("WARNING: Error accessing keystore: " + m_keystores[i]);
+ }
+
+ if (!certs.isEmpty())
+ {
+ m_stores.addAll(certs);
+ certs.clear();
+ }
+ }
+
+ return null;
+ }
+ });
+ }
+ if (m_stores.isEmpty())
+ {
+ System.err.println("WARNING: No trusted CA certificates!");
+ }
+ }
+ }
}
\ No newline at end of file