diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2023-06-13 21:56:57 +0200 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2023-12-19 13:07:19 +0100 |
commit | 7c6577ba9f5eb348476a53d822a4db6af0d36d36 (patch) | |
tree | b799a90123dc4216af60006772adf4fe18d6dfa0 /apps | |
parent | 430dcbd0463573fece704263648cc15e891c3d49 (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.c | 44 | ||||
-rw-r--r-- | apps/lib/cmp_mock_srv.c | 36 |
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) { |