From badf06d810bb0c03b7385b68bef628d6b16de9fe Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Tue, 23 Apr 2013 11:37:03 -0400
Subject: [PATCH] Refactored code to import CA certificate.

The code to import CA certificate has been moved from PKIConnection
into PKIClient to allow reuse.

The Client classes have been modified such that it uses a shared
PKIClient object instead of PKIConnection.

The return codes in CertFindCLI has been fixed to be more consistent
with other commands.

Ticket #491
---
 .../netscape/certsrv/account/AccountClient.java    |  17 ++-
 .../src/com/netscape/certsrv/ca/CAClient.java      |  21 ++--
 .../src/com/netscape/certsrv/cert/CertClient.java  |  19 ++--
 .../src/com/netscape/certsrv/client/PKIClient.java | 120 ++++++++++++++++++++-
 .../com/netscape/certsrv/client/PKIConnection.java |  71 ++++--------
 .../com/netscape/certsrv/group/GroupClient.java    |  25 +++--
 .../src/com/netscape/certsrv/key/KeyClient.java    |  19 ++--
 .../src/com/netscape/certsrv/kra/DRMClient.java    |  23 ++--
 .../certsrv/system/KRAConnectorClient.java         |  18 ++--
 .../certsrv/system/SecurityDomainClient.java       |  23 ++--
 .../certsrv/system/SystemConfigClient.java         |  17 ++-
 .../src/com/netscape/certsrv/user/UserClient.java  |  29 +++--
 .../cms/servlet/csadmin/ConfigurationUtils.java    |  10 +-
 .../src/com/netscape/cmstools/cert/CertCLI.java    |   2 +-
 .../com/netscape/cmstools/cert/CertFindCLI.java    |  27 +++--
 .../src/com/netscape/cmstools/cli/MainCLI.java     |  15 ++-
 .../src/com/netscape/cmstools/group/GroupCLI.java  |   2 +-
 .../src/com/netscape/cmstools/key/KeyCLI.java      |   2 +-
 .../netscape/cmstools/system/KRAConnectorCLI.java  |   2 +-
 .../src/com/netscape/cmstools/user/UserCLI.java    |   2 +-
 20 files changed, 274 insertions(+), 190 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/account/AccountClient.java b/base/common/src/com/netscape/certsrv/account/AccountClient.java
index e60112229446ea34bd398915d31a6d26c9250aac..36adcf57a1aa0c6cb2234384e74b3a46850df26a 100644
--- a/base/common/src/com/netscape/certsrv/account/AccountClient.java
+++ b/base/common/src/com/netscape/certsrv/account/AccountClient.java
@@ -21,27 +21,26 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 /**
  * @author Endi S. Dewata
  */
