summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/cmp.c94
-rw-r--r--crypto/cmp/cmp_ctx.c16
-rw-r--r--crypto/cmp/cmp_local.h2
-rw-r--r--crypto/cmp/cmp_vfy.c28
-rw-r--r--doc/man1/openssl-cmp.pod.in6
-rw-r--r--doc/man3/OSSL_CMP_CTX_new.pod12
-rw-r--r--include/openssl/cmp.h.in1
-rw-r--r--test/cmp_ctx_test.c6
-rw-r--r--test/cmp_vfy_test.c18
-rw-r--r--util/libcrypto.num1
10 files changed, 127 insertions, 57 deletions
diff --git a/apps/cmp.c b/apps/cmp.c
index deb709cae0..f3624aa94a 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -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;
diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c
index 207f65430c..0fcb3c7ae5 100644
--- a/crypto/cmp/cmp_ctx.c
+++ b/crypto/cmp/cmp_ctx.c
@@ -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...
diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h
index 255eb58ba6..3718970ff8 100644
--- a/crypto/cmp/cmp_local.h
+++ b/crypto/cmp/cmp_local.h
@@ -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);
diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c
index a269ef49da..543a978c0f 100644
--- a/crypto/cmp/cmp_vfy.c
+++ b/crypto/cmp/cmp_vfy.c
@@ -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);
diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in
index 17223beea0..1fa2e99842 100644
--- a/doc/man1/openssl-cmp.pod.in
+++ b/doc/man1/openssl-cmp.pod.in
@@ -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
diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod
index 1abbfc9bfa..636bce94bf 100644
--- a/doc/man3/OSSL_CMP_CTX_new.pod
+++ b/doc/man3/OSSL_CMP_CTX_new.pod
@@ -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.
diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in
index dd4d9a633d..1d2f90fc56 100644
--- a/include/openssl/cmp.h.in
+++ b/include/openssl/cmp.h.in
@@ -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);
diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c
index 5876ae08a3..e4f80d93fc 100644
--- a/test/cmp_ctx_test.c
+++ b/test/cmp_ctx_test.c
@@ -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);
diff --git a/test/cmp_vfy_test.c b/test/cmp_vfy_test.c
index 6b5844b30a..b17f17baeb 100644
--- a/test/cmp_vfy_test.c
+++ b/test/cmp_vfy_test.c
@@ -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))
diff --git a/util/libcrypto.num b/util/libcrypto.num
index bbd5e2b229..e9338aabab 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -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