Check java.policy files
diff --git a/update/org.eclipse.update.core/Scrapbook.jpage b/update/org.eclipse.update.core/Scrapbook.jpage
index 791a48b..a5162de 100644
--- a/update/org.eclipse.update.core/Scrapbook.jpage
+++ b/update/org.eclipse.update.core/Scrapbook.jpage
@@ -62,6 +62,12 @@
 list.get(0)

 

 

+org.eclipse.update.internal.security.KeyStores k = new org.eclipse.update.internal.security.KeyStores();

+while (k.hasNext()){

+	org.eclipse.update.internal.security.KeystoreHandle handle = (org.eclipse.update.internal.security.KeystoreHandle) k.next();

+	System.out.println("KeyStore:"+handle.getLocation()+":"+handle.getType());

+}

+

 *****************************************

 OLD Feature Code

 

diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java
index 59d3d54..fc70bfb 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java
@@ -12,8 +12,9 @@
 import java.util.*;
 import java.util.jar.*;
 
-import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.*;
 import org.eclipse.update.internal.core.Policy;
+import org.eclipse.update.internal.core.UpdateManagerPlugin;
 
 /**
  * The JarVerifier will check the integrity of the JAR.
@@ -28,12 +29,14 @@
 	/**
 	 * Set of certificates of the JAR file
 	 */
-	private Collection /* of List of Certificate */certificateEntries;
+	private Collection /* of List of Certificate */
+	certificateEntries;
 
 	/**
 	 * List of certificates of the KeyStores
 	 */
-	private List  /* of List of Certificate */ listOfKeystoreCertifcates;
+	private List /* of List of KeystoreHandle */
+	listOfKeystoreHandles;
 
 	/**
 	 * check validity of keystore
@@ -42,10 +45,10 @@
 	private boolean shouldVerifyKeystore = false;
 
 	/**
-	 * check validity of keystore
+	 * Retrieve all keystore handles (reload keystores)
 	 * default == FALSE 
 	 */
-	private boolean shouldRetrieveKeystoreCertificates = false;
+	private boolean shouldRetrieveKeystoreHandles = false;
 
 	/**
 	 * Number of files in the JarFile
@@ -97,46 +100,45 @@
 	 * Can be optimize, within an operation, we only need to get the
 	 * list of certificate once.
 	 */