-public class AccountClient extends PKIClient {
+public class AccountClient {
 
+    public PKIClient client;
     public AccountResource resource;
 
-    public AccountClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public AccountClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public AccountClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        resource = createProxy(AccountResource.class);
+        resource = client.createProxy(AccountResource.class);
     }
 
     public void login() {
diff --git a/base/common/src/com/netscape/certsrv/ca/CAClient.java b/base/common/src/com/netscape/certsrv/ca/CAClient.java
index 93d50b6704f4b9769bb3f6d0af2b388c2c006d24..906caada79d4c4f96387619e57185204a47ec9bd 100644
--- a/base/common/src/com/netscape/certsrv/ca/CAClient.java
+++ b/base/common/src/com/netscape/certsrv/ca/CAClient.java
@@ -31,33 +31,32 @@ import com.netscape.certsrv.cert.CertReviewResponse;
 import com.netscape.certsrv.cert.CertSearchRequest;
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.certsrv.dbs.certdb.CertId;
 import com.netscape.certsrv.profile.ProfileData;
 import com.netscape.certsrv.profile.ProfileDataInfos;
 import com.netscape.certsrv.profile.ProfileResource;
 import com.netscape.certsrv.request.RequestId;
 
-public class CAClient extends PKIClient {
+public class CAClient {
 
+    private PKIClient client;
     private CertResource certClient;
     private CertRequestResource certRequestClient;
     private ProfileResource profileClient;
 
-    public CAClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public CAClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public CAClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        certRequestClient = createProxy(CertRequestResource.class);
-        certClient = createProxy(CertResource.class);
-        profileClient = createProxy(ProfileResource.class);
+        certRequestClient = client.createProxy(CertRequestResource.class);
+        certClient = client.createProxy(CertResource.class);
+        profileClient = client.createProxy(ProfileResource.class);
     }
 
     public Collection<CertRequestInfo> listRequests(String requestState, String requestType) {
diff --git a/base/common/src/com/netscape/certsrv/cert/CertClient.java b/base/common/src/com/netscape/certsrv/cert/CertClient.java
index 215153fd18a46c30fe2cb868dc5fc9d400076f15..42c78eb2c09400ec3edad8a41b1ab3037741219c 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertClient.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertClient.java
@@ -21,31 +21,30 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.certsrv.dbs.certdb.CertId;
 import com.netscape.certsrv.request.RequestId;
 
 /**
  * @author Endi S. Dewata
  */
-public class CertClient extends PKIClient {
+public class CertClient {
 
+    public PKIClient client;
     public CertResource certClient;
     public CertRequestResource certRequestResource;
 
-    public CertClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public CertClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public CertClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        certClient = createProxy(CertResource.class);
-        certRequestResource = createProxy(CertRequestResource.class);
+        certClient = client.createProxy(CertResource.class);
+        certRequestResource = client.createProxy(CertRequestResource.class);
     }
 
     public CertData getCert(CertId id) {
diff --git a/base/common/src/com/netscape/certsrv/client/PKIClient.java b/base/common/src/com/netscape/certsrv/client/PKIClient.java
index 482ed9fde5b7f2be841fe4f1278a50d9e3518f6b..00b71694be0f19a622990ad28e0ce0b813b13d1b 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIClient.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIClient.java
@@ -1,20 +1,46 @@
 package com.netscape.certsrv.client;
 
+import java.io.IOException;
+import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.cert.CertificateEncodingException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 
 import org.jboss.resteasy.client.ClientResponse;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.TokenCertificate;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.netscape.cmsutil.util.Utils;
 
 
 public class PKIClient {
 
-    PKIConnection connection;
+    public ClientConfig config;
+    public PKIConnection connection;
 
-    public PKIClient(PKIConnection connection) {
-        this.connection = connection;
-    }
+    public boolean verbose;
 
     public PKIClient(ClientConfig config) {
-        this(new PKIConnection(config));
+        this.config = config;
+
+        connection = new PKIConnection(this);
     }
 
     public <T> T createProxy(Class<T> clazz) throws URISyntaxException {
@@ -24,4 +50,88 @@ public class PKIClient {
     public <T> T getEntity(ClientResponse<T> response) {
         return connection.getEntity(response);
     }
+
+    public ClientConfig getConfig() {
+        return config;
+    }
+
+    public PKIConnection getConnection() {
+        return connection;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public X509Certificate[] getCerts() throws NotInitializedException {
+        CryptoManager manager = CryptoManager.getInstance();
+        return manager.getPermCerts();
+    }
+
+    public X509Certificate[] getCACerts() throws NotInitializedException {
+        CryptoManager manager = CryptoManager.getInstance();
+        return manager.getCACerts();
+    }
+
+    public byte[] downloadCACertChain(URI caServerURI)
+            throws ParserConfigurationException, SAXException, IOException {
+
+        URL url = new URL(caServerURI+"/ee/ca/getCertChain");
+
+        DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
+
+        Document document = documentBuilder.parse(url.openStream());
+        NodeList list = document.getElementsByTagName("ChainBase64");
+        Element element = (Element)list.item(0);
+
+        String encodedChain = element.getTextContent();
+        return Utils.base64decode(encodedChain);
+    }
+
+    public X509Certificate importCertPackage(byte[] bytes, String nickname)
+            throws NotInitializedException, CertificateEncodingException,
+            NicknameConflictException, UserCertConflictException,
+            NoSuchItemOnTokenException, TokenException {
+
+        CryptoManager manager = CryptoManager.getInstance();
+        return manager.importCertPackage(bytes, nickname);
+    }
+
+    public X509Certificate importCACertPackage(byte[] bytes)
+            throws NotInitializedException, CertificateEncodingException, TokenException {
+
+        CryptoManager manager = CryptoManager.getInstance();
+        InternalCertificate cert = (InternalCertificate)manager.importCACertPackage(bytes);
+
+        cert.setSSLTrust(
+                InternalCertificate.VALID_CA |
+                InternalCertificate.TRUSTED_CA |
+                InternalCertificate.TRUSTED_CLIENT_CA);
+
+        return cert;
+    }
+
+    public void removeCert(String nickname)
+            throws TokenException, ObjectNotFoundException,
+            NoSuchItemOnTokenException, NotInitializedException {
+
+        CryptoManager manager = CryptoManager.getInstance();
+        X509Certificate cert = manager.findCertByNickname(nickname);
+
+        CryptoToken cryptoToken;
+        if (cert instanceof TokenCertificate) {
+            TokenCertificate tokenCert = (TokenCertificate) cert;
+            cryptoToken = tokenCert.getOwningToken();
+
+        } else {
+            cryptoToken = manager.getInternalKeyStorageToken();
+        }
+
+        cryptoToken.getCryptoStore().deleteCert(cert);
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/client/PKIConnection.java b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
index 556779ec896ad357c6bc24f519435ca55aa80a58..62d54953221d758abe4898c823304d550c5ff75f 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIConnection.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
@@ -14,7 +14,6 @@ import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -23,8 +22,6 @@ import java.util.HashSet;
 import java.util.List;
 
 import javax.ws.rs.core.MediaType;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.commons.httpclient.ConnectTimeoutException;
 import org.apache.http.Header;
@@ -66,19 +63,14 @@ import org.jboss.resteasy.client.core.extractors.ClientErrorHandler;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.crypto.AlreadyInitializedException;
-import org.mozilla.jss.crypto.InternalCertificate;
 import org.mozilla.jss.crypto.X509Certificate;
 import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
 import org.mozilla.jss.ssl.SSLSocket;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import com.netscape.cmsutil.util.Utils;
 
 
 public class PKIConnection {
 
+    PKIClient client;
     ClientConfig config;
 
     Collection<Integer> rejectedCertStatuses;
@@ -97,10 +89,12 @@ public class PKIConnection {
     int responseCounter;
 
     File output;
-    boolean verbose;
 
-    public PKIConnection(ClientConfig config) {
-        this.config = config;
+    public PKIConnection(final PKIClient client) {
+
+        this.client = client;
+
+        config = client.getConfig();
 
         // Register https scheme.
         Scheme scheme = new Scheme("https", 443, new JSSProtocolSocketFactory());
@@ -125,7 +119,7 @@ public class PKIConnection {
 
                 requestCounter++;
 
-                if (verbose) {
+                if (client.verbose) {
                     System.out.println("HTTP request: "+request.getRequestLine());
                     for (Header header : request.getAllHeaders()) {
                         System.out.println("  "+header.getName()+": "+header.getValue());
@@ -153,7 +147,7 @@ public class PKIConnection {
 
                 responseCounter++;
 
-                if (verbose) {
+                if (client.verbose) {
                     System.out.println("HTTP response: "+response.getStatusLine());
                     for (Header header : response.getAllHeaders()) {
                         System.out.println("  "+header.getName()+": "+header.getValue());
@@ -175,7 +169,7 @@ public class PKIConnection {
                 HttpUriRequest uriRequest = super.getRedirect(request, response, context);
 
                 URI uri = uriRequest.getURI();
-                if (verbose) System.out.println("HTTP redirect: "+uri);
+                if (client.verbose) System.out.println("HTTP redirect: "+uri);
 
                 // Redirect the original request to the new URI.
                 RequestWrapper wrapper;
@@ -344,42 +338,23 @@ public class PKIConnection {
                 if (!line.equals("") && !line.equalsIgnoreCase("Y"))
                     return false;
 
-                URI serverURI = config.getServerURI();
-                URI caURI = new URI("http://" + serverURI.getHost() + ":8080/ca");
+                String caServerURI = "http://" + config.getServerURI().getHost() + ":8080/ca";
 
-                System.out.print("CA server URI [" + caURI + "]: ");
+                System.out.print("CA server URI [" + caServerURI + "]: ");
                 System.out.flush();
 
                 line = reader.readLine().trim();
                 if (!line.equals("")) {
-                    caURI = new URI(line);
+                    caServerURI = line;
                 }
 
-                URL url = new URL(caURI+"/ee/ca/getCertChain");
-                if (verbose) System.out.println("Downloading CA cert chain from " + url + ":");
+                if (client.verbose) System.out.println("Downloading CA certificate chain from " + caServerURI + ".");
+                byte[] bytes = client.downloadCACertChain(new URI(caServerURI));
 
-                DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
-                DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
+                if (client.verbose) System.out.println("Importing CA certificate chain.");
+                client.importCACertPackage(bytes);
 
-                Document document = documentBuilder.parse(url.openStream());
-                NodeList list = document.getElementsByTagName("ChainBase64");
-                Element element = (Element)list.item(0);
-
-                String encodedChain = element.getTextContent();
-                if (verbose) System.out.println(encodedChain);
-
-                byte[] chain = Utils.base64decode(encodedChain);
-
-                if (verbose) System.out.println("Importing CA certificate.");
-                CryptoManager manager = CryptoManager.getInstance();
-                InternalCertificate internalCert = (InternalCertificate)manager.importCACertPackage(chain);
-
-                internalCert.setSSLTrust(
-                        InternalCertificate.VALID_CA |
-                        InternalCertificate.TRUSTED_CA |
-                        InternalCertificate.TRUSTED_CLIENT_CA);
-
-                if (verbose) System.out.println("Imported CA certificate.");
+                if (client.verbose) System.out.println("Imported CA certificate.");
                 return true;
 
             } catch (Exception e) {
@@ -395,7 +370,7 @@ public class PKIConnection {
 
             boolean approval = true;
 
-            if (verbose) System.out.println("Server certificate: "+serverCert.getSubjectDN());
+            if (client.verbose) System.out.println("Server certificate: "+serverCert.getSubjectDN());
 
             SSLCertificateApprovalCallback.ValidityItem item;
 
@@ -536,7 +511,7 @@ public class PKIConnection {
 
             String certNickname = config.getCertNickname();
             if (certNickname != null) {
-                if (verbose) System.out.println("Client certificate: "+certNickname);
+                if (client.verbose) System.out.println("Client certificate: "+certNickname);
                 socket.setClientCertNickname(certNickname);
             }
 
@@ -608,12 +583,4 @@ public class PKIConnection {
     public void setOutput(File output) {
         this.output = output;
     }
-
-    public boolean isVerbose() {
-        return verbose;
-    }
-
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
 }
diff --git a/base/common/src/com/netscape/certsrv/group/GroupClient.java b/base/common/src/com/netscape/certsrv/group/GroupClient.java
index 2f7041b3128965194623aadd99500acb8782e7cc..ac666fae693e6d75bd73f39bcc4dbcc8b563f290 100644
--- a/base/common/src/com/netscape/certsrv/group/GroupClient.java
+++ b/base/common/src/com/netscape/certsrv/group/GroupClient.java
@@ -23,29 +23,28 @@ import org.jboss.resteasy.client.ClientResponse;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 /**
  * @author Endi S. Dewata
  */
-public class GroupClient extends PKIClient {
+public class GroupClient {
 
+    public PKIClient client;
     public GroupResource groupClient;
     public GroupMemberResource groupMemberClient;
 
-    public GroupClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public GroupClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public GroupClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        groupClient = createProxy(GroupResource.class);
-        groupMemberClient = createProxy(GroupMemberResource.class);
+        groupClient = client.createProxy(GroupResource.class);
+        groupMemberClient = client.createProxy(GroupMemberResource.class);
     }
 
     public GroupCollection findGroups(String groupIDFilter, Integer start, Integer size) {
@@ -59,13 +58,13 @@ public class GroupClient extends PKIClient {
     public GroupData addGroup(GroupData groupData) {
         @SuppressWarnings("unchecked")
         ClientResponse<GroupData> response = (ClientResponse<GroupData>)groupClient.addGroup(groupData);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public GroupData modifyGroup(String groupID, GroupData groupData) {
         @SuppressWarnings("unchecked")
         ClientResponse<GroupData> response = (ClientResponse<GroupData>)groupClient.modifyGroup(groupID, groupData);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public void removeGroup(String groupID) {
@@ -83,7 +82,7 @@ public class GroupClient extends PKIClient {
     public GroupMemberData addGroupMember(String groupID, String memberID) {
         @SuppressWarnings("unchecked")
         ClientResponse<GroupMemberData> response = (ClientResponse<GroupMemberData>)groupMemberClient.addGroupMember(groupID, memberID);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public void removeGroupMember(String groupID, String memberID) {
diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
index ce2946c1e0e83854cbddaeed9218e79c73e36df9..7deef0472eee728618f036cbf008924fce8f7604 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
@@ -21,30 +21,29 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.certsrv.request.RequestId;
 
 /**
  * @author Endi S. Dewata
  */
-public class KeyClient extends PKIClient {
+public class KeyClient {
 
+    public PKIClient client;
     public KeyResource keyClient;
     public KeyRequestResource keyRequestClient;
 
-    public KeyClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public KeyClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public KeyClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        keyClient = createProxy(KeyResource.class);
-        keyRequestClient = createProxy(KeyRequestResource.class);
+        keyClient = client.createProxy(KeyResource.class);
+        keyRequestClient = client.createProxy(KeyRequestResource.class);
     }
 
     public KeyDataInfos findKeys(String clientID, String status, Integer maxSize, Integer maxTime) {
diff --git a/base/common/src/com/netscape/certsrv/kra/DRMClient.java b/base/common/src/com/netscape/certsrv/kra/DRMClient.java
index de2642eb14ccae885ddb1872ed8c99db79469fc2..75e85a2aee57cbed9f5db548b9136cafc177cc4a 100644
--- a/base/common/src/com/netscape/certsrv/kra/DRMClient.java
+++ b/base/common/src/com/netscape/certsrv/kra/DRMClient.java
@@ -9,7 +9,6 @@ import org.jboss.resteasy.client.ClientResponse;
 import com.netscape.certsrv.cert.CertData;
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.certsrv.dbs.keydb.KeyId;
 import com.netscape.certsrv.key.KeyArchivalRequest;
 import com.netscape.certsrv.key.KeyData;
@@ -24,33 +23,33 @@ import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.system.SystemCertResource;
 import com.netscape.cmsutil.util.Utils;
 
-public class DRMClient  extends PKIClient {
+public class DRMClient {
 
+    private PKIClient client;
     private KeyResource keyClient;
     private KeyRequestResource keyRequestClient;
     private SystemCertResource systemCertClient;
 
-    public DRMClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public DRMClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public DRMClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        systemCertClient = createProxy(SystemCertResource.class);
-        keyRequestClient = createProxy(KeyRequestResource.class);
-        keyClient = createProxy(KeyResource.class);
+        systemCertClient = client.createProxy(SystemCertResource.class);
+        keyRequestClient = client.createProxy(KeyRequestResource.class);
+        keyClient = client.createProxy(KeyResource.class);
     }
 
     public String getTransportCert() {
         @SuppressWarnings("unchecked")
         ClientResponse<CertData> response = (ClientResponse<CertData>) systemCertClient
                 .getTransportCert();
-        CertData certData = getEntity(response);
+        CertData certData = client.getEntity(response);
         String transportCert = certData.getEncoded();
         return transportCert;
     }
diff --git a/base/common/src/com/netscape/certsrv/system/KRAConnectorClient.java b/base/common/src/com/netscape/certsrv/system/KRAConnectorClient.java
index f7b2c7246e1213ede9d4e70440b7b22123a7d08e..ea71cf645010e1449c26f4f57913ea6bf763a825 100644
--- a/base/common/src/com/netscape/certsrv/system/KRAConnectorClient.java
+++ b/base/common/src/com/netscape/certsrv/system/KRAConnectorClient.java
@@ -21,26 +21,26 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 /**
  * @author Ade Lee
  */
-public class KRAConnectorClient extends PKIClient {
+public class KRAConnectorClient {
+
+    public PKIClient client;
     public KRAConnectorResource kraConnectorClient;
 
-    public KRAConnectorClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public KRAConnectorClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public KRAConnectorClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        kraConnectorClient = createProxy(KRAConnectorResource.class);
+        kraConnectorClient = client.createProxy(KRAConnectorResource.class);
     }
 
     public void addConnector(KRAConnectorInfo info) {
diff --git a/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java b/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
index 5ecd56092af67827bed7b374cd9efbc4402ceb7d..490f837dabe2dc6fdf3c6a57c01955aabd33c002 100644
--- a/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
+++ b/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
@@ -21,35 +21,34 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 
 /**
  * @author alee
  */
-public class SecurityDomainClient extends PKIClient {
+public class SecurityDomainClient {
 
-    private SecurityDomainResource client;
-
-    public SecurityDomainClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
+    private PKIClient client;
+    private SecurityDomainResource securityDomainClient;
 
     public SecurityDomainClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public SecurityDomainClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        client = createProxy(SecurityDomainResource.class);
+        securityDomainClient = client.createProxy(SecurityDomainResource.class);
     }
 
     public InstallToken getInstallToken(String hostname, String subsystem) {
-        return client.getInstallToken(hostname, subsystem);
+        return securityDomainClient.getInstallToken(hostname, subsystem);
     }
 
     public DomainInfo getDomainInfo() {
-        return client.getDomainInfo();
+        return securityDomainClient.getDomainInfo();
     }
 }
diff --git a/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java b/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
index 4ccf152b35c9ee66be4b85ee39b7b89df5eb36ab..aa4e6842e53a3a96e845354a8b799a10175d9f0a 100644
--- a/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
+++ b/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
@@ -21,29 +21,28 @@ import java.net.URISyntaxException;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 
 /**
  * @author alee
  *
  */
-public class SystemConfigClient extends PKIClient {
+public class SystemConfigClient {
 
+    private PKIClient client;
     private SystemConfigResource configClient;
 
-    public SystemConfigClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public SystemConfigClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public SystemConfigClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        configClient = createProxy(SystemConfigResource.class);
+        configClient = client.createProxy(SystemConfigResource.class);
     }
 
     public ConfigurationResponse configure(ConfigurationRequest data) {
diff --git a/base/common/src/com/netscape/certsrv/user/UserClient.java b/base/common/src/com/netscape/certsrv/user/UserClient.java
index 2dd3503544f3abd29edf9abefc36f7f807d6cda3..5f1ebd5b8a1935d61af3229f58720ffddc26946f 100644
--- a/base/common/src/com/netscape/certsrv/user/UserClient.java
+++ b/base/common/src/com/netscape/certsrv/user/UserClient.java
@@ -23,31 +23,30 @@ import org.jboss.resteasy.client.ClientResponse;
 
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
-import com.netscape.certsrv.client.PKIConnection;
 
 /**
  * @author Endi S. Dewata
  */
-public class UserClient extends PKIClient {
+public class UserClient {
 
+    public PKIClient client;
     public UserResource userClient;
     public UserCertResource userCertClient;
     public UserMembershipResource userMembershipClient;
 
-    public UserClient(PKIConnection connection) throws URISyntaxException {
-        super(connection);
-        init();
-    }
-
     public UserClient(ClientConfig config) throws URISyntaxException {
-        super(config);
+        this(new PKIClient(config));
+    }
+
+    public UserClient(PKIClient client) throws URISyntaxException {
+        this.client = client;
         init();
     }
 
     public void init() throws URISyntaxException {
-        userClient = createProxy(UserResource.class);
-        userCertClient = createProxy(UserCertResource.class);
-        userMembershipClient = createProxy(UserMembershipResource.class);
+        userClient = client.createProxy(UserResource.class);
+        userCertClient = client.createProxy(UserCertResource.class);
+        userMembershipClient = client.createProxy(UserMembershipResource.class);
     }
 
     public UserCollection findUsers(String filter, Integer start, Integer size) {
@@ -61,13 +60,13 @@ public class UserClient extends PKIClient {
     public UserData addUser(UserData userData) {
         @SuppressWarnings("unchecked")
         ClientResponse<UserData> response = (ClientResponse<UserData>)userClient.addUser(userData);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public UserData modifyUser(String userID, UserData userData) {
         @SuppressWarnings("unchecked")
         ClientResponse<UserData> response = (ClientResponse<UserData>)userClient.modifyUser(userID, userData);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public void removeUser(String userID) {
@@ -85,7 +84,7 @@ public class UserClient extends PKIClient {
     public UserCertData addUserCert(String userID, UserCertData userCertData) {
         @SuppressWarnings("unchecked")
         ClientResponse<UserCertData> response = (ClientResponse<UserCertData>)userCertClient.addUserCert(userID, userCertData);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public void removeUserCert(String userID, String certID) {
@@ -99,7 +98,7 @@ public class UserClient extends PKIClient {
     public UserMembershipData addUserMembership(String userID, String groupID) {
         @SuppressWarnings("unchecked")
         ClientResponse<UserMembershipData> response = (ClientResponse<UserMembershipData>)userMembershipClient.addUserMembership(userID, groupID);
-        return getEntity(response);
+        return client.getEntity(response);
     }
 
     public void removeUserMembership(String userD, String groupID) {
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 82c994652fcf86ebc461144a172c07b6975f9510..014eb448bfdaa78cf23b71b64be8c56d8a7f4564 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -140,6 +140,7 @@ import com.netscape.certsrv.base.IConfigStore;
 import com.netscape.certsrv.base.ISubsystem;
 import com.netscape.certsrv.ca.ICertificateAuthority;
 import com.netscape.certsrv.client.ClientConfig;
+import com.netscape.certsrv.client.PKIClient;
 import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.certsrv.dbs.IDBSubsystem;
 import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
@@ -213,7 +214,8 @@ public class ConfigurationUtils {
         config.setServerURI(protocol + "://" + hostname + ":" + port + path);
         config.setCertNickname(clientnickname);
 
-        PKIConnection connection = new PKIConnection(config);
+        PKIClient client = new PKIClient(config);
+        PKIConnection connection = client.getConnection();
         ClientResponse<String> response = connection.post(content);
 
         return response;
@@ -328,9 +330,9 @@ public class ConfigurationUtils {
         config.setPassword(passwd);
         config.setInstanceCreationMode(true);
 
-        PKIConnection connection = new PKIConnection(config);
-        AccountClient accountClient = new AccountClient(connection);
-        SecurityDomainClient sdClient = new SecurityDomainClient(connection);
+        PKIClient client = new PKIClient(config);
+        AccountClient accountClient = new AccountClient(client);
+        SecurityDomainClient sdClient = new SecurityDomainClient(client);
 
         try {
             accountClient.login();
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
index 9f47b20c60a9a5d3f28d7bd1a1fa1967fccb700c..08211e2de93fb25059e2e934f6435ff858ce8c8b 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
@@ -81,7 +81,7 @@ public class CertCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        client = new CertClient(parent.connection);
+        client = new CertClient(parent.client);
 
         if (args.length == 0) {
             printHelp();
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
index 5415da574f70726526be3c21d0ecdf4e235b6d4f..590d7959866740a5adbfa74c75f8cdebada6672f 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
@@ -63,12 +63,12 @@ public class CertFindCLI extends CLI {
         } catch (ParseException e) {
             System.err.println("Error: " + e.getMessage());
             printHelp();
-            System.exit(-1);
+            System.exit(1);
         }
 
         if (cmd.hasOption("help")) {
             printHelp();
-            System.exit(-1);
+            System.exit(1);
         }
 
         String fileName = null;
@@ -78,20 +78,24 @@ public class CertFindCLI extends CLI {
             if (fileName == null || fileName.length() < 1) {
                 System.err.println("Error: No file name specified.");
                 printHelp();
-                System.exit(-1);
+                System.exit(1);
             }
         }
+
         if (fileName != null) {
             FileReader reader = null;
             try {
                 reader = new FileReader(fileName);
                 searchData = CertSearchRequest.valueOf(reader);
+
             } catch (FileNotFoundException e) {
                 System.err.println("Error: " + e.getMessage());
-                System.exit(-1);
+                System.exit(1);
+
             } catch (JAXBException e) {
                 System.err.println("Error: " + e.getMessage());
-                System.exit(-1);
+                System.exit(1);
+
             } finally {
                 if (reader != null)
                     try {
@@ -100,10 +104,12 @@ public class CertFindCLI extends CLI {
                         e.printStackTrace();
                     }
             }
+
         } else {
             searchData = new CertSearchRequest();
             searchData.setSerialNumberRangeInUse(true);
         }
+
         String s = cmd.getOptionValue("start");
         Integer start = s == null ? null : Integer.valueOf(s);
 
@@ -111,18 +117,21 @@ public class CertFindCLI extends CLI {
         Integer size = s == null ? null : Integer.valueOf(s);
 
         addSearchAttribute(cmd, searchData);
+
         CertDataInfos certs = null;
         try {
             certs = parent.client.findCerts(searchData, start, size);
         } catch (PKIException e) {
             System.err.println("Error: Cannot list certificates. " + e.getMessage());
-            System.exit(-1);
+            System.exit(1);
         }
+
         if (certs.getCertInfos() == null || certs.getCertInfos().isEmpty()) {
-            MainCLI.printMessage("No matches found.");
-            System.exit(-1);
+            MainCLI.printMessage("No certificates found");
+            System.exit(0); // valid result
         }
-        MainCLI.printMessage(certs.getCertInfos().size() + " certificate(s) matched");
+
+        MainCLI.printMessage(certs.getCertInfos().size() + " certificate(s) found");
 
         boolean first = true;
 
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index aa4327fe60ac1bf5b77319b8bf30fe901a176402..1510cc7af07f316fbd1cfa68bdf141d27c123b3f 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -37,6 +37,7 @@ import org.mozilla.jss.util.Password;
 
 import com.netscape.certsrv.account.AccountClient;
 import com.netscape.certsrv.client.ClientConfig;
+import com.netscape.certsrv.client.PKIClient;
 import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.cmstools.cert.CertCLI;
 import com.netscape.cmstools.group.GroupCLI;
@@ -55,6 +56,7 @@ public class MainCLI extends CLI {
     public Collection<Integer> rejectedCertStatuses;
     public Collection<Integer> ignoredCertStatuses;
 
+    public PKIClient client;
     public PKIConnection connection;
     public AccountClient accountClient;
 
@@ -223,8 +225,11 @@ public class MainCLI extends CLI {
     }
 
     public void connect() throws Exception {
-        connection = new PKIConnection(config);
-        connection.setVerbose(verbose);
+
+        client = new PKIClient(config);
+        client.setVerbose(verbose);
+
+        connection = client.getConnection();
         connection.setRejectedCertStatuses(rejectedCertStatuses);
         connection.setIgnoredCertStatuses(ignoredCertStatuses);
 
@@ -234,7 +239,7 @@ public class MainCLI extends CLI {
             connection.setOutput(file);
         }
 
-        accountClient = new AccountClient(connection);
+        accountClient = new AccountClient(client);
     }
 
     public void execute(String[] args) throws Exception {
@@ -355,8 +360,8 @@ public class MainCLI extends CLI {
         try {
             connect();
 
-            // login
-            if (config.getCertDatabase() != null || config.getUsername() != null) {
+            // login if username or nickname is specified
+            if (config.getUsername() != null || config.getCertNickname() != null) {
                 accountClient.login();
                 loggedIn = true;
             }
diff --git a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
index 75eeffd97ea0a170fee360b6c8c95c0bf4309578..bd8cec7735f8802328d99ae07cbbda3bdbfd8637 100644
--- a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
@@ -75,7 +75,7 @@ public class GroupCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        client = new GroupClient(parent.connection);
+        client = new GroupClient(parent.client);
 
         if (args.length == 0) {
             printHelp();
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
index f3922d5da1266f82c5f26f6f3204d53b1f2c3f36..0d239624329c4c66cd56b28b00babeb81fdc11ea 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
@@ -67,7 +67,7 @@ public class KeyCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        keyClient = new KeyClient(parent.connection);
+        keyClient = new KeyClient(parent.client);
 
         if (args.length == 0) {
             printHelp();
diff --git a/base/java-tools/src/com/netscape/cmstools/system/KRAConnectorCLI.java b/base/java-tools/src/com/netscape/cmstools/system/KRAConnectorCLI.java
index d59d7445ad4c1d9da88d3087b0f262153a3cc5d0..03db762d41f17ee6fc4f1ab21d209e920a44c4de 100644
--- a/base/java-tools/src/com/netscape/cmstools/system/KRAConnectorCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/system/KRAConnectorCLI.java
@@ -62,7 +62,7 @@ public class KRAConnectorCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        client = new KRAConnectorClient(parent.connection);
+        client = new KRAConnectorClient(parent.client);
 
         if (args.length == 0) {
             printHelp();
diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
index 84dd6bae510391c1b39cdcca54496d3b4cf0b1cf..2343d1989e412b7d06102cbb6773a4dde2a0b319 100644
--- a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
@@ -81,7 +81,7 @@ public class UserCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        client = new UserClient(parent.connection);
+        client = new UserClient(parent.client);
 
         if (args.length == 0) {
             printHelp();
-- 
1.8.1.4

