]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add OSSL_CMP_CTX_get0_validatedSrvCert(), correcting OSSL_CMP_validate_msg()
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 14 Dec 2021 10:29:19 +0000 (11:29 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Wed, 20 Jul 2022 09:40:37 +0000 (11:40 +0200)
Also change ossl_cmp_ctx_set0_validatedSrvCert() to ossl_cmp_ctx_set1_validatedSrvCert(),
and add respective tests as well as the -srvcertout CLI option using the new function.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/18656)

apps/cmp.c
crypto/cmp/cmp_ctx.c
crypto/cmp/cmp_local.h
crypto/cmp/cmp_vfy.c
doc/man1/openssl-cmp.pod.in
doc/man3/OSSL_CMP_CTX_new.pod
include/openssl/cmp.h.in
test/cmp_ctx_test.c
test/cmp_vfy_test.c
util/libcrypto.num

index deb709cae03de35fa19503c5b0aa54027f81ab34..f3624aa94a6712b6d639278b9f89ae4123a6afbe 100644 (file)
@@ -86,6 +86,7 @@ static char *opt_srvcert = NULL;
 static char *opt_expect_sender = NULL;
 static int opt_ignore_keyusage = 0;
 static int opt_unprotected_errors = 0;
+static char *opt_srvcertout = NULL;
 static char *opt_extracertsout = NULL;
 static char *opt_cacertsout = NULL;
 
