aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/security
diff options
context:
space:
mode:
authorandrew <devnull@localhost>2010-10-19 17:55:59 +0100
committerandrew <devnull@localhost>2010-10-19 17:55:59 +0100
commit7603e948d7a0a7eb2e72358cb4a40ae6779f95da (patch)
treec6441f7d14eafe8119d890cddd09b05b8f88c52a /netx/net/sourceforge/jnlp/security
Initial import from IcedTea6.
2010-10-19 Andrew John Hughes <[email protected]> * .hgignore, * Makefile.am, * acinclude.m4, * autogen.sh, * configure.ac, * extra/net/sourceforge/jnlp/about/HTMLPanel.java, * extra/net/sourceforge/jnlp/about/Main.java, * extra/net/sourceforge/jnlp/about/resources/about.html, * extra/net/sourceforge/jnlp/about/resources/applications.html, * extra/net/sourceforge/jnlp/about/resources/notes.html, * javac.in, * javaws.desktop: Imported from IcedTea6. * launcher/java.c, * launcher/java.h, * launcher/java_md.c, * launcher/java_md.h, * launcher/jli_util.h, * launcher/jni.h, * launcher/jvm.h, * launcher/jvm_md.h, * launcher/manifest_info.h, * launcher/splashscreen.h, * launcher/splashscreen_stubs.c, * launcher/version_comp.h, * launcher/wildcard.h: Imported from OpenJDK. * netx/javaws.1, * netx/javax/jnlp/BasicService.java, * netx/javax/jnlp/ClipboardService.java, * netx/javax/jnlp/DownloadService.java, * netx/javax/jnlp/DownloadServiceListener.java, * netx/javax/jnlp/ExtendedService.java, * netx/javax/jnlp/ExtensionInstallerService.java, * netx/javax/jnlp/FileContents.java, * netx/javax/jnlp/FileOpenService.java, * netx/javax/jnlp/FileSaveService.java, * netx/javax/jnlp/JNLPRandomAccessFile.java, * netx/javax/jnlp/PersistenceService.java, * netx/javax/jnlp/PrintService.java, * netx/javax/jnlp/ServiceManager.java, * netx/javax/jnlp/ServiceManagerStub.java, * netx/javax/jnlp/SingleInstanceListener.java, * netx/javax/jnlp/SingleInstanceService.java, * netx/javax/jnlp/UnavailableServiceException.java, * netx/net/sourceforge/jnlp/AppletDesc.java, * netx/net/sourceforge/jnlp/ApplicationDesc.java, * netx/net/sourceforge/jnlp/AssociationDesc.java, * netx/net/sourceforge/jnlp/ComponentDesc.java, * netx/net/sourceforge/jnlp/DefaultLaunchHandler.java, * netx/net/sourceforge/jnlp/ExtensionDesc.java, * netx/net/sourceforge/jnlp/IconDesc.java, * netx/net/sourceforge/jnlp/InformationDesc.java, * netx/net/sourceforge/jnlp/InstallerDesc.java, * netx/net/sourceforge/jnlp/JARDesc.java, * netx/net/sourceforge/jnlp/JNLPFile.java, * netx/net/sourceforge/jnlp/JNLPSplashScreen.java, * netx/net/sourceforge/jnlp/JREDesc.java, * netx/net/sourceforge/jnlp/LaunchException.java, * netx/net/sourceforge/jnlp/LaunchHandler.java, * netx/net/sourceforge/jnlp/Launcher.java, * netx/net/sourceforge/jnlp/MenuDesc.java, * netx/net/sourceforge/jnlp/NetxPanel.java, * netx/net/sourceforge/jnlp/Node.java, * netx/net/sourceforge/jnlp/PackageDesc.java, * netx/net/sourceforge/jnlp/ParseException.java, * netx/net/sourceforge/jnlp/Parser.java, * netx/net/sourceforge/jnlp/PluginBridge.java, * netx/net/sourceforge/jnlp/PropertyDesc.java, * netx/net/sourceforge/jnlp/RelatedContentDesc.java, * netx/net/sourceforge/jnlp/ResourcesDesc.java, * netx/net/sourceforge/jnlp/SecurityDesc.java, * netx/net/sourceforge/jnlp/ShortcutDesc.java, * netx/net/sourceforge/jnlp/StreamEater.java, * netx/net/sourceforge/jnlp/UpdateDesc.java, * netx/net/sourceforge/jnlp/Version.java, * netx/net/sourceforge/jnlp/cache/CacheEntry.java, * netx/net/sourceforge/jnlp/cache/CacheUtil.java, * netx/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/DownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/Resource.java, * netx/net/sourceforge/jnlp/cache/ResourceTracker.java, * netx/net/sourceforge/jnlp/cache/UpdatePolicy.java, * netx/net/sourceforge/jnlp/cache/package.html, * netx/net/sourceforge/jnlp/event/ApplicationEvent.java, * netx/net/sourceforge/jnlp/event/ApplicationListener.java, * netx/net/sourceforge/jnlp/event/DownloadEvent.java, * netx/net/sourceforge/jnlp/event/DownloadListener.java, * netx/net/sourceforge/jnlp/event/package.html, * netx/net/sourceforge/jnlp/package.html, * netx/net/sourceforge/jnlp/resources/Manifest.mf, * netx/net/sourceforge/jnlp/resources/Messages.properties, * netx/net/sourceforge/jnlp/resources/about.jnlp, * netx/net/sourceforge/jnlp/resources/default.jnlp, * netx/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * netx/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * netx/net/sourceforge/jnlp/runtime/AppletInstance.java, * netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * netx/net/sourceforge/jnlp/runtime/Boot.java, * netx/net/sourceforge/jnlp/runtime/Boot13.java, * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * netx/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * netx/net/sourceforge/jnlp/runtime/package.html, * netx/net/sourceforge/jnlp/security/AccessWarningPane.java, * netx/net/sourceforge/jnlp/security/AppletWarningPane.java, * netx/net/sourceforge/jnlp/security/CertVerifier.java, * netx/net/sourceforge/jnlp/security/CertWarningPane.java, * netx/net/sourceforge/jnlp/security/CertsInfoPane.java, * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * netx/net/sourceforge/jnlp/security/MoreInfoPane.java, * netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java, * netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java, * netx/net/sourceforge/jnlp/security/SecurityUtil.java, * netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * netx/net/sourceforge/jnlp/services/ExtendedSingleInstanceService.java, * netx/net/sourceforge/jnlp/services/InstanceExistsException.java, * netx/net/sourceforge/jnlp/services/ServiceUtil.java, * netx/net/sourceforge/jnlp/services/SingleInstanceLock.java, * netx/net/sourceforge/jnlp/services/XBasicService.java, * netx/net/sourceforge/jnlp/services/XClipboardService.java, * netx/net/sourceforge/jnlp/services/XDownloadService.java, * netx/net/sourceforge/jnlp/services/XExtendedService.java, * netx/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * netx/net/sourceforge/jnlp/services/XFileContents.java, * netx/net/sourceforge/jnlp/services/XFileOpenService.java, * netx/net/sourceforge/jnlp/services/XFileSaveService.java, * netx/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * netx/net/sourceforge/jnlp/services/XPersistenceService.java, * netx/net/sourceforge/jnlp/services/XPrintService.java, * netx/net/sourceforge/jnlp/services/XServiceManagerStub.java, * netx/net/sourceforge/jnlp/services/XSingleInstanceService.java, * netx/net/sourceforge/jnlp/services/package.html, * netx/net/sourceforge/jnlp/tools/CharacterEncoder.java, * netx/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * netx/net/sourceforge/jnlp/tools/JarRunner.java, * netx/net/sourceforge/jnlp/tools/JarSigner.java, * netx/net/sourceforge/jnlp/tools/JarSignerResources.java, * netx/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * netx/net/sourceforge/jnlp/tools/KeyTool.java, * netx/net/sourceforge/jnlp/util/FileUtils.java, * netx/net/sourceforge/jnlp/util/PropertiesFile.java, * netx/net/sourceforge/jnlp/util/Reflect.java, * netx/net/sourceforge/jnlp/util/WeakList.java, * netx/net/sourceforge/jnlp/util/XDesktopEntry.java, * netx/net/sourceforge/nanoxml/XMLElement.java, * netx/net/sourceforge/nanoxml/XMLParseException.java, * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc, * plugin/icedteanp/IcedTeaJavaRequestProcessor.h, * plugin/icedteanp/IcedTeaNPPlugin.cc, * plugin/icedteanp/IcedTeaNPPlugin.h, * plugin/icedteanp/IcedTeaPluginRequestProcessor.cc, * plugin/icedteanp/IcedTeaPluginRequestProcessor.h, * plugin/icedteanp/IcedTeaPluginUtils.cc, * plugin/icedteanp/IcedTeaPluginUtils.h, * plugin/icedteanp/IcedTeaRunnable.cc, * plugin/icedteanp/IcedTeaRunnable.h, * plugin/icedteanp/IcedTeaScriptablePluginObject.cc, * plugin/icedteanp/IcedTeaScriptablePluginObject.h, * plugin/icedteanp/java/netscape/javascript/JSException.java, * plugin/icedteanp/java/netscape/javascript/JSObject.java, * plugin/icedteanp/java/netscape/javascript/JSObjectCreatePermission.java, * plugin/icedteanp/java/netscape/javascript/JSProxy.java, * plugin/icedteanp/java/netscape/javascript/JSRunnable.java, * plugin/icedteanp/java/netscape/javascript/JSUtil.java, * plugin/icedteanp/java/netscape/security/ForbiddenTargetException.java, * plugin/icedteanp/java/sun/applet/AppletSecurityContextManager.java, * plugin/icedteanp/java/sun/applet/GetMemberPluginCallRequest.java, * plugin/icedteanp/java/sun/applet/GetWindowPluginCallRequest.java, * plugin/icedteanp/java/sun/applet/JavaConsole.java, * plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java, * plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java, * plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java, * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java, * plugin/icedteanp/java/sun/applet/PluginCallRequest.java, * plugin/icedteanp/java/sun/applet/PluginCallRequestFactory.java, * plugin/icedteanp/java/sun/applet/PluginClassLoader.java, * plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java, * plugin/icedteanp/java/sun/applet/PluginCookieManager.java, * plugin/icedteanp/java/sun/applet/PluginDebug.java, * plugin/icedteanp/java/sun/applet/PluginException.java, * plugin/icedteanp/java/sun/applet/PluginMain.java, * plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java, * plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java, * plugin/icedteanp/java/sun/applet/PluginObjectStore.java, * plugin/icedteanp/java/sun/applet/PluginProxyInfoRequest.java, * plugin/icedteanp/java/sun/applet/PluginProxySelector.java, * plugin/icedteanp/java/sun/applet/PluginStreamHandler.java, * plugin/icedteanp/java/sun/applet/RequestQueue.java, * plugin/icedteanp/java/sun/applet/TestEnv.java, * plugin/icedteanp/java/sun/applet/VoidPluginCallRequest.java, * plugin/tests/LiveConnect/DummyObject.java, * plugin/tests/LiveConnect/OverloadTestHelper1.java, * plugin/tests/LiveConnect/OverloadTestHelper2.java, * plugin/tests/LiveConnect/OverloadTestHelper3.java, * plugin/tests/LiveConnect/PluginTest.java, * plugin/tests/LiveConnect/build, * plugin/tests/LiveConnect/common.js, * plugin/tests/LiveConnect/index.html, * plugin/tests/LiveConnect/jjs_eval_test.js, * plugin/tests/LiveConnect/jjs_func_parameters_tests.js, * plugin/tests/LiveConnect/jjs_func_rettype_tests.js, * plugin/tests/LiveConnect/jjs_get_tests.js, * plugin/tests/LiveConnect/jjs_set_tests.js, * plugin/tests/LiveConnect/jsj_func_overload_tests.js, * plugin/tests/LiveConnect/jsj_func_parameters_tests.js, * plugin/tests/LiveConnect/jsj_func_rettype_tests.js, * plugin/tests/LiveConnect/jsj_get_tests.js, * plugin/tests/LiveConnect/jsj_set_tests.js, * plugin/tests/LiveConnect/jsj_type_casting_tests.js, * plugin/tests/LiveConnect/jsj_type_conversion_tests.js: Initial import from IcedTea6. * AUTHORS, * COPYING * INSTALL, * NEWS, * README: New documentation.
Diffstat (limited to 'netx/net/sourceforge/jnlp/security')
-rw-r--r--netx/net/sourceforge/jnlp/security/AccessWarningPane.java209
-rw-r--r--netx/net/sourceforge/jnlp/security/AppletWarningPane.java115
-rw-r--r--netx/net/sourceforge/jnlp/security/CertVerifier.java92
-rw-r--r--netx/net/sourceforge/jnlp/security/CertWarningPane.java254
-rw-r--r--netx/net/sourceforge/jnlp/security/CertsInfoPane.java341
-rw-r--r--netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java238
-rw-r--r--netx/net/sourceforge/jnlp/security/MoreInfoPane.java110
-rw-r--r--netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java120
-rw-r--r--netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java134
-rw-r--r--netx/net/sourceforge/jnlp/security/SecurityUtil.java285
-rw-r--r--netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java474
-rw-r--r--netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java77
-rw-r--r--netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java314
-rw-r--r--netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java335
-rw-r--r--netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java120
15 files changed, 3218 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/security/AccessWarningPane.java b/netx/net/sourceforge/jnlp/security/AccessWarningPane.java
new file mode 100644
index 0000000..5afbfff
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/AccessWarningPane.java
@@ -0,0 +1,209 @@
+/* AccessWarningPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.util.FileUtils;
+
+/**
+ * Provides a panel to show inside a SecurityWarningDialog. These dialogs are
+ * used to warn the user when either signed code (with or without signing
+ * issues) is going to be run, or when service permission (file, clipboard,
+ * printer, etc) is needed with unsigned code.
+ *
+ * @author <a href="mailto:[email protected]">Joshua Sumali</a>
+ */
+public class AccessWarningPane extends SecurityDialogPanel {
+
+ JCheckBox alwaysAllow;
+ Object[] extras;
+
+ public AccessWarningPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ addComponents();
+ }
+
+ public AccessWarningPane(SecurityWarningDialog x, Object[] extras, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ this.extras = extras;
+ addComponents();
+ }
+
+ /**
+ * Creates the actual GUI components, and adds it to this panel
+ */
+ private void addComponents() {
+ SecurityWarningDialog.AccessType type = parent.getAccessType();
+ JNLPFile file = parent.getFile();
+
+ String name = "";
+ String publisher = "";
+ String from = "";
+
+ //We don't worry about exceptions when trying to fill in
+ //these strings -- we just want to fill in as many as possible.
+ try {
+ name = file.getInformation().getTitle() != null ? file.getInformation().getTitle() : "<no associated certificate>";
+ } catch (Exception e) {
+ }
+
+ try {
+ publisher = file.getInformation().getVendor() != null ? file.getInformation().getVendor() : "<no associated certificate>";
+ } catch (Exception e) {
+ }
+
+ try {
+ from = !file.getInformation().getHomepage().toString().equals("") ? file.getInformation().getHomepage().toString() : file.getSourceLocation().getAuthority();
+ } catch (Exception e) {
+ from = file.getSourceLocation().getAuthority();
+ }
+
+ //Top label
+ String topLabelText = "";
+ switch (type) {
+ case READ_FILE:
+ if (extras != null && extras.length > 0 && extras[0] instanceof String) {
+ topLabelText = R("SFileReadAccess", FileUtils.displayablePath((String)extras[0]));
+ } else {
+ topLabelText = R("SFileReadAccess", R("AFileOnTheMachine"));
+ }
+ break;
+ case WRITE_FILE:
+ if (extras != null && extras.length > 0 && extras[0] instanceof String) {
+ topLabelText = R("SFileWriteAccess", FileUtils.displayablePath((String)extras[0]));
+ } else {
+ topLabelText = R("SFileWriteAccess", R("AFileOnTheMachine"));
+ }
+ break;
+ case CREATE_DESTKOP_SHORTCUT:
+ topLabelText = R("SDesktopShortcut");
+ break;
+ case CLIPBOARD_READ:
+ topLabelText = R("SClipboardReadAccess");
+ break;
+ case CLIPBOARD_WRITE:
+ topLabelText = R("SClipboardWriteAccess");
+ break;
+ case PRINTER:
+ topLabelText = R("SPrinterAccess");
+ break;
+ case NETWORK:
+ if (extras != null && extras.length >= 0)
+ topLabelText = R("SNetworkAccess", extras[0]);
+ else
+ topLabelText = R("SNetworkAccess", "(address here)");
+ }
+
+ ImageIcon icon = new ImageIcon((new sun.misc.Launcher()).getClassLoader().getResource("net/sourceforge/jnlp/resources/warning.png"));
+ JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT);
+ topLabel.setFont(new Font(topLabel.getFont().toString(),
+ Font.BOLD, 12));
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.setBackground(Color.WHITE);
+ topPanel.add(topLabel, BorderLayout.CENTER);
+ topPanel.setPreferredSize(new Dimension(450,100));
+ topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //application info
+ JLabel nameLabel = new JLabel("Name: " + name);
+ nameLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ JLabel publisherLabel = new JLabel("Publisher: " + publisher);
+ publisherLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ JLabel fromLabel = new JLabel("From: " + from);
+ fromLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+
+ alwaysAllow = new JCheckBox("Always allow this action");
+ alwaysAllow.setEnabled(false);
+
+ JPanel infoPanel = new JPanel(new GridLayout(4,1));
+ infoPanel.add(nameLabel);
+ infoPanel.add(publisherLabel);
+ infoPanel.add(fromLabel);
+ infoPanel.add(alwaysAllow);
+ infoPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
+
+ //run and cancel buttons
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ JButton run = new JButton("Allow");
+ JButton cancel = new JButton("Cancel");
+ run.addActionListener(createSetValueListener(parent,0));
+ run.addActionListener(new CheckBoxListener());
+ cancel.addActionListener(createSetValueListener(parent, 1));
+ initialFocusComponent = cancel;
+ buttonPanel.add(run);
+ buttonPanel.add(cancel);
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //all of the above
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(topPanel);
+ add(infoPanel);
+ add(buttonPanel);
+
+ }
+
+
+ private class CheckBoxListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (alwaysAllow != null && alwaysAllow.isSelected()) {
+ // TODO: somehow tell the ApplicationInstance
+ // to stop asking for permission
+ }
+ }
+ }
+
+}
diff --git a/netx/net/sourceforge/jnlp/security/AppletWarningPane.java b/netx/net/sourceforge/jnlp/security/AppletWarningPane.java
new file mode 100644
index 0000000..8bd14ef
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/AppletWarningPane.java
@@ -0,0 +1,115 @@
+/* AppletWarningPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+
+public class AppletWarningPane extends SecurityDialogPanel {
+
+ public AppletWarningPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ addComponents();
+ }
+
+ protected void addComponents() {
+
+ //Top label
+ String topLabelText = "While support for verifying signed code" +
+ " has not been implemented yet, some applets will not run " +
+ "properly under the default restricted security level.";
+ String bottomLabelText = "Do you want to run this applet under the " +
+ "restricted security level? (clicking No will run this applet " +
+ "without any security checking, and should only be done if you " +
+ "trust the applet!)";
+
+ JLabel topLabel = new JLabel(htmlWrap(topLabelText));
+ topLabel.setFont(new Font(topLabel.getFont().toString(),
+ Font.BOLD, 12));
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.setBackground(Color.WHITE);
+ topPanel.add(topLabel, BorderLayout.CENTER);
+ topPanel.setPreferredSize(new Dimension(400,80));
+ topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ JLabel bottomLabel = new JLabel(htmlWrap(bottomLabelText));
+ JPanel infoPanel = new JPanel(new BorderLayout());
+ infoPanel.add(bottomLabel, BorderLayout.CENTER);
+ infoPanel.setPreferredSize(new Dimension(400,80));
+ infoPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //run and cancel buttons
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ JButton yes = new JButton("Yes");
+ JButton no = new JButton("No");
+ JButton cancel = new JButton("Cancel");
+ int buttonWidth = cancel.getMinimumSize().width;
+ int buttonHeight = cancel.getMinimumSize().height;
+ Dimension d = new Dimension(buttonWidth, buttonHeight);
+ yes.setPreferredSize(d);
+ no.setPreferredSize(d);
+ cancel.setPreferredSize(d);
+ yes.addActionListener(createSetValueListener(parent, 0));
+ no.addActionListener(createSetValueListener(parent, 1));
+ cancel.addActionListener(createSetValueListener(parent, 2));
+ initialFocusComponent = cancel;
+ buttonPanel.add(yes);
+ buttonPanel.add(no);
+ buttonPanel.add(cancel);
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //all of the above
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(topPanel);
+ add(infoPanel);
+ add(buttonPanel);
+
+ }
+
+}
diff --git a/netx/net/sourceforge/jnlp/security/CertVerifier.java b/netx/net/sourceforge/jnlp/security/CertVerifier.java
new file mode 100644
index 0000000..cef69c3
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/CertVerifier.java
@@ -0,0 +1,92 @@
+/* CertVerifier.java
+ Copyright (C) 2009 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+
+/**
+ * An interface that provides various details about a certificate
+ */
+
+public interface CertVerifier {
+
+ /**
+ * Return if the publisher is already trusted
+ */
+ public boolean getAlreadyTrustPublisher();
+
+ /**
+ * Return if the root is in CA certs
+ */
+ public boolean getRootInCacerts();
+
+ /**
+ * Return if there are signing issues with the certificate(s) being veried
+ */
+ public boolean hasSigningIssues();
+
+ /**
+ * Return if there are no signing issues with this cert (!hasSigningIssues())
+ */
+ public boolean noSigningIssues();
+
+ /**
+ * Get the details regarding issue(s) with this certificate
+ */
+ public ArrayList<String> getDetails();
+
+ /**
+ * Return a valid certificate path to this certificate(s) being verified
+ * @return The CertPath
+ */
+ public ArrayList<CertPath> getCerts();
+
+ /**
+ * Returns the application's publisher's certificate.
+ */
+ public abstract Certificate getPublisher();
+
+ /**
+ * Returns the application's root's certificate. This
+ * may return the same certificate as getPublisher() in
+ * the event that the application is self signed.
+ */
+ public abstract Certificate getRoot();
+}
diff --git a/netx/net/sourceforge/jnlp/security/CertWarningPane.java b/netx/net/sourceforge/jnlp/security/CertWarningPane.java
new file mode 100644
index 0000000..59559c4
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java
@@ -0,0 +1,254 @@
+/* CertWarningPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.PluginBridge;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.tools.KeyTool;
+
+/**
+ * Provides the panel for using inside a SecurityWarningDialog. These dialogs are
+ * used to warn the user when either signed code (with or without signing
+ * issues) is going to be run, or when service permission (file, clipboard,
+ * printer, etc) is needed with unsigned code.
+ *
+ * @author <a href="mailto:[email protected]">Joshua Sumali</a>
+ */
+public class CertWarningPane extends SecurityDialogPanel {
+
+ JCheckBox alwaysTrust;
+ CertVerifier certVerifier;
+
+ public CertWarningPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ this.certVerifier = certVerifier;
+ addComponents();
+ }
+
+ /**
+ * Creates the actual GUI components, and adds it to this panel
+ */
+ private void addComponents() {
+ SecurityWarningDialog.AccessType type = parent.getAccessType();
+ JNLPFile file = parent.getFile();
+ Certificate c = parent.getJarSigner().getPublisher();
+
+ String name = "";
+ String publisher = "";
+ String from = "";
+
+ //We don't worry about exceptions when trying to fill in
+ //these strings -- we just want to fill in as many as possible.
+ try {
+ if ((certVerifier instanceof HttpsCertVerifier) &&
+ (c instanceof X509Certificate))
+ name = SecurityUtil.getCN(((X509Certificate)c)
+ .getSubjectX500Principal().getName());
+ else if (file instanceof PluginBridge)
+ name = file.getTitle();
+ else
+ name = file.getInformation().getTitle();
+ } catch (Exception e) {
+ }
+
+ try {
+ if (c instanceof X509Certificate) {
+ publisher = SecurityUtil.getCN(((X509Certificate)c)
+ .getSubjectX500Principal().getName());
+ }
+ } catch (Exception e) {
+ }
+
+ try {
+ if (file instanceof PluginBridge)
+ from = file.getCodeBase().getHost();
+ else
+ from = file.getInformation().getHomepage().toString();
+ } catch (Exception e) {
+ }
+
+ //Top label
+ String topLabelText = "";
+ String propertyName = "";
+ if (certVerifier instanceof HttpsCertVerifier)
+ {
+ topLabelText = "The website's certificate cannot be verified. " +
+ "Do you want to continue?";
+ propertyName = "OptionPane.warningIcon";
+ }
+ else
+ switch (type) {
+ case VERIFIED:
+ topLabelText = R("SSigVerified");
+ propertyName = "OptionPane.informationIcon";
+ break;
+ case UNVERIFIED:
+ topLabelText = R("SSigUnverified");
+ propertyName = "OptionPane.warningIcon";
+ break;
+ case SIGNING_ERROR:
+ topLabelText = R("SSignatureError");
+ propertyName = "OptionPane.warningIcon";
+ break;
+ }
+ ImageIcon icon = new ImageIcon((new sun.misc.Launcher())
+ .getClassLoader().getResource("net/sourceforge/jnlp/resources/warning.png"));
+ JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT);
+ topLabel.setFont(new Font(topLabel.getFont().toString(),
+ Font.BOLD, 12));
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.setBackground(Color.WHITE);
+ topPanel.add(topLabel, BorderLayout.CENTER);
+ topPanel.setPreferredSize(new Dimension(400,60));
+ topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //application info
+ JLabel nameLabel = new JLabel("Name: " + name);
+ nameLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ JLabel publisherLabel = new JLabel("Publisher: " + publisher);
+ publisherLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ JLabel fromLabel = new JLabel("From: " + from);
+ fromLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+
+ alwaysTrust = new JCheckBox(
+ "Always trust content from this publisher");
+ alwaysTrust.setEnabled(true);
+
+ JPanel infoPanel = new JPanel(new GridLayout(4,1));
+ infoPanel.add(nameLabel);
+ infoPanel.add(publisherLabel);
+
+ if (!(certVerifier instanceof HttpsCertVerifier))
+ infoPanel.add(fromLabel);
+
+ infoPanel.add(alwaysTrust);
+ infoPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
+
+ //run and cancel buttons
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ JButton run = new JButton("Run");
+ JButton cancel = new JButton("Cancel");
+ int buttonWidth = Math.max(run.getMinimumSize().width,
+ cancel.getMinimumSize().width);
+ int buttonHeight = run.getMinimumSize().height;
+ Dimension d = new Dimension(buttonWidth, buttonHeight);
+ run.setPreferredSize(d);
+ cancel.setPreferredSize(d);
+ run.addActionListener(createSetValueListener(parent, 0));
+ run.addActionListener(new CheckBoxListener());
+ cancel.addActionListener(createSetValueListener(parent, 1));
+ initialFocusComponent = cancel;
+ buttonPanel.add(run);
+ buttonPanel.add(cancel);
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //all of the above
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(topPanel);
+ add(infoPanel);
+ add(buttonPanel);
+
+ JLabel bottomLabel;
+ JButton moreInfo = new JButton("More information...");
+ moreInfo.addActionListener(new MoreInfoButtonListener());
+
+ if (parent.getJarSigner().getRootInCacerts())
+ bottomLabel = new JLabel(htmlWrap(R("STrustedSource")));
+ else
+ bottomLabel = new JLabel(htmlWrap(R("SUntrustedSource")));
+
+ JPanel bottomPanel = new JPanel();
+ bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
+ bottomPanel.add(bottomLabel);
+ bottomPanel.add(moreInfo);
+ bottomPanel.setPreferredSize(new Dimension(500,100));
+ bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+ add(bottomPanel);
+
+ }
+
+ private class MoreInfoButtonListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ SecurityWarningDialog.showMoreInfoDialog(parent.getJarSigner(),
+ parent);
+ }
+ }
+
+ /**
+ * Updates the user's KeyStore of trusted Certificates.
+ */
+ private class CheckBoxListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (alwaysTrust != null && alwaysTrust.isSelected()) {
+ try {
+ KeyTool kt = new KeyTool();
+ Certificate c = parent.getJarSigner().getPublisher();
+ kt.importCert(c);
+ if (JNLPRuntime.isDebug()) {
+ System.out.println("certificate is now permanently trusted");
+ }
+ } catch (Exception ex) {
+ //TODO: Let NetX show a dialog here notifying user
+ //about being unable to add cert to keystore
+ }
+ }
+ }
+ }
+
+}
diff --git a/netx/net/sourceforge/jnlp/security/CertsInfoPane.java b/netx/net/sourceforge/jnlp/security/CertsInfoPane.java
new file mode 100644
index 0000000..85afd1b
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/CertsInfoPane.java
@@ -0,0 +1,341 @@
+/* CertsInfoPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.security.cert.CertPath;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.math.BigInteger;
+import javax.security.auth.x500.X500Principal;
+import sun.security.x509.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeSelectionModel;
+
+import net.sourceforge.jnlp.tools.*;
+
+/**
+ * Provides the panel for the Certificate Info dialog. This dialog displays data from
+ * X509Certificate(s) used in jar signing.
+ *
+ * @author <a href="mailto:[email protected]">Joshua Sumali</a>
+ */
+public class CertsInfoPane extends SecurityDialogPanel {
+
+ private ArrayList<CertPath> certs;
+ private JList list;
+ protected JTree tree;
+ private JTable table;
+ private JTextArea output;
+ private ListSelectionModel listSelectionModel;
+ private ListSelectionModel tableSelectionModel;
+ protected String[] certNames;
+ private String[] columnNames = { "Field", "Value" };
+ protected ArrayList<String[][]> certsData;
+
+ public CertsInfoPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ addComponents();
+ }
+
+ /**
+ * Builds the JTree out of CertPaths.
+ */
+ void buildTree() {
+ certs = parent.getJarSigner().getCerts();
+ //for now, we're only going to display the first signer, even though
+ //jars can be signed by multiple people.
+ CertPath firstPath = certs.get(0);
+ X509Certificate firstCert =
+ ((X509Certificate)firstPath.getCertificates().get(0));
+ String subjectString =
+ SecurityUtil.getCN(firstCert.getSubjectX500Principal().getName());
+ String issuerString =
+ SecurityUtil.getCN(firstCert.getIssuerX500Principal().getName());
+
+ DefaultMutableTreeNode top =
+ new DefaultMutableTreeNode(subjectString
+ + " (" + issuerString + ")");
+
+ //not self signed
+ if (!firstCert.getSubjectDN().equals(firstCert.getIssuerDN())
+ && (firstPath.getCertificates().size() > 1)) {
+ X509Certificate secondCert =
+ ((X509Certificate)firstPath.getCertificates().get(1));
+ subjectString =
+ SecurityUtil.getCN(secondCert.getSubjectX500Principal().getName());
+ issuerString =
+ SecurityUtil.getCN(secondCert.getIssuerX500Principal().getName());
+ top.add(new DefaultMutableTreeNode(subjectString
+ + " (" + issuerString + ")"));
+ }
+
+ tree = new JTree(top);
+ tree.getSelectionModel().setSelectionMode
+ (TreeSelectionModel.SINGLE_TREE_SELECTION);
+ tree.addTreeSelectionListener(new TreeSelectionHandler());
+ }
+
+ /**
+ * Fills in certsNames, certsData with data from the certificates.
+ */
+ protected void populateTable() {
+ certNames = new String[certs.get(0).getCertificates().size()];
+ certsData = new ArrayList<String[][]>();
+
+ for (int i = 0; i < certs.get(0).getCertificates().size(); i++) {
+
+ X509Certificate c = (X509Certificate) certs.get(0).getCertificates().get(i);
+ certsData.add(parseCert(c));
+ certNames[i] = SecurityUtil.getCN(c.getSubjectX500Principal().getName())
+ + " (" + SecurityUtil.getCN(c.getIssuerX500Principal().getName()) + ")";
+ }
+ }
+
+ protected String[][] parseCert(X509Certificate c) {
+
+ String version = ""+c.getVersion();
+ String serialNumber = c.getSerialNumber().toString();
+ String signatureAlg = c.getSigAlgName();
+ String issuer = c.getIssuerX500Principal().toString();
+ String validity = new CertificateValidity(c.getNotBefore(),
+ c.getNotAfter()).toString();
+ String subject = c.getSubjectX500Principal().toString();
+
+ //convert our signature into a nice human-readable form.
+ HexDumpEncoder encoder = new HexDumpEncoder();
+ String signature = encoder.encodeBuffer(c.getSignature());
+
+ String md5Hash = "";
+ String sha1Hash = "";
+ try {
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+ digest.update(c.getEncoded());
+ md5Hash = makeFingerprint(digest.digest());
+
+ digest = MessageDigest.getInstance("SHA-1");
+ digest.update(c.getEncoded());
+ sha1Hash = makeFingerprint(digest.digest());
+ } catch (Exception e) {
+ //fail quietly
+ }
+
+ String[][] cert = { {"Version", version},
+ {"Serial", serialNumber},
+ {"Signature Algorithm", signatureAlg},
+ {"Issuer", issuer},
+ {"Validity", validity},
+ {"Subject", subject},
+ {"Signature", signature},
+ {"MD5 Fingerprint", md5Hash},
+ {"SHA1 Fingerprint", sha1Hash}
+ };
+ return cert;
+ }
+
+ /**
+ * Constructs the GUI components of this panel
+ */
+ protected void addComponents() {
+ buildTree();
+ populateTable();
+ /**
+ //List of Certs
+ list = new JList(certNames);
+ list.setSelectedIndex(0); //assuming there's at least 1 cert
+ listSelectionModel = list.getSelectionModel();
+ listSelectionModel.addListSelectionListener(new ListSelectionHandler());
+ JScrollPane listPane = new JScrollPane(list);
+ */
+ JScrollPane listPane = new JScrollPane(tree);
+
+ //Table of field-value pairs
+ DefaultTableModel tableModel = new DefaultTableModel(certsData.get(0),
+ columnNames);
+ table = new JTable(tableModel);
+ table.getTableHeader().setReorderingAllowed(false);
+ tableSelectionModel = table.getSelectionModel();
+ tableSelectionModel.addListSelectionListener(new TableSelectionHandler());
+ table.setFillsViewportHeight(true);
+ JScrollPane tablePane = new JScrollPane(table);
+ tablePane.setPreferredSize(new Dimension(500,200));
+
+ //Text area to display the larger values
+ output = new JTextArea();
+ output.setEditable(false);
+ JScrollPane outputPane = new JScrollPane(output,
+ ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
+ ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ outputPane.setPreferredSize(new Dimension(500,200));
+
+ //split pane of the field-value pairs and textbox
+ JSplitPane rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+ tablePane, outputPane);
+ rightSplitPane.setDividerLocation(0.50);
+ rightSplitPane.setResizeWeight(0.50);
+
+ JSplitPane mainPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+ listPane, rightSplitPane);
+ mainPane.setDividerLocation(0.30);
+ mainPane.setResizeWeight(0.30);
+
+ JPanel buttonPane = new JPanel(new BorderLayout());
+ JButton close = new JButton("Close");
+ JButton copyToClipboard = new JButton("Copy to Clipboard");
+ close.addActionListener(createSetValueListener(parent, 0));
+ copyToClipboard.addActionListener(new CopyToClipboardHandler());
+ buttonPane.add(close, BorderLayout.EAST);
+ buttonPane.add(copyToClipboard, BorderLayout.WEST);
+ buttonPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+
+ add(mainPane, BorderLayout.CENTER);
+ add(buttonPane, BorderLayout.SOUTH);
+ }
+
+ /**
+ * Copies the currently selected certificate to the system Clipboard.
+ */
+ private class CopyToClipboardHandler implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ int certIndex = 0;
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)
+ tree.getLastSelectedPathComponent();
+ if (node == null) return;
+ if (node.isRoot())
+ certIndex = 0;
+ else if (node.isLeaf())
+ certIndex = 1;
+
+ String[][] cert = certsData.get(certIndex);
+ int rows = cert.length;
+ int cols = cert[0].length;
+
+ String certString = "";
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ certString += cert[i][j];
+ certString += " ";
+ }
+ certString += "\n";
+ }
+
+ clipboard.setContents(new StringSelection(certString), null);
+ }
+ }
+
+ /**
+ * Updates the JTable when the JTree selection has changed.
+ */
+ protected class TreeSelectionHandler implements TreeSelectionListener {
+ public void valueChanged(TreeSelectionEvent e) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)
+ tree.getLastSelectedPathComponent();
+
+ if (node == null) return;
+ if (node.isRoot()) {
+ table.setModel(new DefaultTableModel(certsData.get(0),
+ columnNames));
+ } else if (node.isLeaf()) {
+ table.setModel(new DefaultTableModel(certsData.get(1),
+ columnNames));
+ }
+ }
+ }
+
+ /**
+ * Updates the JTable when the selection on the list has changed.
+ */
+ private class ListSelectionHandler implements ListSelectionListener {
+ public void valueChanged(ListSelectionEvent e) {
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+
+ int minIndex = lsm.getMinSelectionIndex();
+ int maxIndex = lsm.getMaxSelectionIndex();
+
+ for (int i = minIndex; i <= maxIndex; i++) {
+ if (lsm.isSelectedIndex(i)) {
+ table.setModel(new DefaultTableModel(certsData.get(i),
+ columnNames));
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the JTextArea output when the selection on the JTable
+ * has changed.
+ */
+ private class TableSelectionHandler implements ListSelectionListener {
+ public void valueChanged(ListSelectionEvent e) {
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+
+ int minIndex = lsm.getMinSelectionIndex();
+ int maxIndex = lsm.getMaxSelectionIndex();
+
+ for (int i = minIndex; i <= maxIndex; i++) {
+ if (lsm.isSelectedIndex(i)) {
+ output.setText((String) table.getValueAt(i,1));
+ }
+ }
+ }
+ }
+
+ /**
+ * Makes a human readable hash fingerprint.
+ * For example: 11:22:33:44:AA:BB:CC:DD:EE:FF.
+ */
+ private String makeFingerprint(byte[] hash) {
+ String fingerprint = "";
+ for (int i = 0; i < hash.length; i++) {
+ if (!fingerprint.equals(""))
+ fingerprint += ":";
+ fingerprint += Integer.toHexString(
+ ((hash[i] & 0xFF)|0x100)).substring(1,3);
+ }
+ return fingerprint.toUpperCase();
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java
new file mode 100644
index 0000000..ca2fc08
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java
@@ -0,0 +1,238 @@
+/* HttpsCertVerifier.java
+ Copyright (C) 2009 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.io.IOException;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.tools.KeyTool;
+import sun.security.util.DerValue;
+import sun.security.util.HostnameChecker;
+import sun.security.x509.X500Name;
+
+public class HttpsCertVerifier implements CertVerifier {
+
+ private VariableX509TrustManager tm;
+ private X509Certificate[] chain;
+ private String authType;
+ private String hostName;
+ private boolean isTrusted;
+ private boolean hostMatched;
+ private ArrayList<String> details = new ArrayList<String>();
+
+ public HttpsCertVerifier(VariableX509TrustManager tm,
+ X509Certificate[] chain, String authType,
+ boolean isTrusted, boolean hostMatched,
+ String hostName) {
+ this.tm = tm;
+ this.chain = chain;
+ this.authType = authType;
+ this.hostName = hostName;
+ this.isTrusted = isTrusted;
+ this.hostMatched = hostMatched;
+ }
+
+ public boolean getAlreadyTrustPublisher() {
+ return isTrusted;
+ }
+
+ public ArrayList<CertPath> getCerts() {
+
+ ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
+ for (int i=0; i < chain.length; i++)
+ list.add(chain[i]);
+
+ ArrayList<CertPath> certPaths = new ArrayList<CertPath>();
+
+ try {
+ certPaths.add(CertificateFactory.getInstance("X.509").generateCertPath(list));
+ } catch (CertificateException ce) {
+ ce.printStackTrace();
+
+ // carry on
+ }
+
+ return certPaths;
+ }
+
+ public ArrayList<String> getDetails() {
+
+ boolean hasExpiredCert=false;
+ boolean hasExpiringCert=false;
+ boolean notYetValidCert=false;
+ boolean isUntrusted=false;
+ boolean CNMisMatch = !hostMatched;
+
+ if (! getAlreadyTrustPublisher())
+ isUntrusted = true;
+
+ for (int i=0; i < chain.length; i++)
+ {
+ X509Certificate cert = chain[i];
+
+ long now = System.currentTimeMillis();
+ long SIX_MONTHS = 180*24*60*60*1000L;
+ long notAfter = cert.getNotAfter().getTime();
+ if (notAfter < now) {
+ hasExpiredCert = true;
+ } else if (notAfter < now + SIX_MONTHS) {
+ hasExpiringCert = true;
+ }
+
+ try {
+ cert.checkValidity();
+ } catch (CertificateNotYetValidException cnyve) {
+ notYetValidCert = true;
+ } catch (CertificateExpiredException cee) {
+ hasExpiredCert = true;
+ }
+ }
+
+ String altNames = getNamesForCert(chain[0]);
+
+ if (isUntrusted || hasExpiredCert || hasExpiringCert || notYetValidCert || CNMisMatch) {
+ if (isUntrusted)
+ addToDetails(R("SUntrustedCertificate"));
+ if (hasExpiredCert)
+ addToDetails(R("SHasExpiredCert"));
+ if (hasExpiringCert)
+ addToDetails(R("SHasExpiringCert"));
+ if (notYetValidCert)
+ addToDetails(R("SNotYetValidCert"));
+ if (CNMisMatch)
+ addToDetails(R("SCNMisMatch", altNames, this.hostName));
+ }
+
+
+ return details;
+ }
+
+ private String getNamesForCert(X509Certificate c) {
+
+ String names = "";
+
+
+ // We use the specification from
+ // http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/X509Certificate.html#getSubjectAlternativeNames()
+ // to determine the type of address
+ int ALTNAME_DNS = 2;
+ int ALTNAME_IP = 7;
+
+ try {
+ Collection<List<?>> subjAltNames = c.getSubjectAlternativeNames();
+ X500Name subjectName = HostnameChecker.getSubjectX500Name(c);
+ DerValue derValue = subjectName.findMostSpecificAttribute
+ (X500Name.commonName_oid);
+ names += derValue.getAsString();
+
+ if (subjAltNames != null) {
+ for (List<?> next : subjAltNames) {
+ if ( ((Integer)next.get(0)).intValue() == ALTNAME_IP ||
+ ((Integer)next.get(0)).intValue() == ALTNAME_DNS
+ ) {
+ names += ", " + (String)next.get(1);
+ }
+ }
+ }
+
+ if (subjAltNames != null)
+ names = names.substring(2); // remove proceeding ", "
+
+ } catch (CertificateParsingException cpe) {
+ cpe.printStackTrace();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ return names;
+ }
+
+ private void addToDetails(String detail) {
+ if (!details.contains(detail))
+ details.add(detail);
+ }
+
+ private static String R(String key) {
+ return JNLPRuntime.getMessage(key);
+ }
+
+ private static String R(String key, String arg1, String arg2) {
+ return JNLPRuntime.getMessage(key, new Object[] { arg1, arg2 });
+ }
+
+ public Certificate getPublisher() {
+ if (chain.length > 0)
+ return (Certificate)chain[0];
+ return null;
+ }
+
+ public Certificate getRoot() {
+ if (chain.length > 0)
+ return (Certificate)chain[chain.length - 1];
+ return null;
+ }
+
+ public boolean getRootInCacerts() {
+ try {
+ KeyTool kt = new KeyTool();
+ return kt.checkCacertsForCertificate(getRoot());
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ public boolean hasSigningIssues() {
+ return false;
+ }
+
+ public boolean noSigningIssues() {
+ return false;
+ }
+
+}
diff --git a/netx/net/sourceforge/jnlp/security/MoreInfoPane.java b/netx/net/sourceforge/jnlp/security/MoreInfoPane.java
new file mode 100644
index 0000000..729eb1c
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/MoreInfoPane.java
@@ -0,0 +1,110 @@
+/* MoreInfoPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+/**
+ * Provides the panel for the More Info dialog. This dialog shows details about an
+ * application's signing status.
+ *
+ * @author <a href="mailto:[email protected]">Joshua Sumali</a>
+ */
+public class MoreInfoPane extends SecurityDialogPanel {
+
+ public MoreInfoPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ addComponents();
+ }
+
+ /**
+ * Constructs the GUI components of this panel
+ */
+ private void addComponents() {
+ ArrayList<String> details = certVerifier.getDetails();
+
+ int numLabels = details.size();
+ JPanel errorPanel = new JPanel(new GridLayout(numLabels,1));
+ errorPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+ errorPanel.setPreferredSize(new Dimension(400, 70*(numLabels)));
+
+ for (int i = 0; i < numLabels; i++) {
+ ImageIcon icon = null;
+ if (details.get(i).equals(R("STrustedCertificate")))
+ icon = new ImageIcon((new sun.misc.Launcher())
+ .getClassLoader().getResource("net/sourceforge/jnlp/resources/info-small.png"));
+ else
+ icon = new ImageIcon((new sun.misc.Launcher())
+ .getClassLoader().getResource("net/sourceforge/jnlp/resources/warning-small.png"));
+
+ errorPanel.add(new JLabel(htmlWrap(details.get(i)), icon, SwingConstants.LEFT));
+ }
+
+ JPanel buttonsPanel = new JPanel(new BorderLayout());
+ JButton certDetails = new JButton("Certificate Details");
+ certDetails.addActionListener(new CertInfoButtonListener());
+ JButton close = new JButton("Close");
+ close.addActionListener(createSetValueListener(parent, 0));
+ buttonsPanel.add(certDetails, BorderLayout.WEST);
+ buttonsPanel.add(close, BorderLayout.EAST);
+ buttonsPanel.setBorder(BorderFactory.createEmptyBorder(15,15,15,15));
+
+ add(errorPanel, BorderLayout.NORTH);
+ add(buttonsPanel, BorderLayout.SOUTH);
+
+ }
+
+ private class CertInfoButtonListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ SecurityWarningDialog.showCertInfoDialog(parent.getJarSigner(),
+ parent);
+ }
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java b/netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java
new file mode 100644
index 0000000..7210a89
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java
@@ -0,0 +1,120 @@
+/* NotAllSignedWarningPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import net.sourceforge.jnlp.JNLPFile;
+
+
+public class NotAllSignedWarningPane extends SecurityDialogPanel {
+
+ public NotAllSignedWarningPane(SecurityWarningDialog x) {
+ super(x);
+ addComponents();
+ }
+
+ /**
+ * Creates the actual GUI components, and adds it to this panel
+ */
+ private void addComponents() {
+ JNLPFile file = parent.getFile();
+
+ String topLabelText = "Only parts of this application code are signed.";
+ String infoLabelText = "This application contains both signed and" +
+ " unsigned code. While signed code is safe if you trust the " +
+ "provider, unsigned code may imply code outside of the trusted " +
+ "provider's control.";
+ String questionLabelText = "Do you wish to proceed and run this " +
+ "application anyway?";
+
+ ImageIcon icon = new ImageIcon((new sun.misc.Launcher()).getClassLoader().getResource("net/sourceforge/jnlp/resources/warning.png"));
+ JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT);
+ topLabel.setFont(new Font(topLabel.getFont().toString(),
+ Font.BOLD, 12));
+ JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.setBackground(Color.WHITE);
+ topPanel.add(topLabel, BorderLayout.CENTER);
+ topPanel.setPreferredSize(new Dimension(500,80));
+ topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ JLabel infoLabel = new JLabel(htmlWrap(infoLabelText));
+ JPanel infoPanel = new JPanel(new BorderLayout());
+ infoPanel.add(infoLabel, BorderLayout.CENTER);
+ infoPanel.setPreferredSize(new Dimension(500,100));
+ infoPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ JLabel questionLabel = new JLabel(htmlWrap(questionLabelText));
+ JPanel questionPanel = new JPanel(new BorderLayout());
+ questionPanel.add(questionLabel, BorderLayout.CENTER);
+ questionPanel.setPreferredSize(new Dimension(500,100));
+ questionPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //run and cancel buttons
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ JButton run = new JButton("Proceed");
+ JButton cancel = new JButton("Cancel");
+ run.addActionListener(createSetValueListener(parent,0));
+ cancel.addActionListener(createSetValueListener(parent, 1));
+ initialFocusComponent = cancel;
+ buttonPanel.add(run);
+ buttonPanel.add(cancel);
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //all of the above
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(topPanel);
+ add(infoPanel);
+ add(questionPanel);
+ add(buttonPanel);
+
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java b/netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java
new file mode 100644
index 0000000..f3b8ee8
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java
@@ -0,0 +1,134 @@
+ /* SecurityDialogPanel.java
+ Copyright (C) 2008-2010 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+/**
+ * Provides a JPanel for use in JNLP warning dialogs.
+ */
+public abstract class SecurityDialogPanel extends JPanel {
+
+ protected SecurityWarningDialog parent;
+
+ JComponent initialFocusComponent = null;
+
+ CertVerifier certVerifier = null;
+
+ public SecurityDialogPanel(SecurityWarningDialog dialog, CertVerifier certVerifier){
+ this.parent = dialog;
+ this.certVerifier = certVerifier;
+ this.setLayout(new BorderLayout());
+ }
+
+ public SecurityDialogPanel(SecurityWarningDialog dialog) {
+ this.parent = dialog;
+ this.setLayout(new BorderLayout());
+ }
+
+ /*
+ * String translation functions
+ */
+
+ protected static String R(String key) {
+ return JNLPRuntime.getMessage(key);
+ }
+
+ protected static String R(String key, Object param) {
+ return JNLPRuntime.getMessage(key, new Object[] {param});
+ }
+
+ /**
+ * Needed to get word wrap working in JLabels.
+ */
+ protected String htmlWrap (String s) {
+ return "<html>"+s+"</html>";
+ }
+
+ /**
+ * Create an ActionListener suitable for use with buttons. When this {@link ActionListener}
+ * is invoked, it will set the value of the {@link SecurityWarningDialog} and then dispossed.
+ *
+ * @param buttonIndex the index of the button. By convention 0 = Yes. 1 = No, 2 = Cancel
+ * @return
+ */
+ protected ActionListener createSetValueListener(SecurityWarningDialog dialog, int buttonIndex) {
+ return new SetValueHandler(dialog, buttonIndex);
+ }
+
+ @Override
+ public void setVisible(boolean aFlag) {
+ super.setVisible(aFlag);
+ requestFocusOnDefaultButton();
+ }
+
+ public void requestFocusOnDefaultButton() {
+ if (initialFocusComponent != null) {
+ initialFocusComponent.requestFocusInWindow();
+ }
+ }
+
+ /**
+ * Creates a handler that sets a dialog's value and then disposes it when activated
+ *
+ */
+ private class SetValueHandler implements ActionListener {
+
+ Integer buttonIndex;
+ SecurityWarningDialog dialog;
+
+ public SetValueHandler(SecurityWarningDialog dialog, int buttonIndex) {
+ this.dialog = dialog;
+ this.buttonIndex = buttonIndex;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dialog.setValue(buttonIndex);
+ dialog.dispose();
+ }
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/SecurityUtil.java b/netx/net/sourceforge/jnlp/security/SecurityUtil.java
new file mode 100644
index 0000000..2a63a21
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/SecurityUtil.java
@@ -0,0 +1,285 @@
+/* SecurityUtil.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+public class SecurityUtil {
+
+ private static final char[] password = "changeit".toCharArray();
+
+ public static String getTrustedCertsFilename() throws Exception{
+
+ String homeDir = JNLPRuntime.HOME_DIR;
+
+ if (homeDir == null) {
+ throw new Exception("Could not access home directory");
+ } else {
+ return JNLPRuntime.CERTIFICATES_FILE;
+ }
+ }
+
+ public static char[] getTrustedCertsPassword() {
+ return password;
+ }
+
+ /**
+ * Extracts the CN field from a Certificate principal string. Or, if it
+ * can't find that, return the principal unmodified.
+ *
+ * This is a simple (and hence 'wrong') version. See
+ * http://www.ietf.org/rfc/rfc2253.txt for all the gory details.
+ */
+ public static String getCN(String principal) {
+
+ /*
+ * FIXME Incomplete
+ *
+ * This does not implement RFC 2253 completely
+ *
+ * Issues:
+ * - rfc2253 talks about utf8, java uses utf16.
+ * - theoretically, java should have dealt with all byte encodings
+ * so we shouldnt even see cases like \FF
+ * - if the above is wrong, then we need to deal with cases like
+ * \FF\FF
+ */
+
+ int start = principal.indexOf("CN=");
+ if (start == -1) {
+ return principal;
+ }
+
+ StringBuilder commonName = new StringBuilder();
+
+ boolean inQuotes = false;
+ boolean escaped = false;
+
+ /*
+ * bit 0 = high order bit. bit 1 = low order bit
+ */
+ char[] hexBits = null;
+
+ for (int i = start + 3; i < principal.length(); i++) {
+ char ch = principal.charAt(i);
+ switch (ch) {
+ case '"':
+ if (escaped) {
+ commonName.append(ch);
+ escaped = false;
+ } else {
+ inQuotes = !inQuotes;
+ }
+ break;
+
+ case '\\':
+ if (escaped) {
+ commonName.append(ch);
+ escaped = false;
+ } else {
+ escaped = true;
+ }
+ break;
+
+ case ',':
+ /* fall through */
+ case ';':
+ /* fall through */
+ case '+':
+ if (escaped || inQuotes) {
+ commonName.append(ch);
+ if (escaped) {
+ escaped = false;
+ }
+ } else {
+ return commonName.toString();
+ }
+ break;
+
+ default:
+ if (escaped && isHexDigit(ch)) {
+ hexBits = new char[2];
+ hexBits[0] = ch;
+ } else if (hexBits != null) {
+ if (!isHexDigit(ch)) {
+ /* error parsing */
+ return "";
+ }
+ hexBits[1] = ch;
+ commonName.append((char) Integer.parseInt(new String(hexBits), 16));
+ hexBits = null;
+ } else {
+ commonName.append(ch);
+ }
+ escaped = false;
+ }
+ }
+
+ return commonName.toString();
+
+ }
+
+ private static boolean isHexDigit(char ch) {
+ return ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'));
+ }
+
+ /**
+ * Checks the user's home directory to see if the trusted.certs file exists.
+ * If it does not exist, it tries to create an empty keystore.
+ * @return true if the trusted.certs file exists or a new trusted.certs
+ * was created successfully, otherwise false.
+ */
+ public static boolean checkTrustedCertsFile() throws Exception {
+
+ File certFile = new File(getTrustedCertsFilename());
+
+ //file does not exist
+ if (!certFile.isFile()) {
+ File dir = certFile.getAbsoluteFile().getParentFile();
+ boolean madeDir = false;
+ if (!dir.isDirectory()) {
+ madeDir = dir.mkdirs();
+ }
+
+ //made directory, or directory exists
+ if (madeDir || dir.isDirectory()) {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, password);
+ FileOutputStream fos = new FileOutputStream(certFile);
+ ks.store(fos, password);
+ fos.close();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Returns the keystore associated with the user's trusted.certs file,
+ * or null otherwise.
+ */
+ public static KeyStore getUserKeyStore() throws Exception {
+
+ KeyStore ks = null;
+ FileInputStream fis = null;
+
+ if (checkTrustedCertsFile()) {
+
+ try {
+ File file = new File(getTrustedCertsFilename());
+ if (file.exists()) {
+ fis = new FileInputStream(file);
+ ks = KeyStore.getInstance("JKS");
+ ks.load(fis, password);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+ }
+ return ks;
+ }
+
+ /**
+ * Returns the keystore associated with the JDK cacerts file,
+ * or null otherwise.
+ */
+ public static KeyStore getCacertsKeyStore() throws Exception {
+
+ KeyStore caks = null;
+ FileInputStream fis = null;
+
+ try {
+ File file = new File(System.getProperty("java.home")
+ + "/lib/security/cacerts");
+ if (file.exists()) {
+ fis = new FileInputStream(file);
+ caks = KeyStore.getInstance("JKS");
+ caks.load(fis, null);
+ }
+ } catch (Exception e) {
+ caks = null;
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+
+ return caks;
+ }
+
+ /**
+ * Returns the keystore associated with the system certs file,
+ * or null otherwise.
+ */
+ public static KeyStore getSystemCertStore() throws Exception {
+
+ KeyStore caks = null;
+ FileInputStream fis = null;
+
+ try {
+ File file = new File(System.getProperty("javax.net.ssl.trustStore"));
+ String type = System.getProperty("javax.net.ssl.trustStoreType");
+ //String provider = "SUN";
+ char[] password = System.getProperty(
+ "javax.net.ssl.trustStorePassword").toCharArray();
+ if (file.exists()) {
+ fis = new FileInputStream(file);
+ caks = KeyStore.getInstance(type);
+ caks.load(fis, password);
+ }
+ } catch (Exception e) {
+ caks = null;
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+
+ return caks;
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java b/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java
new file mode 100644
index 0000000..14f5fe0
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java
@@ -0,0 +1,474 @@
+/* SecurityWarningDialog.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+import java.awt.event.*;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * Provides methods for showing security warning dialogs
+ * for a wide range of JNLP security issues.
+ *
+ * @author <a href="mailto:[email protected]">Joshua Sumali</a>
+ */
+public class SecurityWarningDialog extends JDialog {
+
+ /** Types of dialogs we can create */
+ public static enum DialogType {
+ CERT_WARNING,
+ MORE_INFO,
+ CERT_INFO,
+ SINGLE_CERT_INFO,
+ ACCESS_WARNING,
+ NOTALLSIGNED_WARNING,
+ APPLET_WARNING
+ }
+
+ /** The types of access which may need user permission. */
+ public static enum AccessType {
+ READ_FILE,
+ WRITE_FILE,
+ CREATE_DESTKOP_SHORTCUT,
+ CLIPBOARD_READ,
+ CLIPBOARD_WRITE,
+ PRINTER,
+ NETWORK,
+ VERIFIED,
+ UNVERIFIED,
+ NOTALLSIGNED,
+ SIGNING_ERROR
+ }
+
+ /** The type of dialog we want to show */
+ private DialogType dialogType;
+
+ /** The type of access that this dialog is for */
+ private AccessType accessType;
+
+ private SecurityDialogPanel panel;
+
+ /** The application file associated with this security warning */
+ private JNLPFile file;
+
+ private CertVerifier certVerifier;
+
+ private X509Certificate cert;
+
+ /** An optional String array that's only necessary when a dialog
+ * label requires some parameters (e.g. showing which address an application
+ * is trying to connect to).
+ */
+ private Object[] extras;
+
+ /** Whether or not this object has been fully initialized */
+ private boolean initialized = false;
+
+ /**
+ * the return value of this dialog. result: 0 = Yes, 1 = No, 2 = Cancel,
+ * null = Window closed.
+ */
+ private Object value;
+
+ public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
+ JNLPFile file) {
+ super();
+ this.dialogType = dialogType;
+ this.accessType = accessType;
+ this.file = file;
+ this.certVerifier = null;
+ initialized = true;
+ initDialog();
+ }
+
+ public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
+ JNLPFile file, CertVerifier jarSigner) {
+ super();
+ this.dialogType = dialogType;
+ this.accessType = accessType;
+ this.file = file;
+ this.certVerifier = jarSigner;
+ initialized = true;
+ initDialog();
+ }
+
+ public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
+ CertVerifier certVerifier) {
+ super();
+ this.dialogType = dialogType;
+ this.accessType = accessType;
+ this.file = null;
+ this.certVerifier = certVerifier;
+ initialized = true;
+ initDialog();
+ }
+
+ public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
+ JNLPFile file, Object[] extras) {
+ super();
+ this.dialogType = dialogType;
+ this.accessType = accessType;
+ this.file = file;
+ this.certVerifier = null;
+ initialized = true;
+ this.extras = extras;
+ initDialog();
+ }
+
+ //for displaying a single certificate
+ public SecurityWarningDialog(DialogType dialogType, X509Certificate c) {
+ super();
+ this.dialogType = dialogType;
+ this.accessType = null;
+ this.file = null;
+ this.certVerifier = null;
+ this.cert = c;
+ initialized = true;
+ initDialog();
+ }
+
+ /**
+ * Returns if this dialog has been fully initialized yet.
+ * @return true if this dialog has been initialized, and false otherwise.
+ */
+ public boolean isInitialized(){
+ return initialized;
+ }
+
+ /**
+ * Shows a warning dialog for different types of system access (i.e. file
+ * open/save, clipboard read/write, printing, etc).
+ *
+ * @param accessType the type of system access requested.
+ * @param file the jnlp file associated with the requesting application.
+ * @return true if permission was granted by the user, false otherwise.
+ */
+ public static boolean showAccessWarningDialog(AccessType accessType,
+ JNLPFile file) {
+ return showAccessWarningDialog(accessType, file, null);
+ }
+
+ /**
+ * Shows a warning dialog for different types of system access (i.e. file
+ * open/save, clipboard read/write, printing, etc).
+ *
+ * @param accessType the type of system access requested.
+ * @param file the jnlp file associated with the requesting application.
+ * @param extras an optional array of Strings (typically) that gets
+ * passed to the dialog labels.
+ * @return true if permission was granted by the user, false otherwise.
+ */
+ public static boolean showAccessWarningDialog(AccessType accessType,
+ JNLPFile file, Object[] extras) {
+ SecurityWarningDialog dialog = new SecurityWarningDialog(
+ DialogType.ACCESS_WARNING, accessType, file, extras);
+ dialog.setVisible(true);
+ dialog.dispose();
+
+ Object selectedValue = dialog.getValue();
+ if (selectedValue == null) {
+ return false;
+ } else if (selectedValue instanceof Integer) {
+ if (((Integer)selectedValue).intValue() == 0)
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Shows a warning dialog for when the main application jars are signed,
+ * but extensions aren't
+ *
+ * @return true if permission was granted by the user, false otherwise.
+ */
+ public static boolean showNotAllSignedWarningDialog(JNLPFile file) {
+ SecurityWarningDialog dialog = new SecurityWarningDialog(
+ DialogType.NOTALLSIGNED_WARNING, AccessType.NOTALLSIGNED, file, (new Object[0]));
+ dialog.setVisible(true);
+ dialog.dispose();
+
+ Object selectedValue = dialog.getValue();
+ if (selectedValue == null) {
+ return false;
+ } else if (selectedValue instanceof Integer) {
+ if (((Integer)selectedValue).intValue() == 0)
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Shows a security warning dialog according to the specified type of
+ * access. If <code>type</code> is one of AccessType.VERIFIED or
+ * AccessType.UNVERIFIED, extra details will be available with regards
+ * to code signing and signing certificates.
+ *
+ * @param accessType the type of warning dialog to show
+ * @param file the JNLPFile associated with this warning
+ * @param jarSigner the JarSigner used to verify this application
+ */
+ public static boolean showCertWarningDialog(AccessType accessType,
+ JNLPFile file, CertVerifier jarSigner) {
+ SecurityWarningDialog dialog =
+ new SecurityWarningDialog(DialogType.CERT_WARNING, accessType, file,
+ jarSigner);
+ dialog.setVisible(true);
+ dialog.dispose();
+
+ Object selectedValue = dialog.getValue();
+ if (selectedValue == null) {
+ return false;
+ } else if (selectedValue instanceof Integer) {
+ if (((Integer)selectedValue).intValue() == 0)
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Shows more information regarding jar code signing
+ *
+ * @param jarSigner the JarSigner used to verify this application
+ * @param parent the parent option pane
+ */
+ public static void showMoreInfoDialog(
+ CertVerifier jarSigner, SecurityWarningDialog parent) {
+
+ SecurityWarningDialog dialog =
+ new SecurityWarningDialog(DialogType.MORE_INFO, null, null,
+ jarSigner);
+ dialog.setVisible(true);
+ dialog.dispose();
+ }
+
+ /**
+ * Displays CertPath information in a readable table format.
+ *
+ * @param certs the certificates used in signing.
+ */
+ public static void showCertInfoDialog(CertVerifier jarSigner,
+ SecurityWarningDialog parent) {
+ SecurityWarningDialog dialog = new SecurityWarningDialog(DialogType.CERT_INFO,
+ null, null, jarSigner);
+ dialog.setLocationRelativeTo(parent);
+ dialog.setVisible(true);
+ dialog.dispose();
+ }
+
+ /**
+ * Displays a single certificate's information.
+ *
+ * @param c
+ * @param optionPane
+ */
+ public static void showSingleCertInfoDialog(X509Certificate c,
+ JDialog parent) {
+ SecurityWarningDialog dialog = new SecurityWarningDialog(DialogType.SINGLE_CERT_INFO, c);
+ dialog.setLocationRelativeTo(parent);
+ dialog.setVisible(true);
+ dialog.dispose();
+ }
+
+ public static int showAppletWarning() {
+ SecurityWarningDialog dialog = new SecurityWarningDialog(DialogType.APPLET_WARNING,
+ null, null, (CertVerifier) null);
+ dialog.setVisible(true);
+ dialog.dispose();
+
+ Object selectedValue = dialog.getValue();
+
+ //result 0 = Yes, 1 = No, 2 = Cancel
+ if (selectedValue == null) {
+ return 2;
+ } else if (selectedValue instanceof Integer) {
+ return ((Integer)selectedValue).intValue();
+ } else {
+ return 2;
+ }
+ }
+
+ private void initDialog() {
+ setSystemLookAndFeel();
+
+ String dialogTitle = "";
+ if (dialogType == DialogType.CERT_WARNING)
+ dialogTitle = "Warning - Security";
+ else if (dialogType == DialogType.MORE_INFO)
+ dialogTitle = "More Information";
+ else if (dialogType == DialogType.CERT_INFO)
+ dialogTitle = "Details - Certificate";
+ else if (dialogType == DialogType.ACCESS_WARNING)
+ dialogTitle = "Security Warning";
+ else if (dialogType == DialogType.APPLET_WARNING)
+ dialogTitle = "Applet Warning";
+ else if (dialogType == DialogType.NOTALLSIGNED_WARNING)
+ dialogTitle = "Security Warning";
+
+ setTitle(dialogTitle);
+ setModal(true);
+
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+
+ installPanel();
+
+ pack();
+
+ WindowAdapter adapter = new WindowAdapter() {
+ private boolean gotFocus = false;
+ @Override
+ public void windowClosing(WindowEvent we) {
+ setValue(null);
+ }
+ @Override
+ public void windowGainedFocus(WindowEvent we) {
+ // Once window gets focus, set initial focus
+ if (!gotFocus) {
+ selectDefaultButton();
+ gotFocus = true;
+ }
+ }
+ @Override
+ public void windowOpened(WindowEvent e) {
+ if (e.getSource() instanceof SecurityWarningDialog) {
+ SecurityWarningDialog dialog = (SecurityWarningDialog) e.getSource();
+ dialog.setResizable(true);
+ centerDialog(dialog);
+ dialog.setValue(null);
+ }
+ }
+ };
+ addWindowListener(adapter);
+ addWindowFocusListener(adapter);
+
+ }
+
+ public AccessType getAccessType() {
+ return accessType;
+ }
+
+ public JNLPFile getFile() {
+ return file;
+ }
+
+ public CertVerifier getJarSigner() {
+ return certVerifier;
+ }
+
+ public X509Certificate getCert() {
+ return cert;
+ }
+
+ /**
+ * Adds the appropriate JPanel to this Dialog, based on {@link DialogType}.
+ */
+ private void installPanel() {
+
+ if (dialogType == DialogType.CERT_WARNING)
+ panel = new CertWarningPane(this, this.certVerifier);
+ else if (dialogType == DialogType.MORE_INFO)
+ panel = new MoreInfoPane(this, this.certVerifier);
+ else if (dialogType == DialogType.CERT_INFO)
+ panel = new CertsInfoPane(this, this.certVerifier);
+ else if (dialogType == DialogType.SINGLE_CERT_INFO)
+ panel = new SingleCertInfoPane(this, this.certVerifier);
+ else if (dialogType == DialogType.ACCESS_WARNING)
+ panel = new AccessWarningPane(this, extras, this.certVerifier);
+ else if (dialogType == DialogType.APPLET_WARNING)
+ panel = new AppletWarningPane(this, this.certVerifier);
+ else if (dialogType == DialogType.NOTALLSIGNED_WARNING)
+ panel = new NotAllSignedWarningPane(this);
+
+ add(panel, BorderLayout.CENTER);
+ }
+
+ private static void centerDialog(JDialog dialog) {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension dialogSize = dialog.getSize();
+
+ dialog.setLocation((screen.width - dialogSize.width)/2,
+ (screen.height - dialogSize.height)/2);
+ }
+
+ private void selectDefaultButton() {
+ if (panel == null) {
+ System.out.println("initial value panel is null");
+ }
+ panel.requestFocusOnDefaultButton();
+ }
+
+ protected void setValue(Object value) {
+ if (JNLPRuntime.isDebug()) {
+ System.out.println("Setting value:" + value);
+ }
+ this.value = value;
+ }
+
+ protected Object getValue() {
+ if (JNLPRuntime.isDebug()) {
+ System.out.println("Returning value:" + value);
+ }
+ return value;
+ }
+
+ /**
+ * Updates the look and feel of the window to be the system look and feel
+ */
+ protected void setSystemLookAndFeel() {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ //don't worry if we can't.
+ }
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java b/netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java
new file mode 100644
index 0000000..59b8ab8
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java
@@ -0,0 +1,77 @@
+/* SingleCertInfoPane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeSelectionModel;
+
+
+public class SingleCertInfoPane extends CertsInfoPane {
+
+ public SingleCertInfoPane(SecurityWarningDialog x, CertVerifier certVerifier) {
+ super(x, certVerifier);
+ }
+
+ protected void buildTree() {
+ X509Certificate cert = parent.getCert();
+ String subjectString =
+ SecurityUtil.getCN(cert.getSubjectX500Principal().getName());
+ String issuerString =
+ SecurityUtil.getCN(cert.getIssuerX500Principal().getName());
+
+ DefaultMutableTreeNode top = new DefaultMutableTreeNode(subjectString
+ + " (" + issuerString + ")");
+
+ tree = new JTree(top);
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ tree.addTreeSelectionListener(new TreeSelectionHandler());
+ }
+
+ protected void populateTable() {
+ X509Certificate c = parent.getCert();
+ certNames = new String[1];
+ certsData = new ArrayList<String[][]>();
+ certsData.add(parseCert(c));
+ certNames[0] = SecurityUtil.getCN(c.getSubjectX500Principal().getName())
+ + " (" + SecurityUtil.getCN(c.getIssuerX500Principal().getName()) + ")";
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
new file mode 100644
index 0000000..d5ad6da
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
@@ -0,0 +1,314 @@
+/* VariableX509TrustManager.java
+ Copyright (C) 2009 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security;
+
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import sun.security.util.HostnameChecker;
+import sun.security.validator.ValidatorException;
+
+import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
+
+/**
+ * This class implements an X509 Trust Manager. The certificates it trusts are
+ * "variable", in the sense that it can dynamically, and temporarily support
+ * different certificates that are not in the keystore.
+ */
+
+public class VariableX509TrustManager extends X509ExtendedTrustManager {
+
+ KeyStore userKeyStore = null;
+ KeyStore caKeyStore = null;
+
+ X509TrustManager userTrustManager = null;
+ X509TrustManager caTrustManager = null;
+
+ ArrayList<Certificate> temporarilyTrusted = new ArrayList<Certificate>();
+ ArrayList<Certificate> temporarilyUntrusted = new ArrayList<Certificate>();
+
+ static VariableX509TrustManager instance = null;
+
+ /**
+ * Constructor initializes the system, user and custom stores
+ */
+ public VariableX509TrustManager() {
+
+ try {
+ userKeyStore = SecurityUtil.getUserKeyStore();
+ TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
+ tmFactory.init(userKeyStore);
+
+ // tm factory initialized, now get the managers so we can assign the X509 one
+ TrustManager[] trustManagers = tmFactory.getTrustManagers();
+
+ for (int i=0; i < trustManagers.length; i++) {
+ if (trustManagers[i] instanceof X509TrustManager) {
+ userTrustManager = (X509TrustManager) trustManagers[i];
+ }
+ }
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ try {
+ caKeyStore = SecurityUtil.getCacertsKeyStore();
+ TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
+ tmFactory.init(caKeyStore);
+
+ // tm factory initialized, now get the managers so we can extract the X509 one
+ TrustManager[] trustManagers = tmFactory.getTrustManagers();
+
+ for (int i=0; i < trustManagers.length; i++) {
+ if (trustManagers[i] instanceof X509TrustManager) {
+ caTrustManager = (X509TrustManager) trustManagers[i];
+ }
+ }
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Check if client is trusted (no support for custom here, only system/user)
+ */
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ String hostName, String algorithm)
+ throws CertificateException {
+ // First try catrustmanager, then try usertrustmanager
+ try {
+ caTrustManager.checkClientTrusted(chain, authType);
+ } catch (Exception caex) {
+ try {
+ userTrustManager.checkClientTrusted(chain, authType);
+ } catch (Exception userex) {
+ // Do nothing here. This trust manager is intended to be used
+ // only in the plugin instance vm, which does not act as a
+ // server
+ }
+ }
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ checkClientTrusted(chain, authType, null, null);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ String hostName, String algorithm)
+ throws CertificateException {
+ checkServerTrusted(chain, authType, hostName, false);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ checkServerTrusted(chain, authType, null, null);
+ }
+
+ /**
+ * Check if the server is trusted
+ *
+ * @param chain The cert chain
+ * @param authType The auth type algorithm
+ * @param checkOnly Whether to "check only" i.e. no user prompt, or to prompt for permission
+ */
+ public synchronized void checkServerTrusted(X509Certificate[] chain,
+ String authType, String hostName,
+ boolean checkOnly) throws CertificateException {
+ CertificateException ce = null;
+ boolean trusted = true;
+ boolean CNMatched = true;
+
+ try {
+ checkAllManagers(chain, authType);
+ } catch (CertificateException e) {
+ trusted = false;
+ ce = e;
+ }
+
+ // If the certificate is not explicitly trusted, we
+ // need to prompt the user
+ if (!isExplicitlyTrusted(chain, authType)) {
+
+ try {
+ HostnameChecker checker = HostnameChecker
+ .getInstance(HostnameChecker.TYPE_TLS);
+
+ checker.match(hostName, chain[0]); // only need to match @ 0 for
+ // CN
+
+ } catch (CertificateException e) {
+ CNMatched = false;
+ ce = e;
+ }
+ }
+
+ if (!trusted || !CNMatched) {
+ if (checkOnly) {
+ throw ce;
+ } else {
+ if (!isTemporarilyUntrusted(chain[0])) {
+ boolean b = askUser(chain, authType, trusted, CNMatched, hostName);
+
+ if (b) {
+ temporarilyTrust(chain[0]);
+ } else {
+ temporarilyUntrust(chain[0]);
+ }
+ }
+
+ checkAllManagers(chain, authType);
+ }
+ }
+ }
+
+ /**
+ * Check system, user and custom trust manager
+ */
+ private void checkAllManagers(X509Certificate[] chain, String authType) throws CertificateException {
+ // First try catrustmanager, then try usertrustmanager, and finally, check temp trusted certs
+ try {
+ caTrustManager.checkServerTrusted(chain, authType);
+ } catch (ValidatorException caex) {
+ try {
+ userTrustManager.checkServerTrusted(chain, authType);
+ } catch (ValidatorException uex) {
+ if (!temporarilyTrusted.contains(chain[0]))
+ throw (CertificateException) uex;
+ }
+ }
+ }
+
+ /**
+ * Return if the user explicitly trusted this i.e. in userTrustManager or temporarilyTrusted
+ */
+ private boolean isExplicitlyTrusted(X509Certificate[] chain, String authType) {
+ boolean explicitlyTrusted = false;
+
+ try {
+ userTrustManager.checkServerTrusted(chain, authType);
+ explicitlyTrusted = true;
+ } catch (ValidatorException uex) {
+ if (temporarilyTrusted.contains(chain[0]))
+ explicitlyTrusted = true;
+ } catch (CertificateException ce) {
+ // do nothing, this means that the cert is not explicitly trusted
+ }
+
+ return explicitlyTrusted;
+
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ // delegate to default
+ return caTrustManager.getAcceptedIssuers();
+ }
+
+ /**
+ * Temporarily untrust the given cert - do not ask the user to trust this
+ * certificate again
+ *
+ * @param c The certificate to trust
+ */
+ private void temporarilyUntrust(Certificate c) {
+ temporarilyUntrusted.add(c);
+ }
+
+ /**
+ * Was this certificate explicitly untrusted by user?
+ *
+ * @param c the certificate
+ * @return true if the user was presented with this certificate and chose
+ * not to trust it
+ */
+ private boolean isTemporarilyUntrusted(Certificate c) {
+ if (temporarilyUntrusted.contains(c)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Temporarily trust the given cert (runtime)
+ *
+ * @param c The certificate to trust
+ */
+ private void temporarilyTrust(Certificate c) {
+ temporarilyTrusted.add(c);
+ }
+
+ /**
+ * Ask user if the certificate should be trusted
+ *
+ * @param chain The certificate chain
+ * @param authType The authentication algorithm
+ * @return user's response
+ */
+ private boolean askUser(X509Certificate[] chain, String authType,
+ boolean isTrusted, boolean hostMatched,
+ String hostName) {
+ return SecurityWarningDialog.showCertWarningDialog(
+ SecurityWarningDialog.AccessType.UNVERIFIED, null,
+ new HttpsCertVerifier(this, chain, authType,
+ isTrusted, hostMatched,
+ hostName));
+ }
+
+ /**
+ * Return an instance of this singleton
+ *
+ * @return The instance
+ */
+ public static VariableX509TrustManager getInstance() {
+ if (instance == null)
+ instance = new VariableX509TrustManager();
+
+ return instance;
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java b/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java
new file mode 100644
index 0000000..69b98b4
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java
@@ -0,0 +1,335 @@
+/* CertificatePane.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+
+import net.sourceforge.jnlp.security.SecurityUtil;
+import net.sourceforge.jnlp.security.SecurityWarningDialog;
+import net.sourceforge.jnlp.tools.KeyTool;
+
+public class CertificatePane extends JPanel {
+
+ /**
+ * The certificates stored in the user's trusted.certs file.
+ */
+ private ArrayList<X509Certificate> certs = null;
+
+ /**
+ * "Issued To" and "Issued By" string pairs for certs.
+ */
+ private String[][] issuedToAndBy = null;
+ private final String[] columnNames = { "Issued To", "Issued By" };
+
+ private JTable table;
+
+ private JDialog parent;
+
+ private JComponent defaultFocusComponent = null;
+
+ /**
+ * The KeyStore associated with the user's trusted.certs file.
+ */
+ private KeyStore keyStore = null;
+
+ public CertificatePane(JDialog parent) {
+ super();
+ this.parent = parent;
+ initializeKeyStore();
+ addComponents();
+ }
+
+ /**
+ * Reads the user's trusted.cacerts keystore.
+ */
+ private void initializeKeyStore() {
+ try {
+ keyStore = SecurityUtil.getUserKeyStore();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ //create the GUI here.
+ protected void addComponents() {
+ readKeyStore();
+
+ JPanel main = new JPanel(new BorderLayout());
+
+ JPanel tablePanel = new JPanel(new BorderLayout());
+
+ //Table
+ DefaultTableModel tableModel
+ = new DefaultTableModel(issuedToAndBy, columnNames);
+ table = new JTable(tableModel);
+ table.getTableHeader().setReorderingAllowed(false);
+ table.setFillsViewportHeight(true);
+ JScrollPane tablePane = new JScrollPane(table);
+ tablePane.setPreferredSize(new Dimension(500,200));
+ tablePane.setSize(new Dimension(500,200));
+ tablePane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ JTabbedPane tabbedPane = new JTabbedPane();
+ tabbedPane.addTab("User", tablePane);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+
+ String[] buttonNames = {"Import", "Export", "Remove", "Details"};
+ char[] buttonMnemonics = { KeyEvent.VK_I,
+ KeyEvent.VK_E,
+ KeyEvent.VK_M,
+ KeyEvent.VK_D};
+ ActionListener[] listeners = { new ImportButtonListener(),
+ new ExportButtonListener(),
+ new RemoveButtonListener(),
+ new DetailsButtonListener() };
+ JButton button;
+
+ //get the max width
+ int maxWidth = 0;
+ for (int i = 0; i < buttonNames.length; i++) {
+ button = new JButton(buttonNames[i]);
+ maxWidth = Math.max(maxWidth, button.getMinimumSize().width);
+ }
+
+ for (int i = 0; i < buttonNames.length; i++) {
+ button = new JButton(buttonNames[i]);
+ button.setMnemonic(buttonMnemonics[i]);
+ button.addActionListener(listeners[i]);
+ button.setSize(maxWidth, button.getSize().height);
+ buttonPanel.add(button);
+ }
+
+ tablePanel.add(tabbedPane, BorderLayout.CENTER);
+ tablePanel.add(buttonPanel, BorderLayout.SOUTH);
+
+ JPanel closePanel = new JPanel(new BorderLayout());
+ closePanel.setBorder(BorderFactory.createEmptyBorder(7,7,7,7));
+ JButton closeButton = new JButton("Close");
+ closeButton.addActionListener(new CloseButtonListener());
+ defaultFocusComponent = closeButton;
+ closePanel.add(closeButton, BorderLayout.EAST);
+
+ main.add(tablePanel, BorderLayout.CENTER);
+ main.add(closePanel, BorderLayout.SOUTH);
+
+ add(main);
+
+ }
+
+ /**
+ * Read in the optionPane's keystore to issuedToAndBy.
+ */
+ private void readKeyStore() {
+
+ Enumeration<String> aliases = null;
+ certs = new ArrayList<X509Certificate>();
+ try {
+
+ //Get all of the X509Certificates and put them into an ArrayList
+ aliases = keyStore.aliases();
+ while (aliases.hasMoreElements()) {
+ Certificate c = keyStore.getCertificate(aliases.nextElement());
+ if (c instanceof X509Certificate)
+ certs.add((X509Certificate)c);
+ }
+
+ //get the publisher and root information
+ issuedToAndBy = new String[certs.size()][2];
+ for (int i = 0; i < certs.size(); i++) {
+ X509Certificate c = certs.get(i);
+ issuedToAndBy[i][0] =
+ SecurityUtil.getCN(c.getSubjectX500Principal().getName());
+ issuedToAndBy[i][1] =
+ SecurityUtil.getCN(c.getIssuerX500Principal().getName());
+ }
+ } catch (Exception e) {
+ //TODO
+ }
+ }
+
+ /**
+ * Re-reads the certs file and repopulates the JTable. This is typically
+ * called after a certificate was deleted from the keystore.
+ */
+ private void repopulateTable() {
+ initializeKeyStore();
+ readKeyStore();
+ DefaultTableModel tableModel
+ = new DefaultTableModel(issuedToAndBy, columnNames);
+
+ table.setModel(tableModel);
+ repaint();
+ }
+
+ public void focusOnDefaultButton() {
+ if (defaultFocusComponent != null) {
+ defaultFocusComponent.requestFocusInWindow();
+ }
+ }
+
+ private class ImportButtonListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JFileChooser chooser = new JFileChooser();
+ int returnVal = chooser.showOpenDialog(parent);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ try {
+ KeyTool kt = new KeyTool();
+ kt.importCert(chooser.getSelectedFile());
+ repopulateTable();
+ } catch (Exception ex) {
+ // TODO: handle exception
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private class ExportButtonListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ //For now, let's just export in -rfc mode as keytool does.
+ //we'll write to a file the exported certificate.
+
+
+ try {
+ int selectedRow = table.getSelectedRow();
+ if (selectedRow != -1) {
+ JFileChooser chooser = new JFileChooser();
+ int returnVal = chooser.showOpenDialog(parent);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ String alias = keyStore.getCertificateAlias(certs
+ .get(selectedRow));
+ if (alias != null) {
+ Certificate c = keyStore.getCertificate(alias);
+ PrintStream ps = new PrintStream(chooser.getSelectedFile().getAbsolutePath());
+ KeyTool.dumpCert(c, ps);
+ repopulateTable();
+ }
+ }
+ }
+ } catch (Exception ex) {
+ // TODO
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private class RemoveButtonListener implements ActionListener {
+
+ /**
+ * Removes a certificate from the keyStore and writes changes to disk.
+ */
+ public void actionPerformed(ActionEvent e) {
+
+ try {
+ int selectedRow = table.getSelectedRow();
+
+ if (selectedRow != -1){
+ String alias = keyStore.getCertificateAlias(certs.get(selectedRow));
+ if (alias != null) {
+
+ int i = JOptionPane.showConfirmDialog(parent,
+ "Are you sure you want to remove the selected certificate?",
+ "Confirmation - Remove Certificate?",
+ JOptionPane.YES_NO_OPTION);
+ if (i == 0) {
+ keyStore.deleteEntry(alias);
+ FileOutputStream fos = new FileOutputStream(
+ SecurityUtil.getTrustedCertsFilename());
+ keyStore.store(fos, SecurityUtil.getTrustedCertsPassword());
+ fos.close();
+ }
+ }
+ repopulateTable();
+ }
+ } catch (Exception ex) {
+ // TODO
+ ex.printStackTrace();
+ }
+
+ }
+ }
+
+ private class DetailsButtonListener implements ActionListener {
+
+ /**
+ * Shows the details of a trusted certificate.
+ */
+ public void actionPerformed(ActionEvent e) {
+
+ int selectedRow = table.getSelectedRow();
+ if (selectedRow != -1 && selectedRow >= 0) {
+ X509Certificate c = certs.get(selectedRow);
+ SecurityWarningDialog.showSingleCertInfoDialog(c, parent);
+ }
+ }
+ }
+
+ private class CloseButtonListener implements ActionListener {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ parent.dispose();
+ }
+ }
+
+}
diff --git a/netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java b/netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java
new file mode 100644
index 0000000..403472c
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java
@@ -0,0 +1,120 @@
+/* CertificateViewer.java
+ Copyright (C) 2008 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+package net.sourceforge.jnlp.security.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JDialog;
+import javax.swing.UIManager;
+
+public class CertificateViewer extends JDialog {
+
+ private boolean initialized = false;
+ private static final String dialogTitle = "Certificates";
+
+ CertificatePane panel;
+
+ public CertificateViewer() {
+ super((Frame)null, dialogTitle, true);
+
+ Container contentPane = getContentPane();
+ contentPane.setLayout(new BorderLayout());
+
+ panel = new CertificatePane(this);
+
+ add(panel);
+
+ pack();
+
+ WindowAdapter adapter = new WindowAdapter() {
+ private boolean gotFocus = false;
+
+ public void windowGainedFocus(WindowEvent we) {
+ // Once window gets focus, set initial focus
+ if (!gotFocus) {
+ panel.focusOnDefaultButton();
+ gotFocus = true;
+ }
+ }
+ };
+ addWindowFocusListener(adapter);
+
+ initialized = true;
+ }
+
+ public boolean isInitialized(){
+ return initialized;
+ }
+
+ private void centerDialog() {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension dialogSize = getSize();
+
+ setLocation((screen.width - dialogSize.width)/2,
+ (screen.height - dialogSize.height)/2);
+ }
+
+
+ public static void showCertificateViewer() throws Exception {
+ setSystemLookAndFeel();
+
+ CertificateViewer cv = new CertificateViewer();
+ cv.setResizable(true);
+ cv.centerDialog();
+ cv.setVisible(true);
+ cv.dispose();
+ }
+
+ private static void setSystemLookAndFeel() {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ // don't worry if we can't.
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ CertificateViewer.showCertificateViewer();
+ }
+}