summaryrefslogtreecommitdiffstats
path: root/base/ca/src/com
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-05-31 16:10:05 +1000
committerFraser Tweedale <ftweedal@redhat.com>2016-06-03 15:48:18 +1000
commitf11e0b372e3a0736050dd9e2858fce3178171ee6 (patch)
tree547a90c2fd927345ffa9167c5409e52d22b96f7d /base/ca/src/com
parentf78af863edb020db763ce7920b3b0a6ea61d8e5e (diff)
downloadpki-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.java24
-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);