cmp_client_test.c: add tests for errors reported by server on subsequent requests...
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Wed, 1 Feb 2023 14:50:54 +0000 (15:50 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Tue, 18 Apr 2023 07:12:55 +0000 (09:12 +0200)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/20257)

(cherry picked from commit 154625e1090b18c8c306a6b7a6970dbab185c49d)

apps/cmp.c
apps/include/cmp_mock_srv.h
apps/lib/cmp_mock_srv.c
doc/internal/man3/ossl_cmp_mock_srv_new.pod
test/cmp_client_test.c

index c8394cbb6e03c06fd55253f455b5c11dd4507ecf..22fc137de96b1154b6290d18740a449ee40c9801 100644 (file)
@@ -1133,7 +1133,7 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
         goto err;
 
     if (opt_send_error)
-        (void)ossl_cmp_mock_srv_set_send_error(srv_ctx, 1);
+        (void)ossl_cmp_mock_srv_set_sendError(srv_ctx, 1);
 
     if (opt_send_unprotected)
         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1);
index 6beba1473590a7e6462c5412061bcf95bf9c82f8..9288181ad38f87bac4e7f685a060b0396e5bd71e 100644 (file)
@@ -27,7 +27,7 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                      STACK_OF(X509) *caPubs);
 int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
                                      int fail_info, const char *text);
-int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype);
 int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
 int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
 
index 55d380cb6dcbd8bc05564d53934a0c6a45980d0d..f6ca885162ae8a0fd401a6398d660524e45a8dd8 100644 (file)
@@ -14,7 +14,7 @@
 #include <openssl/cmp.h>
 #include <openssl/err.h>
 #include <openssl/cmperr.h>
+
 /* the context for the CMP mock server */
 typedef struct
 {
@@ -22,7 +22,7 @@ typedef struct
     STACK_OF(X509) *chainOut;  /* chain of certOut to add to extraCerts field */
     STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
     OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
-    int sendError;             /* send error response also on valid requests */
+    int sendError;             /* send error response on given request type */
     OSSL_CMP_MSG *certReq;     /* ir/cr/p10cr/kur remembered while polling */
     int pollCount;             /* number of polls before actual cert response */
     int curr_pollCount;        /* number of polls so far for current request */
@@ -53,7 +53,7 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
     if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL)
         goto err;
 
-    ctx->sendError = 0;
+    ctx->sendError = -1;
 
     /* all other elements are initialized to 0 or NULL, respectively */
     return ctx;
@@ -129,7 +129,7 @@ int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
     return 1;
 }
 
-int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype)
 {
     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
 
@@ -137,7 +137,8 @@ int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val)
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    ctx->sendError = val != 0;
+    /* might check bodytype, but this would require exporting all body types */
+    ctx->sendError = bodytype;
     return 1;
 }
 
@@ -186,7 +187,8 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return NULL;
     }
-    if (ctx->sendError) {
+    if (ctx->sendError == 1
+            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
     }
@@ -268,7 +270,8 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return NULL;
     }
-    if (ctx->sendError || ctx->certOut == NULL) {
+    if (ctx->certOut == NULL || ctx->sendError == 1
+            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
     }
@@ -299,7 +302,9 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    if (sk_OSSL_CMP_ITAV_num(in) > 1 || ctx->sendError) {
+    if (ctx->sendError == 1
+            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(genm)
+            || sk_OSSL_CMP_ITAV_num(in) > 1) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return 0;
     }
@@ -368,7 +373,9 @@ static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    if (ctx->sendError || ctx->certOut == NULL) {
+    if (ctx->sendError == 1
+            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(certConf)
+            || ctx->certOut == NULL) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return 0;
     }
@@ -396,7 +403,8 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;
     }
