summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2023-06-13 21:56:57 +0200
committerDr. David von Oheimb <dev@ddvo.net>2023-12-19 13:07:19 +0100
commit7c6577ba9f5eb348476a53d822a4db6af0d36d36 (patch)
treeb799a90123dc4216af60006772adf4fe18d6dfa0 /apps
parent430dcbd0463573fece704263648cc15e891c3d49 (diff)
CMP lib and app: add optional certProfile request message header and respective -profile option
Also add missing getter functionss OSSL_CMP_{CTX,HDR}_get0_geninfo_ITAVs() to CMP API. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> (Merged from https://github.com/openssl/openssl/pull/21281)
Diffstat (limited to 'apps')
-rw-r--r--apps/cmp.c44
-rw-r--r--apps/lib/cmp_mock_srv.c36
2 files changed, 78 insertions, 2 deletions
diff --git a/apps/cmp.c b/apps/cmp.c
index dd5a69af7c..67f281e0aa 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -112,6 +112,7 @@ static int opt_cmd = -1;
static char *opt_geninfo = NULL;
static char *opt_infotype_s = NULL;
static int opt_infotype = NID_undef;
+static char *opt_profile = NULL;
/* certificate enrollment */
static char *opt_newkey = NULL;
@@ -210,7 +211,7 @@ typedef enum OPTION_choice {
OPT_COMMON,
OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY,
- OPT_CMD, OPT_INFOTYPE, OPT_GENINFO,
+ OPT_CMD, OPT_INFOTYPE, OPT_PROFILE, OPT_GENINFO,
OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT,
OPT_DAYS, OPT_REQEXTS,
@@ -291,6 +292,8 @@ const OPTIONS cmp_options[] = {
"InfoType name for requesting specific info in genm, with specific support"},
{OPT_MORE_STR, 0, 0,
"for 'caCerts' and 'rootCaCert'"},
+ {"profile", OPT_PROFILE, 's',
+ "Certificate profile name to place in generalInfo field of request PKIHeader"},
{"geninfo", OPT_GENINFO, 's',
"generalInfo integer values to place in request PKIHeader with given OID"},
{OPT_MORE_STR, 0, 0,
@@ -587,7 +590,7 @@ typedef union {
static varref cmp_vars[] = { /* must be in same order as enumerated above! */
{&opt_config}, {&opt_section}, {(char **)&opt_verbosity},
- {&opt_cmd_s}, {&opt_infotype_s}, {&opt_geninfo},
+ {&opt_cmd_s}, {&opt_infotype_s}, {&opt_profile}, {&opt_geninfo},
{&opt_newkey}, {&opt_newkeypass}, {&opt_subject},
{(char **)&opt_days}, {&opt_reqexts},
@@ -1837,6 +1840,37 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
return 0;
}
+static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name)
+{
+ OSSL_CMP_ITAV *itav = NULL;
+ STACK_OF(ASN1_UTF8STRING) *sk;
+ ASN1_UTF8STRING *utf8string;
+
+ if (ctx == NULL || name == NULL)
+ return 0;
+
+ if ((sk = sk_ASN1_UTF8STRING_new_reserve(NULL, 1)) == NULL)
+ return 0;
+ if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
+ goto err;
+ if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) {
+ ASN1_STRING_free(utf8string);
+ goto err;
+ }
+ /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */
+ (void)sk_ASN1_UTF8STRING_push(sk, utf8string);
+ if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL)
+ goto err;
+ if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav))
+ return 1;
+ OSSL_CMP_ITAV_free(itav);
+ return 0;
+
+ err:
+ sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free);
+ return 0;
+}
+
static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
{
long value;
@@ -2078,6 +2112,8 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
goto err;
+ if (opt_profile != NULL && !add_certProfile(ctx, opt_profile))
+ goto err;
/* not printing earlier, to minimize confusion in case setup fails before */
if (opt_rspin != NULL)
@@ -2603,6 +2639,9 @@ static int get_opts(int argc, char **argv)
case OPT_INFOTYPE:
opt_infotype_s = opt_str();
break;
+ case OPT_PROFILE:
+ opt_profile = opt_str();
+ break;
case OPT_GENINFO:
opt_geninfo = opt_str();
break;
@@ -3131,6 +3170,7 @@ int cmp_main(int argc, char **argv)
cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq());
if (cmp_ctx == NULL)
goto err;
+
OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity);
if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) {
CMP_err1("cannot set up error reporting and logging for %s", prog);
diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c
index a0450446c1..d58937ea78 100644
--- a/apps/lib/cmp_mock_srv.c
+++ b/apps/lib/cmp_mock_srv.c
@@ -241,6 +241,42 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
/* give final response after polling */
ctx->curr_pollCount = 0;
+ /* accept cert profile for cr messages only with the configured name */
+ if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_CR) {
+ STACK_OF(OSSL_CMP_ITAV) *itavs =
+ OSSL_CMP_HDR_get0_geninfo_ITAVs(OSSL_CMP_MSG_get0_header(cert_req));
+ int i;
+
+ for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
+ OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i);
+ ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav);
+ STACK_OF(ASN1_UTF8STRING) *strs;
+ ASN1_UTF8STRING *str;
+ const char *data;
+
+ if (OBJ_obj2nid(obj) == NID_id_it_certProfile) {
+ if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs))
+ return NULL;
+ if (sk_ASN1_UTF8STRING_num(strs) < 1) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+ return NULL;
+ }
+ str = sk_ASN1_UTF8STRING_value(strs, 0);
+ if (str == NULL
+ || (data =
+ (const char *)ASN1_STRING_get0_data(str)) == NULL) {
+ ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
+ return NULL;
+ }
+ if (strcmp(data, "profile1") != 0) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+ return NULL;
+ }
+ break;
+ }
+ }
+ }
+
/* accept cert update request only for the reference cert, if given */
if (bodytype == OSSL_CMP_KUR
&& crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {