summaryrefslogtreecommitdiffstats
path: root/crypto/cmp
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-12-14 11:29:19 +0100
committerDr. David von Oheimb <dev@ddvo.net>2022-07-20 11:40:37 +0200
commitb6fbef1159c9aeb1590c116a9426e169d2203506 (patch)
treefa6a73df8d5bd7fb5357966a96c3c34dddcbb358 /crypto/cmp
parentfad0f80eff188ef938fed614245a56ed56110deb (diff)
Add OSSL_CMP_CTX_get0_validatedSrvCert(), correcting OSSL_CMP_validate_msg()
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)
Diffstat (limited to 'crypto/cmp')
-rw-r--r--crypto/cmp/cmp_ctx.c16
-rw-r--r--crypto/cmp/cmp_local.h2
-rw-r--r--crypto/cmp/cmp_vfy.c28
3 files changed, 19 insertions, 27 deletions
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);