From f9342db638cc9a8a312f19cc019f05824bcd3b7c Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Apr 14 2020 15:50:17 +0000 Subject: [PATCH 1/3] 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. --- 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 b0bd214..926a091 100644 --- a/src/scep.c +++ b/src/scep.c @@ -427,11 +427,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))) { @@ -453,11 +457,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))) { @@ -932,14 +940,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); @@ -1049,26 +1059,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); @@ -1079,11 +1070,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); @@ -1097,11 +1085,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; From 58cc1f2638f7c369fddb8daaff5b953105365a23 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Apr 14 2020 15:50:17 +0000 Subject: [PATCH 2/3] Add verbose option to SCEP CA if requested in add-scep-ca This option was silently dropped from the helper arguments even if requested on the add-scep-ca CLI and was only passed to the dbus helper. Add as many -v as requested though the scep helper only logs at most at level 1. --- diff --git a/src/getcert.c b/src/getcert.c index e01f78a..19df7c1 100644 --- a/src/getcert.c +++ b/src/getcert.c @@ -4608,6 +4608,9 @@ add_scep_ca(const char *argv0, int argc, const char **argv) certs ? "-I" : "", certs ? shell_escape(globals.tctx, certs) : "", prefer_non_renewal ? "-n" : ""); + for (c = 0; c < verbose; c++) { + command = talloc_strdup_append(command, " -v"); + } if (command == NULL) { printf(_("Error building command line.\n")); exit(1); From 3881b8a968248702d7c2bc504a0495d5fdf21a8d Mon Sep 17 00:00:00 2001 From: Your Name Date: Apr 15 2020 22:39:55 +0000 Subject: [PATCH 3/3] Cleanup the SCEP helper curl and talloc contexts when finished The talloc context was freed in only a few cases and the curl context was never freed. --- diff --git a/src/scep.c b/src/scep.c index 926a091..1724f22 100644 --- a/src/scep.c +++ b/src/scep.c @@ -199,7 +199,7 @@ int 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 @@ main(int argc, const char **argv) 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 @@ main(int argc, const char **argv) } 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 @@ main(int argc, const char **argv) } 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,8 +420,8 @@ main(int argc, const char **argv) /* 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. */ @@ -504,7 +505,6 @@ main(int argc, const char **argv) 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) { @@ -550,7 +550,8 @@ main(int argc, const char **argv) } 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) { @@ -575,7 +576,8 @@ main(int argc, const char **argv) } 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) { @@ -637,7 +639,8 @@ main(int argc, const char **argv) cm_submit_h_result_code(hctx), url); } - return CM_SUBMIT_STATUS_UNREACHABLE; + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto done; } switch (op) { case op_unset: @@ -650,16 +653,19 @@ main(int argc, const char **argv) 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: @@ -684,10 +690,12 @@ main(int argc, const char **argv) 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, @@ -696,7 +704,8 @@ main(int argc, const char **argv) "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; @@ -709,7 +718,8 @@ main(int argc, const char **argv) 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); @@ -726,7 +736,8 @@ main(int argc, const char **argv) 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); @@ -740,7 +751,8 @@ main(int argc, const char **argv) 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; @@ -754,7 +766,8 @@ main(int argc, const char **argv) 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; @@ -849,7 +862,8 @@ main(int argc, const char **argv) 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; @@ -881,11 +895,11 @@ main(int argc, const char **argv) } } } - 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: @@ -956,42 +970,50 @@ main(int argc, const char **argv) 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) { @@ -1001,7 +1023,8 @@ main(int argc, const char **argv) 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) { @@ -1049,7 +1072,8 @@ main(int argc, const char **argv) 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) { @@ -1066,7 +1090,8 @@ main(int argc, const char **argv) 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")); @@ -1078,7 +1103,8 @@ main(int argc, const char **argv) 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) || @@ -1093,29 +1119,42 @@ main(int argc, const char **argv) 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; } diff --git a/src/submit-h.c b/src/submit-h.c index 33f9b39..9b507db 100644 --- a/src/submit-h.c +++ b/src/submit-h.c @@ -298,6 +298,15 @@ cm_submit_h_result_type(struct cm_submit_h_context *ctx) return ret; } +void +cm_submit_h_cleanup(struct cm_submit_h_context *ctx) +{ + + if (ctx != NULL && ctx->curl != NULL) { + curl_easy_cleanup(ctx->curl); + } +} + #ifdef CM_SUBMIT_H_MAIN int main(int argc, const char **argv) @@ -307,7 +316,7 @@ main(int argc, const char **argv) enum cm_submit_h_opt_negotiate negotiate; enum cm_submit_h_opt_delegate negotiate_delegate; enum cm_submit_h_opt_clientauth clientauth; - int c, fd, l, verbose = 0, length = 0; + int c, fd, l, verbose = 0, length = 0, rval = 0; char *ctype, *accept, *capath, *cainfo, *sslcert, *sslkey, *sslpass; char *pinfile; const char *method, *url; @@ -423,6 +432,8 @@ main(int argc, const char **argv) cm_submit_h_result_code(ctx), cm_submit_h_result_code_text(ctx)); } - return cm_submit_h_result_code(ctx); + rval = cm_submit_h_result_code(ctx); + cm_submit_h_cleanup(ctx); + return rval; } #endif diff --git a/src/submit-h.h b/src/submit-h.h index 1283c53..931cc89 100644 --- a/src/submit-h.h +++ b/src/submit-h.h @@ -61,5 +61,6 @@ int cm_submit_h_result_code(struct cm_submit_h_context *ctx); const char *cm_submit_h_result_code_text(struct cm_submit_h_context *ctx); const char *cm_submit_h_results(struct cm_submit_h_context *ctx, int *length); const char *cm_submit_h_result_type(struct cm_submit_h_context *ctx); +void cm_submit_h_cleanup(struct cm_submit_h_context *ctx); #endif