| |
@@ -199,7 +199,7 @@
|
| |
main(int argc, const char **argv)
|
| |
{
|
| |
const char *url = NULL, *results = NULL, *results2 = NULL;
|
| |
- struct cm_submit_h_context *hctx;
|
| |
+ struct cm_submit_h_context *hctx = NULL;
|
| |
int c, verbose = 0, results_length = 0, results_length2 = 0, i;
|
| |
int prefer_non_renewal = 0, can_renewal = 0;
|
| |
int response_code = 0, response_code2 = 0;
|
| |
@@ -224,7 +224,8 @@
|
| |
size_t payload_length;
|
| |
long error;
|
| |
PKCS7 *p7;
|
| |
- poptContext pctx;
|
| |
+ int rval = CM_SUBMIT_STATUS_UNCONFIGURED;
|
| |
+ poptContext pctx = NULL;
|
| |
struct poptOption popts[] = {
|
| |
{"url", 'u', POPT_ARG_STRING, &url, 0, "service location", "URL"},
|
| |
{"ca-identifier", 'i', POPT_ARG_STRING, &id, 0, "name to use when querying for capabilities", "IDENTIFIER"},
|
| |
@@ -387,8 +388,8 @@
|
| |
}
|
| |
if ((message == NULL) || (strlen(message) == 0)) {
|
| |
printf(_("Error reading request. Expected PKCS7 data containing a GetInitialCert pkiMessage, got nothing.\n"));
|
| |
- free(cainfo);
|
| |
- return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ goto done;
|
| |
}
|
| |
/* First step: read capabilities for our use. */
|
| |
params = talloc_asprintf(ctx, "operation=" OP_GET_CA_CAPS);
|
| |
@@ -407,8 +408,8 @@
|
| |
}
|
| |
if ((message == NULL) || (strlen(message) == 0)) {
|
| |
printf(_("Error reading request. Expected PKCS7 data containing a PKCSReq pkiMessage, got nothing.\n"));
|
| |
- free(cainfo);
|
| |
- return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ goto done;
|
| |
}
|
| |
/* First step: read capabilities for our use. */
|
| |
params = talloc_asprintf(ctx, "operation=" OP_GET_CA_CAPS);
|
| |
@@ -419,19 +420,23 @@
|
| |
/* Supply help output, if it's needed. */
|
| |
if (missing_args) {
|
| |
poptPrintUsage(pctx, stdout, 0);
|
| |
- free(cainfo);
|
| |
- return CM_SUBMIT_STATUS_UNCONFIGURED;
|
| |
+ rval = CM_SUBMIT_STATUS_UNCONFIGURED;
|
| |
+ goto done;
|
| |
}
|
| |
|
| |
/* Check the rekey PKCSReq message, if we have one. */
|
| |
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))) {
|
| |
@@ -453,11 +458,15 @@
|
| |
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))) {
|
| |
@@ -496,7 +505,6 @@
|
| |
verbose > 1 ?
|
| |
cm_submit_h_curl_verbose_on :
|
| |
cm_submit_h_curl_verbose_off);
|
| |
- free(cainfo);
|
| |
cm_submit_h_run(hctx);
|
| |
content_type = cm_submit_h_result_type(hctx);
|
| |
if (content_type == NULL) {
|
| |
@@ -542,7 +550,8 @@
|
| |
}
|
| |
if ((tmp2 == NULL) || (strlen(tmp2) == 0)) {
|
| |
printf(_("Error reading request. Expected PKCS7 data containing a GetInitialCert pkiMessage, got nothing.\n"));
|
| |
- return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ goto done;
|
| |
} else
|
| |
if (verbose > 0) {
|
| |
if (tmp2 == rekey_message) {
|
| |
@@ -567,7 +576,8 @@
|
| |
}
|
| |
if ((tmp2 == NULL) || (strlen(tmp2) == 0)) {
|
| |
printf(_("Error reading request. Expected PKCS7 data containing a PKCSReq pkiMessage, got nothing.\n"));
|
| |
- return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
|
| |
+ goto done;
|
| |
} else
|
| |
if (verbose > 0) {
|
| |
if (tmp2 == rekey_message) {
|
| |
@@ -629,7 +639,8 @@
|
| |
cm_submit_h_result_code(hctx),
|
| |
url);
|
| |
}
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
switch (op) {
|
| |
case op_unset:
|
| |
@@ -642,16 +653,19 @@
|
| |
response_code, url);
|
| |
if (response_code == 500) {
|
| |
/* The server might recover, right? */
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
} else {
|
| |
/* Maybe not? */
|
| |
- return CM_SUBMIT_STATUS_REJECTED;
|
| |
+ rval = CM_SUBMIT_STATUS_REJECTED;
|
| |
+ goto done;
|
| |
}
|
| |
}
|
| |
if (results == NULL) {
|
| |
printf(_("Internal error: no response to \"%s?%s\".\n"),
|
| |
url, params);
|
| |
- return CM_SUBMIT_STATUS_REJECTED;
|
| |
+ rval = CM_SUBMIT_STATUS_REJECTED;
|
| |
+ goto done;
|
| |
}
|
| |
break;
|
| |
case op_get_cert_initial:
|
| |
@@ -676,10 +690,12 @@
|
| |
fprintf(stderr, "Result is surprisingly large, "
|
| |
"suppressing it.\n");
|
| |
}
|
| |
- return CM_SUBMIT_STATUS_REJECTED;
|
| |
+ rval = CM_SUBMIT_STATUS_REJECTED;
|
| |
+ goto done;
|
| |
}
|
| |
printf("%s\n", results);
|
| |
- return CM_SUBMIT_STATUS_ISSUED;
|
| |
+ rval = CM_SUBMIT_STATUS_ISSUED;
|
| |
+ goto done;
|
| |
break;
|
| |
case op_get_ca_certs:
|
| |
if ((strcasecmp(content_type,
|
| |
@@ -688,7 +704,8 @@
|
| |
"application/x-x509-ca-ra-cert") != 0)) {
|
| |
printf(_("Server reply was of unexpected MIME type "
|
| |
"\"%s\".\n"), content_type);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (racert == NULL) {
|
| |
racertp = &racert;
|
| |
@@ -701,7 +718,8 @@
|
| |
n_buffers + 1);
|
| |
if ((buffers == NULL) || (lengths == NULL)) {
|
| |
fprintf(stderr, "Out of memory.\n");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
buffers[n_buffers] = (unsigned char *) racert;
|
| |
lengths[n_buffers] = strlen(racert);
|
| |
@@ -718,7 +736,8 @@
|
| |
n_buffers + 1);
|
| |
if ((buffers == NULL) || (lengths == NULL)) {
|
| |
fprintf(stderr, "Out of memory.\n");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
buffers[n_buffers] = (unsigned char *) cacert;
|
| |
lengths[n_buffers] = strlen(cacert);
|
| |
@@ -732,7 +751,8 @@
|
| |
n_buffers + 1);
|
| |
if ((buffers == NULL) || (lengths == NULL)) {
|
| |
fprintf(stderr, "Out of memory.\n");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
buffers[n_buffers] = (unsigned char *) results;
|
| |
lengths[n_buffers] = results_length;
|
| |
@@ -746,7 +766,8 @@
|
| |
n_buffers + 1);
|
| |
if ((buffers == NULL) || (lengths == NULL)) {
|
| |
fprintf(stderr, "Out of memory.\n");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
buffers[n_buffers] = (unsigned char *) results2;
|
| |
lengths[n_buffers] = results_length2;
|
| |
@@ -841,7 +862,8 @@
|
| |
n_buffers + 1);
|
| |
if ((buffers == NULL) || (lengths == NULL)) {
|
| |
fprintf(stderr, "Out of memory.\n");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
buffers[n_buffers] = (unsigned char *) results2;
|
| |
lengths[n_buffers] = results_length2;
|
| |
@@ -873,11 +895,11 @@
|
| |
}
|
| |
}
|
| |
}
|
| |
- talloc_free(ctx);
|
| |
- return CM_SUBMIT_STATUS_ISSUED;
|
| |
+ rval = CM_SUBMIT_STATUS_ISSUED;
|
| |
+ goto done;
|
| |
} else {
|
| |
- talloc_free(ctx);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
break;
|
| |
case op_get_cert_initial:
|
| |
@@ -932,56 +954,66 @@
|
| |
&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);
|
| |
fprintf(stderr, "%s", s);
|
| |
cm_log(1, "%s", s);
|
| |
free(s);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if ((msgtype == NULL) ||
|
| |
(strcmp(msgtype, SCEP_MSGTYPE_CERTREP) != 0)) {
|
| |
printf(_("Error: reply was not a CertRep (%s).\n"),
|
| |
msgtype ? msgtype : "none");
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (tx == NULL) {
|
| |
printf(_("Error: reply is missing transactionId.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (sent_tx != NULL) {
|
| |
if (strcmp(sent_tx, tx) != 0) {
|
| |
printf(_("Error: reply contains a "
|
| |
"different transactionId.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
}
|
| |
if (pkistatus == NULL) {
|
| |
printf(_("Error: reply is missing pkiStatus.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (recipient_nonce == NULL) {
|
| |
printf(_("Error: reply is missing recipientNonce.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if ((recipient_nonce_length != sent_nonce_length) ||
|
| |
(memcmp(recipient_nonce, sent_nonce,
|
| |
sent_nonce_length) != 0)) {
|
| |
printf(_("Error: reply nonce doesn't match request.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (sender_nonce == NULL) {
|
| |
printf(_("Error: reply is missing senderNonce.\n"));
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if (strcmp(pkistatus, SCEP_PKISTATUS_PENDING) == 0) {
|
| |
if (verbose > 0) {
|
| |
@@ -991,7 +1023,8 @@
|
| |
s = cm_store_base64_from_bin(ctx, sender_nonce,
|
| |
sender_nonce_length);
|
| |
printf("%s\n", s);
|
| |
- return CM_SUBMIT_STATUS_WAIT;
|
| |
+ rval = CM_SUBMIT_STATUS_WAIT;
|
| |
+ goto done;
|
| |
} else
|
| |
if (strcmp(pkistatus, SCEP_PKISTATUS_FAILURE) == 0) {
|
| |
if (verbose > 0) {
|
| |
@@ -1039,7 +1072,8 @@
|
| |
printf(_("Server returned failure code \"%s\".\n"),
|
| |
failinfo);
|
| |
}
|
| |
- return CM_SUBMIT_STATUS_REJECTED;
|
| |
+ rval = CM_SUBMIT_STATUS_REJECTED;
|
| |
+ goto done;
|
| |
} else
|
| |
if (strcmp(pkistatus, SCEP_PKISTATUS_SUCCESS) == 0) {
|
| |
if (verbose > 0) {
|
| |
@@ -1049,88 +1083,78 @@
|
| |
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);
|
| |
s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
|
| |
fprintf(stderr, "Full reply:\n%s", s);
|
| |
free(s);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
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);
|
| |
s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
|
| |
fprintf(stderr, "Full reply:\n%s", s);
|
| |
free(s);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
if ((p7->d.enveloped == NULL) ||
|
| |
(p7->d.enveloped->enc_data == NULL) ||
|
| |
(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);
|
| |
s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
|
| |
fprintf(stderr, "Full reply:\n%s", s);
|
| |
free(s);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
s = cm_store_base64_from_bin(ctx, payload,
|
| |
payload_length);
|
| |
s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
|
| |
printf("%s", s);
|
| |
free(s);
|
| |
- return CM_SUBMIT_STATUS_ISSUED;
|
| |
+ rval = CM_SUBMIT_STATUS_ISSUED;
|
| |
+ goto done;
|
| |
} else {
|
| |
if (verbose > 0) {
|
| |
fprintf(stderr, "SCEP status is \"%s\".\n", pkistatus);
|
| |
}
|
| |
printf(_("Error: pkiStatus \"%s\" not recognized.\n"),
|
| |
pkistatus);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
} else {
|
| |
printf(_("Server reply was of unexpected MIME type "
|
| |
"\"%s\".\n"), content_type);
|
| |
printf("Full reply:\n%.*s", results_length2, results2);
|
| |
- return CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ rval = CM_SUBMIT_STATUS_UNREACHABLE;
|
| |
+ goto done;
|
| |
}
|
| |
break;
|
| |
}
|
| |
- return CM_SUBMIT_STATUS_UNCONFIGURED;
|
| |
+
|
| |
+ done:
|
| |
+ if (pctx) {
|
| |
+ poptFreeContext(pctx);
|
| |
+ }
|
| |
+ free(cainfo);
|
| |
+ free(id);
|
| |
+ cm_submit_h_cleanup(hctx);
|
| |
+ talloc_free(ctx);
|
| |
+ return rval;
|
| |
}
|
| |
Log by default any errors that occur.
Provide a hint from the openssl error(s) in the return value to certmonger as to what the RCA of the failure is.
Remove some duplicated code.
Honor the -v flag to add-scep-ca.