summaryrefslogtreecommitdiffstats
path: root/pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java')
-rw-r--r--pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java761
1 files changed, 761 insertions, 0 deletions
diff --git a/pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java b/pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java
new file mode 100644
index 000000000..27292b3d9
--- /dev/null
+++ b/pki/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java
@@ -0,0 +1,761 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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 of the License.
+//
+// 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.connection;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+import com.netscape.management.client.util.*;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs11.*;
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * JSSConnection deals with establishing a connection to
+ * a server, sending requests and reading responses.
+ *
+ * XXX - Performance optimizations if any, persistent connection
+ * support, server auth verification and client authentication
+ * support to be added. NEED TO COME BACK AND CLEAN UP - coding
+ * standard.
+ *
+ * @author Jack Pan-Chen
+ * @author kanda
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class JSSConnection implements IConnection, SSLCertificateApprovalCallback,
+ SSLClientCertificateSelectionCallback {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ /* static variables */
+ static CryptoManager cryptoManager;
+ static CertificateFactory cf;
+ static SelectCertDialog selectCertDialog = null;
+ static PromptForTrustDialog promptForTrustDialog = null;
+
+ /* private valiable */
+ private InputStream httpIn;
+ private OutputStream httpOut;
+ private byte[] body;
+ private int bodyLen;
+ private String header;
+ private int available;
+ private int totalRead;
+ private boolean endOfHeader = false;
+
+ private static int HTTP_OK_RESPONSE = 200;
+ private static final String PANELNAME = "SSLCLIENT";
+ private boolean abort = false;;
+ private boolean mClientAuth = false;
+ private boolean mCertAccepted = true;
+ private boolean mClientCertFound = true;
+ private boolean mServerCertImported = true;
+ private boolean mTokenPasswordInit = true;
+ private boolean mTokenPasswdSame = true;
+
+ protected SSLSocket s = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JSSConnection(String host, int port)
+ throws IOException, UnknownHostException {
+
+ UtilConsoleGlobals.initJSS();
+ cf = UtilConsoleGlobals.getX509CertificateFactory();
+ try {
+ cryptoManager = CryptoManager.getInstance();
+ } catch (Exception e) {
+ }
+
+ // SSLSocket needs to be set before getting an instance
+ // to get the ciphers
+ SSLSocket.enableSSL2Default(false);
+ SSLSocket.enableSSL3Default(true);
+ int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005;
+ int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
+
+ int ciphers[] = SSLSocket.getImplementedCipherSuites();
+ for (int i = 0; ciphers != null && i < ciphers.length; i++) {
+ // make sure SSLv2 ciphers are not enabled
+ if ((ciphers[i] & 0xfff0) !=0xff00) {
+ Debug.println("JSSConnection Debug: non-SSL2 NSS Cipher Supported '0x" +
+ Integer.toHexString(ciphers[i]) + "'");
+ SSLSocket.setCipherPreferenceDefault(ciphers[i], true);
+ } else {
+ Debug.println("JSSConnection Debug: SSL2 (turned off) NSS Cipher Supported '0x" +
+ Integer.toHexString(ciphers[i]) + "'");
+ SSLSocket.setCipherPreferenceDefault(ciphers[i], false);
+ }
+
+ /* Enable ECC Cipher */
+
+ if (ciphers[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) {
+ Debug.println("JSSConnection Debug: found TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, setting preference");
+ SSLSocket.setCipherPreferenceDefault(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, true);
+ }
+ if (ciphers[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) {
+ Debug.println("JSSConnection Debug: found TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, setting preference");
+ SSLSocket.setCipherPreferenceDefault(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true);
+ }
+ }
+ s = new SSLSocket(host, port, null, 0, this, this);
+ s.enableSSL2(false);
+ s.enableSSL2Default(false);
+ s.enableV2CompatibleHello(false);
+ s.enableSSL3(true);
+ s.enableSSL3Default(true);
+
+ // Initialze Http Input and Output Streams
+ httpIn = s.getInputStream();
+ httpOut = s.getOutputStream();
+ cryptoManager.setPasswordCallback(new pwcb());
+ Debug.println("JSSConnection Debug: end of JSSConnection constructor");
+ }
+
+ public boolean approve(org.mozilla.jss.crypto.X509Certificate serverCert,
+ ValidityStatus status)
+ {
+ if (!mCertAccepted)
+ return false;
+
+ boolean promptForTrust = true;
+
+ //if server auth is not enabled
+ if (!(UtilConsoleGlobals.isServerAuthEnabled())) {
+ return mCertAccepted;
+ }
+
+ Enumeration errors = status.getReasons();
+ //if there are more then 1 error we need to propmt user for trust
+ promptForTrust = errors.hasMoreElements();
+
+ /* if trusted already */
+ if (!promptForTrust)
+ return mCertAccepted;
+
+ //the x509certificate pass in by jss is lacking some
+ //api. so I am getting the encoding then
+ //use the default security provider provided by sun
+ //to decode certificate.
+ //due to the fact that current JSS(version2.1) will clobber
+ //the way jdk loads the default sun security provider I am
+ //using the workaround for now. Which is to load the sun
+ //provider before jss is loaded. (see static section above)
+ X509Certificate x509Cert = null;
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(serverCert.getEncoded());
+
+ while (bais.available() > 0) {
+ x509Cert = (X509Certificate)(cf.generateCertificate(bais));
+ Debug.println(x509Cert.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ //bring up the trust dialog
+ promptForTrustDialog = new PromptForTrustDialog(getFrame(), x509Cert, status);
+ promptForTrustDialog.setVisible(true);
+ mCertAccepted = promptForTrustDialog.isCertAccepted();
+ if (mCertAccepted) {
+ //user want to save this certificate not just this session
+ //so we have to store the cert as perm cert.
+ if (!(promptForTrustDialog.isAcceptedForOneSession())) {
+ try {
+ String nickname = serverCert.getNickname();
+
+ CryptoToken internalToken =
+ cryptoManager.getInternalKeyStorageToken();
+
+ if (!internalToken.passwordIsInitialized()) {
+ InitPasswordDialog initPasswordDialog =
+ new InitPasswordDialog(internalToken);
+ initPasswordDialog.setVisible(true);
+ if (initPasswordDialog.isCancel()) {
+ mTokenPasswordInit = false;
+ return false;
+ }
+ if (!initPasswordDialog.isPwdSame()) {
+ mTokenPasswdSame = false;
+ mTokenPasswordInit = false;
+ return false;
+ }
+ if (!initPasswordDialog.isTokenInit()) {
+ mTokenPasswordInit = false;
+ return false;
+ }
+ }
+
+ if (!internalToken.isLoggedIn()) {
+ internalToken.login(new pwcb());
+ }
+ if (abort) {
+ mServerCertImported = false;
+ mCertAccepted = false;
+ return false;
+ }
+ InternalCertificate internalCert =
+ cryptoManager.importCertToPerm(serverCert,
+ (nickname==null)?serverCert.getSubjectDN().toString():nickname);
+ internalCert.setSSLTrust(
+ org.mozilla.jss.crypto.InternalCertificate.TRUSTED_PEER |
+ org.mozilla.jss.crypto.InternalCertificate.VALID_PEER);
+ } catch (Exception e) {
+ mServerCertImported = false;
+ mCertAccepted = false;
+ if (Debug.getTrace()) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ }
+ }
+
+ return mCertAccepted;
+ }
+
+ public boolean isSamePwd() {
+ return mTokenPasswdSame;
+ }
+
+ public boolean isTokenPasswordInit() {
+ return mTokenPasswordInit;
+ }
+
+ public boolean hasClientCert() {
+ return mClientCertFound;
+ }
+
+ public boolean isClientAuth() {
+ return mClientAuth;
+ }
+
+ public boolean isCertAccepted() {
+ return mCertAccepted;
+ }
+
+ public boolean isAbortAction() {
+ return abort;
+ }
+
+ public boolean isServerCertImported() {
+ return mServerCertImported;
+ }
+
+ public String select(Vector nicknames)
+ {
+ selectCertDialog = null;
+ mClientAuth = true;
+ if (nicknames == null || nicknames.size() == 0) {
+ mClientCertFound = false;
+ return "";
+ }
+
+ selectCertDialog = new JSSConnection.SelectCertDialog();
+
+ Debug.println("JSSConnection::select(...) - SELECT CERTIFICATE");
+ selectCertDialog.setCertList(nicknames);
+ selectCertDialog.setVisible(true);
+ return (selectCertDialog.isCancel()?"":selectCertDialog.getSelectedCert());
+ }
+
+ public class pwcb implements PasswordCallback {
+ private int nthPrompt = 0;
+ private static final int MAX_PASSWORD_PROMPT = 20;
+ GetPasswordDialog getPasswordDialog = null;
+
+ public Password getPasswordFirstAttempt(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+
+ if (abort)
+ throw new PasswordCallback.GiveUpException();
+
+ nthPrompt++;
+
+ if (getPasswordDialog == null)
+ getPasswordDialog = new GetPasswordDialog();
+
+ getPasswordDialog.setPasswordInfo(info, false);
+ getPasswordDialog.setVisible(true);
+
+ if (getPasswordDialog.isCancel()) {
+ nthPrompt = 0;
+ abort = true;
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ return getPasswordDialog.getPassword();
+ }
+
+ public Password getPasswordAgain(PasswordCallbackInfo info)
+ throws GiveUpException
+ {
+
+ if (abort)
+ throw new PasswordCallback.GiveUpException();
+ nthPrompt++;
+ if (nthPrompt > MAX_PASSWORD_PROMPT || getPasswordDialog.isCancel()) {
+ nthPrompt = 0;
+ abort = true;
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ getPasswordDialog.setPasswordInfo(info, true);
+ getPasswordDialog.setVisible(true);
+
+ return getPasswordDialog.getPassword();
+ }
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Send request to the server using this connection
+ *
+ * @param req request object
+ * @return status 1-success, 0- failed
+ * @excpetion IOExcpetion
+ */
+ public int sendRequest(String req)
+ throws IOException {
+
+ int stat = 1;
+ if (req == null)
+ {
+ //System.out.println("Request is null");
+ return 0;
+ }
+ endOfHeader = false;
+
+ PrintStream ps = new PrintStream(httpOut);
+ ps.println(req);
+ ps.println();
+ ps.flush();
+ try
+ {
+ Thread.sleep(100);
+ }
+ catch (Exception e) {
+ Debug.println("JSSConnection Debug: in sendRequest:"+e.toString());
+ System.out.println("sleeping "+e.toString());
+ }
+ //System.out.println("Request Sent - bytes:" + httpOut.getTotal());
+
+ // Init the Reply stream
+ totalRead = 0;
+ header = null;
+ initReadResponse();
+ return stat;
+ }
+
+ /**
+ * Retrieve the input stream
+ */
+ public InputStream getInputStream()
+ throws IOException {
+
+ return s.getInputStream();
+ }
+
+ /**
+ * Read
+ */
+ public int read(byte[] buf)
+ throws IOException {
+
+ return httpIn.read(buf, 0, buf.length);
+ }
+
+ /**
+ * Get Header
+ */
+ public String getHeader() {
+ if (header == null)
+ return "No Header Read";
+ else
+ return header;
+ }
+
+ /**
+ * Get response
+ */
+ public byte[] getResponse() {
+ if (totalRead == 0)
+ return null;
+ else {
+ byte[] buf = new byte[bodyLen];
+ System.arraycopy(body, 0, buf, 0, bodyLen);
+ return buf;
+ }
+ }
+
+ /**
+ * get available
+ */
+ public int available()
+ throws IOException {
+
+ return httpIn.available();
+ }
+
+ /**
+ * Disconnect this connection
+ */
+ public void disconnect() {
+ try {
+ s.close();
+ } catch (Exception e) {
+ //ignor ?
+ }
+ }
+
+ /**
+ * Set time out
+ */
+ public void setSoTimeout(int timeout) throws SocketException {
+ //System.out.println("JSSConnection: setSoTimeout() - "+timeout);
+ s.setSoTimeout(timeout);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JFrame getFrame() {
+ if (UtilConsoleGlobals.getActivatedFrame() != null)
+ return UtilConsoleGlobals.getActivatedFrame();
+ return new JFrame();
+ }
+
+ private void initReadResponse()
+ throws IOException {
+
+ readHeader();
+ readBody();
+ }
+
+ private int readLineFromStream(InputStream is, byte line[],
+ int startpos, int len) throws IOException {
+ //return is.readLine(line, startpos, len);
+ int pos = startpos;
+ int count = 0;
+ while (len > 0)
+ {
+ int nRead = httpIn.read(line, pos, 1);
+ if (nRead == -1)
+ break;
+ count++;
+ if (line[pos] == '\n') {
+ break;
+ }
+ pos++;
+ }
+ return count > 0 ? count : -1;
+ }
+
+ private void readHeader() throws IOException
+ {
+ // Read the status line of response and parse for
+ // Errors.
+ byte[] headerLine = new byte[1096];
+ int nRead = readLineFromStream(httpIn, headerLine, 0, 1096);
+
+ //System.out.println("XXX read " + nRead);
+
+ if (requestFailed(new String(headerLine))) {
+ Debug.println("JSSConnection Debug: in readHeader requestFailed");
+ throw new IOException(getReasonPhrase(new String (headerLine)));
+ }
+
+ while (true) {
+ nRead = readLineFromStream(httpIn, headerLine, 0, 1096);
+ int available = httpIn.available();
+
+ //System.out.println("Available: " + available);
+
+ if (nRead == -1) {
+ System.out.println("Unexpected end of stream");
+ break;
+ }
+
+ processHeader(headerLine, nRead);
+
+ if (endOfHeader) {
+ //System.out.println("End of Header");
+ break;
+ } else {
+ //System.out.println("Header: " + new String(headerLine)
+ // + ", nRead: " + nRead);
+ }
+ }
+ }
+
+ private boolean endOfHeader(byte[] hdr, int available) {
+ if (available == 2) {
+ int c1 = (int)hdr[0];
+ int c2 = (int)hdr[1];
+
+ //System.out.println("C1= " + c1);
+ //System.out.println("C2= " + c2);
+
+ return true;
+ } else
+ return false;
+ }
+
+ private void readBody()
+ throws IOException {
+
+ body = new byte[bodyLen];
+ totalRead = 0;
+ while (totalRead < bodyLen) {
+ int nRead = httpIn.read(body, totalRead, bodyLen - totalRead);
+ totalRead += nRead;
+ }
+ }
+
+
+ private void processHeader(byte[] buf, int nRead)
+ {
+ if (endOfHeader(buf, nRead)) {
+ endOfHeader = true;
+ return;
+ }
+
+ String hdr = new String(buf, 0, nRead);
+ int index = 0;
+ if (hdr.toLowerCase().startsWith("content-length: ")) {
+ try {
+ String length = hdr.substring(hdr.indexOf(": ") + 1);
+ bodyLen = Integer.parseInt(length.trim());
+ return;
+ } catch (Exception e){e.printStackTrace(); }
+ }
+ }
+
+ private boolean requestFailed(String header) {
+ return (header.indexOf(Integer.toString(HTTP_OK_RESPONSE)) > 0) ? false: true;
+ }
+
+ private String getReasonPhrase(String header) {
+ String str1 = header.substring(header.indexOf(' ') +1);
+ return str1.substring(str1.indexOf(' ') +1);
+ }
+
+ class InitPasswordDialog extends AbstractDialog {
+ protected ResourceBundle mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ SingleBytePasswordField pwd;
+ SingleBytePasswordField pwdAgain;
+ CryptoToken mToken;
+ boolean tokenPasswdInit = true;
+ boolean pwdSame = true;
+
+ public InitPasswordDialog(CryptoToken token) {
+ super(null,"",true, OK|CANCEL);
+ setMinimumSize(300, 150);
+ mToken = token;
+ setTitle(mResource.getString("SSLCLIENT_INITPASSWORD_DIALOG_TITLE"));
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ pwd = new SingleBytePasswordField();
+ pwdAgain = new SingleBytePasswordField();
+ JLabel pwdLbl = new JLabel();
+ JLabel pwdAgainLbl = new JLabel();
+ pwdLbl.setText(mResource.getString("SSLCLIENT_INITPASSWORD_PWD_LABEL"));
+ pwdAgainLbl.setText(
+ mResource.getString("SSLCLIENT_INITPASSWORD_PWDAGAIN_LABEL"));
+ GridBagUtil.constrain(p, pwdLbl,
+ 0, y, 1, 1,
+ 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.NONE);
+ GridBagUtil.constrain(p, pwd,
+ 1, y, GridBagConstraints.REMAINDER, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
+ GridBagUtil.constrain(p, pwdAgainLbl,
+ 0, ++y, 1, 1,
+ 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE);
+ GridBagUtil.constrain(p, pwdAgain,
+ 1, y, GridBagConstraints.REMAINDER, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
+/*
+ GridBagUtil.constrain(p, pwd,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+*/
+
+ pack();
+ }
+
+ protected void okInvoked() {
+ if (!pwd.getText().equals(pwdAgain.getText())) {
+ pwdSame = false;
+ dispose();
+ return;
+ }
+
+ try {
+ mToken.initPassword(null, getPassword());
+ dispose();
+ } catch (Exception e) {
+ tokenPasswdInit = false;
+ }
+ }
+
+ public boolean isPwdSame() {
+ return pwdSame;
+ }
+
+ public boolean isTokenInit() {
+ return tokenPasswdInit;
+ }
+
+ public void setVisible(boolean visible) {
+ pack();
+ pwd.grabFocus();
+ super.setVisible(visible);
+ }
+
+ public Password getPassword() {
+ Password jssPwd = new Password(pwd.getText().toCharArray());
+ return jssPwd;
+ }
+ }
+
+ class GetPasswordDialog extends AbstractDialog {
+
+ MultilineLabel enterPwdLabel = new MultilineLabel();
+ protected ResourceBundle mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ SingleBytePasswordField pwd;
+ public GetPasswordDialog() {
+ super(null,"",true, OK|CANCEL);
+ setTitle(mResource.getString("SSLCLIENT_PASSWORD_DIALOG_TITLE"));
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ GridBagUtil.constrain(p, enterPwdLabel,
+ 0, y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ pwd = new SingleBytePasswordField();
+ GridBagUtil.constrain(p, pwd,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ pack();
+ }
+
+ public void setVisible(boolean visible) {
+ pack();
+ pwd.grabFocus();
+ super.setVisible(visible);
+ }
+
+ public void setPasswordInfo(PasswordCallbackInfo info, boolean getPwdAgain) {
+ if (getPwdAgain)
+ enterPwdLabel.setText(mResource.getString(
+ "SSLCLIENT_PASSWORDAGAIN_DIALOG_LABEL")+" "+info.getName()+":");
+ else
+ enterPwdLabel.setText(mResource.getString(
+ "SSLCLIENT_PASSWORD_DIALOG_LABEL")+" "+ info.getName()+":");
+ Debug.println(info.getName());
+ }
+
+ public Password getPassword() {
+ Password jssPwd = new Password(pwd.getText().toCharArray());
+ return jssPwd;
+ }
+ }
+
+
+ class SelectCertDialog extends AbstractDialog {
+
+ JComboBox certList = new JComboBox();
+ protected ResourceBundle mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+ public SelectCertDialog() {
+ super(null,"", true, OK|CANCEL);
+ setTitle(mResource.getString("SSLCLIENT_CERTSELECT_DIALOG_TITLE"));
+
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ GridBagUtil.constrain(p, new JLabel(
+ mResource.getString("SSLCLIENT_CERTSELECT_DIALOG_LABEL")),
+ 0, y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p, certList,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+ pack();
+ }
+
+ public void setCertList(Vector nicknames) {
+ certList.removeAllItems();
+ Enumeration enum1 = nicknames.elements();
+ while (enum1.hasMoreElements()) {
+ certList.insertItemAt(enum1.nextElement(), 0);
+ }
+ try {
+ certList.setSelectedIndex(0);
+ } catch (Exception e) {
+ }
+ }
+
+ public String getSelectedCert() {
+ return certList.getSelectedItem().toString();
+ }
+
+ }
+
+}