Added support from Elias Naur for loading a bundled signing certificate instead

of using the signers on the jar file. Also tidied up the code that passes
certificates around so that we get rid of that wonderful Object[] as early as
possible.
This commit is contained in:
Michael Bayne
2011-07-26 17:17:54 +00:00
parent 84ebe33396
commit f7fa27884e
3 changed files with 53 additions and 17 deletions
@@ -188,7 +188,7 @@ public class Application
* @param appargs additional arguments to pass on to launched application; these will be added * @param appargs additional arguments to pass on to launched application; these will be added
* after the args in the getdown.txt file. * after the args in the getdown.txt file.
*/ */
public Application (File appdir, String appid, Object[] signers, public Application (File appdir, String appid, List<Certificate> signers,
String[] jvmargs, String[] appargs) String[] jvmargs, String[] appargs)
{ {
_appdir = appdir; _appdir = appdir;
@@ -1272,7 +1272,7 @@ public class Application
File target = downloadFile(path); File target = downloadFile(path);
if (validateSignature) { if (validateSignature) {
if (_signers == null) { if (_signers.isEmpty()) {
log.info("No signers, not verifying file", "path", path); log.info("No signers, not verifying file", "path", path);
} else { } else {
@@ -1289,12 +1289,7 @@ public class Application
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
int length, validated = 0; int length, validated = 0;
for (Object signer : _signers) { for (Certificate cert : _signers) {
if (!(signer instanceof Certificate)) {
continue;
}
Certificate cert = (Certificate)signer;
FileInputStream dataInput = null; FileInputStream dataInput = null;
try { try {
dataInput = new FileInputStream(target); dataInput = new FileInputStream(target);
@@ -1526,7 +1521,7 @@ public class Application
protected String[] _extraJvmArgs; protected String[] _extraJvmArgs;
protected String[] _extraAppArgs; protected String[] _extraAppArgs;
protected Object[] _signers; protected List<Certificate> _signers;
/** If a warning has been issued about not being able to set modtimes. */ /** If a warning has been issued about not being able to set modtimes. */
protected boolean _warnedAboutSetLastModified; protected boolean _warnedAboutSetLastModified;
@@ -25,8 +25,6 @@
package com.threerings.getdown.launcher; package com.threerings.getdown.launcher;
import java.util.Locale;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Container; import java.awt.Container;
import java.awt.EventQueue; import java.awt.EventQueue;
@@ -50,11 +48,14 @@ import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.cert.Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
@@ -95,7 +96,8 @@ public abstract class Getdown extends Thread
this(appDir, appId, null, null, null); 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<Certificate> signers,
String[] jvmargs, String[] appargs)
{ {
super("Getdown"); super("Getdown");
try { try {
@@ -30,9 +30,17 @@ import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; 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.JApplet;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -58,10 +66,21 @@ public class GetdownApplet extends JApplet
_errmsg = e.getMessage(); _errmsg = e.getMessage();
} }
// XXX getSigners() returns all certificates used to sign this applet which may allow List<Certificate> signers = new ArrayList<Certificate>();
// a third party to insert a trusted certificate. This should be replaced with Certificate cert = loadCertificate("resource.crt");
// statically included trusted keys. if (cert != null) {
_getdown = new Getdown(_config.appdir, null, GetdownApplet.class.getSigners(), 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) { _config.jvmargs, _config.appargs) {
@Override @Override
protected Container createContainer () { 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 */ /** The Getdown configuration as pulled from the applet params */
protected GetdownAppletConfig _config; protected GetdownAppletConfig _config;