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