Blame SOURCES/pki-core-10.5.1-alpha.patch

fe6b0b
From 8d109e0b7ca6af60f862c641a6287d93a1dcb01b Mon Sep 17 00:00:00 2001
fe6b0b
From: Jack Magne <jmagne@redhat.com>
fe6b0b
Date: Tue, 7 Nov 2017 11:05:55 -0800
fe6b0b
Subject: Fix #2735 Secure removal of secret data storage (phase 2)
fe6b0b
fe6b0b
This portion of the fix attempts to take care of the remaining secret data
fe6b0b
storage issues that could be practically taken care of with respect to
fe6b0b
servers and clients.
fe6b0b
fe6b0b
A new method was placed in CryptoUtil to server the needs of clients.
fe6b0b
Change-Id: I1a14daabcad72e531572d1be8bc255e2e501b70a
fe6b0b
fe6b0b
(cherry picked from commit f5ec7c2af4a1fb44d5731c74672bf789e9240499)
fe6b0b
---
fe6b0b
 base/common/src/com/netscape/certsrv/key/Key.java  |   6 +
fe6b0b
 .../src/com/netscape/cmstools/CMCRequest.java      |  23 ++-
fe6b0b
 .../src/com/netscape/cmstools/CMCSharedToken.java  |   2 +
fe6b0b
 .../src/com/netscape/cmstools/PasswordCache.java   |   1 +
fe6b0b
 .../com/netscape/cmstools/key/KeyRetrieveCLI.java  | 162 +++++++++++----------
fe6b0b
 .../cms/servlet/tks/SecureChannelProtocol.java     |  14 +-
fe6b0b
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    |  20 +++
fe6b0b
 7 files changed, 139 insertions(+), 89 deletions(-)
fe6b0b
fe6b0b
diff --git a/base/common/src/com/netscape/certsrv/key/Key.java b/base/common/src/com/netscape/certsrv/key/Key.java
fe6b0b
index 1afd54c..69b59f3 100644
fe6b0b
--- a/base/common/src/com/netscape/certsrv/key/Key.java
fe6b0b
+++ b/base/common/src/com/netscape/certsrv/key/Key.java
fe6b0b
@@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlElement;
fe6b0b
 import javax.xml.bind.annotation.XmlRootElement;
fe6b0b
 
fe6b0b
 import com.netscape.certsrv.request.RequestId;
fe6b0b
+import com.netscape.cmsutil.crypto.CryptoUtil;
fe6b0b
 import com.netscape.cmsutil.util.Utils;
fe6b0b
 
fe6b0b
 /**
fe6b0b
@@ -159,4 +160,9 @@ public class Key {
fe6b0b
     public void setPublicKey(String publicKey) {
fe6b0b
         this.publicKey = publicKey;
fe6b0b
     }
fe6b0b
+
fe6b0b
+    public void clearSensitiveData() {
fe6b0b
+        CryptoUtil.obscureBytes(data, "random");
fe6b0b
+        data = null;
fe6b0b
+    }
fe6b0b
 }
fe6b0b
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
fe6b0b
index 37752cd..fc58f4e 100644
fe6b0b
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
fe6b0b
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
fe6b0b
@@ -38,13 +38,6 @@ import java.util.Arrays;
fe6b0b
 import java.util.Date;
fe6b0b
 import java.util.StringTokenizer;
fe6b0b
 
fe6b0b
-import netscape.security.pkcs.PKCS10;
fe6b0b
-import netscape.security.x509.KeyIdentifier;
fe6b0b
-import netscape.security.x509.PKIXExtensions;
fe6b0b
-import netscape.security.x509.SubjectKeyIdentifierExtension;
fe6b0b
-import netscape.security.x509.X500Name;
fe6b0b
-import netscape.security.x509.X509CertImpl;
fe6b0b
-
fe6b0b
 import org.mozilla.jss.CryptoManager;
fe6b0b
 import org.mozilla.jss.asn1.ANY;
fe6b0b
 import org.mozilla.jss.asn1.ASN1Util;
fe6b0b
@@ -114,6 +107,13 @@ import com.netscape.cmsutil.util.Cert;
fe6b0b
 import com.netscape.cmsutil.util.HMACDigest;
fe6b0b
 import com.netscape.cmsutil.util.Utils;
fe6b0b
 
fe6b0b
+import netscape.security.pkcs.PKCS10;
fe6b0b
+import netscape.security.x509.KeyIdentifier;
fe6b0b
+import netscape.security.x509.PKIXExtensions;
fe6b0b
+import netscape.security.x509.SubjectKeyIdentifierExtension;
fe6b0b
+import netscape.security.x509.X500Name;
fe6b0b
+import netscape.security.x509.X509CertImpl;
fe6b0b
+
fe6b0b
 /**
fe6b0b
  * Tool for creating CMC full request
fe6b0b
  *
fe6b0b
@@ -1803,6 +1803,7 @@ public class CMCRequest {
fe6b0b
             System.exit(1);
fe6b0b
         }
fe6b0b
 
fe6b0b
+        byte challenge[] = null;
fe6b0b
         try {
fe6b0b
             TaggedRequest request = encryptedPop.getRequest();
fe6b0b
             AlgorithmIdentifier thePOPAlgID = encryptedPop.getThePOPAlgID();
fe6b0b
@@ -1838,7 +1839,7 @@ public class CMCRequest {
fe6b0b
             }
fe6b0b
             System.out.println(method + "symKey unwrapped.");
fe6b0b
 
fe6b0b
-            byte challenge[] = CryptoUtil.decryptUsingSymmetricKey(
fe6b0b
+            challenge = CryptoUtil.decryptUsingSymmetricKey(
fe6b0b
                     token,
fe6b0b
                     ivps,
fe6b0b
                     encCI.getEncryptedContent().toByteArray(),
fe6b0b
@@ -1857,13 +1858,16 @@ public class CMCRequest {
fe6b0b
                 MessageDigest hash = MessageDigest.getInstance(CryptoUtil.getNameFromHashAlgorithm(witnessAlgID));
fe6b0b
                 byte[] digest = hash.digest(challenge);
fe6b0b
                 boolean witnessChecked = Arrays.equals(digest, witness.toByteArray());
fe6b0b
+                CryptoUtil.obscureBytes(digest,"random");
fe6b0b
                 if (witnessChecked) {
fe6b0b
                     System.out.println(method + "Yay! witness verified");
fe6b0b
                 } else {
fe6b0b
+                    CryptoUtil.obscureBytes(challenge, "random");
fe6b0b
                     System.out.println(method + "Oops! witness failed to verify.  Must abort!");
fe6b0b
                     System.exit(1);
fe6b0b
                 }
fe6b0b
             } catch (Exception ex) {
fe6b0b
+                CryptoUtil.obscureBytes(challenge, "random");
fe6b0b
                 System.out.println(method + ex);
fe6b0b
                 System.exit(1);
fe6b0b
             }
fe6b0b
@@ -1877,6 +1881,7 @@ public class CMCRequest {
fe6b0b
                 hmacDigest.update(ASN1Util.encode(request));
fe6b0b
                 popProofValue = hmacDigest.digest();
fe6b0b
             } catch (Exception ex) {
fe6b0b
+                CryptoUtil.obscureBytes(challenge, "random");
fe6b0b
                 System.out.println(method + "calculating POP Proof Value failed: " + ex);
fe6b0b
                 System.exit(1);
fe6b0b
             }
fe6b0b
@@ -1912,6 +1917,8 @@ public class CMCRequest {
fe6b0b
         } catch (Exception e) {
fe6b0b
             System.out.println(method + e);
fe6b0b
             System.exit(1);
fe6b0b
+        } finally {
fe6b0b
+            CryptoUtil.obscureBytes(challenge, "random");
fe6b0b
         }
fe6b0b
 
fe6b0b
         System.out.println(method + " completes.");
fe6b0b
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCSharedToken.java b/base/java-tools/src/com/netscape/cmstools/CMCSharedToken.java
fe6b0b
index a0a7651..d16dd0c 100644
fe6b0b
--- a/base/java-tools/src/com/netscape/cmstools/CMCSharedToken.java
fe6b0b
+++ b/base/java-tools/src/com/netscape/cmstools/CMCSharedToken.java
fe6b0b
@@ -299,6 +299,8 @@ public class CMCSharedToken {
fe6b0b
 
fe6b0b
                 String ver_spassphrase = new String(ver_passphrase, "UTF-8");
fe6b0b
 
fe6b0b
+                CryptoUtil.obscureBytes(ver_passphrase, "random");
fe6b0b
+
fe6b0b
                 System.out.println("ver_passphrase String = " + ver_spassphrase);
fe6b0b
                 System.out.println("ver_passphrase UTF-8 bytes = ");
fe6b0b
                 System.out.println(Arrays.toString(ver_spassphrase.getBytes("UTF-8")));
fe6b0b
diff --git a/base/java-tools/src/com/netscape/cmstools/PasswordCache.java b/base/java-tools/src/com/netscape/cmstools/PasswordCache.java
fe6b0b
index 7f17c8f..859eda3 100644
fe6b0b
--- a/base/java-tools/src/com/netscape/cmstools/PasswordCache.java
fe6b0b
+++ b/base/java-tools/src/com/netscape/cmstools/PasswordCache.java
fe6b0b
@@ -554,6 +554,7 @@ class PWsdrCache {
fe6b0b
                 byte[] dcryptb = sdr.decrypt(bos.toByteArray());
fe6b0b
 
fe6b0b
                 dcrypts = new String(dcryptb, "UTF-8");
fe6b0b
+                CryptoUtil.obscureBytes(dcryptb, "random");
fe6b0b
             } catch (TokenException e) {
fe6b0b
                 System.out.println("password cache decrypto failed " + e.toString());
fe6b0b
                 e.printStackTrace();
fe6b0b
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
fe6b0b
index 736c6e6..8339218 100644
fe6b0b
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
fe6b0b
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
fe6b0b
@@ -87,106 +87,116 @@ public class KeyRetrieveCLI extends CLI {
fe6b0b
             throw new Exception("Incorrect number of parameters provided.");
fe6b0b
         }
fe6b0b
 
fe6b0b
-        String keyId = cmd.getOptionValue("keyID");
fe6b0b
-        String passphrase = cmd.getOptionValue("passphrase");
fe6b0b
-        String requestId = cmd.getOptionValue("requestID");
fe6b0b
-        String outputFilePath = cmd.getOptionValue("output");
fe6b0b
-        String outputDataFile = cmd.getOptionValue("output-data");
fe6b0b
-        String requestFile = cmd.getOptionValue("input");
fe6b0b
-        String transportNickname = cmd.getOptionValue("transport");
fe6b0b
-
fe6b0b
-        KeyClient keyClient = keyCLI.getKeyClient(transportNickname);
fe6b0b
         Key keyData = null;
fe6b0b
 
fe6b0b
-        if (requestFile != null) {
fe6b0b
-            JAXBContext context = JAXBContext.newInstance(KeyRecoveryRequest.class);
fe6b0b
-            Unmarshaller unmarshaller = context.createUnmarshaller();
fe6b0b
-            FileInputStream fis = new FileInputStream(requestFile);
fe6b0b
-            KeyRecoveryRequest req = (KeyRecoveryRequest) unmarshaller.unmarshal(fis);
fe6b0b
-
fe6b0b
-            if (req.getKeyId() == null) {
fe6b0b
-                throw new Exception("Key ID must be specified in the request file.");
fe6b0b
-            }
fe6b0b
-
fe6b0b
-            if (req.getCertificate() != null) {
fe6b0b
-                keyData = keyClient.retrieveKeyByPKCS12(req.getKeyId(), req.getCertificate(),
fe6b0b
-                        req.getPassphrase());
fe6b0b
+        try {
fe6b0b
+            String keyId = cmd.getOptionValue("keyID");
fe6b0b
+            String passphrase = cmd.getOptionValue("passphrase");
fe6b0b
+            String requestId = cmd.getOptionValue("requestID");
fe6b0b
+            String outputFilePath = cmd.getOptionValue("output");
fe6b0b
+            String outputDataFile = cmd.getOptionValue("output-data");
fe6b0b
+            String requestFile = cmd.getOptionValue("input");
fe6b0b
+            String transportNickname = cmd.getOptionValue("transport");
fe6b0b
+
fe6b0b
+            KeyClient keyClient = keyCLI.getKeyClient(transportNickname);
fe6b0b
+
fe6b0b
+            if (requestFile != null) {
fe6b0b
+                JAXBContext context = JAXBContext.newInstance(KeyRecoveryRequest.class);
fe6b0b
+                Unmarshaller unmarshaller = context.createUnmarshaller();
fe6b0b
+                FileInputStream fis = new FileInputStream(requestFile);
fe6b0b
+                KeyRecoveryRequest req = (KeyRecoveryRequest) unmarshaller.unmarshal(fis);
fe6b0b
+
fe6b0b
+                if (req.getKeyId() == null) {
fe6b0b
+                    throw new Exception("Key ID must be specified in the request file.");
fe6b0b
+                }
fe6b0b
 
fe6b0b
-            } else if (req.getPassphrase() != null) {
fe6b0b
-                keyData = keyClient.retrieveKeyByPassphrase(req.getKeyId(), req.getPassphrase());
fe6b0b
+                if (req.getCertificate() != null) {
fe6b0b
+                    keyData = keyClient.retrieveKeyByPKCS12(req.getKeyId(), req.getCertificate(),
fe6b0b
+                            req.getPassphrase());
fe6b0b
 
fe6b0b
-            } else if (req.getSessionWrappedPassphrase() != null) {
fe6b0b
-                keyData = keyClient.retrieveKeyUsingWrappedPassphrase(req.getKeyId(),
fe6b0b
-                        Utils.base64decode(req.getTransWrappedSessionKey()),
fe6b0b
-                        Utils.base64decode(req.getSessionWrappedPassphrase()),
fe6b0b
-                        Utils.base64decode(req.getNonceData()));
fe6b0b
+                } else if (req.getPassphrase() != null) {
fe6b0b
+                    keyData = keyClient.retrieveKeyByPassphrase(req.getKeyId(), req.getPassphrase());
fe6b0b
 
fe6b0b
-            } else if (req.getTransWrappedSessionKey() != null) {
fe6b0b
-                keyData = keyClient.retrieveKey(req.getKeyId(),
fe6b0b
-                        Utils.base64decode(req.getTransWrappedSessionKey()));
fe6b0b
+                } else if (req.getSessionWrappedPassphrase() != null) {
fe6b0b
+                    keyData = keyClient.retrieveKeyUsingWrappedPassphrase(req.getKeyId(),
fe6b0b
+                            Utils.base64decode(req.getTransWrappedSessionKey()),
fe6b0b
+                            Utils.base64decode(req.getSessionWrappedPassphrase()),
fe6b0b
+                            Utils.base64decode(req.getNonceData()));
fe6b0b
 
fe6b0b
-            } else {
fe6b0b
-                keyData = keyClient.retrieveKey(req.getKeyId());
fe6b0b
-            }
fe6b0b
+                } else if (req.getTransWrappedSessionKey() != null) {
fe6b0b
+                    keyData = keyClient.retrieveKey(req.getKeyId(),
fe6b0b
+                            Utils.base64decode(req.getTransWrappedSessionKey()));
fe6b0b
 
fe6b0b
-        } else {
fe6b0b
-            // Using command line options.
fe6b0b
-            if (requestId == null && keyId == null) {
fe6b0b
-                throw new Exception("Either requestID or keyID must be specified");
fe6b0b
-            }
fe6b0b
-
fe6b0b
-            if (passphrase != null) {
fe6b0b
-                if (requestId != null) {
fe6b0b
-                    keyData = keyClient.retrieveKeyByRequestWithPassphrase(
fe6b0b
-                            new RequestId(requestId), passphrase);
fe6b0b
                 } else {
fe6b0b
-                    keyData = keyClient.retrieveKeyByPassphrase(new KeyId(keyId), passphrase);
fe6b0b
+                    keyData = keyClient.retrieveKey(req.getKeyId());
fe6b0b
                 }
fe6b0b
 
fe6b0b
             } else {
fe6b0b
-                if (requestId != null) {
fe6b0b
-                    keyData = keyClient.retrieveKeyByRequest(new RequestId(requestId));
fe6b0b
-                } else {
fe6b0b
-                    keyData = keyClient.retrieveKey(new KeyId(keyId));
fe6b0b
+                // Using command line options.
fe6b0b
+                if (requestId == null && keyId == null) {
fe6b0b
+                    throw new Exception("Either requestID or keyID must be specified");
fe6b0b
                 }
fe6b0b
 
fe6b0b
-                clientEncryption = false;
fe6b0b
+                if (passphrase != null) {
fe6b0b
+                    if (requestId != null) {
fe6b0b
+                        keyData = keyClient.retrieveKeyByRequestWithPassphrase(
fe6b0b
+                                new RequestId(requestId), passphrase);
fe6b0b
+                    } else {
fe6b0b
+                        keyData = keyClient.retrieveKeyByPassphrase(new KeyId(keyId), passphrase);
fe6b0b
+                    }
fe6b0b
+
fe6b0b
+                } else {
fe6b0b
+                    if (requestId != null) {
fe6b0b
+                        keyData = keyClient.retrieveKeyByRequest(new RequestId(requestId));
fe6b0b
+                    } else {
fe6b0b
+                        keyData = keyClient.retrieveKey(new KeyId(keyId));
fe6b0b
+                    }
fe6b0b
+
fe6b0b
+                    clientEncryption = false;
fe6b0b
 
fe6b0b
-                // No need to return the encrypted data since encryption
fe6b0b
-                // is done locally.
fe6b0b
-                keyData.setEncryptedData(null);
fe6b0b
+                    // No need to return the encrypted data since encryption
fe6b0b
+                    // is done locally.
fe6b0b
+                    keyData.setEncryptedData(null);
fe6b0b
+                }
fe6b0b
             }
fe6b0b
-        }
fe6b0b
 
fe6b0b
-        MainCLI.printMessage("Retrieve Key Information");
fe6b0b
+            MainCLI.printMessage("Retrieve Key Information");
fe6b0b
 
fe6b0b
-        if (outputDataFile != null) {
fe6b0b
+            if (outputDataFile != null) {
fe6b0b
 
fe6b0b
-            byte[] data;
fe6b0b
-            if (clientEncryption) { // store encrypted data
fe6b0b
-                data = keyData.getEncryptedData();
fe6b0b
+                byte[] data;
fe6b0b
+                if (clientEncryption) { // store encrypted data
fe6b0b
+                    data = keyData.getEncryptedData();
fe6b0b
 
fe6b0b
-            } else { // store unencrypted data
fe6b0b
-                data = keyData.getData();
fe6b0b
-            }
fe6b0b
+                } else { // store unencrypted data
fe6b0b
+                    data = keyData.getData();
fe6b0b
+                }
fe6b0b
 
fe6b0b
-            Path path = Paths.get(outputDataFile);
fe6b0b
-            Files.write(path, data);
fe6b0b
+                Path path = Paths.get(outputDataFile);
fe6b0b
+                Files.write(path, data);
fe6b0b
 
fe6b0b
-            printKeyInfo(keyData);
fe6b0b
-            System.out.println("  Output: " + outputDataFile);
fe6b0b
+                printKeyInfo(keyData);
fe6b0b
+                System.out.println("  Output: " + outputDataFile);
fe6b0b
 
fe6b0b
-        } else if (outputFilePath != null) {
fe6b0b
-            JAXBContext context = JAXBContext.newInstance(Key.class);
fe6b0b
-            Marshaller marshaller = context.createMarshaller();
fe6b0b
-            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
fe6b0b
-            marshaller.marshal(keyData, new File(outputFilePath));
fe6b0b
+            } else if (outputFilePath != null) {
fe6b0b
+                JAXBContext context = JAXBContext.newInstance(Key.class);
fe6b0b
+                Marshaller marshaller = context.createMarshaller();
fe6b0b
+                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
fe6b0b
+                marshaller.marshal(keyData, new File(outputFilePath));
fe6b0b
 
fe6b0b
-            System.out.println("  Output: " + outputFilePath);
fe6b0b
+                System.out.println("  Output: " + outputFilePath);
fe6b0b
 
fe6b0b
-        } else {
fe6b0b
-            printKeyInfo(keyData);
fe6b0b
-            printKeyData(keyData);
fe6b0b
+            } else {
fe6b0b
+                printKeyInfo(keyData);
fe6b0b
+                printKeyData(keyData);
fe6b0b
+            }
fe6b0b
+
fe6b0b
+        } catch (Exception e) {
fe6b0b
+            throw e;
fe6b0b
+        } finally {
fe6b0b
+            if (keyData != null) {
fe6b0b
+                keyData.clearSensitiveData();
fe6b0b
+            }
fe6b0b
         }
fe6b0b
     }
fe6b0b
 
fe6b0b
diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
fe6b0b
index c3b3952..1110cc6 100644
fe6b0b
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
fe6b0b
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
fe6b0b
@@ -25,12 +25,13 @@ import org.mozilla.jss.crypto.SymmetricKey.NotExtractableException;
fe6b0b
 import org.mozilla.jss.crypto.SymmetricKeyDeriver;
fe6b0b
 import org.mozilla.jss.crypto.TokenException;
fe6b0b
 
fe6b0b
-import sun.security.pkcs11.wrapper.PKCS11Constants;
fe6b0b
-
fe6b0b
 import com.netscape.certsrv.apps.CMS;
fe6b0b
 import com.netscape.certsrv.base.EBaseException;
fe6b0b
+import com.netscape.cmscore.security.JssSubsystem;
fe6b0b
 import com.netscape.cmsutil.crypto.CryptoUtil;
fe6b0b
 
fe6b0b
+import sun.security.pkcs11.wrapper.PKCS11Constants;
fe6b0b
+
fe6b0b
 public class SecureChannelProtocol {
fe6b0b
 
fe6b0b
     static String sharedSecretKeyName = null;
fe6b0b
@@ -341,7 +342,8 @@ public class SecureChannelProtocol {
fe6b0b
                     byte[] finalKeyBytes = nistKdf.kdf_AES_CMAC_SCP03(divKey, context, constant, 16);
fe6b0b
                     sessionKey = unwrapAESSymKeyOnToken(token, finalKeyBytes, false);
fe6b0b
 
fe6b0b
-                    Arrays.fill(finalKeyBytes,(byte) 0);
fe6b0b
+                    JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+                    jssSubsystem.obscureBytes(finalKeyBytes);
fe6b0b
 
fe6b0b
                     //The final session key is AES.
fe6b0b
                 }
fe6b0b
@@ -393,7 +395,8 @@ public class SecureChannelProtocol {
fe6b0b
                     byte[] finalKeyBytes = nistKdf.kdf_AES_CMAC_SCP03(divKey, context, constant, 16);
fe6b0b
                     sessionKey = unwrapAESSymKeyOnToken(token, finalKeyBytes, false);
fe6b0b
 
fe6b0b
-                    Arrays.fill(finalKeyBytes,(byte) 0);
fe6b0b
+                    JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+                    jssSubsystem.obscureBytes(finalKeyBytes);
fe6b0b
                 }
fe6b0b
             }
fe6b0b
         }
fe6b0b
@@ -908,7 +911,8 @@ public class SecureChannelProtocol {
fe6b0b
             finalAESKey = keyUnWrap.unwrapSymmetric(wrappedKey, SymmetricKey.AES, 16);
fe6b0b
 
fe6b0b
 
fe6b0b
-            Arrays.fill(wrappedKey,(byte) 0);
fe6b0b
+            JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+            jssSubsystem.obscureBytes(wrappedKey);
fe6b0b
 
fe6b0b
             //byte[] finalKeyBytes = finalAESKey.getKeyData();
fe6b0b
             //displayByteArray(finalKeyBytes, false);
fe6b0b
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
index 1337803..8a0ea08 100644
fe6b0b
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
@@ -2176,6 +2176,26 @@ public class CryptoUtil {
fe6b0b
 
fe6b0b
     }
fe6b0b
 
fe6b0b
+    public static void obscureBytes(byte[] memory, String method) {
fe6b0b
+        if (memory == null || memory.length == 0) {
fe6b0b
+            //in case we want to log
fe6b0b
+            return;
fe6b0b
+        }
fe6b0b
+
fe6b0b
+        SecureRandom rnd;
fe6b0b
+        try {
fe6b0b
+            rnd = getRandomNumberGenerator();
fe6b0b
+        } catch (GeneralSecurityException e) {
fe6b0b
+            throw new RuntimeException(e);
fe6b0b
+        }
fe6b0b
+
fe6b0b
+        if ("zeroes".equals(method)) {
fe6b0b
+            Arrays.fill(memory, (byte)0);
fe6b0b
+        } else {
fe6b0b
+            rnd.nextBytes(memory);
fe6b0b
+        }
fe6b0b
+    }
fe6b0b
+
fe6b0b
     public static byte[] unwrapUsingPassphrase(byte[] wrappedRecoveredKey, String recoveryPassphrase)
fe6b0b
             throws IOException, InvalidBERException, InvalidKeyException, IllegalStateException,
fe6b0b
             NoSuchAlgorithmException, InvalidAlgorithmParameterException, NotInitializedException, TokenException,
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b
fe6b0b
fe6b0b
From 0cbe30064861a9908475aa95a686e69e3012a841 Mon Sep 17 00:00:00 2001
fe6b0b
From: Christian Heimes <cheimes@redhat.com>
fe6b0b
Date: Wed, 8 Nov 2017 20:46:57 +0100
fe6b0b
Subject: Ignore empty key in read_environment_files
fe6b0b
fe6b0b
Don't set empty key or key '_' (last command) in read_environment_files.
fe6b0b
Fixes "ValueError: illegal environment variable name".
fe6b0b
fe6b0b
Change-Id: I22d295ebbf0845bcf8aab3019e1b1f5a3a731e10
fe6b0b
Closes: https://pagure.io/dogtagpki/issue/2850
fe6b0b
Signed-off-by: Christian Heimes <cheimes@redhat.com>
fe6b0b
(cherry picked from commit a105341f777354429dfc9f28c7baf5bddd2d5e1f)
fe6b0b
---
fe6b0b
 base/common/python/pki/util.py | 2 ++
fe6b0b
 1 file changed, 2 insertions(+)
fe6b0b
fe6b0b
diff --git a/base/common/python/pki/util.py b/base/common/python/pki/util.py
fe6b0b
index 5832f55..871c899 100644
fe6b0b
--- a/base/common/python/pki/util.py
fe6b0b
+++ b/base/common/python/pki/util.py
fe6b0b
@@ -272,4 +272,6 @@ def read_environment_files(env_file_list=None):
fe6b0b
 
fe6b0b
     for env_val in env_vals:
fe6b0b
         (key, _, value) = env_val.partition("=")
fe6b0b
+        if not key.strip() or key == u'_':
fe6b0b
+            continue
fe6b0b
         os.environ[key] = value
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b
fe6b0b
fe6b0b
From 45c07d48a8a5f4acda8ce4ca3be5803c2596901e Mon Sep 17 00:00:00 2001
fe6b0b
From: Jack Magne <jmagne@redhat.com>
fe6b0b
Date: Fri, 10 Nov 2017 15:55:36 -0800
fe6b0b
Subject: ReFix for  #2824 TPS new configuration to allow the protocol of the
fe6b0b
 to determine applet loaded.
fe6b0b
fe6b0b
The problem discovered was that in only the external registration case, there was a problem obtaining the protocol
fe6b0b
information for the token being enrolled. This simple fix makes sure the protocol info is obtained correctly for external
fe6b0b
reg and non external reg enrollment cases.
fe6b0b
fe6b0b
Change-Id: Iccd40adbdafd5e94e04cbb8c391bd2706e483a1f
fe6b0b
(cherry picked from commit e48374cd8a744fad5a03f64e8685ec3b3c465553)
fe6b0b
---
fe6b0b
 .../src/org/dogtagpki/server/tps/processor/TPSProcessor.java   | 10 ++++++----
fe6b0b
 1 file changed, 6 insertions(+), 4 deletions(-)
fe6b0b
fe6b0b
diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
fe6b0b
index 57e5d79..a78db64 100644
fe6b0b
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
fe6b0b
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
fe6b0b
@@ -33,8 +33,6 @@ import java.util.List;
fe6b0b
 import java.util.Map;
fe6b0b
 import java.util.Set;
fe6b0b
 
fe6b0b
-import netscape.security.x509.RevocationReason;
fe6b0b
-
fe6b0b
 import org.dogtagpki.server.tps.TPSSession;
fe6b0b
 import org.dogtagpki.server.tps.TPSSubsystem;
fe6b0b
 import org.dogtagpki.server.tps.authentication.AuthUIParameter;
fe6b0b
@@ -104,6 +102,8 @@ import com.netscape.cms.servlet.tks.SecureChannelProtocol;
fe6b0b
 import com.netscape.cmsutil.crypto.CryptoUtil;
fe6b0b
 import com.netscape.symkey.SessionKey;
fe6b0b
 
fe6b0b
+import netscape.security.x509.RevocationReason;
fe6b0b
+
fe6b0b
 public class TPSProcessor {
fe6b0b
 
fe6b0b
     private static Logger signedAuditLogger = SignedAuditLogger.getLogger();
fe6b0b
@@ -558,8 +558,10 @@ public class TPSProcessor {
fe6b0b
             CMS.debug("TPSProcessor.setupSecureChannel: obtained randomData");
fe6b0b
         }
fe6b0b
 
fe6b0b
-        // We already do this when checking for applet upgrade earlier.
fe6b0b
-        //acquireChannelPlatformAndProtocolInfo();
fe6b0b
+        // Do this on behalf of external reg, which needs it
fe6b0b
+        // If already called, the routine will return anyway.
fe6b0b
+
fe6b0b
+        acquireChannelPlatformAndProtocolInfo();
fe6b0b
 
fe6b0b
         TPSBuffer initUpdateResp = initializeUpdate(keyVersion, keyIndex, randomData);
fe6b0b
 
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b
fe6b0b
fe6b0b
From 23ce60193a31c070441f93238565a7250cff981b Mon Sep 17 00:00:00 2001
fe6b0b
From: Jack Magne <jmagne@redhat.com>
fe6b0b
Date: Fri, 10 Nov 2017 10:57:36 -0800
fe6b0b
Subject: Fix #2735 Secure removal of secret data storage (phase 3)
fe6b0b
fe6b0b
Add more secure data removal with respect to passwords.
fe6b0b
Concentrate on the CMC Shared Token area. Done by changing
fe6b0b
String based passwords to char[] based password, which then can be cleaned.
fe6b0b
Cleaned up a couple of minor review suggestions.
fe6b0b
fe6b0b
Change-Id: I898814000353978f403f19f679083474548edc5e
fe6b0b
(cherry picked from commit daff3951340246d97a9877d5dde4782c8c675974)
fe6b0b
---
fe6b0b
 .../certsrv/authentication/ISharedToken.java       |  10 +-
fe6b0b
 .../servlet/test/GeneratePKIArchiveOptions.java    |   9 +-
fe6b0b
 base/kra/src/com/netscape/kra/RecoveryService.java |  30 +-
fe6b0b
 .../com/netscape/kra/SecurityDataProcessor.java    |   8 +-
fe6b0b
 .../netscape/cms/authentication/SharedSecret.java  |  24 +-
fe6b0b
 .../netscape/cms/profile/common/EnrollProfile.java | 349 ++++++++++++---------
fe6b0b
 .../cms/servlet/common/CMCOutputTemplate.java      |  19 +-
fe6b0b
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 266 +++++++++-------
fe6b0b
 .../netscape/cmscore/security/JssSubsystem.java    |   8 +
fe6b0b
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    |  65 +++-
fe6b0b
 10 files changed, 494 insertions(+), 294 deletions(-)
fe6b0b
fe6b0b
diff --git a/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java b/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
fe6b0b
index b33ae7b..761c344 100644
fe6b0b
--- a/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
fe6b0b
+++ b/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
fe6b0b
@@ -16,24 +16,24 @@
fe6b0b
 // All rights reserved.
fe6b0b
 // --- END COPYRIGHT BLOCK ---
fe6b0b
 package com.netscape.certsrv.authentication;
fe6b0b
-import com.netscape.certsrv.base.EBaseException;
fe6b0b
-
fe6b0b
 import java.math.BigInteger;
fe6b0b
 
fe6b0b
 import org.mozilla.jss.pkix.cmc.PKIData;
fe6b0b
 
fe6b0b
+import com.netscape.certsrv.base.EBaseException;
fe6b0b
+
fe6b0b
 /**
fe6b0b
  * Shared Token interface.
fe6b0b
  */