@@ -220,7 +221,7 @@ typedef enum OPTION_choice {
     OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT,
     OPT_EXPECT_SENDER,
     OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS,
-    OPT_EXTRACERTSOUT, OPT_CACERTSOUT,
+    OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT,
 
     OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS,
     OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS,
@@ -388,6 +389,8 @@ const OPTIONS cmp_options[] = {
      "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"},
     {OPT_MORE_STR, 0, 0,
      "WARNING: This setting leads to behavior allowing violation of RFC 4210"},
+    { "srvcertout", OPT_SRVCERTOUT, 's',
+      "File to save the server cert used and validated for CMP response protection"},
     {"extracertsout", OPT_EXTRACERTSOUT, 's',
      "File to save extra certificates received in the extraCerts field"},
     {"cacertsout", OPT_CACERTSOUT, 's',
@@ -573,7 +576,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
     {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert},
     {&opt_expect_sender},
     {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors},
-    {&opt_extracertsout}, {&opt_cacertsout},
+    {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout},
 
     {&opt_ref}, {&opt_secret},
     {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass},
@@ -1493,6 +1496,7 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
 
     if (opt_mac != NULL) {
         int mac = OBJ_ln2nid(opt_mac);
+
         if (mac == NID_undef) {
             CMP_err1("MAC algorithm name not recognized: '%s'", opt_mac);
             return 0;
@@ -2005,36 +2009,41 @@ static int write_cert(BIO *bio, X509 *cert)
 }
 
 /*
- * If destFile != NULL writes out a stack of certs to the given file.
- * In any case frees the certs.
+ * If file != NULL writes out a stack of certs to the given file.
+ * If certs is NULL, the file is emptied.
+ * Frees the certs if present.
  * Depending on options use either PEM or DER format,
  * where DER does not make much sense for writing more than one cert!
  * Returns number of written certificates on success, -1 on error.
  */
-static int save_free_certs(OSSL_CMP_CTX *ctx,
-                           STACK_OF(X509) *certs, char *destFile, char *desc)
+static int save_free_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
+                           const char *file, const char *desc)
 {
     BIO *bio = NULL;
     int i;
-    int n = sk_X509_num(certs);
+    int n = sk_X509_num(certs /* may be NULL */);
 
-    if (destFile == NULL)
+    if (n < 0)
+        n = 0;
+    if (file == NULL)
         goto end;
-    CMP_info3("received %d %s certificate(s), saving to file '%s'",
-              n, desc, destFile);
+    if (certs != NULL)
+        CMP_info3("received %d %s certificate(s), saving to file '%s'",
+                  n, desc, file);
     if (n > 1 && opt_certform != FORMAT_PEM)
         CMP_warn("saving more than one certificate in non-PEM format");
 
-    if (destFile == NULL || (bio = BIO_new(BIO_s_file())) == NULL
-            || !BIO_write_filename(bio, (char *)destFile)) {
-        CMP_err1("could not open file '%s' for writing", destFile);
+    if ((bio = BIO_new(BIO_s_file())) == NULL
+            || !BIO_write_filename(bio, (char *)file)) {
+        CMP_err3("could not open file '%s' for %s %s certificate(s)",
+                 file, certs == NULL ? "deleting" : "writing", desc);
         n = -1;
         goto end;
     }
 
     for (i = 0; i < n; i++) {
         if (!write_cert(bio, sk_X509_value(certs, i))) {
-            CMP_err1("cannot write certificate to file '%s'", destFile);
+            CMP_err2("cannot write %s certificate to file '%s'", desc, file);
             n = -1;
             goto end;
         }
@@ -2046,6 +2055,35 @@ static int save_free_certs(OSSL_CMP_CTX *ctx,
     return n;
 }
 
+static int delete_certfile(const char *file, const char *desc)
+{
+    if (file == NULL)
+        return 1;
+
+    if (unlink(file) != 0 && errno != ENOENT) {
+        CMP_err2("Failed to delete %s, which should be done to indicate there is no %s cert",
+                 file, desc);
+        return 0;
+    }
+    return 1;
+}
+
+static int save_cert(OSSL_CMP_CTX *ctx, X509 *cert,
+                     const char *file, const char *desc)
+{
+    if (file == NULL || cert == NULL) {
+        return 1;
+    } else {
+        STACK_OF(X509) *certs = sk_X509_new_null();
+
+        if (!X509_add_cert(certs, cert, X509_ADD_FLAG_UP_REF)) {
+            sk_X509_free(certs);
+            return 0;
+        }
+        return save_free_certs(ctx, certs, file, desc) >= 0;
+    }
+}
+
 static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs)
 {
     int i, ret = 1;
@@ -2422,6 +2460,9 @@ static int get_opts(int argc, char **argv)
         case OPT_UNPROTECTED_ERRORS:
             opt_unprotected_errors = 1;
             break;
+        case OPT_SRVCERTOUT:
+            opt_srvcertout = opt_str();
+            break;
         case OPT_EXTRACERTSOUT:
             opt_extracertsout = opt_str();
             break;
@@ -2789,6 +2830,7 @@ int cmp_main(int argc, char **argv)
                               opt_section, configfile);
             } else {
                 const char *end = opt_section + strlen(opt_section);
+
                 while ((end = prev_item(opt_section, end)) != NULL) {
                     if (!NCONF_get_section(conf, opt_item)) {
                         CMP_err2("no [%s] section found in config file '%s'",
@@ -2812,7 +2854,15 @@ int cmp_main(int argc, char **argv)
     ret = get_opts(argc, argv);
     if (ret <= 0)
         goto err;
+
     ret = 0;
+    if (!delete_certfile(opt_srvcertout, "validated server")
+        || !delete_certfile(opt_certout, "enrolled")
+        || save_free_certs(NULL, NULL, opt_extracertsout, "extra") < 0
+        || save_free_certs(NULL, NULL, opt_cacertsout, "CA") < 0
+        || save_free_certs(NULL, NULL, opt_chainout, "chain") < 0)
+        goto err;
+
     if (!app_RAND_load())
         goto err;
 
@@ -2942,6 +2992,7 @@ int cmp_main(int argc, char **argv)
                 if (opt_infotype != NID_undef) {
                     OSSL_CMP_ITAV *itav =
                         OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL);
+
                     if (itav == NULL)
                         goto err;
                     OSSL_CMP_CTX_push0_genm_ITAV(cmp_ctx, itav);
@@ -2997,19 +3048,14 @@ int cmp_main(int argc, char **argv)
         if (!ret)
             goto err;
         ret = 0;
+        if (!save_cert(cmp_ctx, OSSL_CMP_CTX_get0_validatedSrvCert(cmp_ctx),
+                       opt_srvcertout, "validated server"))
+            goto err;
         if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_caPubs(cmp_ctx),
                             opt_cacertsout, "CA") < 0)
             goto err;
-        if (newcert != NULL) {
-            STACK_OF(X509) *certs = sk_X509_new_null();
-
-            if (!X509_add_cert(certs, newcert, X509_ADD_FLAG_UP_REF)) {
-                sk_X509_free(certs);
-                goto err;
-            }
-            if (save_free_certs(cmp_ctx, certs, opt_certout, "enrolled") < 0)
-                goto err;
-        }
+        if (!save_cert(cmp_ctx, newcert, opt_certout, "enrolled"))
+            goto err;
         if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_newChain(cmp_ctx),
                             opt_chainout, "chain") < 0)
             goto err;
index 207f65430ce324e2adf2353148766add1b7d4e75..0fcb3c7ae5c862a3b1cbd8c5fdbe4f751d4d2a02 100644 (file)
@@ -166,7 +166,7 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
         && ossl_cmp_ctx_set1_newChain(ctx, NULL)
         && ossl_cmp_ctx_set1_caPubs(ctx, NULL)
         && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL)
-        && ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL)
+        && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL)
         && OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
         && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)
         && ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
