Blob Blame Raw
From 37ebf87fb6fc93d445139310a1c89b98f3f514de Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 29 Apr 2020 16:29:50 -0400
Subject: [PATCH 37/39] Add new option to allow overriding the detected SCEP CA
 chain

The -R option was doing double-duty for the SCEP CA.

1. It was required if the SCEP URL used TLS
2. It override the CA certificate downloaded from the SCEP server

If the chains were different then validating the SCEP responses would
fail.

https://bugzilla.redhat.com/show_bug.cgi?id=1808613
---
 src/certmonger-scep-submit.8.in | 14 +++++++++-----
 src/getcert-add-scep-ca.1.in    | 12 ++++++++----
 src/getcert.c                   |  6 +++++-
 src/scep.c                      | 13 ++++++-------
 4 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/certmonger-scep-submit.8.in b/src/certmonger-scep-submit.8.in
index 95d674a..42ffcd6 100644
--- a/src/certmonger-scep-submit.8.in
+++ b/src/certmonger-scep-submit.8.in
@@ -8,6 +8,7 @@ scep-submit -u SERVER-URL
 [-r ra-cert-file]
 [-R ca-cert-file]
 [-I other-certs-file]
+[-N ca-cert-file]
 [-i ca-identifier]
 [-v]
 [-n]
@@ -57,11 +58,14 @@ typically \fIhttp://\fBSERVER\fP/cgi-bin/PKICLIENT.EXE\fR or
 always required.
 .TP
 \fB\-R\fR CA-certificate-file
-The location of the SCEP server's CA certificate, which was used to
-issue the SCEP server's certificate, or the SCEP server's own
-certificate, if it is self-signed, in PEM form.  If the URL specified
-with the \fB-u\fR option is an \fIhttps\fR URL, then this option is
-required.
+The location of the CA certificate which was used to issue the SCEP web
+server's certificate in PEM form. If the URL specified with the
+\fB-u\fR option is an \fIhttps\fR URL, then this option is required.
+.TP
+\fB\-N\fR ca-certificate-file
+The location of a PEM-formatted copy of the SCEP server's CA certificate.
+A discovered value is normally supplied by the certmonger daemon, but one can
+be specified for troubleshooting purposes.
 .TP
 \fB\-r\fR RA-certificate-file
 The location of the SCEP server's RA certificate, which is expected to
diff --git a/src/getcert-add-scep-ca.1.in b/src/getcert-add-scep-ca.1.in
index 11ab4ce..bf07306 100644
--- a/src/getcert-add-scep-ca.1.in
+++ b/src/getcert-add-scep-ca.1.in
@@ -24,12 +24,16 @@ The location of the SCEP server's enrollment interface.  This option must be
 specified.
 .TP
 \fB\-R\fR ca-certificate-file
-The location of a PEM-formatted copy of the SCEP server's CA's certificate.
-A discovered value is supplied by the certmonger daemon for use in verifying
-the signature on data returned by the SCEP server, but it is not used for
-verifying HTTPS server certificates.
+The location of a PEM-formatted copy of the CA's certificate used to verify
+the TLS connection the SCEP server.
+
 This option must be specified if the URL is an \fIhttps\fR location.
 .TP
+\fB\-N\fR ca-certificate-file
+The location of a PEM-formatted copy of the SCEP server's CA certificate.
+A discovered value is normally supplied by the certmonger daemon, but one can
+be specified for troubleshooting purposes.
+.TP
 \fB\-r\fR ra-certificate-file
 The location of a PEM-formatted copy of the SCEP server's RA's certificate.
 A discovered value is normally supplied by the certmonger daemon, but one can
diff --git a/src/getcert.c b/src/getcert.c
index 3d78a73..493771f 100644
--- a/src/getcert.c
+++ b/src/getcert.c
@@ -4496,6 +4496,7 @@ add_scep_ca(const char *argv0, int argc, const char **argv)
 	enum cm_tdbus_type bus = CM_DBUS_DEFAULT_BUS;
 	char *caname = NULL, *url = NULL, *path = NULL, *id = NULL;
 	char *root = NULL, *racert = NULL, *certs = NULL, *nickname, *command;
+	char *signingca = NULL;
 	const char *err;
 	int c, prefer_non_renewal = 0, verbose = 0;
 	dbus_bool_t b;
@@ -4508,6 +4509,7 @@ add_scep_ca(const char *argv0, int argc, const char **argv)
 		{"ca-cert", 'R', POPT_ARG_STRING, &root, 0, _("file containing CA's certificate"), HELP_TYPE_FILENAME},
 		{"ra-cert", 'r', POPT_ARG_STRING, &racert, 0, _("file containing RA's certificate"), HELP_TYPE_FILENAME},
 		{"other-certs", 'I', POPT_ARG_STRING, &certs, 0, _("file containing certificates in RA's certifying chain"), HELP_TYPE_FILENAME},
+		{"signingca", 'N', POPT_ARG_STRING, NULL, &signingca, 0, _("the CA certificate which signed the RA certificate"), HELP_TYPE_FILENAME},
 		{"non-renewal", 'n', POPT_ARG_NONE, &prefer_non_renewal, 0, _("prefer to not use the SCEP Renewal feature"), NULL},
 		{"session", 's', POPT_ARG_NONE, NULL, 's', _("connect to the certmonger service on the session bus"), NULL},
 		{"system", 'S', POPT_ARG_NONE, NULL, 'S', _("connect to the certmonger service on the system bus"), NULL},
@@ -4569,7 +4571,7 @@ add_scep_ca(const char *argv0, int argc, const char **argv)
 		return 1;
 	}
 	command = talloc_asprintf(globals.tctx,
-				  "%s -u %s %s %s %s %s %s %s %s",
+				  "%s -u %s %s %s %s %s %s %s %s %s %s",
 				  shell_escape(globals.tctx,
 					       CM_SCEP_HELPER_PATH),
 				  shell_escape(globals.tctx, url),
@@ -4579,6 +4581,8 @@ add_scep_ca(const char *argv0, int argc, const char **argv)
 				  racert ? shell_escape(globals.tctx, racert) : "",
 				  certs ? "-I" : "",
 				  certs ? shell_escape(globals.tctx, certs) : "",
+				  signingca ? "-N" : "",
+				  signingca ? shell_escape(globals.tctx, signingca) : "",
 				  prefer_non_renewal ? "-n" : "");
 	for (c = 0; c < verbose; c++) {
 		command = talloc_strdup_append(command, " -v");
diff --git a/src/scep.c b/src/scep.c
index b80278e..4294cda 100644
--- a/src/scep.c
+++ b/src/scep.c
@@ -206,7 +206,6 @@ main(int argc, const char **argv)
 	enum known_ops op = op_unset;
 	const char *id = NULL;
 	char *cainfo = NULL;
-	char *poptarg;
 	char *message = NULL, *rekey_message = NULL;
 	const char *mode = NULL, *content_type = NULL, *content_type2 = NULL;
 	void *ctx;
@@ -235,8 +234,9 @@ main(int argc, const char **argv)
 		{"get-initial-cert", 'g', POPT_ARG_NONE, NULL, 'g', "send a PKIOperation pkiMessage", NULL},
 		{"pki-message", 'p', POPT_ARG_NONE, NULL, 'p', "send a PKIOperation pkiMessage", NULL},
 		{"racert", 'r', POPT_ARG_STRING, NULL, 'r', "the RA certificate, used for encrypting requests", "FILENAME"},
-		{"cacert", 'R', POPT_ARG_STRING, NULL, 'R', "the CA certificate, used for verifying responses", "FILENAME"},
+		{"cacert", 'R', POPT_ARG_STRING, NULL, 'R', "the CA certificate, used for verifying TLS connections", "FILENAME"},
 		{"other-certs", 'I', POPT_ARG_STRING, NULL, 'I', "additional certificates", "FILENAME"},
+		{"signingca", 'N', POPT_ARG_STRING, NULL, 'N', "the CA certificate which signed the RA certificate", "FILENAME"},
 		{"non-renewal", 'n', POPT_ARG_NONE, &prefer_non_renewal, 0, "prefer to not use the SCEP Renewal feature", NULL},
 		{"verbose", 'v', POPT_ARG_NONE, NULL, 'v', NULL, NULL},
 		POPT_AUTOHELP
@@ -329,9 +329,10 @@ main(int argc, const char **argv)
 			racert = cm_submit_u_from_file(poptGetOptArg(pctx));
 			break;
 		case 'R':
-			poptarg = poptGetOptArg(pctx);
-			cainfo = strdup(poptarg);
-			cacert = cm_submit_u_from_file(poptarg);
+			cainfo = poptGetOptArg(pctx);
+			break;
+		case 'N':
+			cacert = cm_submit_u_from_file(poptGetOptArg(pctx));
 			break;
 		case 'I':
 			certs = cm_submit_u_from_file(poptGetOptArg(pctx));
@@ -340,7 +341,6 @@ main(int argc, const char **argv)
 	}
 	if (c != -1) {
 		poptPrintUsage(pctx, stdout, 0);
-		free(cainfo);
 		return CM_SUBMIT_STATUS_UNCONFIGURED;
 	}
 
@@ -1189,7 +1189,6 @@ done:
 	if (pctx) {
 		poptFreeContext(pctx);
 	}
-	free(cainfo);
 	free(id);
 	cm_submit_h_cleanup(hctx);
 	talloc_free(ctx);
-- 
2.21.1