On Fri, 2016-04-22 at 16:37 -0500, Endi Sukma Dewata wrote:
> On 4/22/2016 2:37 PM, Ade Lee wrote:
> > commit 0fe7bf5ff989bbc24875dce30cec8f32e89c0a8f
> > Author: Ade Lee <[email protected]>
> > Date:   Fri Apr 22 15:31:43 2016 -0400
> > 
> >      Add validity check for the signing certificate in pkispawn
> > 
> >      When either an existing CA or external CA installation is
> >      performed, use the pki-server cert validation tool to check
> >      the signing certiticate and chain.
> > 
> >      Ticket #2043
> > 
> > commit 9104fdda145c4f2bbbedec7256c73922e8bffcef
> > Author: Ade Lee <[email protected]>
> > Date:   Wed Apr 20 17:26:23 2016 -0400
> > 
> >      Add CLI to check system certificate status
> > 
> >      We add two different calls:
> >      1. pki client-cert-validate - which checks a certificate in
> > the client
> >         certdb and calls the System cert verification call
> > performed by JSS
> >        in the system self test.  This does some basic extensions
> > and trust
> >        tests, and also validates cert validity and cert trust
> > chain.
> > 
> >      2. pki-server subsystem-cert-validate  <subsystem>
> >         This calls pki client-cert-validate using the nssdb for the
> > subsystem
> >         on all of the system certificates by default (or just one
> > if the
> >         nickname is defined).
> > 
> >         This is a great thing to call when healthchecking an
> > instance,
> >         and also will be used by pkispawn to verify the signing
> > cert in the
> >         externally signed CA case.
> > 
> >      Trac Ticket 2043
> > 
> 
> In general it's ACKed. I have some minor comments/questions:
> 
> 1. The SubsystemCertificateVerifier probably should be renamed to 
> SystemCertificateVerifier since "system certificate" refers to a cert
> in 
> the subsystem/instance's NSS database and "subsystem certificate"
> could 
> be confused with the "subsystemCert cert-pki-tomcat".
> 
done

> 2. Instead of storing a shared SubsystemCertificateVerifier object in
> the PKIDeployer object it might be better to create a factory method,
> so 
> the verifier can be used like this:
> 
>    verifier = deployer.create_system_cert_verifier()
>    verifier.verify_certificate('signing')
> 
> That way the life-cycle of the verifier object will be short.
> 
done
> 3. The .classpath got changed to point to a local path on your
> machine.
> 
done
> 4. Is the "hardward-<token>" name used consistently in our code?
> 
>    passwd = instance.get_password("hardware-%s" % token)
> 

it should be for non-internal.
From 537828983b11d1b26c5b1b140e79eaa45a06c63a Mon Sep 17 00:00:00 2001
From: Ade Lee <[email protected]>
Date: Fri, 22 Apr 2016 15:31:43 -0400
Subject: [PATCH 2/2] Add validity check for the signing certificate in
 pkispawn

When either an existing CA or external CA installation is
performed, use the pki-server cert validation tool to check
the signing certiticate and chain.

Ticket #2043
---
 .../python/pki/server/deployment/pkihelper.py      | 32 ++++++++++++++
 .../server/deployment/scriptlets/configuration.py  | 51 +++++++++++++++-------
 2 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index f01f6f69ff66d3687875c8f3d88840daf2115e3f..2898d7fe072883ca37bda0ffdbe5965c680ceb36 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -4592,6 +4592,34 @@ class ConfigClient:
         return cert
 
 
