]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
CMP lib and app: add optional certProfile request message header and respective ...
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 13 Jun 2023 19:56:57 +0000 (21:56 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Tue, 19 Dec 2023 12:07:19 +0000 (13:07 +0100)
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)

17 files changed:
CHANGES.md
apps/cmp.c
apps/lib/cmp_mock_srv.c
crypto/cmp/cmp_asn.c
crypto/cmp/cmp_ctx.c
crypto/cmp/cmp_err.c
crypto/cmp/cmp_hdr.c
crypto/cmp/cmp_local.h
crypto/err/openssl.txt
doc/man1/openssl-cmp.pod.in
doc/man3/OSSL_CMP_CTX_new.pod
doc/man3/OSSL_CMP_HDR_get0_transactionID.pod
doc/man3/OSSL_CMP_ITAV_set0.pod
include/openssl/cmp.h.in
include/openssl/cmperr.h
test/recipes/80-test_cmp_http_data/test_commands.csv
util/libcrypto.num

index 93365619fa8f8f3f3f379fbeb31e03d732a50aae..f1c8bce1b34f597512710c2c9f17bb78339e66b3 100644 (file)
@@ -33,6 +33,11 @@ OpenSSL 3.3
 
    *James Muir*
 
+ * Added several new features of CMPv3 defined in RFC 9480 and RFC 9483:
+   - `certProfile` request message header and respective `-profile` CLI option
+
+   *David von Oheimb*
+
  * The build of exporters (such as `.pc` files for pkg-config) cleaned up to
    be less hard coded in the build file templates, and to allow easier
    addition of more exporters.  With that, an exporter for CMake is also
index dd5a69af7c35b1593756461fc847a2d7eadb3740..67f281e0aa74b30f66ec708aa88164ecc19b3118 100644 (file)
@@ -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);
index a0450446c1ca631cbe25d8879374a1dfb91ea441..d58937ea7823bbf05ff632e516c1cdf30f03ed02 100644 (file)
@@ -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) {
index 0133dc5f80b610e126f0cc90e6dddc51b6c94596..3049d4f0800817a1728d99f06661464ef6c97644 100644 (file)
@@ -58,11 +58,7 @@ IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)
 ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
     ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI),
     ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER),
-    /*
-     * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     *
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails,
                          ASN1_UTF8STRING)
 } ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT)
@@ -121,6 +117,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = {
     ADB_ENTRY(NID_id_it_rootCaKeyUpdate,
               ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate,
                        OSSL_CMP_ROOTCAKEYUPDATE)),
+    ADB_ENTRY(NID_id_it_certProfile,
+              ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile,
+                                   ASN1_UTF8STRING)),
 } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0,
                &infotypeandvalue_default_tt, NULL);
 
@@ -190,13 +189,40 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
     return 1;
 
  err:
-    if (created != 0) {
+    if (created) {
         sk_OSSL_CMP_ITAV_free(*itav_sk_p);
         *itav_sk_p = NULL;
     }
     return 0;
 }
 
+OSSL_CMP_ITAV
+*OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING) *certProfile)
+{
+    OSSL_CMP_ITAV *itav;
+
+    if ((itav = OSSL_CMP_ITAV_new()) == NULL)
+        return NULL;
+    itav->infoType = OBJ_nid2obj(NID_id_it_certProfile);
+    itav->infoValue.certProfile = certProfile;
+    return itav;
+}
+
+int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
+                                   STACK_OF(ASN1_UTF8STRING) **out)
+{
+    if (itav == NULL || out == NULL) {
+        ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (OBJ_obj2nid(itav->infoType) != NID_id_it_certProfile) {
+        ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+    *out = itav->infoValue.certProfile;
+    return 1;
+}
+
 OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts)
 {
     OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
@@ -327,7 +353,7 @@ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a)
 }
 
 static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval,
-                           const ASN1_ITEM *it, void *exarg)
+                           ossl_unused const ASN1_ITEM *it, void *exarg)
 {
     OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval;
 
@@ -417,14 +443,9 @@ ASN1_ITEM_TEMPLATE_END(OSSL_CMP_PKISTATUS)
 
 ASN1_SEQUENCE(OSSL_CMP_PKISI) = {
     ASN1_SIMPLE(OSSL_CMP_PKISI, status, OSSL_CMP_PKISTATUS),
-    /*
-     * CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_PKISI, statusString, ASN1_UTF8STRING),
-    /*
-     * OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING so used directly
-     */
+    /* OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING, used directly */
     ASN1_OPT(OSSL_CMP_PKISI, failInfo, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END(OSSL_CMP_PKISI)
 IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
@@ -541,10 +562,7 @@ ASN1_SEQUENCE(OSSL_CMP_PKIHEADER) = {
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, transactionID, ASN1_OCTET_STRING, 4),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderNonce, ASN1_OCTET_STRING, 5),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipNonce, ASN1_OCTET_STRING, 6),
-    /*
-     * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, freeText, ASN1_UTF8STRING, 7),
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, generalInfo,
                              OSSL_CMP_ITAV, 8)
index 947d2ceb8fde8b255ce0e119aac585715c0bff9a..5e542200e9e05d22dc44e05d12081895360ecafe 100644 (file)
@@ -534,6 +534,8 @@ int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx)
     return 1;
 }
 
+DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs, STACK_OF(OSSL_CMP_ITAV))
+
 /* Add an itav for the body of outgoing general messages */
 int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
 {
index 3853e52605969a23e4a64f87d422104a9f83cf84..c4d5c97f9e1b878c278b5efc74901c7833e834bb 100644 (file)
@@ -144,6 +144,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "transactionid unmatched"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE),
+     "unexpected certprofile"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
     "unexpected pkistatus"},
