Blame SOURCES/0022-Allow-configuration-of-client-SCEP-algorithms.patch

1495bf
From 3523ad7b8b2349ed4ee301b992797902b7288028 Mon Sep 17 00:00:00 2001
1495bf
From: Trevor Vaughan <tvaughan@onyxpoint.com>
1495bf
Date: Fri, 23 Feb 2018 16:11:35 -0500
1495bf
Subject: [PATCH 22/25] Allow configuration of client SCEP algorithms
1495bf
1495bf
* Allow users to set `scep_cipher` and `scep_digest` in their CA
1495bf
configuration. These settings are authoritative and will override
1495bf
anything from the server.  This was added to support connections to
1495bf
systems, such as Dogtag, that do not provide a CA capabilities string
1495bf
and, therefore, are prone to causing incorrect ciphers to be used on the
1495bf
client side.
1495bf
1495bf
* In accordance with the latest SCEP Draft RFC, the default cipher has
1495bf
been changed to AES-256 and the default digest has been changed to
1495bf
SHA-256. These were chosen as reasonable defaults for most users and
1495bf
systems.
1495bf
1495bf
* To ease the determination of which configuration file controls what
1495bf
CA, the output of `getcert list-cas -v` was updated to print a
1495bf
`config-path` entry which will list the specific configuration
1495bf
associated with a given CA.
1495bf
1495bf
Closes #89
1495bf
---
1495bf
 src/getcert.c     |   6 ++
1495bf
 src/prefs.h       |   5 ++
1495bf
 src/scepgen-o.c   | 182 ++++++++++++++++++++++++++++++++++++++++++------------
1495bf
 src/store-files.c |  22 +++++++
1495bf
 src/store-int.h   |   4 ++
1495bf
 src/tdbus.h       |   2 +
1495bf
 src/tdbush.c      | 149 +++++++++++++++++++++++++++++++++++++++++++-
1495bf
 7 files changed, 331 insertions(+), 39 deletions(-)
1495bf
1495bf
diff --git a/src/getcert.c b/src/getcert.c
1495bf
index 35fd0d6..724d125 100644
1495bf
--- a/src/getcert.c
1495bf
+++ b/src/getcert.c
1495bf
@@ -4157,6 +4157,12 @@ list_cas(const char *argv0, int argc, const char **argv)
1495bf
 		if ((s != NULL) && (strlen(s) > 0)) {
1495bf
 			printf(_("\tpost-save command: %s\n"), s);
1495bf
 		}
1495bf
+		if (verbose > 0) {
1495bf
+			printf(_("\tconfig-path: %s\n"),
1495bf
+			       query_rep_s(bus, cas[i], CM_DBUS_CA_INTERFACE,
1495bf
+					   "get_config_file_path",
1495bf
+					   verbose, globals.tctx));
1495bf
+		}
1495bf
 	}
1495bf
 	return 0;
1495bf
 }
1495bf
diff --git a/src/prefs.h b/src/prefs.h
1495bf
index 231aea7..349ec64 100644
1495bf
--- a/src/prefs.h
1495bf
+++ b/src/prefs.h
1495bf
@@ -20,9 +20,12 @@
1495bf
 
1495bf
 enum cm_prefs_cipher {
1495bf
 	cm_prefs_aes128,
1495bf
+	cm_prefs_aes192,
1495bf
 	cm_prefs_aes256,
1495bf
 	cm_prefs_des3,
1495bf
 	cm_prefs_des,
1495bf
+	/* This is for the selection logic */
1495bf
+	cm_prefs_nocipher,
1495bf
 };
1495bf
 
1495bf
 enum cm_prefs_digest {
1495bf
@@ -31,6 +34,8 @@ enum cm_prefs_digest {
1495bf
 	cm_prefs_sha512,
1495bf
 	cm_prefs_sha1,
1495bf
 	cm_prefs_md5,
1495bf
+	/* This is for the selection logic */
1495bf
+	cm_prefs_nodigest,
1495bf
 };
1495bf
 
1495bf
 enum cm_notification_method;
1495bf
diff --git a/src/scepgen-o.c b/src/scepgen-o.c
1495bf
index d11e3de..07c2b8b 100644
1495bf
--- a/src/scepgen-o.c
1495bf
+++ b/src/scepgen-o.c
1495bf
@@ -433,49 +433,155 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
1495bf
 		free(pem);
1495bf
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
1495bf
 	}