+class SystemCertificateVerifier:
+    """ Verifies system certificates for a subsystem"""
+
+    def __init__(self, instance=None, subsystem=None):
+        self.instance = instance
+        self.subsystem = subsystem
+
+    def verify_certificate(self, cert_id=None):
+        cmd = ['pki-server', 'subsystem-cert-validate',
+               '-i', self.instance.name,
+               self.subsystem]
+        if cert_id is not None:
+            cmd.append(cert_id)
+        try:
+            subprocess.check_output(
+                cmd,
+                stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError as e:
+            config.pki_log.error(
+                "pki subsystem-cert-validate return code: " + str(e.returncode),
+                extra=config.PKI_INDENTATION_LEVEL_2
+            )
+            config.pki_log.error(
+                e.output,
+                extra=config.PKI_INDENTATION_LEVEL_2)
+            raise
+
+
 class PKIDeployer:
     """Holds the global dictionaries and the utility objects"""
 
@@ -4660,3 +4688,7 @@ class PKIDeployer:
         os.chmod(
             new_descriptor,
             config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS)
+
+    @staticmethod
+    def create_system_cert_verifier(instance=None, subsystem=None):
+        return SystemCertificateVerifier(instance, subsystem)
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
index 9be9a92f02503fcac0e4e0e3eb9ddd582ba847a3..fc5dc84c4bbcde0c8972705ab64ebdcada20fc4d 100644
--- a/base/server/python/pki/server/deployment/scriptlets/configuration.py
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
@@ -24,6 +24,7 @@ import re
 
 # PKI Deployment Imports
 from .. import pkiconfig as config
+from .. import pkihelper
 from .. import pkimessages as log
 from .. import pkiscriptlet
 
@@ -88,7 +89,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         instance = pki.server.PKIInstance(deployer.mdict['pki_instance_name'])
         instance.load()
 
-        subsystem = instance.get_subsystem(deployer.mdict['pki_subsystem'].lower())
+        subsystem = instance.get_subsystem(
+            deployer.mdict['pki_subsystem'].lower())
 
         token = deployer.mdict['pki_token_name']
         nssdb = instance.open_nssdb(token)
@@ -146,7 +148,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                     with open(external_csr_path) as f:
                         signing_csr = f.read()
 
-                    signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64')
+                    signing_csr = pki.nssdb.convert_csr(
+                        signing_csr, 'pem', 'base64')
                     subsystem.config['ca.signing.certreq'] = signing_csr
 
                 # This is needed by IPA to detect step 1 completion.
@@ -155,7 +158,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
 
                 subsystem.save()
 
-            if existing or external and step_two:  # existing CA or external CA step 2
+            if existing or external and step_two:
+                # existing CA or external CA step 2
 
                 # If specified, import CA signing CSR into CS.cfg.
                 signing_csr_path = deployer.mdict['pki_external_csr_path']
@@ -166,7 +170,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     with open(signing_csr_path) as f:
                         signing_csr = f.read()
-                    signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64')
+                    signing_csr = pki.nssdb.convert_csr(
+                        signing_csr, 'pem', 'base64')
                     subsystem.config['ca.signing.certreq'] = signing_csr
 
                 # If specified, import CA signing cert into NSS database.
@@ -174,32 +179,38 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 signing_cert_file = deployer.mdict['pki_external_ca_cert_path']
                 if signing_cert_file:
                     config.pki_log.info(
-                        "importing %s from %s", signing_nickname, signing_cert_file,
+                        "importing %s from %s",
+                        signing_nickname, signing_cert_file,
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     nssdb.add_cert(
                         nickname=signing_nickname,
                         cert_file=signing_cert_file,
                         trust_attributes='CT,C,C')
 
-                # If specified, import certs and keys from PKCS #12 file into NSS database.
+                # If specified, import certs and keys from PKCS #12 file
+                # into NSS database.
                 pkcs12_file = deployer.mdict['pki_external_pkcs12_path']
                 if pkcs12_file:
                     config.pki_log.info(
                         "importing certificates and keys from %s", pkcs12_file,
                         extra=config.PKI_INDENTATION_LEVEL_2)
-                    pkcs12_password = deployer.mdict['pki_external_pkcs12_password']
+                    pkcs12_password = deployer.mdict[
+                        'pki_external_pkcs12_password']
                     nssdb.import_pkcs12(pkcs12_file, pkcs12_password)
 
                 # If specified, import cert chain into NSS database.
-                # Note: Cert chain must be imported after the system certs to ensure that
-                # the system certs are imported with the correct nicknames.
+                # Note: Cert chain must be imported after the system certs
+                # to ensure that the system certs are imported with
+                # the correct nicknames.
                 external_ca_cert_chain_nickname = \
                     deployer.mdict['pki_external_ca_cert_chain_nickname']
-                external_ca_cert_chain_file = deployer.mdict['pki_external_ca_cert_chain_path']
+                external_ca_cert_chain_file = deployer.mdict[
+                    'pki_external_ca_cert_chain_path']
                 if external_ca_cert_chain_file:
                     config.pki_log.info(
                         "importing certificate chain %s from %s",
-                        external_ca_cert_chain_nickname, external_ca_cert_chain_file,
+                        external_ca_cert_chain_nickname,
+                        external_ca_cert_chain_file,
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     cert_chain, _nicks = nssdb.import_cert_chain(
                         nickname=external_ca_cert_chain_nickname,
@@ -207,19 +218,29 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                         trust_attributes='CT,C,C')
                     subsystem.config['ca.external_ca_chain.cert'] = cert_chain
 
-                # Export CA signing cert from NSS database and import it into CS.cfg.
+                # Export CA signing cert from NSS database and import
+                # it into CS.cfg.
                 signing_cert_data = nssdb.get_cert(
                     nickname=signing_nickname,
                     output_format='base64')
                 subsystem.config['ca.signing.nickname'] = signing_nickname
-                subsystem.config['ca.signing.tokenname'] = deployer.mdict['pki_ca_signing_token']
+                subsystem.config['ca.signing.tokenname'] = (
+                    deployer.mdict['pki_ca_signing_token'])
                 subsystem.config['ca.signing.cert'] = signing_cert_data
                 subsystem.config['ca.signing.cacertnickname'] = signing_nickname
-                subsystem.config['ca.signing.defaultSigningAlgorithm'] = \
-                    deployer.mdict['pki_ca_signing_signing_algorithm']
+                subsystem.config['ca.signing.defaultSigningAlgorithm'] = (
+                    deployer.mdict['pki_ca_signing_signing_algorithm'])
 
                 subsystem.save()
 
+                # verify the signing certificate
+                # raises exception on  failure
+                config.pki_log.info("validating the signing certificate",
+                                    extra=config.PKI_INDENTATION_LEVEL_2)
+                verifier = pkihelper.PKIDeployer.create_system_cert_verifier(
+                    instance, 'ca')
+                verifier.verify_certificate('signing')
+
             else:  # self-signed CA
 
                 # To be implemented in ticket #1692.
-- 
2.4.3

From f8e6d684f6a24a4ea52e1fcf9d81e1b9ef96ccca Mon Sep 17 00:00:00 2001
From: Ade Lee <[email protected]>
Date: Wed, 20 Apr 2016 17:26:23 -0400
Subject: [PATCH 1/2] Add CLI to check system certificate status

We add two different calls:
1. pki client-cert-validate - which checks a certificate in the client
   certdb and calls the System cert verification call performed by JSS
  in the system self test.  This does some basic extensions and trust
  tests, and also validates cert validity and cert trust chain.

2. pki-server subsystem-cert-validate  <subsystem>
   This calls pki client-cert-validate using the nssdb for the subsystem
   on all of the system certificates by default (or just one if the
   nickname is defined).

   This is a great thing to call when healthchecking an instance,
   and also will be used by pkispawn to verify the signing cert in the
   externally signed CA case.

Trac Ticket 2043
---
 .../com/netscape/cmstools/client/ClientCLI.java    |   1 +
 .../cmstools/client/ClientCertValidateCLI.java     | 194 +++++++++++++++++++++
 base/server/python/pki/server/__init__.py          |   2 +
 base/server/python/pki/server/cli/subsystem.py     | 118 +++++++++++++
 4 files changed, 315 insertions(+)
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientCertValidateCLI.java

diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
index f09ea74e9ca514e7c9c5448ef4e2a028038cdd98..8bafd84f67f61da24f5df212c9c5b6c0debfe97f 100644
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
@@ -39,6 +39,7 @@ public class ClientCLI extends CLI {
         addModule(new ClientCertRemoveCLI(this));
         addModule(new ClientCertRequestCLI(this));
         addModule(new ClientCertShowCLI(this));
+        addModule(new ClientCertValidateCLI(this));
     }
 
     public String getFullName() {
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertValidateCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertValidateCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..3988c71e25df58bef2bca2d5ff111a7d295ddcd1
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertValidateCLI.java
@@ -0,0 +1,194 @@
+// --- 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) 2016 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.lang.StringUtils;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+
+import com.netscape.cmstools.cli.CLI;
+
+/**
+ * @author Ade Lee
+ */
+public class ClientCertValidateCLI extends CLI {
+
+    public ClientCLI clientCLI;
+
+    public ClientCertValidateCLI(ClientCLI clientCLI) {
+        super("cert-validate", "Validate certificate", clientCLI);
+        this.clientCLI = clientCLI;
+
+        createOptions();
+    }
+
+    public void createOptions() {
+        Option option = new Option(null, "certusage", true, "Certificate usage.");
+        option.setArgName("certusage");
+        options.addOption(option);
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " nickname", options);
+    }
+
+    public void execute(String[] args) throws Exception {
+        // Always check for "--help" prior to parsing
+        if (Arrays.asList(args).contains("--help")) {
+            // Display usage
+            printHelp();
+            System.exit(0);
+        }
+
+        CommandLine cmd = null;
+
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(-1);
+        }
+
+        String[] cmdArgs = cmd.getArgs();
+
+        if (cmdArgs.length != 1) {
+            System.err.println("Error: Invalid number of arguments.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        // Get nickname from command argument.
+        String nickname = cmdArgs[0];
+
+        // get usages from options
+        String certusage = cmd.getOptionValue("certusage");
+        boolean isValid = false;
+
+        try {
+            isValid = verifySystemCertByNickname(nickname, certusage);
+        } catch (Exception e) {
+            System.err.println("Certificate verification failed: " + e);
+            isValid = false;
+        }
+
+        if (isValid) {
+            System.exit(0);
+        } else {
+            System.exit(1);
+        }
+    }
+
+    public boolean verifySystemCertByNickname(String nickname, String certusage) throws Exception {
+        CertificateUsage cu = getCertificateUsage(certusage);
+        int ccu = 0;
+
+        if (cu == null) {
+            throw new Exception("Unsupported certificate usage " + certusage +
+                    " in certificate " + nickname);
+        }
+
+        CryptoManager cm = CryptoManager.getInstance();
+        if (cu.getUsage() != CryptoManager.CertificateUsage.CheckAllUsages.getUsage()) {
+            if (cm.isCertValid(nickname, true, cu)) {
+                System.out.println("Valid certificate: " + nickname);
+                return true;
+            } else {
+                System.out.println("Invalid certificate: " + nickname);
+                return false;
+            }
+
+        } else {
+            // check all possible usages
+            ccu = cm.isCertValid(nickname, true);
+            if (ccu == CertificateUsage.basicCertificateUsages) {
+                /* cert is good for nothing */
+                System.out.println("Cert is good for nothing: " + nickname);
+                return false;
+            } else {
+                List<String> usages = new ArrayList<String>();
+                if ((ccu & CryptoManager.CertificateUsage.SSLServer.getUsage()) != 0)
+                    usages.add("SSLServer");
+                if ((ccu & CryptoManager.CertificateUsage.SSLClient.getUsage()) != 0)
+                    usages.add("SSLClient");
+                if ((ccu & CryptoManager.CertificateUsage.SSLServerWithStepUp.getUsage()) != 0)
+                    usages.add("SSLServerWithStepUp");
+                if ((ccu & CryptoManager.CertificateUsage.SSLCA.getUsage()) != 0)
+                    usages.add("SSLCA");
+                if ((ccu & CryptoManager.CertificateUsage.EmailSigner.getUsage()) != 0)
+                    usages.add("EmailSigner");
+                if ((ccu & CryptoManager.CertificateUsage.EmailRecipient.getUsage()) != 0)
+                    usages.add("EmailRecipient");
+                if ((ccu & CryptoManager.CertificateUsage.ObjectSigner.getUsage()) != 0)
+                    usages.add("ObjectSigner");
+                if ((ccu & CryptoManager.CertificateUsage.UserCertImport.getUsage()) != 0)
+                    usages.add("UserCertImport");
+                if ((ccu & CryptoManager.CertificateUsage.VerifyCA.getUsage()) != 0)
+                    usages.add("VerifyCA");
+                if ((ccu & CryptoManager.CertificateUsage.ProtectedObjectSigner.getUsage()) != 0)
+                    usages.add("ProtectedObjectSigner");
+                if ((ccu & CryptoManager.CertificateUsage.StatusResponder.getUsage()) != 0)
+                    usages.add("StatusResponder");
+                if ((ccu & CryptoManager.CertificateUsage.AnyCA.getUsage()) != 0)
+                    usages.add("AnyCA");
+                System.out.println("Cert has the following usages: " + StringUtils.join(usages, ','));
+                return true;
+            }
+        }
+    }
+
+    public CertificateUsage getCertificateUsage(String certusage) {
+        CertificateUsage cu = null;
+        if ((certusage == null) || certusage.equals(""))
+            cu = CryptoManager.CertificateUsage.CheckAllUsages;
+        else if (certusage.equalsIgnoreCase("CheckAllUsages"))
+            cu = CryptoManager.CertificateUsage.CheckAllUsages;
+        else if (certusage.equalsIgnoreCase("SSLServer"))
+            cu = CryptoManager.CertificateUsage.SSLServer;
+        else if (certusage.equalsIgnoreCase("SSLServerWithStepUp"))
+            cu = CryptoManager.CertificateUsage.SSLServerWithStepUp;
+        else if (certusage.equalsIgnoreCase("SSLClient"))
+            cu = CryptoManager.CertificateUsage.SSLClient;
+        else if (certusage.equalsIgnoreCase("SSLCA"))
+            cu = CryptoManager.CertificateUsage.SSLCA;
+        else if (certusage.equalsIgnoreCase("AnyCA"))
+            cu = CryptoManager.CertificateUsage.AnyCA;
+        else if (certusage.equalsIgnoreCase("StatusResponder"))
+            cu = CryptoManager.CertificateUsage.StatusResponder;
+        else if (certusage.equalsIgnoreCase("ObjectSigner"))
+            cu = CryptoManager.CertificateUsage.ObjectSigner;
+        else if (certusage.equalsIgnoreCase("UserCertImport"))
+            cu = CryptoManager.CertificateUsage.UserCertImport;
+        else if (certusage.equalsIgnoreCase("ProtectedObjectSigner"))
+            cu = CryptoManager.CertificateUsage.ProtectedObjectSigner;
+        else if (certusage.equalsIgnoreCase("VerifyCA"))
+            cu = CryptoManager.CertificateUsage.VerifyCA;
+        else if (certusage.equalsIgnoreCase("EmailSigner"))
+            cu = CryptoManager.CertificateUsage.EmailSigner;
+
+        return cu;
+    }
+}
diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
index 64688b3c4ad80ac5371f621f6046d62564317521..1c590c37e75315d27de6b42674f6de1d8bd651f6 100644
--- a/base/server/python/pki/server/__init__.py
+++ b/base/server/python/pki/server/__init__.py
@@ -156,6 +156,8 @@ class PKISubsystem(object):
             '%s.%s.cert' % (self.name, cert_id), None)
         cert['request'] = self.config.get(
             '%s.%s.certreq' % (self.name, cert_id), None)
+        cert['certusage'] = self.config.get(
+            '%s.cert.%s.certusage' % (self.name, cert_id), None)
         return cert
 
     def update_subsystem_cert(self, cert):
diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
index 03d48f9262f8ac15e1dfbb8df63111c9cf0dabce..6d60468a657a048367c146ef8216acf646364976 100644
--- a/base/server/python/pki/server/cli/subsystem.py
+++ b/base/server/python/pki/server/cli/subsystem.py
@@ -24,8 +24,11 @@ import base64
 import getopt
 import getpass
 import nss.nss as nss
+import os
 import string
+import subprocess
 import sys
+from tempfile import mkstemp
 
 import pki.cli
 import pki.nssdb
@@ -299,6 +302,7 @@ class SubsystemCertCLI(pki.cli.CLI):
         self.add_module(SubsystemCertShowCLI())
         self.add_module(SubsystemCertExportCLI())
         self.add_module(SubsystemCertUpdateCLI())
+        self.add_module(SubsystemCertValidateCLI())
 
     @staticmethod
     def print_subsystem_cert(cert, show_all=False):
@@ -713,3 +717,117 @@ class SubsystemCertUpdateCLI(pki.cli.CLI):
         self.print_message('Updated "%s" subsystem certificate' % cert_id)
 
         SubsystemCertCLI.print_subsystem_cert(subsystem_cert)
+
+
+class SubsystemCertValidateCLI(pki.cli.CLI):
+
+    def __init__(self):
+        super(SubsystemCertValidateCLI, self).__init__(
+            'validate', 'Validate subsystem certificates')
+
+    def usage(self):
+        print('Usage: pki-server subsystem-cert-validate [OPTIONS] <subsystem ID> [<cert_id>]')
+        print()
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
+        print('  -v, --verbose                   Run in verbose mode.')
+        print('      --help                      Show help message.')
+        print()
+
+    def execute(self, argv):
+
+        try:
+            opts, args = getopt.gnu_getopt(argv, 'i:v', [
+                'instance=',
+                'verbose', 'help'])
+
+        except getopt.GetoptError as e:
+            print('ERROR: ' + str(e))
+            self.usage()
+            sys.exit(1)
+
+        if len(args) < 1:
+            print('ERROR: missing subsystem ID')
+            self.usage()
+            sys.exit(1)
+
+        subsystem_name = args[0]
+
+        if len(args) >=2:
+            cert_id = args[1]
+        else:
+            cert_id = None
+
+        instance_name = 'pki-tomcat'
+
+        for o, a in opts:
+            if o in ('-i', '--instance'):
+                instance_name = a
+
+            elif o in ('-v', '--verbose'):
+                self.set_verbose(True)
+
+            elif o == '--help':
+                self.print_help()
+                sys.exit()
+
+            else:
+                self.print_message('ERROR: unknown option ' + o)
+                self.usage()
+                sys.exit(1)
+
+        instance = pki.server.PKIInstance(instance_name)
+        instance.load()
+
+        subsystem = instance.get_subsystem(subsystem_name)
+
+        if cert_id is not None:
+            certs = [subsystem.get_subsystem_cert(cert_id)]
+        else:
+            certs = subsystem.find_system_certs()
+
+        certs_valid = True
+        for cert in certs:
+            token = cert['token']
+
+            # get token password and store in temporary file
+            if token == 'Internal Key Storage Token':
+                passwd = instance.get_password('internal')
+            else:
+                passwd = instance.get_password("hardware-%s" % token)
+
+            pwfile_handle, pwfile_path = mkstemp()
+            os.write(pwfile_handle, passwd)
+            os.close(pwfile_handle)
+
+            cmd = ['pki', '-d', instance.nssdb_dir,
+                   '-W', pwfile_path ]
+
+            if token != 'Internal Key Storage Token':
+                cmd.extend(['--token', token])
+
+            cmd.extend(
+                ['client-cert-validate',
+                 cert['nickname'],
+                 '--certusage', cert['certusage']]
+            )
+
+            try:
+                subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+                self.print_message("Valid certificate : %s" %cert['nickname'])
+            except subprocess.CalledProcessError as e:
+                certs_valid = False
+                if e.returncode == 1:
+                    self.print_message("Invalid certificate: %s"
+                                       % cert['nickname'])
+                else:
+                    self.print_message("Error in validating certificate: %s"
+                                       % cert['nickname'])
+                self.print_message(e.output)
+            finally:
+                os.unlink(pwfile_path)
+
+        if certs_valid:
+            sys.exit(0)
+        else:
+            sys.exit(1)
+
-- 
2.4.3

_______________________________________________
Pki-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/pki-devel

Reply via email to