-	private List getKeyStoreCertificates() {
-		if (listOfKeystoreCertifcates == null || shouldRetrieveKeystoreCertificates) {
-			listOfKeystoreCertifcates = new ArrayList(0);
+	private List getKeyStores() throws CoreException {
+		if (listOfKeystoreHandles == null || shouldRetrieveKeystoreHandles) {
+			listOfKeystoreHandles = new ArrayList(0);
 			KeyStores listOfKeystores = new KeyStores();
 			InputStream in = null;
+			KeyStore keystore = null;
+			while (listOfKeystores.hasNext()) {
+				try {
+					KeystoreHandle handle = listOfKeystores.next();
+					keystore = KeyStore.getInstance(handle.getType());
+					in = handle.getLocation().openStream();
+					keystore.load(in, null); // no password
+				} catch (NoSuchAlgorithmException e) {
+					throw newCoreException("Unable to find encrption algorithm", e);
 
-			try {
-				KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
-				while (listOfKeystores.hasNext()) {
-					try {
-						in = listOfKeystores.next().openStream();
-						keystore.load(in, null); // no password
-					} catch (NoSuchAlgorithmException e) {
-					} catch (CertificateException e) {
-					} catch (IOException e) {
-						// open error message, the keystore is not valid
-					} finally {
-						if (in != null) {
-							try {
-								in.close();
-							} catch (IOException e) {
-							} // nothing
-						}
-					} // try loading a keyStore
-
-					// keystore was loaded
-					Enumeration enum = keystore.aliases();
-					if (enum != null) {
-						while (enum.hasMoreElements()) {
-							listOfKeystoreCertifcates.add(keystore.getCertificate((String) enum.nextElement()));
-						}
+				} catch (CertificateException e) {
+					throw newCoreException("Unable to load a certificate in the keystore", e);
+				} catch (IOException e) {
+					// open error message, the keystore is not valid
+					throw newCoreException("Unable to access keystore", e);
+				} catch (KeyStoreException e) {
+					throw newCoreException("Unable to find provider for the keystore type", e);
+				} finally {
+					if (in != null) {
+						try {
+							in.close();
+						} catch (IOException e) {
+						} // nothing
 					}
-				} // while all key stores
+				} // try loading a keyStore
 
-			} catch (KeyStoreException e) {
-				// cannot instanciate a default keystore...
-			}
+				// keystore was loaded
+				listOfKeystoreHandles.add(keystore);
+
+			} // while all key stores
+
 		}
 
-		return listOfKeystoreCertifcates;
+		return listOfKeystoreHandles;
 	}
 	/**
 	 */
@@ -148,7 +150,7 @@
 	 */
 	private void initializeVariables(File jarFile) throws IOException {
 		resultCode = UNKNOWN_ERROR;
-		resultException = new Exception(Policy.bind("JarVerifier.InvalidJarFile",jarFile.getAbsolutePath())); //$NON-NLS-1$
+		resultException = new Exception(Policy.bind("JarVerifier.InvalidJarFile", jarFile.getAbsolutePath())); //$NON-NLS-1$
 		JarFile jar = new JarFile(jarFile);
 		entries = jar.size();
 		try {
@@ -160,15 +162,26 @@
 		certificateEntries = new HashSet();
 	}
 	/**
-	 * Returns true if the 2 collections
-	 * have an intersection
+	 * Returns true if one of the certificate exists in the keystore
 	 */
-	private boolean intersect(Collection c1, Collection c2) {
-		Iterator e = c1.iterator();
-		while (e.hasNext())
-			if (c2.contains(e.next()))
-				return true;
-
+	private boolean existsInKeystore(Collection certs) throws CoreException {
+		try {
+			Iterator listOfCerts = certs.iterator();
+			while (listOfCerts.hasNext()) {
+				List keyStores = getKeyStores();
+				if (!keyStores.isEmpty()) {
+					Iterator listOfKeystores = keyStores.iterator();
+					while (listOfKeystores.hasNext()) {
+						KeyStore keystore = (KeyStore) listOfKeystores.next();
+						Certificate cert = (Certificate) listOfCerts.next();
+						if (keystore.getCertificateAlias(cert) != null)
+							return true;
+					}
+				}
+			}
+		} catch (KeyStoreException e) {
+			throw newCoreException("KeyStore not loaded", e);
+		}
 		return false;
 	}
 	/**
@@ -177,28 +190,26 @@
 	private List readJarFile(final JarInputStream jis) throws IOException, InterruptedException, InvocationTargetException {
 		final List list = new ArrayList(0);
 
-				byte[] buffer = new byte[4096];
-				JarEntry ent;
+		byte[] buffer = new byte[4096];
+		JarEntry ent;
+		if (monitor != null)
+			monitor.beginTask(Policy.bind("JarVerifier.Verify", jarFileName), entries); //$NON-NLS-1$ //$NON-NLS-2$
+		try {
+			while ((ent = jis.getNextJarEntry()) != null) {
+				list.add(ent);
 				if (monitor != null)
-					monitor.beginTask(Policy.bind("JarVerifier.Verify", jarFileName), entries); //$NON-NLS-1$ //$NON-NLS-2$
-				try {
-					while ((ent = jis.getNextJarEntry()) != null) {
-						list.add(ent);
-						if (monitor != null)
-							monitor.worked(1);
-						while ((jis.read(buffer, 0, buffer.length)) != -1) {
-							// Security error thrown if tempered
-						}
-					}
+					monitor.worked(1);
+				while ((jis.read(buffer, 0, buffer.length)) != -1) {
+					// Security error thrown if tempered
 				}
-				catch (IOException e) {
-					resultCode = UNKNOWN_ERROR;
-					resultException = e;
-				}
-				finally {
-					if (monitor != null)
-						monitor.done();
-				}
+			}
+		} catch (IOException e) {
+			resultCode = UNKNOWN_ERROR;
+			resultException = e;
+		} finally {
+			if (monitor != null)
+				monitor.done();
+		}
 		return list;
 	}
 	/**
@@ -211,8 +222,8 @@
 	/**
 	 * 
 	 */
-	public void shouldRetrieveCertificate(boolean value) {
-		shouldRetrieveKeystoreCertificates = value;
+	public void shouldRetrieveHandles(boolean value) {
+		shouldRetrieveKeystoreHandles = value;
 	}
 	/**
 	 * 
@@ -270,26 +281,21 @@
 	 * At least one certificate from each Certificate Array
 	 * of the Jar file must be found in the known Certificates
 	 */
-	private void verifyAuthentication() {
+	private void verifyAuthentication() throws CoreException {
 
-		List keyStoreCertificates = getKeyStoreCertificates();
-		if (!keyStoreCertificates.isEmpty()) {
-			Iterator entries = certificateEntries.iterator();
-			boolean certificateFound = true;
+		Iterator entries = certificateEntries.iterator();
+		boolean certificateFound = false;
 
-			// If all the cartificate of an entry are
-			// not found in the list of known certifcate
-			// we exit the loop.
-			while (entries.hasNext() && certificateFound) {
-				List certs = (List) entries.next();
-				certificateFound = intersect(keyStoreCertificates, certs);
-			}
-			
-			if (certificateFound)
-				resultCode = SOURCE_VERIFIED;
-			 else installCertificates(certificateEntries);
+		// If all the cartificate of an entry are
+		// not found in the list of known certifcate
+		// we exit the loop.
+		while (entries.hasNext() && !certificateFound) {
+			List certs = (List) entries.next();
+			certificateFound = existsInKeystore(certs);
 		}
 
+		if (certificateFound)
+			resultCode = SOURCE_VERIFIED;
 	}
 	/**
 	 * Verifies the integrity of the JAR
@@ -347,15 +353,20 @@
 	private boolean verifyIntegrityOfKeyStore() {
 		return shouldVerifyKeystore;
 	}
-	
+
 	/**
 	 * 
 	 */
-	private void installCertificates(Collection certificates){
-		// each item in the collection is a List of certificates
+	public void installCertificates() {
+		Iterator entries = certificateEntries.iterator();
+		// each item in the iterator is a List of certificates
 		// a JAR can be signed using different certificates,
 		// and each Certificate can be a chained certificate
+		//  which one do we install ?
+
+		
 	}
+	
 	/**
 	 * Gets the certificateEntries.
 	 * @return Returns a Collection
@@ -364,5 +375,12 @@
 		return certificateEntries;
 	}
 
-	
+	/**
+	 * 
+	 */
+	private CoreException newCoreException(String s, Throwable e) throws CoreException {
+		String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
+		return new CoreException(new Status(IStatus.ERROR, id, 0, s, e));
+	}
+
 }
\ No newline at end of file
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java
index 51a67d1..7157d51 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java
@@ -4,7 +4,11 @@
  * All Rights Reserved.
  */
 
-import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.io.*;
+import java.io.File;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
+import java.security.Security;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 /**
  * Class to manage the different KeyStores we should
  * check for certificates of Signed JAR
@@ -14,18 +18,23 @@
 	/**
 	 * true if check default and user keystore at each startup
 	 */
-	public static boolean ALWAYS_INITIALIZE = true;
+	private  static boolean ALWAYS_INITIALIZE = true;
 
 	/**
 	 * java.policy files properties of the java.security file
 	 */
-	public static final String JAVA_POLICY = "policy.url"; //$NON-NLS-1$
+	private static final String JAVA_POLICY_URL = "policy.url."; //$NON-NLS-1$
 
 	/**
-	 * List of URL pointing of valid KeyStores
-	 * the URL is not tested yet...
+	 * Default keystore type in java.security file
+	 */	
+    private static final String DEFAULT_KEYSTORE_TYPE = "keystore.type";
+
+	/**
+	 * List of KeystoreHandle pointing of valid KeyStores
+	 * the URL of the KeystoreHandle is not tested yet...
 	 */
-	private List listOfKeyStores;
+	private List /* of KeystoreHandle */ listOfKeyStores;
 
 	/**
 	 * Iterator
@@ -72,7 +81,8 @@
 
 		// get JRE cacerts
 		try {
-			listOfKeyStores.add(new URL("file", null, 0, System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+			URL url = new URL("file", null, 0, System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+			listOfKeyStores.add(new KeystoreHandle(url,Security.getProperty(DEFAULT_KEYSTORE_TYPE)));
 		}
 		catch (MalformedURLException e) {
 			// should not happen, hardcoded...
@@ -80,21 +90,33 @@
 
 		// get java.home .keystore
 		try {
-			listOfKeyStores.add(new URL("file", null, 0, System.getProperty("user.home") + File.separator + ".keystore")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			URL url = new URL("file", null, 0, System.getProperty("user.home") + File.separator + ".keystore"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			listOfKeyStores.add(new KeystoreHandle(url,Security.getProperty(DEFAULT_KEYSTORE_TYPE)));
 		}
 		catch (MalformedURLException e) {
 			// should not happen, hardcoded...
 		}
 
 		// get KeyStores from policy files...
-		//Security.getProperty(JAVA_POLICY);
+		int index = 1;
+		String java_policy = Security.getProperty(JAVA_POLICY_URL+index);
+		while (java_policy!=null){
+			// retrieve keystore url from java.policy
+			// also retrieve keystore type
+			KeystoreHandle keystore = getKeystoreFromLocation(java_policy);
+			if (keystore!=null){
+				listOfKeyStores.add(keystore);
+			}
+			index++;	
+			java_policy = Security.getProperty(JAVA_POLICY_URL+index);			
+		}
 
 	}
 	/**
-	 * returns the URL for the Next Keystore
+	 * returns the URL for the Next KeystoreHandle
 	 */
-	public URL next() {
-		return (URL) getIterator().next();
+	public KeystoreHandle next() {
+		return (KeystoreHandle) getIterator().next();
 	}
 	/**
 	 * populate the list of Keystores from the previously saved list
@@ -104,4 +126,94 @@
 	private void readKeystoresFromPersistent() {
 		// not implemented
 	}
+	
+	/**
+	 * retrieve the keystore from java.policy file
+	 */
+	private KeystoreHandle getKeystoreFromLocation(String location){
+		
+		InputStream in = null;
+		char[] buff = new char[4096];
+		
+		
+		int indexOf$ = location.indexOf("${");
+		int indexOfCurly = location.indexOf('}',indexOf$);
+		if (indexOf$!=-1 && indexOfCurly!=-1){
+			String prop = System.getProperty(location.substring(indexOf$+2,indexOfCurly));
+			String location2 = location.substring(0,indexOf$);
+			location2 += prop;
+			location2 += location.substring(indexOfCurly+1);
+			location = location2;
+		}
+		
+		
+		try {
+			URL url = new URL(location);
+			in = url.openStream();
+			Reader reader = new InputStreamReader(in);
+			int result = reader.read(buff);
+			StringBuffer contentBuff = new StringBuffer();
+			while (result!=-1){
+				contentBuff.append(buff,0,result);
+				result = reader.read(buff);				
+			}
+
+			if (contentBuff.length()>0){			
+				String content = new String(contentBuff);
+				int indexOfKeystore = content.indexOf("keystore");
+				if (indexOfKeystore != -1){
+					int indexOfSemiColumn = content.indexOf(';',indexOfKeystore);
+					return getKeystoreFromString(content.substring(indexOfKeystore,indexOfSemiColumn),url);
+				}
+			}
+		} catch (MalformedURLException e){
+			// FIXME log
+			e.printStackTrace();
+		} catch (IOException e){
+			// url.openStream, reader.read (x2)
+			// log
+			// the keystore may not exist
+		} finally {
+			try { in.close();} catch (Exception e){}
+		}
+		return null;
+	}
+	
+	/**
+	 * retrieve the keystore from java.policy file
+	 */
+	private KeystoreHandle getKeystoreFromString(String content,URL rootURL){
+		KeystoreHandle handle = null;
+		String keyStoreType = DEFAULT_KEYSTORE_TYPE;
+		
+		
+		int indexOfSpace = content.indexOf(' ');
+		if (indexOfSpace==-1) return null;
+		
+		int secondSpace = content.lastIndexOf(',');
+		if (secondSpace==-1) {
+			secondSpace = content.length();
+		} else {
+			keyStoreType = content.substring(secondSpace+1,content.length()).trim();
+		}
+		
+		URL url = null;
+		try {
+			url = new URL(content.substring(indexOfSpace,secondSpace));
+		} catch (MalformedURLException e){
+			//FIXME log
+			// the url maybe relative
+			try {
+			url = new URL(rootURL,content.substring(indexOfSpace,secondSpace));				
+			} catch (MalformedURLException e1){
+				// FIXME log
+				e1.printStackTrace();				
+			}
+		}
+
+		if (url!=null)
+			handle = new KeystoreHandle(url,keyStoreType);				
+			
+		return handle;
+	}	
 }
\ No newline at end of file
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java
new file mode 100644
index 0000000..117c554
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java
@@ -0,0 +1,56 @@
+package org.eclipse.update.internal.security;
+
+import java.net.URL;
+
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+ 
+/**
+ * Manages a handle to a keystore
+ */
+public class KeystoreHandle {
+	
+	private URL location;
+	private String type;
+	
+	public KeystoreHandle(URL url, String type){
+		this.location = url;
+		this.type = type;
+	}
+
+	/**
+	 * Gets the location.
+	 * @return Returns a URL
+	 */
+	public URL getLocation() {
+		return location;
+	}
+
+	/**
+	 * Sets the location.
+	 * @param location The location to set
+	 */
+	public void setLocation(URL location) {
+		this.location = location;
+	}
+
+	/**
+	 * Gets the type.
+	 * @return Returns a String
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * Sets the type.
+	 * @param type The type to set
+	 */
+	public void setType(String type) {
+		this.type = type;
+	}
+
+}