/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester   
 * 
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 * 
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *    
 *  This program 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
 *  Lesser General Public License for more details.
 *    
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.activities.wsdl.servicedescriptions;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.math.BigInteger;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.JSeparator;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;

import net.sf.taverna.t2.lang.ui.DialogTextArea;
import net.sf.taverna.t2.security.credentialmanager.CMException;
import net.sf.taverna.t2.security.credentialmanager.CMUtils;
import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;

import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.misc.NetscapeCertType;

/**
 * Displays the details of a X.509 certificate and asks user if they want to
 * trust it.
 * 
 * @author Alex Nenadic
 */
@SuppressWarnings("serial")
public class ConfirmTrustedCertificateDialog extends HelpEnabledDialog {
	
	private static Logger logger = Logger.getLogger(ConfirmTrustedCertificateDialog.class);

	// Stores certificate to display
	private X509Certificate cert;

	// Stores user's decision as whether to trust this service's certificaet or not.
	private boolean shouldTrust;

	/**
	 * Creates new ConfirmTrustedCertificateDialog where parent is a Frame.
	 */
	public ConfirmTrustedCertificateDialog(Frame parent, String title,
			boolean modal, X509Certificate crt)
			throws CMException {
		super(parent, title, modal, null);
		this.cert = crt;
		initComponents();
	}
	
	/**
	 * Creates new ConfirmTrustedCertificateDialog where parent is a Dialog.
	 */
	public ConfirmTrustedCertificateDialog(Dialog parent, String title,
			boolean modal, X509Certificate crt)
			throws CMException {
		super(parent, title, modal, null);
		this.cert = crt;
		initComponents();
	}