-    if (ctx->sendError) {
+    if (ctx->sendError == 1
+            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
         *certReq = NULL;
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return 0;
index 46df6d49468de53567e985cc8de77c9d3808f924..a0306f910e44988ef14b9de78f28fc016798dd1b 100644 (file)
@@ -8,7 +8,7 @@ ossl_cmp_mock_srv_set1_certOut,
 ossl_cmp_mock_srv_set1_chainOut,
 ossl_cmp_mock_srv_set1_caPubsOut,
 ossl_cmp_mock_srv_set_statusInfo,
-ossl_cmp_mock_srv_set_send_error,
+ossl_cmp_mock_srv_set_sendError,
 ossl_cmp_mock_srv_set_pollCount,
 ossl_cmp_mock_srv_set_checkAfterTime
 - functions used for testing with CMP mock server
@@ -27,7 +27,7 @@ ossl_cmp_mock_srv_set_checkAfterTime
                                       STACK_OF(X509) *caPubs);
  int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
                                       int fail_info, const char *text);
- int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+ int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype);
  int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
  int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
 
@@ -51,7 +51,9 @@ ossl_cmp_mock_srv_set1_caPubsOut() sets the caPubs to be returned in an ip.
 
 ossl_cmp_mock_srv_set_statusInfo() sets the status info to be returned.
 
-ossl_cmp_mock_srv_set_send_error() enables enforcement of error responses.
+ossl_cmp_mock_srv_set_sendError() enables enforcement of error responses
+for requests of the given I<bodytype>, or for all requests if I<bodytype> is 1.
+A I<bodytype> of -1 can be used to disable this feature, which is the default.
 
 ossl_cmp_mock_srv_set_pollCount() sets the number of polls before cert response.
 
index 3276a27847205687bb7846562d80de45246838be..7b3aa90fde91ba54c2e16bc0418fe872d1390353 100644 (file)
@@ -127,6 +127,7 @@ static int execute_exec_certrequest_ses_test(CMP_SES_TEST_FIXTURE *fixture)
     X509 *res = OSSL_CMP_exec_certreq(ctx, fixture->req_type, NULL);
     int status = OSSL_CMP_CTX_get_status(ctx);
 
+    OSSL_CMP_CTX_print_errors(ctx);
     if (!TEST_int_eq(status, fixture->expected)
         && !(fixture->expected == OSSL_CMP_PKISTATUS_waiting
              && TEST_int_eq(status, OSSL_CMP_PKISTATUS_trans)))
@@ -174,7 +175,7 @@ static int test_exec_RR_ses_receive_error(void)
                                      OSSL_CMP_PKISTATUS_rejection,
                                      OSSL_CMP_CTX_FAILINFO_signerNotTrusted,
                                      "test string");
-    ossl_cmp_mock_srv_set_send_error(fixture->srv_ctx, 1);
+    ossl_cmp_mock_srv_set_sendError(fixture->srv_ctx, OSSL_CMP_PKIBODY_RR);
     fixture->expected = OSSL_CMP_PKISTATUS_rejection;
     EXECUTE_TEST(execute_exec_RR_ses_test, tear_down);
     return result;
@@ -225,27 +226,31 @@ static int test_exec_IR_ses_poll_total_timeout(void)
                                  OSSL_CMP_PKISTATUS_waiting);
 }
 
-static int test_exec_CR_ses(int implicit_confirm, int granted)
+static int test_exec_CR_ses(int implicit_confirm, int granted, int reject)
 {
     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
     fixture->req_type = OSSL_CMP_CR;
-    fixture->expected = OSSL_CMP_PKISTATUS_accepted;
     OSSL_CMP_CTX_set_option(fixture->cmp_ctx,
                             OSSL_CMP_OPT_IMPLICIT_CONFIRM, implicit_confirm);
     OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(fixture->srv_ctx, granted);
+    ossl_cmp_mock_srv_set_sendError(fixture->srv_ctx,
+                                    reject ? OSSL_CMP_PKIBODY_CERTCONF : -1);
+    fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejection
+        : OSSL_CMP_PKISTATUS_accepted;
     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
     return result;
 }
 
 static int test_exec_CR_ses_explicit_confirm(void)
 {
-    return test_exec_CR_ses(0, 0);
+    return test_exec_CR_ses(0, 0, 0)
+        && test_exec_CR_ses(0, 0, 1 /* reject */);
 }
 
 static int test_exec_CR_ses_implicit_confirm(void)
 {
-    return test_exec_CR_ses(1, 0)
-        && test_exec_CR_ses(1, 1);
+    return test_exec_CR_ses(1, 0, 0)
+        && test_exec_CR_ses(1, 1 /* granted */, 0);
 }
 
 static int test_exec_KUR_ses(int transfer_error)
