From: Dr. David von Oheimb Date: Thu, 3 Apr 2025 06:53:58 +0000 (+0200) Subject: CMP: Optionally accept missing or non-matching transactionID or recipNonce values X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cb005ceaaf1fb50722e0101762a3e266338c5bf9;p=thirdparty%2Fopenssl.git CMP: Optionally accept missing or non-matching transactionID or recipNonce values This is done for error messages received if OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES is set or the respective -nonmatched_error_nonces CLI option is given. Can be helpful when the server (or other peer) cannot provide a proper error message header, for instance if was unable to parse the ASN.1 encoding of a request message. Reviewed-by: Eugene Syromiatnikov Reviewed-by: Tomas Mraz MergeDate: Thu Jun 11 14:56:49 2026 (Merged from https://github.com/openssl/openssl/pull/29043) --- diff --git a/CHANGES.md b/CHANGES.md index 4e33d004731..1bfdba4035e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -155,6 +155,13 @@ OpenSSL Releases *Daniel Kubec* + * Added `OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES` option for `OSSL_CMP_CTX` and + a corresponding `-nonmatched_error_nonces` option for the `openssl cmp` command. + + This work was sponsored by Siemens AG. + + *David von Oheimb* + * Added support for RFC 8701 GREASE (Generate Random Extensions And Sustain Extensibility). When `SSL_OP_GREASE` is set, the TLS client injects reserved GREASE values into cipher suites, supported versions, supported diff --git a/apps/cmp.c b/apps/cmp.c index 8739e860d3b..a5d5f0d9e62 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -87,6 +87,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 int opt_nonmatched_error_nonces = 0; static int opt_ta_in_ip_extracerts = 0; static int opt_no_cache_extracerts = 0; static char *opt_srvcertout = NULL; @@ -282,6 +283,7 @@ typedef enum OPTION_choice { OPT_EXPECT_SENDER, OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, + OPT_NONMATCHED_ERROR_NONCES, OPT_TA_IN_IP_EXTRACERTS, OPT_NO_CACHE_EXTRACERTS, OPT_SRVCERTOUT, @@ -511,6 +513,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 9810" }, + { "nonmatched_error_nonces", OPT_NONMATCHED_ERROR_NONCES, '-', + "Accept missing or non-matching transactionID or recipNonce in error messages" }, { "ta_in_ip_extracerts", OPT_TA_IN_IP_EXTRACERTS, '-', "Permit using self-issued certificates from the extraCerts in an IP message" }, { OPT_MORE_STR, 0, 0, @@ -735,6 +739,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 }, + { (char **)&opt_nonmatched_error_nonces }, { (char **)&opt_ta_in_ip_extracerts }, { (char **)&opt_no_cache_extracerts }, { &opt_srvcertout }, { &opt_extracertsout }, { &opt_cacertsout }, @@ -1417,6 +1422,8 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) if (opt_unprotected_errors) (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1); + if (opt_nonmatched_error_nonces) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES, 1); if (opt_ta_in_ip_extracerts) { (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR, 1); CMP_warn("permitting non-authenticated trust anchors in IP extracerts according to 3GPP TS 33.310"); @@ -2989,6 +2996,9 @@ static int get_opts(int argc, char **argv) case OPT_UNPROTECTED_ERRORS: opt_unprotected_errors = 1; break; + case OPT_NONMATCHED_ERROR_NONCES: + opt_nonmatched_error_nonces = 1; + break; case OPT_TA_IN_IP_EXTRACERTS: opt_ta_in_ip_extracerts = 1; break; diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index f2717de83fd..da8277f5fea 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -925,6 +925,9 @@ DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, transactionID) case OSSL_CMP_OPT_UNPROTECTED_ERRORS: ctx->unprotectedErrors = val; break; + case OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES: + ctx->nonmatchedErrorNonces = val; + break; case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS: ctx->noCacheExtraCerts = val; break; @@ -1013,6 +1016,8 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) return ctx->unprotectedSend; case OSSL_CMP_OPT_UNPROTECTED_ERRORS: return ctx->unprotectedErrors; + case OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES: + return ctx->nonmatchedErrorNonces; case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS: return ctx->noCacheExtraCerts; case OSSL_CMP_OPT_VALIDITY_DAYS: diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index b96acf77ce6..e664a6ae221 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -55,6 +55,7 @@ struct ossl_cmp_ctx_st { * certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf */ int unprotectedErrors; + int nonmatchedErrorNonces; /* accept missing/wrong transactionID or recipNonce in error msgs */ int noCacheExtraCerts; X509 *srvCert; /* certificate used to identify the server */ X509 *validatedSrvCert; /* caches any already validated sender cert */ diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index 588649c8000..48014295e33 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -676,24 +676,35 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) return 0; } -static int check_transactionID_or_nonce(ASN1_OCTET_STRING *expected, - ASN1_OCTET_STRING *actual, int reason) +static int check_transactionID_or_nonce(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *expected, + const ASN1_OCTET_STRING *actual, int bodytype, int reason) { if (expected != NULL && (actual == NULL || ASN1_OCTET_STRING_cmp(expected, actual) != 0)) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - char *expected_str, *actual_str; + char *expected_str, *actual_str, *expected_msg, *actual_msg; + const int strict = bodytype != OSSL_CMP_PKIBODY_ERROR || !ctx->nonmatchedErrorNonces; + int res = 0; + if (reason == 0) /* at end of polling, overall check is not yet complete */ + return res; expected_str = i2s_ASN1_OCTET_STRING(NULL, expected); + expected_msg = expected_str == NULL ? "?" : expected_str; actual_str = actual == NULL ? NULL : i2s_ASN1_OCTET_STRING(NULL, actual); - ERR_raise_data(ERR_LIB_CMP, reason, - "expected = %s, actual = %s", - expected_str == NULL ? "?" : expected_str, - actual == NULL ? "(none)" : actual_str == NULL ? "?" - : actual_str); + actual_msg = actual == NULL ? "(none)" : actual_str == NULL ? "?" + : actual_str; + if (strict) { + ERR_raise_data(ERR_LIB_CMP, reason, "expected = %s, actual = %s", + expected_msg, actual_msg); + } else { + ossl_cmp_log3(WARN, ctx, "ignoring missing or non-matching %s of error message, expected = %s, actual = %s", + reason == CMP_R_TRANSACTIONID_UNMATCHED ? "transactionID" : "recipNonce", + expected_msg, actual_msg); + res = 1; + } OPENSSL_free(expected_str); OPENSSL_free(actual_str); - return 0; + return res; #endif } return 1; @@ -724,11 +735,13 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, { OSSL_CMP_PKIHEADER *hdr; const X509_NAME *expected_sender; + int bodytype, end_of_polling; int num_untrusted, num_added, res; if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL)) return 0; hdr = OSSL_CMP_MSG_get0_header(msg); + bodytype = OSSL_CMP_MSG_get_bodytype(msg); /* If expected_sender is given, validate sender name of received msg */ expected_sender = ctx->expected_sender; @@ -762,6 +775,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, return 0; } } + + /* Ignoring recipient */ /* Note: if recipient was NULL-DN it could be learned here if needed */ num_added = sk_X509_num(msg->extraCerts); @@ -823,7 +838,7 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, #endif } - if (OSSL_CMP_MSG_get_bodytype(msg) < 0) { + if (bodytype < 0) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ERR_raise(ERR_LIB_CMP, CMP_R_PKIBODY_ERROR); return 0; @@ -831,30 +846,25 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, } /* compare received transactionID with the expected one in previous msg */ - if (!check_transactionID_or_nonce(ctx->transactionID, hdr->transactionID, - CMP_R_TRANSACTIONID_UNMATCHED)) + if (!check_transactionID_or_nonce(ctx, ctx->transactionID, hdr->transactionID, + bodytype, CMP_R_TRANSACTIONID_UNMATCHED)) return 0; /* - * enable clearing irrelevant errors - * in attempts to validate recipient nonce in case of delayed delivery. + * Compare received nonce with the one we sent last. + * When we received the final response at the end of polling, + * we allow also the nonce that we sent earlier with the original request, + * as specified in RFC 9483 section 5.1.5. */ - (void)ERR_set_mark(); - /* compare received nonce with the one we sent */ - if (!check_transactionID_or_nonce(ctx->senderNonce, hdr->recipNonce, - CMP_R_RECIPNONCE_UNMATCHED)) { - /* check if we are polling and received final response */ - if (ctx->first_senderNonce == NULL - || OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_POLLREP - /* compare received nonce with our sender nonce at poll start */ - || !check_transactionID_or_nonce(ctx->first_senderNonce, - hdr->recipNonce, - CMP_R_RECIPNONCE_UNMATCHED)) { - (void)ERR_clear_last_mark(); + end_of_polling = ctx->first_senderNonce != NULL && bodytype != OSSL_CMP_PKIBODY_POLLREP; + if (!check_transactionID_or_nonce(ctx, ctx->senderNonce, hdr->recipNonce, + bodytype, end_of_polling ? 0 : CMP_R_RECIPNONCE_UNMATCHED)) { + if (!end_of_polling + /* otherwise, compare received nonce with our sender nonce at poll start: */ + || !check_transactionID_or_nonce(ctx, ctx->first_senderNonce, hdr->recipNonce, + bodytype, CMP_R_RECIPNONCE_UNMATCHED)) return 0; - } } - (void)ERR_pop_to_mark(); /* if not yet present, learn transactionID */ if (ctx->transactionID == NULL @@ -876,7 +886,7 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, * the caPubs field may be directly trusted as a root CA * certificate by the initiator.' */ - switch (OSSL_CMP_MSG_get_bodytype(msg)) { + switch (bodytype) { case OSSL_CMP_PKIBODY_IP: case OSSL_CMP_PKIBODY_CP: case OSSL_CMP_PKIBODY_KUP: diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in index c3939292643..797414ea943 100644 --- a/doc/man1/openssl-cmp.pod.in +++ b/doc/man1/openssl-cmp.pod.in @@ -70,6 +70,7 @@ Server authentication options: [B<-expect_sender> I] [B<-ignore_keyusage>] [B<-unprotected_errors>] +[B<-nonmatched_error_nonces>] [B<-ta_in_ip_extracerts>] [B<-no_cache_extracerts>] [B<-srvcertout> I] @@ -722,6 +723,12 @@ with a signature key." =back +=item B<-nonmatched_error_nonces> + +Accept missing or non-matching transactionID or recipNonce values in error messages. +This can be helpful in case the server cannot provide a proper error message, +for instance if it was unable to parse the ASN.1 encoding of a request message. + =item B<-ta_in_ip_extracerts> This is a quirk option added to support 3GPP TS 33.310. @@ -1545,6 +1552,8 @@ The B<-ta_in_ip_extracerts> quirk option was added in OpenSSL 4.0. The B<-engine> option was removed in OpenSSL 4.0. +The B<-nonmatched_error_nonces> option was added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod index 146bdbd0649..ce8a0b7fc9d 100644 --- a/doc/man3/OSSL_CMP_CTX_new.pod +++ b/doc/man3/OSSL_CMP_CTX_new.pod @@ -335,6 +335,12 @@ B This setting leads to unspecified behavior and it is meant exclusively to allow interoperability with server implementations violating RFC 9810. +=item B + +Accept missing or non-matching transactionID or recipNonce in error messages. +This can be helpful in case the server cannot provide a proper error message, +for instance if it was unable to parse the ASN.1 encoding of a request message. + =item B Ignore key usage restrictions in the signer's certificate when @@ -894,8 +900,11 @@ OSSL_CMP_CTX_get0_geninfo_ITAVs() were added in OpenSSL 3.3. Support for central key generation, requested via B, was added in OpenSSL 3.5. + The B option was added in OpenSSL 4.0. +The B option was added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index 639197eef38..6ae08e1872b 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -376,6 +376,7 @@ const char *OSSL_CMP_CTX_get0_propq(const OSSL_CMP_CTX *ctx); #define OSSL_CMP_OPT_IGNORE_KEYUSAGE 35 #define OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR 36 #define OSSL_CMP_OPT_NO_CACHE_EXTRACERTS 37 +#define OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES 38 int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val); int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt); /* CMP-specific callback for logging and outputting the error queue: */ diff --git a/test/cmp_vfy_test.c b/test/cmp_vfy_test.c index 70d776c0f57..ec7131a8613 100644 --- a/test/cmp_vfy_test.c +++ b/test/cmp_vfy_test.c @@ -22,6 +22,7 @@ static const char *ir_protected_f; static const char *ir_unprotected_f; static const char *ir_rmprotection_f; static const char *ip_waiting_f; +static const char *error_protected_f; static const char *instacert_f; static const char *instaca_f; static const char *ir_protected_0_extracerts; @@ -81,7 +82,7 @@ static X509 *endentity1 = NULL, *endentity2 = NULL, static X509 *insta_cert = NULL, *instaca_cert = NULL; static unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH]; -static OSSL_CMP_MSG *ir_unprotected, *ir_rmprotection; +static OSSL_CMP_MSG *ir_unprotected, *ir_rmprotection, *error_protected; /* secret value used for IP_waitingStatus_PBM.der */ static const unsigned char sec_1[] = { @@ -452,9 +453,9 @@ static int execute_msg_check_test(CMP_VFY_TEST_FIXTURE *fixture) if (fixture->expected == 0) /* error expected already during above check */ return 1; - return TEST_int_eq(0, - ASN1_OCTET_STRING_cmp(ossl_cmp_hdr_get0_senderNonce(hdr), - fixture->cmp_ctx->recipNonce)) + if (OSSL_CMP_CTX_get_option(fixture->cmp_ctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES)) + return 1; + return TEST_int_eq(0, ASN1_OCTET_STRING_cmp(ossl_cmp_hdr_get0_senderNonce(hdr), fixture->cmp_ctx->recipNonce)) && TEST_int_eq(0, ASN1_OCTET_STRING_cmp(tid, fixture->cmp_ctx->transactionID)); @@ -468,6 +469,7 @@ static int allow_unprotected(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, static void setup_check_update(CMP_VFY_TEST_FIXTURE **fixture, int expected, ossl_cmp_allow_unprotected_cb_t cb, int arg, + const OSSL_CMP_MSG *msg, const unsigned char *trid_data, const unsigned char *nonce_data) { @@ -477,7 +479,7 @@ static void setup_check_update(CMP_VFY_TEST_FIXTURE **fixture, int expected, (*fixture)->expected = expected; (*fixture)->allow_unprotected_cb = cb; (*fixture)->additional_arg = arg; - (*fixture)->msg = OSSL_CMP_MSG_dup(ir_rmprotection); + (*fixture)->msg = OSSL_CMP_MSG_dup(msg); if ((*fixture)->msg == NULL || (nonce_data != NULL && !ossl_cmp_asn1_octet_string_set1_bytes(&ctx->senderNonce, @@ -502,7 +504,7 @@ static void setup_check_update(CMP_VFY_TEST_FIXTURE **fixture, int expected, static int test_msg_check_no_protection_no_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 0, NULL, 0, NULL, NULL); + setup_check_update(&fixture, 0, NULL, 0, ir_rmprotection, NULL, NULL); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } @@ -510,7 +512,7 @@ static int test_msg_check_no_protection_no_cb(void) static int test_msg_check_no_protection_restrictive_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 0, allow_unprotected, 0, NULL, NULL); + setup_check_update(&fixture, 0, allow_unprotected, 0, ir_rmprotection, NULL, NULL); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } @@ -519,7 +521,7 @@ static int test_msg_check_no_protection_restrictive_cb(void) static int test_msg_check_no_protection_permissive_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 1, allow_unprotected, 1, NULL, NULL); + setup_check_update(&fixture, 1, allow_unprotected, 1, ir_rmprotection, NULL, NULL); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } @@ -533,7 +535,7 @@ static int test_msg_check_transaction_id(void) }; SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 1, allow_unprotected, 1, trans_id, NULL); + setup_check_update(&fixture, 1, allow_unprotected, 1, ir_rmprotection, trans_id, NULL); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } @@ -542,12 +544,22 @@ static int test_msg_check_transaction_id(void) static int test_msg_check_transaction_id_bad(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 0, allow_unprotected, 1, rand_data, NULL); + setup_check_update(&fixture, 0, allow_unprotected, 1, ir_rmprotection, rand_data, NULL); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #endif +static int test_msg_check_transaction_id_error(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + + (void)OSSL_CMP_CTX_set_option(fixture->cmp_ctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES, 1); + setup_check_update(&fixture, 1, allow_unprotected, 1, error_protected, rand_data, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); + return result; +} + static int test_msg_check_recipient_nonce(void) { /* Recipient nonce belonging to CMP_IP_ir_rmprotection.der */ @@ -557,7 +569,7 @@ static int test_msg_check_recipient_nonce(void) }; SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 1, allow_unprotected, 1, NULL, rec_nonce); + setup_check_update(&fixture, 1, allow_unprotected, 1, ir_rmprotection, NULL, rec_nonce); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } @@ -566,12 +578,23 @@ static int test_msg_check_recipient_nonce(void) static int test_msg_check_recipient_nonce_bad(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_update(&fixture, 0, allow_unprotected, 1, NULL, rand_data); + setup_check_update(&fixture, 0, allow_unprotected, 1, ir_rmprotection, NULL, rand_data); EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #endif +/* Transaction id belonging to error_protected.der not needed here: */ +/* 0x5D, 0x90, 0x14, 0xB4, 0xBA, 0xAD, 0x6F, 0xCC, 0x36, 0x7B, 0xB8, 0x09, 0xB6, 0x98, 0xBF, 0x21 */ +static int test_msg_check_recipient_nonce_error(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + (void)OSSL_CMP_CTX_set_option(fixture->cmp_ctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES, 1); + setup_check_update(&fixture, 1, allow_unprotected, 1, error_protected, NULL, rand_data); + EXECUTE_TEST(execute_msg_check_test, tear_down); + return result; +} + void cleanup_tests(void) { X509_free(srvcert); @@ -584,6 +607,7 @@ void cleanup_tests(void) X509_free(instaca_cert); OSSL_CMP_MSG_free(ir_unprotected); OSSL_CMP_MSG_free(ir_rmprotection); + OSSL_CMP_MSG_free(error_protected); OSSL_PROVIDER_unload(default_null_provider); OSSL_PROVIDER_unload(provider); OSSL_LIB_CTX_free(libctx); @@ -595,6 +619,7 @@ void cleanup_tests(void) "Root_CA.crt Intermediate_CA.crt " \ "CMP_IR_protected.der CMP_IR_unprotected.der " \ "IP_waitingStatus_PBM.der IR_rmprotection.der " \ + "error_protected.der " \ "insta.cert.pem insta_ca.cert.pem " \ "IR_protected_0_extraCerts.der " \ "IR_protected_2_extraCerts.der module_name [module_conf_file]\n" @@ -628,15 +653,16 @@ int setup_tests(void) || !TEST_ptr(ir_unprotected_f = test_get_argument(7)) || !TEST_ptr(ip_waiting_f = test_get_argument(8)) || !TEST_ptr(ir_rmprotection_f = test_get_argument(9)) - || !TEST_ptr(instacert_f = test_get_argument(10)) - || !TEST_ptr(instaca_f = test_get_argument(11)) - || !TEST_ptr(ir_protected_0_extracerts = test_get_argument(12)) - || !TEST_ptr(ir_protected_2_extracerts = test_get_argument(13))) { + || !TEST_ptr(error_protected_f = test_get_argument(10)) + || !TEST_ptr(instacert_f = test_get_argument(11)) + || !TEST_ptr(instaca_f = test_get_argument(12)) + || !TEST_ptr(ir_protected_0_extracerts = test_get_argument(13)) + || !TEST_ptr(ir_protected_2_extracerts = test_get_argument(14))) { TEST_error("usage: cmp_vfy_test %s", USAGE); return 0; } - if (!test_arg_libctx(&libctx, &default_null_provider, &provider, 14, USAGE)) + if (!test_arg_libctx(&libctx, &default_null_provider, &provider, 15, USAGE)) return 0; /* Load certificates for cert chain */ @@ -657,8 +683,8 @@ int setup_tests(void) if (!TEST_int_eq(1, RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH))) goto err; if (!TEST_ptr(ir_unprotected = load_pkimsg(ir_unprotected_f, libctx)) - || !TEST_ptr(ir_rmprotection = load_pkimsg(ir_rmprotection_f, - libctx))) + || !TEST_ptr(ir_rmprotection = load_pkimsg(ir_rmprotection_f, libctx)) + || !TEST_ptr(error_protected = load_pkimsg(error_protected_f, libctx))) goto err; /* Message validation tests */ @@ -708,10 +734,12 @@ int setup_tests(void) #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_msg_check_transaction_id_bad); #endif + ADD_TEST(test_msg_check_transaction_id_error); ADD_TEST(test_msg_check_recipient_nonce); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_msg_check_recipient_nonce_bad); #endif + ADD_TEST(test_msg_check_recipient_nonce_error); return 1; diff --git a/test/recipes/65-test_cmp_vfy.t b/test/recipes/65-test_cmp_vfy.t index f722800e276..7cfeb4cc05c 100644 --- a/test/recipes/65-test_cmp_vfy.t +++ b/test/recipes/65-test_cmp_vfy.t @@ -37,6 +37,7 @@ my @basic_cmd = ("cmp_vfy_test", data_file("IR_unprotected.der"), data_file("IP_waitingStatus_PBM.der"), data_file("IR_rmprotection.der"), + data_file("error_protected.der"), data_file("insta.cert.pem"), data_file("insta_ca.cert.pem"), data_file("IR_protected_0_extraCerts.der"), diff --git a/test/recipes/65-test_cmp_vfy_data/error_protected.der b/test/recipes/65-test_cmp_vfy_data/error_protected.der new file mode 100644 index 00000000000..26af9f03fff Binary files /dev/null and b/test/recipes/65-test_cmp_vfy_data/error_protected.der differ