	/**
	 * Initialise the dialog's GUI components.
	 */
	private void initComponents(){
		
		// title panel
		JPanel titlePanel = new JPanel(new BorderLayout());
		titlePanel.setBackground(Color.WHITE);
		JLabel titleLabel = new JLabel("View service's certificate");
		titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 13.5f));
		titleLabel.setBorder(new EmptyBorder(10, 10, 0, 10));
		DialogTextArea titleMessage = new DialogTextArea("This service requires HTTPS connection and has identified itself with the certificate below.\n" +
				"Do you want to trust this service? (Refusing to trust means you will not be able to invoke it from a workflow.)");
		titleMessage.setMargin(new Insets(5, 20, 10, 10));
		titleMessage.setFont(titleMessage.getFont().deriveFont(11f));
		titleMessage.setEditable(false);
		titleMessage.setFocusable(false);
		titlePanel.setBorder( new EmptyBorder(10, 10, 0, 10));
		titlePanel.add(titleLabel, BorderLayout.NORTH);
		titlePanel.add(titleMessage, BorderLayout.CENTER);
		
		// Certificate details:

		// Grid Bag Constraints templates for labels (column 1) and
		// values (column 2) of certificate details
		GridBagConstraints gbcLabel = new GridBagConstraints();
		gbcLabel.gridx = 0;
		gbcLabel.ipadx = 20;
		gbcLabel.gridwidth = 1;
		gbcLabel.gridheight = 1;
		gbcLabel.insets = new Insets(2, 15, 2, 2);
		gbcLabel.anchor = GridBagConstraints.LINE_START;

		GridBagConstraints gbcValue = new GridBagConstraints();
		gbcValue.gridx = 1;
		gbcValue.gridwidth = 1;
		gbcValue.gridheight = 1;
		gbcValue.insets = new Insets(2, 5, 2, 2);
		gbcValue.anchor = GridBagConstraints.LINE_START;

		// Netscape Certificate Type non-critical extension (if any)
		// defines the intended uses of the certificate - to make it look like
		// firefox's view certificate dialog
		byte[] intendedUses = cert.getExtensionValue("2.16.840.1.113730.1.1"); // Netscape Certificate Type OID
		JLabel jlIntendedUses = null;
		JTextField jtfIntendedUsesValue = null;
		JPanel jpUses = null;
		GridBagConstraints gbc_jpUses = null;
		if (intendedUses != null) {
			jlIntendedUses = new JLabel(
					"This certificate has been approved for the following uses:");
			jlIntendedUses.setFont(new Font(null, Font.BOLD, 11));
			jlIntendedUses.setBorder(new EmptyBorder(5, 5, 5, 5));

			jtfIntendedUsesValue = new JTextField(45);
			jtfIntendedUsesValue.setText(getIntendedUses(intendedUses));
			jtfIntendedUsesValue.setEditable(false);
			jtfIntendedUsesValue.setFont(new Font(null, Font.PLAIN, 11));

			jpUses = new JPanel(new BorderLayout());
			jpUses.add(jlIntendedUses, BorderLayout.NORTH);
			jpUses.add(jtfIntendedUsesValue, BorderLayout.CENTER);
			JSeparator jsp = new JSeparator(JSeparator.HORIZONTAL);
			jpUses.add(jsp, BorderLayout.SOUTH);

			gbc_jpUses = (GridBagConstraints) gbcLabel.clone();
			gbc_jpUses.gridy = 0;
			gbc_jpUses.gridwidth = 2; // takes two columns
			gbc_jpUses.insets = new Insets(5, 5, 5, 5);// has slightly bigger insets
		}

		// Issued To
		JLabel jlIssuedTo = new JLabel("Issued To");
		jlIssuedTo.setFont(new Font(null, Font.BOLD, 11));
		GridBagConstraints gbc_jlIssuedTo = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlIssuedTo.gridy = 1;
		gbc_jlIssuedTo.gridwidth = 2; // takes two columns
		gbc_jlIssuedTo.insets = new Insets(5, 5, 5, 5);// has slightly bigger insets
		// Distinguished Name (DN)
		String sDN = cert.getSubjectX500Principal().getName(
				X500Principal.RFC2253);
		CMUtils util = new CMUtils();
		util.parseDN(sDN);
		// Extract the CN, O, OU and EMAILADDRESS fields
		String sCN = util.getCN();
		String sOrg = util.getO();
		String sOU = util.getOU();
		// String sEMAILADDRESS = CMX509Util.getEmilAddress();
		// Common Name (CN)
		JLabel jlCN = new JLabel("Common Name (CN)");
		jlCN.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlCN = (GridBagConstraints) gbcLabel.clone();
		gbc_jlCN.gridy = 2;
		JLabel jlCNValue = new JLabel(sCN);
		jlCNValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlCNValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlCNValue.gridy = 2;
		// Organisation (O)
		JLabel jlOrg = new JLabel("Organisation (O)");
		jlOrg.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlOrg = (GridBagConstraints) gbcLabel.clone();
		gbc_jlOrg.gridy = 3;
		JLabel jlOrgValue = new JLabel(sOrg);
		jlOrgValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlOrgValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlOrgValue.gridy = 3;
		// Organisation Unit (OU)
		JLabel jlOU = new JLabel("Organisation Unit (OU)");
		jlOU.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlOU = (GridBagConstraints) gbcLabel.clone();
		gbc_jlOU.gridy = 4;
		JLabel jlOUValue = new JLabel(sOU);
		jlOUValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlOUValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlOUValue.gridy = 4;
		// E-mail Address
		// JLabel jlEmail = new JLabel("E-mail Address");
		// jlEmail.setFont(new Font(null, Font.PLAIN, 11));
		// GridBagConstraints gbc_jlEmail = (GridBagConstraints)
		// gbcLabel.clone();
		// gbc_jlEmail.gridy = 5;
		// JLabel jlEmailValue = new JLabel(sEMAILADDRESS);
		// jlEmailValue.setFont(new Font(null, Font.PLAIN, 11));
		// GridBagConstraints gbc_jlEmailValue = (GridBagConstraints)
		// gbcValue.clone();
		// gbc_jlEmailValue.gridy = 5;
		// Serial Number
		JLabel jlSN = new JLabel("Serial Number");
		jlSN.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlSN = (GridBagConstraints) gbcLabel.clone();
		gbc_jlSN.gridy = 6;
		JLabel jlSNValue = new JLabel();
		// Get the hexadecimal serial number
		StringBuffer strBuff = new StringBuffer(new BigInteger(1, cert
				.getSerialNumber().toByteArray()).toString(16).toUpperCase());
		// Place colons at every two hexadecimal characters
		if (strBuff.length() > 2) {
			for (int iCnt = 2; iCnt < strBuff.length(); iCnt += 3) {
				strBuff.insert(iCnt, ':');
			}
		}
		jlSNValue.setText(strBuff.toString());
		jlSNValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlSNValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlSNValue.gridy = 6;
		// Version
		JLabel jlVersion = new JLabel("Version");
		jlVersion.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlVersion = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlVersion.gridy = 7;
		JLabel jlVersionValue = new JLabel(Integer.toString(cert.getVersion()));
		jlVersionValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlVersionValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlVersionValue.gridy = 7;

		// Issued By
		JLabel jlIssuedBy = new JLabel("Issued By");
		jlIssuedBy.setFont(new Font(null, Font.BOLD, 11));
		GridBagConstraints gbc_jlIssuedBy = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlIssuedBy.gridy = 8;
		gbc_jlIssuedBy.gridwidth = 2; // takes two columns
		gbc_jlIssuedBy.insets = new Insets(5, 5, 5, 5);// has slightly bigger
														// insets
		// Distinguished Name (DN)
		String iDN = cert.getIssuerX500Principal().getName(
				X500Principal.RFC2253);
		util.parseDN(iDN);
		// Extract the CN, O and OU fields
		String iCN = util.getCN();
		String iOrg = util.getO();
		String iOU = util.getOU();
		// Common Name (CN)
		JLabel jlICN = new JLabel("Common Name (CN)");
		jlICN.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlICN = (GridBagConstraints) gbcLabel.clone();
		gbc_jlICN.gridy = 9;
		JLabel jlICNValue = new JLabel(iCN);
		jlICNValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlICNValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlICNValue.gridy = 9;
		// Organisation (O)
		JLabel jlIOrg = new JLabel("Organisation (O)");
		jlIOrg.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIOrg = (GridBagConstraints) gbcLabel.clone();
		gbc_jlIOrg.gridy = 10;
		JLabel jlIOrgValue = new JLabel(iOrg);
		jlIOrgValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIOrgValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlIOrgValue.gridy = 10;
		// Organisation Unit (OU)
		JLabel jlIOU = new JLabel("Organisation Unit (OU)");
		jlIOU.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIOU = (GridBagConstraints) gbcLabel.clone();
		gbc_jlIOU.gridy = 11;
		JLabel jlIOUValue = new JLabel(iOU);
		jlIOUValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIOUValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlIOUValue.gridy = 11;
		// Validity
		JLabel jlValidity = new JLabel("Validity");
		jlValidity.setFont(new Font(null, Font.BOLD, 11));
		GridBagConstraints gbc_jlValidity = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlValidity.gridy = 12;
		gbc_jlValidity.gridwidth = 2; // takes two columns
		gbc_jlValidity.insets = new Insets(5, 5, 5, 5);// has slightly bigger
														// insets
		// Issued On
		JLabel jlIssuedOn = new JLabel("Issued On");
		jlIssuedOn.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIssuedOn = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlIssuedOn.gridy = 13;
		JLabel jlIssuedOnValue = new JLabel(cert.getNotBefore().toString());
		jlIssuedOnValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlIssuedOnValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlIssuedOnValue.gridy = 13;
		// Expires On
		JLabel jlExpiresOn = new JLabel("Expires On");
		jlExpiresOn.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlExpiresOn = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlExpiresOn.gridy = 14;
		JLabel jlExpiresOnValue = new JLabel(cert.getNotAfter().toString());
		jlExpiresOnValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlExpiresOnValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlExpiresOnValue.gridy = 14;

		// Fingerprints
		byte[] bCert = new byte[0];
		try {
			bCert = cert.getEncoded();
		} catch (CertificateEncodingException ex) {
			logger.error("Could not get the encoded form of the certificate.", ex);
		}
		JLabel jlFingerprints = new JLabel("Fingerprints");
		jlFingerprints.setFont(new Font(null, Font.BOLD, 11));
		GridBagConstraints gbc_jlFingerprints = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlFingerprints.gridy = 15;
		gbc_jlFingerprints.gridwidth = 2; // takes two columns
		gbc_jlFingerprints.insets = new Insets(5, 5, 5, 5);// has slightly
															// bigger insets
		// SHA-1 Fingerprint
		JLabel jlSHA1Fingerprint = new JLabel("SHA1 Fingerprint");
		jlSHA1Fingerprint.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlSHA1Fingerprint = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlSHA1Fingerprint.gridy = 16;
		JLabel jlSHA1FingerprintValue = new JLabel(getMessageDigest(bCert,
				"SHA1"));
		jlSHA1FingerprintValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlSHA1FingerprintValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlSHA1FingerprintValue.gridy = 16;
		// MD5 Fingerprint
		JLabel jlMD5Fingerprint = new JLabel("MD5 Fingerprint");
		jlMD5Fingerprint.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlMD5Fingerprint = (GridBagConstraints) gbcLabel
				.clone();
		gbc_jlMD5Fingerprint.gridy = 17;
		JLabel jlMD5FingerprintValue = new JLabel(
				getMessageDigest(bCert, "MD5"));
		jlMD5FingerprintValue.setFont(new Font(null, Font.PLAIN, 11));
		GridBagConstraints gbc_jlMD5FingerprintValue = (GridBagConstraints) gbcValue
				.clone();
		gbc_jlMD5FingerprintValue.gridy = 17;

		// Empty label to add a bit space at the bottom of the panel
		// to make it look like firefox's view certificate dialog
		JLabel jlEmpty = new JLabel("");
		GridBagConstraints gbc_jlEmpty = (GridBagConstraints) gbcLabel.clone();
		gbc_jlEmpty.gridy = 18;
		gbc_jlEmpty.gridwidth = 2; // takes two columns
		gbc_jlEmpty.ipady = 40;

		JPanel jpCertificate = new JPanel(new GridBagLayout());
		jpCertificate.setBorder(new CompoundBorder(new EmptyBorder(15, 15, 15,
				15), new EtchedBorder()));

		if (intendedUses != null) {
			jpCertificate.add(jpUses, gbc_jpUses);
		}
		jpCertificate.add(jlIssuedTo, gbc_jlIssuedTo); // Issued To
		jpCertificate.add(jlCN, gbc_jlCN);
		jpCertificate.add(jlCNValue, gbc_jlCNValue);
		jpCertificate.add(jlOrg, gbc_jlOrg);
		jpCertificate.add(jlOrgValue, gbc_jlOrgValue);
		jpCertificate.add(jlOU, gbc_jlOU);
		jpCertificate.add(jlOUValue, gbc_jlOUValue);
		// jpCertificate.add(jlEmail, gbc_jlEmail);
		// jpCertificate.add(jlEmailValue, gbc_jlEmailValue);
		jpCertificate.add(jlSN, gbc_jlSN);
		jpCertificate.add(jlSNValue, gbc_jlSNValue);
		jpCertificate.add(jlVersion, gbc_jlVersion);
		jpCertificate.add(jlVersionValue, gbc_jlVersionValue);
		jpCertificate.add(jlIssuedBy, gbc_jlIssuedBy); // Issued By
		jpCertificate.add(jlICN, gbc_jlICN);
		jpCertificate.add(jlICNValue, gbc_jlICNValue);
		jpCertificate.add(jlIOrg, gbc_jlIOrg);
		jpCertificate.add(jlIOrgValue, gbc_jlIOrgValue);
		jpCertificate.add(jlIOU, gbc_jlIOU);
		jpCertificate.add(jlIOUValue, gbc_jlIOUValue);
		jpCertificate.add(jlValidity, gbc_jlValidity); // Validity
		jpCertificate.add(jlIssuedOn, gbc_jlIssuedOn);
		jpCertificate.add(jlIssuedOnValue, gbc_jlIssuedOnValue);
		jpCertificate.add(jlExpiresOn, gbc_jlExpiresOn);
		jpCertificate.add(jlExpiresOnValue, gbc_jlExpiresOnValue);
		jpCertificate.add(jlFingerprints, gbc_jlFingerprints); // Fingerprints
		jpCertificate.add(jlSHA1Fingerprint, gbc_jlSHA1Fingerprint);
		jpCertificate.add(jlSHA1FingerprintValue, gbc_jlSHA1FingerprintValue);
		jpCertificate.add(jlMD5Fingerprint, gbc_jlMD5Fingerprint);
		jpCertificate.add(jlMD5FingerprintValue, gbc_jlMD5FingerprintValue);
		jpCertificate.add(jlEmpty, gbc_jlEmpty); // Empty label to get some vertical space on the frame

		// OK button
		JPanel jpButtons = new JPanel(new FlowLayout(FlowLayout.CENTER));

		final JButton jbTrust = new JButton("Trust");
		jbTrust.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				trustPressed();
			}
		});
		final JButton jbDontTrust = new JButton("Do not trust");
		jbDontTrust.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				dontTrustPressed();
			}
		});

		jpButtons.add(jbTrust);
		jpButtons.add(jbDontTrust);

		// Put it all together
		getContentPane().add(titlePanel, BorderLayout.NORTH);
		getContentPane().add(jpCertificate, BorderLayout.CENTER);
		getContentPane().add(jpButtons, BorderLayout.SOUTH);

		// Resizing wreaks havoc
		setResizable(false);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent evt) {
				closeDialog();
			}
		});

		getRootPane().setDefaultButton(jbTrust);

		pack();
	}

	/**
	 * Get the digest of a message as a formatted String.
	 * 
	 * @param bMessage
	 *            The message to digest
	 * @param digestType
	 *            The message digest algorithm
	 * @return The message digest
	 */
	public static String getMessageDigest(byte[] bMessage, String digestType) {
		// Create message digest object using the supplied algorithm
		MessageDigest messageDigest;
		try {
			messageDigest = MessageDigest.getInstance(digestType);
		} catch (NoSuchAlgorithmException ex) {
			logger.error("Failed to create message digest.", ex);
			return "";
		}

		// Create raw message digest
		byte[] bFingerPrint = messageDigest.digest(bMessage);

		// Place the raw message digest into a StringBuffer as a Hex number
		StringBuffer strBuff = new StringBuffer(new BigInteger(1, bFingerPrint)
				.toString(16).toUpperCase());

		// Odd number of characters so add in a padding "0"
		if ((strBuff.length() % 2) != 0) {
			strBuff.insert(0, '0');
		}

		// Place colons at every two hex characters
		if (strBuff.length() > 2) {
			for (int iCnt = 2; iCnt < strBuff.length(); iCnt += 3) {
				strBuff.insert(iCnt, ':');
			}
		}

		// Return the formatted message digest
		return strBuff.toString();
	}

	/**
	 * Gets the intended certificate uses, i.e. Netscape Certificate Type
	 * extension (2.16.840.1.113730.1.1) value as a string
	 * 
	 * @param value
	 *            Extension value as a DER-encoded OCTET string
	 * @return Extension value as a string
	 */
	private String getIntendedUses(byte[] value) {

		// Netscape Certificate Types (2.16.840.1.113730.1.1)
		int[] INTENDED_USES = new int[] { NetscapeCertType.sslClient,
				NetscapeCertType.sslServer, NetscapeCertType.smime,
				NetscapeCertType.objectSigning, NetscapeCertType.reserved,
				NetscapeCertType.sslCA, NetscapeCertType.smimeCA,
				NetscapeCertType.objectSigningCA, };

		// Netscape Certificate Type strings (2.16.840.1.113730.1.1)
		HashMap<String, String> INTENDED_USES_STRINGS = new HashMap<String, String>();
		INTENDED_USES_STRINGS.put("128", "SSL Client");
		INTENDED_USES_STRINGS.put("64", "SSL Server");
		INTENDED_USES_STRINGS.put("32", "S/MIME");
		INTENDED_USES_STRINGS.put("16", "Object Signing");
		INTENDED_USES_STRINGS.put("8", "Reserved");
		INTENDED_USES_STRINGS.put("4", "SSL CA");
		INTENDED_USES_STRINGS.put("2", "S/MIME CA");
		INTENDED_USES_STRINGS.put("1", "Object Signing CA");

		// Get octet string from extension value
		ASN1OctetString fromByteArray = new DEROctetString(value);
		byte[] octets = fromByteArray.getOctets();
		DERBitString fromByteArray2 = new DERBitString(octets);
		int val = new NetscapeCertType(fromByteArray2).intValue();
		StringBuffer strBuff = new StringBuffer();
		for (int i = 0, len = INTENDED_USES.length; i < len; i++) {
			int use = INTENDED_USES[i];
			if ((val & use) == use) {
				strBuff.append(INTENDED_USES_STRINGS.get(String.valueOf(use))
						+ ", \n");
			}
		}
		// remove the last ", \n" from the end of the buffer
		String str = strBuff.toString();
		str = str.substring(0, str.length() - 3);
		return str;
	}

	/**
	 * 'Trust' button pressed.
	 */
	private void trustPressed() {
		shouldTrust = true;
		closeDialog();
	}

	/**
	 * 'Do not trust' button pressed.
	 */
	private void dontTrustPressed() {
		shouldTrust = false;
		closeDialog();
	}	
	
	/**
	 * Closes the dialog.
	 */
	public void closeDialog() {
		setVisible(false);
		dispose();
	}

	public boolean shouldTrust() {
		return shouldTrust;
	}
}