diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java index 0dbb56e..b22bfb1 100644 --- a/src/main/java/com/threerings/getdown/data/Application.java +++ b/src/main/java/com/threerings/getdown/data/Application.java @@ -188,7 +188,7 @@ public class Application * @param appargs additional arguments to pass on to launched application; these will be added * after the args in the getdown.txt file. */ - public Application (File appdir, String appid, Object[] signers, + public Application (File appdir, String appid, List signers, String[] jvmargs, String[] appargs) { _appdir = appdir; @@ -1272,7 +1272,7 @@ public class Application File target = downloadFile(path); if (validateSignature) { - if (_signers == null) { + if (_signers.isEmpty()) { log.info("No signers, not verifying file", "path", path); } else { @@ -1289,12 +1289,7 @@ public class Application byte[] buffer = new byte[8192]; int length, validated = 0; - for (Object signer : _signers) { - if (!(signer instanceof Certificate)) { - continue; - } - - Certificate cert = (Certificate)signer; + for (Certificate cert : _signers) { FileInputStream dataInput = null; try { dataInput = new FileInputStream(target); @@ -1526,7 +1521,7 @@ public class Application protected String[] _extraJvmArgs; protected String[] _extraAppArgs; - protected Object[] _signers; + protected List _signers; /** If a warning has been issued about not being able to set modtimes. */ protected boolean _warnedAboutSetLastModified; diff --git a/src/main/java/com/threerings/getdown/launcher/Getdown.java b/src/main/java/com/threerings/getdown/launcher/Getdown.java index 8efe7a8..586c99a 100644 --- a/src/main/java/com/threerings/getdown/launcher/Getdown.java +++ b/src/main/java/com/threerings/getdown/launcher/Getdown.java @@ -25,8 +25,6 @@ package com.threerings.getdown.launcher; -import java.util.Locale; - import java.awt.BorderLayout; import java.awt.Container; import java.awt.EventQueue; @@ -50,11 +48,14 @@ import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.security.cert.Certificate; + import java.util.ArrayList; import java.util.HashSet; -import java.util.Map; import java.util.Iterator; import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; import java.util.Set; @@ -95,7 +96,8 @@ public abstract class Getdown extends Thread this(appDir, appId, null, null, null); } - public Getdown (File appDir, String appId, Object[] signers, String[] jvmargs, String[] appargs) + public Getdown (File appDir, String appId, List signers, + String[] jvmargs, String[] appargs) { super("Getdown"); try { diff --git a/src/main/java/com/threerings/getdown/launcher/GetdownApplet.java b/src/main/java/com/threerings/getdown/launcher/GetdownApplet.java index a9da88c..7ab498c 100644 --- a/src/main/java/com/threerings/getdown/launcher/GetdownApplet.java +++ b/src/main/java/com/threerings/getdown/launcher/GetdownApplet.java @@ -30,9 +30,17 @@ import java.awt.Image; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; + import javax.swing.JApplet; import javax.swing.JPanel; @@ -58,10 +66,21 @@ public class GetdownApplet extends JApplet _errmsg = e.getMessage(); } - // XXX getSigners() returns all certificates used to sign this applet which may allow - // a third party to insert a trusted certificate. This should be replaced with - // statically included trusted keys. - _getdown = new Getdown(_config.appdir, null, GetdownApplet.class.getSigners(), + List signers = new ArrayList(); + Certificate cert = loadCertificate("resource.crt"); + if (cert != null) { + signers.add(cert); + } else { + // getSigners() returns all certificates used to sign this applet which may allow a + // third party to insert a trusted certificate. This should be avoided. + log.warning("No resource certificate found, falling back to class signers"); + for (Object signer : GetdownApplet.class.getSigners()) { + if (signer instanceof Certificate) { + signers.add((Certificate)signer); + } + } + } + _getdown = new Getdown(_config.appdir, null, signers, _config.jvmargs, _config.appargs) { @Override protected Container createContainer () { @@ -160,6 +179,26 @@ public class GetdownApplet extends JApplet } } + protected static Certificate loadCertificate (String path) + { + try { + URL keyUrl = GetdownApplet.class.getClassLoader().getResource(path); + if (keyUrl == null) { + return null; + } + InputStream is = keyUrl.openStream(); + try { + return CertificateFactory.getInstance("X.509").generateCertificate(is); + } finally { + is.close(); + } + } catch (CertificateException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** The Getdown configuration as pulled from the applet params */ protected GetdownAppletConfig _config;