[Pki-devel] [PATCH] 628 Fixed user-cert-add --serial with remote CA.

Endi Sukma Dewata edewata at redhat.com
Tue Jul 7 16:08:08 UTC 2015


The user-cert-add command has been modified to ask the user for
the CA server URI if the CA is not available locally.

A new SubsystemClient.exists() method has been added to check
whether a subsystem is deployed on the target instance.

The SubsystemCLI has been modified to call logout() only if
the operation is executed successfully.

The certificate approval callback class has been refactored out
of PKIConnection into a separate class to clean up circular
dependency with PKIClient.

https://fedorahosted.org/pki/ticket/1448

-- 
Endi S. Dewata
-------------- next part --------------
From f789637b5a638404349b6ce7ee1c63378802a8a6 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Mon, 6 Jul 2015 18:03:08 -0400
Subject: [PATCH] Fixed user-cert-add --serial with remote CA.

The user-cert-add command has been modified to ask the user for
the CA server URI if the CA is not available locally.

A new SubsystemClient.exists() method has been added to check
whether a subsystem is deployed on the target instance.

The SubsystemCLI has been modified to call logout() only if
the operation is executed successfully.

The certificate approval callback class has been refactored out
of PKIConnection into a separate class to clean up circular
dependency with PKIClient.

https://fedorahosted.org/pki/ticket/1448
---
 .../src/com/netscape/certsrv/cert/CertClient.java  |   5 +
 .../client/PKICertificateApprovalCallback.java     | 196 ++++++++++++++++
 .../src/com/netscape/certsrv/client/PKIClient.java |  63 ++++-
 .../com/netscape/certsrv/client/PKIConnection.java | 257 ++++-----------------
 .../netscape/certsrv/client/SubsystemClient.java   |  40 ++++
 .../src/com/netscape/cmstools/cli/MainCLI.java     |   7 +-
 .../com/netscape/cmstools/cli/SubsystemCLI.java    |  20 +-
 .../com/netscape/cmstools/user/UserCertAddCLI.java |  35 ++-
 .../cms/servlet/csadmin/ConfigurationUtils.java    |  10 +-
 9 files changed, 394 insertions(+), 239 deletions(-)
 create mode 100644 base/common/src/com/netscape/certsrv/client/PKICertificateApprovalCallback.java

diff --git a/base/common/src/com/netscape/certsrv/cert/CertClient.java b/base/common/src/com/netscape/certsrv/cert/CertClient.java
index 86e5e15374d23563faac987b40e9d5c33a38cc25..42b04b7021f0063894c340c177915d799b621ddd 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertClient.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertClient.java
@@ -23,6 +23,7 @@ import javax.ws.rs.core.Response;
 
 import com.netscape.certsrv.client.Client;
 import com.netscape.certsrv.client.PKIClient;
+import com.netscape.certsrv.client.SubsystemClient;
 import com.netscape.certsrv.dbs.certdb.CertId;
 import com.netscape.certsrv.profile.ProfileDataInfos;
 import com.netscape.certsrv.request.RequestId;
