+static int do_genm(OSSL_CMP_CTX *ctx)
+{
+ if (opt_infotype == NID_id_it_caCerts) {
+ STACK_OF(X509) *cacerts = NULL;
+
+ if (opt_cacertsout == NULL) {
+ CMP_err("Missing -cacertsout option for -infotype caCerts");
+ return 0;
+ }
+
+ if (!OSSL_CMP_get1_caCerts(ctx, &cacerts))
+ return 0;
+
+ /* could check authorization of sender/origin at this point */
+ if (cacerts == NULL) {
+ CMP_warn("no CA certificates provided by server");
+ } else if (save_free_certs(cacerts, opt_cacertsout, "CA") < 0) {
+ CMP_err1("Failed to store CA certificates from genp in %s",
+ opt_cacertsout);
+ return 0;
+ }
+ return 1;
+ } else if (opt_infotype == NID_id_it_rootCaCert) {
+ X509 *oldwithold = NULL;
+ X509 *newwithnew = NULL;
+ X509 *newwithold = NULL;
+ X509 *oldwithnew = NULL;
+ int res = 0;
+
+ if (opt_newwithnew == NULL) {
+ CMP_err("Missing -newwithnew option for -infotype rootCaCert");
+ return 0;
+ }
+ if (opt_oldwithold == NULL) {
+ CMP_warn("No -oldwithold given, will use all certs given with -trusted as trust anchors for verifying the newWithNew cert");
+ } else {
+ oldwithold = load_cert_pwd(opt_oldwithold, opt_otherpass,
+ "OldWithOld cert for genm with -infotype rootCaCert");
+ if (oldwithold == NULL)
+ goto end_upd;
+ }
+ if (!OSSL_CMP_get1_rootCaKeyUpdate(ctx, oldwithold, &newwithnew,
+ &newwithold, &oldwithnew))
+ goto end_upd;
+ /* At this point might check authorization of response sender/origin */
+
+ if (newwithnew == NULL)
+ CMP_info("no root CA certificate update available");
+ else if (oldwithold == NULL && oldwithnew != NULL)
+ CMP_warn("oldWithNew certificate received in genp for verifying oldWithOld, but oldWithOld was not provided");
+
+ if (save_cert_or_delete(newwithnew, opt_newwithnew,
+ "NewWithNew cert from genp")
+ && save_cert_or_delete(newwithold, opt_newwithold,
+ "NewWithOld cert from genp")
+ && save_cert_or_delete(oldwithnew, opt_oldwithnew,
+ "OldWithNew cert from genp"))
+ res = 1;
+
+ X509_free(newwithnew);
+ X509_free(newwithold);
+ X509_free(oldwithnew);
+ end_upd:
+ X509_free(oldwithold);
+ return res;
+ } else {
+ OSSL_CMP_ITAV *req;
+ STACK_OF(OSSL_CMP_ITAV) *itavs;
+
+ if (opt_infotype != NID_undef) {
+ CMP_warn1("No specific support for -infotype %s available",
+ opt_infotype_s);
+
+ req = OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL);
+ if (req == NULL || !OSSL_CMP_CTX_push0_genm_ITAV(ctx, req)) {
+ CMP_err1("Failed to create genm for -infotype %s",
+ opt_infotype_s);
+ return 0;
+ }
+ }
+
+ if ((itavs = OSSL_CMP_exec_GENM_ses(ctx)) != NULL) {
+ int res = print_itavs(itavs);
+
+ sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
+ return res;
+ }
+ if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request)
+ CMP_err("Did not receive response on genm or genp is not valid");
+ return 0;
+ }
+}
+