index 5fabf1aa3349106dfafe7c068f7f52a31f1e5f5e..4358b38873f357579bf6267601f07463adbf288d 100644 (file)
@@ -72,6 +72,16 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr)
     return hdr->recipNonce;
 }
 
+STACK_OF(OSSL_CMP_ITAV)
+    *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr)
+{
+    if (hdr == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return NULL;
+    }
+    return hdr->generalInfo;
+}
+
 /* a NULL-DN as an empty sequence of RDNs */
 int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name)
 {
index 29aa84cd2a09e69afe0790ab9947cc0712bb899a..b8da48ac439c82eb1d56b2190232cc76d256fa6a 100644 (file)
@@ -254,6 +254,8 @@ struct ossl_cmp_itav_st {
         OSSL_CMP_MSGS *origPKIMessage;
         /* NID_id_it_suppLangTags - Supported Language Tags */
         STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue;
+        /* NID_id_it_certProfile - Certificate Profile */
+        STACK_OF(ASN1_UTF8STRING) *certProfile;
         /* NID_id_it_caCerts - CA Certificates */
         STACK_OF(X509) *caCerts;
         /* NID_id_it_rootCaCert - Root CA Certificate */
index 5f60bd52d2d46613e620010b4b166987fe188863..8e6d9ddcae96b137ccce8bb1bea4a5b9b7b0f8b5 100644 (file)
@@ -272,6 +272,7 @@ CMP_R_TOTAL_TIMEOUT:184:total timeout
 CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
 CMP_R_TRANSFER_ERROR:159:transfer error
 CMP_R_UNCLEAN_CTX:191:unclean ctx
+CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile
 CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
 CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
 CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
index 051c749d08e617e879651bb79274838c15b18735..ee54697c9c65b20600a31e953ecc5d9c53143ce1 100644 (file)
@@ -17,6 +17,7 @@ Generic message options:
 
 [B<-cmd> I<ir|cr|kur|p10cr|rr|genm>]
 [B<-infotype> I<name>]
+[B<-profile> I<name>]
 [B<-geninfo> I<OID:int:N>]
 
 Certificate enrollment options:
@@ -246,6 +247,11 @@ Set InfoType name to use for requesting specific info in B<genm>,
 e.g., C<signKeyPairTypes>.
 So far, there is specific support for C<caCerts> and C<rootCaCert>.
 
+=item B<-profile> I<name>
+
+Name of a certificate profile to place in
+the PKIHeader generalInfo field of request messages.
+
 =item B<-geninfo> I<OID:int:N>
 
 generalInfo integer values to place in request PKIHeader with given OID,
@@ -1390,7 +1396,9 @@ L<openssl-req(1)>, L<openssl-x509(1)>, L<x509v3_config(5)>
 
 The B<cmp> application was added in OpenSSL 3.0.
 
-The B<-engine option> was deprecated in OpenSSL 3.0.
+The B<-engine> option was deprecated in OpenSSL 3.0.
+
+The B<-profile> option was added in OpenSSL 3.3.
 
 =head1 COPYRIGHT
 
index 810997017176b32b9a408dadcf185a9b0adec5bc..d038f2f61c62fc488afb56f2b6abec20e09e5b31 100644 (file)
@@ -39,6 +39,7 @@ OSSL_CMP_CTX_set1_secretValue,
 OSSL_CMP_CTX_set1_recipient,
 OSSL_CMP_CTX_push0_geninfo_ITAV,
 OSSL_CMP_CTX_reset_geninfo_ITAVs,
+OSSL_CMP_CTX_get0_geninfo_ITAVs,
 OSSL_CMP_CTX_set1_extraCertsOut,
 OSSL_CMP_CTX_set0_newPkey,
 OSSL_CMP_CTX_get0_newPkey,
@@ -127,6 +128,8 @@ OSSL_CMP_CTX_set1_senderNonce
  int OSSL_CMP_CTX_set1_recipient(OSSL_CMP_CTX *ctx, const X509_NAME *name);
  int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav);
  int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx);
