From 9d09ca6cc65204f2ed0fe45c4693ebbb31954216 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Aug 12 2025 17:46:19 +0000 Subject: Replace deprecated OpenSSL 3.0.0 function calls Use EVP_PKEY instead of algorithm-specific calls to generate required parameters and keys. This is a prerequisite for supporting PQ algorithms in a clean way and will future-proof certmonger. While not strictly related to OSSL 3.0.0 deprecation, add a global error logging function so we can reduce code duplication and make it easier to log what happened when a call fails. This was helpful during development of this change. Fixes: https://pagure.io/certmonger/issue/292 Signed-off-by: Rob Crittenden --- diff --git a/.gitignore b/.gitignore index 4f915cd..71715b0 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,4 @@ actual.out /tests/tools/scepgen /tests/tools/srv /tests/tools/submit +/tests/026-local/expected.out diff --git a/src/Makefile.am b/src/Makefile.am index f11024a..2de9f96 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -192,7 +192,8 @@ if WITH_XMLRPC noinst_PROGRAMS += submit-x endif tdbusm_check_SOURCES = tdbusm-check.c tm.c tm.h -tdbusm_check_LDADD = libcm.a $(CERTMONGER_LIBS) $(POPT_LIBS) $(LDAP_LIBS) +tdbusm_check_LDADD = libcm.a $(CERTMONGER_LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ + $(OPENSSL_LIBS) $(NSS_LIBS) serial_check_LDADD = libcm.a $(CERTMONGER_LIBS) $(LTLIBICONV) $(LDAP_LIBS) nl_check_LDADD = libcm.a $(CERTMONGER_LIBS) $(LDAP_LIBS) if WITH_XMLRPC @@ -225,7 +226,7 @@ ipa_submit_SOURCES = ipa.c srvloc.c srvloc.h store.h store-gen.c \ ipa_submit_LDADD = $(XMLRPC_LIBS) $(LDAP_LIBS) $(KRB5_LIBS) $(TALLOC_LIBS) \ $(GMP_LIBS) $(IDN_LIBS) $(OPENSSL_LIBS) $(UUID_LIBS) \ $(RESOLV_LIBS) $(LTLIBICONV) $(POPT_LIBS) $(CURL_LIBS) \ - $(JANSSON_LIBS) + $(JANSSON_LIBS) $(OPENSSL_LIBS) $(NSS_LIBS) if WITH_XMLRPC certmaster_submit_CFLAGS = $(AM_CFLAGS) $(NSS_CFLAGS) certmaster_submit_SOURCES = certmaster.c submit-x.c submit-x.h \ @@ -272,16 +273,18 @@ local_submit_SOURCES = local.c env.h store.h store-gen.c submit-o.c submit-o.h \ util.c util.h util-o.c util-o.h pin.c pin.h local_submit_LDADD = $(NSS_LIBS) $(OPENSSL_LIBS) $(TALLOC_LIBS) $(UUID_LIBS) \ $(POPT_LIBS) -submit_d_CFLAGS = $(AM_CFLAGS) $(CURL_CFLAGS) $(XML_CFLAGS) -DCM_SUBMIT_D_MAIN +submit_d_CFLAGS = $(AM_CFLAGS) $(CURL_CFLAGS) $(XML_CFLAGS) $(OPENSSL_CFLAGS) \ + $(NSS_CFLAGS) -DCM_SUBMIT_D_MAIN submit_d_SOURCES = submit-d.c submit-d.h submit-h.c submit-h.h \ submit-u.c submit-u.h log.c log.h tm.c tm.h util-m.c util-m.h submit_d_LDADD = libcm-o.a $(CURL_LIBS) $(OPENSSL_LIBS) $(XML_LIBS) \ $(TALLOC_LIBS) $(GMP_LIBS) $(UUID_LIBS) $(LTLIBICONV) \ - $(POPT_LIBS) -submit_h_CFLAGS = $(AM_CFLAGS) $(CURL_CFLAGS) $(XML_CFLAGS) -DCM_SUBMIT_H_MAIN + $(POPT_LIBS) $(OPENSSL_LIBS) $(NSS_LIBS) +submit_h_CFLAGS = $(AM_CFLAGS) $(NSS_CFLAGS) $(CURL_CFLAGS) $(XML_CFLAGS) \ + -DCM_SUBMIT_H_MAIN submit_h_SOURCES = submit-h.c submit-h.h log.c log.h tm.c tm.h -submit_h_LDADD = $(CURL_LIBS) $(XML_LIBS) $(TALLOC_LIBS) $(LTLIBICONV) \ - $(POPT_LIBS) +submit_h_LDADD = $(NSS_LIBS) $(OPENSSL_LIBS) $(CURL_LIBS) $(XML_LIBS) $(TALLOC_LIBS) \ + $(LTLIBICONV) $(POPT_LIBS) .PHONY: manlint manlint: $(man_MANS) diff --git a/src/certsave-o.c b/src/certsave-o.c index b145a21..caab151 100644 --- a/src/certsave-o.c +++ b/src/certsave-o.c @@ -285,7 +285,7 @@ cm_certsave_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, /* Double-check that we're not trying to rotate in a * key that we won't actually be using. */ if ((old_pkey != NULL) && - (EVP_PKEY_cmp(old_pkey, X509_get_pubkey(cert)) == 1)) { + (EVP_PKEY_eq(old_pkey, X509_get_pubkey(cert)) == 1)) { entry->cm_key_next_marker = NULL; if (next_key != NULL) { cm_log(1, "Public key was not changed.\n"); diff --git a/src/keygen-o.c b/src/keygen-o.c index 676db8b..0f16729 100644 --- a/src/keygen-o.c +++ b/src/keygen-o.c @@ -99,6 +99,10 @@ cm_keygen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, struct cm_pin_cb_data cb_data; FILE *fp, *status; EVP_PKEY *pkey; + EVP_PKEY *pkey_params; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *check_ctx = NULL; + EVP_PKEY_CTX *pctx_params = NULL; char buf[LINE_MAX], *pin, *pubhex, *pubihex, *oldfile; unsigned char *p, *q; long error, errno_save; @@ -106,15 +110,11 @@ cm_keygen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, int cm_key_size; int len; int keyfd; + int ret; char *filename; char *marker; BIGNUM *exponent; - RSA *rsa; -#ifdef CM_ENABLE_DSA - DSA *dsa; -#endif #ifdef CM_ENABLE_EC - EC_KEY *ec; int ecurve; #endif @@ -148,93 +148,182 @@ retry_gen: case cm_key_rsa: exponent = BN_new(); if (exponent == NULL) { - cm_log(1, "Error setting up exponent.\n"); + cm_log(1, "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"); + + pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (pctx == NULL) { + cm_log(1, "Error allocating new RSA context.\n"); + BN_free(exponent); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_keygen_init(pctx) == 0) { + cm_log(1, "Error initializing RSA key generation.\n"); + BN_free(exponent); + EVP_PKEY_CTX_free(pctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, cm_key_size) <= 0) { + cm_log(1, "Error setting RSA key size.\n"); + BN_free(exponent); + EVP_PKEY_CTX_free(pctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, exponent) <= 0) { + cm_log(1, "Error setting RSA exponent.\n"); + BN_free(exponent); + EVP_PKEY_CTX_free(pctx); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (RSA_generate_key_ex(rsa, cm_key_size, exponent, NULL) != 1) { + + if (EVP_PKEY_generate(pctx, &pkey) <= 0 ) { if (cm_key_size != CM_DEFAULT_PUBKEY_SIZE) { - cm_log(1, "Error generating %d-bit key, " + cm_log(1, "Error generating RSA %d-bit key, " "attempting %d bits.\n", cm_key_size, CM_DEFAULT_PUBKEY_SIZE); cm_key_size = CM_DEFAULT_PUBKEY_SIZE; + BN_free(exponent); + EVP_PKEY_CTX_free(pctx); goto retry_gen; } - cm_log(1, "Error generating key.\n"); + cm_log(1, "Error generating RSA key.\n"); + EVP_PKEY_CTX_free(pctx); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (RSA_check_key(rsa) != 1) { /* should be unnecessary */ - cm_log(1, "Key fails checks. Retrying.\n"); - goto retry_gen; + EVP_PKEY_CTX_free(pctx); + + check_ctx = EVP_PKEY_CTX_new(pkey, NULL); + + ret = EVP_PKEY_check(check_ctx); + if (ret == 0) { + cm_log(1, "keygen-o: EVP_PKEY_check): Key pair is invalid.\n"); + EVP_PKEY_CTX_free(check_ctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } else if (ret == -2) { + cm_log(1, "keygen-o: EVP_PKEY_check: RSA operation not supported for this algorithm.\n"); + EVP_PKEY_CTX_free(check_ctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - EVP_PKEY_set1_RSA(pkey, rsa); + EVP_PKEY_CTX_free(check_ctx); break; #ifdef CM_ENABLE_DSA case cm_key_dsa: - dsa = DSA_new(); - if (dsa == NULL) { - cm_log(1, "Error allocating new DSA key.\n"); + EVP_PKEY_CTX *pctx_params = NULL; + EVP_PKEY* pkey_params = NULL; + + pctx_params = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); + if (pctx_params == NULL) { + cm_log(1, "keygen-o: Error allocating new DSA params context.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_paramgen_init(pctx_params) == 0) { + cm_log(1, "keygen-o: Error initializing DSA param generation.\n"); + EVP_PKEY_CTX_free(pctx_params); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + if (EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx_params, cm_key_size) == 0) { + cm_log(1, "keygen-o: Error setting DSA bits to %d.\n", cm_key_size); + EVP_PKEY_CTX_free(pctx_params); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (DSA_generate_parameters_ex(dsa, cm_key_size, - NULL, 0, - NULL, NULL, NULL) != 1) { + + if (EVP_PKEY_paramgen(pctx_params, &pkey_params) != 1) { + cm_log(1, "keygen-o: Error in DSA paramgen.\n"); + EVP_PKEY_CTX_free(pctx_params); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + pctx = EVP_PKEY_CTX_new(pkey_params, NULL); + if (EVP_PKEY_keygen_init(pctx) == 0) { + cm_log(1, "keygen-o: Error initializing parameter DSA key generation.\n"); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_CTX_free(pctx_params); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_generate(pctx, &pkey) != 1) { if (cm_key_size != CM_DEFAULT_PUBKEY_SIZE) { - cm_log(1, "Error generating %d-bit key, " + cm_log(1, "keygen-o: Error generating DSA %d-bit key, " "attempting %d bits.\n", cm_key_size, CM_DEFAULT_PUBKEY_SIZE); cm_key_size = CM_DEFAULT_PUBKEY_SIZE; + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_CTX_free(pctx_params); goto retry_gen; } - cm_log(1, "Error generating parameters.\n"); + cm_log(1, "Error generating DSA key.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (DSA_generate_key(dsa) != 1) { - cm_log(1, "Error generating key.\n"); + EVP_PKEY_free(pkey_params); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_CTX_free(pctx_params); + + check_ctx = EVP_PKEY_CTX_new(pkey, NULL); + ret = EVP_PKEY_param_check(check_ctx); + if (ret == 0) { + cm_log(1, "keygen-o: DSA key pair is invalid\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } else if (ret == -2) { + cm_log(1, "keygen-o: EVP_PKEY_check: DSA operation not supported for this algorithm.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - EVP_PKEY_set1_DSA(pkey, dsa); + EVP_PKEY_CTX_free(check_ctx); break; #endif #ifdef CM_ENABLE_EC case cm_key_ecdsa: - if (cm_key_size <= 256) + char *curve = NULL; + if (cm_key_size <= 256) { ecurve = NID_X9_62_prime256v1; - else if (cm_key_size <= 384) + } else if (cm_key_size <= 384) { ecurve = NID_secp384r1; - else + } else { ecurve = NID_secp521r1; - ec = EC_KEY_new_by_curve_name(ecurve); - while ((ec == NULL) && (ecurve != NID_X9_62_prime256v1)) { - cm_log(1, "Error allocating new EC key.\n"); - switch (ecurve) { - case NID_secp521r1: - cm_log(1, "Trying with a smaller key.\n"); - ecurve = NID_secp384r1; - ec = EC_KEY_new_by_curve_name(ecurve); - break; - case NID_secp384r1: - cm_log(1, "Trying with a smaller key.\n"); - ecurve = NID_X9_62_prime256v1; - ec = EC_KEY_new_by_curve_name(ecurve); - break; - } } - if (ec == NULL) { - cm_log(1, "Error allocating new EC key.\n"); + + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (pctx == NULL) { + cm_log(1, "Error allocating new EC context.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + if (EVP_PKEY_keygen_init(pctx) <= 0) { + cm_log(1, "Error initializing EC key generation context.\n"); + EVP_PKEY_CTX_free(pctx); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (EC_KEY_generate_key(ec) != 1) { - cm_log(1, "Error generating key.\n"); + + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecurve) <= 0) { + cm_log(1, "Error creating EC key generation context.\n"); + EVP_PKEY_CTX_free(pctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_generate(pctx, &pkey) <= 0) { + if (ecurve != NID_X9_62_prime256v1) { + cm_log(1, "Error generating EC key, " + "trying with a smaller curve.\n"); + switch (ecurve) { + case NID_secp521r1: + ecurve = NID_secp384r1; + break; + case NID_secp384r1: + ecurve = NID_X9_62_prime256v1; + break; + } + EVP_PKEY_CTX_free(pctx); + goto retry_gen; + } + cm_log(1, "Error generating EC key.\n"); + EVP_PKEY_CTX_free(pctx); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); - EVP_PKEY_set1_EC_KEY(pkey, ec); + EVP_PKEY_CTX_free(pctx); break; #endif default: @@ -372,6 +461,7 @@ retry_gen: fprintf(status, "%s\n%s\n%s\n", pubihex, pubhex, marker); fclose(fp); fclose(status); + EVP_PKEY_free(pkey); /* Try to remove any keys with old candidate names. */ if ((entry->cm_key_next_marker != NULL) && diff --git a/src/local.c b/src/local.c index a62ebda..7d2e942 100644 --- a/src/local.c +++ b/src/local.c @@ -199,11 +199,14 @@ get_signer_info(void *parent, char *localdir, X509 ***roots, char *creds, *hexserial = NULL, *serial, buf[LINE_MAX], *csr; STACK_OF(X509) *cas = NULL; PKCS12 *p12 = NULL; - BIGNUM *exponent = NULL; - RSA *rsa; + unsigned int bits = CM_DEFAULT_PUBKEY_SIZE; + unsigned int exponent = CM_DEFAULT_RSA_EXPONENT; + OSSL_PARAM rsa_params[3]; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *check_ctx = NULL; dbus_bool_t save = FALSE; time_t now, then, life, lifedelta; - int i; + int i, ret; *roots = NULL; *signer_cert = NULL; @@ -301,29 +304,39 @@ get_signer_info(void *parent, char *localdir, X509 ***roots, } /* Generate a new key. For now at least, generate RSA of the * default size with the default exponent. */ - exponent = BN_new(); - if (exponent == NULL) { - cm_log(1, "Error setting up exponent.\n"); + pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (pctx == NULL) { + cm_log(1, "Error allocating new RSA context.\n"); return CM_SUBMIT_STATUS_UNREACHABLE; } - BN_set_word(exponent, CM_DEFAULT_RSA_EXPONENT); - rsa = RSA_new(); - if (rsa == NULL) { - cm_log(1, "Error allocating new RSA key.\n"); + + if (EVP_PKEY_keygen_init(pctx) == 0) { + cm_log(1, "Error initializing RSA key generation.\n"); + return CM_SUBMIT_STATUS_UNREACHABLE; + } + + rsa_params[0] = OSSL_PARAM_construct_uint("bits", &bits); + rsa_params[1] = OSSL_PARAM_construct_uint("e", &exponent); + rsa_params[2] = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_set_params(pctx, rsa_params) == 0) { + cm_log(1, "Error setting RSA key parameters.\n"); return CM_SUBMIT_STATUS_UNREACHABLE; } + + retry_gen: - if (RSA_generate_key_ex(rsa, CM_DEFAULT_PUBKEY_SIZE, exponent, - NULL) != 1) { - cm_log(1, "Error generating key.\n"); + if (EVP_PKEY_generate(pctx, signer_key) != 1) { + cm_log(1, "Error generating RSA %d-bit key.\n", bits); + EVP_PKEY_CTX_free(pctx); return CM_SUBMIT_STATUS_UNREACHABLE; } - if (RSA_check_key(rsa) != 1) { /* should be unnecessary */ + check_ctx = EVP_PKEY_CTX_new(*signer_key, NULL); + + ret = EVP_PKEY_check(check_ctx); + if (ret == 0) { cm_log(1, "Key fails checks. Retrying.\n"); goto retry_gen; } - *signer_key = EVP_PKEY_new(); - EVP_PKEY_set1_RSA(*signer_key, rsa); /* Build a suitable CA signing request. */ csr = make_ca_csr(parent, *signer_key, *signer_cert); if (csr == NULL) { diff --git a/src/log.c b/src/log.c index 4cc8368..b0a1a31 100644 --- a/src/log.c +++ b/src/log.c @@ -28,6 +28,9 @@ #include #include +#include +#include +#include #include #include "log.h" @@ -112,3 +115,28 @@ cm_log(int level, const char *fmt, ...) } } } + +/* Log the passed message at level and then display all errors reported + * by OpenSSL and NSS. Then clear all errors in both. + */ +void +cm_log_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); + } + ERR_clear_error(); + + nss_err = PORT_GetError(); + if (nss_err < 0) { + cm_log(level, "%d: %s\n", nss_err, PR_ErrorToString(nss_err, 0)); + } + PORT_SetError(0); +} diff --git a/src/log.h b/src/log.h index e4645e1..5ad2fd5 100644 --- a/src/log.h +++ b/src/log.h @@ -43,5 +43,6 @@ void cm_log(int level, const char *fmt, ...) __attribute__((format(printf,2,3))) #endif ; +void cm_log_errors(int level, char *msg); #endif diff --git a/src/pkcs7.c b/src/pkcs7.c index b2cccc0..3b94043 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -275,25 +275,6 @@ 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, @@ -545,7 +526,7 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher, } recipient = PEM_read_bio_X509(in, NULL, NULL, NULL); if (recipient == NULL) { - log_pkcs7_errors(0, "Error parsing recipient certificate.\n"); + cm_log_errors(0, "Error parsing recipient certificate.\n"); goto done; } BIO_free(in); @@ -567,12 +548,12 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher, BIO_free(in); if (p7 == NULL) { - log_pkcs7_errors(0, "Error encrypting signing request.\n"); + cm_log_errors(0, "Error encrypting signing request.\n"); goto done; } len = i2d_PKCS7(p7, NULL); if (len < 0) { - log_pkcs7_errors(0, "Error encoding encrypted signing request.\n"); + cm_log_errors(0, "Error encoding encrypted signing request.\n"); goto done; } dp7 = malloc(len); @@ -582,7 +563,7 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher, } u = dp7; if (i2d_PKCS7(p7, &u) != len) { - log_pkcs7_errors(0, "Error encoding encrypted signing request.\n"); + cm_log_errors(0, "Error encoding encrypted signing request.\n"); goto done; } *enveloped = dp7; @@ -619,13 +600,13 @@ cm_pkcs7_envelope_csr(char *encryption_cert, enum cm_prefs_cipher cipher, req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); if (req == NULL) { - log_pkcs7_errors(0, "Error parsing certificate signing request.\n"); + cm_log_errors(0, "Error parsing certificate signing request.\n"); goto done; } dlen = i2d_X509_REQ(req, NULL); if (dlen < 0) { - log_pkcs7_errors(0, "Error encoding certificate signing request.\n"); + cm_log_errors(0, "Error encoding certificate signing request.\n"); goto done; } dreq = malloc(dlen); @@ -635,7 +616,7 @@ cm_pkcs7_envelope_csr(char *encryption_cert, enum cm_prefs_cipher cipher, } u = dreq; if (i2d_X509_REQ(req, &u) != dlen) { - log_pkcs7_errors(0, "Error encoding certificate signing request.\n"); + cm_log_errors(0, "Error encoding certificate signing request.\n"); goto done; } ret = cm_pkcs7_envelope_data(encryption_cert, cipher, dreq, dlen, @@ -697,7 +678,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, ca = PEM_read_bio_X509(in, NULL, NULL, NULL); BIO_free(in); if (ca == NULL) { - log_pkcs7_errors(0, "Error parsing CA certificate.\n"); + cm_log_errors(0, "Error parsing CA certificate.\n"); goto done; } @@ -709,7 +690,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, mini = PEM_read_bio_X509(in, NULL, NULL, NULL); BIO_free(in); if (mini == NULL) { - log_pkcs7_errors(0, "Error parsing client certificate.\n"); + cm_log_errors(0, "Error parsing client certificate.\n"); goto done; } @@ -725,7 +706,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, } u = issuer; if (i2d_X509_NAME(X509_get_issuer_name(ca), &u) != issuerlen) { - log_pkcs7_errors(0, "Error encoding CA certificate issuer name.\n"); + cm_log_errors(0, "Error encoding CA certificate issuer name.\n"); goto done; } @@ -741,7 +722,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, } u = subject; if (i2d_X509_NAME(X509_get_subject_name(mini), &u) != subjectlen) { - log_pkcs7_errors(0, "Error encoding client certificate subject name.\n"); + cm_log_errors(0, "Error encoding client certificate subject name.\n"); goto done; } PORT_SetError(0); @@ -753,7 +734,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, issuerandsubject.subject.len = subjectlen; if (SEC_ASN1EncodeItem(NULL, &encoded, &issuerandsubject, cm_pkcs7_ias_template) != &encoded) { - log_pkcs7_errors(0, "Error encoding issuer and subject names.\n"); + cm_log_errors(0, "Error encoding issuer and subject names.\n"); goto done; } *ias = malloc(encoded.len); diff --git a/src/scep.c b/src/scep.c index 35d6688..b1a2f97 100644 --- a/src/scep.c +++ b/src/scep.c @@ -441,7 +441,7 @@ main(int argc, const char **argv) NULL, NULL, NULL, NULL, NULL, NULL); if (i != 0) { - log_pkcs7_errors(0, "Error: failed to verify signature on " + cm_log_errors(0, "Error: failed to verify signature on " "rekey PKCSReq.\n"); } if ((msgtype == NULL) || @@ -471,7 +471,7 @@ main(int argc, const char **argv) &sent_nonce, &sent_nonce_length, NULL, NULL, NULL, NULL); if (i != 0) { - log_pkcs7_errors(0, "Error: failed to verify signature on " + cm_log_errors(0, "Error: failed to verify signature on " "message.\n"); } if ((msgtype == NULL) || @@ -1005,7 +1005,7 @@ main(int argc, const char **argv) printf("%s", buf); } printf("\n"); - log_pkcs7_errors(0, "Error: failed to verify signature on " + cm_log_errors(0, "Error: failed to verify signature on " "server response.\n"); s = cm_store_base64_from_bin(ctx, (unsigned char *) results2, results_length2); @@ -1126,7 +1126,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")); - log_pkcs7_errors(0, "Error: couldn't parse signed-data.\n"); + cm_log_errors(0, "Error: couldn't parse signed-data.\n"); s = cm_store_base64_from_bin(ctx, (unsigned char *) results2, results_length2); @@ -1138,7 +1138,7 @@ main(int argc, const char **argv) } if (!PKCS7_type_is_enveloped(p7)) { printf(_("Error: signed-data payload is not enveloped-data.\n")); - log_pkcs7_errors(0, "Error: signed-data payload is not " + cm_log_errors(0, "Error: signed-data payload is not " "enveloped-data.\n"); s = cm_store_base64_from_bin(ctx, (unsigned char *) results2, @@ -1154,7 +1154,7 @@ 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")); - log_pkcs7_errors(0, "Error: enveloped-data payload is " + cm_log_errors(0, "Error: enveloped-data payload is " "not data.\n"); s = cm_store_base64_from_bin(ctx, (unsigned char *) results2, diff --git a/src/scepgen-n.c b/src/scepgen-n.c index e5a0a81..46244de 100644 --- a/src/scepgen-n.c +++ b/src/scepgen-n.c @@ -134,10 +134,14 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, struct cm_keyiread_n_ctx_and_keys *keys; const char *p, *es, *reason; int ec; + int ret; PKCS7 *csr_new, *csr_old, *ias_new, *ias_old; + unsigned int bits = CM_DEFAULT_PUBKEY_SIZE; + unsigned int exponent = CM_DEFAULT_RSA_EXPONENT; EVP_PKEY *key; - RSA *rsa; - BIGNUM *exponent; + OSSL_PARAM params[3]; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *check_ctx = NULL; status = fdopen(fd, "w"); if (status == NULL) { @@ -205,32 +209,48 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, /* Use a dummy key to sign using OpenSSL. */ cm_log(1, "Generating dummy key.\n"); + pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (pctx == NULL) { + cm_log(1, "Error allocating new RSA context.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_keygen_init(pctx) == 0) { + cm_log(1, "Error initializing RSA key generation.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + key = EVP_PKEY_new(); if (key == NULL) { cm_log(0, "Error allocating new key.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - exponent = BN_new(); - if (exponent == NULL) { - 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(0, "Error allocating new RSA key.\n"); + params[0] = OSSL_PARAM_construct_uint("bits", &bits); + params[1] = OSSL_PARAM_construct_uint("e", &exponent); + params[2] = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_set_params(pctx, params) == 0) { + cm_log(1, "Error setting RSA key parameters.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } + retry_gen: - if (RSA_generate_key_ex(rsa, CM_DEFAULT_PUBKEY_SIZE, exponent, NULL) != 1) { - cm_log(0, "Error generating key.\n"); + if (EVP_PKEY_generate(pctx, &key) != 1) { + cm_log(1, "Error generating RSA %d-bit key.\n", bits); + EVP_PKEY_CTX_free(pctx); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (RSA_check_key(rsa) != 1) { /* should be unnecessary */ - cm_log(1, "Key fails checks. Retrying.\n"); + + check_ctx = EVP_PKEY_CTX_new(key, NULL); + + ret = EVP_PKEY_check(check_ctx); + if (ret == 0) { + cm_log(1, "EVP_PKEY_check (pairwise check): Key pair is invalid.\n"); goto retry_gen; + } else if (ret == -2) { + cm_log(1, "EVP_PKEY_check: Operation not supported for this algorithm.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - BN_free(exponent); + EVP_PKEY_CTX_free(check_ctx); /* Read the proper keys. */ keys = cm_keyiread_n_get_keys(entry, 0); @@ -242,7 +262,6 @@ retry_gen: } /* Sign using a dummy key. */ - EVP_PKEY_set1_RSA(key, rsa); csr_new = NULL; csr_old = NULL; ias_new = NULL; diff --git a/src/submit-n.c b/src/submit-n.c index 2b64902..dcb88b8 100644 --- a/src/submit-n.c +++ b/src/submit-n.c @@ -93,10 +93,14 @@ try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, ASN1_STRING *params = NULL; PKCS7 *p7 = NULL; PKCS7_RECIP_INFO *p7i = NULL; - BIGNUM *exponent = NULL; EVP_PKEY *pkey = NULL; + unsigned int bits = CM_DEFAULT_PUBKEY_SIZE; + unsigned int exponent = CM_DEFAULT_RSA_EXPONENT; + OSSL_PARAM rsa_params[3]; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *check_ctx = NULL; + int rc = 0; BIO *out; - RSA *rsa = NULL; char buf[BUFSIZ]; const unsigned char *u; unsigned char *enc_key, *dec, *reenc, *param_data; @@ -191,36 +195,69 @@ try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, pkey = EVP_PKEY_new(); if (pkey == NULL) { cm_log(1, "Error allocating new key.\n"); - goto done; + _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - exponent = BN_new(); - if (exponent == NULL) { - cm_log(1, "Error setting up exponent.\n"); - goto done; +retry_gen: + pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (pctx == NULL) { + cm_log(1, "Error allocating new RSA context.\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"); - goto done; + + if (EVP_PKEY_keygen_init(pctx) == 0) { + cm_log(1, "Error initializing RSA key generation.\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"); - goto done; + + + rsa_params[0] = OSSL_PARAM_construct_uint("bits", &bits); + rsa_params[1] = OSSL_PARAM_construct_uint("e", &exponent); + rsa_params[2] = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_set_params(pctx, rsa_params) == 0) { + cm_log(1, "Error setting RSA key parameters.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + if (EVP_PKEY_generate(pctx, &pkey) != 1) { + cm_log(1, "Error generating RSA %d-bit key.\n", bits); + EVP_PKEY_CTX_free(pctx); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (RSA_check_key(rsa) != 1) { /* should be unnecessary */ - cm_log(1, "Key fails checks. Retrying.\n"); + + check_ctx = EVP_PKEY_CTX_new(pkey, NULL); + + rc = EVP_PKEY_check(check_ctx); + if (rc == 0) { + cm_log(1, "submit-n: EVP_PKEY_check (pairwise check): Key pair %d bits is invalid.\n", bits); + + EVP_PKEY_CTX_free(pctx); goto retry_gen; + } else if (rc == -2) { + cm_log(1, "EVP_PKEY_check: Operation not supported for this algorithm.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - EVP_PKEY_set1_RSA(pkey, rsa); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_CTX_free(check_ctx); /* Encrypt the bulk key. We're about to decrypt it again, so do it the * simplest way that we can. */ - reenc_len = dec_len + RSA_size(rsa); + pctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (pctx == NULL) { + cm_log(1, "submit-n: Error allocating new RSA context.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + if (EVP_PKEY_encrypt_init(pctx) <= 0) { + cm_log(1, "submit-n: Error initializing RSA encrypt context.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) <= 0) { + cm_log(1, "submit-n: Error setting RSA encrypt padding to RSA_PKCS1_PADDING\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + + reenc_len = dec_len + EVP_PKEY_size(pkey); reenc = talloc_size(parent, reenc_len); - padding = RSA_PKCS1_PADDING; - reenc_len = RSA_public_encrypt(dec_len, dec, reenc, rsa, padding); + EVP_PKEY_encrypt(pctx, reenc, &reenc_len, dec, dec_len); if (reenc_len < 0) { cm_log(1, "Error reencrypting.\n"); goto retry_gen; @@ -253,17 +290,18 @@ retry_gen: done: if (ret == NULL) { + cm_log(1, "something failed, ret is NULL\n"); while ((error = ERR_get_error()) != 0) { ERR_error_string_n(error, buf, sizeof(buf)); cm_log(1, "%s\n", buf); } } + if (pctx) { + EVP_PKEY_CTX_free(pctx); + } if (pkey != NULL) { EVP_PKEY_free(pkey); } - if (exponent != NULL) { - BN_free(exponent); - } if (p7 != NULL) { PKCS7_free(p7); }