@@ -275,15 +275,6 @@ DEFINE_OSSL_CMP_CTX_get0(statusString, OSSL_CMP_PKIFREETEXT)
 
 DEFINE_OSSL_set0(ossl_cmp_ctx, statusString, OSSL_CMP_PKIFREETEXT)
 
-int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
-{
-    if (!ossl_assert(ctx != NULL))
-        return 0;
-    X509_free(ctx->validatedSrvCert);
-    ctx->validatedSrvCert = cert;
-    return 1;
-}
-
 /* Set callback function for checking if the cert is ok or should be rejected */
 DEFINE_OSSL_set(OSSL_CMP_CTX, certConf_cb, OSSL_CMP_certConf_cb_t)
 
@@ -585,6 +576,8 @@ int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
     return 1; \
 }
 
+DEFINE_OSSL_set1_up_ref(ossl_cmp_ctx, validatedSrvCert, X509)
+
 /*
  * Pins the server certificate to be directly trusted (even if it is expired)
  * for verifying response messages.
@@ -718,6 +711,9 @@ DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
  */
 DEFINE_OSSL_set0(ossl_cmp_ctx, newCert, X509)
 
+/* Get successfully validated server cert, if any, of current transaction */
+DEFINE_OSSL_CMP_CTX_get0(validatedSrvCert, X509)
+
 /*
  * Get the (newly received in IP/KUP/CP) client certificate from the context
  * This only permits for one client cert to be received...
index 255eb58ba60905a588645f15ba2dba95aa39c5bb..3718970ff86b8caa255f27bf9ae91763129cd87d 100644 (file)
@@ -779,7 +779,7 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
 # define ossl_cmp_info(ctx, msg)  ossl_cmp_log(INFO,  ctx, msg)
 # define ossl_cmp_debug(ctx, msg) ossl_cmp_log(DEBUG, ctx, msg)
 # define ossl_cmp_trace(ctx, msg) ossl_cmp_log(TRACE, ctx, msg)
-int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert);
+int ossl_cmp_ctx_set1_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert);
 int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status);
 int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx,
                                    OSSL_CMP_PKIFREETEXT *text);
index a269ef49da5e9edafca53beae286fd70b623c37b..543a978c0f031ebfec276a1285b31e90ca38b874 100644 (file)
@@ -354,7 +354,7 @@ static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert,
 /*-
  * Try all certs in given list for verifying msg, normally or in 3GPP mode.
  * If already_checked1 == NULL then certs are assumed to be the msg->extraCerts.
- * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
+ * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert().
  */
 static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
                                 const char *desc,
@@ -383,13 +383,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
         if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert)
                       : check_cert_path(ctx, ctx->trusted, cert)) {
             /* store successful sender cert for further msgs in transaction */
-            if (!X509_up_ref(cert))
-                return 0;
-            if (!ossl_cmp_ctx_set0_validatedSrvCert(ctx, cert)) {
-                X509_free(cert);
-                return 0;
-            }
-            return 1;
+            return ossl_cmp_ctx_set1_validatedSrvCert(ctx, cert);
         }
     }
     if (in_extraCerts && n_acceptable_certs == 0)
