xref: /freebsd/crypto/openssl/test/cmp_client_test.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
1 /*
2  * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright Nokia 2007-2019
4  * Copyright Siemens AG 2015-2019
5  *
6  * Licensed under the Apache License 2.0 (the "License").  You may not use
7  * this file except in compliance with the License.  You can obtain a copy
8  * in the file LICENSE in the source distribution or at
9  * https://www.openssl.org/source/license.html
10  */
11 
12 #include "helpers/cmp_testlib.h"
13 #include "../crypto/crmf/crmf_local.h" /* for manipulating the CertId issuer */
14 
15 #include "cmp_mock_srv.h"
16 
17 static const char *server_key_f;
18 static const char *server_cert_f;
19 static const char *client_key_f;
20 static const char *client_cert_f;
21 static const char *pkcs10_f;
22 
23 typedef struct test_fixture {
24     const char *test_case_name;
25     OSSL_CMP_CTX *cmp_ctx;
26     OSSL_CMP_SRV_CTX *srv_ctx;
27     int req_type;
28     int expected;
29     STACK_OF(X509) *caPubs;
30 } CMP_SES_TEST_FIXTURE;
31 
32 static OSSL_LIB_CTX *libctx = NULL;
33 static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
34 
35 static EVP_PKEY *server_key = NULL;
36 static X509 *server_cert = NULL;
37 static EVP_PKEY *client_key = NULL;
38 static X509 *client_cert = NULL;
39 static unsigned char ref[CMP_TEST_REFVALUE_LENGTH]; /* not actually used */
40 
41 /*
42  * For these unit tests, the client abandons message protection, and for
43  * error messages the mock server does so as well.
44  * Message protection and verification is tested in cmp_lib_test.c
45  */
46 
47 static void tear_down(CMP_SES_TEST_FIXTURE *fixture)
48 {
49     OSSL_CMP_CTX_free(fixture->cmp_ctx);
50     ossl_cmp_mock_srv_free(fixture->srv_ctx);
51     sk_X509_free(fixture->caPubs);
52     OPENSSL_free(fixture);
53 }
54 
55 static int set_simple_trust(OSSL_CMP_CTX *ctx, X509 *trusted)
56 {
57     X509_STORE *ts = X509_STORE_new();
58     X509_VERIFY_PARAM *vpm;
59 
60     /*
61      * not simply using OSSL_CMP_CTX_set1_srvCert() (to pin the server cert)
62      * in order to make sure that validated server cert gets cached,
63      * which is needed for the negative test case test_exec_KUR_bad_pkiConf_protection
64      */
65     if (ts == NULL || !X509_STORE_add_cert(ts, trusted))
66         goto err;
67 
68     vpm = X509_STORE_get0_param(ts);
69     if (!X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME | X509_V_FLAG_PARTIAL_CHAIN)
70         || !OSSL_CMP_CTX_set0_trusted(ctx, ts))
71         goto err;
72 
73     return 1;
74 err:
75     X509_STORE_free(ts);
76     return 0;
77 }
78 
79 static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name)
80 {
81     CMP_SES_TEST_FIXTURE *fixture;
82     OSSL_CMP_CTX *srv_cmp_ctx = NULL;
83     OSSL_CMP_CTX *ctx = NULL; /* for client */
84 
85     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
86         return NULL;
87     fixture->test_case_name = test_case_name;
88     if (!TEST_ptr(fixture->srv_ctx = ossl_cmp_mock_srv_new(libctx, NULL))
89         || !OSSL_CMP_SRV_CTX_set_accept_unprotected(fixture->srv_ctx, 1)
90         || !ossl_cmp_mock_srv_set1_refCert(fixture->srv_ctx, client_cert)
91         || !ossl_cmp_mock_srv_set1_certOut(fixture->srv_ctx, client_cert)
92         || (srv_cmp_ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(fixture->srv_ctx)) == NULL
93         || !OSSL_CMP_CTX_set1_cert(srv_cmp_ctx, server_cert)
94         || !OSSL_CMP_CTX_set1_pkey(srv_cmp_ctx, server_key))
95         goto err;
96     if (!TEST_ptr(fixture->cmp_ctx = ctx = OSSL_CMP_CTX_new(libctx, NULL))
97         || !OSSL_CMP_CTX_set_log_cb(fixture->cmp_ctx, print_to_bio_out)
98         /* using default verbosity: OSSL_CMP_LOG_INFO */
99         || !OSSL_CMP_CTX_set_transfer_cb(ctx, ossl_cmp_mock_server_perform)
100         || !OSSL_CMP_CTX_set_transfer_cb_arg(ctx, fixture->srv_ctx)
101         || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1)
102         || !OSSL_CMP_CTX_set1_oldCert(ctx, client_cert)
103         || !OSSL_CMP_CTX_set1_pkey(ctx, client_key)
104         /* client_key is by default used also for newPkey */
105         || !set_simple_trust(ctx, server_cert)
106         || !OSSL_CMP_CTX_set1_referenceValue(ctx, ref, sizeof(ref))) /* not actually needed */
107         goto err;
108     fixture->req_type = -1;
109     return fixture;
110 
111 err:
112     tear_down(fixture);
113     return NULL;
114 }
115 
116 static int execute_exec_RR_ses_test(CMP_SES_TEST_FIXTURE *fixt)
117 {
118     return TEST_int_eq(OSSL_CMP_CTX_get_status(fixt->cmp_ctx),
119                OSSL_CMP_PKISTATUS_unspecified)
120         && TEST_int_eq(OSSL_CMP_exec_RR_ses(fixt->cmp_ctx),
121             fixt->expected == OSSL_CMP_PKISTATUS_accepted)
122         && TEST_int_eq(OSSL_CMP_CTX_get_status(fixt->cmp_ctx), fixt->expected);
123 }
124 
125 static int execute_exec_GENM_ses_test_single(CMP_SES_TEST_FIXTURE *fixture)
126 {
127     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
128     ASN1_OBJECT *type = OBJ_txt2obj("1.3.6.1.5.5.7.4.2", 1);
129     OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_create(type, NULL);
130     STACK_OF(OSSL_CMP_ITAV) *itavs;
131     int ret;
132 
133     OSSL_CMP_CTX_push0_genm_ITAV(ctx, itav);
134     itavs = OSSL_CMP_exec_GENM_ses(ctx);
135 
136     ret = TEST_int_eq(OSSL_CMP_CTX_get_status(ctx), fixture->expected)
137         && (fixture->expected == OSSL_CMP_PKISTATUS_accepted
138                 ? TEST_ptr(itavs)
139                 : TEST_ptr_null(itavs));
140     sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
141     return ret;
142 }
143 
144 static int execute_exec_GENM_ses_test(CMP_SES_TEST_FIXTURE *fixture)
145 {
146     return execute_exec_GENM_ses_test_single(fixture)
147         && OSSL_CMP_CTX_reinit(fixture->cmp_ctx)
148         && execute_exec_GENM_ses_test_single(fixture);
149 }
150 
151 static int execute_exec_certrequest_ses_test(CMP_SES_TEST_FIXTURE *fixture)
152 {
153     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
154     X509 *res = OSSL_CMP_exec_certreq(ctx, fixture->req_type, NULL);
155     int status = OSSL_CMP_CTX_get_status(ctx);
156 
157     OSSL_CMP_CTX_print_errors(ctx);
158     if (!TEST_int_eq(status, fixture->expected))
159         return 0;
160     if (fixture->expected != OSSL_CMP_PKISTATUS_accepted)
161         return TEST_ptr_null(res);
162 
163     if (!TEST_ptr(res) || !TEST_int_eq(X509_cmp(res, client_cert), 0))
164         return 0;
165     if (fixture->caPubs != NULL) {
166         STACK_OF(X509) *caPubs = OSSL_CMP_CTX_get1_caPubs(fixture->cmp_ctx);
167         int ret = TEST_int_eq(STACK_OF_X509_cmp(fixture->caPubs, caPubs), 0);
168 
169         OSSL_STACK_OF_X509_free(caPubs);
170         return ret;
171     }
172     return 1;
173 }
174 
175 static int test_exec_RR_ses(int request_error)
176 {
177     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
178     if (request_error)
179         OSSL_CMP_CTX_set1_oldCert(fixture->cmp_ctx, NULL);
180     fixture->expected = request_error ? OSSL_CMP_PKISTATUS_request
181                                       : OSSL_CMP_PKISTATUS_accepted;
182     EXECUTE_TEST(execute_exec_RR_ses_test, tear_down);
183     return result;
184 }
185 
186 static int test_exec_RR_ses_ok(void)
187 {
188     return test_exec_RR_ses(0);
189 }
190 
191 static int test_exec_RR_ses_request_error(void)
192 {
193     return test_exec_RR_ses(1);
194 }
195 
196 static int test_exec_RR_ses_receive_error(void)
197 {
198     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
199     ossl_cmp_mock_srv_set_statusInfo(fixture->srv_ctx,
200         OSSL_CMP_PKISTATUS_rejection,
201         OSSL_CMP_CTX_FAILINFO_signerNotTrusted,
202         "test string");
203     ossl_cmp_mock_srv_set_sendError(fixture->srv_ctx, OSSL_CMP_PKIBODY_RR);
204     fixture->expected = OSSL_CMP_PKISTATUS_rejection;
205     EXECUTE_TEST(execute_exec_RR_ses_test, tear_down);
206     return result;
207 }
208 
209 /*
210  * Create a CertId the issuer of which is not a directoryName, such that
211  * OSSL_CRMF_CERTID_get0_issuer() yields NULL for it, while
212  * OSSL_CRMF_CERTID_get0_serialNumber() yields the serial number as usual.
213  */
214 static OSSL_CRMF_CERTID *certid_new_non_dirName_issuer(void)
215 {
216     OSSL_CRMF_CERTID *cid = OSSL_CRMF_CERTID_new();
217     ASN1_IA5STRING *dns = ASN1_IA5STRING_new();
218 
219     if (cid == NULL || dns == NULL)
220         goto err;
221     if (!ASN1_STRING_set(dns, "server.example", -1))
222         goto err;
223     GENERAL_NAME_set0_value(cid->issuer, GEN_DNS, dns);
224     dns = NULL; /* ownership transferred to cid->issuer */
225     if (!ASN1_INTEGER_set(cid->serialNumber, 1))
226         goto err;
227     return cid;
228 
229 err:
230     ASN1_IA5STRING_free(dns);
231     OSSL_CRMF_CERTID_free(cid);
232     return NULL;
233 }
234 
235 /*
236  * Transfer callback wrapping the mock server: add a CertId to the revCerts
237  * field of the RP, which the server side omits for an RR request derived from
238  * a PKCS#10 CSR because such a request contains no issuer and serial number.
239  */
240 static OSSL_CMP_MSG *transfer_add_revCerts(OSSL_CMP_CTX *ctx,
241     const OSSL_CMP_MSG *req)
242 {
243     OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(ctx);
244     OSSL_CMP_MSG *rp = ossl_cmp_mock_server_perform(ctx, req);
245     OSSL_CRMF_CERTID *cid;
246 
247     if (rp == NULL || OSSL_CMP_MSG_get_bodytype(rp) != OSSL_CMP_PKIBODY_RP)
248         return rp;
249 
250     if ((cid = certid_new_non_dirName_issuer()) == NULL)
251         goto err;
252     if (!sk_OSSL_CRMF_CERTID_push(rp->body->value.rp->revCerts, cid)) {
253         OSSL_CRMF_CERTID_free(cid);
254         goto err;
255     }
256     /* the body has been modified after the server protected the message */
257     if (!ossl_cmp_msg_protect(OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx), rp))
258         goto err;
259     return rp;
260 
261 err:
262     OSSL_CMP_MSG_free(rp);
263     return NULL;
264 }
265 
266 /*
267  * The certificate to be revoked is given by a PKCS#10 CSR, so the RR contains
268  * neither issuer nor serial number, yet the RP contains a CertId in revCerts.
269  * The client cannot compare the CertId with what it did not send and thus
270  * must not reject the response.
271  * The CertId issuer is not a directoryName, such that the issuer comparison
272  * compares NULL with NULL and succeeds, which makes the client go on
273  * comparing the serial numbers with the one it did not send being NULL.
274  */
275 static int test_exec_RR_ses_p10CSR_revCerts(void)
276 {
277     OSSL_CMP_CTX *ctx;
278     X509_REQ *csr = NULL;
279 
280     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
281     ctx = fixture->cmp_ctx;
282     fixture->expected = OSSL_CMP_PKISTATUS_accepted;
283     if (!TEST_ptr(csr = load_csr_der(pkcs10_f, libctx))
284         /* drop the reference cert such that the CSR is used instead */
285         || !TEST_true(OSSL_CMP_CTX_set1_oldCert(ctx, NULL))
286         || !TEST_true(OSSL_CMP_CTX_set1_p10CSR(ctx, csr))
287         /* no recipient can be derived from just a CSR */
288         || !TEST_true(OSSL_CMP_CTX_set1_recipient(ctx,
289             X509_get_subject_name(server_cert)))
290         || !TEST_true(OSSL_CMP_CTX_set_transfer_cb(ctx,
291             transfer_add_revCerts))) {
292         tear_down(fixture);
293         fixture = NULL;
294     }
295     X509_REQ_free(csr);
296     EXECUTE_TEST(execute_exec_RR_ses_test, tear_down);
297     return result;
298 }
299 
300 static int test_exec_IR_ses(void)
301 {
302     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
303     fixture->req_type = OSSL_CMP_PKIBODY_IR;
304     fixture->expected = OSSL_CMP_PKISTATUS_accepted;
305     fixture->caPubs = sk_X509_new_null();
306     if (!sk_X509_push(fixture->caPubs, server_cert)
307         || !sk_X509_push(fixture->caPubs, server_cert)) {
308         tear_down(fixture);
309         return 0;
310     }
311     ossl_cmp_mock_srv_set1_caPubsOut(fixture->srv_ctx, fixture->caPubs);
312     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
313     return result;
314 }
315 
316 static int test_exec_REQ_ses_poll(int req_type, int check_after,
317     int poll_count, int total_timeout,
318     int expect)
319 {
320     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
321     fixture->req_type = req_type;
322     fixture->expected = expect;
323     ossl_cmp_mock_srv_set_checkAfterTime(fixture->srv_ctx, check_after);
324     ossl_cmp_mock_srv_set_pollCount(fixture->srv_ctx, poll_count);
325     OSSL_CMP_CTX_set_option(fixture->cmp_ctx,
326         OSSL_CMP_OPT_TOTAL_TIMEOUT, total_timeout);
327 
328     if (req_type == OSSL_CMP_PKIBODY_IR) {
329         EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
330     } else if (req_type == OSSL_CMP_PKIBODY_GENM) {
331         EXECUTE_TEST(execute_exec_GENM_ses_test, tear_down);
332     }
333     return result;
334 }
335 
336 static const int checkAfter = 1;
337 static const int pollCount = 3;
338 
339 static int test_exec_IR_ses_poll_ok(void)
340 {
341     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter, 2, 0,
342         OSSL_CMP_PKISTATUS_accepted);
343 }
344 
345 static int test_exec_IR_ses_poll_no_timeout(void)
346 {
347     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter,
348         2 /* pollCount */,
349         checkAfter + 14, /* usually 4 is sufficient */
350         OSSL_CMP_PKISTATUS_accepted);
351 }
352 
353 static int test_exec_IR_ses_poll_total_timeout(void)
354 {
355     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter,
356         pollCount, (pollCount - 1) * checkAfter,
357         OSSL_CMP_PKISTATUS_trans);
358 }
359 
360 static int test_exec_CR_ses(int implicit_confirm, int granted, int reject)
361 {
362     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
363     fixture->req_type = OSSL_CMP_PKIBODY_CR;
364     OSSL_CMP_CTX_set_option(fixture->cmp_ctx,
365         OSSL_CMP_OPT_IMPLICIT_CONFIRM, implicit_confirm);
366     OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(fixture->srv_ctx, granted);
367     ossl_cmp_mock_srv_set_sendError(fixture->srv_ctx,
368         reject ? OSSL_CMP_PKIBODY_CERTCONF : -1);
369     fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejection
370                                : OSSL_CMP_PKISTATUS_accepted;
371     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
372     return result;
373 }
374 
375 static int test_exec_CR_ses_explicit_confirm(void)
376 {
377     return test_exec_CR_ses(0, 0, 0)
378         && test_exec_CR_ses(0, 0, 1 /* reject */);
379 }
380 
381 static int test_exec_CR_ses_implicit_confirm(void)
382 {
383     return test_exec_CR_ses(1, 0, 0)
384         && test_exec_CR_ses(1, 1 /* granted */, 0);
385 }
386 
387 /* the KUR transactions include certConf/pkiConf */
388 static int test_exec_KUR_ses(int transfer_error, int server_use_bad_protection,
389     int pubkey, int raverified)
390 {
391     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
392     fixture->req_type = OSSL_CMP_PKIBODY_KUR;
393     /* ctx->oldCert has already been set */
394 
395     if (transfer_error)
396         OSSL_CMP_CTX_set_transfer_cb_arg(fixture->cmp_ctx, NULL);
397     (void)ossl_cmp_mock_srv_set_useBadProtection(fixture->srv_ctx, server_use_bad_protection);
398 
399     if (pubkey) {
400         EVP_PKEY *key = raverified /* wrong key */ ? server_key : client_key;
401 
402         if (!EVP_PKEY_up_ref(key))
403             return 0;
404 
405         OSSL_CMP_CTX_set0_newPkey(fixture->cmp_ctx, 0 /* not priv */, key);
406         OSSL_CMP_SRV_CTX_set_accept_raverified(fixture->srv_ctx, 1);
407     }
408     if (pubkey || raverified)
409         OSSL_CMP_CTX_set_option(fixture->cmp_ctx, OSSL_CMP_OPT_POPO_METHOD,
410             OSSL_CRMF_POPO_RAVERIFIED);
411     fixture->expected = transfer_error ? OSSL_CMP_PKISTATUS_trans : raverified ? (pubkey ? OSSL_CMP_PKISTATUS_rejected_by_client : OSSL_CMP_PKISTATUS_rejection)
412         : server_use_bad_protection != -1                                      ? OSSL_CMP_PKISTATUS_checking_response
413                                                                                : OSSL_CMP_PKISTATUS_accepted;
414     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
415     return result;
416 }
417 
418 static int test_exec_KUR_ses_ok(void)
419 {
420     return test_exec_KUR_ses(0, -1, 0, 0);
421 }
422 
423 static int test_exec_KUR_ses_transfer_error(void)
424 {
425     return test_exec_KUR_ses(1, -1, 0, 0);
426 }
427 
428 static int test_exec_KUR_bad_pkiConf_protection(void)
429 {
430     return test_exec_KUR_ses(0, -1 /* disabled: OSSL_CMP_PKIBODY_PKICONF */, 0, 0);
431 }
432 
433 static int test_exec_KUR_ses_wrong_popo(void)
434 {
435 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* cf ossl_cmp_verify_popo() */
436     return test_exec_KUR_ses(0, -1, 0, 1);
437 #else
438     return 1;
439 #endif
440 }
441 
442 static int test_exec_KUR_ses_pub(void)
443 {
444     return test_exec_KUR_ses(0, -1, 1, 0);
445 }
446 
447 static int test_exec_KUR_ses_wrong_pub(void)
448 {
449     return test_exec_KUR_ses(0, -1, 1, 1);
450 }
451 
452 static int test_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
453     const char **txt)
454 {
455     int *reject = OSSL_CMP_CTX_get_certConf_cb_arg(ctx);
456 
457     if (*reject) {
458         *txt = "not to my taste";
459         fail_info = OSSL_CMP_PKIFAILUREINFO_badCertTemplate;
460     }
461     return fail_info;
462 }
463 
464 static int test_exec_P10CR_ses(int reject)
465 {
466     OSSL_CMP_CTX *ctx;
467     X509_REQ *csr = NULL;
468 
469     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
470     fixture->req_type = OSSL_CMP_PKIBODY_P10CR;
471     fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejected_by_client
472                                : OSSL_CMP_PKISTATUS_accepted;
473     ctx = fixture->cmp_ctx;
474     if (!TEST_ptr(csr = load_csr_der(pkcs10_f, libctx))
475         || !TEST_true(OSSL_CMP_CTX_set1_p10CSR(ctx, csr))
476         || !TEST_true(OSSL_CMP_CTX_set_certConf_cb(ctx, test_certConf_cb))
477         || !TEST_true(OSSL_CMP_CTX_set_certConf_cb_arg(ctx, &reject))) {
478         tear_down(fixture);
479         fixture = NULL;
480     }
481     X509_REQ_free(csr);
482     EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
483     return result;
484 }
485 
486 static int test_exec_P10CR_ses_ok(void)
487 {
488     return test_exec_P10CR_ses(0);
489 }
490 
491 static int test_exec_P10CR_ses_reject(void)
492 {
493     return test_exec_P10CR_ses(1);
494 }
495 
496 static int execute_try_certreq_poll_test(CMP_SES_TEST_FIXTURE *fixture)
497 {
498     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
499     int check_after;
500     const int CHECK_AFTER = 0;
501     const int TYPE = OSSL_CMP_PKIBODY_KUR;
502 
503     ossl_cmp_mock_srv_set_pollCount(fixture->srv_ctx, 3);
504     ossl_cmp_mock_srv_set_checkAfterTime(fixture->srv_ctx, CHECK_AFTER);
505     return TEST_int_eq(-1, OSSL_CMP_try_certreq(ctx, TYPE, NULL, &check_after))
506         && check_after == CHECK_AFTER
507         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(ctx), NULL)
508         && TEST_int_eq(-1, OSSL_CMP_try_certreq(ctx, TYPE, NULL, &check_after))
509         && check_after == CHECK_AFTER
510         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(ctx), NULL)
511         && TEST_int_eq(fixture->expected,
512             OSSL_CMP_try_certreq(ctx, TYPE, NULL, NULL))
513         && TEST_int_eq(0,
514             X509_cmp(OSSL_CMP_CTX_get0_newCert(ctx), client_cert));
515 }
516 
517 static int test_try_certreq_poll(void)
518 {
519     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
520     fixture->expected = 1;
521     EXECUTE_TEST(execute_try_certreq_poll_test, tear_down);
522     return result;
523 }
524 
525 static int execute_try_certreq_poll_abort_test(CMP_SES_TEST_FIXTURE *fixture)
526 {
527     OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
528     int check_after;
529     const int CHECK_AFTER = 99;
530     const int TYPE = OSSL_CMP_PKIBODY_CR;
531 
532     ossl_cmp_mock_srv_set_pollCount(fixture->srv_ctx, 3);
533     ossl_cmp_mock_srv_set_checkAfterTime(fixture->srv_ctx, CHECK_AFTER);
534     return TEST_int_eq(-1, OSSL_CMP_try_certreq(ctx, TYPE, NULL, &check_after))
535         && check_after == CHECK_AFTER
536         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(ctx), NULL)
537         && TEST_int_eq(fixture->expected,
538             OSSL_CMP_try_certreq(ctx, -1 /* abort */, NULL, NULL))
539         && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(fixture->cmp_ctx), NULL);
540 }
541 
542 static int test_try_certreq_poll_abort(void)
543 {
544     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
545     fixture->expected = 1;
546     EXECUTE_TEST(execute_try_certreq_poll_abort_test, tear_down);
547     return result;
548 }
549 
550 static int test_exec_GENM_ses_poll_ok(void)
551 {
552     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter, 2, 0,
553         OSSL_CMP_PKISTATUS_accepted);
554 }
555 
556 static int test_exec_GENM_ses_poll_no_timeout(void)
557 {
558     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter,
559         1 /* pollCount */, checkAfter + 1,
560         OSSL_CMP_PKISTATUS_accepted);
561 }
562 
563 static int test_exec_GENM_ses_poll_total_timeout(void)
564 {
565     return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter,
566         pollCount, (pollCount - 1) * checkAfter,
567         OSSL_CMP_PKISTATUS_trans);
568 }
569 
570 static int test_exec_GENM_ses(int transfer_error, int total_timeout, int expect)
571 {
572     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
573     if (transfer_error)
574         OSSL_CMP_CTX_set_transfer_cb_arg(fixture->cmp_ctx, NULL);
575     /*
576      * cannot use OSSL_CMP_CTX_set_option(... OSSL_CMP_OPT_TOTAL_TIMEOUT)
577      * here because this will correct total_timeout to be >= 0
578      */
579     fixture->cmp_ctx->total_timeout = total_timeout;
580     fixture->expected = expect;
581     EXECUTE_TEST(execute_exec_GENM_ses_test, tear_down);
582     return result;
583 }
584 
585 static int test_exec_GENM_ses_ok(void)
586 {
587     return test_exec_GENM_ses(0, 0, OSSL_CMP_PKISTATUS_accepted);
588 }
589 
590 static int test_exec_GENM_ses_transfer_error(void)
591 {
592     return test_exec_GENM_ses(1, 0, OSSL_CMP_PKISTATUS_trans);
593 }
594 
595 static int test_exec_GENM_ses_total_timeout(void)
596 {
597     return test_exec_GENM_ses(0, -1, OSSL_CMP_PKISTATUS_trans);
598 }
599 
600 static int execute_exchange_certConf_test(CMP_SES_TEST_FIXTURE *fixture)
601 {
602     int res = ossl_cmp_exchange_certConf(fixture->cmp_ctx, OSSL_CMP_CERTREQID,
603         OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable,
604         "abcdefg");
605 
606     return TEST_int_eq(fixture->expected, res);
607 }
608 
609 static int execute_exchange_error_test(CMP_SES_TEST_FIXTURE *fixture)
610 {
611     int res = ossl_cmp_exchange_error(fixture->cmp_ctx,
612         OSSL_CMP_PKISTATUS_rejection,
613         1 << OSSL_CMP_PKIFAILUREINFO_unsupportedVersion,
614         "foo_status", 999, "foo_details");
615 
616     return TEST_int_eq(fixture->expected, res);
617 }
618 
619 static int test_exchange_certConf(void)
620 {
621     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
622     fixture->expected = 0; /* client should not send certConf immediately */
623     if (!ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx, X509_dup(client_cert))) {
624         tear_down(fixture);
625         fixture = NULL;
626     }
627     EXECUTE_TEST(execute_exchange_certConf_test, tear_down);
628     return result;
629 }
630 
631 static int test_exchange_error(void)
632 {
633     SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up);
634     fixture->expected = 1; /* client may send error any time */
635     EXECUTE_TEST(execute_exchange_error_test, tear_down);
636     return result;
637 }
638 
639 void cleanup_tests(void)
640 {
641     X509_free(server_cert);
642     EVP_PKEY_free(server_key);
643     X509_free(client_cert);
644     EVP_PKEY_free(client_key);
645     OSSL_PROVIDER_unload(default_null_provider);
646     OSSL_PROVIDER_unload(provider);
647     OSSL_LIB_CTX_free(libctx);
648     return;
649 }
650 
651 #define USAGE "server.key server.crt client.key client.crt client.csr module_name [module_conf_file]\n"
652 OPT_TEST_DECLARE_USAGE(USAGE)
653 
654 int setup_tests(void)
655 {
656     if (!test_skip_common_options()) {
657         TEST_error("Error parsing test options\n");
658         return 0;
659     }
660 
661     if (!TEST_ptr(server_key_f = test_get_argument(0))
662         || !TEST_ptr(server_cert_f = test_get_argument(1))
663         || !TEST_ptr(client_key_f = test_get_argument(2))
664         || !TEST_ptr(client_cert_f = test_get_argument(3))
665         || !TEST_ptr(pkcs10_f = test_get_argument(4))) {
666         TEST_error("usage: cmp_client_test %s", USAGE);
667         return 0;
668     }
669 
670     if (!test_arg_libctx(&libctx, &default_null_provider, &provider, 5, USAGE))
671         return 0;
672 
673     if (!TEST_ptr(server_key = load_pkey_pem(server_key_f, libctx))
674         || !TEST_ptr(server_cert = load_cert_pem(server_cert_f, libctx))
675         || !TEST_ptr(client_key = load_pkey_pem(client_key_f, libctx))
676         || !TEST_ptr(client_cert = load_cert_pem(client_cert_f, libctx))
677         || !TEST_int_eq(1, RAND_bytes_ex(libctx, ref, sizeof(ref), 0))) { /* not actually used */
678         cleanup_tests();
679         return 0;
680     }
681 
682     ADD_TEST(test_exec_RR_ses_ok);
683     ADD_TEST(test_exec_RR_ses_request_error);
684     ADD_TEST(test_exec_RR_ses_receive_error);
685     ADD_TEST(test_exec_RR_ses_p10CSR_revCerts);
686     ADD_TEST(test_exec_CR_ses_explicit_confirm);
687     ADD_TEST(test_exec_CR_ses_implicit_confirm);
688     ADD_TEST(test_exec_IR_ses);
689     ADD_TEST(test_exec_IR_ses_poll_ok);
690     ADD_TEST(test_exec_IR_ses_poll_no_timeout);
691     ADD_TEST(test_exec_IR_ses_poll_total_timeout);
692     ADD_TEST(test_exec_KUR_ses_ok);
693     ADD_TEST(test_exec_KUR_ses_transfer_error);
694     ADD_TEST(test_exec_KUR_bad_pkiConf_protection);
695     ADD_TEST(test_exec_KUR_ses_wrong_popo);
696     ADD_TEST(test_exec_KUR_ses_pub);
697     ADD_TEST(test_exec_KUR_ses_wrong_pub);
698     ADD_TEST(test_exec_P10CR_ses_ok);
699     ADD_TEST(test_exec_P10CR_ses_reject);
700     ADD_TEST(test_try_certreq_poll);
701     ADD_TEST(test_try_certreq_poll_abort);
702     ADD_TEST(test_exec_GENM_ses_ok);
703     ADD_TEST(test_exec_GENM_ses_transfer_error);
704     ADD_TEST(test_exec_GENM_ses_total_timeout);
705     ADD_TEST(test_exec_GENM_ses_poll_ok);
706     ADD_TEST(test_exec_GENM_ses_poll_no_timeout);
707     ADD_TEST(test_exec_GENM_ses_poll_total_timeout);
708     ADD_TEST(test_exchange_certConf);
709     ADD_TEST(test_exchange_error);
710     return 1;
711 }
712