/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.update.internal.security; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.security.Security; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.update.internal.core.UpdateCore; import org.eclipse.update.internal.core.connection.ConnectionFactory; /** * Class to manage the different KeyStores we should * check for certificates of Signed JAR */ public class KeyStores { /** * java.policy files properties of the java.security file */ private static final String JAVA_POLICY_URL = "policy.url."; //$NON-NLS-1$ /** * Default keystore type in java.security file */ private static final String DEFAULT_KEYSTORE_TYPE = "keystore.type"; //$NON-NLS-1$ /** * List of KeystoreHandle pointing of valid KeyStores * the URL of the KeystoreHandle is not tested yet... */ private List /* of KeystoreHandle */ listOfKeyStores; /** * Iterator */ private Iterator iterator; /** * KeyStores constructor comment. */ public KeyStores() { super(); initializeDefaultKeyStores(); } /** * */ private Iterator getIterator() { if (iterator == null) iterator = listOfKeyStores.iterator(); return iterator; } /** * returns trus if there is more Keystores in the list */ public boolean hasNext() { return getIterator().hasNext(); } /** * populate the list of Keystores * should be done with Dialog with Cancel/Skip button if * the connection to the URL is down... */ private void initializeDefaultKeyStores() { listOfKeyStores = new ArrayList(5); // get JRE cacerts try { 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... } // get java.home .keystore try { 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... 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 KeystoreHandle */ public KeystoreHandle next() { return (KeystoreHandle) getIterator().next(); } /** * retrieve the keystore from java.policy file */ private KeystoreHandle getKeystoreFromLocation(String location){ InputStream in = null; char[] buff = new char[4096]; int indexOf$ = location.indexOf("${"); //$NON-NLS-1$ 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 = ConnectionFactory.get(url).getInputStream(); 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"); //$NON-NLS-1$ if (indexOfKeystore != -1){ int indexOfSemiColumn = content.indexOf(';',indexOfKeystore); return getKeystoreFromString(content.substring(indexOfKeystore,indexOfSemiColumn),url); } } } catch (MalformedURLException e){ log(e); } catch (IOException e){ // url.openStream, reader.read (x2) // only log, the keystore may not exist log(e); } finally { if (in!=null){ try { in.close(); } catch (IOException e){} } } return null; } /** * retrieve the keystore from java.policy file */ private KeystoreHandle getKeystoreFromString(String content,URL rootURL){ KeystoreHandle handle = null; String keyStoreType = Security.getProperty(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){ log(e); // the url maybe relative try { url = new URL(rootURL,content.substring(indexOfSpace,secondSpace)); } catch (MalformedURLException e1){ log(e1); } } if (url!=null) handle = new KeystoreHandle(url,keyStoreType); return handle; } private void log(Exception e){ UpdateCore.warn("Cannot retrieve a KeyStore",e); //$NON-NLS-1$ } }