+ STACK_OF(OSSL_CMP_ITAV)
+     *OSSL_CMP_CTX_get0_geninfo_ITAVs(const OSSL_CMP_CTX *ctx);
  int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
                                      STACK_OF(X509) *extraCertsOut);
 
@@ -540,12 +543,16 @@ the issuer of the CMP signer certificate,
 as far as any of those is present, else the NULL-DN as last resort.
 
 OSSL_CMP_CTX_push0_geninfo_ITAV() adds I<itav> to the stack in the I<ctx> to be
-added to the GeneralInfo field of the CMP PKIMessage header of a request
+added to the generalInfo field of the CMP PKIMessage header of a request
 message sent with this context.
 
 OSSL_CMP_CTX_reset_geninfo_ITAVs()
 clears any ITAVs that were added by OSSL_CMP_CTX_push0_geninfo_ITAV().
 
+OSSL_CMP_CTX_get0_geninfo_ITAVs() returns the list of ITAVs set in I<ctx>
+for inclusion in the generalInfo field of the CMP PKIMessage header of requests
+or NULL if not set.
+
 OSSL_CMP_CTX_set1_extraCertsOut() sets the stack of extraCerts that will be
 sent to remote.
 
@@ -737,6 +744,7 @@ OSSL_CMP_CTX_get_http_cb_arg(),
 OSSL_CMP_CTX_get_transfer_cb_arg(),
 OSSL_CMP_CTX_get0_trusted(),
 OSSL_CMP_CTX_get0_untrusted(),
+OSSL_CMP_CTX_get0_geninfo_ITAVs(),
 OSSL_CMP_CTX_get0_newPkey(),
 OSSL_CMP_CTX_get_certConf_cb_arg(),
 OSSL_CMP_CTX_get0_statusString(),
@@ -841,10 +849,11 @@ in OpenSSL 3.2.
 
 OSSL_CMP_CTX_reset_geninfo_ITAVs() was added in OpenSSL 3.0.8.
 
+OSSL_CMP_CTX_set1_serialNumber(),
 OSSL_CMP_CTX_get0_libctx(), OSSL_CMP_CTX_get0_propq(), and
 OSSL_CMP_CTX_get0_validatedSrvCert() were added in OpenSSL 3.2.
 
-OSSL_CMP_CTX_set1_serialNumber() was added in OpenSSL 3.2.
+OSSL_CMP_CTX_get0_geninfo_ITAVs() was added in OpenSSL 3.3.
 
 =head1 COPYRIGHT
 
index 36bdf1917f39950e4fd57a5cfea9d4749ba81b96..6e79e9a0e3c399c2851b1ed971a5c98d209c9ff5 100644 (file)
@@ -3,7 +3,8 @@
 =head1 NAME
 
 OSSL_CMP_HDR_get0_transactionID,
-OSSL_CMP_HDR_get0_recipNonce
+OSSL_CMP_HDR_get0_recipNonce,
+OSSL_CMP_HDR_get0_geninfo_ITAVs
 - functions manipulating CMP message headers
 
 =head1 SYNOPSIS
@@ -14,6 +15,8 @@ OSSL_CMP_HDR_get0_recipNonce
                                                      OSSL_CMP_PKIHEADER *hdr);
   ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const
                                                   OSSL_CMP_PKIHEADER *hdr);
+ STACK_OF(OSSL_CMP_ITAV)
+     *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr);
 
 =head1 DESCRIPTION
 
@@ -22,6 +25,9 @@ PKIHeader.
 
 OSSL_CMP_HDR_get0_recipNonce returns the recipient nonce of the given PKIHeader.
 