@@ -400,7 +394,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
 /*-
  * Verify msg trying first ctx->untrusted, which should include extraCerts
  * at its front, then trying the trusted certs in truststore (if any) of ctx.
- * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
+ * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert().
  */
 static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                                int mode_3gpp)
@@ -445,7 +439,7 @@ static int no_log_cb(const char *func, const char *file, int line,
 
 /*-
  * Verify message signature with any acceptable and valid candidate cert.
- * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
+ * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert().
  */
 static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
 {
@@ -482,7 +476,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
             return 1;
         }
         /* cached sender cert has shown to be no more successfully usable */
-        (void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
+        (void)ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL);
         /* re-do the above check (just) for adding diagnostic information */
         ossl_cmp_info(ctx,
                       "trying to verify msg signature with previously validated cert");
@@ -537,7 +531,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
  * the sender certificate can have been pinned by providing it in ctx->srvCert,
  * else it is searched in msg->extraCerts, ctx->untrusted, in ctx->trusted
  * (in this order) and is path is validated against ctx->trusted.
- * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
+ * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert().
  *
  * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg,
  * the trust anchor for validating the IP msg may be taken from msg->extraCerts
@@ -622,15 +616,17 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
                 ossl_cmp_warn(ctx, "no trust store nor pinned server cert available for verifying signature-based CMP message protection");
                 return 1;
             }
-            if (check_msg_find_cert(ctx, msg))
+            if (check_msg_find_cert(ctx, msg)) {
+                ossl_cmp_debug(ctx,
+                               "sucessfully validated signature-based CMP message protection using trust store");
                 return 1;
+            }
         } else { /* use pinned sender cert */
             /* use ctx->srvCert for signature check even if not acceptable */
             if (verify_signature(ctx, msg, scrt)) {
                 ossl_cmp_debug(ctx,
-                               "successfully validated signature-based CMP message protection");
-
-                return 1;
+                               "successfully validated signature-based CMP message protection using pinned server cert");
+                return ossl_cmp_ctx_set1_validatedSrvCert(ctx, scrt);
             }
             ossl_cmp_warn(ctx, "CMP message signature verification failed");
             ERR_raise(ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
index 17223beea00d4bc353e6705575541a459d62ca1c..1fa2e998421099fbfb2ee7cad60e4004feb746ef 100644 (file)
@@ -64,6 +64,7 @@ Server authentication options:
 [B<-expect_sender> I<name>]
 [B<-ignore_keyusage>]
 [B<-unprotected_errors>]
+[B<-srvcertout> I<filename>]
 [B<-extracertsout> I<filename>]
 [B<-cacertsout> I<filename>]
 
@@ -623,6 +624,11 @@ with a signature key."
 
 =back
 
+=item B<-srvcertout> I<filename>
+
+The file where to save the successfully validated certificate, if any,
+that the CMP server used for signature-based response message protection.
+
 =item B<-extracertsout> I<filename>
 
 The file where to save all certificates contained in the extraCerts field
index 1abbfc9bfa7d057e3ed6cf1d38517694d97b030f..636bce94bf3044a498b9a6cd789d3fc687590024 100644 (file)
@@ -57,6 +57,7 @@ OSSL_CMP_CTX_get_certConf_cb_arg,
 OSSL_CMP_CTX_get_status,
 OSSL_CMP_CTX_get0_statusString,
 OSSL_CMP_CTX_get_failInfoCode,
+OSSL_CMP_CTX_get0_validatedSrvCert,
 OSSL_CMP_CTX_get0_newCert,
 OSSL_CMP_CTX_get1_newChain,
 OSSL_CMP_CTX_get1_caPubs,
@@ -153,6 +154,7 @@ OSSL_CMP_CTX_set1_senderNonce
  OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx);
  int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx);
 
+ X509 *OSSL_CMP_CTX_get0_validatedSrvCert(const OSSL_CMP_CTX *ctx);
  X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx);
  STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx);
  STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx);
@@ -635,6 +637,13 @@ F<< <openssl/cmp.h> >>.
 The flags start with OSSL_CMP_CTX_FAILINFO, for example:
 OSSL_CMP_CTX_FAILINFO_badAlg. Returns -1 if the failInfoCode field is unset.
 