@@ -270,23 +275,50 @@ static int test_exec_KUR_ses_transfer_error(void)
     return test_exec_KUR_ses(1);
 }
 
-static int test_exec_P10CR_ses(void)
+static int test_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
+                            const char **txt)
+{
+    int *reject = OSSL_CMP_CTX_get_certConf_cb_arg(ctx);
+
+    if (*reject) {
+        *txt = "not to my taste";
+        fail_info = OSSL_CMP_PKIFAILUREINFO_badCertTemplate;
+    }
+    return fail_info;
+}
+
+static int test_exec_P10CR_ses(int reject)
 {
-    X509_REQ *req = NULL;
+    OSSL_CMP_CTX *ctx;
+    X509_REQ *csr = NULL;
 
     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
     fixture->req_type = OSSL_CMP_P10CR;
-    fixture->expected = OSSL_CMP_PKISTATUS_accepted;
-    if (!TEST_ptr(req = load_csr_der(pkcs10_f, libctx))
-            || !TEST_true(OSSL_CMP_CTX_set1_p10CSR(fixture->cmp_ctx, req))) {
+    fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejection
+        : OSSL_CMP_PKISTATUS_accepted;
+    ctx = fixture->cmp_ctx;
+    if (!TEST_ptr(csr = load_csr_der(pkcs10_f, libctx))
+        || !TEST_true(OSSL_CMP_CTX_set1_p10CSR(ctx, csr))
+        || !TEST_true(OSSL_CMP_CTX_set_certConf_cb(ctx, test_certConf_cb))
+        || !TEST_true(OSSL_CMP_CTX_set_certConf_cb_arg(ctx, &reject))) {
         tear_down(fixture);
         fixture = NULL;
     }
-    X509_REQ_free(req);
+    X509_REQ_free(csr);
     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
     return result;
 }
 
+static int test_exec_P10CR_ses_ok(void)
+{
+    return test_exec_P10CR_ses(0);
+}
+
+static int test_exec_P10CR_ses_reject(void)
+{
+    return test_exec_P10CR_ses(1);
+}
+
 static int execute_try_certreq_poll_test(CMP_SES_TEST_FIXTURE *fixture)
 {
     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
@@ -320,7 +352,7 @@ static int execute_try_certreq_poll_abort_test(CMP_SES_TEST_FIXTURE *fixture)
 {
     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
     int check_after;
-    const int CHECK_AFTER = INT_MAX;
+    const int CHECK_AFTER = 99;
     const int TYPE = OSSL_CMP_CR;
 
     ossl_cmp_mock_srv_set_pollCount(fixture->srv_ctx, 3);
@@ -329,7 +361,7 @@ static int execute_try_certreq_poll_abort_test(CMP_SES_TEST_FIXTURE *fixture)
         && check_after == CHECK_AFTER
         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(ctx), NULL)
         && TEST_int_eq(fixture->expected,
-                       OSSL_CMP_try_certreq(ctx, -1, NULL, NULL))
+                       OSSL_CMP_try_certreq(ctx, -1 /* abort */, NULL, NULL))
         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(fixture->cmp_ctx), NULL);
 }
 
@@ -465,7 +497,8 @@ int setup_tests(void)
     ADD_TEST(test_exec_IR_ses_poll_total_timeout);
     ADD_TEST(test_exec_KUR_ses_ok);
     ADD_TEST(test_exec_KUR_ses_transfer_error);
-    ADD_TEST(test_exec_P10CR_ses);
+    ADD_TEST(test_exec_P10CR_ses_ok);
+    ADD_TEST(test_exec_P10CR_ses_reject);
     ADD_TEST(test_try_certreq_poll);
     ADD_TEST(test_try_certreq_poll_abort);
     ADD_TEST(test_exec_GENM_ses_ok);