+OSSL_CMP_HDR_get0_geninfo_ITAVs() returns the list of ITAVs
+in the generalInfo field of the given PKIHeader.
+
 =head1 NOTES
 
 CMP is defined in RFC 4210.
@@ -35,6 +41,8 @@ or NULL if the respective entry does not exist and on error.
 
 The OpenSSL CMP support was added in OpenSSL 3.0.
 
+OSSL_CMP_HDR_get0_geninfo_ITAVs() was added in OpenSSL 3.3.
+
 =head1 COPYRIGHT
 
 Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
index 5dd9bcb266fb847df4b27834ab843a2cdc26b16f..13d7868a6debd56e2641abb15bc9a4edb6afbb53 100644 (file)
@@ -6,7 +6,9 @@ OSSL_CMP_ITAV_create,
 OSSL_CMP_ITAV_set0,
 OSSL_CMP_ITAV_get0_type,
 OSSL_CMP_ITAV_get0_value,
-OSSL_CMP_ITAV_push0_stack_item
+OSSL_CMP_ITAV_push0_stack_item,
+OSSL_CMP_ITAV_new0_certProfile,
+OSSL_CMP_ITAV_get0_certProfile
 - OSSL_CMP_ITAV utility functions
 
 =head1 SYNOPSIS
@@ -20,6 +22,10 @@ OSSL_CMP_ITAV_push0_stack_item
  ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav);
  int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
                                     OSSL_CMP_ITAV *itav);
+ OSSL_CMP_ITAV
+ *OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING) *certProfile);
+ int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
+                                    STACK_OF(ASN1_UTF8STRING) **out);
 
 =head1 DESCRIPTION
 
@@ -43,21 +49,37 @@ the I<itav> as generic B<ASN1_TYPE> pointer.
 OSSL_CMP_ITAV_push0_stack_item() pushes I<itav> to the stack pointed to
 by I<*itav_sk_p>. It creates a new stack if I<*itav_sk_p> points to NULL.
 
+OSSL_CMP_ITAV_new0_certProfile() creates a new B<OSSL_CMP_ITAV> structure
+of type B<certProfile> that includes the optionally given list of profile names.
+On success, ownership of the list is with the new B<OSSL_CMP_ITAV> structure.
+
+OSSL_CMP_ITAV_get0_certProfile() on success assigns to I<*out>
+an internal pointer to the
+list of certificate profile names contained in the infoValue field of I<itav>.
+The pointer may be NULL if no profile name is included.
+It is an error if the infoType of I<itav> is not B<certProfile>.
+
 =head1 NOTES
 
-CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+CMP is defined in RFC 4210 and RFC 9480 (and CRMF in RFC 4211).
+
+OIDs to use as types in B<OSSL_CMP_ITAV> can be found at
+L<https://datatracker.ietf.org/doc/html/rfc9480#section-4.2.2>.
+The respective OpenSSL NIDs, such as B<NID_id_it_certProfile>,
+are defined in the F<< <openssl/obj_mac.h> >> header file.
 
 =head1 RETURN VALUES
 
-OSSL_CMP_ITAV_create() returns a pointer to the ITAV structure on success,
-or NULL on error.
+OSSL_CMP_ITAV_create() and OSSL_CMP_ITAV_new0_certProfile()
+return a pointer to an ITAV structure on success, or NULL on error.
 
 OSSL_CMP_ITAV_set0() does not return a value.
 
 OSSL_CMP_ITAV_get0_type() and OSSL_CMP_ITAV_get0_value()
 return the respective pointer or NULL if their input is NULL.
 
-OSSL_CMP_ITAV_push0_stack_item() returns 1 on success, 0 on error.
+OSSL_CMP_ITAV_push0_stack_item() and OSSL_CMP_ITAV_get0_certProfile()
+return 1 on success, 0 on error.
 
 =head1 EXAMPLES
 
@@ -96,6 +118,9 @@ L<OSSL_CMP_CTX_new(3)>, L<OSSL_CMP_CTX_free(3)>, L<ASN1_TYPE_set(3)>
 
 The OpenSSL CMP support was added in OpenSSL 3.0.
 
+OSSL_CMP_ITAV_new0_certProfile() and OSSL_CMP_ITAV_get0_certProfile()
+were added in OpenSSL 3.3.
+
 =head1 COPYRIGHT
 
 Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