+OSSL_CMP_CTX_get0_validatedSrvCert() returns
+the successfully validated certificate, if any, that the CMP server used
+in the current transaction for signature-based response message protection,
+or NULL if the server used MAC-based protection.
+The value is relevant only at the end of a successful transaction.
+It may be used to check the authorization of the server based on its cert.
+
 OSSL_CMP_CTX_get0_newCert() returns the pointer to the newly obtained
 certificate in case it is available, else NULL.
 
@@ -674,6 +683,7 @@ OSSL_CMP_CTX_get0_untrusted(),
 OSSL_CMP_CTX_get0_newPkey(),
 OSSL_CMP_CTX_get_certConf_cb_arg(),
 OSSL_CMP_CTX_get0_statusString(),
+OSSL_CMP_CTX_get0_validatedSrvCert(),
 OSSL_CMP_CTX_get0_newCert(),
 OSSL_CMP_CTX_get0_newChain(),
 OSSL_CMP_CTX_get1_caPubs(), and
@@ -770,6 +780,8 @@ OSSL_CMP_CTX_set0_trustedStore() was renamed to OSSL_CMP_CTX_set0_trusted(),
 using macros, while keeping the old names for backward compatibility,
 in OpenSSL 3.1.
 
+OSSL_CMP_CTX_get0_validatedSrvCert() was added in OpenSSL 3.1.
+
 =head1 COPYRIGHT
 
 Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved.
index dd4d9a633d219709b09ae463f842eab280752e91..1d2f90fc5638216cbd59303279d099fe118199a5 100644 (file)
@@ -358,6 +358,7 @@ int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx);
 OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx);
 int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx);
 #  define OSSL_CMP_PKISI_BUFLEN 1024
+X509 *OSSL_CMP_CTX_get0_validatedSrvCert(const OSSL_CMP_CTX *ctx);
 X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx);
 STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx);
 STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx);
index 5876ae08a30203546d1c64a8ada22fcb644c5497..e4f80d93fc430df5bb4e155cfa60b1f3006f609a 100644 (file)
@@ -78,7 +78,7 @@ static int execute_CTX_reinit_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture)
             || !ossl_cmp_ctx_set1_newChain(ctx, certs)
             || !ossl_cmp_ctx_set1_caPubs(ctx, certs)
             || !ossl_cmp_ctx_set1_extraCertsIn(ctx, certs)
-            || !ossl_cmp_ctx_set0_validatedSrvCert(ctx, X509_dup(test_cert))
+            || !ossl_cmp_ctx_set1_validatedSrvCert(ctx, test_cert)
             || !TEST_ptr(bytes = ASN1_OCTET_STRING_new())
             || !OSSL_CMP_CTX_set1_transactionID(ctx, bytes)
             || !OSSL_CMP_CTX_set1_senderNonce(ctx, bytes)
@@ -740,7 +740,7 @@ DEFINE_SET_CB_TEST(transfer_cb)
 DEFINE_SET_GET_P_VOID_TEST(transfer_cb_arg)
 
 DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 0, srvCert, X509)
-DEFINE_SET_TEST(ossl_cmp, ctx, 0, 0, validatedSrvCert, X509)
+DEFINE_SET_GET_TEST(ossl_cmp, ctx, 1, 0, 0, validatedSrvCert, X509)
 DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, expected_sender, X509_NAME)
 DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set0, get0, 0, trusted,
                          X509_STORE *, NULL,
@@ -837,7 +837,7 @@ int setup_tests(void)
     ADD_TEST(test_CTX_set_get_transfer_cb_arg);
     /* server authentication: */
     ADD_TEST(test_CTX_set1_get0_srvCert);
-    ADD_TEST(test_CTX_set0_get0_validatedSrvCert);
+    ADD_TEST(test_CTX_set1_get0_validatedSrvCert);
     ADD_TEST(test_CTX_set1_get0_expected_sender);
     ADD_TEST(test_CTX_set0_get0_trusted);
     ADD_TEST(test_CTX_set1_get0_untrusted);
index 6b5844b30a0c9007208040fcdfebe1417a28ecc4..b17f17baeb7694b8377a34f3cf0d0f8f66362982 100644 (file)
@@ -124,11 +124,15 @@ static int test_verify_popo_bad(void)
 }
 #endif
 
+/* indirectly checks also OSSL_CMP_validate_msg() */
 static int execute_validate_msg_test(CMP_VFY_TEST_FIXTURE *fixture)
 {
-    return TEST_int_eq(fixture->expected,
-                       ossl_cmp_msg_check_update(fixture->cmp_ctx, fixture->msg,
-                                                 NULL, 0));
+    int res = TEST_int_eq(fixture->expected,
+                          ossl_cmp_msg_check_update(fixture->cmp_ctx,
+                                                    fixture->msg, NULL, 0));
+    X509 *validated = OSSL_CMP_CTX_get0_validatedSrvCert(fixture->cmp_ctx);
+
+    return res && (!fixture->expected || TEST_ptr_eq(validated, fixture->cert));
 }
 
 static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture)
@@ -151,6 +155,7 @@ static int test_validate_msg_mac_alg_protection(void)
     };
 
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = NULL;
 
     fixture->expected = 1;
     if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_1,
@@ -172,6 +177,7 @@ static int test_validate_msg_mac_alg_protection_bad(void)
     };
 
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = NULL;
     fixture->expected = 0;
 
     if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_bad,
@@ -201,6 +207,7 @@ static int test_validate_msg_signature_partial_chain(int expired)
     X509_STORE *ts;
 
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = srvcert;
 
     ts = OSSL_CMP_CTX_get0_trusted(fixture->cmp_ctx);
     fixture->expected = !expired;
@@ -247,6 +254,7 @@ static int test_validate_msg_signature_srvcert_wrong(void)
 static int test_validate_msg_signature_srvcert(int bad_sig)
 {
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = srvcert;
     fixture->expected = !bad_sig;
     if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f, libctx))
         || !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, srvcert))
@@ -273,6 +281,7 @@ static int test_validate_msg_signature_sender_cert_srvcert(void)
 static int test_validate_msg_signature_sender_cert_untrusted(void)
 {
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = insta_cert;
     fixture->expected = 1;
     if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_0_extracerts, libctx))
             || !add_trusted(fixture->cmp_ctx, instaca_cert)
@@ -287,6 +296,7 @@ static int test_validate_msg_signature_sender_cert_untrusted(void)
 static int test_validate_msg_signature_sender_cert_trusted(void)
 {
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = insta_cert;
     fixture->expected = 1;
     if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_0_extracerts, libctx))
             || !add_trusted(fixture->cmp_ctx, instaca_cert)
@@ -307,6 +317,7 @@ static int test_validate_msg_signature_sender_cert_extracert(void)
         tear_down(fixture);
         fixture = NULL;
     }
+    fixture->cert = sk_X509_value(fixture->msg->extraCerts, 1); /* Insta CA */
     EXECUTE_TEST(execute_validate_msg_test, tear_down);
     return result;
 }
@@ -329,6 +340,7 @@ static int test_validate_msg_signature_sender_cert_absent(void)
 static int test_validate_with_sender(const X509_NAME *name, int expected)
 {
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+    fixture->cert = srvcert;
     fixture->expected = expected;
     if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f, libctx))
         || !TEST_true(OSSL_CMP_CTX_set1_expected_sender(fixture->cmp_ctx, name))
index bbd5e2b229677a8c9336266190b9681c55d26750..e9338aabab2d5af39254641fb0dd752a4a74a407 100644 (file)
@@ -5438,6 +5438,7 @@ BN_signed_bn2native                     ? 3_1_0   EXIST::FUNCTION:
 ASYNC_set_mem_functions                 ?      3_1_0   EXIST::FUNCTION:
 ASYNC_get_mem_functions                 ?      3_1_0   EXIST::FUNCTION:
 BIO_ADDR_dup                            ?      3_1_0   EXIST::FUNCTION:SOCK
+OSSL_CMP_CTX_get0_validatedSrvCert      ?      3_1_0   EXIST::FUNCTION:CMP
 CMS_final_digest                        ?      3_1_0   EXIST::FUNCTION:CMS
 CMS_EnvelopedData_it                    ?      3_1_0   EXIST::FUNCTION:CMS
 CMS_EnvelopedData_decrypt               ?      3_1_0   EXIST::FUNCTION:CMS