fe6b0b
 public interface ISharedToken {
fe6b0b
 
fe6b0b
     // support for id_cmc_identification
fe6b0b
-    public String getSharedToken(String identification)
fe6b0b
+    public char[] getSharedToken(String identification)
fe6b0b
             throws EBaseException;
fe6b0b
 
fe6b0b
-    public String getSharedToken(PKIData cmcData)
fe6b0b
+    public char[] getSharedToken(PKIData cmcData)
fe6b0b
             throws EBaseException;
fe6b0b
 
fe6b0b
-    public String getSharedToken(BigInteger serialnum)
fe6b0b
+    public char[] getSharedToken(BigInteger serialnum)
fe6b0b
             throws EBaseException;
fe6b0b
 }
fe6b0b
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java b/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java
fe6b0b
index e1a9816..5ccf7a8 100644
fe6b0b
--- a/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java
fe6b0b
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java
fe6b0b
@@ -213,8 +213,15 @@ public class GeneratePKIArchiveOptions {
fe6b0b
                 new OCTET_STRING(ivps.getIV()));
fe6b0b
 
fe6b0b
         if (passphraseMode) {
fe6b0b
+            char[] pwdChars = passphrase.toCharArray();
fe6b0b
+            try {
fe6b0b
             encoded = CryptoUtil.createEncodedPKIArchiveOptions(
fe6b0b
-                    token, transportCert.getPublicKey(), passphrase, params, aid);
fe6b0b
+                    token, transportCert.getPublicKey(), pwdChars, params, aid);
fe6b0b
+            } catch (Exception e) {
fe6b0b
+                throw e;
fe6b0b
+            } finally {
fe6b0b
+                CryptoUtil.obscureChars(pwdChars);
fe6b0b
+            }
fe6b0b
         } else {
fe6b0b
             encoded = CryptoUtil.createEncodedPKIArchiveOptions(
fe6b0b
                     token, transportCert.getPublicKey(), vek, params, aid);
fe6b0b
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
fe6b0b
index d562c15..96ee73b 100644
fe6b0b
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
fe6b0b
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
fe6b0b
@@ -461,6 +461,7 @@ public class RecoveryService implements IService {
fe6b0b
     public void createPFX(IRequest request, Hashtable<String, Object> params,
fe6b0b
             PrivateKey priKey, CryptoToken ct) throws EBaseException {
fe6b0b
         CMS.debug("RecoverService: createPFX() allowEncDecrypt_recovery=false");
fe6b0b
+        org.mozilla.jss.util.Password pass = null;
fe6b0b
         try {
fe6b0b
             // create p12
fe6b0b
             X509Certificate x509cert =
fe6b0b
@@ -493,9 +494,14 @@ public class RecoveryService implements IService {
fe6b0b
             // add key
fe6b0b
             mKRA.log(ILogger.LL_INFO, "KRA adds key to P12");
fe6b0b
             CMS.debug("RecoverService: createPFX() adds key to P12");
fe6b0b
-            org.mozilla.jss.util.Password pass = new
fe6b0b
+            char[] pwdChar = pwd.toCharArray();
fe6b0b
+            pass = new
fe6b0b
                     org.mozilla.jss.util.Password(
fe6b0b
-                            pwd.toCharArray());
fe6b0b
+                            pwdChar);
fe6b0b
+            {
fe6b0b
+                JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+                jssSubsystem.obscureChars(pwdChar);
fe6b0b
+            }
fe6b0b
 
fe6b0b
             SEQUENCE safeContents = new SEQUENCE();
fe6b0b
             PasswordConverter passConverter = new
fe6b0b
@@ -580,7 +586,6 @@ public class RecoveryService implements IService {
fe6b0b
                     ByteArrayOutputStream();
fe6b0b
 
fe6b0b
             pfx.encode(fos);
fe6b0b
-            pass.clear();
fe6b0b
 
fe6b0b
             // put final PKCS12 into volatile request
fe6b0b
             params.put(ATTR_PKCS12, fos.toByteArray());
fe6b0b
@@ -590,6 +595,10 @@ public class RecoveryService implements IService {
fe6b0b
             CMS.debug("RecoverService: createPFX() exception caught:"+
fe6b0b
                 e.toString());
fe6b0b
             throw new EKRAException(CMS.getUserMessage("CMS_KRA_PKCS12_FAILED_1", e.toString()));
fe6b0b
+        } finally {
fe6b0b
+            if(pass != null) {
fe6b0b
+                pass.clear();
fe6b0b
+            }
fe6b0b
         }
fe6b0b
 
fe6b0b
         // update request
fe6b0b
@@ -637,6 +646,7 @@ public class RecoveryService implements IService {
fe6b0b
     public void createPFX(IRequest request, Hashtable<String, Object> params,
fe6b0b
             byte priData[]) throws EBaseException {
fe6b0b
         CMS.debug("RecoverService: createPFX() allowEncDecrypt_recovery=true");
fe6b0b
+        org.mozilla.jss.util.Password pass = null;
fe6b0b
         try {
fe6b0b
             // create p12
fe6b0b
             X509Certificate x509cert =
fe6b0b
@@ -667,9 +677,13 @@ public class RecoveryService implements IService {
fe6b0b
 
fe6b0b
             // add key
fe6b0b
             mKRA.log(ILogger.LL_INFO, "KRA adds key to P12");
fe6b0b
-            org.mozilla.jss.util.Password pass = new
fe6b0b
-                    org.mozilla.jss.util.Password(
fe6b0b
-                            pwd.toCharArray());
fe6b0b
+            char[] pwdChars = pwd.toCharArray();
fe6b0b
+            pass = new org.mozilla.jss.util.Password(
fe6b0b
+                    pwdChars);
fe6b0b
+
fe6b0b
+            JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+            jssSubsystem.obscureChars(pwdChars);
fe6b0b
+
fe6b0b
 
fe6b0b
             SEQUENCE safeContents = new SEQUENCE();
fe6b0b
             PrivateKeyInfo pki = (PrivateKeyInfo)
fe6b0b
@@ -735,13 +749,15 @@ public class RecoveryService implements IService {
fe6b0b
                     ByteArrayOutputStream();
fe6b0b
 
fe6b0b
             pfx.encode(fos);
fe6b0b
-            pass.clear();
fe6b0b
 
fe6b0b
             // put final PKCS12 into volatile request
fe6b0b
             params.put(ATTR_PKCS12, fos.toByteArray());
fe6b0b
         } catch (Exception e) {
fe6b0b
             mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_CONSTRUCT_P12", e.toString()));
fe6b0b
             throw new EKRAException(CMS.getUserMessage("CMS_KRA_PKCS12_FAILED_1", e.toString()));
fe6b0b
+        } finally {
fe6b0b
+            if(pass != null)
fe6b0b
+                pass.clear();
fe6b0b
         }
fe6b0b
 
fe6b0b
         // update request
fe6b0b
diff --git a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
fe6b0b
index 71d1233..8de1311 100644
fe6b0b
--- a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
fe6b0b
+++ b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
fe6b0b
@@ -487,9 +487,11 @@ public class SecurityDataProcessor {
fe6b0b
                         unwrappedSess,
fe6b0b
                         wrapParams.getPayloadEncryptionAlgorithm());
fe6b0b
 
fe6b0b
-                String passStr = new String(unwrappedPass, "UTF-8");
fe6b0b
-                pass = new Password(passStr.toCharArray());
fe6b0b
-                passStr = null;
fe6b0b
+                char[] passChars = CryptoUtil.bytesToChars(unwrappedPass);
fe6b0b
+                pass = new Password(passChars);
fe6b0b
+                JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
fe6b0b
+                jssSubsystem.obscureChars(passChars);
fe6b0b
+
fe6b0b
 
fe6b0b
                 if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
fe6b0b
 
fe6b0b
diff --git a/base/server/cms/src/com/netscape/cms/authentication/SharedSecret.java b/base/server/cms/src/com/netscape/cms/authentication/SharedSecret.java
fe6b0b
index cf69975..ee7a7d7 100644
fe6b0b
--- a/base/server/cms/src/com/netscape/cms/authentication/SharedSecret.java
fe6b0b
+++ b/base/server/cms/src/com/netscape/cms/authentication/SharedSecret.java
fe6b0b
@@ -240,7 +240,7 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
      * Note: caller should clear the memory for the returned token
fe6b0b
      *       after each use
fe6b0b
      */
fe6b0b
-    public String getSharedToken(String identification)
fe6b0b
+    public char[] getSharedToken(String identification)
fe6b0b
             throws EBaseException {
fe6b0b
         String method = "SharedSecret.getSharedToken(String identification): ";
fe6b0b
         String msg = "";
fe6b0b
@@ -319,7 +319,7 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
             }
fe6b0b
             CMS.debug(method + " got entryShrTok");
fe6b0b
 
fe6b0b
-            String shrSecret = decryptShrTokData(new String(entryShrTok));
fe6b0b
+            char[] shrSecret = decryptShrTokData(new String(entryShrTok));
fe6b0b
             CMS.debug(method + "returning");
fe6b0b
             return shrSecret;
fe6b0b
         } catch (Exception e) {
fe6b0b
@@ -338,11 +338,11 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
      *     encryptedPrivate OCTET STRING
fe6b0b
      * }
fe6b0b
      * @param data_s
fe6b0b
-     * @return
fe6b0b
+     * @return phrase in char array.
fe6b0b
      */
fe6b0b
-    private String decryptShrTokData(String data_s) {
fe6b0b
+    private char[] decryptShrTokData(String data_s) {
fe6b0b
         String method = "SharedSecret.decryptShrTokData: ";
fe6b0b
-        String msg = "";
fe6b0b
+        byte[] ver_passphrase = null;
fe6b0b
         try {
fe6b0b
             byte[] wrapped_secret_data = Utils.base64decode(data_s);
fe6b0b
             DerValue wrapped_val = new DerValue(wrapped_secret_data);
fe6b0b
@@ -357,22 +357,24 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
 
fe6b0b
             SymmetricKey ver_session = CryptoUtil.unwrap(tmpToken, SymmetricKey.AES, 128, SymmetricKey.Usage.UNWRAP,
fe6b0b
                     issuanceProtPrivKey, wrapped_session, wrapAlgorithm);
fe6b0b
-            byte[] ver_passphrase = CryptoUtil.decryptUsingSymmetricKey(tmpToken, new IVParameterSpec(iv),
fe6b0b
+            ver_passphrase = CryptoUtil.decryptUsingSymmetricKey(tmpToken, new IVParameterSpec(iv),
fe6b0b
                     wrapped_passphrase,
fe6b0b
                     ver_session, EncryptionAlgorithm.AES_128_CBC_PAD);
fe6b0b
 
fe6b0b
-            String ver_spassphrase = new String(ver_passphrase, "UTF-8");
fe6b0b
-            return ver_spassphrase;
fe6b0b
+            char[] ver_spassphraseChars = CryptoUtil.bytesToChars(ver_passphrase);
fe6b0b
+            return ver_spassphraseChars;
fe6b0b
         } catch (Exception e) {
fe6b0b
             CMS.debug(method + e.toString());
fe6b0b
             return null;
fe6b0b
+        } finally {
fe6b0b
+            CryptoUtil.obscureBytes(ver_passphrase, "random");
fe6b0b
         }
fe6b0b
     }
fe6b0b
 
fe6b0b
     /**
fe6b0b
      * unsupported
fe6b0b
      */
fe6b0b
-    public String getSharedToken(PKIData cmcdata)
fe6b0b
+    public char[] getSharedToken(PKIData cmcdata)
fe6b0b
             throws EBaseException {
fe6b0b
         String method = "SharedSecret.getSharedToken(PKIData cmcdata): ";
fe6b0b
         String msg = "";
fe6b0b
@@ -389,7 +391,7 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
      * Note: caller should clear the memory for the returned token
fe6b0b
      *       after each use
fe6b0b
      */
fe6b0b
-    public String getSharedToken(BigInteger serial)
fe6b0b
+    public char[] getSharedToken(BigInteger serial)
fe6b0b
             throws EBaseException {
fe6b0b
         String method = "SharedSecret.getSharedToken(BigInteger serial): ";
fe6b0b
         String msg = "";
fe6b0b
@@ -417,7 +419,7 @@ public class SharedSecret extends DirBasedAuthentication
fe6b0b
             throw new EBaseException(method + msg);
fe6b0b
         }
fe6b0b
 
fe6b0b
-        String shrSecret = decryptShrTokData(shrTok_s);
fe6b0b
+        char[] shrSecret = decryptShrTokData(shrTok_s);
fe6b0b
         CMS.debug(method + "returning");
fe6b0b
         return shrSecret;
fe6b0b
     }
fe6b0b
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
fe6b0b
index 5f34ec9..9051baf 100644
fe6b0b
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
fe6b0b
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
fe6b0b
@@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream;
fe6b0b
 import java.io.ByteArrayOutputStream;
fe6b0b
 import java.io.IOException;
fe6b0b
 import java.math.BigInteger;
fe6b0b
+import java.nio.ByteBuffer;
fe6b0b
 import java.security.InvalidKeyException;
fe6b0b
 import java.security.MessageDigest;
fe6b0b
 import java.security.NoSuchAlgorithmException;
fe6b0b
@@ -1300,7 +1301,7 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
     protected boolean verifyPopLinkWitnessV2(
fe6b0b
             PopLinkWitnessV2 popLinkWitnessV2,
fe6b0b
             byte[] randomSeed,
fe6b0b
-            String sharedSecret,
fe6b0b
+            byte[] sharedSecret,
fe6b0b
             String ident_string) {
fe6b0b
         String method = "EnrollProfile: verifyPopLinkWitnessV2: ";
fe6b0b
 
fe6b0b
@@ -1326,6 +1327,7 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
             return false;
fe6b0b
         }
fe6b0b
 
fe6b0b
+        byte[] verifyBytes = null;
fe6b0b
         try {
fe6b0b
             DigestAlgorithm keyGenAlgID = DigestAlgorithm.fromOID(keyGenAlg.getOID());
fe6b0b
             MessageDigest keyGenMDAlg = MessageDigest.getInstance(keyGenAlgID.toString());
fe6b0b
@@ -1335,17 +1337,41 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
                     .getInstance(CryptoUtil.getHMACtoMessageDigestName(macAlgID.toString()));
fe6b0b
 
fe6b0b
             byte[] witness_bytes = witness.toByteArray();
fe6b0b
-            return verifyDigest(
fe6b0b
-                    (ident_string != null) ? (sharedSecret + ident_string).getBytes() : sharedSecret.getBytes(),
fe6b0b
+
fe6b0b
+            ByteBuffer bb = null;
fe6b0b
+
fe6b0b
+            if(ident_string != null) {
fe6b0b
+                bb = ByteBuffer.allocate(ident_string.getBytes().length + sharedSecret.length);
fe6b0b
+                bb.put(sharedSecret);
fe6b0b
+                bb.put(ident_string.getBytes());
fe6b0b
+                verifyBytes = bb.array();
fe6b0b
+            } else {
fe6b0b
+                verifyBytes = sharedSecret;
fe6b0b
+            }
fe6b0b
+
fe6b0b
+            boolean result = verifyDigest(
fe6b0b
+                    verifyBytes,
fe6b0b
                     randomSeed,
fe6b0b
                     witness_bytes,
fe6b0b
                     keyGenMDAlg, macMDAlg);
fe6b0b
+
fe6b0b
+            //Check ident_string because, verifyBytes will be = sharedSecret otherwise.
fe6b0b
+            //Let caller clear sharedSecret when the time comes.
fe6b0b
+            if (ident_string != null) {
fe6b0b
+                CryptoUtil.obscureBytes(verifyBytes, "random");
fe6b0b
+            }
fe6b0b
+
fe6b0b
+            return result;
fe6b0b
         } catch (NoSuchAlgorithmException e) {
fe6b0b
             CMS.debug(method + e);
fe6b0b
             return false;
fe6b0b
         } catch (Exception e) {
fe6b0b
             CMS.debug(method + e);
fe6b0b
             return false;
fe6b0b
+        } finally {
fe6b0b
+            if (ident_string != null) {
fe6b0b
+                CryptoUtil.obscureBytes(verifyBytes, "random");
fe6b0b
+            }
fe6b0b
         }
fe6b0b
     }
fe6b0b
 
fe6b0b
@@ -1365,162 +1391,175 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
 
fe6b0b
         boolean sharedSecretFound = true;
fe6b0b
         String configName = "SharedToken";
fe6b0b
-        String sharedSecret = null;
fe6b0b
+        char[] sharedSecret = null;
fe6b0b
+        byte[] sharedSecretBytes = null;
fe6b0b
+
fe6b0b
         try {
fe6b0b
-            IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
fe6b0b
 
fe6b0b
-            IAuthManager sharedTokenAuth = authSS.getAuthManager(configName);
fe6b0b
-            if (sharedTokenAuth == null) {
fe6b0b
-                CMS.debug(method + " Failed to retrieve shared secret authentication plugin class");
fe6b0b
-                sharedSecretFound = false;
fe6b0b
-            }
fe6b0b
-            ISharedToken tokenClass = (ISharedToken) sharedTokenAuth;
fe6b0b
+            try {
fe6b0b
+                IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
fe6b0b
 
fe6b0b
-            if (ident_string != null) {
fe6b0b
-                sharedSecret = tokenClass.getSharedToken(ident_string);
fe6b0b
-            } else {
fe6b0b
-                sharedSecret = tokenClass.getSharedToken(mCMCData);
fe6b0b
-            }
fe6b0b
-            if (sharedSecret == null)
fe6b0b
-                sharedSecretFound = false;
fe6b0b
+                IAuthManager sharedTokenAuth = authSS.getAuthManager(configName);
fe6b0b
+                if (sharedTokenAuth == null) {
fe6b0b
+                    CMS.debug(method + " Failed to retrieve shared secret authentication plugin class");
fe6b0b
+                    sharedSecretFound = false;
fe6b0b
+                }
fe6b0b
+                ISharedToken tokenClass = (ISharedToken) sharedTokenAuth;
fe6b0b
 
fe6b0b
-        } catch (Exception e) {
fe6b0b
-            CMS.debug(e);
fe6b0b
-            return false;
fe6b0b
-        }
fe6b0b
+                if (ident_string != null) {
fe6b0b
+                    sharedSecret = tokenClass.getSharedToken(ident_string);
fe6b0b
+                } else {
fe6b0b
+                    sharedSecret = tokenClass.getSharedToken(mCMCData);
fe6b0b
+                }
fe6b0b
+                if (sharedSecret == null) {
fe6b0b
+                    sharedSecretFound = false;
fe6b0b
+                } else {
fe6b0b
+                    sharedSecretBytes = CryptoUtil.charsToBytes(sharedSecret);
fe6b0b
+                }
fe6b0b
 
fe6b0b
-        INTEGER reqId = null;
fe6b0b
-        byte[] bv = null;
fe6b0b
+            } catch (Exception e) {
fe6b0b
+                CMS.debug(e);
fe6b0b
+                return false;
fe6b0b
+            }
fe6b0b
 
fe6b0b
-        if (req.getType().equals(TaggedRequest.PKCS10)) {
fe6b0b
-            String methodPos = method + "PKCS10: ";
fe6b0b
-            CMS.debug(methodPos + "begins");
fe6b0b
+            INTEGER reqId = null;
fe6b0b
+            byte[] bv = null;
fe6b0b
 
fe6b0b
-            TaggedCertificationRequest tcr = req.getTcr();
fe6b0b
-            if (!sharedSecretFound) {
fe6b0b
-                bpids.addElement(tcr.getBodyPartID());
fe6b0b
-                context.put("POPLinkWitness", bpids);
fe6b0b
-                return false;
fe6b0b
-            } else {
fe6b0b
-                CertificationRequest creq = tcr.getCertificationRequest();
fe6b0b
-                CertificationRequestInfo cinfo = creq.getInfo();
fe6b0b
-                SET attrs = cinfo.getAttributes();
fe6b0b
-                for (int j = 0; j < attrs.size(); j++) {
fe6b0b
-                    Attribute pkcs10Attr = (Attribute) attrs.elementAt(j);
fe6b0b
-                    if (pkcs10Attr.getType().equals(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2)) {
fe6b0b
-                        CMS.debug(methodPos + "found id_cmc_popLinkWitnessV2");
fe6b0b
-                        if (ident_string == null) {
fe6b0b
-                            bpids.addElement(reqId);
fe6b0b
-                            context.put("identification", bpids);
fe6b0b
-                            context.put("POPLinkWitnessV2", bpids);
fe6b0b
-                            String msg = "id_cmc_popLinkWitnessV2 must be accompanied by id_cmc_identification in this server";
fe6b0b
-                            CMS.debug(methodPos + msg);
fe6b0b
-                            return false;
fe6b0b
-                        }
fe6b0b
+            if (req.getType().equals(TaggedRequest.PKCS10)) {
fe6b0b
+                String methodPos = method + "PKCS10: ";
fe6b0b
+                CMS.debug(methodPos + "begins");
fe6b0b
 
fe6b0b
-                        SET witnessVal = pkcs10Attr.getValues();
fe6b0b
-                        if (witnessVal.size() > 0) {
fe6b0b
-                            try {
fe6b0b
-                                PopLinkWitnessV2 popLinkWitnessV2 = getPopLinkWitnessV2control(witnessVal.elementAt(0));
fe6b0b
-                                boolean valid = verifyPopLinkWitnessV2(popLinkWitnessV2,
fe6b0b
-                                        randomSeed,
fe6b0b
-                                        sharedSecret,
fe6b0b
-                                        ident_string);
fe6b0b
-                                if (!valid) {
fe6b0b
-                                    bpids.addElement(reqId);
fe6b0b
-                                    context.put("POPLinkWitnessV2", bpids);
fe6b0b
-                                    return valid;
fe6b0b
-                                }
fe6b0b
-                                return true;
fe6b0b
-                            } catch (Exception ex) {
fe6b0b
-                                CMS.debug(methodPos + ex);
fe6b0b
+                TaggedCertificationRequest tcr = req.getTcr();
fe6b0b
+                if (!sharedSecretFound) {
fe6b0b
+                    bpids.addElement(tcr.getBodyPartID());
fe6b0b
+                    context.put("POPLinkWitness", bpids);
fe6b0b
+                    return false;
fe6b0b
+                } else {
fe6b0b
+                    CertificationRequest creq = tcr.getCertificationRequest();
fe6b0b
+                    CertificationRequestInfo cinfo = creq.getInfo();
fe6b0b
+                    SET attrs = cinfo.getAttributes();
fe6b0b
+                    for (int j = 0; j < attrs.size(); j++) {
fe6b0b
+                        Attribute pkcs10Attr = (Attribute) attrs.elementAt(j);
fe6b0b
+                        if (pkcs10Attr.getType().equals(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2)) {
fe6b0b
+                            CMS.debug(methodPos + "found id_cmc_popLinkWitnessV2");
fe6b0b
+                            if (ident_string == null) {
fe6b0b
+                                bpids.addElement(reqId);
fe6b0b
+                                context.put("identification", bpids);
fe6b0b
+                                context.put("POPLinkWitnessV2", bpids);
fe6b0b
+                                String msg = "id_cmc_popLinkWitnessV2 must be accompanied by id_cmc_identification in this server";
fe6b0b
+                                CMS.debug(methodPos + msg);
fe6b0b
                                 return false;
fe6b0b
                             }
fe6b0b
-                        }
fe6b0b
-                    } else if (pkcs10Attr.getType().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
fe6b0b
-                        SET witnessVal = pkcs10Attr.getValues();
fe6b0b
-                        if (witnessVal.size() > 0) {
fe6b0b
-                            try {
fe6b0b
-                                OCTET_STRING str = (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
fe6b0b
-                                        ASN1Util.encode(witnessVal.elementAt(0))));
fe6b0b
-                                bv = str.toByteArray();
fe6b0b
-                                return verifyDigest(sharedSecret.getBytes(),
fe6b0b
-                                        randomSeed, bv);
fe6b0b
-                            } catch (InvalidBERException ex) {
fe6b0b
-                                return false;
fe6b0b
+
fe6b0b
+                            SET witnessVal = pkcs10Attr.getValues();
fe6b0b
+                            if (witnessVal.size() > 0) {
fe6b0b
+                                try {
fe6b0b
+                                    PopLinkWitnessV2 popLinkWitnessV2 = getPopLinkWitnessV2control(
fe6b0b
+                                            witnessVal.elementAt(0));
fe6b0b
+                                    boolean valid = verifyPopLinkWitnessV2(popLinkWitnessV2,
fe6b0b
+                                            randomSeed,
fe6b0b
+                                            sharedSecretBytes,
fe6b0b
+                                            ident_string);
fe6b0b
+                                    if (!valid) {
fe6b0b
+                                        bpids.addElement(reqId);
fe6b0b
+                                        context.put("POPLinkWitnessV2", bpids);
fe6b0b
+                                        return valid;
fe6b0b
+                                    }
fe6b0b
+                                    return true;
fe6b0b
+                                } catch (Exception ex) {
fe6b0b
+                                    CMS.debug(methodPos + ex);
fe6b0b
+                                    return false;
fe6b0b
+                                }
fe6b0b
+                            }
fe6b0b
+                        } else if (pkcs10Attr.getType().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
fe6b0b
+                            SET witnessVal = pkcs10Attr.getValues();
fe6b0b
+                            if (witnessVal.size() > 0) {
fe6b0b
+                                try {
fe6b0b
+                                    OCTET_STRING str = (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
fe6b0b
+                                            ASN1Util.encode(witnessVal.elementAt(0))));
fe6b0b
+                                    bv = str.toByteArray();
fe6b0b
+                                    return verifyDigest(sharedSecretBytes,
fe6b0b
+                                            randomSeed, bv);
fe6b0b
+                                } catch (InvalidBERException ex) {
fe6b0b
+                                    return false;
fe6b0b
+                                }
fe6b0b
                             }
fe6b0b
                         }
fe6b0b
                     }
fe6b0b
-                }
fe6b0b
-
fe6b0b
-                return false;
fe6b0b
-            }
fe6b0b
-        } else if (req.getType().equals(TaggedRequest.CRMF)) {
fe6b0b
-            String methodPos = method + "CRMF: ";
fe6b0b
-            CMS.debug(methodPos + "begins");
fe6b0b
-
fe6b0b
-            CertReqMsg crm = req.getCrm();
fe6b0b
-            CertRequest certReq = crm.getCertReq();
fe6b0b
-            reqId = certReq.getCertReqId();
fe6b0b
-            if (!sharedSecretFound) {
fe6b0b
-                bpids.addElement(reqId);
fe6b0b
-                context.put("POPLinkWitness", bpids);
fe6b0b
-                return false;
fe6b0b
-            } else {
fe6b0b
-                for (int i = 0; i < certReq.numControls(); i++) {
fe6b0b
-                    AVA ava = certReq.controlAt(i);
fe6b0b
 
fe6b0b
-                    if (ava.getOID().equals(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2)) {
fe6b0b
-                        CMS.debug(methodPos + "found id_cmc_popLinkWitnessV2");
fe6b0b
-                        if (ident_string == null) {
fe6b0b
-                            bpids.addElement(reqId);
fe6b0b
-                            context.put("identification", bpids);
fe6b0b
-                            context.put("POPLinkWitnessV2", bpids);
fe6b0b
-                            String msg = "id_cmc_popLinkWitnessV2 must be accompanied by id_cmc_identification in this server";
fe6b0b
-                            CMS.debug(methodPos + msg);
fe6b0b
-                            return false;
fe6b0b
-                        }
fe6b0b
+                    return false;
fe6b0b
+                }
fe6b0b
+            } else if (req.getType().equals(TaggedRequest.CRMF)) {
fe6b0b
+                String methodPos = method + "CRMF: ";
fe6b0b
+                CMS.debug(methodPos + "begins");
fe6b0b
 
fe6b0b
-                        ASN1Value value = ava.getValue();
fe6b0b
-                        PopLinkWitnessV2 popLinkWitnessV2 = getPopLinkWitnessV2control(value);
fe6b0b
+                CertReqMsg crm = req.getCrm();
fe6b0b
+                CertRequest certReq = crm.getCertReq();
fe6b0b
+                reqId = certReq.getCertReqId();
fe6b0b
+                if (!sharedSecretFound) {
fe6b0b
+                    bpids.addElement(reqId);
fe6b0b
+                    context.put("POPLinkWitness", bpids);
fe6b0b
+                    return false;
fe6b0b
+                } else {
fe6b0b
+                    for (int i = 0; i < certReq.numControls(); i++) {
fe6b0b
+                        AVA ava = certReq.controlAt(i);
fe6b0b
+
fe6b0b
+                        if (ava.getOID().equals(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2)) {
fe6b0b
+                            CMS.debug(methodPos + "found id_cmc_popLinkWitnessV2");
fe6b0b
+                            if (ident_string == null) {
fe6b0b
+                                bpids.addElement(reqId);
fe6b0b
+                                context.put("identification", bpids);
fe6b0b
+                                context.put("POPLinkWitnessV2", bpids);
fe6b0b
+                                String msg = "id_cmc_popLinkWitnessV2 must be accompanied by id_cmc_identification in this server";
fe6b0b
+                                CMS.debug(methodPos + msg);
fe6b0b
+                                return false;
fe6b0b
+                            }
fe6b0b
 
fe6b0b
-                        boolean valid = verifyPopLinkWitnessV2(popLinkWitnessV2,
fe6b0b
-                                randomSeed,
fe6b0b
-                                sharedSecret,
fe6b0b
-                                ident_string);
fe6b0b
-                        if (!valid) {
fe6b0b
-                            bpids.addElement(reqId);
fe6b0b
-                            context.put("POPLinkWitnessV2", bpids);
fe6b0b
-                            return valid;
fe6b0b
-                        }
fe6b0b
-                    } else if (ava.getOID().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
fe6b0b
-                        CMS.debug(methodPos + "found id_cmc_idPOPLinkWitness");
fe6b0b
-                        ASN1Value value = ava.getValue();
fe6b0b
-                        ByteArrayInputStream bis = new ByteArrayInputStream(
fe6b0b
-                                ASN1Util.encode(value));
fe6b0b
-                        OCTET_STRING ostr = null;
fe6b0b
-                        try {
fe6b0b
-                            ostr = (OCTET_STRING) (new OCTET_STRING.Template()).decode(bis);
fe6b0b
-                            bv = ostr.toByteArray();
fe6b0b
-                        } catch (Exception e) {
fe6b0b
-                            bpids.addElement(reqId);
fe6b0b
-                            context.put("POPLinkWitness", bpids);
fe6b0b
-                            return false;
fe6b0b
-                        }
fe6b0b
+                            ASN1Value value = ava.getValue();
fe6b0b
+                            PopLinkWitnessV2 popLinkWitnessV2 = getPopLinkWitnessV2control(value);
fe6b0b
+
fe6b0b
+                            boolean valid = verifyPopLinkWitnessV2(popLinkWitnessV2,
fe6b0b
+                                    randomSeed,
fe6b0b
+                                    sharedSecretBytes,
fe6b0b
+                                    ident_string);
fe6b0b
+                            if (!valid) {
fe6b0b
+                                bpids.addElement(reqId);
fe6b0b
+                                context.put("POPLinkWitnessV2", bpids);
fe6b0b
+                                return valid;
fe6b0b
+                            }
fe6b0b
+                        } else if (ava.getOID().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
fe6b0b
+                            CMS.debug(methodPos + "found id_cmc_idPOPLinkWitness");
fe6b0b
+                            ASN1Value value = ava.getValue();
fe6b0b
+                            ByteArrayInputStream bis = new ByteArrayInputStream(
fe6b0b
+                                    ASN1Util.encode(value));
fe6b0b
+                            OCTET_STRING ostr = null;
fe6b0b
+                            try {
fe6b0b
+                                ostr = (OCTET_STRING) (new OCTET_STRING.Template()).decode(bis);
fe6b0b
+                                bv = ostr.toByteArray();
fe6b0b
+                            } catch (Exception e) {
fe6b0b
+                                bpids.addElement(reqId);
fe6b0b
+                                context.put("POPLinkWitness", bpids);
fe6b0b
+                                return false;
fe6b0b
+                            }
fe6b0b
 
fe6b0b
-                        boolean valid = verifyDigest(sharedSecret.getBytes(),
fe6b0b
-                                randomSeed, bv);
fe6b0b
-                        if (!valid) {
fe6b0b
-                            bpids.addElement(reqId);
fe6b0b
-                            context.put("POPLinkWitness", bpids);
fe6b0b
-                            return valid;
fe6b0b
+                            boolean valid = verifyDigest(sharedSecretBytes,
fe6b0b
+                                    randomSeed, bv);
fe6b0b
+                            if (!valid) {
fe6b0b
+                                bpids.addElement(reqId);
fe6b0b
+                                context.put("POPLinkWitness", bpids);
fe6b0b
+                                return valid;
fe6b0b
+                            }
fe6b0b
                         }
fe6b0b
                     }
fe6b0b
                 }
fe6b0b
             }
fe6b0b
-        }
fe6b0b
 
fe6b0b
-        return true;
fe6b0b
+            return true;
fe6b0b
+
fe6b0b
+        } finally {
fe6b0b
+            CryptoUtil.obscureBytes(sharedSecretBytes, "random");
fe6b0b
+            CryptoUtil.obscureChars(sharedSecret);
fe6b0b
+        }
fe6b0b
     }
fe6b0b
 
fe6b0b
     private boolean verifyDigest(byte[] sharedSecret, byte[] text, byte[] bv) {
fe6b0b
@@ -1664,7 +1703,7 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
             }
fe6b0b
             ISharedToken tokenClass = (ISharedToken) sharedTokenAuth;
fe6b0b
 
fe6b0b
-            String token = null;
fe6b0b
+            char[] token = null;
fe6b0b
             if (ident_string != null) {
fe6b0b
                 auditAttemptedCred = ident_string;
fe6b0b
                 token = tokenClass.getSharedToken(ident_string);
fe6b0b
@@ -1702,14 +1741,36 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
 
fe6b0b
             byte[] witness_bytes = witness.toByteArray();
fe6b0b
             byte[] request_bytes = ASN1Util.encode(reqSeq); // PKIData reqSequence field
fe6b0b
+
fe6b0b
+            byte[] verifyBytes = null;
fe6b0b
+            ByteBuffer bb = null;
fe6b0b
+
fe6b0b
+            byte[] tokenBytes = CryptoUtil.charsToBytes(token);
fe6b0b
+
fe6b0b
+            if(ident_string != null) {
fe6b0b
+                bb = ByteBuffer.allocate(ident_string.getBytes().length + token.length);
fe6b0b
+                bb.put(tokenBytes);
fe6b0b
+                bb.put(ident_string.getBytes());
fe6b0b
+                verifyBytes = bb.array();
fe6b0b
+            } else {
fe6b0b
+                verifyBytes = tokenBytes;
fe6b0b
+            }
fe6b0b
+
fe6b0b
+
fe6b0b
             verified = verifyDigest(
fe6b0b
-                    (ident_string != null) ? (token + ident_string).getBytes() : token.getBytes(),
fe6b0b
+                    verifyBytes,
fe6b0b
                     request_bytes,
fe6b0b
                     witness_bytes,
fe6b0b
                     hashAlg, macAlg);
fe6b0b
 
fe6b0b
             String auditSubjectID = null;
fe6b0b
 
fe6b0b
+            if(ident_string != null) {
fe6b0b
+                CryptoUtil.obscureBytes(verifyBytes, "random");
fe6b0b
+            }
fe6b0b
+
fe6b0b
+            CryptoUtil.obscureChars(token);
fe6b0b
+
fe6b0b
             if (verified) {
fe6b0b
                 auditSubjectID = (String) sessionContext.get(SessionContext.USER_ID);
fe6b0b
                 CMS.debug(method + "current auditSubjectID was:" + auditSubjectID);
fe6b0b
@@ -1760,13 +1821,14 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
         }
fe6b0b
 
fe6b0b
         OCTET_STRING ostr = null;
fe6b0b
-        String token = null;
fe6b0b
+        char[] token = null;
fe6b0b
         try {
fe6b0b
             token = tokenClass.getSharedToken(mCMCData);
fe6b0b
             ostr = (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
fe6b0b
                     ASN1Util.encode(vals.elementAt(0))));
fe6b0b
         } catch (InvalidBERException e) {
fe6b0b
             CMS.debug(method + "Failed to decode the byte value.");
fe6b0b
+            CryptoUtil.obscureChars(token);
fe6b0b
             return false;
fe6b0b
         } catch (Exception e) {
fe6b0b
             CMS.debug(method + "exception: " + e.toString());
fe6b0b
@@ -1775,10 +1837,15 @@ public abstract class EnrollProfile extends BasicProfile
fe6b0b
         byte[] b = ostr.toByteArray();
fe6b0b
         byte[] text = ASN1Util.encode(reqSeq);
fe6b0b
 
fe6b0b
-        verified = verifyDigest(token.getBytes(), text, b);
fe6b0b
+        byte[] verifyBytes = CryptoUtil.charsToBytes(token);
fe6b0b
+        verified = verifyDigest(verifyBytes, text, b);
fe6b0b
         if (verified) {// update auditSubjectID
fe6b0b
             //placeholder. Should probably just disable this v1 method
fe6b0b
         }
fe6b0b
+
fe6b0b
+        CryptoUtil.obscureBytes(verifyBytes, "random");
fe6b0b
+        CryptoUtil.obscureChars(token);
fe6b0b
+
fe6b0b
         return verified;
fe6b0b
     }
fe6b0b
 
fe6b0b
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
fe6b0b
index 1d70b36..6c40d2d 100644
fe6b0b
--- a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
fe6b0b
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
fe6b0b
@@ -68,6 +68,7 @@ import org.mozilla.jss.pkix.cms.SignerIdentifier;
fe6b0b
 import org.mozilla.jss.pkix.cms.SignerInfo;
fe6b0b
 import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
fe6b0b
 import org.mozilla.jss.pkix.primitive.Name;
fe6b0b
+import org.mozilla.jss.util.Password;
fe6b0b
 
fe6b0b
 import com.netscape.certsrv.apps.CMS;
fe6b0b
 import com.netscape.certsrv.authentication.IAuthManager;
fe6b0b
@@ -1093,7 +1094,7 @@ public class CMCOutputTemplate {
fe6b0b
                     }
fe6b0b
                     ISharedToken tokenClass = (ISharedToken) sharedTokenAuth;
fe6b0b
 
fe6b0b
-                    String sharedSecret = tokenClass.getSharedToken(revokeSerial);
fe6b0b
+                    char[] sharedSecret = tokenClass.getSharedToken(revokeSerial);
fe6b0b
 
fe6b0b
                     if (sharedSecret == null) {
fe6b0b
                         CMS.debug("CMCOutputTemplate: shared secret not found.");
fe6b0b
@@ -1110,11 +1111,21 @@ public class CMCOutputTemplate {
fe6b0b
                     }
fe6b0b
 
fe6b0b
                     byte[] reqSecretb = reqSecret.toByteArray();
fe6b0b
-                    String clientSC = new String(reqSecretb);
fe6b0b
-                    if (clientSC.equals(sharedSecret)) {
fe6b0b
+                    char[] reqSecretbChars = CryptoUtil.bytesToChars(reqSecretb);
fe6b0b
+
fe6b0b
+                    Password secret1 = new Password(sharedSecret);
fe6b0b
+                    Password secret2 = new Password(reqSecretbChars);
fe6b0b
+
fe6b0b
+                    CryptoUtil.obscureChars(sharedSecret);
fe6b0b
+                    CryptoUtil.obscureChars(reqSecretbChars);
fe6b0b
+                    CryptoUtil.obscureBytes(reqSecretb, "random");
fe6b0b
+
fe6b0b
+                    if(secret1.equals(secret2)) {
fe6b0b
                         CMS.debug(method
fe6b0b
                                 + " Client and server shared secret are the same, can go ahead and revoke certificate.");
fe6b0b
                         revoke = true;
fe6b0b
+                        secret1.clear();
fe6b0b
+                        secret2.clear();
fe6b0b
                     } else {
fe6b0b
                         CMS.debug(method
fe6b0b
                                 + " Client and server shared secret are not the same, cannot revoke certificate.");
fe6b0b
@@ -1137,6 +1148,8 @@ public class CMCOutputTemplate {
fe6b0b
                                 auditReasonNum,
fe6b0b
                                 auditApprovalStatus));
fe6b0b
 
fe6b0b
+                        secret1.clear();
fe6b0b
+                        secret2.clear();
fe6b0b
                         return bpid;
fe6b0b
                     }
fe6b0b
                 }
fe6b0b
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
fe6b0b
index 0018841..1d37d73 100644
fe6b0b
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
fe6b0b
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
fe6b0b
@@ -217,18 +217,28 @@ public class ConfigurationUtils {
fe6b0b
         Password password = null;
fe6b0b
         password = new Password(tokPwd.toCharArray());
fe6b0b
 
fe6b0b
-        if (token.passwordIsInitialized()) {
fe6b0b
-            CMS.debug("loginToken():token password is initialized");
fe6b0b
-            if (!token.isLoggedIn()) {
fe6b0b
-                CMS.debug("loginToken():Token is not logged in, try it");
fe6b0b
-                token.login(password);
fe6b0b
+        try {
fe6b0b
+            if (token.passwordIsInitialized()) {
fe6b0b
+                CMS.debug("loginToken():token password is initialized");
fe6b0b
+                if (!token.isLoggedIn()) {
fe6b0b
+                    CMS.debug("loginToken():Token is not logged in, try it");
fe6b0b
+                    token.login(password);
fe6b0b
+                } else {
fe6b0b
+                    CMS.debug("loginToken():Token has already logged on");
fe6b0b
+                }
fe6b0b
             } else {
fe6b0b
-                CMS.debug("loginToken():Token has already logged on");
fe6b0b
+                CMS.debug("loginToken():Token password not initialized");
fe6b0b
+                rv = false;
fe6b0b
+            }
fe6b0b
+
fe6b0b
+        } catch (TokenException | IncorrectPasswordException e) {
fe6b0b
+            throw e;
fe6b0b
+        } finally {
fe6b0b
+            if (password != null) {
fe6b0b
+                password.clear();
fe6b0b
             }
fe6b0b
-        } else {
fe6b0b
-            CMS.debug("loginToken():Token password not initialized");
fe6b0b
-            rv = false;
fe6b0b
         }
fe6b0b
+
fe6b0b
         return rv;
fe6b0b
     }
fe6b0b
 
fe6b0b
@@ -877,117 +887,126 @@ public class ConfigurationUtils {
fe6b0b
         StringBuffer reason = new StringBuffer();
fe6b0b
         Password password = new Password(p12Pass.toCharArray());
fe6b0b
 
fe6b0b
-        PFX pfx = (PFX) (new PFX.Template()).decode(bis);
fe6b0b
-        boolean verifypfx = pfx.verifyAuthSafes(password, reason);
fe6b0b
+        try {
fe6b0b
 
fe6b0b
-        if (!verifypfx) {
fe6b0b
-            throw new IOException("PKCS #12 password is incorrect");
fe6b0b
-        }
fe6b0b
+            PFX pfx = (PFX) (new PFX.Template()).decode(bis);
fe6b0b
+            boolean verifypfx = pfx.verifyAuthSafes(password, reason);
fe6b0b
 
fe6b0b
-        AuthenticatedSafes safes = pfx.getAuthSafes();
fe6b0b
-        Vector<Vector<Object>> pkeyinfo_collection = new Vector<Vector<Object>>();
fe6b0b
-        Vector<Vector<Object>> cert_collection = new Vector<Vector<Object>>();
fe6b0b
+            if (!verifypfx) {
fe6b0b
+                throw new IOException("PKCS #12 password is incorrect");
fe6b0b
+            }
fe6b0b
 
fe6b0b
-        CMS.debug("Importing PKCS #12 data");
fe6b0b
+            AuthenticatedSafes safes = pfx.getAuthSafes();
fe6b0b
+            Vector<Vector<Object>> pkeyinfo_collection = new Vector<Vector<Object>>();
fe6b0b
+            Vector<Vector<Object>> cert_collection = new Vector<Vector<Object>>();
fe6b0b
 
fe6b0b
-        for (int i = 0; i < safes.getSize(); i++) {
fe6b0b
+            CMS.debug("Importing PKCS #12 data");
fe6b0b
 
fe6b0b
-            CMS.debug("- Safe #" + i + ":");
fe6b0b
-            SEQUENCE scontent = safes.getSafeContentsAt(null, i);
fe6b0b
+            for (int i = 0; i < safes.getSize(); i++) {
fe6b0b
 
fe6b0b
-            for (int j = 0; j < scontent.size(); j++) {
fe6b0b
+                CMS.debug("- Safe #" + i + ":");
fe6b0b
+                SEQUENCE scontent = safes.getSafeContentsAt(null, i);
fe6b0b
 
fe6b0b
-                SafeBag bag = (SafeBag) scontent.elementAt(j);
fe6b0b
-                OBJECT_IDENTIFIER oid = bag.getBagType();
fe6b0b
+                for (int j = 0; j < scontent.size(); j++) {
fe6b0b
 
fe6b0b
-                if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) {
fe6b0b
+                    SafeBag bag = (SafeBag) scontent.elementAt(j);
fe6b0b
+                    OBJECT_IDENTIFIER oid = bag.getBagType();
fe6b0b
 
fe6b0b
-                    CMS.debug("  - Bag #" + j + ": key");
fe6b0b
-                    byte[] epki = bag.getBagContent().getEncoded();
fe6b0b
+                    if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) {
fe6b0b
 
fe6b0b
-                    SET bagAttrs = bag.getBagAttributes();
fe6b0b
-                    String subjectDN = null;
fe6b0b
+                        CMS.debug("  - Bag #" + j + ": key");
fe6b0b
+                        byte[] epki = bag.getBagContent().getEncoded();
fe6b0b
 
fe6b0b
-                    for (int k = 0; k < bagAttrs.size(); k++) {
fe6b0b
+                        SET bagAttrs = bag.getBagAttributes();
fe6b0b
+                        String subjectDN = null;
fe6b0b
 
fe6b0b
-                        Attribute attrs = (Attribute) bagAttrs.elementAt(k);
fe6b0b
-                        OBJECT_IDENTIFIER aoid = attrs.getType();
fe6b0b
+                        for (int k = 0; k < bagAttrs.size(); k++) {
fe6b0b
 
fe6b0b
-                        if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
fe6b0b
-                            SET val = attrs.getValues();
fe6b0b
-                            ANY ss = (ANY) val.elementAt(0);
fe6b0b
+                            Attribute attrs = (Attribute) bagAttrs.elementAt(k);
fe6b0b
+                            OBJECT_IDENTIFIER aoid = attrs.getType();
fe6b0b
 
fe6b0b
-                            ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
fe6b0b
-                            BMPString sss = (BMPString) new BMPString.Template().decode(bbis);
fe6b0b
-                            subjectDN = sss.toString();
fe6b0b
-                            CMS.debug("    Subject DN: " + subjectDN);
fe6b0b
-                            break;
fe6b0b
+                            if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
fe6b0b
+                                SET val = attrs.getValues();
fe6b0b
+                                ANY ss = (ANY) val.elementAt(0);
fe6b0b
+
fe6b0b
+                                ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
fe6b0b
+                                BMPString sss = (BMPString) new BMPString.Template().decode(bbis);
fe6b0b
+                                subjectDN = sss.toString();
fe6b0b
+                                CMS.debug("    Subject DN: " + subjectDN);
fe6b0b
+                                break;
fe6b0b
+                            }
fe6b0b
                         }
fe6b0b
-                    }
fe6b0b
 
fe6b0b
-                    // pkeyinfo_v stores EncryptedPrivateKeyInfo
fe6b0b
-                    // (byte[]) and subject DN (String)
fe6b0b
-                    Vector<Object> pkeyinfo_v = new Vector<Object>();
fe6b0b
-                    pkeyinfo_v.addElement(epki);
fe6b0b
-                    if (subjectDN != null)
fe6b0b
-                        pkeyinfo_v.addElement(subjectDN);
fe6b0b
+                        // pkeyinfo_v stores EncryptedPrivateKeyInfo
fe6b0b
+                        // (byte[]) and subject DN (String)
fe6b0b
+                        Vector<Object> pkeyinfo_v = new Vector<Object>();
fe6b0b
+                        pkeyinfo_v.addElement(epki);
fe6b0b
+                        if (subjectDN != null)
fe6b0b
+                            pkeyinfo_v.addElement(subjectDN);
fe6b0b
 
fe6b0b
-                    pkeyinfo_collection.addElement(pkeyinfo_v);
fe6b0b
+                        pkeyinfo_collection.addElement(pkeyinfo_v);
fe6b0b
 
fe6b0b
-                } else if (oid.equals(SafeBag.CERT_BAG)) {
fe6b0b
+                    } else if (oid.equals(SafeBag.CERT_BAG)) {
fe6b0b
 
fe6b0b
-                    CMS.debug("  - Bag #" + j + ": certificate");
fe6b0b
-                    CertBag cbag = (CertBag) bag.getInterpretedBagContent();
fe6b0b
-                    OCTET_STRING str = (OCTET_STRING) cbag.getInterpretedCert();
fe6b0b
-                    byte[] x509cert = str.toByteArray();
fe6b0b
+                        CMS.debug("  - Bag #" + j + ": certificate");
fe6b0b
+                        CertBag cbag = (CertBag) bag.getInterpretedBagContent();
fe6b0b
+                        OCTET_STRING str = (OCTET_STRING) cbag.getInterpretedCert();
fe6b0b
+                        byte[] x509cert = str.toByteArray();
fe6b0b
 
fe6b0b
-                    SET bagAttrs = bag.getBagAttributes();
fe6b0b
-                    String nickname = null;
fe6b0b
+                        SET bagAttrs = bag.getBagAttributes();
fe6b0b
+                        String nickname = null;
fe6b0b
 
fe6b0b
-                    if (bagAttrs != null) {
fe6b0b
+                        if (bagAttrs != null) {
fe6b0b
 
fe6b0b
-                        for (int k = 0; k < bagAttrs.size(); k++) {
fe6b0b
+                            for (int k = 0; k < bagAttrs.size(); k++) {
fe6b0b
 
fe6b0b
-                            Attribute attrs = (Attribute) bagAttrs.elementAt(k);
fe6b0b
-                            OBJECT_IDENTIFIER aoid = attrs.getType();
fe6b0b
+                                Attribute attrs = (Attribute) bagAttrs.elementAt(k);
fe6b0b
+                                OBJECT_IDENTIFIER aoid = attrs.getType();
fe6b0b
 
fe6b0b
-                            if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
fe6b0b
-                                SET val = attrs.getValues();
fe6b0b
-                                ANY ss = (ANY) val.elementAt(0);
fe6b0b
+                                if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
fe6b0b
+                                    SET val = attrs.getValues();
fe6b0b
+                                    ANY ss = (ANY) val.elementAt(0);
fe6b0b
 
fe6b0b
-                                ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
fe6b0b
-                                BMPString sss = (BMPString) (new BMPString.Template()).decode(bbis);
fe6b0b
-                                nickname = sss.toString();
fe6b0b
-                                CMS.debug("    Nickname: " + nickname);
fe6b0b
-                                break;
fe6b0b
+                                    ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
fe6b0b
+                                    BMPString sss = (BMPString) (new BMPString.Template()).decode(bbis);
fe6b0b
+                                    nickname = sss.toString();
fe6b0b
+                                    CMS.debug("    Nickname: " + nickname);
fe6b0b
+                                    break;
fe6b0b
+                                }
fe6b0b
                             }
fe6b0b
                         }
fe6b0b
-                    }
fe6b0b
 
fe6b0b
-                    X509CertImpl certImpl = new X509CertImpl(x509cert);
fe6b0b
-                    CMS.debug("    Serial number: " + certImpl.getSerialNumber());
fe6b0b
+                        X509CertImpl certImpl = new X509CertImpl(x509cert);
fe6b0b
+                        CMS.debug("    Serial number: " + certImpl.getSerialNumber());
fe6b0b
 
fe6b0b
-                    try {
fe6b0b
-                        certImpl.checkValidity();
fe6b0b
-                        CMS.debug("    Status: valid");
fe6b0b
+                        try {
fe6b0b
+                            certImpl.checkValidity();
fe6b0b
+                            CMS.debug("    Status: valid");
fe6b0b
 
fe6b0b
-                    } catch (CertificateExpiredException | CertificateNotYetValidException e) {
fe6b0b
-                        CMS.debug("    Status: " + e);
fe6b0b
-                        continue;
fe6b0b
-                    }
fe6b0b
+                        } catch (CertificateExpiredException | CertificateNotYetValidException e) {
fe6b0b
+                            CMS.debug("    Status: " + e);
fe6b0b
+                            continue;
fe6b0b
+                        }
fe6b0b
 
fe6b0b
-                    // cert_v stores certificate (byte[]) and nickname (String)
fe6b0b
-                    Vector<Object> cert_v = new Vector<Object>();
fe6b0b
-                    cert_v.addElement(x509cert);
fe6b0b
-                    if (nickname != null)
fe6b0b
-                        cert_v.addElement(nickname);
fe6b0b
+                        // cert_v stores certificate (byte[]) and nickname (String)
fe6b0b
+                        Vector<Object> cert_v = new Vector<Object>();
fe6b0b
+                        cert_v.addElement(x509cert);
fe6b0b
+                        if (nickname != null)
fe6b0b
+                            cert_v.addElement(nickname);
fe6b0b
 
fe6b0b
-                    cert_collection.addElement(cert_v);
fe6b0b
+                        cert_collection.addElement(cert_v);
fe6b0b
+                    }
fe6b0b
                 }
fe6b0b
             }
fe6b0b
-        }
fe6b0b
 
fe6b0b
-        importKeyCert(password, pkeyinfo_collection, cert_collection);
fe6b0b
+            importKeyCert(password, pkeyinfo_collection, cert_collection);
fe6b0b
+        } catch (Exception e) {
fe6b0b
+            throw e;
fe6b0b
+        } finally {
fe6b0b
+            if (password != null) {
fe6b0b
+                password.clear();
fe6b0b
+            }
fe6b0b
+        }
fe6b0b
     }
fe6b0b
 
fe6b0b
     public static void verifySystemCertificates() throws Exception {
fe6b0b
@@ -3248,54 +3267,63 @@ public class ConfigurationUtils {
fe6b0b
 
fe6b0b
         Password pass = new org.mozilla.jss.util.Password(pwd.toCharArray());
fe6b0b
 
fe6b0b
-        PKCS12Util util = new PKCS12Util();
fe6b0b
-        PKCS12 pkcs12 = new PKCS12();
fe6b0b
+        try {
fe6b0b
 
fe6b0b
-        // load system certificate (with key but without chain)
fe6b0b
-        while (st.hasMoreTokens()) {
fe6b0b
+            PKCS12Util util = new PKCS12Util();
fe6b0b
+            PKCS12 pkcs12 = new PKCS12();
fe6b0b
 
fe6b0b
-            String t = st.nextToken();
fe6b0b
-            if (t.equals("sslserver"))
fe6b0b
-                continue;
fe6b0b
+            // load system certificate (with key but without chain)
fe6b0b
+            while (st.hasMoreTokens()) {
fe6b0b
 
fe6b0b
-            String nickname = cs.getString("preop.cert." + t + ".nickname");
fe6b0b
-            String modname = cs.getString("preop.module.token");
fe6b0b
+                String t = st.nextToken();
fe6b0b
+                if (t.equals("sslserver"))
fe6b0b
+                    continue;
fe6b0b
 
fe6b0b
-            if (!CryptoUtil.isInternalToken(modname))
fe6b0b
-                nickname = modname + ":" + nickname;
fe6b0b
+                String nickname = cs.getString("preop.cert." + t + ".nickname");
fe6b0b
+                String modname = cs.getString("preop.module.token");
fe6b0b
 
fe6b0b
-            util.loadCertFromNSS(pkcs12, nickname, true, false);
fe6b0b
-        }
fe6b0b
+                if (!CryptoUtil.isInternalToken(modname))
fe6b0b
+                    nickname = modname + ":" + nickname;
fe6b0b
 
fe6b0b
-        // load CA certificates (without keys or chains)
fe6b0b
-        for (X509Certificate caCert : cm.getCACerts()) {
fe6b0b
-            util.loadCertFromNSS(pkcs12, caCert, false, false);
fe6b0b
-        }
fe6b0b
+                util.loadCertFromNSS(pkcs12, nickname, true, false);
fe6b0b
+            }
fe6b0b
 
fe6b0b
-        PFX pfx = util.generatePFX(pkcs12, pass);
fe6b0b
+            // load CA certificates (without keys or chains)
fe6b0b
+            for (X509Certificate caCert : cm.getCACerts()) {
fe6b0b
+                util.loadCertFromNSS(pkcs12, caCert, false, false);
fe6b0b
+            }
fe6b0b
 
fe6b0b
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
fe6b0b
-        pfx.encode(bos);
fe6b0b
-        byte[] output = bos.toByteArray();
fe6b0b
+            PFX pfx = util.generatePFX(pkcs12, pass);
fe6b0b
 
fe6b0b
-        cs.putString("preop.pkcs12", CryptoUtil.byte2string(output));
fe6b0b
-        pass.clear();
fe6b0b
-        cs.commit(false);
fe6b0b
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
fe6b0b
+            pfx.encode(bos);
fe6b0b
+            byte[] output = bos.toByteArray();
fe6b0b
 
fe6b0b
-        if (fname != null) {
fe6b0b
-            FileOutputStream fout = null;
fe6b0b
-            try {
fe6b0b
-                fout = new FileOutputStream(fname);
fe6b0b
-                fout.write(output);
fe6b0b
+            cs.putString("preop.pkcs12", CryptoUtil.byte2string(output));
fe6b0b
+            cs.commit(false);
fe6b0b
 
fe6b0b
-            } catch (Exception e) {
fe6b0b
-                throw new IOException("Failed to store keys in backup file " + e, e);
fe6b0b
+            if (fname != null) {
fe6b0b
+                FileOutputStream fout = null;
fe6b0b
+                try {
fe6b0b
+                    fout = new FileOutputStream(fname);
fe6b0b
+                    fout.write(output);
fe6b0b
 
fe6b0b
-            } finally {
fe6b0b
-                if (fout != null) {
fe6b0b
-                    fout.close();
fe6b0b
+                } catch (Exception e) {
fe6b0b
+                    throw new IOException("Failed to store keys in backup file " + e, e);
fe6b0b
+
fe6b0b
+                } finally {
fe6b0b
+                    if (fout != null) {
fe6b0b
+                        fout.close();
fe6b0b
+                    }
fe6b0b
                 }
fe6b0b
             }
fe6b0b
+
fe6b0b
+        } catch (Exception e) {
fe6b0b
+            throw e;
fe6b0b
+        } finally {
fe6b0b
+            if (pass != null) {
fe6b0b
+                pass.clear();
fe6b0b
+            }
fe6b0b
         }
fe6b0b
     }
fe6b0b
 
fe6b0b
diff --git a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
fe6b0b
index be7edd5..a9bb003 100644
fe6b0b
--- a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
fe6b0b
+++ b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
fe6b0b
@@ -409,6 +409,14 @@ public final class JssSubsystem implements ICryptoSubsystem {
fe6b0b
         }
fe6b0b
     }
fe6b0b
 
fe6b0b
+    public void obscureChars(char[] memory) {
fe6b0b
+        String methodName = "JssSubsystem.obscureBytes: ";
fe6b0b
+        if (memory == null || memory.length == 0)
fe6b0b
+            return;
fe6b0b
+        CMS.debug(methodName + " filling with zeroes, numChars: " + memory.length);
fe6b0b
+        Arrays.fill(memory, (char) 0);
fe6b0b
+    }
fe6b0b
+
fe6b0b
     public String getCipherVersion() throws EBaseException {
fe6b0b
         return "cipherdomestic";
fe6b0b
     }
fe6b0b
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
index 8a0ea08..7a68c9b 100644
fe6b0b
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
fe6b0b
@@ -24,6 +24,9 @@ import java.io.IOException;
fe6b0b
 import java.io.PrintStream;
fe6b0b
 import java.math.BigInteger;
fe6b0b
 import java.net.SocketException;
fe6b0b
+import java.nio.ByteBuffer;
fe6b0b
+import java.nio.CharBuffer;
fe6b0b
+import java.nio.charset.Charset;
fe6b0b
 import java.security.GeneralSecurityException;
fe6b0b
 import java.security.InvalidAlgorithmParameterException;
fe6b0b
 import java.security.InvalidKeyException;
fe6b0b
@@ -1950,6 +1953,52 @@ public class CryptoUtil {
fe6b0b
         return bytes;
fe6b0b
     }
fe6b0b
 
fe6b0b
+    public static char[] bytesToChars(byte[] bytes) {
fe6b0b
+        if(bytes == null)
fe6b0b
+            return null;
fe6b0b
+
fe6b0b
+        Charset charset = Charset.forName("UTF-8");
fe6b0b
+        CharBuffer charBuffer = charset.decode(ByteBuffer.wrap(bytes));
fe6b0b
+        char[] result = Arrays.copyOf(charBuffer.array(), charBuffer.limit());
fe6b0b
+
fe6b0b
+        //Clear up the CharBuffer we just created
fe6b0b
+        if (charBuffer.hasArray()) {
fe6b0b
+            char[] contentsToBeErased = charBuffer.array();
fe6b0b
+            CryptoUtil.obscureChars(contentsToBeErased);
fe6b0b
+        }
fe6b0b
+        return result;
fe6b0b
+    }
fe6b0b
+
fe6b0b
+    public static byte[] charsToBytes(char[] chars) {
fe6b0b
+        if(chars == null)
fe6b0b
+            return null;
fe6b0b
+
fe6b0b
+        Charset charset = Charset.forName("UTF-8");
fe6b0b
+        ByteBuffer byteBuffer = charset.encode(CharBuffer.wrap(chars));
fe6b0b
+        byte[] result = Arrays.copyOf(byteBuffer.array(), byteBuffer.limit());
fe6b0b
+
fe6b0b
+        if(byteBuffer.hasArray()) {
fe6b0b
+            byte[] contentsToBeErased = byteBuffer.array();
fe6b0b
+            CryptoUtil.obscureBytes(contentsToBeErased, "random");
fe6b0b
+        }
fe6b0b
+        return result;
fe6b0b
+    }
fe6b0b
+
fe6b0b
+    /**
fe6b0b
+     * Create a jss Password object from a provided byte array.
fe6b0b
+     */
fe6b0b
+    public static Password createPasswordFromBytes(byte[] bytes ) {
fe6b0b
+
fe6b0b
+        if(bytes == null)
fe6b0b
+            return null;
fe6b0b
+
fe6b0b
+        char[] pwdChars = bytesToChars(bytes);
fe6b0b
+        Password password = new Password(pwdChars);
fe6b0b
+        obscureChars(pwdChars);
fe6b0b
+
fe6b0b
+        return password;
fe6b0b
+    }
fe6b0b
+
fe6b0b
     /**
fe6b0b
      * Retrieves a private key from a unique key ID.
fe6b0b
      */
fe6b0b
@@ -2176,6 +2225,14 @@ public class CryptoUtil {
fe6b0b
 
fe6b0b
     }
fe6b0b
 
fe6b0b
+    public static void obscureChars(char[] memory) {
fe6b0b
+        if (memory == null || memory.length == 0) {
fe6b0b
+            //in case we want to log
fe6b0b
+            return;
fe6b0b
+        }
fe6b0b
+        Arrays.fill(memory, (char) 0);
fe6b0b
+    }
fe6b0b
+
fe6b0b
     public static void obscureBytes(byte[] memory, String method) {
fe6b0b
         if (memory == null || memory.length == 0) {
fe6b0b
             //in case we want to log
fe6b0b
@@ -2279,7 +2336,7 @@ public class CryptoUtil {
fe6b0b
     public static PKIArchiveOptions createPKIArchiveOptions(
fe6b0b
             CryptoToken token,
fe6b0b
             PublicKey wrappingKey,
fe6b0b
-            String data,
fe6b0b
+            char[] data,
fe6b0b
             WrappingParams params,
fe6b0b
             AlgorithmIdentifier aid) throws Exception {
fe6b0b
         return createPKIArchiveOptionsInternal(
fe6b0b
@@ -2289,7 +2346,7 @@ public class CryptoUtil {
fe6b0b
     public static byte[] createEncodedPKIArchiveOptions(
fe6b0b
             CryptoToken token,
fe6b0b
             PublicKey wrappingKey,
fe6b0b
-            String data,
fe6b0b
+            char []data,
fe6b0b
             WrappingParams params,
fe6b0b
             AlgorithmIdentifier aid) throws Exception {
fe6b0b
         PKIArchiveOptions opts = createPKIArchiveOptionsInternal(
fe6b0b
@@ -2300,7 +2357,7 @@ public class CryptoUtil {
fe6b0b
     private static PKIArchiveOptions createPKIArchiveOptionsInternal(
fe6b0b
             CryptoToken token,
fe6b0b
             PublicKey wrappingKey,
fe6b0b
-            String passphraseData,
fe6b0b
+            char[] passphraseData,
fe6b0b
             PrivateKey privKeyData,
fe6b0b
             SymmetricKey symKeyData,
fe6b0b
             WrappingParams params,
fe6b0b
@@ -2315,7 +2372,7 @@ public class CryptoUtil {
fe6b0b
 
fe6b0b
         if (passphraseData != null) {
fe6b0b
 
fe6b0b
-            byte[] secret = passphraseData.getBytes("UTF-8");
fe6b0b
+            byte[] secret =  CryptoUtil.charsToBytes(passphraseData);
fe6b0b
             key_data = encryptSecret(
fe6b0b
                     token,
fe6b0b
                     secret,
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b
fe6b0b
fe6b0b
From 45a098dfbe3bbb951a7cb22d50e13e8e093d03cc Mon Sep 17 00:00:00 2001
fe6b0b
From: Geetika Kapoor <gkapoor@redhat.com>
fe6b0b
Date: Mon, 20 Nov 2017 12:13:41 +0530
fe6b0b
Subject: Added ansible playbooks code and documentation for setup
fe6b0b
fe6b0b
Change-Id: I0e597ec86661d2ccf72e8a04279981471b0590b1
fe6b0b
Signed-off-by: Geetika Kapoor <gkapoor@redhat.com>
fe6b0b
(cherry picked from commit 48fbe1e75de5d91699aaa418fd8e34ab3745e25c)
fe6b0b
---
fe6b0b
 tests/dogtag/pytest-ansible/README.md              |  27 ++
fe6b0b
 tests/dogtag/pytest-ansible/common-modules/pki.py  | 127 +++++++++
fe6b0b
 tests/dogtag/pytest-ansible/installation/README.md |  99 +++++++
fe6b0b
 tests/dogtag/pytest-ansible/installation/host      |   2 +
fe6b0b
 tests/dogtag/pytest-ansible/installation/main.yml  |  11 +
fe6b0b
 .../files/config_templates/ansible_constants.py    |  52 ++++
fe6b0b
 .../roles/Test_Execution/files/test/script         |  79 ++++++
fe6b0b
 .../roles/Test_Execution/handlers/main.yml         |   3 +
fe6b0b
 .../roles/Test_Execution/handlers/pki-core.yml     |  54 ++++
fe6b0b
 .../roles/Test_Execution/tasks/configure_ca.yml    |  18 ++
fe6b0b
 .../Test_Execution/tasks/configure_common.yml      |  77 +++++
fe6b0b
 .../roles/Test_Execution/tasks/configure_kra.yml   |  24 ++
fe6b0b
 .../roles/Test_Execution/tasks/configure_ldap.yml  |  20 ++
fe6b0b
 .../roles/Test_Execution/tasks/configure_ocsp.yml  |  17 ++
fe6b0b
 .../Test_Execution/tasks/configure_shared.yml      |  14 +
fe6b0b
 .../tasks/configure_sharedsecret.yml               |   4 +
fe6b0b
 .../roles/Test_Execution/tasks/configure_tks.yml   |  30 ++
fe6b0b
 .../roles/Test_Execution/tasks/configure_tps.yml   |  24 ++
fe6b0b
 .../roles/Test_Execution/tasks/main.yml            |  19 ++
fe6b0b
 .../files/config_templates/ansible_constants.py    |  52 ++++
fe6b0b
 .../roles/Test_Trigger/files/test/ca.cfg           |  38 +++
fe6b0b
 .../roles/Test_Trigger/files/test/constants.py     |  67 +++++
fe6b0b
 .../roles/Test_Trigger/files/test/kra.cfg          |  42 +++
fe6b0b
 .../roles/Test_Trigger/files/test/ldap.cfg         |  12 +
fe6b0b
 .../roles/Test_Trigger/files/test/ocsp.cfg         |  36 +++
fe6b0b
 .../roles/Test_Trigger/files/test/script           |  79 ++++++
fe6b0b
 .../roles/Test_Trigger/files/test/tks.cfg          |  26 ++
fe6b0b
 .../roles/Test_Trigger/files/test/tps.cfg          |  34 +++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_ca.yml      |  25 ++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_common.yml  | 146 ++++++++++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_kra.yml     |  27 ++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_ldap.yml    |  47 ++++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_ocsp.yml    |  27 ++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_tks.yml     |  27 ++
fe6b0b
 .../roles/Test_Trigger/tasks/configure_tps.yml     |  39 +++
fe6b0b
 .../installation/roles/Test_Trigger/tasks/main.yml |  15 +
fe6b0b
 .../dogtag/pytest-ansible/installation/vars/ca.yml |   4 +
fe6b0b
 .../pytest-ansible/installation/vars/ca_shared.yml |  24 ++
fe6b0b
 .../pytest-ansible/installation/vars/kra.yml       |   4 +
fe6b0b
 .../pytest-ansible/installation/vars/ldap.yml      |   8 +
fe6b0b
 .../installation/vars/ldap_shared.yml              |   3 +
fe6b0b
 .../pytest-ansible/installation/vars/ocsp.yml      |   4 +
fe6b0b
 .../pytest-ansible/installation/vars/tks.yml       |   4 +
fe6b0b
 .../pytest-ansible/installation/vars/tps.yml       |   4 +
fe6b0b
 tests/dogtag/pytest-ansible/provision/readme.txt   |   0
fe6b0b
 tests/dogtag/pytest-ansible/pytest/README.md       | 313 +++++++++++++++++++++
fe6b0b
 .../pytest/tps-token/ldapUserAdd.yml               |  35 +++
fe6b0b
 .../pytest/tps-token/test_tps_token_show.py        | 106 +++++++
fe6b0b
 .../pytest/tps-token/tokenEnroll.yml               |  35 +++
fe6b0b
 tests/dogtag/pytest-ansible/requirements.txt       |   5 +
fe6b0b
 50 files changed, 1989 insertions(+)
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/README.md
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/common-modules/pki.py
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/README.md
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/host
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/main.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/config_templates/ansible_constants.py
fe6b0b
 create mode 100755 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/test/script
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/main.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/pki-core.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ca.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_common.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_kra.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ldap.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ocsp.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_shared.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_sharedsecret.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tks.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tps.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/main.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/config_templates/ansible_constants.py
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ca.cfg
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/constants.py
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/kra.cfg
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ldap.cfg
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ocsp.cfg
fe6b0b
 create mode 100755 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/script
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tks.cfg
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tps.cfg
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ca.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_common.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_kra.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ldap.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ocsp.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tks.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tps.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/main.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/ca.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/ca_shared.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/kra.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/ldap.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/ldap_shared.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/ocsp.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/tks.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/installation/vars/tps.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/provision/readme.txt
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/pytest/README.md
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/pytest/tps-token/ldapUserAdd.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/pytest/tps-token/test_tps_token_show.py
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/pytest/tps-token/tokenEnroll.yml
fe6b0b
 create mode 100644 tests/dogtag/pytest-ansible/requirements.txt
fe6b0b
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/README.md b/tests/dogtag/pytest-ansible/README.md
fe6b0b
new file mode 100644
fe6b0b
index 0000000..8142f39
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/README.md
fe6b0b
@@ -0,0 +1,27 @@
fe6b0b
+# Environment-Setup Instructions
fe6b0b
+
fe6b0b
+## Installing pip
fe6b0b
+
fe6b0b
+[pip] (https://pip.pypa.io/en/stable/installing/)  is needed for ansible & pytest installation.
fe6b0b
+
fe6b0b
+## Installing Supporting Packages
fe6b0b
+
fe6b0b
+Install the pip and run requirements.txt file 
fe6b0b
+
fe6b0b
+```
fe6b0b
+pip install -r requirements.txt
fe6b0b
+```
fe6b0b
+
fe6b0b
+## Installing CA, KRA, OCSP, TKS & TPS Subsystems
fe6b0b
+
fe6b0b
+Refer [README.md] (installation/README.md)
fe6b0b
+
fe6b0b
+
fe6b0b
+
fe6b0b
+## Running Pytest-Ansible test cases.
fe6b0b
+
fe6b0b
+### Pre-requisite
fe6b0b
+
fe6b0b
+1. Run Role user setup for setting up different users for different subsystem for setting up Admin, Agent, Revoked and Expired certificates.
fe6b0b
+    -- To-do
fe6b0b
+2. Refer [README.md] (pytest/README.md)
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/common-modules/pki.py b/tests/dogtag/pytest-ansible/common-modules/pki.py
fe6b0b
new file mode 100644
fe6b0b
index 0000000..4d489e9
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/common-modules/pki.py
fe6b0b
@@ -0,0 +1,127 @@
fe6b0b
+#!/usr/bin/python
fe6b0b
+# -*- coding: utf-8 -*-
fe6b0b
+# (c) 2016, Geetika Kapoor <gkapoor@redhat.com>
fe6b0b
+#
fe6b0b
+# This file is part of Ansible
fe6b0b
+#
fe6b0b
+# Ansible is free software: you can redistribute it and/or modify
fe6b0b
+# it under the terms of the GNU General Public License as published by
fe6b0b
+# the Free Software Foundation, either version 3 of the License, or
fe6b0b
+# (at your option) any later version.
fe6b0b
+#
fe6b0b
+# Ansible is distributed in the hope that it will be useful,
fe6b0b
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
fe6b0b
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
fe6b0b
+# GNU General Public License for more details.
fe6b0b
+#
fe6b0b
+# You should have received a copy of the GNU General Public License
fe6b0b
+# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
fe6b0b
+
fe6b0b
+ANSIBLE_METADATA = {'metadata_version': '1.0',
fe6b0b
+                    'status': ['stableinterface'],
fe6b0b
+                    'supported_by': 'core'}
fe6b0b
+
fe6b0b
+DOCUMENTATION = '''
fe6b0b
+---
fe6b0b
+module: pki
fe6b0b
+short_description: Execute dogtag "pki" commands remotely on any machine.
fe6b0b
+Point it to the host where you want them to run.
fe6b0b
+This utility supports all the authentication modes as mentioned in 
fe6b0b
+man pages of pki. Refer 'man pki' for supported options.
fe6b0b
+
fe6b0b
+Usage: This can be added as mentioned in the example.
fe6b0b
+Authentication types supported:
fe6b0b
+1. Connection - Plain URI connection
fe6b0b
+2. Basic Authentication: username/password support
fe6b0b
+3. Client Authentication: certificate authentication support
fe6b0b
+conn_args: Name assigned to variable that has common arguments
fe6b0b
+needed for all types of connection.
fe6b0b
+auth_args: Name assigned to authentication commands that are run using pki.
fe6b0b
+cli_args: Name assigned to sub-cli-commands that are run underneath 
fe6b0b
+pki command.
fe6b0b
+
fe6b0b
+Example:
fe6b0b
+- name: Call pki command
fe6b0b
+  pki: cli='ca-cert-find' authType='connection'
fe6b0b
+
fe6b0b
+'''
fe6b0b
+
fe6b0b
+import datetime
fe6b0b
+import glob
fe6b0b
+import shlex
fe6b0b
+import os
fe6b0b
+
fe6b0b
+if os.path.isfile('/tmp/test_dir/constants.py'):
fe6b0b
+    import sys
fe6b0b
+    sys.path.append('/tmp/test_dir')
fe6b0b
+    import constants
fe6b0b
+else:
fe6b0b
+    from pki.testlib.common import constants
fe6b0b
+from ansible.module_utils.basic import AnsibleModule
fe6b0b
+from ansible.module_utils.six import b
fe6b0b
+
fe6b0b
+
fe6b0b
+def main():
fe6b0b
+
fe6b0b
+    # the command module is the one ansible module that does not take key=value args
fe6b0b
+    # hence don't copy this one if you are looking to build others!
fe6b0b
+    module = AnsibleModule(
fe6b0b
+        argument_spec=dict(
fe6b0b
+            raw_params = dict(default='pki'),
fe6b0b
+	    port = dict(default=''),
fe6b0b
+	    cli = dict(default='--help'),
fe6b0b
+	    extra_args = dict(default=''),
fe6b0b
+	    certnick = dict(default="'PKI CA Administrator for Example.Org'"),
fe6b0b
+	    username = dict(default='caadmin'),
fe6b0b
+	    userpassword = dict(default='Secret123'),
fe6b0b
+	    userpwdfile = dict(default='Secret123'),
fe6b0b
+	    dbpassword = dict(default='Secret123'),
fe6b0b
+	    nssdb = dict(default='/opt/pkitest/certdb'),
fe6b0b
+	    protocol = dict(default='http'),
fe6b0b
+	    hostname = dict(default='localhost'),
fe6b0b
+	    authType = dict(default='clientAuth', choices=['connection', 'basicAuth', 'clientAuth'])
fe6b0b
+        )
fe6b0b
+    )
fe6b0b
+    if module.params['port']:
fe6b0b
+	port = module.params['port']
fe6b0b
+    else:
fe6b0b
+    	Subsystem=map(lambda x: {"True" if x in module.params['cli'] else False: x } ,["ca", "kra", "ocsp", "tks", "tps"])
fe6b0b
+    	for idx, val in enumerate(Subsystem):
fe6b0b
+		for key, value in val.iteritems():
fe6b0b
+			if key == 'True':
fe6b0b
+				sub = value
fe6b0b
+    	port = '_'.join([sub.upper(), module.params['protocol'].upper(), "PORT"])
fe6b0b
+        port = getattr(constants, port)
fe6b0b
+    conn_args = [module.params['raw_params'], '-d', module.params['nssdb'], '-P', module.params['protocol'], '-p', '%s' %(port), '-h', module.params['hostname'], '-c', module.params['dbpassword']]
fe6b0b
+    cli_args = [module.params['cli'], module.params['extra_args']]
fe6b0b
+
fe6b0b
+    if module.params['authType'] == 'clientAuth':
fe6b0b
+        auth_args = ['-n', module.params['certnick']]
fe6b0b
+        args = ' '.join(conn_args + auth_args + cli_args)
fe6b0b
+
fe6b0b
+    if module.params['authType'] == 'basicAuth':
fe6b0b
+	auth_args = ['-u', module.params['username'], '-w', module.params['userpassword']]
fe6b0b
+        args = ' '.join(conn_args + auth_args + cli_args)
fe6b0b
+
fe6b0b
+    if module.params['authType'] == 'connection':
fe6b0b
+         args = ' '.join(conn_args)
fe6b0b
+
fe6b0b
+    rc, out, err = module.run_command(args)
fe6b0b
+
fe6b0b
+    result = dict(
fe6b0b
+        cmd      = args,
fe6b0b
+        stdout   = out.rstrip(b("\r\n")),
fe6b0b
+        stderr   = err.rstrip(b("\r\n")),
fe6b0b
+        rc       = rc,
fe6b0b
+        changed  = True,
fe6b0b
+    )
fe6b0b
+
fe6b0b
+    if rc != 0:
fe6b0b
+        module.fail_json(msg='non-zero return code', **result)
fe6b0b
+
fe6b0b
+    module.exit_json(**result)
fe6b0b
+
fe6b0b
+
fe6b0b
+if __name__ == '__main__':
fe6b0b
+    main()
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/README.md b/tests/dogtag/pytest-ansible/installation/README.md
fe6b0b
new file mode 100644
fe6b0b
index 0000000..6b18ee0
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/README.md
fe6b0b
@@ -0,0 +1,99 @@
fe6b0b
+# Project Name - Dogtagpki
fe6b0b
+
fe6b0b
+## Subsystem Installation using Ansible
fe6b0b
+
fe6b0b
+### About
fe6b0b
+
fe6b0b
+This ansible playbook is written to setup all the subsystems(CA, KRA, OCSP, TKS and TPS).
fe6b0b
+These playbooks can setup the environment based on the topology specified in the runtime.
fe6b0b
+
fe6b0b
+### Requirements:
fe6b0b
+
fe6b0b
+1. Pip should be installed.
fe6b0b
+2. Pip [requiremets.txt](../Installation/requirements.txt) should be installed 
fe6b0b
+3. Make sure to check ansible version after installation.This can be quickly done using
fe6b0b
+ansible --version.
fe6b0b
+If this commands works, Your ansible is installed properly.
fe6b0b
+
fe6b0b
+4. Before running the playbooks make sure machines that are going to communicate with each other they have passwordless communication working.
fe6b0b
+This can be easily done using:
fe6b0b
+                                  `ssh-copy-id root@<remote machine>`
fe6b0b
+
fe6b0b
+This will ask you for one time password after which it will copy keys between machines.
fe6b0b
+
fe6b0b
+### Verification Step
fe6b0b
+```
fe6b0b
+     ssh root@<remote host>
fe6b0b
+```
fe6b0b
+This should not prompt for password any more.
fe6b0b
+
fe6b0b
+### Packages to Install `Only for RHEL users`
fe6b0b
+
fe6b0b
+Configure repo that have below listed packages.It is mandatory to setup repo's 
fe6b0b
+correctly  before triggering ansible playbooks for system installation.
fe6b0b
+
fe6b0b
+```
fe6b0b
+Required Packages:
fe6b0b
+
fe6b0b
+    - redhat-pki
fe6b0b
+    - redhat-pki-console-theme
fe6b0b
+    - redhat-pki-server-theme
fe6b0b
+    - pki-console
fe6b0b
+    - 389-ds-base
fe6b0b
+    - pki-ca
fe6b0b
+    - pki-kra
fe6b0b
+    - pki-ocsp
fe6b0b
+    - pki-tks
fe6b0b
+    - pki-tps
fe6b0b
+    - policycoreutils-python
fe6b0b
+    - expect
fe6b0b
+    - libselinux-python
fe6b0b
+```
fe6b0b
+
fe6b0b
+### Usage:
fe6b0b
+
fe6b0b
+For Setting up Subsystems on different port, use `topology-02 `
fe6b0b
+```
fe6b0b
+ansible-playbook -i /tmp/test/pki-tests/ci/ansible/host main.yml --extra-vars "topology=topology-02" -v
fe6b0b
+```
fe6b0b
+
fe6b0b
+For Setting up Subsystems on default and same port, use `topology-01`
fe6b0b
+```
fe6b0b
+ansible-playbook -i /tmp/test/pki-tests/ci/ansible/host main.yml --extra-vars "topology=topology-01" -v
fe6b0b
+```
fe6b0b
+
fe6b0b
+where,
fe6b0b
+
fe6b0b
+  -i INVENTORY, --inventory-file=INVENTORY
fe6b0b
+                        specify inventory host path
fe6b0b
+                        (default=/etc/ansible/hosts) or comma separated host
fe6b0b
+                        list.
fe6b0b
+                        
fe6b0b
+## Examples of ansible-inventory
fe6b0b
+
fe6b0b
+Inventory file consist of the roles and the ip-address.Tests will run for the roles and ip's that are mentioned.
fe6b0b
+
fe6b0b
+```
fe6b0b
+[master]
fe6b0b
+10.1.2.3
fe6b0b
+10.2.3.4
fe6b0b
+```
fe6b0b
+                        
fe6b0b
+### Sanity tests
fe6b0b
+
fe6b0b
+Once playbook installation is complete, use below command and make certificates are returned.
fe6b0b
+```
fe6b0b
+        pki -p 20080 ca-cert-find
fe6b0b
+```
fe6b0b
+Incase, you are required to run any other topology let us say "topology-01" for shared instance, replace topology-02 with topology-01.
fe6b0b
+
fe6b0b
+
fe6b0b
+### Gathering Subsystems Facts
fe6b0b
+
fe6b0b
+Gather configuration files, ports and other environment data from `/tmp/test_dir` on the system under test.
fe6b0b
+
fe6b0b
+
fe6b0b
+## References:
fe6b0b
+
fe6b0b
+1. http://docs.ansible.com/ansible/intro.html
fe6b0b
+2. http://docs.ansible.com/ansible/intro_installation.html
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/host b/tests/dogtag/pytest-ansible/installation/host
fe6b0b
new file mode 100644
fe6b0b
index 0000000..056033d
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/host
fe6b0b
@@ -0,0 +1,2 @@
fe6b0b
+[master]
fe6b0b
+10.8.52.99
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/main.yml b/tests/dogtag/pytest-ansible/installation/main.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..41d4b66
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/main.yml
fe6b0b
@@ -0,0 +1,11 @@
fe6b0b
+# Configure cosmos repo and install all pre-requisites on Jenkins slave.
fe6b0b
+# Git clone and install ipa-pytests on Jenkins slave.
fe6b0b
+- hosts: localhost
fe6b0b
+  gather_facts: true
fe6b0b
+  roles:
fe6b0b
+  - Test_Trigger
fe6b0b
+
fe6b0b
+# Git clone and install ipa-pytests on all SUT
fe6b0b
+- hosts: master
fe6b0b
+  roles:
fe6b0b
+  - Test_Execution
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/config_templates/ansible_constants.py b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/config_templates/ansible_constants.py
fe6b0b
new file mode 100644
fe6b0b
index 0000000..ccb19b6
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/config_templates/ansible_constants.py
fe6b0b
@@ -0,0 +1,52 @@
fe6b0b
+#common to all subsystems
fe6b0b
+CLIENT_PKCS12_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DIR_PASSWORD = 'Secret123'
fe6b0b
+BACKUP_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DATABASE_PASSWORD = 'Secret123'
fe6b0b
+#CA Instance
fe6b0b
+CA_HTTPS_PORT = '20443'
fe6b0b
+CA_HTTP_PORT = '20080'
fe6b0b
+CA_AJP_PORT = '20009'
fe6b0b
+CA_TOMCAT_PORT = '20005'
fe6b0b
+CA_CLIENT_DIR = '/opt/topology-CA'
fe6b0b
+CA_INSTANCE_NAME = 'topology-CA'
fe6b0b
+SECURITY_DOMAIN_PASSWORD = 'Secret123'
fe6b0b
+CA_PASSWORD = 'Secret123'
fe6b0b
+CA_SECURITY_DOMAIN_NAME = 'topology_Foobarmaster.org'
fe6b0b
+CA_ADMIN_USERNAME = 'caadmin'
fe6b0b
+CA_ADMIN_NICK = 'PKI CA Administrator for Example.Org'
fe6b0b
+#KRA Instance
fe6b0b
+KRA_INSTANCE_NAME = 'topology-KRA'
fe6b0b
+KRA_HTTPS_PORT = 21443
fe6b0b
+KRA_HTTP_PORT = 21080
fe6b0b
+KRA_AJP_PORT = 21009
fe6b0b
+KRA_TOMCAT_PORT = 21005
fe6b0b
+KRA_PASSWORD = 'Secret123'
fe6b0b
+KRA_CLIENT_DIR = '/opt/topology-KRA'
fe6b0b
+KRA_ADMIN_NICK = 'PKI KRA Administrator for Example.Org'
fe6b0b
+#OCSP Instance
fe6b0b
+OCSP_INSTANCE_NAME = 'topology-OCSP'
fe6b0b
+OCSP_HTTPS_PORT = 22443
fe6b0b
+OCSP_HTTP_PORT = 22080
fe6b0b
+OCSP_AJP_PORT = 22009
fe6b0b
+OCSP_TOMCAT_PORT = 22005
fe6b0b
+OCSP_PASSWORD = 'Secret123'
fe6b0b
+OCSP_CLIENT_DIR = '/opt/topology-OCSP'
fe6b0b
+OCSP_ADMIN_NICK = 'PKI OCSP Administrator for Example.Org'
fe6b0b
+#TKS Instance
fe6b0b
+TKS_INSTANCE_NAME = 'topology-TKS'
fe6b0b
+TKS_HTTPS_PORT = 23443
fe6b0b
+TKS_HTTP_PORT = 23080
fe6b0b
+TKS_AJP_PORT = 23009
fe6b0b
+TKS_TOMCAT_PORT = 23005
fe6b0b
+TKS_PASSWORD = 'Secret123'
fe6b0b
+TKS_CLIENT_DIR = '/opt/topology-TKS'
fe6b0b
+#TPS instance
fe6b0b
+TPS_INSTANCE_NAME = 'topology-TPS'
fe6b0b
+TPS_HTTPS_PORT = '25443'
fe6b0b
+TPS_HTTP_PORT = '25080'
fe6b0b
+TPS_AJP_PORT = '25009'
fe6b0b
+TPS_TOMCAT_PORT = '25005'
fe6b0b
+TPS_PASSWORD = 'Secret123'
fe6b0b
+TPS_CLIENT_DIR = '/opt/topology-TPS'
fe6b0b
+TPS_ADMIN_NICK = 'PKI TPS Administrator for Example.Org'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/test/script b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/test/script
fe6b0b
new file mode 100755
fe6b0b
index 0000000..c98e4ae
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/files/test/script
fe6b0b
@@ -0,0 +1,79 @@
fe6b0b
+#!/bin/sh
fe6b0b
+#Generate Noise using Openssl
fe6b0b
+echo "Defining variables "
fe6b0b
+tks_password="/tmp/tkspassword.txt"
fe6b0b
+tps_password="/tmp/tpspassword.txt"
fe6b0b
+tks_alias="/var/lib/pki/$1-TKS/alias"
fe6b0b
+tps_alias="/var/lib/pki/$1-TPS/alias"
fe6b0b
+tks_noise="/tmp/tks_noise"
fe6b0b
+tks_shared_secret="sharedSecret"
fe6b0b
+tks_conf="/var/lib/pki/$1-TKS/tks/conf/CS.cfg"
fe6b0b
+tps_conf="/var/lib/pki/$1-TPS/tps/conf/CS.cfg"
fe6b0b
+tps_input_file="/tmp/tps-input.txt"
fe6b0b
+tks_secret_output="/tmp/secret"
fe6b0b
+tks_input_file="/tmp/tks-input.txt"
fe6b0b
+tks_input="proceed\r\n"
fe6b0b
+tks_secret_output="/tmp/sharedSecret.out"
fe6b0b
+tps_key_import_status="/tmp/sharedSecretImport.out"
fe6b0b
+echo "proceed\r\n" > $tks_input_file
fe6b0b
+echo "Generate Noise using OpenSSL"
fe6b0b
+openssl rand -hex 2048 |  perl -p -e 's/\n//' > $tks_noise
fe6b0b
+cat /var/lib/pki/$1-TKS/conf/password.conf | sed 's/^internal=//' > $tks_password
fe6b0b
+cat /var/lib/pki/$1-TPS/conf/password.conf | sed 's/^internal=//' > $tps_password
fe6b0b
+
fe6b0b
+echo "Stopping TKS  & TPS instance"
fe6b0b
+systemctl stop pki-tomcatd@$1-TKS.service
fe6b0b
+systemctl stop pki-tomcatd@$1-TPS.service
fe6b0b
+echo "Generating shared secret"
fe6b0b
+/usr/bin/tkstool -D -d $tks_alias -n "TPS-`hostname`-25443 sharedSecret" -f $tks_password
fe6b0b
+/usr/bin/tkstool -T -d $tks_alias -n $tks_shared_secret -f $tks_password -z $tks_noise > $tks_secret_output < $tks_input_file
fe6b0b
+/usr/bin/tkstool -L -d $tks_alias -n $tks_shared_secret -f $tks_password > /tmp/sharedSecretList1.out
fe6b0b
+grep "$tks_shared_secret" /tmp/sharedSecretList1.out
fe6b0b
+first_session_tmp1=$(cat $tks_secret_output | grep -A1 "first\ssession\skey\sshare:")
fe6b0b
+first_session_tmp2=$(echo $first_session_tmp1 | sed 's/^first session key share://')
fe6b0b
+first_session_key=$(echo ${first_session_tmp2%% })
fe6b0b
+first_session_KCV_tmp1=$(cat $tks_secret_output | grep "first\ssession\skey\sshare\sKCV:")
fe6b0b
+first_session_KCV_tmp2=$(echo $first_session_KCV_tmp1 | sed 's/^first session key share KCV://')
fe6b0b
+first_session_KCV_key=$(echo ${first_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+second_session_tmp1=$(cat $tks_secret_output | grep -A1 "second\ssession\skey\sshare:")
fe6b0b
+second_session_tmp2=$(echo $second_session_tmp1 | sed 's/^second session key share://')
fe6b0b
+second_session_key=$(echo ${second_session_tmp2%% })
fe6b0b
+second_session_KCV_tmp1=$(cat $tks_secret_output | grep "second\ssession\skey\sshare\sKCV:")
fe6b0b
+second_session_KCV_tmp2=$(echo $second_session_KCV_tmp1 | sed 's/^second session key share KCV://')
fe6b0b
+second_session_KCV_key=$(echo ${second_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+third_session_tmp1=$(cat $tks_secret_output | grep -A1 "third\ssession\skey\sshare:")
fe6b0b
+third_session_tmp2=$(echo $third_session_tmp1 | sed 's/^third session key share://')
fe6b0b
+third_session_key=$(echo ${third_session_tmp2%% })
fe6b0b
+third_session_KCV_tmp1=$(cat $tks_secret_output | grep "third\ssession\skey\sshare\sKCV:")
fe6b0b
+third_session_KCV_tmp2=$(echo $third_session_KCV_tmp1 | sed 's/^third session key share KCV://')
fe6b0b
+third_session_KCV_key=$(echo ${third_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+sed -i -e "/tps.0.nickname=/s/=.*/=$tks_shared_secret/g" $tks_conf
fe6b0b
+sed -i -e "/tks.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tks_conf
fe6b0b
+echo "Restart $1-TKS instance"
fe6b0b
+systemctl restart pki-tomcatd@$1-TKS.service
fe6b0b
+echo "proceed\r\n" > $tps_input_file
fe6b0b
+echo "$first_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$first_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "$second_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$second_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "$third_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$third_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+
fe6b0b
+/usr/bin/tkstool -I -d $tps_alias -n $tks_shared_secret -f $tps_password < $tps_input_file > $tps_key_import_status
fe6b0b
+/usr/bin/tkstool -L -d $tps_alias -n $tks_shared_secret -f $tps_password > /tmp/sharedSecretList2.out
fe6b0b
+grep "$tks_shared_secret" /tmp/sharedSecretList2.out
fe6b0b
+sed -i -e "/tps.connector.tks1.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tps_conf
fe6b0b
+sed -i -e "/conn.tks1.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tps_conf
fe6b0b
+echo "Restart $1-TPS instance"
fe6b0b
+systemctl restart pki-tomcatd@$1-TPS.service
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/main.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/main.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..3342a9a
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/main.yml
fe6b0b
@@ -0,0 +1,3 @@
fe6b0b
+- name: Inclue pki-core handlers
fe6b0b
+  include: pki-core.yml
fe6b0b
+  tags: pki-core
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/pki-core.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/pki-core.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..ed22477
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/handlers/pki-core.yml
fe6b0b
@@ -0,0 +1,54 @@
fe6b0b
+- name: STOPCA
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-CA
fe6b0b
+    state: stopped
fe6b0b
+
fe6b0b
+- name: STARTCA
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-CA
fe6b0b
+    state: started
fe6b0b
+
fe6b0b
+- name: STOPKRA
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-KRA
fe6b0b
+    state: stopped
fe6b0b
+
fe6b0b
+- name: STARTKRA
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-KRA
fe6b0b
+    state: started
fe6b0b
+
fe6b0b
+- name: STOPOCSP
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-OCSP
fe6b0b
+    state: stopped
fe6b0b
+
fe6b0b
+- name: STARTOCSP
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-OCSP
fe6b0b
+    state: started
fe6b0b
+
fe6b0b
+- name: STOPTKS
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-TKS
fe6b0b
+    state: stopped
fe6b0b
+
fe6b0b
+- name: STARTTKS
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-TKS
fe6b0b
+    state: started
fe6b0b
+
fe6b0b
+- name: STOPTPS
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-TPS
fe6b0b
+    state: stopped
fe6b0b
+
fe6b0b
+- name: STARTTPS
fe6b0b
+  service:
fe6b0b
+    name: pki-tomcatd@{{ topology }}-TPS
fe6b0b
+    state: started
fe6b0b
+
fe6b0b
+- name: INC_CONSTANTS
fe6b0b
+  include_vars:
fe6b0b
+    file: /tmp/test_dir/constants.yml
fe6b0b
+    name: variable
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ca.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ca.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..a1de87d
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ca.yml
fe6b0b
@@ -0,0 +1,18 @@
fe6b0b
+- name: Install CA master
fe6b0b
+  shell: pkispawn -s CA -f /tmp/test_dir/ca.cfg
fe6b0b
+
fe6b0b
+- name : Stopping CA Subsystem
fe6b0b
+  shell: systemctl stop pki-tomcatd@{{ topology }}-CA.service
fe6b0b
+
fe6b0b
+- name: Enable SignedAudit for Subsystem
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-CA/ca/CS.cfg regexp="log.instance.SignedAudit.logSigning=false" replace="log.instance.SignedAudit.logSigning=true"
fe6b0b
+
fe6b0b
+- name: Getting certificate nickname for CA CS.cfg
fe6b0b
+  shell: grep "ca.ocsp_signing.nickname" /etc/pki/{{ topology }}-CA/ca/CS.cfg |awk -F"=" ' { print $2 } '
fe6b0b
+  register: nickname_ocsp
fe6b0b
+
fe6b0b
+- name: Importing client certificate for OCSP
fe6b0b
+  shell: certutil -L -d /var/lib/pki/{{ topology }}-CA/alias -n "{{ nickname_ocsp.stdout }}" -a > /tmp/test_dir/ocsp_signing.crt
fe6b0b
+
fe6b0b
+- name : Starting CA Subsystem
fe6b0b
+  shell: systemctl start pki-tomcatd@{{ topology }}-CA.service
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_common.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_common.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..ac44bc5
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_common.yml
fe6b0b
@@ -0,0 +1,77 @@
fe6b0b
+- name: Disable firewalld before LDAP and Subsystem installation
fe6b0b
+  systemd: state=stopped name=firewalld
fe6b0b
+
fe6b0b
+- name : Set hostname for machines Bydefault we choose pki1 for master and pki2 for clones.
fe6b0b
+  hostname: name=pki1.example.com
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+- name: Install a required package for modify hostname task below
fe6b0b
+  dnf: pkg={{item}} state=latest
fe6b0b
+  with_items:
fe6b0b
+    - libselinux-python
fe6b0b
+  when: ansible_distribution == "Fedora"
fe6b0b
+
fe6b0b
+- name : Modify hostname for master in  /etc/hosts
fe6b0b
+  lineinfile: dest=/etc/hosts regexp='.*{{ inventory_hostname }}$' create=yes insertafter=EOF line="{{ inventory_hostname }} {{ansible_fqdn}}" state=present
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+
fe6b0b
+- name : fetch file in  master in  /etc/hosts
fe6b0b
+  fetch: src=/etc/hosts dest=/etc/ flat=yes validate_checksum=no
fe6b0b
+  tags: platform-ci
fe6b0b
+  
fe6b0b
+- name: Install list of packages for CS Master for Redhat
fe6b0b
+  yum : pkg={{item}} state=latest
fe6b0b
+  with_items:
fe6b0b
+    - redhat-pki
fe6b0b
+    - redhat-pki-console-theme
fe6b0b
+    - redhat-pki-server-theme
fe6b0b
+    - pki-console
fe6b0b
+    - 389-ds-base
fe6b0b
+    - pki-ca
fe6b0b
+    - pki-kra
fe6b0b
+    - pki-ocsp
fe6b0b
+    - pki-tks
fe6b0b
+    - pki-tps
fe6b0b
+    - policycoreutils-python
fe6b0b
+    - expect
fe6b0b
+    - libselinux-python
fe6b0b
+  when: ansible_distribution == "RedHat"
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+- name: Install list of packages for CS Master for Fedora
fe6b0b
+  dnf : pkg={{item}} state=latest
fe6b0b
+  with_items:
fe6b0b
+    - 389-ds-base
fe6b0b
+    - dogtag-pki
fe6b0b
+    - dogtag-pki-console-theme
fe6b0b
+    - dogtag-pki-server-theme
fe6b0b
+    - policycoreutils-python
fe6b0b
+    - expect
fe6b0b
+  when: ansible_distribution == "Fedora"
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+- name: Check for Removed dependency from mod_revocator and mod_nss.If failes refer BZ 1295276 
fe6b0b
+  command: rpm -q {{item}}
fe6b0b
+  with_items:
fe6b0b
+    - mod_revocator
fe6b0b
+    - mod_nss
fe6b0b
+  register: rpm_check
fe6b0b
+  failed_when: "rpm_check.rc == 0"
fe6b0b
+
fe6b0b
+- name: Check for Removed dependency of perl from pki-server.If fails, refer BZ 1305769
fe6b0b
+  command: rpm -qR pki-server | grep perl
fe6b0b
+  register: rpm_check
fe6b0b
+  failed_when: "rpm_check.rc == 0"
fe6b0b
+
fe6b0b
+- name: Copying templates to /tmp folder
fe6b0b
+  copy : src=/tmp/test_dir  dest=/tmp/
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+- name: Making constants.py file compatable for including as vars.
fe6b0b
+  shell: sed -e "s/ =/:/g;s/'//g" /tmp/test_dir/constants.py > /tmp/test_dir/constants.yml
fe6b0b
+
fe6b0b
+- name: Fetch the file
fe6b0b
+  fetch: src=/tmp/test_dir/constants.yml dest=/tmp/test_dir/ flat=yes validate_checksum=no
fe6b0b
+
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_kra.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_kra.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..670fa5e
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_kra.yml
fe6b0b
@@ -0,0 +1,24 @@
fe6b0b
+- name: Install KRA master
fe6b0b
+  shell: pkispawn -s KRA -f /tmp/test_dir/kra.cfg
fe6b0b
+
fe6b0b
+- name : Stopping KRA Subsystem
fe6b0b
+  shell: echo "Stopping Subsystem for enabling Audit logging"
fe6b0b
+  notify:
fe6b0b
+    - STOPKRA
fe6b0b
+    - INC_CONSTANTS
fe6b0b
+
fe6b0b
+- meta: flush_handlers
fe6b0b
+
fe6b0b
+- name: Enable SignedAudit
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-KRA/kra/CS.cfg regexp="log.instance.SignedAudit.logSigning=false" replace="log.instance.SignedAudit.logSigning=true"
fe6b0b
+
fe6b0b
+- name: Enable OCSP for KRA
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-KRA/server.xml regexp='enableOCSP="false"' replace='enableOCSP="true"'
fe6b0b
+
fe6b0b
+- name: Pointing KRA to correct OCSP port
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-KRA/server.xml regexp='([0-9]+)/ca/ocsp' replace={{ variable.CA_HTTP_PORT }}/ca/ocsp
fe6b0b
+
fe6b0b
+- name: Importing OCSP certificate in kra nssdb
fe6b0b
+  shell: certutil -A -d /etc/pki/{{ topology }}-KRA/alias -n "ocspSigningCert cert-pki-ca" -t "C,," -i  /tmp/test_dir/ocsp_signing.crt
fe6b0b
+  notify:
fe6b0b
+    - STARTKRA
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ldap.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ldap.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..01d867b
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ldap.yml
fe6b0b
@@ -0,0 +1,20 @@
fe6b0b
+
fe6b0b
+- name: Setup DS Service
fe6b0b
+  shell: setup-ds.pl --silent --file=/tmp/test_dir/ldap.cfg
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology  == "topology-05" or topology == "topology-ecc"
fe6b0b
+
fe6b0b
+- name: Setup DS Service
fe6b0b
+  shell: setup-ds.pl --silent --file=/tmp/test_dir/ldap_kra.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Setup DS Service
fe6b0b
+  shell: setup-ds.pl --silent --file=/tmp/test_dir/ldap_ocsp.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Setup DS Service
fe6b0b
+  shell: setup-ds.pl --silent --file=/tmp/test_dir/ldap_tks.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Setup DS Service
fe6b0b
+  shell: setup-ds.pl --silent --file=/tmp/test_dir/ldap_tps.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ocsp.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ocsp.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..373a16c
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_ocsp.yml
fe6b0b
@@ -0,0 +1,17 @@
fe6b0b
+- name: sleep
fe6b0b
+  shell: sleep 5s
fe6b0b
+  
fe6b0b
+- name: Install OCSP master
fe6b0b
+  shell: pkispawn -s OCSP -f /tmp/test_dir/ocsp.cfg
fe6b0b
+
fe6b0b
+- name : Stopping OCSP Subsystem
fe6b0b
+  shell: echo "Stopping Subsystem for enabling Audit logging"
fe6b0b
+  notify:
fe6b0b
+    - STOPOCSP
fe6b0b
+
fe6b0b
+- name: Enable SignedAudit
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-OCSP/ocsp/CS.cfg regexp="log.instance.SignedAudit.logSigning=false" replace="log.instance.SignedAudit.logSigning=true"
fe6b0b
+  notify:
fe6b0b
+    - STARTOCSP
fe6b0b
+
fe6b0b
+- meta: flush_handlers
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_shared.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_shared.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..dee083c
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_shared.yml
fe6b0b
@@ -0,0 +1,14 @@
fe6b0b
+- name: Install CA master
fe6b0b
+  shell: pkispawn -s CA -f /tmp/test_dir/ca.cfg
fe6b0b
+
fe6b0b
+- name: Install KRA master
fe6b0b
+  shell: pkispawn -s KRA -f /tmp/test_dir/kra.cfg
fe6b0b
+
fe6b0b
+- name: Install OCSP master
fe6b0b
+  shell: pkispawn -s OCSP -f /tmp/test_dir/ocsp.cfg
fe6b0b
+
fe6b0b
+- name: Install TKS master
fe6b0b
+  shell: pkispawn -s TKS -f /tmp/test_dir/tks.cfg
fe6b0b
+
fe6b0b
+- name: Install TPS master
fe6b0b
+  shell: pkispawn -s TPS -f /tmp/test_dir/tps.cfg
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_sharedsecret.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_sharedsecret.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..f2e4de4
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_sharedsecret.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+- name: Shared Secret sharing between TPS and TKS
fe6b0b
+  script: test/script {{ topology }}
fe6b0b
+  when: topology  == "topology-02" or topology  == "topology-05"
fe6b0b
+  tags: platform-ci
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tks.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tks.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..78295d1
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tks.yml
fe6b0b
@@ -0,0 +1,30 @@
fe6b0b
+- name: Install TKS master
fe6b0b
+  shell: pkispawn -s TKS -f /tmp/test_dir/tks.cfg
fe6b0b
+
fe6b0b
+- name : Stopping TKS Subsystem
fe6b0b
+  shell: echo "Stopping Subsystem for enabling Audit logging"
fe6b0b
+  notify:
fe6b0b
+    - STOPTKS
fe6b0b
+    - INC_CONSTANTS
fe6b0b
+
fe6b0b
+- meta: flush_handlers
fe6b0b
+
fe6b0b
+- name: Enable SignedAudit
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TKS/tks/CS.cfg regexp="log.instance.SignedAudit.logSigning=false" replace="log.instance.SignedAudit.logSigning=true"
fe6b0b
+
fe6b0b
+- name: Enable OCSP for TKS
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TKS/server.xml regexp='enableOCSP="false"' replace='enableOCSP="true"'
fe6b0b
+
fe6b0b
+- name: Pointing TKS to correct OCSP port
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TKS/server.xml regexp='([0-9]+)/ca/ocsp' replace={{ variable.CA_HTTP_PORT }}/ca/ocsp
fe6b0b
+
fe6b0b
+- name: Importing OCSP certificate in TKS nssdb
fe6b0b
+  shell: certutil -A -d /etc/pki/{{ topology }}-TKS/alias -n "ocspSigningCert cert-pki-ca" -t "C,," -i  /tmp/test_dir/ocsp_signing.crt
fe6b0b
+  notify:
fe6b0b
+    - STARTTKS
fe6b0b
+
fe6b0b
+- meta: flush_handlers
fe6b0b
+
fe6b0b
+- name: Sleep for a while to start TKS
fe6b0b
+  shell: sleep 3s
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tps.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tps.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..5aa1021
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/configure_tps.yml
fe6b0b
@@ -0,0 +1,24 @@
fe6b0b
+- name: Install TPS master
fe6b0b
+  shell: pkispawn -s TPS -f /tmp/test_dir/tps.cfg
fe6b0b
+
fe6b0b
+- name : Stopping TPS Subsystem
fe6b0b
+  shell: echo "Stopping Subsystem for enabling Audit logging"
fe6b0b
+  notify:
fe6b0b
+    - STOPTPS
fe6b0b
+    - INC_CONSTANTS
fe6b0b
+
fe6b0b
+- meta: flush_handlers
fe6b0b
+
fe6b0b
+- name: Enable SignedAudit
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TPS/tps/CS.cfg regexp="log.instance.SignedAudit.logSigning=false" replace="log.instance.SignedAudit.logSigning=true"
fe6b0b
+
fe6b0b
+- name: Enable OCSP for TPS
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TPS/server.xml regexp='enableOCSP="false"' replace='enableOCSP="true"'
fe6b0b
+
fe6b0b
+- name: Pointing TPS to correct OCSP port
fe6b0b
+  replace: dest=/etc/pki/{{ topology }}-TPS/server.xml regexp='([0-9]+)/ca/ocsp' replace={{ variable.CA_HTTP_PORT }}/ca/ocsp
fe6b0b
+
fe6b0b
+- name: Importing OCSP certificate in tps nssdb
fe6b0b
+  shell: certutil -A -d /etc/pki/{{ topology }}-TPS/alias -n "ocspSigningCert cert-pki-ca" -t "C,," -i  /tmp/test_dir/ocsp_signing.crt
fe6b0b
+  notify:
fe6b0b
+    - STARTTPS
fe6b0b
\ No newline at end of file
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/main.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/main.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..2aa432b
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Execution/tasks/main.yml
fe6b0b
@@ -0,0 +1,19 @@
fe6b0b
+---
fe6b0b
+- include: configure_common.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_ldap.yml
fe6b0b
+  when:  topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_shared.yml
fe6b0b
+  when: topology  == "topology-01"
fe6b0b
+- include: configure_ca.yml
fe6b0b
+  when: topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_ocsp.yml
fe6b0b
+  when: topology == "topology-02" or topology == "topology-03" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_kra.yml
fe6b0b
+  when: topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_tks.yml
fe6b0b
+  when: topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05"
fe6b0b
+- include: configure_tps.yml
fe6b0b
+  when: topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05"
fe6b0b
+- include: configure_sharedsecret.yml
fe6b0b
+  when: topology  == "topology-02" or topology == "topology-04" or topology == "topology-05"
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/config_templates/ansible_constants.py b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/config_templates/ansible_constants.py
fe6b0b
new file mode 100644
fe6b0b
index 0000000..ccb19b6
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/config_templates/ansible_constants.py
fe6b0b
@@ -0,0 +1,52 @@
fe6b0b
+#common to all subsystems
fe6b0b
+CLIENT_PKCS12_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DIR_PASSWORD = 'Secret123'
fe6b0b
+BACKUP_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DATABASE_PASSWORD = 'Secret123'
fe6b0b
+#CA Instance
fe6b0b
+CA_HTTPS_PORT = '20443'
fe6b0b
+CA_HTTP_PORT = '20080'
fe6b0b
+CA_AJP_PORT = '20009'
fe6b0b
+CA_TOMCAT_PORT = '20005'
fe6b0b
+CA_CLIENT_DIR = '/opt/topology-CA'
fe6b0b
+CA_INSTANCE_NAME = 'topology-CA'
fe6b0b
+SECURITY_DOMAIN_PASSWORD = 'Secret123'
fe6b0b
+CA_PASSWORD = 'Secret123'
fe6b0b
+CA_SECURITY_DOMAIN_NAME = 'topology_Foobarmaster.org'
fe6b0b
+CA_ADMIN_USERNAME = 'caadmin'
fe6b0b
+CA_ADMIN_NICK = 'PKI CA Administrator for Example.Org'
fe6b0b
+#KRA Instance
fe6b0b
+KRA_INSTANCE_NAME = 'topology-KRA'
fe6b0b
+KRA_HTTPS_PORT = 21443
fe6b0b
+KRA_HTTP_PORT = 21080
fe6b0b
+KRA_AJP_PORT = 21009
fe6b0b
+KRA_TOMCAT_PORT = 21005
fe6b0b
+KRA_PASSWORD = 'Secret123'
fe6b0b
+KRA_CLIENT_DIR = '/opt/topology-KRA'
fe6b0b
+KRA_ADMIN_NICK = 'PKI KRA Administrator for Example.Org'
fe6b0b
+#OCSP Instance
fe6b0b
+OCSP_INSTANCE_NAME = 'topology-OCSP'
fe6b0b
+OCSP_HTTPS_PORT = 22443
fe6b0b
+OCSP_HTTP_PORT = 22080
fe6b0b
+OCSP_AJP_PORT = 22009
fe6b0b
+OCSP_TOMCAT_PORT = 22005
fe6b0b
+OCSP_PASSWORD = 'Secret123'
fe6b0b
+OCSP_CLIENT_DIR = '/opt/topology-OCSP'
fe6b0b
+OCSP_ADMIN_NICK = 'PKI OCSP Administrator for Example.Org'
fe6b0b
+#TKS Instance
fe6b0b
+TKS_INSTANCE_NAME = 'topology-TKS'
fe6b0b
+TKS_HTTPS_PORT = 23443
fe6b0b
+TKS_HTTP_PORT = 23080
fe6b0b
+TKS_AJP_PORT = 23009
fe6b0b
+TKS_TOMCAT_PORT = 23005
fe6b0b
+TKS_PASSWORD = 'Secret123'
fe6b0b
+TKS_CLIENT_DIR = '/opt/topology-TKS'
fe6b0b
+#TPS instance
fe6b0b
+TPS_INSTANCE_NAME = 'topology-TPS'
fe6b0b
+TPS_HTTPS_PORT = '25443'
fe6b0b
+TPS_HTTP_PORT = '25080'
fe6b0b
+TPS_AJP_PORT = '25009'
fe6b0b
+TPS_TOMCAT_PORT = '25005'
fe6b0b
+TPS_PASSWORD = 'Secret123'
fe6b0b
+TPS_CLIENT_DIR = '/opt/topology-TPS'
fe6b0b
+TPS_ADMIN_NICK = 'PKI TPS Administrator for Example.Org'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ca.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ca.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..e286927
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ca.cfg
fe6b0b
@@ -0,0 +1,38 @@
fe6b0b
+[DEFAULT]
fe6b0b
+pki_instance_name = topology-CA
fe6b0b
+pki_https_port = capki_https_port
fe6b0b
+pki_http_port = capki_http_port
fe6b0b
+pki_token_password = Secret123
fe6b0b
+pki_admin_password = Secret123
fe6b0b
+pki_hostname = SERVERNAME
fe6b0b
+pki_security_domain_name = topology_Foobarmaster.org
fe6b0b
+pki_security_domain_password = Secret123
fe6b0b
+pki_client_dir = /opt/topology-CA
fe6b0b
+pki_client_pkcs12_password = Secret123
fe6b0b
+pki_backup_keys = True
fe6b0b
+pki_backup_password = Secret123
fe6b0b
+pki_ds_password = Secret123
fe6b0b
+pki_ds_ldap_port = ldapServerPort
fe6b0b
+pki_ssl_server_key_algorithm=SHA512withRSA
fe6b0b
+pki_ssl_server_key_size=2048
fe6b0b
+pki_ssl_server_key_type=rsa
fe6b0b
+pki_subsystem_key_algorithm=SHA512withRSA
fe6b0b
+pki_subsystem_key_size=2048
fe6b0b
+pki_subsystem_key_type=rsa
fe6b0b
+
fe6b0b
+[Tomcat]
fe6b0b
+pki_ajp_port = capki_ajp_port
fe6b0b
+pki_tomcat_server_port = capki_tomcat_port
fe6b0b
+
fe6b0b
+[CA]
fe6b0b
+pki_import_admin_cert = False
fe6b0b
+pki_ds_hostname = SERVERNAME
fe6b0b
+pki_admin_nickname = PKI CA Administrator for Example.Org
fe6b0b
+pki_ca_signing_key_algorithm=SHA512withRSA
fe6b0b
+pki_ca_signing_key_size=2048
fe6b0b
+pki_ca_signing_key_type=rsa
fe6b0b
+pki_ca_signing_signing_algorithm=SHA512withRSA
fe6b0b
+pki_ocsp_signing_key_algorithm=SHA512withRSA
fe6b0b
+pki_ocsp_signing_key_size=2048
fe6b0b
+pki_ocsp_signing_key_type=rsa
fe6b0b
+pki_ocsp_signing_signing_algorithm=SHA512withRSA
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/constants.py b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/constants.py
fe6b0b
new file mode 100644
fe6b0b
index 0000000..8df625c
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/constants.py
fe6b0b
@@ -0,0 +1,67 @@
fe6b0b
+#common to all subsystems
fe6b0b
+CLIENT_PKCS12_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DIR_PASSWORD = 'Secret123'
fe6b0b
+BACKUP_PASSWORD = 'Secret123'
fe6b0b
+CLIENT_DATABASE_PASSWORD = 'Secret123'
fe6b0b
+#CA Instance
fe6b0b
+CA_HTTPS_PORT = 'capki_https_port'
fe6b0b
+CA_HTTP_PORT = 'capki_http_port'
fe6b0b
+CA_AJP_PORT = 'capki_ajp_port'
fe6b0b
+CA_TOMCAT_PORT = 'capki_tomcat_port'
fe6b0b
+CA_CLIENT_DIR = '/opt/topology-CA'
fe6b0b
+CA_INSTANCE_NAME = 'topology-CA'
fe6b0b
+SECURITY_DOMAIN_PASSWORD = 'Secret123'
fe6b0b
+CA_PASSWORD = 'Secret123'
fe6b0b
+CA_SECURITY_DOMAIN_NAME = 'topology_Foobarmaster.org'
fe6b0b
+CA_ADMIN_USERNAME = 'caadmin'
fe6b0b
+CA_ADMIN_NICK = 'PKI CA Administrator for Example.Org'
fe6b0b
+#KRA Instance
fe6b0b
+KRA_INSTANCE_NAME = 'topology-KRA'
fe6b0b
+KRA_HTTPS_PORT = 'krapki_https_port'
fe6b0b
+KRA_HTTP_PORT = 'krapki_http_port'
fe6b0b
+KRA_AJP_PORT = 'krapki_ajp_port'
fe6b0b
+KRA_TOMCAT_PORT = 'krapki_tomcat_server_port'
fe6b0b
+KRA_PASSWORD = 'Secret123'
fe6b0b
+KRA_CLIENT_DIR = '/opt/topology-KRA'
fe6b0b
+KRA_ADMIN_NICK = 'PKI KRA Administrator for Example.Org'
fe6b0b
+#OCSP Instance
fe6b0b
+OCSP_INSTANCE_NAME = 'topology-OCSP'
fe6b0b
+OCSP_HTTPS_PORT = 'ocsppki_https_port'
fe6b0b
+OCSP_HTTP_PORT = 'ocsppki_http_port'
fe6b0b
+OCSP_AJP_PORT = 'ocsppki_ajp_port'
fe6b0b
+OCSP_TOMCAT_PORT = 'ocsppki_tomcat_server_port'
fe6b0b
+OCSP_PASSWORD = 'Secret123'
fe6b0b
+OCSP_CLIENT_DIR = '/opt/topology-OCSP'
fe6b0b
+OCSP_ADMIN_NICK = 'PKI OCSP Administrator for Example.Org'
fe6b0b
+#TKS Instance
fe6b0b
+TKS_INSTANCE_NAME = 'topology-TKS'
fe6b0b
+TKS_HTTPS_PORT = 'tkspki_https_port'
fe6b0b
+TKS_HTTP_PORT = 'tkspki_http_port'
fe6b0b
+TKS_AJP_PORT = 'tkspki_ajp_port'
fe6b0b
+TKS_TOMCAT_PORT = 'tkspki_tomcat_server_port'
fe6b0b
+TKS_PASSWORD = 'Secret123'
fe6b0b
+TKS_CLIENT_DIR = '/opt/topology-TKS'
fe6b0b
+TKS_ADMIN_NICK = 'PKI TKS Administrator for Example.Org'
fe6b0b
+#TPS instance
fe6b0b
+TPS_INSTANCE_NAME = 'topology-TPS'
fe6b0b
+TPS_HTTPS_PORT = 'tpspki_https_port'
fe6b0b
+TPS_HTTP_PORT = 'tpspki_http_port'
fe6b0b
+TPS_AJP_PORT = 'tpspki_ajp_port'
fe6b0b
+TPS_TOMCAT_PORT = 'tpspki_tomcat_server_port'
fe6b0b
+TPS_PASSWORD = 'Secret123'
fe6b0b
+TPS_CLIENT_DIR = '/opt/topology-TPS'
fe6b0b
+TPS_ADMIN_NICK = 'PKI TPS Administrator for Example.Org'
fe6b0b
+#LDAP Details
fe6b0b
+LDAP_PORT = 'ldapServerPort'
fe6b0b
+LDAP_BIND_DN = 'cn=Directory Manager'
fe6b0b
+LDAP_PASSWD = 'Secret123'
fe6b0b
+LDAP_BASE_DN = 'dc=example,dc=org'
fe6b0b
+LDAP_KRA_PORT = 'ldapkraServerPort'
fe6b0b
+LDAP_OCSP_PORT = 'ldapocspServerPort'
fe6b0b
+LDAP_TKS_PORT = 'ldaptksServerPort'
fe6b0b
+LDAP_TPS_PORT = 'ldaptpsServerPort'
fe6b0b
+LDAP_USER = 'foobar'
fe6b0b
+LDAP_USER_ENROLL = 'testuser'
fe6b0b
+CUID = '40906145C76224192D2B'
fe6b0b
+CUID_01 = '40906145C76224192D11'
fe6b0b
+TPS_OPERATION = 'ra_enroll'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/kra.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/kra.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..fd46b09
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/kra.cfg
fe6b0b
@@ -0,0 +1,42 @@
fe6b0b
+[DEFAULT]
fe6b0b
+pki_instance_name = topology-KRA
fe6b0b
+pki_https_port = krapki_https_port
fe6b0b
+pki_http_port = krapki_http_port
fe6b0b
+pki_token_password = Secret123
fe6b0b
+pki_admin_password = Secret123
fe6b0b
+pki_hostname = SERVERNAME
fe6b0b
+pki_security_domain_hostname = SERVERNAME
fe6b0b
+pki_security_domain_https_port = secure_domain_port
fe6b0b
+pki_security_domain_name = topology_Foobarmaster.org
fe6b0b
+pki_security_domain_password = Secret123
fe6b0b
+pki_client_dir = /opt/topology-KRA
fe6b0b
+pki_client_pkcs12_password = Secret123
fe6b0b
+pki_backup_keys = True
fe6b0b
+pki_backup_password = Secret123
fe6b0b
+pki_ds_password = Secret123
fe6b0b
+pki_ds_ldap_port = ldapServerPort
fe6b0b
+pki_client_database_password = Secret123
fe6b0b
+pki_ssl_server_key_algorithm=SHA512withRSA
fe6b0b
+pki_ssl_server_key_size=2048
fe6b0b
+pki_ssl_server_key_type=rsa
fe6b0b
+pki_subsystem_key_algorithm=SHA512withRSA
fe6b0b
+pki_subsystem_key_size=2048
fe6b0b
+pki_subsystem_key_type=rsa
fe6b0b
+
fe6b0b
+[Tomcat]
fe6b0b
+pki_ajp_port = krapki_ajp_port
fe6b0b
+pki_tomcat_server_port = krapki_tomcat_server_port
fe6b0b
+
fe6b0b
+[KRA]
fe6b0b
+pki_import_admin_cert = False
fe6b0b
+pki_ds_hostname = SERVERNAME
fe6b0b
+pki_admin_nickname = PKI KRA Administrator for Example.Org
fe6b0b
+pki_storage_key_algorithm=SHA512withRSA
fe6b0b
+pki_storage_key_size=2048
fe6b0b
+pki_storage_key_type=rsa
fe6b0b
+pki_storage_signing_algorithm=SHA512withRSA
fe6b0b
+pki_transport_key_algorithm=SHA512withRSA
fe6b0b
+pki_transport_key_size=2048
fe6b0b
+pki_transport_key_type=rsa
fe6b0b
+pki_transport_signing_algorithm=SHA512withRSA
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ldap.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ldap.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..820efec
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ldap.cfg
fe6b0b
@@ -0,0 +1,12 @@
fe6b0b
+[General]
fe6b0b
+FullMachineName = SERVERNAME 
fe6b0b
+SuiteSpotUserID = nobody
fe6b0b
+SuiteSpotGroup = nobody
fe6b0b
+ConfigDirectoryAdminID = admin
fe6b0b
+
fe6b0b
+[slapd]
fe6b0b
+ServerIdentifier = topology-testingmaster
fe6b0b
+ServerPort = ldapServerPort 
fe6b0b
+Suffix = dc=example,dc=org
fe6b0b
+RootDN = CN=Directory Manager
fe6b0b
+RootDNPwd = Secret123
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ocsp.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ocsp.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..e553c32
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/ocsp.cfg
fe6b0b
@@ -0,0 +1,36 @@
fe6b0b
+[DEFAULT]
fe6b0b
+pki_instance_name = topology-OCSP
fe6b0b
+pki_https_port = ocsppki_https_port
fe6b0b
+pki_http_port = ocsppki_http_port
fe6b0b
+pki_token_password = Secret123
fe6b0b
+pki_admin_password = Secret123
fe6b0b
+pki_hostname = SERVERNAME
fe6b0b
+pki_security_domain_name = topology_Foobarmaster.org
fe6b0b
+pki_security_domain_password = Secret123
fe6b0b
+pki_security_domain_https_port = secure_domain_port
fe6b0b
+pki_client_dir = /opt/topology-OCSP
fe6b0b
+pki_client_pkcs12_password = Secret123
fe6b0b
+pki_backup_keys = True
fe6b0b
+pki_backup_password = Secret123
fe6b0b
+pki_ds_password = Secret123
fe6b0b
+pki_ds_ldap_port = ldapServerPort
fe6b0b
+pki_client_database_password = Secret123
fe6b0b
+pki_ssl_server_key_algorithm=SHA512withRSA
fe6b0b
+pki_ssl_server_key_size=2048
fe6b0b
+pki_ssl_server_key_type=rsa
fe6b0b
+pki_subsystem_key_algorithm=SHA512withRSA
fe6b0b
+pki_subsystem_key_size=2048
fe6b0b
+pki_subsystem_key_type=rsa
fe6b0b
+
fe6b0b
+[Tomcat]
fe6b0b
+pki_ajp_port = ocsppki_ajp_port
fe6b0b
+pki_tomcat_server_port = ocsppki_tomcat_server_port
fe6b0b
+
fe6b0b
+[OCSP]
fe6b0b
+pki_import_admin_cert = False
fe6b0b
+pki_ds_hostname = SERVERNAME
fe6b0b
+pki_admin_nickname= PKI OCSP Administrator for Example.Org
fe6b0b
+pki_ocsp_signing_key_algorithm=SHA512withRSA
fe6b0b
+pki_ocsp_signing_key_size=2048
fe6b0b
+pki_ocsp_signing_key_type=rsa
fe6b0b
+pki_ocsp_signing_signing_algorithm=SHA512withRSA
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/script b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/script
fe6b0b
new file mode 100755
fe6b0b
index 0000000..c98e4ae
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/script
fe6b0b
@@ -0,0 +1,79 @@
fe6b0b
+#!/bin/sh
fe6b0b
+#Generate Noise using Openssl
fe6b0b
+echo "Defining variables "
fe6b0b
+tks_password="/tmp/tkspassword.txt"
fe6b0b
+tps_password="/tmp/tpspassword.txt"
fe6b0b
+tks_alias="/var/lib/pki/$1-TKS/alias"
fe6b0b
+tps_alias="/var/lib/pki/$1-TPS/alias"
fe6b0b
+tks_noise="/tmp/tks_noise"
fe6b0b
+tks_shared_secret="sharedSecret"
fe6b0b
+tks_conf="/var/lib/pki/$1-TKS/tks/conf/CS.cfg"
fe6b0b
+tps_conf="/var/lib/pki/$1-TPS/tps/conf/CS.cfg"
fe6b0b
+tps_input_file="/tmp/tps-input.txt"
fe6b0b
+tks_secret_output="/tmp/secret"
fe6b0b
+tks_input_file="/tmp/tks-input.txt"
fe6b0b
+tks_input="proceed\r\n"
fe6b0b
+tks_secret_output="/tmp/sharedSecret.out"
fe6b0b
+tps_key_import_status="/tmp/sharedSecretImport.out"
fe6b0b
+echo "proceed\r\n" > $tks_input_file
fe6b0b
+echo "Generate Noise using OpenSSL"
fe6b0b
+openssl rand -hex 2048 |  perl -p -e 's/\n//' > $tks_noise
fe6b0b
+cat /var/lib/pki/$1-TKS/conf/password.conf | sed 's/^internal=//' > $tks_password
fe6b0b
+cat /var/lib/pki/$1-TPS/conf/password.conf | sed 's/^internal=//' > $tps_password
fe6b0b
+
fe6b0b
+echo "Stopping TKS  & TPS instance"
fe6b0b
+systemctl stop pki-tomcatd@$1-TKS.service
fe6b0b
+systemctl stop pki-tomcatd@$1-TPS.service
fe6b0b
+echo "Generating shared secret"
fe6b0b
+/usr/bin/tkstool -D -d $tks_alias -n "TPS-`hostname`-25443 sharedSecret" -f $tks_password
fe6b0b
+/usr/bin/tkstool -T -d $tks_alias -n $tks_shared_secret -f $tks_password -z $tks_noise > $tks_secret_output < $tks_input_file
fe6b0b
+/usr/bin/tkstool -L -d $tks_alias -n $tks_shared_secret -f $tks_password > /tmp/sharedSecretList1.out
fe6b0b
+grep "$tks_shared_secret" /tmp/sharedSecretList1.out
fe6b0b
+first_session_tmp1=$(cat $tks_secret_output | grep -A1 "first\ssession\skey\sshare:")
fe6b0b
+first_session_tmp2=$(echo $first_session_tmp1 | sed 's/^first session key share://')
fe6b0b
+first_session_key=$(echo ${first_session_tmp2%% })
fe6b0b
+first_session_KCV_tmp1=$(cat $tks_secret_output | grep "first\ssession\skey\sshare\sKCV:")
fe6b0b
+first_session_KCV_tmp2=$(echo $first_session_KCV_tmp1 | sed 's/^first session key share KCV://')
fe6b0b
+first_session_KCV_key=$(echo ${first_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+second_session_tmp1=$(cat $tks_secret_output | grep -A1 "second\ssession\skey\sshare:")
fe6b0b
+second_session_tmp2=$(echo $second_session_tmp1 | sed 's/^second session key share://')
fe6b0b
+second_session_key=$(echo ${second_session_tmp2%% })
fe6b0b
+second_session_KCV_tmp1=$(cat $tks_secret_output | grep "second\ssession\skey\sshare\sKCV:")
fe6b0b
+second_session_KCV_tmp2=$(echo $second_session_KCV_tmp1 | sed 's/^second session key share KCV://')
fe6b0b
+second_session_KCV_key=$(echo ${second_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+third_session_tmp1=$(cat $tks_secret_output | grep -A1 "third\ssession\skey\sshare:")
fe6b0b
+third_session_tmp2=$(echo $third_session_tmp1 | sed 's/^third session key share://')
fe6b0b
+third_session_key=$(echo ${third_session_tmp2%% })
fe6b0b
+third_session_KCV_tmp1=$(cat $tks_secret_output | grep "third\ssession\skey\sshare\sKCV:")
fe6b0b
+third_session_KCV_tmp2=$(echo $third_session_KCV_tmp1 | sed 's/^third session key share KCV://')
fe6b0b
+third_session_KCV_key=$(echo ${third_session_KCV_tmp2%% })
fe6b0b
+
fe6b0b
+sed -i -e "/tps.0.nickname=/s/=.*/=$tks_shared_secret/g" $tks_conf
fe6b0b
+sed -i -e "/tks.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tks_conf
fe6b0b
+echo "Restart $1-TKS instance"
fe6b0b
+systemctl restart pki-tomcatd@$1-TKS.service
fe6b0b
+echo "proceed\r\n" > $tps_input_file
fe6b0b
+echo "$first_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$first_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "$second_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$second_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+echo "$third_session_key\r\n" >> $tps_input_file
fe6b0b
+echo "\r\n" >> $tps_input_file
fe6b0b
+echo "$third_session_KCV_key\r\n" >> $tps_input_file
fe6b0b
+echo "proceed\r\n" >> $tps_input_file
fe6b0b
+
fe6b0b
+/usr/bin/tkstool -I -d $tps_alias -n $tks_shared_secret -f $tps_password < $tps_input_file > $tps_key_import_status
fe6b0b
+/usr/bin/tkstool -L -d $tps_alias -n $tks_shared_secret -f $tps_password > /tmp/sharedSecretList2.out
fe6b0b
+grep "$tks_shared_secret" /tmp/sharedSecretList2.out
fe6b0b
+sed -i -e "/tps.connector.tks1.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tps_conf
fe6b0b
+sed -i -e "/conn.tks1.tksSharedSymKeyName=/s/=.*/=$tks_shared_secret/g" $tps_conf
fe6b0b
+echo "Restart $1-TPS instance"
fe6b0b
+systemctl restart pki-tomcatd@$1-TPS.service
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tks.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tks.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..479bbbf
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tks.cfg
fe6b0b
@@ -0,0 +1,26 @@
fe6b0b
+[DEFAULT]
fe6b0b
+pki_instance_name = topology-TKS
fe6b0b
+pki_https_port = tkspki_https_port
fe6b0b
+pki_http_port = tkspki_http_port
fe6b0b
+pki_token_password = Secret123
fe6b0b
+pki_admin_password = Secret123
fe6b0b
+pki_hostname = SERVERNAME
fe6b0b
+pki_security_domain_name = topology_Foobarmaster.org
fe6b0b
+pki_security_domain_password = Secret123
fe6b0b
+pki_security_domain_https_port = secure_domain_port
fe6b0b
+pki_client_dir = /opt/topology-TKS
fe6b0b
+pki_client_pkcs12_password = Secret123
fe6b0b
+pki_backup_keys = True
fe6b0b
+pki_backup_password = Secret123
fe6b0b
+pki_ds_password = Secret123
fe6b0b
+pki_ds_ldap_port = ldapServerPort
fe6b0b
+pki_client_database_password = Secret123
fe6b0b
+
fe6b0b
+[Tomcat]
fe6b0b
+pki_ajp_port = tkspki_ajp_port
fe6b0b
+pki_tomcat_server_port = tkspki_tomcat_server_port
fe6b0b
+
fe6b0b
+[TKS]
fe6b0b
+pki_import_admin_cert = False
fe6b0b
+pki_ds_hostname = SERVERNAME
fe6b0b
+pki_admin_nickname= PKI TKS Administrator for Example.Org
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tps.cfg b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tps.cfg
fe6b0b
new file mode 100644
fe6b0b
index 0000000..b878abc
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/files/test/tps.cfg
fe6b0b
@@ -0,0 +1,34 @@
fe6b0b
+[DEFAULT]
fe6b0b
+pki_instance_name = topology-TPS
fe6b0b
+pki_https_port = tpspki_https_port
fe6b0b
+pki_http_port = tpspki_http_port
fe6b0b
+pki_token_password = Secret123
fe6b0b
+pki_admin_password = Secret123
fe6b0b
+pki_hostname = SERVERNAME
fe6b0b
+pki_security_domain_hostname = SERVERNAME
fe6b0b
+pki_security_domain_https_port = secure_domain_port
fe6b0b
+pki_security_domain_name = topology_Foobarmaster.org
fe6b0b
+pki_security_domain_password = Secret123
fe6b0b
+pki_client_dir = /opt/topology-TPS
fe6b0b
+pki_client_pkcs12_password = Secret123
fe6b0b
+pki_backup_keys = True
fe6b0b
+pki_backup_password = Secret123
fe6b0b
+pki_ds_password = Secret123
fe6b0b
+pki_ds_ldap_port = ldapServerPort
fe6b0b
+pki_client_database_password = Secret123
fe6b0b
+
fe6b0b
+[Tomcat]
fe6b0b
+pki_ajp_port = tpspki_ajp_port
fe6b0b
+pki_tomcat_server_port = tpspki_tomcat_server_port
fe6b0b
+
fe6b0b
+[TPS]
fe6b0b
+pki_import_admin_cert = False
fe6b0b
+pki_ds_hostname = SERVERNAME
fe6b0b
+pki_authdb_basedn = ou=People,dc=example,dc=org
fe6b0b
+pki_authdb_hostname=SERVERNAME
fe6b0b
+pki_authdb_port=3389
fe6b0b
+pki_ca_uri=https://SERVERNAME:capki_https_port
fe6b0b
+pki_tks_uri=https://SERVERNAME:tkspki_https_port
fe6b0b
+pki_kra_uri=https://SERVERNAME:krapki_https_port
fe6b0b
+pki_admin_nickname=PKI TPS Administrator for Example.Org
fe6b0b
+pki_enable_server_side_keygen=True
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ca.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ca.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..67c112b
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ca.yml
fe6b0b
@@ -0,0 +1,25 @@
fe6b0b
+
fe6b0b
+- name: Replace CA specific changes 
fe6b0b
+  replace: dest={{item}} regexp="capki_https_port" replace={{capki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace http port for CA.
fe6b0b
+  replace: dest={{item}} regexp="capki_http_port" replace={{capki_http_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace ajp port for CA
fe6b0b
+  replace: dest={{item}} regexp="capki_ajp_port" replace={{capki_ajp_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for CA
fe6b0b
+  replace: dest={{item}} regexp="capki_tomcat_port" replace={{capki_tomcat_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_common.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_common.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..4bb8bc4
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_common.yml
fe6b0b
@@ -0,0 +1,146 @@
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap_shared.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca_shared.yml"
fe6b0b
+  when: topology  == "topology-01"
fe6b0b
+
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/kra.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ocsp.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tks.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tps.yml"
fe6b0b
+  when: topology  == "topology-02"
fe6b0b
+
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/kra.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ocsp.yml"
fe6b0b
+  when: topology  == "topology-03"
fe6b0b
+
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/kra.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tks.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tps.yml"
fe6b0b
+  when: topology  == "topology-04"
fe6b0b
+
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/kra.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ocsp.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tks.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tps.yml"
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Pick constants based on {{topology}}
fe6b0b
+  include_vars: "{{ item }}"
fe6b0b
+  with_items:
fe6b0b
+  - "{{ playbook_dir }}/vars/ldap.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ca.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/kra.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/ocsp.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tks.yml"
fe6b0b
+  - "{{ playbook_dir }}/vars/tps.yml"
fe6b0b
+  when: topology  == "topology-ecc"
fe6b0b
+
fe6b0b
+- name: Creates directory
fe6b0b
+  file: path=/tmp/test_files state=directory
fe6b0b
+
fe6b0b
+- name: Copying templates to /tmp folder
fe6b0b
+  copy : src=test/  dest=/tmp/test_dir
fe6b0b
+  tags: platform-ci
fe6b0b
+
fe6b0b
+- name: Replace  Ldap server port in all configuration files
fe6b0b
+  replace: dest={{item}} regexp="ldapServerPort" replace={{ldapServerPort}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap.cfg
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace topology in use in all configuration files
fe6b0b
+  replace: dest={{item}} regexp="topology" replace={{topology}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap.cfg
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Substitute ecc with rsa when topology=topology-ecc
fe6b0b
+  replace: dest={{item}} regexp="SHA512withRSA" replace="SHA384withEC"
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  when:
fe6b0b
+    - topology == "topology-ecc"
fe6b0b
+
fe6b0b
+- name : Substitute ecc with rsa when topology=topology-ecc
fe6b0b
+  replace: dest={{item}} regexp="rsa" replace="ecc"
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  when:
fe6b0b
+    - topology == "topology-ecc"
fe6b0b
+
fe6b0b
+- name : Substitute ecc with rsa when topology=topology-ecc
fe6b0b
+  replace: dest={{item}} regexp="2048" replace="nistp384"
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  when:
fe6b0b
+    - topology == "topology-ecc"
fe6b0b
+    
fe6b0b
+- name : For topology-01
fe6b0b
+  replace: dest={{item}} regexp="pki_instance_name" replace="#pki_instance_name"
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  when:
fe6b0b
+    - topology == "topology-01"
fe6b0b
+
fe6b0b
+
fe6b0b
+- name: Replace ServerName in all configuration files.
fe6b0b
+  replace: dest={{item}} regexp="SERVERNAME" replace=pki1.example.com
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap.cfg
fe6b0b
+  - /tmp/test_dir/ca.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+
fe6b0b
+- name: Replace ServerName in all configuration files.
fe6b0b
+  replace: dest={{item}} regexp="SERVERNAME" replace=pki1.example.com
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap_kra.cfg
fe6b0b
+  - /tmp/test_dir/ldap_ocsp.cfg
fe6b0b
+  - /tmp/test_dir/ldap_tks.cfg
fe6b0b
+  - /tmp/test_dir/ldap_tps.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+    
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_kra.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_kra.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..e0edeea
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_kra.yml
fe6b0b
@@ -0,0 +1,27 @@
fe6b0b
+- name: Replace KRA specific changes 
fe6b0b
+  replace: dest={{item}} regexp="krapki_https_port" replace={{krapki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace http port for KRA.
fe6b0b
+  replace: dest={{item}} regexp="krapki_http_port" replace={{krapki_http_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace ajp port for KRA
fe6b0b
+  replace: dest={{item}} regexp="krapki_ajp_port" replace={{krapki_ajp_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for KRA
fe6b0b
+  replace: dest={{item}} regexp="krapki_tomcat_server_port" replace={{krapki_tomcat_server_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for KRA
fe6b0b
+  replace: dest=/tmp/test_dir/kra.cfg regexp="secure_domain_port" replace={{capki_https_port}}
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ldap.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ldap.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..f9af68c
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ldap.yml
fe6b0b
@@ -0,0 +1,47 @@
fe6b0b
+- name : Create different ldap files for ca,kra,ocsp,tks and tps.
fe6b0b
+  shell : for i in kra ocsp tks tps ;do cp /tmp/test_dir/ldap.cfg /tmp/test_dir/ldap_$i.cfg ; sed -i "s/testingmaster/$i-testingmaster/" /tmp/test_dir/ldap_$i.cfg; done
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name : Conditional check before replacing values in ldap.cfg file.
fe6b0b
+  replace: dest={{item}} regexp="3389" replace={{ldapkraServerPort}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap_kra.cfg
fe6b0b
+  - /tmp/test_dir/kra.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name : Conditional check before replacing values in ldap.cfg file.
fe6b0b
+  replace: dest={{item}} regexp="3389" replace={{ldapocspServerPort}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap_ocsp.cfg
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name : Conditional check before replacing values in ldap.cfg file.
fe6b0b
+  replace: dest={{item}} regexp="3389" replace={{ldaptksServerPort}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap_tks.cfg
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name : Conditional check before replacing values in ldap.cfg file.
fe6b0b
+  replace: dest={{item}} regexp="3389" replace={{ldaptpsServerPort}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ldap_tps.cfg
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Replace  Ldap server port in all configuration files
fe6b0b
+  replace: dest=/tmp/test_dir/constants.py regexp="ldapkraServerPort" replace={{ldapkraServerPort}}
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Replace  Ldap server port in all configuration files
fe6b0b
+  replace: dest=/tmp/test_dir/constants.py regexp="ldapocspServerPort" replace={{ldapocspServerPort}}
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Replace  Ldap server port in all configuration files
fe6b0b
+  replace: dest=/tmp/test_dir/constants.py regexp="ldaptksServerPort" replace={{ldaptksServerPort}}
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+
fe6b0b
+- name: Replace  Ldap server port in all configuration files
fe6b0b
+  replace: dest=/tmp/test_dir/constants.py regexp="ldaptpsServerPort" replace={{ldaptpsServerPort}}
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ocsp.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ocsp.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..dea8645
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_ocsp.yml
fe6b0b
@@ -0,0 +1,27 @@
fe6b0b
+- name: Replace OCSP specific changes 
fe6b0b
+  replace: dest={{item}} regexp="ocsppki_https_port" replace={{ocsppki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace http port for OCSP.
fe6b0b
+  replace: dest={{item}} regexp="ocsppki_http_port" replace={{ocsppki_http_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace ajp port for OCSP
fe6b0b
+  replace: dest={{item}} regexp="ocsppki_ajp_port" replace={{ocsppki_ajp_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for OCSP
fe6b0b
+  replace: dest={{item}} regexp="ocsppki_tomcat_server_port" replace={{ocsppki_tomcat_server_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/ocsp.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for OCSP
fe6b0b
+  replace: dest=/tmp/test_dir/ocsp.cfg regexp="secure_domain_port" replace={{capki_https_port}}
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tks.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tks.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..9cd2bc7
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tks.yml
fe6b0b
@@ -0,0 +1,27 @@
fe6b0b
+- name: Replace TKS specific changes 
fe6b0b
+  replace: dest={{item}} regexp="tkspki_https_port" replace={{tkspki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace http port for TKS.
fe6b0b
+  replace: dest={{item}} regexp="tkspki_http_port" replace={{tkspki_http_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace ajp port for TKS
fe6b0b
+  replace: dest={{item}} regexp="tkspki_ajp_port" replace={{tkspki_ajp_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for TKS
fe6b0b
+  replace: dest={{item}} regexp="tkspki_tomcat_server_port" replace={{tkspki_tomcat_server_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tks.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for TKS
fe6b0b
+  replace: dest=/tmp/test_dir/tks.cfg regexp="secure_domain_port" replace={{capki_https_port}}
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tps.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tps.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..69fe4c5
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/configure_tps.yml
fe6b0b
@@ -0,0 +1,39 @@
fe6b0b
+- name: Replace TPS specific changes 
fe6b0b
+  replace: dest={{item}} regexp="tpspki_https_port" replace={{tpspki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace http port for TPS.
fe6b0b
+  replace: dest={{item}} regexp="tpspki_http_port" replace={{tpspki_http_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name: Replace ajp port for TPS
fe6b0b
+  replace: dest={{item}} regexp="tpspki_ajp_port" replace={{tpspki_ajp_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for TPS
fe6b0b
+  replace: dest={{item}} regexp="tpspki_tomcat_server_port" replace={{tpspki_tomcat_server_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace tomcat port for TPS
fe6b0b
+  replace: dest={{item}} regexp="secure_domain_port" replace={{capki_https_port}}
fe6b0b
+  with_items:
fe6b0b
+  - /tmp/test_dir/tps.cfg
fe6b0b
+  - /tmp/test_dir/constants.py
fe6b0b
+
fe6b0b
+- name : Replace ca uri for TPS
fe6b0b
+  replace: dest=/tmp/test_dir/tps.cfg regexp="capki_https_port" replace={{capki_https_port}}
fe6b0b
+
fe6b0b
+- name : Replace kra uri for TPS
fe6b0b
+  replace: dest=/tmp/test_dir/tps.cfg regexp="krapki_https_port" replace={{krapki_https_port}}
fe6b0b
+
fe6b0b
+- name : Replace tks uri for TPS
fe6b0b
+  replace: dest=/tmp/test_dir/tps.cfg regexp="tkspki_https_port" replace={{tkspki_https_port}}
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/main.yml b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/main.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..17e0ecc
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/roles/Test_Trigger/tasks/main.yml
fe6b0b
@@ -0,0 +1,15 @@
fe6b0b
+---
fe6b0b
+- include: configure_common.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_ca.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology  == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_ldap.yml
fe6b0b
+  when: topology  == "topology-05"
fe6b0b
+- include: configure_kra.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology  == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_ocsp.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology  == "topology-05" or topology == "topology-ecc"
fe6b0b
+- include: configure_tks.yml 
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology  == "topology-05"
fe6b0b
+- include: configure_tps.yml
fe6b0b
+  when: topology  == "topology-01" or topology == "topology-02" or topology == "topology-03" or topology == "topology-04" or topology  == "topology-05"
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/ca.yml b/tests/dogtag/pytest-ansible/installation/vars/ca.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..6768f66
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/ca.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+capki_https_port: '20443'
fe6b0b
+capki_http_port: '20080'
fe6b0b
+capki_ajp_port: '20009'
fe6b0b
+capki_tomcat_port: '20005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/ca_shared.yml b/tests/dogtag/pytest-ansible/installation/vars/ca_shared.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..83aa43e
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/ca_shared.yml
fe6b0b
@@ -0,0 +1,24 @@
fe6b0b
+capki_https_port: '8443'
fe6b0b
+capki_http_port: '8080'
fe6b0b
+capki_ajp_port: '8009'
fe6b0b
+capki_tomcat_port: '8005'
fe6b0b
+capki_https_port: '8443'
fe6b0b
+capki_http_port: '8080'
fe6b0b
+capki_ajp_port: '8009'
fe6b0b
+capki_tomcat_port: '8005'
fe6b0b
+krapki_https_port: '8443'
fe6b0b
+krapki_http_port: '8080'
fe6b0b
+krapki_ajp_port: '8009'
fe6b0b
+krapki_tomcat_server_port: '8005'
fe6b0b
+ocsppki_https_port: '8443'
fe6b0b
+ocsppki_http_port: '8080'
fe6b0b
+ocsppki_ajp_port: '8009'
fe6b0b
+ocsppki_tomcat_server_port: '8005'
fe6b0b
+tkspki_https_port: '8443'
fe6b0b
+tkspki_http_port: '8080'
fe6b0b
+tkspki_ajp_port: '8009'
fe6b0b
+tkspki_tomcat_server_port: '8005'
fe6b0b
+tpspki_https_port: '8443'
fe6b0b
+tpspki_http_port: '8080'
fe6b0b
+tpspki_ajp_port: '8009'
fe6b0b
+tpspki_tomcat_server_port: '8005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/kra.yml b/tests/dogtag/pytest-ansible/installation/vars/kra.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..2d45fab
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/kra.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+krapki_https_port: '21443'
fe6b0b
+krapki_http_port: '21080'
fe6b0b
+krapki_ajp_port: '21009'
fe6b0b
+krapki_tomcat_server_port: '21005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/ldap.yml b/tests/dogtag/pytest-ansible/installation/vars/ldap.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..401c4a7
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/ldap.yml
fe6b0b
@@ -0,0 +1,8 @@
fe6b0b
+ldapServerPort: '3389'
fe6b0b
+ldapRootDN: CN=Directory Manager
fe6b0b
+ldapRootDNPwd: Secret123
fe6b0b
+ldapcaServerPort: '4389'
fe6b0b
+ldapkraServerPort: '5389'
fe6b0b
+ldapocspServerPort: '6389'
fe6b0b
+ldaptksServerPort: '7389'
fe6b0b
+ldaptpsServerPort: '8389'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/ldap_shared.yml b/tests/dogtag/pytest-ansible/installation/vars/ldap_shared.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..0e1d7e6
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/ldap_shared.yml
fe6b0b
@@ -0,0 +1,3 @@
fe6b0b
+ldapServerPort: '2389'
fe6b0b
+ldapRootDN: CN=Directory Manager
fe6b0b
+ldapRootDNPwd: Secret123
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/ocsp.yml b/tests/dogtag/pytest-ansible/installation/vars/ocsp.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..497ebb8
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/ocsp.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+ocsppki_https_port: '22443'
fe6b0b
+ocsppki_http_port: '22080'
fe6b0b
+ocsppki_ajp_port: '22009'
fe6b0b
+ocsppki_tomcat_server_port: '22005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/tks.yml b/tests/dogtag/pytest-ansible/installation/vars/tks.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..3f402a4
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/tks.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+tkspki_https_port: '23443'
fe6b0b
+tkspki_http_port: '23080'
fe6b0b
+tkspki_ajp_port: '23009'
fe6b0b
+tkspki_tomcat_server_port: '23005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/installation/vars/tps.yml b/tests/dogtag/pytest-ansible/installation/vars/tps.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..92534c2
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/installation/vars/tps.yml
fe6b0b
@@ -0,0 +1,4 @@
fe6b0b
+tpspki_https_port: '25443'
fe6b0b
+tpspki_http_port: '25080'
fe6b0b
+tpspki_ajp_port: '25009'
fe6b0b
+tpspki_tomcat_server_port: '25005'
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/provision/readme.txt b/tests/dogtag/pytest-ansible/provision/readme.txt
fe6b0b
new file mode 100644
fe6b0b
index 0000000..e69de29
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/pytest/README.md b/tests/dogtag/pytest-ansible/pytest/README.md
fe6b0b
new file mode 100644
fe6b0b
index 0000000..24c3f66
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/pytest/README.md
fe6b0b
@@ -0,0 +1,313 @@
fe6b0b
+# Pytest-ansible for Dogtag Tests
fe6b0b
+
fe6b0b
+## Note
fe6b0b
+Recommended version to install ansible version 2.3.x. 
fe6b0b
+Integration testing with other versions like pytest-ansible 2.4.0  are still in-progress.
fe6b0b
+
fe6b0b
+## Installing pip
fe6b0b
+
fe6b0b
+[pip] (https://pip.pypa.io/en/stable/installing/)  is needed for ansible & pytest installation.
fe6b0b
+
fe6b0b
+## Description about pytest-ansible & pytest-ansible-playbook
fe6b0b
+
fe6b0b
+This repository contains a plugin for py.test which adds several fixtures for running ansible modules, or inspecting ansible_facts. While one can simply call out to ansible using the subprocess module, having to parse stdout to determine the outcome of the operation is unpleasant and prone to error. With pytest-ansible, modules return JSON data which you can inspect and act on, much like with an ansible playbook.
fe6b0b
+See [pytest-ansible] (https://pypi.python.org/pypi/pytest-ansible)
fe6b0b
+
fe6b0b
+### Installation
fe6b0b
+
fe6b0b
+#### Installing ansible
fe6b0b
+#### Installing pytest-ansible
fe6b0b
+#### Installing pytest-ansible-playbook
fe6b0b
+
fe6b0b
+Covered under [README] (../README.md#installing-supporting-packages)
fe6b0b
+### Usage
fe6b0b
+
fe6b0b
+Once installed, the following py.test command-line parameters are available:
fe6b0b
+
fe6b0b
+```
fe6b0b
+     py.test \
fe6b0b
+    [--ansible-inventory <path_to_inventory>] \
fe6b0b
+    [--ansible-host-pattern <host-pattern>] \
fe6b0b
+    [--ansible-playbook-directory <path_to_directory_with_playbooks>] \
fe6b0b
+    [--ansible-playbook-inventory <path_to_inventory_file>]
fe6b0b
+    [--ansible-connection <plugin>] \
fe6b0b
+    [--ansible-user <username>] \
fe6b0b
+    [--ansible-sudo] \
fe6b0b
+    [--ansible-sudo-user <username>]
fe6b0b
+
fe6b0b
+```
fe6b0b
+
fe6b0b
+#### Mandatory command-line parameters:
fe6b0b
+
fe6b0b
+```
fe6b0b
+    py.test \
fe6b0b
+    [--ansible-inventory <path_to_inventory>] \
fe6b0b
+    [--ansible-playbook-directory <path_to_directory_with_playbooks>] \
fe6b0b
+    [--ansible-playbook-inventory <path_to_inventory_file>] \
fe6b0b
+    [--ansible-host-pattern <host-pattern>]
fe6b0b
+```
fe6b0b
+
fe6b0b
+### Available Fixtures with pytest-ansible
fe6b0b
+
fe6b0b
+1. Fixture ansible_module
fe6b0b
+
fe6b0b
+    The ansible_module fixture allows tests and fixtures to call ansible modules. See [ansible_module] (http://docs.ansible.com/ansible/2.3/modules.html)
fe6b0b
+
fe6b0b
+2. Fixture ansible_facts
fe6b0b
+
fe6b0b
+    The ansible_facts fixture returns a JSON structure representing the system facts for the associated inventory. Sample fact data is available in the [ansible documentation](http://docs.ansible.com/ansible/latest/playbooks_variables.html#information-discovered-from-systems-facts)
fe6b0b
+
fe6b0b
+### Available Fixtures with pytest-ansible-playbook
fe6b0b
+
fe6b0b
+1. Fixture ansible playbook
fe6b0b
+
fe6b0b
+    The plugin provides a single pytest fixture called ansible_playbook. To specify playbooks to be executed by the fixture, use the following pytest markers:
fe6b0b
+
fe6b0b
+```
fe6b0b
+
fe6b0b
+    @pytest.mark.ansible_playbook_setup('playbook.yml')
fe6b0b
+    @pytest.mark.ansible_playbook_teardown('playbook.yml')
fe6b0b
+
fe6b0b
+    @pytest.mark.ansible_playbook_setup('playbook.01.yml', 'playbook.02.yml')
fe6b0b
+
fe6b0b
+```
fe6b0b
+
fe6b0b
+### Install pytest-autochecklog
fe6b0b
+
fe6b0b
+In case you have plans to use logging that we get from `pytest-autochecklog`, get it using
fe6b0b
+
fe6b0b
+```
fe6b0b
+pip install pytest-autochecklog
fe6b0b
+```
fe6b0b
+
fe6b0b
+###  Parameterizing with pytest.mark.ansible
fe6b0b
+
fe6b0b
+Perhaps the --ansible-inventory=<inventory> includes many systems, but you only wish to interact with a subset. The pytest.mark.ansible marker can be used to modify the pytest-ansible command-line parameters for a single test.
fe6b0b
+
fe6b0b
+For example, to interact with the local system, you would adjust the host_pattern and connection parameters.
fe6b0b
+
fe6b0b
+
fe6b0b
+```
fe6b0b
+@pytest.mark.ansible(host_pattern='local,', connection='local')
fe6b0b
+class Test_Local(object):
fe6b0b
+    def test_install(self, ansible_module):
fe6b0b
+        '''do some testing'''
fe6b0b
+    def test_template(self, ansible_module):
fe6b0b
+        '''do some testing'''
fe6b0b
+    def test_service(self, ansible_module):
fe6b0b
+        '''do some testing'''
fe6b0b
+```
fe6b0b
+It works with both class and function.
fe6b0b
+
fe6b0b
+More on [Paramaterizing](https://docs.pytest.org/en/latest/example/parametrize.html)
fe6b0b
+
fe6b0b
+### Exception Handling
fe6b0b
+
fe6b0b
+Below is the example of exception handling.During runtime, if we wanted to change inventory file it can be done using `@pytest.mark.ansible(inventory='abc')`.
fe6b0b
+Here , if host mentioned in file "abc" is not reachable using ping it should raise exception `AnsibleHostUnreachable`
fe6b0b
+
fe6b0b
+```
fe6b0b
+@pytest.mark.ansible(inventory='abc')
fe6b0b
+def test_shutdown(ansible_module):
fe6b0b
+         pytest.raises(pytest_ansible.plugin.AnsibleHostUnreachable, ansible_module.ping)
fe6b0b
+```
fe6b0b
+
fe6b0b
+## About PKI Module
fe6b0b
+
fe6b0b
+PKI module is an ansible module that can be called either from python code or from ansible-playbooks to run any pki client commands
fe6b0b
+See [PKI Module](https://copr.fedorainfracloud.org/coprs/g/pki/10.5/package/test-pki-modules/) for latest modules and common packages.
fe6b0b
+
fe6b0b
+PKI Module has few default values and those can be over-written by defining them during tests creation.This is same as any standard ansible modules.
fe6b0b
+
fe6b0b
+### Getting PKI Module
fe6b0b
+
fe6b0b
+PKI module can be installed with below procedure. Install latest rpm from [copr site] (https://copr.fedorainfracloud.org/coprs/g/pki/10.5/package/test-pki-modules/)
fe6b0b
+
fe6b0b
+```
fe6b0b
+Example: 
fe6b0b
+
fe6b0b
+1. wget https://copr.fedorainfracloud.org/coprs/g/pki/10.5/package/test-pki-modules/
fe6b0b
+2. rpm -qlp idm-modules
fe6b0b
+    - Make sure above command lists pki.py module
fe6b0b
+3. rpm -ivh idm-modules
fe6b0b
+
fe6b0b
+Make sure pki.py exist under PYTHONPATH/ansible/modules/identity/pki/pki.py
fe6b0b
+```
fe6b0b
+
fe6b0b
+In case, it is difficult with above procedure, this can be done manually using
fe6b0b
+
fe6b0b
+```
fe6b0b
+cp pki-pytest-ansible/raw/pytest-task/common-modules/pki.py PYTHONPATH/ansible/modules/identity/pki/pki.py
fe6b0b
+```
fe6b0b
+
fe6b0b
+All the common modules are part of common-modules code.
fe6b0b
+
fe6b0b
+### Usage
fe6b0b
+
fe6b0b
+`with python`
fe6b0b
+
fe6b0b
+```
fe6b0b
+def test_pki(ansible_facts,ansible_module):
fe6b0b
+    for (host, facts) in ansible_facts.items():
fe6b0b
+    	contacted = ansible_module.pki(
fe6b0b
+        cli='ca-cert-find',
fe6b0b
+		hostname = host,
fe6b0b
+		nssdb = '/root/nssdb',
fe6b0b
+		certnick = "'PKI Administrator for example.com'"
fe6b0b
+    	)
fe6b0b
+    item=contacted.items()
fe6b0b
+    print dict(item)
fe6b0b
+
fe6b0b
+For Positive test case:
fe6b0b
+----------------------
fe6b0b
+
fe6b0b
+@pytest.mark.positive
fe6b0b
+def test_tpsToken_show_01(ansible_module, certnick, expected):
fe6b0b
+    contacted = ansible_module.pki(
fe6b0b
+                cli='ca-cert-find',
fe6b0b
+                protocol='http',
fe6b0b
+                certnick = certnick
fe6b0b
+        )
fe6b0b
+    for  result in contacted.values():
fe6b0b
+        for iter in expected:
fe6b0b
+                assert iter in result['stdout']
fe6b0b
+
fe6b0b
+For Negative test case:
fe6b0b
+-----------------------
fe6b0b
+
fe6b0b
+@pytest.mark.negative
fe6b0b
+def test_tpsToken_show_01(ansible_module, certnick, expected):
fe6b0b
+    contacted = ansible_module.pki(
fe6b0b
+                cli='ca-cert-find',
fe6b0b
+                protocol='http',
fe6b0b
+                certnick = certnick
fe6b0b
+        )
fe6b0b
+    for  result in contacted.values():
fe6b0b
+        for iter in expected:
fe6b0b
+                assert iter in result['stderr']
fe6b0b
+
fe6b0b
+
fe6b0b
+```
fe6b0b
+
fe6b0b
+`with ansible-playbook`
fe6b0b
+
fe6b0b
+```
fe6b0b
+  tasks:
fe6b0b
+
fe6b0b
+    - name: Run pki module from ansible-playbook
fe6b0b
+      pki: cli='ca-cert-show' port='9443'
fe6b0b
+
fe6b0b
+Output
fe6b0b
+
fe6b0b
+"cmd": "pki -d <path to nssdb> -P http -p 9443 -h localhost -c Secret123 -n 'PKI CA Administrator for Example.Org' ca-cert-show "
fe6b0b
+
fe6b0b
+```
fe6b0b
+### Examples
fe6b0b
+
fe6b0b
+See [Examples](tps-token/test_tps_token_show.py)
fe6b0b
+
fe6b0b
+### Parametrizing your tests
fe6b0b
+
fe6b0b
+This involves clubbing of tests which are similar in nature.
fe6b0b
+
fe6b0b
+Example: All Positive tests whose output comes under stdout can be clubbed together.
fe6b0b
+
fe6b0b
+Negative tests where output goes in stderr can be put together.
fe6b0b
+
fe6b0b
+See [Parametrizing your tests](tps-token/test_tps_token_show.py)
fe6b0b
+
fe6b0b
+### Advantages of parametrizing tests
fe6b0b
+
fe6b0b
+1. Test cases are much shorter.
fe6b0b
+2. Easy to run smoke, positive, negative cases using markers.
fe6b0b
+3. Similar kind of test are clubbed together and avoid code duplication.
fe6b0b
+4. Multiple asserts are implemented.
fe6b0b
+5. Code is never touched.Just input and output is changed.
fe6b0b
+
fe6b0b
+## Pre-requisite before running a pytest-ansible using pki module
fe6b0b
+
fe6b0b
+Py.test assumes that your Subsystem installation is done using [ansible-playbooks](../installation/README.md)
fe6b0b
+Tests look for ansible environment constants file for fetching port if not provided in pytest code.
fe6b0b
+
fe6b0b
+
fe6b0b
+## Importing the CA cert to nssdb. Please run this command on the machine on which RHCS is setup
fe6b0b
+
fe6b0b
+```
fe6b0b
+1. Create nssdb in <path to nssdb>.
fe6b0b
+2. Import CA Admin Certificate into nssdb.
fe6b0b
+pki -d <path to nssdb>-c Secret123 -h <hostname> -p <CA HTTP PORT> client-cert-import "RootCA" --ca-server
fe6b0b
+pk12util -i <Subsystem admin p12 file> -d <path to nssdb> -K Secret123 -W Secret123
fe6b0b
+```
fe6b0b
+
fe6b0b
+## Running a pytest-ansible test
fe6b0b
+
fe6b0b
+```
fe6b0b
+py.test --ansible-inventory host --ansible-host-pattern master <python file>  -q -s  -vvv
fe6b0b
+```
fe6b0b
+
fe6b0b
+where,
fe6b0b
+
fe6b0b
+    --ansible-inventory,   the inventory file from where hosts ip are picked.
fe6b0b
+    --ansible-host-pattern,  the host pattern on which tests needs to be run like master or clone
fe6b0b
+
fe6b0b
+
fe6b0b
+## Running a combination of pytest-ansible and pytest-ansible-playbook
fe6b0b
+
fe6b0b
+```
fe6b0b
+py.test --ansible-inventory host --ansible-host-pattern master --ansible-playbook-inventory host <python file>  -q -s  -vvv
fe6b0b
+```
fe6b0b
+
fe6b0b
+
fe6b0b
+where,
fe6b0b
+
fe6b0b
+    --ansible-inventory,  the inventory file from where hosts ip are picked.
fe6b0b
+    --ansible-host-pattern,  the host pattern on which tests needs to be run.
fe6b0b
+    --ansible-playbook-inventory,  the inventory file used for running playbooks which are defined in form of fixtures to run.
fe6b0b
+
fe6b0b
+Refer [Available Fixtures with pytest-ansible-playbook](README.md#available-fixtures-with-pytest-ansible-playbook)
fe6b0b
+
fe6b0b
+## Examples of ansible-inventory and ansible-playbook-inventory
fe6b0b
+
fe6b0b
+Inventory file consist of the roles and the ip-address.Tests will run for the roles and ip's that are mentioned.
fe6b0b
+
fe6b0b
+```
fe6b0b
+[master]
fe6b0b
+10.1.2.3
fe6b0b
+10.2.3.4
fe6b0b
+```
fe6b0b
+
fe6b0b
+## Troubleshooting Errors
fe6b0b
+
fe6b0b
+To Debug any error, `Run py.test command with reporting option.`
fe6b0b
+
fe6b0b
+```
fe6b0b
+reporting:
fe6b0b
+  -v, --verbose         increase verbosity.
fe6b0b
+  -q, --quiet           decrease verbosity.
fe6b0b
+  -r chars              show extra test summary info as specified by chars
fe6b0b
+                        (f)ailed, (E)error, (s)skipped, (x)failed, (X)passed,
fe6b0b
+                        (p)passed, (P)passed with output, (a)all except pP.
fe6b0b
+                        The pytest warnings are displayed at all times except
fe6b0b
+                        when --disable-pytest-warnings is set
fe6b0b
+  --disable-pytest-warnings
fe6b0b
+                        disable warnings summary, overrides -r w flag
fe6b0b
+  -l, --showlocals      show locals in tracebacks (disabled by default).
fe6b0b
+  --tb=style            traceback print mode (auto/long/short/line/native/no).
fe6b0b
+  --full-trace          don't cut any tracebacks (default is to cut).
fe6b0b
+  --color=color         color terminal output (yes/no/auto).
fe6b0b
+  --durations=N         show N slowest setup/test durations (N=0 for all).
fe6b0b
+  --pastebin=mode       send failed|all info to bpaste.net pastebin service.
fe6b0b
+  --junit-xml=path      create junit-xml style report file at given path.
fe6b0b
+  --junit-prefix=str    prepend prefix to classnames in junit-xml output
fe6b0b
+  --result-log=path     DEPRECATED path for machine-readable result log.
fe6b0b
+  --excel-report=path   create excel report file at given path.
fe6b0b
+```
fe6b0b
+
fe6b0b
+## Additional Packages
fe6b0b
+
fe6b0b
+These are additional logging packages that could be used in future if logging improvement is needed.
fe6b0b
+
fe6b0b
+- [Logging-1](https://pypi.python.org/pypi/pytest-logger).
fe6b0b
+- [Logging-2](ttps://pypi.python.org/pypi/pytest-autochecklog).
fe6b0b
+
fe6b0b
+
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/pytest/tps-token/ldapUserAdd.yml b/tests/dogtag/pytest-ansible/pytest/tps-token/ldapUserAdd.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..1648266
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/pytest/tps-token/ldapUserAdd.yml
fe6b0b
@@ -0,0 +1,35 @@
fe6b0b
+- hosts: master
fe6b0b
+  gather_facts: true
fe6b0b
+
fe6b0b
+  tasks:
fe6b0b
+    - name: Making constants.py file compatable for including as vars.
fe6b0b
+      shell: sed -e "s/ =/:/g;s/'//g" /tmp/test_dir/constants.py > /tmp/test_dir/constants.yml
fe6b0b
+
fe6b0b
+    - name: Fetch the file
fe6b0b
+      fetch: src=/tmp/test_dir/constants.yml dest=/tmp/test_dir flat=yes validate_checksum=no
fe6b0b
+
fe6b0b
+    - name: Including variables from Environment
fe6b0b
+      include_vars:
fe6b0b
+         file: /tmp/test_dir/constants.yml
fe6b0b
+         name: variable
fe6b0b
+
fe6b0b
+    - name: Gather facts
fe6b0b
+      set_fact: 
fe6b0b
+         var: "{{ inventory_hostname }}"
fe6b0b
+         userPasswd: "{{ variable.LDAP_PASSWD }}"
fe6b0b
+
fe6b0b
+    - name: Get rid of an old entry
fe6b0b
+      ldap_entry:
fe6b0b
+        dn: uid={{ variable.LDAP_USER }},ou=People,dc=example,dc=org
fe6b0b
+        objectClass:
fe6b0b
+           - top
fe6b0b
+           - person
fe6b0b
+           - inetOrgPerson
fe6b0b
+           - organizationalRole
fe6b0b
+        params:
fe6b0b
+           cn: "{{ variable.LDAP_USER }}"
fe6b0b
+           sn: "{{ variable.LDAP_USER }}"
fe6b0b
+           userPassword: "{{ variable.LDAP_PASSWD }}"
fe6b0b
+        server_uri: ldap://{{ inventory_hostname }}:{{ variable.LDAP_PORT }}
fe6b0b
+        bind_dn: cn=Directory Manager
fe6b0b
+        bind_pw: "{{ variable.LDAP_PASSWD }}"
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/pytest/tps-token/test_tps_token_show.py b/tests/dogtag/pytest-ansible/pytest/tps-token/test_tps_token_show.py
fe6b0b
new file mode 100644
fe6b0b
index 0000000..9c30b19
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/pytest/tps-token/test_tps_token_show.py
fe6b0b
@@ -0,0 +1,106 @@
fe6b0b
+"""
fe6b0b
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fe6b0b
+#
fe6b0b
+#   Description: PKI TPS-TOKEN-SHOW tests
fe6b0b
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fe6b0b
+#   The following pki tps commands needs to be tested:
fe6b0b
+#   pki tps-token-show
fe6b0b
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fe6b0b
+#
fe6b0b
+#   Author: Geetika Kapoor <gkapoor@redhat.com>
fe6b0b
+#
fe6b0b
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fe6b0b
+#
fe6b0b
+#   Copyright (c) 2016 Red Hat, Inc. All rights reserved.
fe6b0b
+#
fe6b0b
+#   This copyrighted material is made available to anyone wishing
fe6b0b
+#   to use, modify, copy, or redistribute it subject to the terms
fe6b0b
+#   and conditions of the GNU General Public License version 2.
fe6b0b
+#
fe6b0b
+#   This program is distributed in the hope that it will be
fe6b0b
+#   useful, but WITHOUT ANY WARRANTY; without even the implied
fe6b0b
+#   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
fe6b0b
+#   PURPOSE. See the GNU General Public License for more details.
fe6b0b
+#
fe6b0b
+#   You should have received a copy of the GNU General Public
fe6b0b
+#   License along with this program; if not, write to the Free
fe6b0b
+#   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
fe6b0b
+#   Boston, MA 02110-1301, USA.
fe6b0b
+"""
fe6b0b
+
fe6b0b
+
fe6b0b
+import pytest
fe6b0b
+import ansible
fe6b0b
+import logging
fe6b0b
+from ansible.inventory import Inventory
fe6b0b
+from pytest_ansible import plugin
fe6b0b
+import ansible.constants
fe6b0b
+import os
fe6b0b
+
fe6b0b
+from test_steps import *
fe6b0b
+import random
fe6b0b
+
fe6b0b
+@pytest.mark.ansible_playbook_setup('ldapUserAdd.yml', 'tokenEnroll.yml')
fe6b0b
+@pytest.mark.setup
fe6b0b
+def test_setup(ansible_playbook):
fe6b0b
+    pass
fe6b0b
+
fe6b0b
+@pytest.mark.parametrize("certnick,expected", [
fe6b0b
+    ('"PKI TPS Administrator for Example.Org"', ['Token ID: 40906145C76224192D2B', 'User ID: foobar', 'Type: userKey', 'Status: ACTIVE']),
fe6b0b
+])
fe6b0b
+
fe6b0b
+@pytest.mark.positive
fe6b0b
+def test_tpstoken_show_validgroup(ansible_module, certnick, expected):
fe6b0b
+    """
fe6b0b
+    :Description: Command should successfully show tokens.
fe6b0b
+    """
fe6b0b
+    contacted = ansible_module.pki(
fe6b0b
+        cli='tps-token-show',
fe6b0b
+        extra_args='40906145C76224192D2B',
fe6b0b
+        protocol='http',
fe6b0b
+        certnick=certnick
fe6b0b
+        )
fe6b0b
+    for (host, result) in contacted.items():
fe6b0b
+        for iter in expected:
fe6b0b
+            ok("Certificate: %s, Expected Output: %s , Actual Output : %s" %(certnick, iter, result['stdout']))
fe6b0b
+            assert iter in result['stdout']
fe6b0b
+@pytest.mark.parametrize("certnick,expected", [
fe6b0b
+    ('"PKI TPS Administrator for Example.Org"', ["PKIException: Record not found"]),
fe6b0b
+])
fe6b0b
+
fe6b0b
+@pytest.mark.negative
fe6b0b
+def test_tpstoken_show_exception(ansible_module, certnick, expected):
fe6b0b
+    """
fe6b0b
+    :Description: Command should give "Records" not found.
fe6b0b
+    """
fe6b0b
+    contacted = ansible_module.pki(
fe6b0b
+        cli='tps-token-show',
fe6b0b
+        extra_args='40906145C76224192D2BRR',
fe6b0b
+        certnick=certnick
fe6b0b
+        )
fe6b0b
+    for (host, result) in  contacted.items():
fe6b0b
+        for iter in expected:
fe6b0b
+            ok("Certificate: %s, Expected Output: %s , Actual Output : %s" %(certnick, iter, result['stderr']))
fe6b0b
+            assert iter in result['stderr']
fe6b0b
+
fe6b0b
+@pytest.mark.positive
fe6b0b
+@pytest.mark.parametrize("extra_args, certnick, expected", [
fe6b0b
+    ('40906145C76224192D2B', '"PKI TPS Administrator for Example.Org"', ['Token ID: 40906145C76224192D2B', 'User ID: foobar', 'Type: userKey', 'Status: ACTIVE']),
fe6b0b
+    ('--help', '"PKI TPS Administrator for Example.Org"', ['usage: tps-token-show', '<Token ID>', '--help   Show help options']),
fe6b0b
+])
fe6b0b
+
fe6b0b
+@pytest.mark.positive
fe6b0b
+def test_tpstoken_show_help(ansible_module, extra_args, certnick, expected):
fe6b0b
+    """
fe6b0b
+    :Description: Command should successfully show tokens.
fe6b0b
+    """
fe6b0b
+    contacted = ansible_module.pki(
fe6b0b
+        cli='tps-token-show',
fe6b0b
+        extra_args=extra_args,
fe6b0b
+        protocol='https',
fe6b0b
+        certnick=certnick
fe6b0b
+        )
fe6b0b
+    for (host, result) in  contacted.items():
fe6b0b
+        for iter in expected:
fe6b0b
+            ok("Certificate: %s, Expected Output: %s , Actual Output : %s" %(certnick, iter, result['stdout']))
fe6b0b
+            assert iter in result['stdout']
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/pytest/tps-token/tokenEnroll.yml b/tests/dogtag/pytest-ansible/pytest/tps-token/tokenEnroll.yml
fe6b0b
new file mode 100644
fe6b0b
index 0000000..872ee51
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/pytest/tps-token/tokenEnroll.yml
fe6b0b
@@ -0,0 +1,35 @@
fe6b0b
+- hosts: master
fe6b0b
+  gather_facts: true
fe6b0b
+  tasks:
fe6b0b
+    - name: Going to TPSClient
fe6b0b
+      shell: echo -e "op=var_set name=ra_host value=hostname\nop=var_set name=ra_port value=TPS_HTTP_PORT\nop=var_set name=ra_uri value=/tps/tps\nop=token_set cuid=TOKEN_CUID msn=0120304 app_ver=6FBBC105 key_info=0101 major_ver=0 minor_ver=0\nop=token_set auth_key=404142434445464748494a4b4c4d4e4f\nop=token_set mac_key=404142434445464748494a4b4c4d4e4f\nop=token_set kek_key=404142434445464748494a4b4c4d4e4f\nop=TPS_OPERATION uid=LDAP_USER pwd=LDAP_PASSWD new_pin=LDAP_NEW_PIN num_threads=1 extensions=tokenType=userKey\nop=exit" > /tmp/tpsclient.txt
fe6b0b
+
fe6b0b
+    - name: Including variables from Environment
fe6b0b
+      include_vars:
fe6b0b
+         file: /tmp/test_dir/constants.yml
fe6b0b
+         name: variable
fe6b0b
+
fe6b0b
+    - name: Replacing correct hostname
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=hostname  replace={{ inventory_hostname }}
fe6b0b
+
fe6b0b
+    - name: Replacing correct Port
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=TPS_HTTP_PORT  replace={{ variable.TPS_HTTP_PORT }}
fe6b0b
+
fe6b0b
+    - name: Replacing correct Password
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=LDAP_PASSWD  replace={{ variable.LDAP_PASSWD }}
fe6b0b
+ 
fe6b0b
+    - name: Replacing correct pin
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=LDAP_NEW_PIN  replace={{ variable.LDAP_PASSWD }}
fe6b0b
+
fe6b0b
+    - name: Replacing correct Cuid
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=TOKEN_CUID  replace={{ variable.CUID }}
fe6b0b
+
fe6b0b
+    - name: Replacing correct TPS Operation
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=TPS_OPERATION  replace={{ variable.TPS_OPERATION }}
fe6b0b
+
fe6b0b
+    - name: Adding LDAP user in tpsclient configuration
fe6b0b
+      replace: dest=/tmp/tpsclient.txt regexp=LDAP_USER  replace={{ variable.LDAP_USER }}
fe6b0b
+
fe6b0b
+    - name: Performing token enrollment
fe6b0b
+      shell: tpsclient < /tmp/tpsclient.txt
fe6b0b
+      ignore_errors: yes 
fe6b0b
diff --git a/tests/dogtag/pytest-ansible/requirements.txt b/tests/dogtag/pytest-ansible/requirements.txt
fe6b0b
new file mode 100644
fe6b0b
index 0000000..160b10e
fe6b0b
--- /dev/null
fe6b0b
+++ b/tests/dogtag/pytest-ansible/requirements.txt
fe6b0b
@@ -0,0 +1,5 @@
fe6b0b
+ansible==2.3.2
fe6b0b
+pytest-ansible==1.3.1
fe6b0b
+pytest-ansible-playbook==0.3.0
fe6b0b
+pytest-logger
fe6b0b
+pytest-autochecklog==0.2.0
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b
fe6b0b
fe6b0b
From 53ad8042f1145aa33990298a4d7dc4d6e4fe646b Mon Sep 17 00:00:00 2001
fe6b0b
From: Ade Lee <alee@redhat.com>
fe6b0b
Date: Mon, 27 Nov 2017 13:43:33 -0500
fe6b0b
Subject: Add pkispawn option for ephemeral requests
fe6b0b
fe6b0b
Ticket 2820
fe6b0b
fe6b0b
Change-Id: I8865d74dd221b69b7fd53f1dbc941c7686bbd858
fe6b0b
(cherry picked from commit 44c732c5ebb1fc6ef7ca851f4118bf58311588bc)
fe6b0b
---
fe6b0b
 base/server/etc/default.cfg                                      | 1 +
fe6b0b
 base/server/man/man5/pki_default.cfg.5                           | 7 +++++++
fe6b0b
 .../python/pki/server/deployment/scriptlets/configuration.py     | 9 +++++++++
fe6b0b
 3 files changed, 17 insertions(+)
fe6b0b
fe6b0b
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
fe6b0b
index ce10d7f..ad19105 100644
fe6b0b
--- a/base/server/etc/default.cfg
fe6b0b
+++ b/base/server/etc/default.cfg
fe6b0b
@@ -436,6 +436,7 @@ pki_replica_number_range_end=100
fe6b0b
 [KRA]
fe6b0b
 pki_import_admin_cert=True
fe6b0b
 pki_standalone=False
fe6b0b
+pki_kra_ephemeral_requests=False
fe6b0b
 
fe6b0b
 # DEPRECATED
fe6b0b
 # Use 'pki_*_csr_path' instead.
fe6b0b
diff --git a/base/server/man/man5/pki_default.cfg.5 b/base/server/man/man5/pki_default.cfg.5
fe6b0b
index ab3e617..a505c4b 100644
fe6b0b
--- a/base/server/man/man5/pki_default.cfg.5
fe6b0b
+++ b/base/server/man/man5/pki_default.cfg.5
fe6b0b
@@ -439,6 +439,13 @@ Required for the second step of a stand-alone PKI process.  This is the location
fe6b0b
 .IP
fe6b0b
 [KRA ONLY] Required for the second step of a stand-alone KRA process.  This is the location of the file containing the transport certificate (as issued by the external CA).  Defaults to '%(pki_instance_configuration_path)s/kra_transport.cert'.
fe6b0b
 
fe6b0b
+.SS KRA PARAMETERS
fe6b0b
+.BR
fe6b0b
+.TP
fe6b0b
+.B pki_kra_ephemeral_requests
fe6b0b
+.IP
fe6b0b
+Specifies to use ephemeral requests for archivals and retrievals.  Defaults to False.
fe6b0b
+
fe6b0b
 .SS TPS PARAMETERS
fe6b0b
 .BR
fe6b0b
 .TP
fe6b0b
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
fe6b0b
index b21adb6..1870505 100644
fe6b0b
--- a/base/server/python/pki/server/deployment/scriptlets/configuration.py
fe6b0b
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
fe6b0b
@@ -968,6 +968,15 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
fe6b0b
             subsystem.config['ca.defaultOcspUri'] = ocsp_uri
fe6b0b
             subsystem.save()
fe6b0b
 
fe6b0b
+        # set ephemeral requests if needed
fe6b0b
+        if subsystem.name == 'kra':
fe6b0b
+            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
fe6b0b
+                config.pki_log.info(
fe6b0b
+                    "setting ephemeral requests to true",
fe6b0b
+                    extra=config.PKI_INDENTATION_LEVEL_1)
fe6b0b
+                subsystem.config['kra.ephemeralRequests'] = 'true'
fe6b0b
+                subsystem.save()
fe6b0b
+
fe6b0b
         token = deployer.mdict['pki_token_name']
fe6b0b
         nssdb = instance.open_nssdb(token)
fe6b0b
 
fe6b0b
-- 
fe6b0b
1.8.3.1
fe6b0b