index 5bd8beb57a14dbe1d743343586b63c581b9dd7b7..fa4fe000ba94d44ace07237e4011e58c77f8a697 100644 (file)
@@ -261,6 +261,10 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
                                    OSSL_CMP_ITAV *itav);
 void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav);
 
+OSSL_CMP_ITAV *OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING)
+                                              *certProfile);
+int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
+                                   STACK_OF(ASN1_UTF8STRING) **out);
 OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts);
 int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out);
 
@@ -351,6 +355,8 @@ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx,
 int OSSL_CMP_CTX_set1_recipient(OSSL_CMP_CTX *ctx, const X509_NAME *name);
 int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav);
 int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx);
+STACK_OF(OSSL_CMP_ITAV)
+    *OSSL_CMP_CTX_get0_geninfo_ITAVs(const OSSL_CMP_CTX *ctx);
 int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
                                     STACK_OF(X509) *extraCertsOut);
 /* certificate template: */
@@ -403,6 +409,8 @@ OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text);
 ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
                                                    OSSL_CMP_PKIHEADER *hdr);
 ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
+STACK_OF(OSSL_CMP_ITAV)
+    *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr);
 
 /* from cmp_msg.c */
 OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
index 57a6effbe3fc2db148abe0c9bec7ddeb79e27dc3..dec9e0be45479e828caf4adf483a2b7b20143804 100644 (file)
@@ -98,6 +98,7 @@
 #  define CMP_R_TRANSACTIONID_UNMATCHED                    152
 #  define CMP_R_TRANSFER_ERROR                             159
 #  define CMP_R_UNCLEAN_CTX                                191
+#  define CMP_R_UNEXPECTED_CERTPROFILE                     196
 #  define CMP_R_UNEXPECTED_PKIBODY                         133
 #  define CMP_R_UNEXPECTED_PKISTATUS                       185
 #  define CMP_R_UNEXPECTED_PVNO                            153
index 5ab2ca3fd7a61696b1b235e81f1e9dbe3a49ef59..869bab7c9967f8191e6e95f991903c440ba9b29a 100644 (file)
@@ -77,6 +77,11 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty
 0,genm rootCaCert newwithold missig arg  , -section,, -cmd,genm,, BLANK,,, -infotype,rootCaCert,, -oldwithold, oldWithOld.pem, -newwithnew, _RESULT_DIR/test.newwithnew.pem, -oldwithnew, _RESULT_DIR/test.oldwithnew.pem, -newwithold,,
 1,genm rootCaCert newwithnew newwithold  , -section,, -cmd,genm,, BLANK,,, -infotype,rootCaCert,, -oldwithold, oldWithOld.pem, -newwithnew, _RESULT_DIR/test.newwithnew3.pem, -newwithold, _RESULT_DIR/test.newwithold2.pem
 ,,,,,,,,,,,,,,,,,,,,,,
+1,profile, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile1,BLANK,,BLANK,
+0,profile wrong value, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile2,BLANK,,BLANK,
+0,profile missing argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,,,,,
+0,profile extra argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile1,profile2,,,
+,,,,,,,,,,,,,,,,,,,
 1,geninfo, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,1.2.3:int:987,BLANK,,BLANK,
 0,geninfo missing argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,,,,,
 0,geninfo bad syntax: leading '.', -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,.1.2.3:int:987,BLANK,,BLANK,
index c9941a383be0d13cd0e6599c9a78975c856d5710..60f320c33a711d4586af35df1c5cf1f2067cffed 100644 (file)
@@ -5536,4 +5536,8 @@ X509_STORE_CTX_set_get_crl              5663      3_2_0   EXIST::FUNCTION:
 X509_STORE_CTX_set_current_reasons      5664   3_2_0   EXIST::FUNCTION:
 OSSL_STORE_delete                       5665   3_2_0   EXIST::FUNCTION:
 BIO_ADDR_copy                           5666   3_2_0   EXIST::FUNCTION:SOCK
+OSSL_CMP_CTX_get0_geninfo_ITAVs         ?      3_3_0   EXIST::FUNCTION:CMP
+OSSL_CMP_HDR_get0_geninfo_ITAVs         ?      3_3_0   EXIST::FUNCTION:CMP
+OSSL_CMP_ITAV_new0_certProfile          ?      3_3_0   EXIST::FUNCTION:CMP
+OSSL_CMP_ITAV_get0_certProfile          ?      3_3_0   EXIST::FUNCTION:CMP
 EVP_DigestSqueeze                       ?      3_3_0   EXIST::FUNCTION: