diff options
| author | Fraser Tweedale <ftweedal@redhat.com> | 2016-05-31 16:10:05 +1000 |
|---|---|---|
| committer | Fraser Tweedale <ftweedal@redhat.com> | 2016-06-03 15:48:18 +1000 |
| commit | f11e0b372e3a0736050dd9e2858fce3178171ee6 (patch) | |
| tree | 547a90c2fd927345ffa9167c5409e52d22b96f7d /base/ca/src/com | |
| parent | f78af863edb020db763ce7920b3b0a6ea61d8e5e (diff) | |
| download | pki-f11e0b372e3a0736050dd9e2858fce3178171ee6.tar.gz pki-f11e0b372e3a0736050dd9e2858fce3178171ee6.tar.xz pki-f11e0b372e3a0736050dd9e2858fce3178171ee6.zip | |
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
Diffstat (limited to 'base/ca/src/com')
| -rw-r--r-- | base/ca/src/com/netscape/ca/CertificateAuthority.java | 24 | ||||
| -rw-r--r-- | base/ca/src/com/netscape/ca/ExternalProcessKeyRetriever.java (renamed from base/ca/src/com/netscape/ca/IPACustodiaKeyRetriever.java) | 33 |
2 files changed, 45 insertions, 12 deletions
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java index 68db50e99..93c5a9fb4 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; @@ -3227,6 +3228,8 @@ public class CertificateAuthority */ private boolean _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); @@ -3235,11 +3238,23 @@ public class CertificateAuthority return false; } + 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); @@ -3248,7 +3263,8 @@ public class CertificateAuthority CMS.debug("Class is not an instance of KeyRetriever: " + className); CMS.debug(e); return false; - } catch (InstantiationException | IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { CMS.debug("Could not instantiate class: " + className); CMS.debug(e); return false; diff --git a/base/ca/src/com/netscape/ca/IPACustodiaKeyRetriever.java b/base/ca/src/com/netscape/ca/ExternalProcessKeyRetriever.java index 4a162d370..6aee9716e 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); |