1495bf
-	cipher = cm_prefs_des;
1495bf
-	for (i = 0;
1495bf
-	     (ca->cm_ca_capabilities != NULL) &&
1495bf
-	     (ca->cm_ca_capabilities[i] != NULL);
1495bf
-	     i++) {
1495bf
-		capability = ca->cm_ca_capabilities[i];
1495bf
-		if (strcmp(capability, "DES3") == 0) {
1495bf
-			cm_log(1, "Server supports DES3, using that.\n");
1495bf
+
1495bf
+	char* scep_cipher = ca->cm_ca_scep_cipher;
1495bf
+	if (scep_cipher != NULL) {
1495bf
+		/* Force the cipher to whatever is in the configuration */
1495bf
+		if (strcmp(scep_cipher, "AES256") == 0) {
1495bf
+			cipher = cm_prefs_aes256;
1495bf
+		}
1495bf
+		else if (strcmp(scep_cipher, "AES192") == 0) {
1495bf
+			cipher = cm_prefs_aes192;
1495bf
+		}
1495bf
+		else if (strcmp(scep_cipher, "AES128") == 0) {
1495bf
+			cipher = cm_prefs_aes128;
1495bf
+		}
1495bf
+		else if (strcmp(scep_cipher, "DES3") == 0) {
1495bf
 			cipher = cm_prefs_des3;
1495bf
-			break;
1495bf
-		}
1495bf
-	}
1495bf
-	if (cipher == cm_prefs_des) {
1495bf
-		cm_log(1, "Server does not support DES3, using DES.\n");
1495bf
-	}
1495bf
-	pref_digest = cm_prefs_preferred_digest();
1495bf
-	digest = cm_prefs_md5;
1495bf
-	for (i = 0;
1495bf
-	     (ca->cm_ca_capabilities != NULL) &&
1495bf
-	     (ca->cm_ca_capabilities[i] != NULL);
1495bf
-	     i++) {
1495bf
-		capability = ca->cm_ca_capabilities[i];
1495bf
-		if ((pref_digest == cm_prefs_sha1) &&
1495bf
-		    (strcmp(capability, "SHA-1") == 0)) {
1495bf
-			cm_log(1, "Server supports SHA-1, using that.\n");
1495bf
-			digest = cm_prefs_sha1;
1495bf
-			break;
1495bf
 		}
1495bf
-		if ((pref_digest == cm_prefs_sha256) &&
1495bf
-		    (strcmp(capability, "SHA-256") == 0)) {
1495bf
-			cm_log(1, "Server supports SHA-256, using that.\n");
1495bf
-			digest = cm_prefs_sha256;
1495bf
-			break;
1495bf
+		else if (strcmp(scep_cipher, "DES") == 0) {
1495bf
+			cipher = cm_prefs_des;
1495bf
 		}
1495bf
-		if ((pref_digest == cm_prefs_sha512) &&
1495bf
-		    (strcmp(capability, "SHA-512") == 0)) {
1495bf
-			cm_log(1, "Server supports SHA-512, using that.\n");
1495bf
-			digest = cm_prefs_sha512;
1495bf
-			break;
1495bf
+		else {
1495bf
+			cm_log(1, "Option 'scep_cipher' must be one of AES256, AES192, AES128, DES3, or DES. Got '%s'\n", scep_cipher);
1495bf
+			_exit(1);
1495bf
+		}
1495bf
+
1495bf
+		cm_log(1, "SCEP cipher authoritatively set to: '%s'\n", scep_cipher);
1495bf
+	}
1495bf
+	else {
1495bf
+		cipher = cm_prefs_nocipher;
1495bf
+		for (i = 0;
1495bf
+		     (ca->cm_ca_capabilities != NULL) &&
1495bf
+		     (ca->cm_ca_capabilities[i] != NULL);
1495bf
+		     i++) {
1495bf
+			capability = ca->cm_ca_capabilities[i];
1495bf
+			if ((strcmp(capability, "AES-256") == 0) ||
1495bf
+				(strcmp(capability, "AES256") == 0)) {
1495bf
+					cm_log(1, "Server supports AES256, using that.\n");
1495bf
+					cipher = cm_prefs_aes256;
1495bf
+					break;
1495bf
+			}
1495bf
+			if ((strcmp(capability, "AES-192") == 0) ||
1495bf
+				(strcmp(capability, "AES192") == 0)) {
1495bf
+					cm_log(1, "Server supports AES192, using that.\n");
1495bf
+					cipher = cm_prefs_aes192;
1495bf
+					break;
1495bf
+			}
1495bf
+			if ((strcmp(capability, "AES-128") == 0) ||
1495bf
+				(strcmp(capability, "AES128") == 0)) {
1495bf
+					cm_log(1, "Server supports AES128, using that.\n");
1495bf
+					cipher = cm_prefs_aes128;
1495bf
+					break;
1495bf
+			}
1495bf
+			if (strcmp(capability, "AES") == 0) {
1495bf
+				cm_log(1, "Server supports AES, using AES256.\n");
1495bf
+				cipher = cm_prefs_aes256;
1495bf
+				break;
1495bf
+			}
1495bf
+			if (strcmp(capability, "DES3") == 0) {
1495bf
+				cm_log(1, "Server supports DES3, using that.\n");
1495bf
+				cipher = cm_prefs_des3;
1495bf
+				break;
1495bf
+			}
1495bf
+			/* This remains for backward compatibility */
1495bf
+			if (strcmp(capability, "DES") == 0) {
1495bf
+				cm_log(1, "Server supports DES, using that.\n");
1495bf
+				cipher = cm_prefs_des;
1495bf
+				break;
1495bf
+			}
1495bf
+		}
1495bf
+		if (cipher == cm_prefs_nocipher) {
1495bf
+			/* Per the latest Draft RFC */
1495bf
+			cm_log(1, "Could not determine supported CA capabilities, using AES256.\n");
1495bf
+			cipher = cm_prefs_aes256;
1495bf
 		}
1495bf
 	}
1495bf
-	if (digest == cm_prefs_md5) {
1495bf
-		cm_log(1, "Server does not support better digests, using MD5.\n");
1495bf
+
1495bf
+	char* scep_digest = ca->cm_ca_scep_digest;
1495bf
+	if (scep_digest != NULL) {
1495bf
+		/* Force the digest to whatever is in the configuration */
1495bf
+		if (strcmp(scep_digest, "SHA512") == 0) {
1495bf
+			digest = cm_prefs_sha512;
1495bf
+		}
1495bf
+		else if (strcmp(scep_digest, "SHA384") == 0) {
1495bf
+			digest = cm_prefs_sha384;
1495bf
+		}
1495bf
+		else if (strcmp(scep_digest, "SHA256") == 0) {
1495bf
+			digest = cm_prefs_sha256;
1495bf
+		}
1495bf
+		else if (strcmp(scep_digest, "SHA1") == 0) {
1495bf
+			digest = cm_prefs_sha1;
1495bf
+		}
1495bf
+		else if (strcmp(scep_digest, "MD5") == 0) {
1495bf
+			digest = cm_prefs_md5;
1495bf
+		}
1495bf
+		else {
1495bf
+			cm_log(1, "Option 'scep_digest' must be one of AES256, AES192, AES128, DES3, or DES. Got '%s'\n", scep_digest);
1495bf
+			_exit(1);
1495bf
+		}
1495bf
+
1495bf
+		cm_log(1, "SCEP digest authoritatively set to: '%s'\n", scep_digest);
1495bf
+	}
1495bf
+	else {
1495bf
+		pref_digest = cm_prefs_preferred_digest();
1495bf
+		digest = cm_prefs_nodigest;
1495bf
+		for (i = 0;
1495bf
+		     (ca->cm_ca_capabilities != NULL) &&
1495bf
+		     (ca->cm_ca_capabilities[i] != NULL);
1495bf
+		     i++) {
1495bf
+			capability = ca->cm_ca_capabilities[i];
1495bf
+			if ((pref_digest == cm_prefs_sha512) &&
1495bf
+			    ((strcmp(capability, "SHA-512") == 0) ||
1495bf
+				(strcmp(capability, "SHA512") == 0))) {
1495bf
+					cm_log(1, "Server supports SHA-512, using that.\n");
1495bf
+					digest = cm_prefs_sha512;
1495bf
+					break;
1495bf
+			}
1495bf
+			if ((pref_digest == cm_prefs_sha384) &&
1495bf
+			    ((strcmp(capability, "SHA-384") == 0) ||
1495bf
+				(strcmp(capability, "SHA384") == 0))) {
1495bf
+					cm_log(1, "Server supports SHA-384, using that.\n");
1495bf
+					digest = cm_prefs_sha384;
1495bf
+					break;
1495bf
+			}
1495bf
+			if ((pref_digest == cm_prefs_sha256) &&
1495bf
+			    ((strcmp(capability, "SHA-256") == 0) ||
1495bf
+				(strcmp(capability, "SHA256") == 0))) {
1495bf
+					cm_log(1, "Server supports SHA-256, using that.\n");
1495bf
+					digest = cm_prefs_sha256;
1495bf
+					break;
1495bf
+			}
1495bf
+			if ((pref_digest == cm_prefs_sha1) &&
1495bf
+			    ((strcmp(capability, "SHA-1") == 0) ||
1495bf
+				(strcmp(capability, "SHA1") == 0))) {
1495bf
+					cm_log(1, "Server supports SHA-1, using that.\n");
1495bf
+					digest = cm_prefs_sha1;
1495bf
+					break;
1495bf
+			}
1495bf
+			/* This remains for backward compatibility */
1495bf
+			if ((pref_digest == cm_prefs_sha1) &&
1495bf
+			    (strcmp(capability, "MD5") == 0)) {
1495bf
+				cm_log(1, "Server supports MD5, using that.\n");
1495bf
+				digest = cm_prefs_md5;
1495bf
+				break;
1495bf
+			}
1495bf
+		}
1495bf
+		if (digest == cm_prefs_nodigest) {
1495bf
+			/* Per the latest Draft RFC */
1495bf
+			cm_log(1, "Could not determine supported CA capabilities, using SHA256.\n");
1495bf
+			digest = cm_prefs_sha256;
1495bf
+		}
1495bf
 	}
1495bf
 	if (old_cert != NULL) {
1495bf
 		if (cm_pkcs7_envelope_ias(ca->cm_ca_encryption_cert, cipher,
1495bf
diff --git a/src/store-files.c b/src/store-files.c
1495bf
index 977e896..c7195c4 100644
1495bf
--- a/src/store-files.c
1495bf
+++ b/src/store-files.c
1495bf
@@ -206,6 +206,8 @@ enum cm_store_file_field {
1495bf
 	cm_store_ca_field_other_cert_nssdbs,
1495bf
 
1495bf
 	cm_store_ca_field_capabilities,
1495bf
+	cm_store_ca_field_scep_cipher,
1495bf
+	cm_store_ca_field_scep_digest,
1495bf
 	cm_store_ca_field_scep_ca_identifier,
1495bf
 	cm_store_ca_field_encryption_cert,
1495bf
 	cm_store_ca_field_encryption_issuer_cert,
1495bf
@@ -385,6 +387,8 @@ static struct cm_store_file_field_list {
1495bf
 	{cm_store_ca_field_other_cert_nssdbs, "ca_other_cert_dbs"},
1495bf
 
1495bf
 	{cm_store_ca_field_capabilities, "ca_capabilities"},
1495bf
+	{cm_store_ca_field_scep_cipher, "scep_cipher"},
1495bf
+	{cm_store_ca_field_scep_digest, "scep_digest"},
1495bf
 	{cm_store_ca_field_scep_ca_identifier, "scep_ca_identifier"},
1495bf
 	{cm_store_ca_field_encryption_cert, "ca_encryption_cert"},
1495bf
 	{cm_store_ca_field_encryption_issuer_cert, "ca_encryption_issuer_cert"},
1495bf
@@ -725,6 +729,8 @@ cm_store_entry_read(void *parent, const char *filename, FILE *fp)
1495bf
 			case cm_store_ca_field_other_root_cert_nssdbs:
1495bf
 			case cm_store_ca_field_other_cert_nssdbs:
1495bf
 			case cm_store_ca_field_capabilities:
1495bf
+			case cm_store_ca_field_scep_cipher:
1495bf
+			case cm_store_ca_field_scep_digest:
1495bf
 			case cm_store_ca_field_scep_ca_identifier:
1495bf
 			case cm_store_ca_field_encryption_cert:
1495bf
 			case cm_store_ca_field_encryption_issuer_cert:
1495bf
@@ -1523,6 +1529,14 @@ cm_store_ca_read(void *parent, const char *filename, FILE *fp)
1495bf
 				ret->cm_ca_capabilities =
1495bf
 					free_if_empty_multi(ret, p);
1495bf
 				break;
1495bf
+			case cm_store_ca_field_scep_cipher:
1495bf
+				ret->cm_ca_scep_cipher =
1495bf
+					free_if_empty(p);
1495bf
+				break;
1495bf
+			case cm_store_ca_field_scep_digest:
1495bf
+				ret->cm_ca_scep_digest =
1495bf
+					free_if_empty(p);
1495bf
+				break;
1495bf
 			case cm_store_ca_field_scep_ca_identifier:
1495bf
 				ret->cm_ca_scep_ca_identifier =
1495bf
 					free_if_empty(p);
1495bf
@@ -2339,6 +2353,10 @@ cm_store_ca_write(FILE *fp, struct cm_store_ca *ca)
1495bf
 				 ca->cm_ca_other_cert_store_nssdbs);
1495bf
 	cm_store_file_write_strs(fp, cm_store_ca_field_capabilities,
1495bf
 				 ca->cm_ca_capabilities);
1495bf
+	cm_store_file_write_str(fp, cm_store_ca_field_scep_cipher,
1495bf
+				ca->cm_ca_scep_cipher);
1495bf
+	cm_store_file_write_str(fp, cm_store_ca_field_scep_digest,
1495bf
+				ca->cm_ca_scep_digest);
1495bf
 	cm_store_file_write_str(fp, cm_store_ca_field_scep_ca_identifier,
1495bf
 				ca->cm_ca_scep_ca_identifier);
1495bf
 	cm_store_file_write_str(fp, cm_store_ca_field_encryption_cert,
1495bf
@@ -2861,6 +2879,10 @@ cm_store_ca_dup(void *parent, struct cm_store_ca *ca)
1495bf
 
1495bf
 	ret->cm_ca_capabilities =
1495bf
 		cm_store_maybe_strdupv(ret, ca->cm_ca_capabilities);
1495bf
+	ret->cm_ca_scep_cipher =
1495bf
+		cm_store_maybe_strdup(ret, ca->cm_ca_scep_cipher);
1495bf
+	ret->cm_ca_scep_digest =
1495bf
+		cm_store_maybe_strdup(ret, ca->cm_ca_scep_digest);
1495bf
 	ret->cm_ca_scep_ca_identifier =
1495bf
 		cm_store_maybe_strdup(ret, ca->cm_ca_scep_ca_identifier);
1495bf
 	ret->cm_ca_encryption_cert =
1495bf
diff --git a/src/store-int.h b/src/store-int.h
1495bf
index 98b37e6..4a40406 100644
1495bf
--- a/src/store-int.h
1495bf
+++ b/src/store-int.h
1495bf
@@ -349,6 +349,10 @@ struct cm_store_ca {
1495bf
 	char **cm_ca_other_cert_store_nssdbs;
1495bf
 	/* CA capabilities.  Currently only ever SCEP capabilities. */
1495bf
 	char **cm_ca_capabilities;
1495bf
+	/* SCEP Cipher to use. Overrides CA Capabilities */
1495bf
+	char *cm_ca_scep_cipher;
1495bf
+	/* SCEP Digest to use. Overrides CA Capabilities */
1495bf
+	char *cm_ca_scep_digest;
1495bf
 	/* An SCEP CA identifier, for use in gathering an RA (and possibly a
1495bf
 	 * CA) certificate. */
1495bf
 	char *cm_ca_scep_ca_identifier;
1495bf
diff --git a/src/tdbus.h b/src/tdbus.h
1495bf
index 7164f11..e63e783 100644
1495bf
--- a/src/tdbus.h
1495bf
+++ b/src/tdbus.h
1495bf
@@ -119,6 +119,8 @@
1495bf
 #define CM_DBUS_PROP_ROOT_CERTS "root-certs"
1495bf
 #define CM_DBUS_PROP_OTHER_ROOT_CERTS "root-other-certs"
1495bf
 #define CM_DBUS_PROP_OTHER_CERTS "other-certs"
1495bf
+#define CM_DBUS_PROP_SCEP_CIPHER "scep-cipher"
1495bf
+#define CM_DBUS_PROP_SCEP_DIGEST "scep-digest"
1495bf
 #define CM_DBUS_PROP_SCEP_CA_IDENTIFIER "scep-ca-identifier"
1495bf
 #define CM_DBUS_PROP_SCEP_CA_CAPABILITIES "scep-ca-capabilities"
1495bf
 #define CM_DBUS_PROP_SCEP_RA_CERT "scep-ra-cert"
1495bf
diff --git a/src/tdbush.c b/src/tdbush.c
1495bf
index 04fe57e..3ce6c40 100644
1495bf
--- a/src/tdbush.c
1495bf
+++ b/src/tdbush.c
1495bf
@@ -2128,6 +2128,27 @@ ca_get_serial(DBusConnection *conn, DBusMessage *msg,
1495bf
 	}
1495bf
 }
1495bf
 
1495bf
+/* org.fedorahosted.certonger.ca.get_config_file_path */
1495bf
+ca_get_config_file_path(DBusConnection *conn, DBusMessage *msg,
1495bf
+		struct cm_client_info *ci, struct cm_context *ctx)
1495bf
+{
1495bf
+	DBusMessage *rep;
1495bf
+	struct cm_store_ca *ca;
1495bf
+	ca = get_ca_for_request_message(msg, ctx);
1495bf
+	if (ca == NULL) {
1495bf
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1495bf
+	}
1495bf
+	rep = dbus_message_new_method_return(msg);
1495bf
+	if (rep != NULL) {
1495bf
+		cm_tdbusm_set_s(rep, ca->cm_store_private);
1495bf
+		dbus_connection_send(conn, rep, NULL);
1495bf
+		dbus_message_unref(rep);
1495bf
+		return DBUS_HANDLER_RESULT_HANDLED;
1495bf
+	} else {
1495bf
+		return send_internal_ca_error(conn, msg);
1495bf
+	}
1495bf
+}
1495bf
+
1495bf
 /* org.fedorahosted.certonger.ca.refresh */
1495bf
 static DBusHandlerResult
1495bf
 ca_refresh(DBusConnection *conn, DBusMessage *msg,
1495bf
@@ -2262,6 +2283,106 @@ ca_prop_set_external_helper(struct cm_context *ctx, void *parent,
1495bf
 }
1495bf
 
1495bf
 static const char *
1495bf
+ca_prop_get_scep_cipher(struct cm_context *ctx, void *parent,
1495bf
+			       void *record, const char *name)
1495bf
+{
1495bf
+	struct cm_store_ca *ca = record;
1495bf
+
1495bf
+	if (strcmp(name, CM_DBUS_PROP_SCEP_CIPHER) == 0) {
1495bf
+		if (ca->cm_ca_type != cm_ca_external) {
1495bf
+			return "";
1495bf
+		}
1495bf
+		if (ca->cm_ca_scep_cipher != NULL) {
1495bf
+			return ca->cm_ca_scep_cipher;
1495bf
+		} else {
1495bf
+			return "";
1495bf
+		}
1495bf
+	}
1495bf
+	return NULL;
1495bf
+}
1495bf
+
1495bf
+static void
1495bf
+ca_prop_set_scep_cipher(struct cm_context *ctx, void *parent,
1495bf
+			       void *record, const char *name,
1495bf
+			       const char *new_value)
1495bf
+{
1495bf
+	const char *propname[2], *path;
1495bf
+	struct cm_store_ca *ca = record;
1495bf
+	enum cm_ca_phase phase;
1495bf
+
1495bf
+	if (strcmp(name, CM_DBUS_PROP_SCEP_CIPHER) == 0) {
1495bf
+		if (ca->cm_ca_type != cm_ca_external) {
1495bf
+			return;
1495bf
+		}
1495bf
+		talloc_free(ca->cm_ca_scep_cipher);
1495bf
+		ca->cm_ca_scep_cipher = new_value ?
1495bf
+					       talloc_strdup(ca, new_value) :
1495bf
+					       NULL;
1495bf
+		for (phase = 0; phase < cm_ca_phase_invalid; phase++) {
1495bf
+			cm_restart_ca(ctx, ca->cm_nickname, phase);
1495bf
+		}
1495bf
+		propname[0] = CM_DBUS_PROP_SCEP_CIPHER;
1495bf
+		propname[1] = NULL;
1495bf
+		path = talloc_asprintf(parent, "%s/%s",
1495bf
+				       CM_DBUS_CA_PATH,
1495bf
+				       ca->cm_busname);
1495bf
+		cm_tdbush_property_emit_changed(ctx, path,
1495bf
+						CM_DBUS_CA_INTERFACE,
1495bf
+						propname);
1495bf
+	}
1495bf
+}
1495bf
+
1495bf
+static const char *
1495bf
+ca_prop_get_scep_digest(struct cm_context *ctx, void *parent,
1495bf
+			       void *record, const char *name)
1495bf
+{
1495bf
+	struct cm_store_ca *ca = record;
1495bf
+
1495bf
+	if (strcmp(name, CM_DBUS_PROP_SCEP_DIGEST) == 0) {
1495bf
+		if (ca->cm_ca_type != cm_ca_external) {
1495bf
+			return "";
1495bf
+		}
1495bf
+		if (ca->cm_ca_scep_digest != NULL) {
1495bf
+			return ca->cm_ca_scep_digest;
1495bf
+		} else {
1495bf
+			return "";
1495bf
+		}
1495bf
+	}
1495bf
+	return NULL;
1495bf
+}
1495bf
+
1495bf
+static void
1495bf
+ca_prop_set_scep_digest(struct cm_context *ctx, void *parent,
1495bf
+			       void *record, const char *name,
1495bf
+			       const char *new_value)
1495bf
+{
1495bf
+	const char *propname[2], *path;
1495bf
+	struct cm_store_ca *ca = record;
1495bf
+	enum cm_ca_phase phase;
1495bf
+
1495bf
+	if (strcmp(name, CM_DBUS_PROP_SCEP_DIGEST) == 0) {
1495bf
+		if (ca->cm_ca_type != cm_ca_external) {
1495bf
+			return;
1495bf
+		}
1495bf
+		talloc_free(ca->cm_ca_scep_digest);
1495bf
+		ca->cm_ca_scep_digest = new_value ?
1495bf
+					       talloc_strdup(ca, new_value) :
1495bf
+					       NULL;
1495bf
+		for (phase = 0; phase < cm_ca_phase_invalid; phase++) {
1495bf
+			cm_restart_ca(ctx, ca->cm_nickname, phase);
1495bf
+		}
1495bf
+		propname[0] = CM_DBUS_PROP_SCEP_DIGEST;
1495bf
+		propname[1] = NULL;
1495bf
+		path = talloc_asprintf(parent, "%s/%s",
1495bf
+				       CM_DBUS_CA_PATH,
1495bf
+				       ca->cm_busname);
1495bf
+		cm_tdbush_property_emit_changed(ctx, path,
1495bf
+						CM_DBUS_CA_INTERFACE,
1495bf
+						propname);
1495bf
+	}
1495bf
+}
1495bf
+
1495bf
+static const char *
1495bf
 ca_prop_get_scep_ca_identifier(struct cm_context *ctx, void *parent,
1495bf
 			       void *record, const char *name)
1495bf
 {
1495bf
@@ -7232,6 +7353,14 @@ cm_tdbush_iface_ca(void)
1495bf
 	if (ret == NULL) {
1495bf
 		ret = make_interface(CM_DBUS_CA_INTERFACE,
1495bf
 				     make_interface_item(cm_tdbush_interface_method,
1495bf
+							 make_method("get_config_file_path",
1495bf
+								     ca_get_config_file_path,
1495bf
+								     make_method_arg("path",
1495bf
+										     DBUS_TYPE_STRING_AS_STRING,
1495bf
+										     cm_tdbush_method_arg_out,
1495bf
+										     NULL),
1495bf
+								     NULL),
1495bf
+				     make_interface_item(cm_tdbush_interface_method,
1495bf
 							 make_method("get_nickname",
1495bf
 								     ca_get_nickname,
1495bf
 								     make_method_arg("nickname",
1495bf
@@ -7483,6 +7612,24 @@ cm_tdbush_iface_ca(void)
1495bf
 								       NULL, NULL, NULL, NULL, NULL,
1495bf
 								       NULL),
1495bf
 				     make_interface_item(cm_tdbush_interface_property,
1495bf
+							 make_property(CM_DBUS_PROP_SCEP_CIPHER,
1495bf
+								       cm_tdbush_property_string,
1495bf
+								       cm_tdbush_property_readwrite,
1495bf
+								       cm_tdbush_property_special,
1495bf
+								       0,
1495bf
+								       ca_prop_get_scep_cipher, NULL, NULL, NULL, NULL,
1495bf
+								       ca_prop_set_scep_cipher, NULL, NULL, NULL, NULL,
1495bf
+								       NULL),
1495bf
+				     make_interface_item(cm_tdbush_interface_property,
1495bf
+							 make_property(CM_DBUS_PROP_SCEP_DIGEST,
1495bf
+								       cm_tdbush_property_string,
1495bf
+								       cm_tdbush_property_readwrite,
1495bf
+								       cm_tdbush_property_special,
1495bf
+								       0,
1495bf
+								       ca_prop_get_scep_digest, NULL, NULL, NULL, NULL,
1495bf
+								       ca_prop_set_scep_digest, NULL, NULL, NULL, NULL,
1495bf
+								       NULL),
1495bf
+				     make_interface_item(cm_tdbush_interface_property,
1495bf
 							 make_property(CM_DBUS_PROP_SCEP_CA_IDENTIFIER,
1495bf
 								       cm_tdbush_property_string,
1495bf
 								       cm_tdbush_property_readwrite,
1495bf
@@ -7527,7 +7674,7 @@ cm_tdbush_iface_ca(void)
1495bf
 								       NULL, NULL, NULL, NULL, NULL,
1495bf
 								       NULL, NULL, NULL, NULL, NULL,
1495bf
 								       NULL),
1495bf
-				     NULL))))))))))))))))))))))))))))))))))));
1495bf
+				     NULL)))))))))))))))))))))))))))))))))))))));
1495bf
 	}
1495bf
 	return ret;
1495bf
 }
1495bf
-- 
1495bf
1.8.3.1
1495bf