Blob Blame Raw
From 0aa25dc4f8c44434e3f28a7fe25a72c0871ac13b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 29 Apr 2020 16:50:16 -0400
Subject: [PATCH 33/39] Improve logging in SCEP helper

Always check return value of cm_pkcs7_verify_signed() and return
a unique error message.

Change log level from 1 to 0 for all errors in scep.c and pkcs7.c
so they appear by default.

Centralize logging across scep.c and pkcs7.c to reduce code
duplication.

Check the return code to cm_pkcs7_verify_signed in all cases.

Add the last available message, if any, to the error returned
via stdout to certmonger as a hint to what is going on.
---
 src/pkcs7.c     | 111 +++++++++++++++++++++++++++---------------------
 src/pkcs7.h     |   2 +
 src/scep.c      |  59 ++++++++++---------------
 src/scepgen-n.c |  28 ++++++------
 src/scepgen-o.c |  72 ++++++++++++++++---------------
 src/scepgen.c   |   2 +-
 6 files changed, 140 insertions(+), 134 deletions(-)

diff --git a/src/pkcs7.c b/src/pkcs7.c
index 6de1775..29420b9 100644
--- a/src/pkcs7.c
+++ b/src/pkcs7.c
@@ -274,6 +274,25 @@ cm_pkcs7_parse_buffer(const unsigned char *buffer, size_t length,
 	}
 }
 
+void
+log_pkcs7_errors(int level, char *msg)
+{
+    char buf[LINE_MAX] = "";
+    long error;
+	int nss_err;   
+
+    cm_log(level, "%s\n", msg);
+    while ((error = ERR_get_error()) != 0) {
+            memset(buf, '\0', sizeof(buf));
+            ERR_error_string_n(error, buf, sizeof(buf));
+            cm_log(level, "%s\n", buf);
+    }
+	nss_err = PORT_GetError();
+    if (nss_err < 0) {
+		cm_log(level, "%d: %s\n", nss_err, PR_ErrorToString(nss_err, 0));
+	}
+}
+
 int
 cm_pkcs7_parsev(unsigned int flags, void *parent,
 		char **certleaf, char **certtop, char ***certothers,
@@ -520,26 +539,26 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher,
 
 	in = BIO_new_mem_buf(encryption_cert, -1);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	recipient = PEM_read_bio_X509(in, NULL, NULL, NULL);
 	if (recipient == NULL) {
-		cm_log(1, "Error parsing recipient certificate.\n");
+		log_pkcs7_errors(0, "Error parsing recipient certificate.\n");
 		goto done;
 	}
 	BIO_free(in);
 
 	recipients = sk_X509_new(util_o_cert_cmp);
 	if (recipients == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	sk_X509_push(recipients, recipient);
 
 	in = BIO_new_mem_buf(data, dlength);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	p7 = PKCS7_encrypt(recipients, in, cm_prefs_ossl_cipher_by_pref(cipher),
@@ -547,22 +566,22 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher,
 	BIO_free(in);
 
 	if (p7 == NULL) {
-		cm_log(1, "Error encrypting signing request.\n");
+		log_pkcs7_errors(0, "Error encrypting signing request.\n");
 		goto done;
 	}
 	len = i2d_PKCS7(p7, NULL);
 	if (len < 0) {
-		cm_log(1, "Error encoding encrypted signing request.\n");
+		log_pkcs7_errors(0, "Error encoding encrypted signing request.\n");
 		goto done;
 	}
 	dp7 = malloc(len);
 	if (dp7 == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	u = dp7;
 	if (i2d_PKCS7(p7, &u) != len) {
-		cm_log(1, "Error encoding encrypted signing request.\n");
+		log_pkcs7_errors(0, "Error encoding encrypted signing request.\n");
 		goto done;
 	}
 	*enveloped = dp7;
@@ -593,29 +612,29 @@ cm_pkcs7_envelope_csr(char *encryption_cert, enum cm_prefs_cipher cipher,
 
 	in = BIO_new_mem_buf(csr, -1);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
 	BIO_free(in);
 	if (req == NULL) {
-		cm_log(1, "Error parsing certificate signing request.\n");
+		log_pkcs7_errors(0, "Error parsing certificate signing request.\n");
 		goto done;
 	}
 
 	dlen = i2d_X509_REQ(req, NULL);
 	if (dlen < 0) {
-		cm_log(1, "Error encoding certificate signing request.\n");
+		log_pkcs7_errors(0, "Error encoding certificate signing request.\n");
 		goto done;
 	}
 	dreq = malloc(dlen);
 	if (dreq == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	u = dreq;
 	if (i2d_X509_REQ(req, &u) != dlen) {
-		cm_log(1, "Error encoding certificate signing request.\n");
+		log_pkcs7_errors(0, "Error encoding certificate signing request.\n");
 		goto done;
 	}
 	ret = cm_pkcs7_envelope_data(encryption_cert, cipher, dreq, dlen,
@@ -671,59 +690,61 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert,
 
 	in = BIO_new_mem_buf(cacert, -1);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	ca = PEM_read_bio_X509(in, NULL, NULL, NULL);
 	BIO_free(in);
 	if (ca == NULL) {
-		cm_log(1, "Error parsing CA certificate.\n");
+		log_pkcs7_errors(0, "Error parsing CA certificate.\n");
 		goto done;
 	}
 
 	in = BIO_new_mem_buf(minicert, -1);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	mini = PEM_read_bio_X509(in, NULL, NULL, NULL);
 	BIO_free(in);
 	if (mini == NULL) {
-		cm_log(1, "Error parsing client certificate.\n");
+		log_pkcs7_errors(0, "Error parsing client certificate.\n");
 		goto done;
 	}
 
 	issuerlen = i2d_X509_NAME(X509_get_issuer_name(ca), NULL);
 	if (issuerlen < 0) {
-		cm_log(1, "Error encoding CA certificate issuer name.\n");
+		cm_log(0, "Error encoding CA certificate issuer name.\n");
 		goto done;
 	}
 	issuer = malloc(issuerlen);
 	if (issuer == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	u = issuer;
 	if (i2d_X509_NAME(X509_get_issuer_name(ca), &u) != issuerlen) {
-		cm_log(1, "Error encoding CA certificate issuer name.\n");
+		log_pkcs7_errors(0, "Error encoding CA certificate issuer name.\n");
 		goto done;
 	}
 
 	subjectlen = i2d_X509_NAME(X509_get_subject_name(mini), NULL);
 	if (subjectlen < 0) {
-		cm_log(1, "Error encoding client certificate subject name.\n");
+		cm_log(0, "Error encoding client certificate subject name.\n");
 		goto done;
 	}
 	subject = malloc(subjectlen);
 	if (subject == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	u = subject;
 	if (i2d_X509_NAME(X509_get_subject_name(mini), &u) != subjectlen) {
-		cm_log(1, "Error encoding client certificate subject name.\n");
+		log_pkcs7_errors(0, "Error encoding client certificate subject name.\n");
 		goto done;
 	}
+	PORT_SetError(0);
+    ERR_clear_error();
 	memset(&issuerandsubject, 0, sizeof(issuerandsubject));
 	issuerandsubject.issuer.data = issuer;
 	issuerandsubject.issuer.len = issuerlen;
@@ -731,7 +752,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert,
 	issuerandsubject.subject.len = subjectlen;
 	if (SEC_ASN1EncodeItem(NULL, &encoded, &issuerandsubject,
 			       cm_pkcs7_ias_template) != &encoded) {
-		cm_log(1, "Error encoding issuer and subject names.\n");
+		log_pkcs7_errors(0, "Error encoding issuer and subject names.\n");
 		goto done;
 	}
 	*ias = malloc(encoded.len);
@@ -948,28 +969,28 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 	u = data;
 	p7 = d2i_PKCS7(NULL, &u, length);
 	if ((p7 == NULL) || (u != data + length)) {
-		cm_log(1, "Error parsing what should be PKCS#7 signed-data.\n");
+		cm_log(0, "Error parsing what should be PKCS#7 signed-data.\n");
 		goto done;
 	}
 	if ((p7->type == NULL) || (OBJ_obj2nid(p7->type) != NID_pkcs7_signed)) {
-		cm_log(1, "PKCS#7 data is not signed-data.\n");
+		cm_log(0, "PKCS#7 data is not signed-data.\n");
 		goto done;
 	}
 	store = X509_STORE_new();
 	if (store == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	X509_STORE_set_verify_cb_func(store, &ignore_purpose_errors);
 	certs = sk_X509_new(util_o_cert_cmp);
 	if (certs == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	for (i = 0; (roots != NULL) && (roots[i] != NULL); i++) {
 		s = talloc_strdup(parent, roots[i]);
 		if (s == NULL) {
-			cm_log(1, "Out of memory.\n");
+			cm_log(0, "Out of memory.\n");
 			goto done;
 		}
 		/* In case one of these is multiple PEM certificates
@@ -990,13 +1011,13 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 			}
 			in = BIO_new_mem_buf(p, q - p);
 			if (in == NULL) {
-				cm_log(1, "Out of memory.\n");
+				cm_log(0, "Out of memory.\n");
 				goto done;
 			}
 			x = PEM_read_bio_X509(in, NULL, NULL, NULL);
 			BIO_free(in);
 			if (x == NULL) {
-				cm_log(1, "Error parsing chain certificate.\n");
+				cm_log(0, "Error parsing chain certificate.\n");
 				goto done;
 			}
 			X509_STORE_add_cert(store, x);
@@ -1008,7 +1029,7 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 	for (i = 0; (othercerts != NULL) && (othercerts[i] != NULL); i++) {
 		s = talloc_strdup(parent, othercerts[i]);
 		if (s == NULL) {
-			cm_log(1, "Out of memory.\n");
+			cm_log(0, "Out of memory.\n");
 			goto done;
 		}
 		/* In case one of these is multiple PEM certificates
@@ -1028,13 +1049,13 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 			}
 			in = BIO_new_mem_buf(p, q - p);
 			if (in == NULL) {
-				cm_log(1, "Out of memory.\n");
+				cm_log(0, "Out of memory.\n");
 				goto done;
 			}
 			x = PEM_read_bio_X509(in, NULL, NULL, NULL);
 			BIO_free(in);
 			if (x == NULL) {
-				cm_log(1, "Error parsing chain certificate.\n");
+				cm_log(0, "Error parsing chain certificate.\n");
 				goto done;
 			}
 			sk_X509_push(certs, x);
@@ -1044,7 +1065,7 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 	}
 	out = BIO_new(BIO_s_mem());
 	if (out == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		goto done;
 	}
 	if (roots != NULL) {
@@ -1057,19 +1078,19 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 		for (i = 0; i < sk_X509_num(certs); i++) {
 			x = X509_dup(sk_X509_value(certs, i));
 			if (x == NULL) {
-				cm_log(1, "Out of memory.\n");
+				cm_log(0, "Out of memory.\n");
 				goto done;
 			}
 			PKCS7_add_certificate(p7, x);
 		}
 		if (PKCS7_verify(p7, certs, store, NULL, out, 0) != 1) {
-			cm_log(1, "Message failed verification.\n");
+			cm_log(0, "Message failed verification.\n");
 			goto done;
 		}
 	}
 	p7s = p7->d.sign;
 	if (sk_PKCS7_SIGNER_INFO_num(p7s->signer_info) != 1) {
-		cm_log(1, "Number of PKCS#7 signed-data signers != 1.\n");
+		cm_log(0, "Number of PKCS#7 signed-data signers != 1.\n");
 		goto done;
 	}
 	si = sk_PKCS7_SIGNER_INFO_value(p7s->signer_info, 0);
@@ -1077,12 +1098,12 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 	encapsulated = p7s->contents;
 	if (expected_content_type != NID_undef) {
 		if (encapsulated == NULL) {
-			cm_log(1, "Error parsing PKCS#7 encapsulated content.\n");
+			cm_log(0, "Error parsing PKCS#7 encapsulated content.\n");
 			goto done;
 		}
 		if ((encapsulated->type == NULL) ||
 		    (OBJ_obj2nid(encapsulated->type) != expected_content_type)) {
-			cm_log(1, "PKCS#7 encapsulated data is not %s (%s).\n",
+			cm_log(0, "PKCS#7 encapsulated data is not %s (%s).\n",
 			       OBJ_nid2ln(expected_content_type),
 			       encapsulated->type ?
 			       OBJ_nid2ln(OBJ_obj2nid(encapsulated->type)) :
@@ -1091,7 +1112,7 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 		}
 	}
 	if (attrs == NULL) {
-		cm_log(1, "PKCS#7 signed-data contains no signed attributes.\n");
+		cm_log(0, "PKCS#7 signed-data contains no signed attributes.\n");
 		goto done;
 	}
 	ret = 0;
@@ -1146,7 +1167,7 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 		if (*payload_length > 0) {
 			*payload = talloc_size(parent, *payload_length + 1);
 			if (*payload == NULL) {
-				cm_log(1, "Out of memory.\n");
+				cm_log(0, "Out of memory.\n");
 				goto done;
 			}
 			memcpy(*payload, s, *payload_length);
@@ -1154,12 +1175,6 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 		}
 	}
 done:
-	if (ret != 0) {
-		while ((error = ERR_get_error()) != 0) {
-			ERR_error_string_n(error, buf, sizeof(buf));
-			cm_log(1, "%s\n", buf);
-		}
-	}
 	if (p7 != NULL) {
 		PKCS7_free(p7);
 	}
diff --git a/src/pkcs7.h b/src/pkcs7.h
index 097f7ca..fae52f8 100644
--- a/src/pkcs7.h
+++ b/src/pkcs7.h
@@ -63,4 +63,6 @@ int cm_pkcs7_verify_signed(unsigned char *data, size_t length,
 			   size_t *recipient_nonce_length,
 			   unsigned char **payload, size_t *payload_length);
 
+void log_pkcs7_errors(int level, char *msg);
+
 #endif
diff --git a/src/scep.c b/src/scep.c
index b37711c..0b8bef9 100644
--- a/src/scep.c
+++ b/src/scep.c
@@ -428,11 +428,15 @@ main(int argc, const char **argv)
 	if ((rekey_message != NULL) && (strlen(rekey_message) != 0)) {
 		tmp1 = cm_submit_u_base64_from_text(rekey_message);
 		tmp2 = cm_store_base64_as_bin(ctx, tmp1, -1, &c);
-		cm_pkcs7_verify_signed((unsigned char *) tmp2, c,
+		i = cm_pkcs7_verify_signed((unsigned char *) tmp2, c,
 				       NULL, NULL, NID_pkcs7_data, ctx, NULL,
 				       NULL, &msgtype, NULL, NULL,
 				       NULL, NULL,
 				       NULL, NULL, NULL, NULL);
+		if (i != 0) {
+			log_pkcs7_errors(0, "Error: failed to verify signature on "
+					"rekey PKCSReq.\n");
+		}
 		if ((msgtype == NULL) ||
 		    ((strcmp(msgtype, SCEP_MSGTYPE_PKCSREQ) != 0) &&
 		     (strcmp(msgtype, SCEP_MSGTYPE_GETCERTINITIAL) != 0))) {
@@ -454,11 +458,15 @@ main(int argc, const char **argv)
 	if ((message != NULL) && (strlen(message) != 0)) {
 		tmp1 = cm_submit_u_base64_from_text(message);
 		tmp2 = cm_store_base64_as_bin(ctx, tmp1, -1, &c);
-		cm_pkcs7_verify_signed((unsigned char *) tmp2, c,
+		i = cm_pkcs7_verify_signed((unsigned char *) tmp2, c,
 				       NULL, NULL, NID_pkcs7_data, ctx, NULL,
 				       &sent_tx, &msgtype, NULL, NULL,
 				       &sent_nonce, &sent_nonce_length,
 				       NULL, NULL, NULL, NULL);
+		if (i != 0) {
+			log_pkcs7_errors(0, "Error: failed to verify signature on "
+					"message.\n");
+		}
 		if ((msgtype == NULL) ||
 		    ((strcmp(msgtype, SCEP_MSGTYPE_PKCSREQ) != 0) &&
 		     (strcmp(msgtype, SCEP_MSGTYPE_GETCERTINITIAL) != 0))) {
@@ -933,14 +941,16 @@ main(int argc, const char **argv)
 						   &payload, &payload_length);
 			if (i != 0) {
 				printf(_("Error: failed to verify signature on "
-					 "server response.\n"));
-				cm_log(1, "Error: failed to verify signature on "
-					 "server response.\n");
-				while ((error = ERR_get_error()) != 0) {
+						 "server response. "));
+				error = ERR_peek_last_error();
+				if (error != 0) {
 					memset(buf, '\0', sizeof(buf));
 					ERR_error_string_n(error, buf, sizeof(buf));
-					cm_log(1, "%s\n", buf);
+					printf("%s", buf);
 				}
+				printf("\n");
+				log_pkcs7_errors(0, "Error: failed to verify signature on "
+						  "server response.\n");
 				s = cm_store_base64_from_bin(ctx, (unsigned char *) results2,
 							     results_length2);
 				s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
@@ -1050,26 +1060,7 @@ main(int argc, const char **argv)
 				p7 = d2i_PKCS7(NULL, &u, payload_length);
 				if (p7 == NULL) {
 					printf(_("Error: couldn't parse signed-data.\n"));
-					while ((error = ERR_get_error()) != 0) {
-						memset(buf, '\0', sizeof(buf));
-						ERR_error_string_n(error, buf, sizeof(buf));
-						cm_log(1, "%s\n", buf);
-					}
-					s = cm_store_base64_from_bin(ctx,
-								     (unsigned char *) results2,
-								     results_length2);
-					s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
-					fprintf(stderr, "Full reply:\n%s", s);
-					free(s);
-					return CM_SUBMIT_STATUS_UNREACHABLE;
-				}
-				if (!PKCS7_type_is_enveloped(p7)) {
-					printf(_("Error: signed-data payload is not enveloped-data.\n"));
-					while ((error = ERR_get_error()) != 0) {
-						memset(buf, '\0', sizeof(buf));
-						ERR_error_string_n(error, buf, sizeof(buf));
-						cm_log(1, "%s\n", buf);
-					}
+					log_pkcs7_errors(0, "Error: couldn't parse signed-data.\n");
 					s = cm_store_base64_from_bin(ctx,
 								     (unsigned char *) results2,
 								     results_length2);
@@ -1080,11 +1071,8 @@ main(int argc, const char **argv)
 				}
 				if (!PKCS7_type_is_enveloped(p7)) {
 					printf(_("Error: signed-data payload is not enveloped-data.\n"));
-					while ((error = ERR_get_error()) != 0) {
-						memset(buf, '\0', sizeof(buf));
-						ERR_error_string_n(error, buf, sizeof(buf));
-						cm_log(1, "%s\n", buf);
-					}
+					log_pkcs7_errors(0, "Error: signed-data payload is not "
+								"enveloped-data.\n");
 					s = cm_store_base64_from_bin(ctx,
 								     (unsigned char *) results2,
 								     results_length2);
@@ -1098,11 +1086,8 @@ main(int argc, const char **argv)
 				    (p7->d.enveloped->enc_data->content_type == NULL) ||
 				    (OBJ_obj2nid(p7->d.enveloped->enc_data->content_type) != NID_pkcs7_data)) {
 					printf(_("Error: enveloped-data payload is not data.\n"));
-					while ((error = ERR_get_error()) != 0) {
-						memset(buf, '\0', sizeof(buf));
-						ERR_error_string_n(error, buf, sizeof(buf));
-						cm_log(1, "%s\n", buf);
-					}
+					log_pkcs7_errors(0, "Error: enveloped-data payload is "
+								"not data.\n");
 					s = cm_store_base64_from_bin(ctx,
 								     (unsigned char *) results2,
 								     results_length2);
diff --git a/src/scepgen-n.c b/src/scepgen-n.c
index 8c67b12..ce73c31 100644
--- a/src/scepgen-n.c
+++ b/src/scepgen-n.c
@@ -86,14 +86,14 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey)
 		return;
 	}
 	if (sk_PKCS7_SIGNER_INFO_num(p7->d.sign->signer_info) != 1) {
-		cm_log(1, "More than one signer, not sure what to do.\n");
+		cm_log(0, "More than one signer, not sure what to do.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	sinfo = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0);
 	salen = ASN1_item_i2d((ASN1_VALUE *)sinfo->auth_attr, NULL, &PKCS7_ATTR_SIGN_it);
 	u = sabuf = malloc(salen);
 	if (sabuf == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	/* ASN1_item_i2d doesn't actually modify the passed-in pointer, which
@@ -101,7 +101,7 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey)
 	 * that ourselves. */
 	l = ASN1_item_i2d((ASN1_VALUE *)sinfo->auth_attr, &u, &PKCS7_ATTR_SIGN_it);
 	if (l != salen) {
-		cm_log(1, "Error encoding attributes.\n");
+		cm_log(0, "Error encoding attributes.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 
@@ -109,12 +109,12 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey)
 	digalg = cm_submit_n_tag_from_nid(OBJ_obj2nid(sinfo->digest_alg->algorithm));
 	sigalg = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, digalg);
 	if (sigalg == SEC_OID_UNKNOWN) {
-		cm_log(1, "Unable to match digest algorithm and key.\n");
+		cm_log(0, "Unable to match digest algorithm and key.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	if (SEC_SignData(&signature, sabuf, salen, privkey,
 			 sigalg) != SECSuccess) {
-		cm_log(1, "Error re-signing: %s.\n",
+		cm_log(0, "Error re-signing: %s.\n",
 		       PR_ErrorToName(PORT_GetError()));
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
@@ -143,7 +143,7 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 	}
 
 	if (ca->cm_ca_encryption_cert == NULL) {
-		cm_log(1, "Can't generate new SCEP request data without "
+		cm_log(0, "Can't generate new SCEP request data without "
 		       "the RA/CA encryption certificate.\n");
 		_exit(CM_SUB_STATUS_NEED_SCEP_DATA);
 	}
@@ -166,12 +166,12 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 			fprintf(status, "Error opening database "
 				"'%s': %s.\n",
 				entry->cm_key_storage_location, es);
-			cm_log(1, "Error opening database '%s': %s.\n",
+			cm_log(0, "Error opening database '%s': %s.\n",
 			       entry->cm_key_storage_location, es);
 		} else {
 			fprintf(status, "Error opening database '%s'.\n",
 				entry->cm_key_storage_location);
-			cm_log(1, "Error opening database '%s'.\n",
+			cm_log(0, "Error opening database '%s'.\n",
 			       entry->cm_key_storage_location);
 		}
 		switch (ec) {
@@ -190,7 +190,7 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 			      NSS_INIT_NOROOTINIT);
 	reason = util_n_fips_hook();
 	if (reason != NULL) {
-		cm_log(1, "Error putting NSS into FIPS mode: %s\n", reason);
+		cm_log(0, "Error putting NSS into FIPS mode: %s\n", reason);
 		_exit(CM_SUB_STATUS_ERROR_INITIALIZING);
 	}
 
@@ -198,23 +198,23 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 	cm_log(1, "Generating dummy key.\n");
 	key = EVP_PKEY_new();
 	if (key == NULL) {
-		cm_log(1, "Error allocating new key.\n");
+		cm_log(0, "Error allocating new key.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	exponent = BN_new();
 	if (exponent == NULL) {
-		cm_log(1, "Error setting up exponent.\n");
+		cm_log(0, "Error setting up exponent.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	BN_set_word(exponent, CM_DEFAULT_RSA_EXPONENT);
 	rsa = RSA_new();
 	if (rsa == NULL) {
-		cm_log(1, "Error allocating new RSA key.\n");
+		cm_log(0, "Error allocating new RSA key.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 retry_gen:
 	if (RSA_generate_key_ex(rsa, CM_DEFAULT_PUBKEY_SIZE, exponent, NULL) != 1) {
-		cm_log(1, "Error generating key.\n");
+		cm_log(0, "Error generating key.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	if (RSA_check_key(rsa) != 1) { /* should be unnecessary */
@@ -228,7 +228,7 @@ retry_gen:
 	if ((keys->privkey->keyType != rsaKey) ||
 	    ((keys->privkey_next != NULL) &&
 	     (keys->privkey_next->keyType != rsaKey))) {
-		cm_log(1, "Keys aren't RSA.  They won't work with SCEP.\n");
+		cm_log(0, "Keys aren't RSA.  They won't work with SCEP.\n");
 		_exit(CM_SUB_STATUS_ERROR_KEY_TYPE);
 	}
 
diff --git a/src/scepgen-o.c b/src/scepgen-o.c
index 010abb7..a431815 100644
--- a/src/scepgen-o.c
+++ b/src/scepgen-o.c
@@ -76,14 +76,14 @@ key_from_file(const char *filename, struct cm_store_entry *entry)
 	keyfp = fopen(filename, "r");
 	if (keyfp == NULL) {
 		if (errno != ENOENT) {
-			cm_log(1, "Error opening key file \"%s\" "
+			cm_log(0, "Error opening key file \"%s\" "
 			       "for reading: %s.\n",
 			       filename, strerror(errno));
 		}
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	if (cm_pin_read_for_key(entry, &pin) != 0) {
-		cm_log(1, "Internal error reading key encryption PIN.\n");
+		cm_log(0, "Internal error reading key encryption PIN.\n");
 		_exit(CM_SUB_STATUS_ERROR_AUTH);
 	}
 	memset(&cb_data, 0, sizeof(cb_data));
@@ -93,24 +93,24 @@ key_from_file(const char *filename, struct cm_store_entry *entry)
 				   cm_pin_read_for_key_ossl_cb, &cb_data);
 	if (pkey == NULL) {
 		error = errno;
-		cm_log(1, "Error reading private key '%s': %s.\n",
+		cm_log(0, "Error reading private key '%s': %s.\n",
 		       filename, strerror(error));
 		while ((error = ERR_get_error()) != 0) {
 			ERR_error_string_n(error, buf, sizeof(buf));
-			cm_log(1, "%s\n", buf);
+			cm_log(0, "%s\n", buf);
 		}
 		_exit(CM_SUB_STATUS_ERROR_AUTH); /* XXX */
 	} else {
 		if ((pin != NULL) &&
 		    (strlen(pin) > 0) &&
 		    (cb_data.n_attempts == 0)) {
-			cm_log(1, "PIN was not needed to read private "
+			cm_log(0, "PIN was not needed to read private "
 			       "key '%s', though one was provided. "
 			       "Treating this as an error.\n",
 			       filename);
 			while ((error = ERR_get_error()) != 0) {
 				ERR_error_string_n(error, buf, sizeof(buf));
-				cm_log(1, "%s\n", buf);
+				cm_log(0, "%s\n", buf);
 			}
 			_exit(CM_SUB_STATUS_ERROR_AUTH); /* XXX */
 		}
@@ -127,13 +127,13 @@ cert_from_pem(char *pem, struct cm_store_entry *entry)
 	if ((pem != NULL) && (strlen(pem) > 0)) {
 		in = BIO_new_mem_buf(pem, -1);
 		if (in == NULL) {
-			cm_log(1, "Out of memory.\n");
+			cm_log(0, "Out of memory.\n");
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
 		cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
 		BIO_free(in);
 		if (cert == NULL) {
-			cm_log(1, "Error parsing certificate \"%s\".\n", pem);
+			cm_log(0, "Error parsing certificate \"%s\".\n", pem);
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
 		return cert;
@@ -155,19 +155,19 @@ certs_from_nickcerts(struct cm_nickcert **list)
 		if ((this->cm_cert != NULL) && (strlen(this->cm_cert) > 0)) {
 			in = BIO_new_mem_buf(this->cm_cert, -1);
 			if (in == NULL) {
-				cm_log(1, "Out of memory.\n");
+				cm_log(0, "Out of memory.\n");
 				_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 			}
 			cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
 			BIO_free(in);
 			if (cert == NULL) {
-				cm_log(1, "Error parsing certificate.\n");
+				cm_log(0, "Error parsing certificate.\n");
 				_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 			}
 			if (sk == NULL) {
 				sk = sk_X509_new(util_o_cert_cmp);
 				if (sk == NULL) {
-					cm_log(1, "Out of memory.\n");
+					cm_log(0, "Out of memory.\n");
 					_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 				}
 			}
@@ -300,19 +300,19 @@ build_pkimessage(EVP_PKEY *key, X509 *signer, STACK_OF(X509) *certs,
 
 	in = BIO_new_mem_buf(data, data_length);
 	if (in == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	ret = PKCS7_sign(signer, key, certs, in, flags);
 	if (ret == NULL) {
-		cm_log(1, "Error signing data.\n");
+		cm_log(0, "Error signing data.\n");
 		goto errors;
 	}
 	BIO_free(in);
 
 	/* Set the digest to use for signing. */
 	if (sk_PKCS7_SIGNER_INFO_num(ret->d.sign->signer_info) != 1) {
-		cm_log(1, "Error signing data: %d signers.\n",
+		cm_log(0, "Error signing data: %d signers.\n",
 		       sk_PKCS7_SIGNER_INFO_num(ret->d.sign->signer_info));
 		goto errors;
 	}
@@ -356,7 +356,7 @@ build_pkimessage(EVP_PKEY *key, X509 *signer, STACK_OF(X509) *certs,
 	PKCS7_content_new(ret, NID_pkcs7_data);
 	out = PKCS7_dataInit(ret, NULL);
 	if (out == NULL) {
-		cm_log(1, "Error signing data.\n");
+		cm_log(0, "Error signing data.\n");
 		goto errors;
 	}
 	BIO_write(out, data, data_length);
@@ -366,7 +366,7 @@ build_pkimessage(EVP_PKEY *key, X509 *signer, STACK_OF(X509) *certs,
 errors:
 	while ((error = ERR_get_error()) != 0) {
 		ERR_error_string_n(error, buf, sizeof(buf));
-		cm_log(1, "%s\n", buf);
+		cm_log(0, "%s\n", buf);
 	}
 	_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 }
@@ -394,11 +394,11 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 	util_o_init();
 	ERR_load_crypto_strings();
         if (RAND_status() != 1) {
-		cm_log(1, "PRNG not seeded for generating key.\n");
+		cm_log(0, "PRNG not seeded for generating key.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	if (RAND_bytes(nonce, nonce_length) == -1) {
-		cm_log(1, "PRNG unable to generate nonce.\n");
+		cm_log(0, "PRNG unable to generate nonce.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 
@@ -410,14 +410,14 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 	pem = cm_submit_u_pem_from_base64("CERTIFICATE", 0,
 					  entry->cm_minicert);
 	if (pem == NULL) {
-		cm_log(1, "Out of memory.\n");
+		cm_log(0, "Out of memory.\n");
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 	new_cert = cert_from_pem(pem, entry);
 	if (new_cert == NULL) {
 		while ((error = ERR_get_error()) != 0) {
 			ERR_error_string_n(error, buf, sizeof(buf));
-			cm_log(1, "%s\n", buf);
+			cm_log(0, "%s\n", buf);
 		}
 		free(pem);
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
@@ -442,7 +442,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 			cipher = cm_prefs_des;
 		}
 		else {
-			cm_log(1, "Option 'scep_cipher' must be one of AES256, AES192, AES128, DES3, or DES. Got '%s'\n", scep_cipher);
+			cm_log(0, "Option 'scep_cipher' must be one of AES256, AES192, AES128, DES3, or DES. Got '%s'\n", scep_cipher);
 			_exit(1);
 		}
 
@@ -516,7 +516,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 			digest = cm_prefs_md5;
 		}
 		else {
-			cm_log(1, "Option 'scep_digest' must be one of SHA512, SHA384, SHA256, SHA1, or MD5. Got '%s'\n", scep_digest);
+			cm_log(0, "Option 'scep_digest' must be one of SHA512, SHA384, SHA256, SHA1, or MD5. Got '%s'\n", scep_digest);
 			_exit(1);
 		}
 
@@ -578,7 +578,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 					  ca->cm_ca_encryption_issuer_cert,
 					  entry->cm_cert,
 					  &old_ias, &old_ias_length) != 0) {
-			cm_log(1, "Error generating enveloped issuer-and-subject.\n");
+			cm_log(0, "Error generating enveloped issuer-and-subject.\n");
 			free(pem);
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
@@ -590,7 +590,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 				  ca->cm_ca_encryption_issuer_cert,
 				  pem,
 				  &new_ias, &new_ias_length) != 0) {
-		cm_log(1, "Error generating enveloped issuer-and-subject.\n");
+		cm_log(0, "Error generating enveloped issuer-and-subject.\n");
 		free(pem);
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
@@ -598,7 +598,11 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 	if (cm_pkcs7_envelope_csr(ca->cm_ca_encryption_cert, cipher,
 				  entry->cm_csr,
 				  &csr, &csr_length) != 0) {
-		cm_log(1, "Error generating enveloped CSR.\n");
+		cm_log(0, "Error generating enveloped CSR.\n");
+		while ((error = ERR_get_error()) != 0) {
+			ERR_error_string_n(error, buf, sizeof(buf));
+			cm_log(0, "%s\n", buf);
+		}
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
 
@@ -608,7 +612,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 		 * the matching key. */
 		pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(old_cert));
 		if (pubkey == NULL) {
-			cm_log(1, "Error generating PKCSREQ pkiMessage: error copying key.\n");
+			cm_log(0, "Error generating PKCSREQ pkiMessage: error copying key.\n");
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
 		util_X509_set_pubkey(old_cert, old_pkey);
@@ -639,7 +643,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 			 * if we do, we did that in another code path. */
 			pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(new_cert));
 			if (pubkey == NULL) {
-				cm_log(1, "Error generating PKCSREQ pkiMessage: error copying key.\n");
+				cm_log(0, "Error generating PKCSREQ pkiMessage: error copying key.\n");
 				_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 			}
 			util_X509_set_pubkey(new_cert, old_pkey);
@@ -673,7 +677,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 		 * any previously-issued certificate won't match. */
 		pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(new_cert));
 		if (pubkey == NULL) {
-			cm_log(1, "Error generating rekeying PKCSREQ pkiMessage: error copying key.\n");
+			cm_log(0, "Error generating rekeying PKCSREQ pkiMessage: error copying key.\n");
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
 		util_X509_set_pubkey(new_cert, new_pkey);
@@ -703,7 +707,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry,
 	X509_free(new_cert);
 	while ((error = ERR_get_error()) != 0) {
 		ERR_error_string_n(error, buf, sizeof(buf));
-		cm_log(1, "%s\n", buf);
+		cm_log(0, "%s\n", buf);
 	}
 }
 
@@ -723,14 +727,14 @@ cm_scepgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 	}
 
 	if (ca->cm_ca_encryption_cert == NULL) {
-		cm_log(1, "Can't generate new SCEP request data without "
+		cm_log(0, "Can't generate new SCEP request data without "
 		       "the RA/CA encryption certificate.\n");
 		_exit(CM_SUB_STATUS_NEED_SCEP_DATA);
 	}
 
 	old_pkey = key_from_file(entry->cm_key_storage_location, entry);
 	if (old_pkey == NULL) {
-		cm_log(1, "Error reading key from file \"%s\".\n",
+		cm_log(0, "Error reading key from file \"%s\".\n",
 		       entry->cm_key_storage_location);
 		_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 	}
@@ -739,14 +743,14 @@ cm_scepgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 		filename = util_build_next_filename(entry->cm_key_storage_location,
 						    entry->cm_key_next_marker);
 		if (filename == NULL) {
-			cm_log(1, "Error opening key file \"%s\" "
+			cm_log(0, "Error opening key file \"%s\" "
 			       "for reading: %s.\n",
 			       filename, strerror(errno));
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
 		}
 		new_pkey = key_from_file(filename, entry);
 		if (new_pkey == NULL) {
-			cm_log(1, "Error reading key from file \"%s\".\n",
+			cm_log(0, "Error reading key from file \"%s\".\n",
 			       filename);
 			free(filename);
 			_exit(CM_SUB_STATUS_INTERNAL_ERROR);
@@ -757,7 +761,7 @@ cm_scepgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 	}
 	if ((util_EVP_PKEY_base_id(old_pkey) != EVP_PKEY_RSA) ||
 	    ((new_pkey != NULL) && (util_EVP_PKEY_base_id(new_pkey) != EVP_PKEY_RSA))) {
-		cm_log(1, "Keys aren't RSA.  They won't work with SCEP.\n");
+		cm_log(0, "Keys aren't RSA.  They won't work with SCEP.\n");
 		_exit(CM_SUB_STATUS_ERROR_KEY_TYPE);
 	}
 
diff --git a/src/scepgen.c b/src/scepgen.c
index eaf2b7c..115446f 100644
--- a/src/scepgen.c
+++ b/src/scepgen.c
@@ -32,7 +32,7 @@ cm_scepgen_start(struct cm_store_ca *ca, struct cm_store_entry *entry)
 {
 	switch (entry->cm_key_storage_type) {
 	case cm_key_storage_none:
-		cm_log(1, "Can't generate new SCEP data for %s('%s') without "
+		cm_log(0, "Can't generate new SCEP data for %s('%s') without "
 		       "the key, and we don't know where that is or should "
 		       "be.\n", entry->cm_busname, entry->cm_nickname);
 		break;
-- 
2.21.1