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
* 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)
{
_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<Certificate> _signers;
/** If a warning has been issued about not being able to set modtimes. */
protected boolean _warnedAboutSetLastModified;
@@ -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<Certificate> signers,
String[] jvmargs, String[] appargs)
{
super("Getdown");
try {
@@ -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<Certificate> signers = new ArrayList<Certificate>();
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;