From 14e44691ef0b61220d390afb745496b7d62945ee Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 30 May 2017 21:15:44 +0200 Subject: [PATCH 04/27] Added pkispawn options for two-step installation. New --skip-configuration and --skip-installation options have been added to pkispawn to provide a mechanism to set the pki_skip_configuration and pki_skip_installation parameters without changing the deployment configuration file. https://pagure.io/dogtagpki/issue/2707 Change-Id: I069b51b5be65dee2fe0f4ca75e3693bcd21007de --- base/server/sbin/pkispawn | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn index 9e2ebc8..742f579 100755 --- a/base/server/sbin/pkispawn +++ b/base/server/sbin/pkispawn @@ -91,6 +91,18 @@ def main(argv): dest='precheck', action='store_true', help='Execute pre-checks and exit') + parser.optional.add_argument( + '--skip-configuration', + dest='skip_configuration', + action='store_true', + help='skip configuration step') + + parser.optional.add_argument( + '--skip-installation', + dest='skip_installation', + action='store_true', + help='skip installation step') + args = parser.process_command_line_arguments() config.default_deployment_cfg = \ @@ -475,6 +487,24 @@ def main(argv): sys.exit(1) start_logging() + + # Read the specified PKI configuration file. + rv = parser.read_pki_configuration_file() + if rv != 0: + config.pki_log.error(log.PKI_UNABLE_TO_PARSE_1, rv, + extra=config.PKI_INDENTATION_LEVEL_0) + sys.exit(1) + + # --skip-configuration + if args.skip_configuration: + parser.set_property(deployer.subsystem_name, + 'pki_skip_configuration', 'True') + + # --skip-installation + if args.skip_installation: + parser.set_property(deployer.subsystem_name, + 'pki_skip_installation', 'True') + create_master_dictionary(parser) if not interactive and \ @@ -635,23 +665,21 @@ def start_logging(): def create_master_dictionary(parser): - # Read the specified PKI configuration file. - rv = parser.read_pki_configuration_file() - if rv != 0: - config.pki_log.error(log.PKI_UNABLE_TO_PARSE_1, rv, - extra=config.PKI_INDENTATION_LEVEL_0) - sys.exit(1) # Read in the PKI slots configuration file. parser.compose_pki_slots_dictionary() + config.pki_log.debug(log.PKI_DICTIONARY_SLOTS, extra=config.PKI_INDENTATION_LEVEL_0) config.pki_log.debug(pkilogging.log_format(parser.slots_dict), extra=config.PKI_INDENTATION_LEVEL_0) + # Combine the various sectional dictionaries into a PKI master dictionary parser.compose_pki_master_dictionary() + parser.mdict['pki_spawn_log'] = \ config.pki_log_dir + "/" + config.pki_log_name + config.pki_log.debug(log.PKI_DICTIONARY_MASTER, extra=config.PKI_INDENTATION_LEVEL_0) config.pki_log.debug(pkilogging.log_format(parser.mdict), -- 1.8.3.1 From 9af1746463bec2e62c990279d857635f693cfac7 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 30 May 2017 21:07:59 +0200 Subject: [PATCH 05/27] Fixed two-step subordinate CA installation. The initialization scriptlet has been fixed to verify the subsystem existence properly when running the second step of the two-step subordinate CA installation. https://pagure.io/dogtagpki/issue/2707 Change-Id: I0cc8ca21fda8637b4b34f4c5a1c108d213f638f8 --- .../pki/server/deployment/scriptlets/initialization.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/base/server/python/pki/server/deployment/scriptlets/initialization.py b/base/server/python/pki/server/deployment/scriptlets/initialization.py index 4dc4e9a..1ae77e4 100644 --- a/base/server/python/pki/server/deployment/scriptlets/initialization.py +++ b/base/server/python/pki/server/deployment/scriptlets/initialization.py @@ -54,13 +54,19 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): else: config.pki_log.info(log.INITIALIZATION_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) + + # Verify that the subsystem already exists for the following cases: + # - External CA (Step 2) + # - Stand-alone PKI (Step 2) + # - Two-step installation (Step 2) + if (deployer.mdict['pki_subsystem'] == "CA" or config.str2bool(deployer.mdict['pki_standalone'])) and \ - config.str2bool(deployer.mdict['pki_external_step_two']): - # verify that this External CA (Step 2), or Stand-alone PKI - # (Step 2) currently EXISTS for this "instance" + config.str2bool(deployer.mdict['pki_external_step_two']) or \ + config.str2bool(deployer.mdict['pki_skip_installation']): deployer.instance.verify_subsystem_exists() deployer.mdict['pki_skip_installation'] = "True" + else: # verify that this type of "subsystem" does NOT yet # exist for this "instance" -- 1.8.3.1 From 0984d8a114b326a75b2c32cd9da2b7dee23920bb Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Fri, 26 May 2017 22:57:07 -0400 Subject: [PATCH 07/27] Convert CMC code to use AES * Switched out CrytoUtil calls that use DES and replaced them with AES equivalents. Removed these now unneeded methods. * Added 16 byte constant IV for AES operations. This must be replaced by a randomly generated IV. Added TODOs where IVs should be replaced. * Corrected misspellings of "enreypted" in both request fields and variable names * Removed some code from null checks where the result could never be null. These cases were flagged in eclipse as dead code. Change-Id: Iec0c0e86fd772af8b3c9588f11a0ea1e517776fb --- .../src/com/netscape/cmstools/CMCRequest.java | 18 +++- .../netscape/cms/profile/common/EnrollProfile.java | 111 ++++++++++++++------- .../cms/servlet/common/CMCOutputTemplate.java | 40 ++++---- .../com/netscape/cmsutil/crypto/CryptoUtil.java | 84 ++-------------- 4 files changed, 113 insertions(+), 140 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java index 9c41403..8d49b20 100644 --- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java +++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java @@ -52,6 +52,9 @@ import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.EncryptionAlgorithm; +import org.mozilla.jss.crypto.IVParameterSpec; +import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.Signature; @@ -1718,19 +1721,30 @@ public class CMCRequest { CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName); SymmetricKey symKey = CryptoUtil.unwrap( token, + SymmetricKey.AES, + 128, SymmetricKey.Usage.DECRYPT, privKey, - recipient.getEncryptedKey().toByteArray()); + recipient.getEncryptedKey().toByteArray(), + KeyWrapAlgorithm.RSA); + if (symKey == null) { System.out.println(method + "symKey returned null from CryptoUtil.unwrap(). Abort!"); System.exit(1); } System.out.println(method + "symKey unwrapped."); + // TODO(alee) The code below should be replaced by code that generates a random IV + byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec default_iv = new IVParameterSpec(iv); + byte challenge[] = CryptoUtil.decryptUsingSymmetricKey( token, + default_iv, encCI.getEncryptedContent().toByteArray(), - symKey); + symKey, + EncryptionAlgorithm.AES_128_CBC); + if (challenge == null) { System.out .println(method + "challenge returned null from CryptoUtil.decryptUsingSymmetricKey(). Abort!"); 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 index 1443a0a..12fb736 100644 --- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java +++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java @@ -45,7 +45,11 @@ import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.HMACAlgorithm; +import org.mozilla.jss.crypto.IVParameterSpec; +import org.mozilla.jss.crypto.KeyGenAlgorithm; +import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.pkcs10.CertificationRequest; @@ -399,6 +403,10 @@ public abstract class EnrollProfile extends BasicProfile String tokenName = CMS.getConfigStore().getString("cmc.token", CryptoUtil.INTERNAL_TOKEN_NAME); token = CryptoUtil.getCryptoToken(tokenName); + // TODO(alee) Replace the IV definition with a call that generates a random IV of the correct length + byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec ivps = new IVParameterSpec(iv); + PublicKey userPubKey = X509Key.parsePublicKey(new DerValue(req_key_data)); if (userPubKey == null) { msg = method + "userPubKey null after X509Key.parsePublicKey"; @@ -406,37 +414,57 @@ public abstract class EnrollProfile extends BasicProfile throw new EBaseException(msg); } - SymmetricKey symKey = CryptoUtil.generateKey(token); - byte[] pop_encreyptedData = CryptoUtil.encryptUsingSymmetricKey( - token, symKey, challenge); - if (pop_encreyptedData == null) { - msg = method + "pop_encreyptedData null"; + SymmetricKey symKey = CryptoUtil.generateKey( + token, + KeyGenAlgorithm.AES, + 128, + null, + true); + + byte[] pop_encryptedData = CryptoUtil.encryptUsingSymmetricKey( + token, + symKey, + challenge, + EncryptionAlgorithm.AES_128_CBC, + ivps); + + if (pop_encryptedData == null) { + msg = method + "pop_encryptedData null"; CMS.debug(msg); throw new EBaseException(msg); } - byte[] pop_sysPubEncreyptedSession = CryptoUtil.wrapUsingPublicKey( - token, issuanceProtPubKey, symKey); - if (pop_sysPubEncreyptedSession == null) { - msg = method + "pop_sysPubEncreyptedSession null"; + byte[] pop_sysPubEncryptedSession = CryptoUtil.wrapUsingPublicKey( + token, + issuanceProtPubKey, + symKey, + KeyWrapAlgorithm.RSA); + + if (pop_sysPubEncryptedSession == null) { + msg = method + "pop_sysPubEncryptedSession null"; CMS.debug(msg); throw new EBaseException(msg); } - byte[] pop_userPubEncreyptedSession = CryptoUtil.wrapUsingPublicKey( - token, userPubKey, symKey); - if (pop_userPubEncreyptedSession == null) { - msg = method + "pop_userPubEncreyptedSession null"; + + byte[] pop_userPubEncryptedSession = CryptoUtil.wrapUsingPublicKey( + token, + userPubKey, + symKey, + KeyWrapAlgorithm.RSA); + + if (pop_userPubEncryptedSession == null) { + msg = method + "pop_userPubEncryptedSession null"; CMS.debug(msg); throw new EBaseException(msg); } CMS.debug(method + "POP challenge fields generated successfully...setting request extData"); - req.setExtData("pop_encreyptedData", pop_encreyptedData); + req.setExtData("pop_encryptedData", pop_encryptedData); - req.setExtData("pop_sysPubEncreyptedSession", pop_sysPubEncreyptedSession); + req.setExtData("pop_sysPubEncryptedSession", pop_sysPubEncryptedSession); - req.setExtData("pop_userPubEncreyptedSession", pop_userPubEncreyptedSession); + req.setExtData("pop_userPubEncryptedSession", pop_userPubEncryptedSession); // now compute and set witness CMS.debug(method + "now compute and set witness"); @@ -1038,19 +1066,19 @@ public abstract class EnrollProfile extends BasicProfile } // now verify the POP witness - byte[] pop_encreyptedData = req.getExtDataInByteArray("pop_encreyptedData"); - if (pop_encreyptedData == null) { + byte[] pop_encryptedData = req.getExtDataInByteArray("pop_encryptedData"); + if (pop_encryptedData == null) { msg = method + - "pop_encreyptedData not found in request:" + + "pop_encryptedData not found in request:" + reqId.toString(); CMS.debug(msg); return null; } - byte[] pop_sysPubEncreyptedSession = req.getExtDataInByteArray("pop_sysPubEncreyptedSession"); - if (pop_sysPubEncreyptedSession == null) { + byte[] pop_sysPubEncryptedSession = req.getExtDataInByteArray("pop_sysPubEncryptedSession"); + if (pop_sysPubEncryptedSession == null) { msg = method + - "pop_sysPubEncreyptedSession not found in request:" + + "pop_sysPubEncryptedSession not found in request:" + reqId.toString(); CMS.debug(msg); return null; @@ -1082,17 +1110,31 @@ public abstract class EnrollProfile extends BasicProfile SymmetricKey symKey = CryptoUtil.unwrap( token, + SymmetricKey.AES, + 128, SymmetricKey.Usage.DECRYPT, issuanceProtPrivKey, - pop_sysPubEncreyptedSession); + pop_sysPubEncryptedSession, + KeyWrapAlgorithm.RSA); + if (symKey == null) { msg = "symKey null after CryptoUtil.unwrap returned"; CMS.debug(msg); return null; } + // TODO(alee) The code below should be replaced by code that gets the IV from the Pop request + // This IV is supposed to be random + byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec default_iv = new IVParameterSpec(iv); + byte[] challenge_b = CryptoUtil.decryptUsingSymmetricKey( - token, pop_encreyptedData, symKey); + token, + default_iv, + pop_encryptedData, + symKey, + EncryptionAlgorithm.AES_128_CBC); + if (challenge_b == null) { msg = method + "challenge_b null after decryptUsingSymmetricKey returned"; CMS.debug(msg); @@ -1596,23 +1638,16 @@ public abstract class EnrollProfile extends BasicProfile witness_bytes, hashAlg, macAlg); - String authMgrID = - (String) sessionContext.get(SessionContext.AUTH_MANAGER_ID); String auditSubjectID = null; if (verified) { - // update auditSubjectID - if (sessionContext != null) { - auditSubjectID = (String) - sessionContext.get(SessionContext.USER_ID); - CMS.debug(method + "current auditSubjectID was:"+ auditSubjectID); - CMS.debug(method + "identity verified. Updating auditSubjectID"); - CMS.debug(method + "updated auditSubjectID is:"+ ident_string); - auditSubjectID = ident_string; - sessionContext.put(SessionContext.USER_ID, auditSubjectID); - } else { //very unlikely - CMS.debug(method + "sessionContext null; cannot update auditSubjectID"); - } + auditSubjectID = (String) + sessionContext.get(SessionContext.USER_ID); + CMS.debug(method + "current auditSubjectID was:"+ auditSubjectID); + CMS.debug(method + "identity verified. Updating auditSubjectID"); + CMS.debug(method + "updated auditSubjectID is:"+ ident_string); + auditSubjectID = ident_string; + sessionContext.put(SessionContext.USER_ID, auditSubjectID); auditMessage = CMS.getLogMessage( AuditEvent.CMC_PROOF_OF_IDENTIFICATION, 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 index c130a1e..8e47298 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java +++ b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java @@ -43,6 +43,7 @@ import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.pkcs11.PK11PubKey; import org.mozilla.jss.pkix.cert.Certificate; @@ -433,10 +434,7 @@ public class CMCOutputTemplate { ResponseBody respBody = new ResponseBody(controlSeq, cmsSeq, otherMsgSeq); - if (respBody != null) - CMS.debug(method + " after new ResponseBody, respBody not null"); - else - CMS.debug(method + " after new ResponseBody, respBody null"); + CMS.debug(method + " after new ResponseBody, respBody not null"); ContentInfo contentInfo = getContentInfo(respBody, certs); ByteArrayOutputStream fos = new ByteArrayOutputStream(); @@ -489,30 +487,25 @@ public class CMCOutputTemplate { CMS.debug(method + "popChallengeRequired true"); byte[] cmc_msg = req.getExtDataInByteArray(IEnrollProfile.CTX_CERT_REQUEST); - byte[] pop_encreyptedData = req.getExtDataInByteArray("pop_encreyptedData"); + byte[] pop_encryptedData = req.getExtDataInByteArray("pop_encryptedData"); //don't need this for encryptedPOP, but need to check for existence anyway - byte[] pop_sysPubEncreyptedSession = req.getExtDataInByteArray("pop_sysPubEncreyptedSession"); - byte[] pop_userPubEncreyptedSession = req.getExtDataInByteArray("pop_userPubEncreyptedSession"); - if ((pop_encreyptedData != null) && - (pop_sysPubEncreyptedSession != null) && - (pop_userPubEncreyptedSession != null)) { + byte[] pop_sysPubEncryptedSession = req.getExtDataInByteArray("pop_sysPubEncryptedSession"); + byte[] pop_userPubEncryptedSession = req.getExtDataInByteArray("pop_userPubEncryptedSession"); + if ((pop_encryptedData != null) && + (pop_sysPubEncryptedSession != null) && + (pop_userPubEncryptedSession != null)) { // generate encryptedPOP here // algs are hard-coded for now try { EnvelopedData envData = CryptoUtil.createEnvelopedData( - pop_encreyptedData, - pop_userPubEncreyptedSession); + pop_encryptedData, + pop_userPubEncryptedSession); if (envData == null) { msg = "envData null returned by createEnvelopedData"; throw new EBaseException(method + msg); } ContentInfo ci = new ContentInfo(envData); - if (ci == null) { - msg = "ci null from new ContentInfo"; - CMS.debug(msg); - throw new EBaseException(method + msg); - } CMS.debug(method + "now we can compose encryptedPOP"); TaggedRequest.Template tReqTemplate = new TaggedRequest.Template(); @@ -524,17 +517,18 @@ public class CMCOutputTemplate { throw new EBaseException(method + msg); } + // TODO(alee) The code below should be replaced by code that generates a random IV + byte[] default_iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + + OBJECT_IDENTIFIER oid = EncryptionAlgorithm.AES_128_CBC.toOID(); + AlgorithmIdentifier aid = new AlgorithmIdentifier(oid, new OCTET_STRING(default_iv)); + encPop = new EncryptedPOP( tReq, ci, - CryptoUtil.getDefaultEncAlg(), + aid, CryptoUtil.getDefaultHashAlg(), new OCTET_STRING(req.getExtDataInByteArray("pop_witness"))); - if (encPop == null) { - msg = "encPop null returned by new EncryptedPOP"; - CMS.debug(msg); - throw new EBaseException(method + msg); - } } catch (Exception e) { CMS.debug(method + " excepton:" + e); diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java index 8b8c443..95b8f81 100644 --- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java +++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java @@ -2572,15 +2572,15 @@ public class CryptoUtil { throw new Exception(method + msg); } + // TODO(alee) Replace the below with a random IV that is likely passed in + byte[] default_iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + OBJECT_IDENTIFIER oid = EncryptionAlgorithm.AES_128_CBC.toOID(); + AlgorithmIdentifier aid = new AlgorithmIdentifier(oid, new OCTET_STRING(default_iv)); + EncryptedContentInfo encCInfo = new EncryptedContentInfo( ContentInfo.DATA, - getDefaultEncAlg(), + aid, new OCTET_STRING(encContent)); - if (encCInfo == null) { - msg = method + "encCInfo null from new EncryptedContentInfo"; - System.out.println(msg); - throw new Exception(method + msg); - } Name name = new Name(); name.addCommonName("unUsedIssuerName"); //unused; okay for cmc EncryptedPOP @@ -2589,11 +2589,6 @@ public class CryptoUtil { new IssuerAndSerialNumber(name, new INTEGER(0)), //unUsed new AlgorithmIdentifier(RSA_ENCRYPTION, new NULL()), new OCTET_STRING(encSymKey)); - if (recipient == null) { - msg = method + "recipient null from new RecipientInfo"; - System.out.println(msg); - throw new Exception(method + msg); - } SET recipients = new SET(); recipients.addElement(recipient); @@ -2615,77 +2610,14 @@ public class CryptoUtil { * the defaults */ - private static byte default_iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; - private static IVParameterSpec default_IV = new IVParameterSpec(default_iv); - - // this generates a temporary 128 bit AES symkey with defaults - public static SymmetricKey generateKey(CryptoToken token) throws Exception { - return generateKey(token, -//TODO: KeyGenAlgorithm.AES, 128, - KeyGenAlgorithm.DES3, 128 /*unused*/, - null, true); - } - - // decryptUsingSymmetricKey with default algorithms - public static byte[] decryptUsingSymmetricKey(CryptoToken token, byte[] encryptedData, SymmetricKey wrappingKey) throws Exception { - return decryptUsingSymmetricKey(token, default_IV, encryptedData, - wrappingKey, - EncryptionAlgorithm.DES3_CBC_PAD); -//TODO: EncryptionAlgorithm.AES_128_CBC); - } - - // encryptUsingSymmetricKey with default algorithms - public static byte[] encryptUsingSymmetricKey(CryptoToken token, SymmetricKey wrappingKey, byte[] data) throws Exception { - return encryptUsingSymmetricKey( - token, - wrappingKey, - data, - EncryptionAlgorithm.DES3_CBC_PAD, -//TODO: EncryptionAlgorithm.AES_128_CBC, - default_IV); - } - - // wrapUsingPublicKey using default algorithm - public static byte[] wrapUsingPublicKey(CryptoToken token, PublicKey wrappingKey, SymmetricKey data) throws Exception { - return wrapUsingPublicKey(token, wrappingKey, data, KeyWrapAlgorithm.RSA); - } - - // unwrap sym key using default algorithms - public static SymmetricKey unwrap(CryptoToken token, SymmetricKey.Usage usage, PrivateKey wrappingKey, byte[] wrappedSymKey) throws Exception { - return unwrap( - token, -//TODO: SymmetricKey.AES, - SymmetricKey.DES3, - 0, - usage, - wrappingKey, - wrappedSymKey, - getDefaultKeyWrapAlg()); - } - - public static AlgorithmIdentifier getDefaultEncAlg() - throws Exception { - OBJECT_IDENTIFIER oid = - EncryptionAlgorithm.DES3_CBC.toOID(); -//TODO: EncryptionAlgorithm.AES_128_CBC.toOID(); - - AlgorithmIdentifier aid = - new AlgorithmIdentifier(oid, new OCTET_STRING(default_iv)); - return aid; - } - public static String getDefaultHashAlgName() { return ("SHA-256"); } - public static KeyWrapAlgorithm getDefaultKeyWrapAlg() { - return KeyWrapAlgorithm.RSA; - } - public static AlgorithmIdentifier getDefaultHashAlg() throws Exception { AlgorithmIdentifier hashAlg; - hashAlg = new AlgorithmIdentifier(CryptoUtil.getHashAlgorithmOID("SHA-256")); + hashAlg = new AlgorithmIdentifier(CryptoUtil.getHashAlgorithmOID(getDefaultHashAlgName())); return hashAlg; } @@ -2768,8 +2700,6 @@ public class CryptoUtil { */ public static String getNameFromHashAlgorithm(AlgorithmIdentifier ai) throws NoSuchAlgorithmException { - OBJECT_IDENTIFIER oid = null; - System.out.println("CryptoUtil: getNameFromHashAlgorithm: " + ai.getOID().toString()); if (ai != null) { if (ai.getOID().equals((DigestAlgorithm.SHA256).toOID())) { -- 1.8.3.1 From 772e05e746570c13afeb60516c07a3fb95ca3e78 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 1 Jun 2017 23:38:04 +0200 Subject: [PATCH 10/27] Removed superfluous deployment configuration backup. The pkispawn has been modified to generate a temporary backup file (instead of permanent and timestamped backup files) of the deployment configuration file before normalizing its content. The temporary backup will be removed automatically when the normalization is complete. https://pagure.io/dogtagpki/issue/2674 Change-Id: Ia541e23314acc120954fa574d1f6f885961c8047 --- base/server/sbin/pkispawn | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn index 742f579..1aa7079 100755 --- a/base/server/sbin/pkispawn +++ b/base/server/sbin/pkispawn @@ -34,8 +34,6 @@ try: import ldap import os import requests - import time - from time import strftime as date import traceback import pki from pki.server.deployment import pkiconfig as config @@ -610,12 +608,9 @@ def main(argv): def sanitize_user_deployment_cfg(cfg): - # Generate a timestamp - ticks = time.time() - timestamp = date('%Y%m%d%H%M%S', time.localtime(ticks)) # Correct any section headings in the user's configuration file - for line in fileinput.FileInput(cfg, inplace=1, backup='.' + timestamp): + for line in fileinput.FileInput(cfg, inplace=1): # Remove extraneous leading and trailing whitespace from all lines line = line.strip() # Normalize section headings to match '/etc/pki/default.cfg' -- 1.8.3.1 From f7b6305396581f5916498cc4ea8247596bf39aaf Mon Sep 17 00:00:00 2001 From: Matthew Harmsen Date: Fri, 2 Jun 2017 02:10:02 +0200 Subject: [PATCH 11/27] Fixed pylint issues - https://pagure.io/dogtagpki/issue/2713 - Build failure due to Pylint issues --- base/common/python/pki/cli/pkcs12.py | 4 ++-- base/common/python/pki/encoder.py | 12 ++++++------ base/server/python/pki/server/cli/audit.py | 8 ++++---- base/server/python/pki/server/cli/ca.py | 16 ++++++++-------- base/server/python/pki/server/cli/db.py | 8 ++++---- base/server/python/pki/server/cli/kra.py | 20 ++++++++++---------- base/server/python/pki/server/cli/ocsp.py | 4 ++-- base/server/python/pki/server/cli/subsystem.py | 4 ++-- base/server/python/pki/server/cli/tks.py | 4 ++-- base/server/python/pki/server/cli/tps.py | 20 ++++++++++---------- base/server/python/pki/server/upgrade.py | 3 --- 11 files changed, 50 insertions(+), 53 deletions(-) diff --git a/base/common/python/pki/cli/pkcs12.py b/base/common/python/pki/cli/pkcs12.py index 8934d33..6b99fcf 100644 --- a/base/common/python/pki/cli/pkcs12.py +++ b/base/common/python/pki/cli/pkcs12.py @@ -62,10 +62,10 @@ class PKCS12ImportCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'v', [ + opts, _ = getopt.gnu_getopt(argv, 'v', [ 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'no-trust-flags', 'no-user-certs', 'no-ca-certs', 'overwrite', 'verbose', 'debug', 'help']) diff --git a/base/common/python/pki/encoder.py b/base/common/python/pki/encoder.py index 8485ab8..d3298bc 100644 --- a/base/common/python/pki/encoder.py +++ b/base/common/python/pki/encoder.py @@ -82,14 +82,14 @@ class CustomTypeEncoder(json.JSONEncoder): """ # pylint: disable=E0202 - def default(self, obj): + def default(self, o): for k, v in iteritems(TYPES): - if isinstance(obj, v): - return {k: obj.__dict__} + if isinstance(o, v): + return {k: o.__dict__} for t in itervalues(NOTYPES): - if isinstance(obj, t): - return self.attr_name_conversion(obj.__dict__, type(obj)) - return json.JSONEncoder.default(self, obj) + if isinstance(o, t): + return self.attr_name_conversion(o.__dict__, type(o)) + return json.JSONEncoder.default(self, o) @staticmethod def attr_name_conversion(attr_dict, object_class): diff --git a/base/server/python/pki/server/cli/audit.py b/base/server/python/pki/server/cli/audit.py index 0833ca8..a19ca8c 100644 --- a/base/server/python/pki/server/cli/audit.py +++ b/base/server/python/pki/server/cli/audit.py @@ -56,10 +56,10 @@ class AuditFileFindCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'verbose', 'help']) @@ -129,10 +129,10 @@ class AuditFileVerifyCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'verbose', 'help']) diff --git a/base/server/python/pki/server/cli/ca.py b/base/server/python/pki/server/cli/ca.py index 550e511..48c7dba 100644 --- a/base/server/python/pki/server/cli/ca.py +++ b/base/server/python/pki/server/cli/ca.py @@ -78,10 +78,10 @@ class CACertChainExportCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) @@ -190,10 +190,10 @@ class CACertRequestFindCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'cert=', 'cert-file=', 'verbose', 'help']) @@ -268,10 +268,10 @@ class CACertRequestShowCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, args = getopt.gnu_getopt(args, 'i:v', [ + opts, args = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'output-file=', 'verbose', 'help']) @@ -356,10 +356,10 @@ class CAClonePrepareCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) diff --git a/base/server/python/pki/server/cli/db.py b/base/server/python/pki/server/cli/db.py index 17b1a2f..3df911c 100644 --- a/base/server/python/pki/server/cli/db.py +++ b/base/server/python/pki/server/cli/db.py @@ -58,10 +58,10 @@ class DBSchemaUpgrade(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, 'i:D:w:v', ['instance=', 'bind-dn=', 'bind-password=', + argv, 'i:D:w:v', ['instance=', 'bind-dn=', 'bind-password=', 'verbose', 'help']) except getopt.GetoptError as e: @@ -150,10 +150,10 @@ class DBUpgrade(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, 'i:v', ['instance=', 'verbose', 'help']) + argv, 'i:v', ['instance=', 'verbose', 'help']) except getopt.GetoptError as e: print('ERROR: ' + str(e)) diff --git a/base/server/python/pki/server/cli/kra.py b/base/server/python/pki/server/cli/kra.py index 3724014..6c1ade9 100644 --- a/base/server/python/pki/server/cli/kra.py +++ b/base/server/python/pki/server/cli/kra.py @@ -81,10 +81,10 @@ class KRAClonePrepareCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) @@ -203,10 +203,10 @@ class KRADBVLVFindCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -315,10 +315,10 @@ class KRADBVLVAddCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -421,10 +421,10 @@ class KRADBVLVDeleteCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -543,10 +543,10 @@ class KRADBVLVReindexCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] diff --git a/base/server/python/pki/server/cli/ocsp.py b/base/server/python/pki/server/cli/ocsp.py index 3e9b6aa..b3e4e45 100644 --- a/base/server/python/pki/server/cli/ocsp.py +++ b/base/server/python/pki/server/cli/ocsp.py @@ -67,10 +67,10 @@ class OCSPClonePrepareCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py index 8395bd2..10af8ca 100644 --- a/base/server/python/pki/server/cli/subsystem.py +++ b/base/server/python/pki/server/cli/subsystem.py @@ -66,10 +66,10 @@ class SubsystemFindCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'verbose', 'help']) diff --git a/base/server/python/pki/server/cli/tks.py b/base/server/python/pki/server/cli/tks.py index 0e6a998..0bfaca1 100644 --- a/base/server/python/pki/server/cli/tks.py +++ b/base/server/python/pki/server/cli/tks.py @@ -67,10 +67,10 @@ class TKSClonePrepareCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) diff --git a/base/server/python/pki/server/cli/tps.py b/base/server/python/pki/server/cli/tps.py index 03df8de..a34bbd9 100644 --- a/base/server/python/pki/server/cli/tps.py +++ b/base/server/python/pki/server/cli/tps.py @@ -76,10 +76,10 @@ class TPSClonePrepareCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: - opts, _ = getopt.gnu_getopt(args, 'i:v', [ + opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', 'verbose', 'help']) @@ -195,10 +195,10 @@ class TPSDBVLVFindCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -306,10 +306,10 @@ class TPSDBVLVAddCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -419,10 +419,10 @@ class TPSDBVLVDeleteCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] @@ -554,10 +554,10 @@ class TPSDBVLVReindexCLI(pki.cli.CLI): print(' --help Show help message.') print() - def execute(self, args): + def execute(self, argv): try: opts, _ = getopt.gnu_getopt( - args, + argv, 'i:D:w:x:g:v', ['instance=', 'bind-dn=', 'bind-password=', 'generate-ldif=', 'verbose', 'help'] diff --git a/base/server/python/pki/server/upgrade.py b/base/server/python/pki/server/upgrade.py index 2c72e48..926c683 100644 --- a/base/server/python/pki/server/upgrade.py +++ b/base/server/python/pki/server/upgrade.py @@ -38,9 +38,6 @@ SUBSYSTEM_TRACKER = '%s/CS.cfg' class PKIServerUpgradeScriptlet(pki.upgrade.PKIUpgradeScriptlet): - def __init__(self): - super(PKIServerUpgradeScriptlet, self).__init__() - def get_backup_dir(self): return BACKUP_DIR + '/' + str(self.version) + '/' + str(self.index) -- 1.8.3.1 From b3d851b864dc986a9af8ffcb1962f8e7b4de3114 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 1 Jun 2017 04:54:05 +0200 Subject: [PATCH 12/27] Added upgrade script for keepAliveTimeout. An upgrade script has been added to set the keepAliveTimeout attribute for the Secure connector in the server.xml. https://pagure.io/dogtagpki/issue/2687 Change-Id: Ia61ed49d0ffc26d4bb44738c71fc663bde37fb1d --- base/common/upgrade/10.4.1/.gitignore | 4 ++ base/common/upgrade/10.4.2/.gitignore | 4 ++ base/common/upgrade/10.4.3/.gitignore | 4 ++ base/common/upgrade/10.4.4/.gitignore | 4 ++ base/common/upgrade/10.4.5/.gitignore | 4 ++ base/common/upgrade/10.4.6/.gitignore | 4 ++ base/server/upgrade/10.4.3/.gitignore | 4 ++ base/server/upgrade/10.4.4/.gitignore | 4 ++ base/server/upgrade/10.4.5/.gitignore | 4 ++ .../upgrade/10.4.6/01-UpdateKeepAliveTimeout | 59 ++++++++++++++++++++++ 10 files changed, 95 insertions(+) create mode 100644 base/common/upgrade/10.4.1/.gitignore create mode 100644 base/common/upgrade/10.4.2/.gitignore create mode 100644 base/common/upgrade/10.4.3/.gitignore create mode 100644 base/common/upgrade/10.4.4/.gitignore create mode 100644 base/common/upgrade/10.4.5/.gitignore create mode 100644 base/common/upgrade/10.4.6/.gitignore create mode 100644 base/server/upgrade/10.4.3/.gitignore create mode 100644 base/server/upgrade/10.4.4/.gitignore create mode 100644 base/server/upgrade/10.4.5/.gitignore create mode 100755 base/server/upgrade/10.4.6/01-UpdateKeepAliveTimeout diff --git a/base/common/upgrade/10.4.1/.gitignore b/base/common/upgrade/10.4.1/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.1/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/common/upgrade/10.4.2/.gitignore b/base/common/upgrade/10.4.2/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.2/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/common/upgrade/10.4.3/.gitignore b/base/common/upgrade/10.4.3/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.3/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/common/upgrade/10.4.4/.gitignore b/base/common/upgrade/10.4.4/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.4/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/common/upgrade/10.4.5/.gitignore b/base/common/upgrade/10.4.5/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.5/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/common/upgrade/10.4.6/.gitignore b/base/common/upgrade/10.4.6/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/common/upgrade/10.4.6/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/server/upgrade/10.4.3/.gitignore b/base/server/upgrade/10.4.3/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/server/upgrade/10.4.3/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/server/upgrade/10.4.4/.gitignore b/base/server/upgrade/10.4.4/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/server/upgrade/10.4.4/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/server/upgrade/10.4.5/.gitignore b/base/server/upgrade/10.4.5/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/base/server/upgrade/10.4.5/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/base/server/upgrade/10.4.6/01-UpdateKeepAliveTimeout b/base/server/upgrade/10.4.6/01-UpdateKeepAliveTimeout new file mode 100755 index 0000000..31c4d1b --- /dev/null +++ b/base/server/upgrade/10.4.6/01-UpdateKeepAliveTimeout @@ -0,0 +1,59 @@ +#!/usr/bin/python +# Authors: +# Endi S. Dewata +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2017 Red Hat, Inc. +# All rights reserved. +# + +from __future__ import absolute_import +import os +from lxml import etree + +import pki + + +class UpdateKeepAliveTimeout( + pki.server.upgrade.PKIServerUpgradeScriptlet): + + def __init__(self): + super(UpdateKeepAliveTimeout, self).__init__() + self.message = 'Update keepAliveTimeout parameter' + + self.parser = etree.XMLParser(remove_blank_text=True) + + def upgrade_instance(self, instance): + + server_xml = os.path.join(instance.conf_dir, 'server.xml') + self.backup(server_xml) + + document = etree.parse(server_xml, self.parser) + + server = document.getroot() + connectors = server.findall('.//Connector') + + for connector in connectors: + + # find the Secure connector + name = connector.get('name') + if name != 'Secure': + continue + + # set the keepAliveTimeout parameter to 5 minutes + connector.set('keepAliveTimeout', '300000') + + with open(server_xml, 'wb') as f: + document.write(f, pretty_print=True, encoding='utf-8') -- 1.8.3.1 From 03235ab51d102ba722e71adf00d2f721c77cd222 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 1 Jun 2017 21:02:41 +0200 Subject: [PATCH 15/27] Fixed random password generator. The equal sign is no longer used to generate random password since it's already used as token name and password delimiter in password.conf. https://pagure.io/dogtagpki/issue/2556 Change-Id: Id59f9aae4d01958f69c305e7d5cda44ce5c81c84 --- base/common/python/pki/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py index 1fc5385..0478b32 100644 --- a/base/common/python/pki/__init__.py +++ b/base/common/python/pki/__init__.py @@ -45,6 +45,11 @@ PACKAGE_VERSION = SHARE_DIR + '/VERSION' CERT_HEADER = "-----BEGIN CERTIFICATE-----" CERT_FOOTER = "-----END CERTIFICATE-----" +# Valid punctuation characters for random password. +# This is identical to string.punctuation minus the equal +# sign since it's used as delimiter in password.conf. +PUNCTUATIONS = '!"#$%&\'()*+,-./:;<>?@[\\]^_`{|}~' + def read_text(message, options=None, default=None, delimiter=':', @@ -139,7 +144,7 @@ def generate_password(): * digits (string.digits) * ASCII lowercase letters (string.ascii_lowercase) * ASCII uppercase letters (string.ascii_uppercase) - * ASCII non-alphanumeric characters (string.punctuation) + * ASCII non-alphanumeric characters (PUNCTUATIONS) * non-ASCII characters If an ASCII uppercase letter is the first character of the password, @@ -159,7 +164,7 @@ def generate_password(): valid_chars = string.digits +\ string.ascii_lowercase +\ string.ascii_uppercase +\ - string.punctuation + PUNCTUATIONS chars = [] @@ -168,7 +173,7 @@ def generate_password(): chars.append(rnd.choice(string.digits)) chars.append(rnd.choice(string.ascii_lowercase)) chars.append(rnd.choice(string.ascii_uppercase)) - chars.append(rnd.choice(string.punctuation)) + chars.append(rnd.choice(PUNCTUATIONS)) # add 6 additional random chars chars.extend(rnd.choice(valid_chars) for i in range(6)) -- 1.8.3.1 From 08bf26f786b8d233382c6fedfad5d33d8c11d78f Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Thu, 1 Jun 2017 17:46:27 -0400 Subject: [PATCH 16/27] Fix NPE in audit log invocation Some audit log objects take a RequestId or KeyId, on which we call toString(). In some cases, we were creating a KeyId or RequestId with null values, resulting in an NPE. We fix these in this patch. Bugzilla BZ# 1458043 Change-Id: I38d5a20e9920966c8414d56afd7690dc3c11a1db --- base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java | 3 ++- base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java index ed20394..5e3b8a9 100644 --- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java +++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java @@ -1128,7 +1128,8 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove r = queue.findRequest(new RequestId(reqID)); auditAgents = r.getExtDataInString(IRequest.ATTR_APPROVE_AGENTS); - keyID = new KeyId(r.getExtDataInBigInteger("serialNumber")); + BigInteger serialNumber = r.getExtDataInBigInteger("serialNumber"); + keyID = serialNumber != null? new KeyId(serialNumber) : null; // set transient parameters params = createVolatileRequest(r.getRequestId()); diff --git a/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java b/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java index c0b5cdd..891b083 100644 --- a/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java +++ b/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java @@ -283,7 +283,7 @@ public class TokenKeyRecoveryService implements IService { // retrieve based on Certificate String cert_s = request.getExtDataInString(ATTR_USER_CERT); String keyid_s = request.getExtDataInString(IRequest.NETKEY_ATTR_KEYID); - KeyId keyId = new KeyId(request.getExtDataInString(IRequest.NETKEY_ATTR_KEYID)); + KeyId keyId = keyid_s != null ? new KeyId(keyid_s): null; /* have to have at least one */ if ((cert_s == null) && (keyid_s == null)) { CMS.debug("TokenKeyRecoveryService: not receive cert or keyid"); @@ -593,7 +593,7 @@ public class TokenKeyRecoveryService implements IService { return true; } catch (Exception e) { - CMS.debug("TokenKeyRecoveryService: " + e.toString()); + CMS.debug(e); request.setExtData(IRequest.RESULT, Integer.valueOf(4)); } -- 1.8.3.1 From 29dbed75f1c214a065cd3bcc438d0584fd980d4f Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 2 Jun 2017 18:46:01 +0200 Subject: [PATCH 17/27] Excluded backslash from random password. The backslash is no longer used for generating random password since it's causing SSL hanshake failure. https://pagure.io/dogtagpki/issue/2676 Change-Id: I2e63769b16fc3fa617b27dccb7b85f139714a411 --- base/common/python/pki/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py index 0478b32..1a6f5c2 100644 --- a/base/common/python/pki/__init__.py +++ b/base/common/python/pki/__init__.py @@ -46,9 +46,10 @@ CERT_HEADER = "-----BEGIN CERTIFICATE-----" CERT_FOOTER = "-----END CERTIFICATE-----" # Valid punctuation characters for random password. -# This is identical to string.punctuation minus the equal -# sign since it's used as delimiter in password.conf. -PUNCTUATIONS = '!"#$%&\'()*+,-./:;<>?@[\\]^_`{|}~' +# This is based on string.punctuation except: +# - equal sign since it's used as delimiter in password.conf +# - backslash since it's causing SSL handshake failure +PUNCTUATIONS = '!"#$%&\'()*+,-./:;<>?@[]^_`{|}~' def read_text(message, -- 1.8.3.1 From a614eb15476adb00df571d3ea05fdd8ea282141d Mon Sep 17 00:00:00 2001 From: Jack Magne Date: Fri, 2 Jun 2017 15:40:52 -0700 Subject: [PATCH 18/27] Resolve #1663 Add SCP03 support . This particular fix resolves a simple issue when formatting a token in FIPS mode for SCP03. --- base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java | 7 ++++--- base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java index 5e5646b..3b80f27 100644 --- a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java +++ b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java @@ -421,10 +421,11 @@ public class SecureChannel { throw new TPSException(method + "Failed to calculate card cryptogram!", TPSStatus.STATUS_ERROR_SECURE_CHANNEL); } - CMS.debug(method + " dumped macSessionKey: " + new TPSBuffer(macSessionKey.getEncoded()).toHexString() ); + if(cardCryptogram != null) + CMS.debug(method + " actual card cryptogram " + cardCryptogram.toHexString()); - CMS.debug(method + " actual card cryptogram " + cardCryptogram.toHexString()); - CMS.debug(method + " calculated card cryptogram " + calculatedCardCryptogram.toHexString()); + if(calculatedCardCryptogram != null) + CMS.debug(method + " calculated card cryptogram " + calculatedCardCryptogram.toHexString()); ExternalAuthenticateAPDUGP211 externalAuth = new ExternalAuthenticateAPDUGP211(hostCryptogram, /* secLevel */secLevelGP211); diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java index 0f96915..e1a5748 100644 --- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java +++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java @@ -957,6 +957,10 @@ public class TPSProcessor { kekSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret, kekSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES); + CMS.debug(" encSessionKeySCP03 " + encSessionKeySCP03); + CMS.debug(" macSessionKeySCP03 " + macSessionKeySCP03); + CMS.debug(" kekSessionKeySCP03 " + kekSessionKeySCP03); + channel = new SecureChannel(this, encSessionKeySCP03, macSessionKeySCP03, kekSessionKeySCP03, drmDesKeyBuff, kekDesKeyBuff, keyCheckBuff, keyDiversificationData, cardChallenge, -- 1.8.3.1 From af41896f083e1101b1ba62f6cc8c9be6064c6786 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 02:07:04 +0200 Subject: [PATCH 19/27] Refactored MainCLI.loadPassword() (part 1). The method that loads password from a file in MainCLI has been renamed into loadPassword() and modified to return early for clarity. https://pagure.io/dogtagpki/issue/2717 Change-Id: I9b031c31040c2d00f04d9997abcdae38163bf6d5 --- .../src/com/netscape/cmstools/cli/MainCLI.java | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java index 1b9c569..2402196 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java @@ -229,7 +229,7 @@ public class MainCLI extends CLI { options.addOption(null, "version", false, "Show version number."); } - public String[] readPlaintextPasswordFromFile(String pwfile) throws Exception { + public String[] loadPassword(String pwfile) throws Exception { String[] tokenPassword = { null, null }; BufferedReader br = null; String delimiter = "="; @@ -238,11 +238,16 @@ public class MainCLI extends CLI { br = new BufferedReader(new FileReader(pwfile)); String line = br.readLine(); - if (line != null) { - if (line.isEmpty()) { - throw new Exception("File '" + pwfile + "' does not define a token or a password!"); - } else if (line.contains(delimiter)) { + if (line == null) { + throw new Exception("File '" + pwfile + "' is empty!"); + } + + if (line.isEmpty()) { + throw new Exception("File '" + pwfile + "' does not define a token or a password!"); + } + + if (line.contains(delimiter)) { // Process 'token=password' format: // // Token: tokenPassword[0] @@ -270,10 +275,7 @@ public class MainCLI extends CLI { // Set simple 'password' (do not trim leading/trailing whitespace) tokenPassword[1] = line; } - } else { - // Case of an empty password file - throw new Exception("File '" + pwfile + "' is empty!"); - } + } finally { if (br != null) { br.close(); @@ -397,7 +399,7 @@ public class MainCLI extends CLI { if (certPasswordFile != null) { // read client security database password from specified file - tokenPasswordPair = readPlaintextPasswordFromFile(certPasswordFile); + tokenPasswordPair = loadPassword(certPasswordFile); // XXX TBD set client security database token certPassword = tokenPasswordPair[1]; @@ -411,7 +413,7 @@ public class MainCLI extends CLI { if (passwordFile != null) { // read user password from specified file - tokenPasswordPair = readPlaintextPasswordFromFile(passwordFile); + tokenPasswordPair = loadPassword(passwordFile); // XXX TBD set user token password = tokenPasswordPair[1]; -- 1.8.3.1 From 9741b7873005419b922ba79c61ef98ae17cb58be Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 02:03:32 +0200 Subject: [PATCH 20/27] Refactored MainCLI.loadPassword() (part 2). The MainCLI.loadPassword() has been modified to fix the code indentation. https://pagure.io/dogtagpki/issue/2717 Change-Id: I7d208f1f4568f2fb1323ab206f45af5c0338b53f --- .../src/com/netscape/cmstools/cli/MainCLI.java | 49 +++++++++++----------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java index 2402196..2b6b173 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java @@ -247,35 +247,36 @@ public class MainCLI extends CLI { throw new Exception("File '" + pwfile + "' does not define a token or a password!"); } - if (line.contains(delimiter)) { - // Process 'token=password' format: - // - // Token: tokenPassword[0] - // Password: tokenPassword[1] - // - tokenPassword = line.split(delimiter, 2); - - // Always trim leading/trailing whitespace from 'token' - tokenPassword[0] = tokenPassword[0].trim(); - - // Check for undefined 'token' - if (tokenPassword[0].isEmpty()) { - // Set default 'token' - tokenPassword[0] = CryptoUtil.INTERNAL_TOKEN_NAME; - } - - // Check for undefined 'password' - if (tokenPassword[1].isEmpty()) { - throw new Exception("File '" + pwfile + "' does not define a password!"); - } - } else { + if (line.contains(delimiter)) { + // Process 'token=password' format: + // + // Token: tokenPassword[0] + // Password: tokenPassword[1] + // + tokenPassword = line.split(delimiter, 2); + + // Always trim leading/trailing whitespace from 'token' + tokenPassword[0] = tokenPassword[0].trim(); + + // Check for undefined 'token' + if (tokenPassword[0].isEmpty()) { // Set default 'token' tokenPassword[0] = CryptoUtil.INTERNAL_TOKEN_NAME; + } - // Set simple 'password' (do not trim leading/trailing whitespace) - tokenPassword[1] = line; + // Check for undefined 'password' + if (tokenPassword[1].isEmpty()) { + throw new Exception("File '" + pwfile + "' does not define a password!"); } + } else { + // Set default 'token' + tokenPassword[0] = CryptoUtil.INTERNAL_TOKEN_NAME; + + // Set simple 'password' (do not trim leading/trailing whitespace) + tokenPassword[1] = line; + } + } finally { if (br != null) { br.close(); -- 1.8.3.1 From 729468e46612569da4c93b15bc0d674099003aba Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 02:28:00 +0200 Subject: [PATCH 21/27] Refactored MainCLI.loadPassword() (part 3). The MainCLI.loadPassword() has been modified to use try-with- resources. Some log messages have been added for clarity. https://pagure.io/dogtagpki/issue/2717 Change-Id: Ic4950ba677613565f548b51d1f985177c6726510 --- .../src/com/netscape/cmstools/cli/MainCLI.java | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java index 2b6b173..dcc60e2 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java @@ -230,12 +230,11 @@ public class MainCLI extends CLI { } public String[] loadPassword(String pwfile) throws Exception { + String[] tokenPassword = { null, null }; - BufferedReader br = null; String delimiter = "="; - try { - br = new BufferedReader(new FileReader(pwfile)); + try (BufferedReader br = new BufferedReader(new FileReader(pwfile))) { String line = br.readLine(); @@ -276,11 +275,6 @@ public class MainCLI extends CLI { // Set simple 'password' (do not trim leading/trailing whitespace) tokenPassword[1] = line; } - - } finally { - if (br != null) { - br.close(); - } } return tokenPassword; @@ -399,7 +393,7 @@ public class MainCLI extends CLI { config.setCertNickname(certNickname); if (certPasswordFile != null) { - // read client security database password from specified file + if (verbose) System.out.println("Loading NSS password from " + certPasswordFile); tokenPasswordPair = loadPassword(certPasswordFile); // XXX TBD set client security database token @@ -413,7 +407,7 @@ public class MainCLI extends CLI { config.setUsername(username); if (passwordFile != null) { - // read user password from specified file + if (verbose) System.out.println("Loading user password from " + passwordFile); tokenPasswordPair = loadPassword(passwordFile); // XXX TBD set user token @@ -494,15 +488,18 @@ public class MainCLI extends CLI { // If password is specified, use password to access security token if (config.getCertPassword() != null) { - if (verbose) System.out.println("Logging into security token"); + try { CryptoManager manager = CryptoManager.getInstance(); String tokenName = config.getTokenName(); - CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName); + if (verbose) System.out.println("Getting " + (tokenName == null ? "internal" : tokenName) + " token"); + CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName); manager.setThreadToken(token); + if (verbose) System.out.println("Logging into " + token.getName()); + Password password = new Password(config.getCertPassword().toCharArray()); token.login(password); -- 1.8.3.1 From d4e5176702b3a08a67233e069ac211e95e01b228 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 01:32:37 +0200 Subject: [PATCH 22/27] Refactored CLI.runExternal(). The methods for running external commands in various CLI classes have been merged into CLI.runExternal(). https://pagure.io/dogtagpki/issue/2717 Change-Id: I5b6d136db699d3bb48e4f36f7f187d0240bbbf62 --- .../src/com/netscape/cmstools/cli/CLI.java | 35 ++++++++++++++++++++++ .../src/com/netscape/cmstools/cli/MainCLI.java | 10 +++---- .../cmstools/client/ClientCertImportCLI.java | 23 ++------------ .../cmstools/client/ClientCertModifyCLI.java | 35 +++++----------------- .../cmstools/client/ClientCertRequestCLI.java | 10 +++---- .../cmstools/client/ClientCertShowCLI.java | 27 +++-------------- .../netscape/cmstools/client/ClientInitCLI.java | 25 ++++++---------- 7 files changed, 65 insertions(+), 100 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java index 4911b8a..60db7a1 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java @@ -18,6 +18,7 @@ package com.netscape.cmstools.cli; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; @@ -351,4 +352,38 @@ public class CLI { public static void setVerbose(boolean verbose) { CLI.verbose = verbose; } + + public void runExternal(List command) throws CLIException, IOException, InterruptedException { + String[] array = command.toArray(new String[command.size()]); + runExternal(array); + } + + public void runExternal(String[] command) throws CLIException, IOException, InterruptedException { + + if (verbose) { + + System.out.print("External command:"); + + for (String c : command) { + + boolean quote = c.contains(" "); + + System.out.print(" "); + + if (quote) System.out.print("\""); + System.out.print(c); + if (quote) System.out.print("\""); + } + + System.out.println(); + } + + Runtime rt = Runtime.getRuntime(); + Process p = rt.exec(command); + int rc = p.waitFor(); + + if (rc != 0) { + throw new CLIException("External command failed. RC: " + rc, rc); + } + } } diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java index dcc60e2..51861b5 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java @@ -473,12 +473,10 @@ public class MainCLI extends CLI { "--empty-password" }; - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(commands); - - int rc = p.waitFor(); - if (rc != 0) { - throw new Exception("Unable to create security database: " + certDatabase.getAbsolutePath() + " (rc: " + rc + ")"); + try { + runExternal(commands); + } catch (Exception e) { + throw new Exception("Unable to create security database", e); } } diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java index 9cb3e67..687dfc4 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java @@ -21,14 +21,12 @@ package com.netscape.cmstools.client; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; -import java.io.IOException; import java.io.PrintWriter; import java.net.URI; import java.util.Arrays; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; -import org.apache.commons.lang.StringUtils; import com.netscape.certsrv.cert.CertClient; import com.netscape.certsrv.cert.CertData; @@ -283,8 +281,7 @@ public class ClientCertImportCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to import certificate file", e); } @@ -305,25 +302,9 @@ public class ClientCertImportCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to import PKCS #12 file", e); } } - - public void run(String[] command) throws IOException, InterruptedException { - - if (verbose) { - System.out.println("Command: " + StringUtils.join(command, " ")); - } - - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(command); - int rc = p.waitFor(); - - if (rc != 0) { - throw new IOException("Command failed. RC: " + rc); - } - } } diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertModifyCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertModifyCLI.java index f229e67..8ae7c6d 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertModifyCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertModifyCLI.java @@ -18,8 +18,6 @@ package com.netscape.cmstools.client; -import java.io.IOException; - import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; @@ -75,38 +73,19 @@ public class ClientCertModifyCLI extends CLI { String trustAttributes = cmd.getOptionValue("trust", "u,u,u"); - int rc = modifyCert( - mainCLI.certDatabase.getAbsolutePath(), - nickname, - trustAttributes); - - if (rc != 0) { - MainCLI.printMessage("Modified failed"); - return; - } - - MainCLI.printMessage("Modified certificate \"" + nickname + "\""); - } - - public int modifyCert( - String dbPath, - String nickname, - String trustAttributes) throws IOException, InterruptedException { - String[] command = { "/usr/bin/certutil", "-M", - "-d", dbPath, + "-d", mainCLI.certDatabase.getAbsolutePath(), "-n", nickname, "-t", trustAttributes }; - return run(command); - } - - public int run(String[] command) throws IOException, InterruptedException { + try { + runExternal(command); + } catch (Exception e) { + throw new Exception("Unable to modify certificate", e); + } - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(command); - return p.waitFor(); + MainCLI.printMessage("Modified certificate \"" + nickname + "\""); } } diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java index 696ab8b..a14bb24 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java @@ -386,12 +386,10 @@ public class ClientCertRequestCLI extends CLI { "-n", subjectDN }; - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(commands); - - int rc = p.waitFor(); - if (rc != 0) { - throw new Exception("CSR generation failed"); + try { + runExternal(commands); + } catch (Exception e) { + throw new Exception("CSR generation failed", e); } if (verbose) { diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java index 2242b37..bb60fbf 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java @@ -20,13 +20,11 @@ package com.netscape.cmstools.client; import java.io.File; import java.io.FileWriter; -import java.io.IOException; import java.io.PrintWriter; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.lang.RandomStringUtils; -import org.apache.commons.lang.StringUtils; import org.mozilla.jss.crypto.X509Certificate; import com.netscape.certsrv.client.PKIClient; @@ -192,8 +190,7 @@ public class ClientCertShowCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to export PKCS #12 file", e); } @@ -215,8 +212,7 @@ public class ClientCertShowCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to export certificate", e); } @@ -238,8 +234,7 @@ public class ClientCertShowCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to export private key", e); } @@ -261,23 +256,9 @@ public class ClientCertShowCLI extends CLI { }; try { - run(command); - + runExternal(command); } catch (Exception e) { throw new Exception("Unable to export client certificate and private key", e); } } - - public void run(String[] command) throws IOException, InterruptedException { - - if (verbose) System.out.println("Command: " + StringUtils.join(command, " ")); - - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(command); - int rc = p.waitFor(); - - if (rc != 0) { - throw new IOException("Command failed. RC: " + rc); - } - } } diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientInitCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientInitCLI.java index 893b40b..7e018de 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientInitCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientInitCLI.java @@ -95,12 +95,11 @@ public class ClientInitCLI extends CLI { File passwordFile = new File(certDatabase, "password.txt"); try { - String[] commands = { - "/usr/bin/certutil", "-N", - "-d", certDatabase.getAbsolutePath(), - }; - - List list = new ArrayList<>(Arrays.asList(commands)); + List list = new ArrayList<>(); + list.add("/usr/bin/certutil"); + list.add("-N"); + list.add("-d"); + list.add(certDatabase.getAbsolutePath()); if (mainCLI.config.getCertPassword() == null) { list.add("--empty-password"); @@ -114,16 +113,10 @@ public class ClientInitCLI extends CLI { list.add(passwordFile.getAbsolutePath()); } - commands = new String[list.size()]; - list.toArray(commands); - - Runtime rt = Runtime.getRuntime(); - Process p = rt.exec(commands); - - int rc = p.waitFor(); - if (rc != 0) { - MainCLI.printMessage("Client initialization failed"); - return; + try { + runExternal(list); + } catch (Exception e) { + throw new Exception("Client initialization failed", e); } MainCLI.printMessage("Client initialized"); -- 1.8.3.1 From 3ef47867df74eb9dce408b88756ccce7d7438da5 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 00:29:29 +0200 Subject: [PATCH 23/27] Fixed pki client-cert-import CLI. The pki client-cert-import CLI has been modified to provide a password file when invoking the certutil -A command. https://pagure.io/dogtagpki/issue/2717 Change-Id: If32f9eeb39d140aaef38c9bc1933f3ae0f57a5a2 --- .../cmstools/client/ClientCertImportCLI.java | 94 +++++++++++++++------- 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java index 687dfc4..1c67f99 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java @@ -23,7 +23,9 @@ import java.io.FileOutputStream; import java.io.FileWriter; import java.io.PrintWriter; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; @@ -128,6 +130,20 @@ public class ClientCertImportCLI extends CLI { String serialNumber = cmd.getOptionValue("serial"); String trustAttributes = cmd.getOptionValue("trust"); + File nssdbPasswordFile = null; + + if (mainCLI.config.getCertPassword() != null) { + + // store NSS database password in a temporary file + + nssdbPasswordFile = File.createTempFile("pki-client-cert-import-", ".nssdb-pwd"); + nssdbPasswordFile.deleteOnExit(); + + try (PrintWriter out = new PrintWriter(new FileWriter(nssdbPasswordFile))) { + out.print(mainCLI.config.getCertPassword()); + } + } + // load the certificate if (certPath != null) { @@ -137,7 +153,8 @@ public class ClientCertImportCLI extends CLI { trustAttributes = "u,u,u"; importCert( - mainCLI.certDatabase.getAbsolutePath(), + mainCLI.certDatabase, + nssdbPasswordFile, certPath, nickname, trustAttributes); @@ -150,7 +167,8 @@ public class ClientCertImportCLI extends CLI { trustAttributes = "CT,c,"; importCert( - mainCLI.certDatabase.getAbsolutePath(), + mainCLI.certDatabase, + nssdbPasswordFile, caCertPath, nickname, trustAttributes); @@ -164,7 +182,7 @@ public class ClientCertImportCLI extends CLI { } else if (pkcs12Password != null) { // store password into a temporary file - File pkcs12PasswordFile = File.createTempFile("pki-client-cert-import-", ".pwd"); + File pkcs12PasswordFile = File.createTempFile("pki-client-cert-import-", ".pkcs12-pwd"); pkcs12PasswordFile.deleteOnExit(); try (PrintWriter out = new PrintWriter(new FileWriter(pkcs12PasswordFile))) { @@ -182,8 +200,8 @@ public class ClientCertImportCLI extends CLI { // import certificates and private key into PKCS #12 file importPKCS12( - mainCLI.certDatabase.getAbsolutePath(), - mainCLI.config.getCertPassword(), + mainCLI.certDatabase, + nssdbPasswordFile, pkcs12Path, pkcs12PasswordPath); @@ -212,7 +230,8 @@ public class ClientCertImportCLI extends CLI { trustAttributes = "CT,c,"; importCert( - mainCLI.certDatabase.getAbsolutePath(), + mainCLI.certDatabase, + nssdbPasswordFile, certFile.getAbsolutePath(), nickname, trustAttributes); @@ -245,7 +264,8 @@ public class ClientCertImportCLI extends CLI { trustAttributes = "u,u,u"; importCert( - mainCLI.certDatabase.getAbsolutePath(), + mainCLI.certDatabase, + nssdbPasswordFile, certFile.getAbsolutePath(), nickname, trustAttributes); @@ -263,8 +283,9 @@ public class ClientCertImportCLI extends CLI { } public void importCert( - String dbPath, - String certPath, + File dbPath, + File dbPasswordFile, + String certFile, String nickname, String trustAttributes) throws Exception { @@ -272,13 +293,23 @@ public class ClientCertImportCLI extends CLI { throw new Exception("Missing certificate nickname."); } - String[] command = { - "/bin/certutil", "-A", - "-d", dbPath, - "-i", certPath, - "-n", nickname, - "-t", trustAttributes - }; + List command = new ArrayList<>(); + command.add("/bin/certutil"); + command.add("-A"); + command.add("-d"); + command.add(dbPath.getAbsolutePath()); + + if (dbPasswordFile != null) { + command.add("-f"); + command.add(dbPasswordFile.getAbsolutePath()); + } + + command.add("-i"); + command.add(certFile); + command.add("-n"); + command.add(nickname); + command.add("-t"); + command.add(trustAttributes); try { runExternal(command); @@ -288,18 +319,25 @@ public class ClientCertImportCLI extends CLI { } public void importPKCS12( - String dbPath, - String dbPassword, - String pkcs12Path, - String pkcs12PasswordPath) throws Exception { - - String[] command = { - "/bin/pk12util", - "-d", dbPath, - "-K", dbPassword, - "-i", pkcs12Path, - "-w", pkcs12PasswordPath - }; + File dbPath, + File dbPasswordFile, + String pkcs12File, + String pkcs12PasswordFile) throws Exception { + + List command = new ArrayList<>(); + command.add("/bin/pk12util"); + command.add("-d"); + command.add(dbPath.getAbsolutePath()); + + if (dbPasswordFile != null) { + command.add("-k"); + command.add(dbPasswordFile.getAbsolutePath()); + } + + command.add("-i"); + command.add(pkcs12File); + command.add("-w"); + command.add(pkcs12PasswordFile); try { runExternal(command); -- 1.8.3.1 From 64b7b7abfed29b6a520be66414139364d713461e Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 3 Jun 2017 03:52:09 +0200 Subject: [PATCH 24/27] Fixed default CA cert trust flags in pki CLI. The pki CLI has been modified to use CT,C,C as the default trust flags for CA certificate import operations. https://pagure.io/dogtagpki/issue/2726 Change-Id: I68c5a0303459319cc746a77703d0a420f4f68377 --- base/common/python/pki/cli/pkcs12.py | 2 +- .../src/com/netscape/cmstools/client/ClientCertImportCLI.java | 4 ++-- .../cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/base/common/python/pki/cli/pkcs12.py b/base/common/python/pki/cli/pkcs12.py index 6b99fcf..2f8aabf 100644 --- a/base/common/python/pki/cli/pkcs12.py +++ b/base/common/python/pki/cli/pkcs12.py @@ -237,7 +237,7 @@ class PKCS12ImportCLI(pki.cli.CLI): trust_flags = cert_info['trust_flags'] else: # default trust flags for CA certificates - trust_flags = 'CT,c,c' + trust_flags = 'CT,C,C' if main_cli.verbose: print('Exporting %s (%s) from PKCS #12 file' % (nickname, cert_id)) diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java index 1c67f99..844453e 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertImportCLI.java @@ -164,7 +164,7 @@ public class ClientCertImportCLI extends CLI { if (verbose) System.out.println("Importing CA certificate from " + caCertPath + "."); if (trustAttributes == null) - trustAttributes = "CT,c,"; + trustAttributes = "CT,C,C"; importCert( mainCLI.certDatabase, @@ -227,7 +227,7 @@ public class ClientCertImportCLI extends CLI { } if (trustAttributes == null) - trustAttributes = "CT,c,"; + trustAttributes = "CT,C,C"; importCert( mainCLI.certDatabase, diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java index c9a375f..ebade36 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java +++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java @@ -1113,6 +1113,7 @@ public class ConfigurationUtils { | InternalCertificate.VALID_CA); } else if (isAuditSigningCert(name)) { + // set trust flags to u,u,Pu icert.setObjectSigningTrust(InternalCertificate.USER | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER); -- 1.8.3.1 From c0b2daef934a8f5ac1c61d673865348aa2a0f702 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Thu, 25 May 2017 15:32:14 +1000 Subject: [PATCH 25/27] Improve exception message for null AuthorityKeyIdentifier When the Authority Key Identifier extension cannot be instantiated, we currently fail with a generic "extension not found" error message. Throw a better exception for this case in particular, and improve the exception message for the general case of attempting to add a null exception. Fixes: https://pagure.io/dogtagpki/issue/2705 Change-Id: Ic79742d8a228391275ffe5bfeef0a324f6b431bd --- .../netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java | 4 ++++ base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java index 42931de..f8d8b44 100644 --- a/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java +++ b/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java @@ -183,6 +183,10 @@ public class AuthorityKeyIdentifierExtDefault extends CAEnrollDefault { } catch (EBaseException e) { throw new EProfileException(e); } + if (ext == null) { + throw new EProfileException( + "Could not instantiate AuthorityKeyIdentifier extension."); + } addExtension(PKIXExtensions.AuthorityKey_Id.toString(), ext, info); } diff --git a/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java index 1d5bfc4..6192888 100644 --- a/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java +++ b/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java @@ -367,7 +367,7 @@ public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDe protected void addExtension(String name, Extension ext, X509CertInfo info) throws EProfileException { if (ext == null) { - throw new EProfileException("extension not found"); + throw new EProfileException("addExtension: extension '" + name + "' is null"); } CertificateExtensions exts = null; -- 1.8.3.1