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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user