G'day comrades, Please review the attached two patches, which...
(Patch 0120) - provide for passing of configuration (from CS.cfg) to KeyRetriever implementations - generalise IPACustodiaKeyRetriever to ExternalProcessKeyRetriever, which executes a configured executable rather than a hardcoded one (Patch 0121) - remove pki-ipa-retrieve-key script; it is being moved to FreeIPA repo Cheers, Fraser
From 34fe6c81202a4ba7d3f3788193fe3d93faeaceff Mon Sep 17 00:00:00 2001 From: Fraser Tweedale <[email protected]> Date: Tue, 31 May 2016 16:10:05 +1000 Subject: [PATCH 120/121] Lightweight CAs: generalise subprocess-based key retrieval The IPACustodiaKeyRetriever doesn't really do anything specific to IPA or Custodia; it merely executes a certain executable with a particular behavioural contract. Add support for passing configuration to KeyRetriever instances, and rename IPACustodiaKeyRetriever to ExternalProcessKeyRetriever, updating it to use the "executable" config property instead of a hardcoded filename. Part of: https://fedorahosted.org/pki/ticket/1625 --- .../src/com/netscape/ca/CertificateAuthority.java | 24 +++++++++++++--- ...iever.java => ExternalProcessKeyRetriever.java} | 33 ++++++++++++++++------ 2 files changed, 45 insertions(+), 12 deletions(-) rename base/ca/src/com/netscape/ca/{IPACustodiaKeyRetriever.java => ExternalProcessKeyRetriever.java} (71%) diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java index 5b2f382c29a716f3e72695b7da5406bb85b34845..6ba9ffed3736f38e4ee1fbf3fb058fdf62dac9f9 100644 --- a/base/ca/src/com/netscape/ca/CertificateAuthority.java +++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java @@ -24,6 +24,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; import java.security.KeyPair; import java.security.MessageDigest; @@ -3181,6 +3182,8 @@ public class CertificateAuthority public void run() { String KR_CLASS_KEY = "features.authority.keyRetrieverClass"; + String KR_CONFIG_KEY = "features.authority.keyRetrieverConfig"; + String className = null; try { className = CMS.getConfigStore().getString(KR_CLASS_KEY); @@ -3189,11 +3192,23 @@ public class CertificateAuthority return; } + IConfigStore krConfig = CMS.getConfigStore().getSubStore(KR_CONFIG_KEY); + KeyRetriever kr = null; try { - kr = Class.forName(className) - .asSubclass(KeyRetriever.class) - .newInstance(); + Class<? extends KeyRetriever> cls = + Class.forName(className).asSubclass(KeyRetriever.class); + + // If there is an accessible constructor that takes + // an IConfigStore, invoke that; otherwise invoke + // the nullary constructor. + try { + kr = cls.getDeclaredConstructor(IConfigStore.class) + .newInstance(krConfig); + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException e) { + kr = cls.newInstance(); + } } catch (ClassNotFoundException e) { CMS.debug("Could not find class: " + className); CMS.debug(e); @@ -3202,7 +3217,8 @@ public class CertificateAuthority CMS.debug("Class is not an instance of KeyRetriever: " + className); CMS.debug(e); return; - } catch (InstantiationException | IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { CMS.debug("Could not instantiate class: " + className); CMS.debug(e); return; diff --git a/base/ca/src/com/netscape/ca/IPACustodiaKeyRetriever.java b/base/ca/src/com/netscape/ca/ExternalProcessKeyRetriever.java similarity index 71% rename from base/ca/src/com/netscape/ca/IPACustodiaKeyRetriever.java rename to base/ca/src/com/netscape/ca/ExternalProcessKeyRetriever.java index 4a162d3702fccc19dfef792a5213c653286930f3..6aee9716e1e5953018ed4c3f3316c9b7d4c88a45 100644 --- a/base/ca/src/com/netscape/ca/IPACustodiaKeyRetriever.java +++ b/base/ca/src/com/netscape/ca/ExternalProcessKeyRetriever.java @@ -27,13 +27,32 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.ArrayUtils; import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.IConfigStore; + + +public class ExternalProcessKeyRetriever implements KeyRetriever { + protected String executable; + + public ExternalProcessKeyRetriever(IConfigStore config) { + if (config == null) + throw new IllegalArgumentException("Missing config"); + + try { + this.executable = config.getString("executable"); + } catch (EPropertyNotFound e) { + throw new IllegalArgumentException("Missing 'executable' config property"); + } catch (EBaseException e) { + throw new RuntimeException(e); + } + } -public class IPACustodiaKeyRetriever implements KeyRetriever { public Result retrieveKey(String nickname, Collection<String> hostPorts) { - CMS.debug("Running IPACustodiaKeyRetriever"); + CMS.debug("Running ExternalProcessKeyRetriever"); Stack<String> command = new Stack<>(); - command.push("/usr/libexec/pki-ipa-retrieve-key"); + command.push(this.executable); command.push(nickname); for (String hostPort : hostPorts) { @@ -47,11 +66,9 @@ public class IPACustodiaKeyRetriever implements KeyRetriever { if (exitValue != 0) continue; - /* Custodia returns a PEM-encoded certificate and a - * base64-encoded PKIArchiveOptions containing the - * wrapped private key. These values are output by - * the Python 'pki-ipa-retrieve-key' program, - * separated by a null byte (password first) + /* Read a PEM-encoded certificate and a base64-encoded + * PKIArchiveOptions containing the wrapped private key, + * separated by a null byte. */ byte[] output = IOUtils.toByteArray(p.getInputStream()); int splitIndex = ArrayUtils.indexOf(output, (byte) 0); -- 2.5.5
From 6781eb1365660963deb3df2e0dcd5d45ba48372f Mon Sep 17 00:00:00 2001 From: Fraser Tweedale <[email protected]> Date: Tue, 31 May 2016 19:33:17 +1000 Subject: [PATCH 121/121] Lightweight CAs: remove pki-ipa-retrieve-key script For the benefit of code locality and subsequent to the generalisation of IPACustodiaKeyRetriever to ExternalProcessKeyRetriever, the pki-ipa-retrieve-key script is being moved to the FreeIPA codebase. Part of: https://fedorahosted.org/pki/ticket/1625 --- base/server/CMakeLists.txt | 11 -------- base/server/libexec/pki-ipa-retrieve-key | 45 -------------------------------- specs/pki-core.spec | 1 - 3 files changed, 57 deletions(-) delete mode 100755 base/server/libexec/pki-ipa-retrieve-key diff --git a/base/server/CMakeLists.txt b/base/server/CMakeLists.txt index 9e5b27833c8d023e63320c43d64ad64b0055c254..5a6aea96a2317655fb454967f9f218020443bcb8 100644 --- a/base/server/CMakeLists.txt +++ b/base/server/CMakeLists.txt @@ -81,17 +81,6 @@ install( install( DIRECTORY - libexec/ - DESTINATION - ${LIBEXEC_INSTALL_DIR} - FILE_PERMISSIONS - OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ -) - -install( - DIRECTORY upgrade DESTINATION ${DATA_INSTALL_DIR}/server/ diff --git a/base/server/libexec/pki-ipa-retrieve-key b/base/server/libexec/pki-ipa-retrieve-key deleted file mode 100755 index 301f818b859577ef1a861bc7a855b6103a6f3af8..0000000000000000000000000000000000000000 --- a/base/server/libexec/pki-ipa-retrieve-key +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/python - -from __future__ import print_function - -import ConfigParser -import base64 -import os -import sys - -from jwcrypto.common import json_decode - -from ipalib import constants -from ipaplatform.paths import paths -from ipapython.secrets.client import CustodiaClient - -conf = ConfigParser.ConfigParser() -conf.read(paths.IPA_DEFAULT_CONF) -hostname = conf.get('global', 'host') -realm = conf.get('global', 'realm') - -keyname = "ca_wrapped/" + sys.argv[1] -servername = sys.argv[2] - -service = constants.PKI_GSSAPI_SERVICE_NAME -client_keyfile = os.path.join(paths.PKI_TOMCAT, service + '.keys') -client_keytab = os.path.join(paths.PKI_TOMCAT, service + '.keytab') - -client = CustodiaClient( - client=hostname, server=servername, realm=realm, - ldap_uri="ldaps://" + hostname, - client_servicename=service, - keyfile=client_keyfile, keytab=client_keytab, - ) - -result_json = client.fetch_key(keyname, store=False) -result = json_decode(result_json) -certificate = result["certificate"] -wrapped_key = base64.b64decode(result["wrapped_key"]) - -# Custodia returns a PEM-encoded certificate and a base64-encoded -# DER PKIArchiveOptions object. Output these values, separated by a -# null byte (certificate first), to be read by the Java -# IPACustodiaKeyRetriever that invoked this program. - -print(certificate, wrapped_key, sep='\0', end='') diff --git a/specs/pki-core.spec b/specs/pki-core.spec index 04baec4f8f4a4aac1da793873e55e422672800c7..cdd087c11f0d03532bf2713db17cadcbd59bc031 100644 --- a/specs/pki-core.spec +++ b/specs/pki-core.spec @@ -1016,7 +1016,6 @@ systemctl daemon-reload %{_sbindir}/pki-server %{_sbindir}/pki-server-nuxwdog %{_sbindir}/pki-server-upgrade -%{_libexecdir}/pki-ipa-retrieve-key %{python2_sitelib}/pki/server/ %dir %{_datadir}/pki/deployment %{_datadir}/pki/deployment/config/ -- 2.5.5
_______________________________________________ Pki-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/pki-devel