@@ -35,6 +36,10 @@ public class CertClient extends Client {
     public CertResource certClient;
     public CertRequestResource certRequestClient;
 
+    public CertClient(SubsystemClient subsystemClient) throws URISyntaxException {
+        this(subsystemClient.client, subsystemClient.getName());
+    }
+
     public CertClient(PKIClient client, String subsystem) throws URISyntaxException {
         super(client, subsystem, "cert");
         init();
diff --git a/base/common/src/com/netscape/certsrv/client/PKICertificateApprovalCallback.java b/base/common/src/com/netscape/certsrv/client/PKICertificateApprovalCallback.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ec46f57396924b75950b9a42b8a41977d1a9038
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/client/PKICertificateApprovalCallback.java
@@ -0,0 +1,196 @@
+// --- 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) 2015 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.certsrv.client;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Enumeration;
+
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+
+public class PKICertificateApprovalCallback implements SSLCertificateApprovalCallback {
+
+    public PKIClient client;
+
+    public PKICertificateApprovalCallback(PKIClient client) {
+        this.client = client;
+    }
+
+    // NOTE:  The following helper method defined as
+    //        'public String displayReason(int reason)'
+    //        should be moved into the JSS class called
+    //        'org.mozilla.jss.ssl.SSLCertificateApprovalCallback'
+    //        under its nested subclass called 'ValidityStatus'.
+
+    // While all reason values should be unique, this method has been
+    // written to return the name of the first defined reason that is
+    // encountered which contains the requested value, or null if no
+    // reason containing the requested value is encountered.
+    public String displayReason(int reason) {
+
+        for (Field f : ValidityStatus.class.getDeclaredFields()) {
+            int mod = f.getModifiers();
+            if (Modifier.isStatic(mod) &&
+                Modifier.isPublic(mod) &&
+                Modifier.isFinal(mod)) {
+                try {
+                    int value = f.getInt(null);
+                    if (value == reason) {
+                        return f.getName();
+                    }
+                } catch (IllegalAccessException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public String getMessage(X509Certificate serverCert, int reason) {
+
+        if (reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
+            return "BAD_CERT_DOMAIN encountered on '"+serverCert.getSubjectDN()+"' indicates a common-name mismatch";
+        }
+
+        if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
+            return "UNTRUSTED ISSUER encountered on '" +
+                    serverCert.getSubjectDN() + "' indicates a non-trusted CA cert '" +
+                    serverCert.getIssuerDN() + "'";
+        }
+
+        if (reason == SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID) {
+            return "CA_CERT_INVALID encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
+        }
+
+        String reasonName = displayReason(reason);
+        if (reasonName != null) {
+            return reasonName+" encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
+        }
+
+        return "Unknown/undefined reason "+reason+" encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
+    }
+
+    public boolean handleUntrustedIssuer(X509Certificate serverCert) {
+        try {
+            System.out.print("Import CA certificate (Y/n)? ");
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+            String line = reader.readLine().trim();
+
+            if (!line.equals("") && !line.equalsIgnoreCase("Y"))
+                return false;
+
+            String caServerURI = "http://" + client.getConfig().getServerURI().getHost() + ":8080/ca";
+
+            System.out.print("CA server URI [" + caServerURI + "]: ");
+            System.out.flush();
+
+            line = reader.readLine().trim();
+            if (!line.equals("")) {
+                caServerURI = line;
+            }
+
+            if (client.verbose) System.out.println("Downloading CA certificate chain from " + caServerURI + ".");
+            byte[] bytes = client.downloadCACertChain(caServerURI);
+
+            if (client.verbose) System.out.println("Importing CA certificate chain.");
+            client.importCACertPackage(bytes);
+
+            if (client.verbose) System.out.println("Imported CA certificate.");
+            return true;
+
+        } catch (Exception e) {
+            System.err.println("ERROR: "+e);
+            return false;
+        }
+    }
+
+    // Callback to approve or deny returned SSL server cert.
+    // Right now, simply approve the cert.
+    public boolean approve(X509Certificate serverCert,
+            SSLCertificateApprovalCallback.ValidityStatus status) {
+
+        boolean approval = true;
+
+        if (client.verbose) System.out.println("Server certificate: "+serverCert.getSubjectDN());
+
+        SSLCertificateApprovalCallback.ValidityItem item;
+
+        // If there are no items in the Enumeration returned by
+        // getReasons(), you can assume that the certificate is
+        // trustworthy, and return true to allow the connection to
+        // continue, or you can continue to make further tests of
+        // your own to determine trustworthiness.
+        Enumeration<?> errors = status.getReasons();
+
+        while (errors.hasMoreElements()) {
+            item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement();
+            int reason = item.getReason();
+
+            if (client.isRejected(reason)) {
+                if (!client.statuses.contains(reason))
+                    System.err.println("ERROR: " + getMessage(serverCert, reason));
+                approval = false;
+
+            } else if (client.isIgnored(reason)) {
+                // Ignore validity status
+
+            } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
+                // Issue a WARNING, but allow this process
+                // to continue since we haven't installed a trusted CA
+                // cert for this operation.
+                if (!client.statuses.contains(reason)) {
+                    System.err.println("WARNING: " + getMessage(serverCert, reason));
+                    handleUntrustedIssuer(serverCert);
+                }
+
+            } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
+                // Issue a WARNING, but allow this process to continue on
+                // common-name mismatches.
+                if (!client.statuses.contains(reason))
+                    System.err.println("WARNING: " + getMessage(serverCert, reason));
+
+            } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID) {
+                // Set approval false to deny this
+                // certificate so that the connection is terminated.
+                // (Expect an IOException on the outstanding
+                //  read()/write() on the socket).
+                if (!client.statuses.contains(reason))
+                    System.err.println("ERROR: " + getMessage(serverCert, reason));
+                approval = false;
+
+            } else {
+                // Set approval false to deny this certificate so that
+                // the connection is terminated. (Expect an IOException
+                // on the outstanding read()/write() on the socket).
+                if (!client.statuses.contains(reason))
+                    System.err.println("ERROR: " + getMessage(serverCert, reason));
+                approval = false;
+            }
+
+            client.statuses.add(reason);
+        }
+
+        return approval;
+    }
+}
diff --git a/base/common/src/com/netscape/certsrv/client/PKIClient.java b/base/common/src/com/netscape/certsrv/client/PKIClient.java
index e06b4db54569d5ed46fdd138af3ded93e6fd1878..9015cfa38f76ac9b23e4baf7e79af06af6566888 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIClient.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIClient.java
@@ -1,3 +1,21 @@
+// --- 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) 2015 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
 package com.netscape.certsrv.client;
 
 import java.io.IOException;
@@ -5,6 +23,8 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.cert.CertificateEncodingException;
+import java.util.Collection;
+import java.util.HashSet;
 
 import javax.ws.rs.core.Response;
 import javax.xml.parsers.DocumentBuilder;
@@ -42,10 +62,22 @@ public class PKIClient {
 
     public boolean verbose;
 
+    Collection<Integer> rejectedCertStatuses = new HashSet<Integer>();
+    Collection<Integer> ignoredCertStatuses = new HashSet<Integer>();
+
+    // List to prevent displaying the same warnings/errors again.
+    Collection<Integer> statuses = new HashSet<Integer>();
+
+    public PKIClient(ClientConfig config) {
+        this(config, null);
+    }
+
     public PKIClient(ClientConfig config, CryptoProvider crypto) {
         this.config = config;
         this.crypto = crypto;
-        connection = new PKIConnection(this);
+
+        connection = new PKIConnection(config);
+        connection.setCallback(new PKICertificateApprovalCallback(this));
     }
 
     public <T> T createProxy(String subsystem, Class<T> clazz) throws URISyntaxException {
@@ -102,6 +134,7 @@ public class PKIClient {
 
     public void setVerbose(boolean verbose) {
         this.verbose = verbose;
+        connection.setVerbose(verbose);
     }
 
     public X509Certificate getCert(String nickname)
@@ -183,4 +216,32 @@ public class PKIClient {
 
         cryptoToken.getCryptoStore().deleteCert(cert);
     }
+
+    public void addRejectedCertStatus(Integer rejectedCertStatus) {
+        rejectedCertStatuses.add(rejectedCertStatus);
+    }
+
+    public void setRejectedCertStatuses(Collection<Integer> rejectedCertStatuses) {
+        this.rejectedCertStatuses.clear();
+        if (rejectedCertStatuses == null) return;
+        this.rejectedCertStatuses.addAll(rejectedCertStatuses);
+    }
+
+    public boolean isRejected(Integer certStatus) {
+        return rejectedCertStatuses.contains(certStatus);
+    }
+
+    public void addIgnoredCertStatus(Integer ignoredCertStatus) {
+        ignoredCertStatuses.add(ignoredCertStatus);
+    }
+
+    public void setIgnoredCertStatuses(Collection<Integer> ignoredCertStatuses) {
+        this.ignoredCertStatuses.clear();
+        if (ignoredCertStatuses == null) return;
+        this.ignoredCertStatuses.addAll(ignoredCertStatuses);
+    }
+
+    public boolean isIgnored(Integer certStatus) {
+        return ignoredCertStatuses.contains(certStatus);
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/client/PKIConnection.java b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
index 0ecee4d8e6587dafec377c1d8bb62e4ccacb78b3..1f9b6dff16e88bd3746b2d9627fa14b1d1cd1cd5 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIConnection.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
@@ -1,15 +1,29 @@
+// --- 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) 2015 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
 package com.netscape.certsrv.client;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
@@ -18,9 +32,6 @@ import java.net.URISyntaxException;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
 import java.util.List;
 
 import javax.ws.rs.client.Entity;
@@ -67,7 +78,6 @@ import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.CryptoManager.NotInitializedException;
-import org.mozilla.jss.crypto.X509Certificate;
 import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
 import org.mozilla.jss.ssl.SSLSocket;
 
@@ -76,16 +86,12 @@ import com.netscape.certsrv.base.PKIException;
 
 public class PKIConnection {
 
-    PKIClient client;
+    boolean verbose;
+
     ClientConfig config;
 
-    Collection<Integer> rejectedCertStatuses = new HashSet<Integer>();
-    Collection<Integer> ignoredCertStatuses = new HashSet<Integer>();
-
-    // List to prevent displaying the same warnings/errors again.
-    Collection<Integer> statuses = new HashSet<Integer>();
-
     DefaultHttpClient httpClient = new DefaultHttpClient();
+    SSLCertificateApprovalCallback callback;
 
     ApacheHttpClient4Engine engine;
     ResteasyClient resteasyClient;
@@ -96,11 +102,9 @@ public class PKIConnection {
 
     File output;
 
-    public PKIConnection(final PKIClient client) {
+    public PKIConnection(ClientConfig config) {
 
-        this.client = client;
-
-        config = client.getConfig();
+        this.config = config;
 
         // Register https scheme.
         Scheme scheme = new Scheme("https", 443, new JSSProtocolSocketFactory());
@@ -125,7 +129,7 @@ public class PKIConnection {
 
                 requestCounter++;
 
-                if (client.verbose) {
+                if (verbose) {
                     System.out.println("HTTP request: "+request.getRequestLine());
                     for (Header header : request.getAllHeaders()) {
                         System.out.println("  "+header.getName()+": "+header.getValue());
@@ -153,7 +157,7 @@ public class PKIConnection {
 
                 responseCounter++;
 
-                if (client.verbose) {
+                if (verbose) {
                     System.out.println("HTTP response: "+response.getStatusLine());
                     for (Header header : response.getAllHeaders()) {
                         System.out.println("  "+header.getName()+": "+header.getValue());
@@ -175,7 +179,7 @@ public class PKIConnection {
                 HttpUriRequest uriRequest = super.getRedirect(request, response, context);
 
                 URI uri = uriRequest.getURI();
-                if (client.verbose) System.out.println("HTTP redirect: "+uri);
+                if (verbose) System.out.println("HTTP redirect: "+uri);
 
                 // Redirect the original request to the new URI.
                 RequestWrapper wrapper;
@@ -203,6 +207,18 @@ public class PKIConnection {
         resteasyClient = new ResteasyClientBuilder().httpEngine(engine).build();
     }
 
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+
+    }
+    public void setCallback(SSLCertificateApprovalCallback callback) {
+        this.callback = callback;
+    }
+
     public void storeRequest(File file, HttpRequest request) throws IOException {
 
         try (PrintStream out = new PrintStream(file)) {
@@ -273,169 +289,6 @@ public class PKIConnection {
         }
     }
 
-    private class ServerCertApprovalCB implements SSLCertificateApprovalCallback {
-
-        // NOTE:  The following helper method defined as
-        //        'public String displayReason(int reason)'
-        //        should be moved into the JSS class called
-        //        'org.mozilla.jss.ssl.SSLCertificateApprovalCallback'
-        //        under its nested subclass called 'ValidityStatus'.
-
-        // While all reason values should be unique, this method has been
-        // written to return the name of the first defined reason that is
-        // encountered which contains the requested value, or null if no
-        // reason containing the requested value is encountered.
-        public String displayReason(int reason) {
-            Class<SSLCertificateApprovalCallback.ValidityStatus> c =
-                SSLCertificateApprovalCallback.ValidityStatus.class;
-            for (Field f : c.getDeclaredFields()) {
-                int mod = f.getModifiers();
-                if (Modifier.isStatic(mod) &&
-                    Modifier.isPublic(mod) &&
-                    Modifier.isFinal(mod)) {
-                    try {
-                        int value = f.getInt(null);
-                        if (value == reason) {
-                            return f.getName();
-                        }
-                    } catch (IllegalAccessException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-
-            return null;
-        }
-
-        public String getMessage(X509Certificate serverCert, int reason) {
-
-            if (reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
-
-                return "BAD_CERT_DOMAIN encountered on '"+serverCert.getSubjectDN()+"' indicates a common-name mismatch";
-            }
-
-            if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
-                return "UNTRUSTED ISSUER encountered on '" +
-                        serverCert.getSubjectDN() + "' indicates a non-trusted CA cert '" +
-                        serverCert.getIssuerDN() + "'";
-            }
-
-            if (reason == SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID) {
-                return "CA_CERT_INVALID encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
-            }
-
-            String reasonName = displayReason(reason);
-            if (reasonName != null) {
-                return reasonName+" encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
-            }
-
-            return "Unknown/undefined reason "+reason+" encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
-        }
-
-        public boolean handleUntrustedIssuer(X509Certificate serverCert) {
-            try {
-                System.out.print("Import CA certificate (Y/n)? ");
-
-                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-                String line = reader.readLine().trim();
-
-                if (!line.equals("") && !line.equalsIgnoreCase("Y"))
-                    return false;
-
-                String caServerURI = "http://" + config.getServerURI().getHost() + ":8080/ca";
-
-                System.out.print("CA server URI [" + caServerURI + "]: ");
-                System.out.flush();
-
-                line = reader.readLine().trim();
-                if (!line.equals("")) {
-                    caServerURI = line;
-                }
-
-                if (client.verbose) System.out.println("Downloading CA certificate chain from " + caServerURI + ".");
-                byte[] bytes = client.downloadCACertChain(caServerURI);
-
-                if (client.verbose) System.out.println("Importing CA certificate chain.");
-                client.importCACertPackage(bytes);
-
-                if (client.verbose) System.out.println("Imported CA certificate.");
-                return true;
-
-            } catch (Exception e) {
-                System.err.println("ERROR: "+e);
-                return false;
-            }
-        }
-
-        // Callback to approve or deny returned SSL server cert.
-        // Right now, simply approve the cert.
-        public boolean approve(X509Certificate serverCert,
-                SSLCertificateApprovalCallback.ValidityStatus status) {
-
-            boolean approval = true;
-
-            if (client.verbose) System.out.println("Server certificate: "+serverCert.getSubjectDN());
-
-            SSLCertificateApprovalCallback.ValidityItem item;
-
-            // If there are no items in the Enumeration returned by
-            // getReasons(), you can assume that the certificate is
-            // trustworthy, and return true to allow the connection to
-            // continue, or you can continue to make further tests of
-            // your own to determine trustworthiness.
-            Enumeration<?> errors = status.getReasons();
-            while (errors.hasMoreElements()) {
-                item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement();
-                int reason = item.getReason();
-
-                if (isRejected(reason)) {
-                    if (!statuses.contains(reason))
-                        System.err.println("ERROR: " + getMessage(serverCert, reason));
-                    approval = false;
-
-                } else if (isIgnored(reason)) {
-                    // Ignore validity status
-
-                } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
-                    // Issue a WARNING, but allow this process
-                    // to continue since we haven't installed a trusted CA
-                    // cert for this operation.
-                    if (!statuses.contains(reason)) {
-                        System.err.println("WARNING: " + getMessage(serverCert, reason));
-                        handleUntrustedIssuer(serverCert);
-                    }
-
-                } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
-                    // Issue a WARNING, but allow this process to continue on
-                    // common-name mismatches.
-                    if (!statuses.contains(reason))
-                        System.err.println("WARNING: " + getMessage(serverCert, reason));
-
-                } else if (reason == SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID) {
-                    // Set approval false to deny this
-                    // certificate so that the connection is terminated.
-                    // (Expect an IOException on the outstanding
-                    //  read()/write() on the socket).
-                    if (!statuses.contains(reason))
-                        System.err.println("ERROR: " + getMessage(serverCert, reason));
-                    approval = false;
-
-                } else {
-                    // Set approval false to deny this certificate so that
-                    // the connection is terminated. (Expect an IOException
-                    // on the outstanding read()/write() on the socket).
-                    if (!statuses.contains(reason))
-                        System.err.println("ERROR: " + getMessage(serverCert, reason));
-                    approval = false;
-                }
-
-                statuses.add(reason);
-            }
-
-            return approval;
-        }
-    }
-
     private class JSSProtocolSocketFactory implements SchemeSocketFactory, SchemeLayeredSocketFactory {
 
         @Override
@@ -499,18 +352,18 @@ public class PKIConnection {
                         port,
                         localAddr,
                         localPort,
-                        new ServerCertApprovalCB(),
+                        callback,
                         null);
 
             } else {
-                socket = new SSLSocket(sock, hostName, new ServerCertApprovalCB(), null);
+                socket = new SSLSocket(sock, hostName, callback, null);
             }
 // setSSLVersionRange needs to be exposed in jss
 //            socket.setSSLVersionRange(org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_0, org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_2);
 
             String certNickname = config.getCertNickname();
             if (certNickname != null) {
-                if (client.verbose) System.out.println("Client certificate: "+certNickname);
+                if (verbose) System.out.println("Client certificate: "+certNickname);
                 socket.setClientCertNickname(certNickname);
             }
 
@@ -592,34 +445,6 @@ public class PKIConnection {
         return target.request().post(Entity.form(form), String.class);
     }
 
-    public void addRejectedCertStatus(Integer rejectedCertStatus) {
-        rejectedCertStatuses.add(rejectedCertStatus);
-    }
-
-    public void setRejectedCertStatuses(Collection<Integer> rejectedCertStatuses) {
-        this.rejectedCertStatuses.clear();
-        if (rejectedCertStatuses == null) return;
-        this.rejectedCertStatuses.addAll(rejectedCertStatuses);
-    }
-
-    public boolean isRejected(Integer certStatus) {
-        return rejectedCertStatuses.contains(certStatus);
-    }
-
-    public void addIgnoredCertStatus(Integer ignoredCertStatus) {
-        ignoredCertStatuses.add(ignoredCertStatus);
-    }
-
-    public void setIgnoredCertStatuses(Collection<Integer> ignoredCertStatuses) {
-        this.ignoredCertStatuses.clear();
-        if (ignoredCertStatuses == null) return;
-        this.ignoredCertStatuses.addAll(ignoredCertStatuses);
-    }
-
-    public boolean isIgnored(Integer certStatus) {
-        return ignoredCertStatuses.contains(certStatus);
-    }
-
     public File getOutput() {
         return output;
     }
diff --git a/base/common/src/com/netscape/certsrv/client/SubsystemClient.java b/base/common/src/com/netscape/certsrv/client/SubsystemClient.java
index d694b397c71f87ae567ea0c2fc476e075bfe9032..3d44bce416a6f9da7b9397be0adfbea2c54d01e7 100644
--- a/base/common/src/com/netscape/certsrv/client/SubsystemClient.java
+++ b/base/common/src/com/netscape/certsrv/client/SubsystemClient.java
@@ -17,8 +17,13 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.certsrv.client;
 
+import java.net.URI;
 import java.net.URISyntaxException;
 
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+
 import com.netscape.certsrv.account.AccountClient;
 
 
@@ -44,6 +49,41 @@ public class SubsystemClient extends Client {
         accountClient.login();
     }
 
+    public boolean exists() throws Exception {
+
+        ClientConfig config = client.getConfig();
+        URI serverURI = config.getServerURI();
+
+        URI subsystemURI = new URI(
+                serverURI.getScheme(),
+                null,
+                serverURI.getHost(),
+                serverURI.getPort(),
+                "/" + name,
+                null,
+                null);
+
+        DefaultHttpClient client = new DefaultHttpClient();
+        HttpGet method = new HttpGet(subsystemURI);
+        try {
+            HttpResponse response = client.execute(method);
+            int code = response.getStatusLine().getStatusCode();
+
+            if (code == 200) {
+                return true;
+
+            } else if (code == 404) {
+                return false;
+
+            } else {
+                throw new Exception("Error: " + response.getStatusLine());
+            }
+
+        } finally {
+            method.releaseConnection();
+        }
+    }
+
     /**
      * Log out from the subsystem.
      */
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 4d63d9bc12c012bc1db207f7a31a0b50cf5bc2af..248d6cb9dabf493b395cbbda5c04267ff9cfff20 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -465,13 +465,14 @@ public class MainCLI extends CLI {
         client = new PKIClient(config, null);
         client.setVerbose(verbose);
 
-        PKIConnection connection = client.getConnection();
-        connection.setRejectedCertStatuses(rejectedCertStatuses);
-        connection.setIgnoredCertStatuses(ignoredCertStatuses);
+        client.setRejectedCertStatuses(rejectedCertStatuses);
+        client.setIgnoredCertStatuses(ignoredCertStatuses);
 
         if (output != null) {
             File file = new File(output);
             file.mkdirs();
+
+            PKIConnection connection = client.getConnection();
             connection.setOutput(file);
         }
     }
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java
index 310a4c29c5c394f3f2bae4e887f9322df54cde0d..b28271dd74371ae75434ffb7f43919b210caa3ac 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java
@@ -48,17 +48,15 @@ public class SubsystemCLI extends CLI {
 
         init();
 
-        try {
-            // login if username or nickname is specified
-            ClientConfig config = getClient().getConfig();
-            if (config.getUsername() != null || config.getCertNickname() != null) {
-                login();
-            }
-
-            super.execute(args);
-
-        } finally {
-            logout();
+        // login if username or nickname is specified
+        ClientConfig config = getClient().getConfig();
+        if (config.getUsername() != null || config.getCertNickname() != null) {
+            login();
         }
+
+        super.execute(args);
+
+        // logout if there is no failures
+        logout();
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserCertAddCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserCertAddCLI.java
index 4425e7003f7094837f644671b7e3acf8aaa2e711..21b3c8a172963688a75e134c64259f54e6d90c2f 100644
--- a/base/java-tools/src/com/netscape/cmstools/user/UserCertAddCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/user/UserCertAddCLI.java
@@ -18,15 +18,21 @@
 
 package com.netscape.cmstools.user;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.InputStreamReader;
+import java.net.URI;
 import java.util.Arrays;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.io.FileUtils;
 
+import com.netscape.certsrv.ca.CAClient;
 import com.netscape.certsrv.cert.CertClient;
 import com.netscape.certsrv.cert.CertData;
+import com.netscape.certsrv.client.ClientConfig;
+import com.netscape.certsrv.client.PKIClient;
 import com.netscape.certsrv.dbs.certdb.CertId;
 import com.netscape.certsrv.user.UserCertData;
 import com.netscape.cmstools.cli.CLI;
@@ -114,8 +120,33 @@ public class UserCertAddCLI extends CLI {
                 System.out.println("Downloading certificate " + serialNumber + ".");
             }
 
-            client = parent.getClient();
-            CertClient certClient = new CertClient(client, "ca");
+            PKIClient client = parent.getClient();
+            ClientConfig config = client.getConfig();
+            CAClient caClient = new CAClient(client);
+
+            while (!caClient.exists()) {
+                System.err.println("ERROR: CA subsystem not available");
+
+                URI serverURI = config.getServerURI();
+                String uri = serverURI.getScheme() + "://" + serverURI.getHost() + ":" + serverURI.getPort();
+
+                System.out.print("CA server URI [" + uri + "]: ");
+                System.out.flush();
+
+                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+                String line = reader.readLine().trim();
+                if (!line.equals("")) {
+                    uri = line;
+                }
+
+                config = new ClientConfig(client.getConfig());
+                config.setServerURI(uri);
+
+                client = new PKIClient(config);
+                caClient = new CAClient(client);
+            }
+
+            CertClient certClient = new CertClient(caClient);
 
             CertData certData = certClient.getCert(new CertId(serialNumber));
             encoded = certData.getEncoded();
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index ee88865e6a92b649b6065a1104ee63ae7cc7807b..7e6c2a3c1fe41684bddd895557ff055b690ede68 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -352,17 +352,16 @@ public class ConfigurationUtils {
         config.setPassword(passwd);
 
         PKIClient client = new PKIClient(config, null);
-        PKIConnection connection = client.getConnection();
 
         // Ignore the "UNTRUSTED_ISSUER" validity status
         // during PKI instance creation since we are
         // utilizing an untrusted temporary CA certificate.
-        connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER);
+        client.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER);
 
         // Ignore the "CA_CERT_INVALID" validity status
         // during PKI instance creation since we are
         // utilizing an untrusted temporary CA certificate.
-        connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID);
+        client.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID);
 
         AccountClient accountClient = new AccountClient(client, "ca");
         SecurityDomainClient sdClient = new SecurityDomainClient(client, "ca");
@@ -3972,12 +3971,11 @@ public class ConfigurationUtils {
         config.setCertPassword(dbPass);
 
         PKIClient client = new PKIClient(config, null);
-        PKIConnection connection = client.getConnection();
 
         // Ignore the "UNTRUSTED_ISSUER" and "CA_CERT_INVALID" validity status
         // during PKI instance creation since we are using an untrusted temporary CA cert.
-        connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER);
-        connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID);
+        client.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER);
+        client.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID);
 
         AccountClient accountClient = new AccountClient(client, "tks");
         TPSConnectorClient tpsConnectorClient = new TPSConnectorClient(client, "tks");
-- 
1.9.3



More information about the Pki-devel mailing list