1/*
2 * Copyright 2007-2024 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
14static unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH];
15
16typedef struct test_fixture {
17    const char *test_case_name;
18    int expected;
19    OSSL_CMP_CTX *cmp_ctx;
20    OSSL_CMP_PKIHEADER *hdr;
21
22} CMP_HDR_TEST_FIXTURE;
23
24static void tear_down(CMP_HDR_TEST_FIXTURE *fixture)
25{
26    OSSL_CMP_PKIHEADER_free(fixture->hdr);
27    OSSL_CMP_CTX_free(fixture->cmp_ctx);
28    OPENSSL_free(fixture);
29}
30
31static CMP_HDR_TEST_FIXTURE *set_up(const char *const test_case_name)
32{
33    CMP_HDR_TEST_FIXTURE *fixture;
34
35    if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
36        return NULL;
37    fixture->test_case_name = test_case_name;
38    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new(NULL, NULL)))
39        goto err;
40    if (!TEST_ptr(fixture->hdr = OSSL_CMP_PKIHEADER_new()))
41        goto err;
42    return fixture;
43
44 err:
45    tear_down(fixture);
46    return NULL;
47}
48
49static int execute_HDR_set_get_pvno_test(CMP_HDR_TEST_FIXTURE *fixture)
50{
51    int pvno = 77;
52
53    if (!TEST_int_eq(ossl_cmp_hdr_set_pvno(fixture->hdr, pvno), 1))
54        return 0;
55    if (!TEST_int_eq(ossl_cmp_hdr_get_pvno(fixture->hdr), pvno))
56        return 0;
57    return 1;
58}
59
60static int test_HDR_set_get_pvno(void)
61{
62    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
63    fixture->expected = 1;
64    EXECUTE_TEST(execute_HDR_set_get_pvno_test, tear_down);
65    return result;
66}
67
68#define X509_NAME_ADD(n, rd, s) \
69    X509_NAME_add_entry_by_txt((n), (rd), MBSTRING_ASC, (unsigned char *)(s), \
70                               -1, -1, 0)
71
72static int execute_HDR_get0_senderNonce_test(CMP_HDR_TEST_FIXTURE *fixture)
73{
74    int res = 0;
75    X509_NAME *sender = X509_NAME_new();
76    ASN1_OCTET_STRING *sn;
77
78    if (!TEST_ptr(sender))
79        goto err;
80
81    X509_NAME_ADD(sender, "CN", "A common sender name");
82    if (!TEST_int_eq(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx, sender),
83                     1))
84        goto err;
85    if (!TEST_int_eq(ossl_cmp_hdr_init(fixture->cmp_ctx, fixture->hdr),
86                     1))
87        goto err;
88    sn = ossl_cmp_hdr_get0_senderNonce(fixture->hdr);
89    if (!TEST_int_eq(ASN1_OCTET_STRING_cmp(fixture->cmp_ctx->senderNonce, sn),
90                     0))
91        goto err;
92
93    res = 1;
94err:
95    X509_NAME_free(sender);
96
97    return res;
98}
99
100static int test_HDR_get0_senderNonce(void)
101{
102    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
103    fixture->expected = 1;
104    EXECUTE_TEST(execute_HDR_get0_senderNonce_test, tear_down);
105    return result;
106}
107
108static int execute_HDR_set1_sender_test(CMP_HDR_TEST_FIXTURE *fixture)
109{
110    int res = 0;
111    X509_NAME *x509name = X509_NAME_new();
112
113    if (!TEST_ptr(x509name))
114        goto err;
115
116    X509_NAME_ADD(x509name, "CN", "A common sender name");
117    if (!TEST_int_eq(ossl_cmp_hdr_set1_sender(fixture->hdr, x509name), 1))
118        goto err;
119
120    if (!TEST_int_eq(fixture->hdr->sender->type, GEN_DIRNAME))
121        goto err;
122
123    if (!TEST_int_eq(X509_NAME_cmp(fixture->hdr->sender->d.directoryName,
124                                   x509name), 0))
125        goto err;
126
127    res = 1;
128err:
129    X509_NAME_free(x509name);
130
131    return res;
132}
133
134static int test_HDR_set1_sender(void)
135{
136    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
137    fixture->expected = 1;
138    EXECUTE_TEST(execute_HDR_set1_sender_test, tear_down);
139    return result;
140}
141
142static int execute_HDR_set1_recipient_test(CMP_HDR_TEST_FIXTURE *fixture)
143{
144    int res = 0;
145    X509_NAME *x509name = X509_NAME_new();
146
147    if (!TEST_ptr(x509name))
148        goto err;
149
150    X509_NAME_ADD(x509name, "CN", "A common recipient name");
151    if (!TEST_int_eq(ossl_cmp_hdr_set1_recipient(fixture->hdr, x509name), 1))
152        goto err;
153
154    if (!TEST_int_eq(fixture->hdr->recipient->type, GEN_DIRNAME))
155        goto err;
156
157    if (!TEST_int_eq(X509_NAME_cmp(fixture->hdr->recipient->d.directoryName,
158                                   x509name), 0))
159        goto err;
160
161    res = 1;
162err:
163    X509_NAME_free(x509name);
164
165    return res;
166}
167
168static int test_HDR_set1_recipient(void)
169{
170    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
171    fixture->expected = 1;
172    EXECUTE_TEST(execute_HDR_set1_recipient_test, tear_down);
173    return result;
174}
175
176static int execute_HDR_update_messageTime_test(CMP_HDR_TEST_FIXTURE *fixture)
177{
178    struct tm hdrtm, tmptm;
179    time_t hdrtime, before, after, now;
180
181    now = time(NULL);
182    /*
183     * Trial and error reveals that passing the return value from gmtime
184     * directly to mktime in a mingw 32 bit build gives unexpected results. To
185     * work around this we take a copy of the return value first.
186     */
187    tmptm = *gmtime(&now);
188    before = mktime(&tmptm);
189
190    if (!TEST_true(ossl_cmp_hdr_update_messageTime(fixture->hdr)))
191        return 0;
192    if (!TEST_true(ASN1_TIME_to_tm(fixture->hdr->messageTime, &hdrtm)))
193        return 0;
194
195    hdrtime = mktime(&hdrtm);
196
197    if (!TEST_time_t_le(before, hdrtime))
198        return 0;
199    now = time(NULL);
200    tmptm = *gmtime(&now);
201    after = mktime(&tmptm);
202
203    return TEST_time_t_le(hdrtime, after);
204}
205
206static int test_HDR_update_messageTime(void)
207{
208    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
209    fixture->expected = 1;
210    EXECUTE_TEST(execute_HDR_update_messageTime_test, tear_down);
211    return result;
212}
213
214static int execute_HDR_set1_senderKID_test(CMP_HDR_TEST_FIXTURE *fixture)
215{
216    ASN1_OCTET_STRING *senderKID = ASN1_OCTET_STRING_new();
217    int res = 0;
218
219    if (!TEST_ptr(senderKID))
220        goto err;
221
222    if (!TEST_int_eq(ASN1_OCTET_STRING_set(senderKID, rand_data,
223                                           sizeof(rand_data)), 1))
224        goto err;
225    if (!TEST_int_eq(ossl_cmp_hdr_set1_senderKID(fixture->hdr, senderKID), 1))
226        goto err;
227    if (!TEST_int_eq(ASN1_OCTET_STRING_cmp(fixture->hdr->senderKID,
228                                           senderKID), 0))
229        goto err;
230    res = 1;
231 err:
232    ASN1_OCTET_STRING_free(senderKID);
233    return res;
234}
235
236static int test_HDR_set1_senderKID(void)
237{
238    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
239    fixture->expected = 1;
240    EXECUTE_TEST(execute_HDR_set1_senderKID_test, tear_down);
241    return result;
242}
243
244static int execute_HDR_push0_freeText_test(CMP_HDR_TEST_FIXTURE *fixture)
245{
246    ASN1_UTF8STRING *text = ASN1_UTF8STRING_new();
247
248    if (!TEST_ptr(text))
249        return 0;
250
251    if (!ASN1_STRING_set(text, "A free text", -1))
252        goto err;
253
254    if (!TEST_int_eq(ossl_cmp_hdr_push0_freeText(fixture->hdr, text), 1))
255        goto err;
256
257    if (!TEST_true(text == sk_ASN1_UTF8STRING_value(fixture->hdr->freeText, 0)))
258        goto err;
259
260    return 1;
261
262 err:
263    ASN1_UTF8STRING_free(text);
264    return 0;
265}
266
267static int test_HDR_push0_freeText(void)
268{
269    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
270    fixture->expected = 1;
271    EXECUTE_TEST(execute_HDR_push0_freeText_test, tear_down);
272    return result;
273}
274
275static int execute_HDR_push1_freeText_test(CMP_HDR_TEST_FIXTURE *fixture)
276{
277    ASN1_UTF8STRING *text = ASN1_UTF8STRING_new();
278    ASN1_UTF8STRING *pushed_text;
279    int res = 0;
280
281    if (!TEST_ptr(text))
282        goto err;
283
284    if (!ASN1_STRING_set(text, "A free text", -1))
285        goto err;
286
287    if (!TEST_int_eq(ossl_cmp_hdr_push1_freeText(fixture->hdr, text), 1))
288        goto err;
289
290    pushed_text = sk_ASN1_UTF8STRING_value(fixture->hdr->freeText, 0);
291    if (!TEST_int_eq(ASN1_STRING_cmp(text, pushed_text), 0))
292        goto err;
293
294    res = 1;
295 err:
296    ASN1_UTF8STRING_free(text);
297
298    return res;
299}
300
301static int test_HDR_push1_freeText(void)
302{
303    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
304    fixture->expected = 1;
305    EXECUTE_TEST(execute_HDR_push1_freeText_test, tear_down);
306    return result;
307}
308
309static int
310execute_HDR_generalInfo_push0_item_test(CMP_HDR_TEST_FIXTURE *fixture)
311{
312    OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
313
314    if (!TEST_ptr(itav))
315        return 0;
316
317    if (!TEST_int_eq(ossl_cmp_hdr_generalInfo_push0_item(fixture->hdr, itav),
318                     1))
319        return 0;
320
321    if (!TEST_true(itav == sk_OSSL_CMP_ITAV_value(fixture->hdr->generalInfo,
322                                                  0)))
323        return 0;
324
325    return 1;
326}
327
328static int test_HDR_generalInfo_push0_item(void)
329{
330    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
331    fixture->expected = 1;
332    EXECUTE_TEST(execute_HDR_generalInfo_push0_item_test, tear_down);
333    return result;
334}
335
336static int
337execute_HDR_generalInfo_push1_items_test(CMP_HDR_TEST_FIXTURE *fixture)
338{
339    const char oid[] = "1.2.3.4";
340    char buf[20];
341    OSSL_CMP_ITAV *itav, *pushed_itav;
342    STACK_OF(OSSL_CMP_ITAV) *itavs = NULL, *ginfo;
343    ASN1_INTEGER *asn1int = ASN1_INTEGER_new();
344    ASN1_TYPE *val = ASN1_TYPE_new();
345    ASN1_TYPE *pushed_val;
346    int res = 0;
347
348    if (!TEST_ptr(asn1int))
349        return 0;
350
351    if (!TEST_ptr(val)
352            || !TEST_true(ASN1_INTEGER_set(asn1int, 88))) {
353        ASN1_INTEGER_free(asn1int);
354        return 0;
355    }
356
357    ASN1_TYPE_set(val, V_ASN1_INTEGER, asn1int);
358    if (!TEST_ptr(itav = OSSL_CMP_ITAV_create(OBJ_txt2obj(oid, 1), val))) {
359        ASN1_TYPE_free(val);
360        return 0;
361    }
362    if (!TEST_true(OSSL_CMP_ITAV_push0_stack_item(&itavs, itav))) {
363        OSSL_CMP_ITAV_free(itav);
364        return 0;
365    }
366
367    if (!TEST_int_eq(ossl_cmp_hdr_generalInfo_push1_items(fixture->hdr, itavs),
368                     1))
369        goto err;
370    ginfo = fixture->hdr->generalInfo;
371    pushed_itav = sk_OSSL_CMP_ITAV_value(ginfo, 0);
372    OBJ_obj2txt(buf, sizeof(buf), OSSL_CMP_ITAV_get0_type(pushed_itav), 0);
373    if (!TEST_int_eq(memcmp(oid, buf, sizeof(oid)), 0))
374        goto err;
375
376    pushed_val = OSSL_CMP_ITAV_get0_value(sk_OSSL_CMP_ITAV_value(ginfo, 0));
377    if (!TEST_int_eq(ASN1_TYPE_cmp(itav->infoValue.other, pushed_val), 0))
378        goto err;
379
380    res = 1;
381
382 err:
383    sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
384    return res;
385}
386
387static int test_HDR_generalInfo_push1_items(void)
388{
389    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
390    fixture->expected = 1;
391    EXECUTE_TEST(execute_HDR_generalInfo_push1_items_test, tear_down);
392    return result;
393}
394
395static int
396execute_HDR_set_and_check_implicitConfirm_test(CMP_HDR_TEST_FIXTURE
397                                               * fixture)
398{
399    return TEST_false(ossl_cmp_hdr_has_implicitConfirm(fixture->hdr))
400        && TEST_true(ossl_cmp_hdr_set_implicitConfirm(fixture->hdr))
401        && TEST_true(ossl_cmp_hdr_has_implicitConfirm(fixture->hdr));
402}
403
404static int test_HDR_set_and_check_implicit_confirm(void)
405{
406    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
407    EXECUTE_TEST(execute_HDR_set_and_check_implicitConfirm_test, tear_down);
408    return result;
409}
410
411
412static int execute_HDR_init_test(CMP_HDR_TEST_FIXTURE *fixture)
413{
414    ASN1_OCTET_STRING *header_nonce, *header_transactionID;
415    ASN1_OCTET_STRING *ctx_nonce;
416
417    if (!TEST_int_eq(fixture->expected,
418                     ossl_cmp_hdr_init(fixture->cmp_ctx, fixture->hdr)))
419        return 0;
420    if (fixture->expected == 0)
421        return 1;
422
423    if (!TEST_int_eq(ossl_cmp_hdr_get_pvno(fixture->hdr), OSSL_CMP_PVNO))
424        return 0;
425
426    header_nonce = ossl_cmp_hdr_get0_senderNonce(fixture->hdr);
427    if (!TEST_int_eq(0, ASN1_OCTET_STRING_cmp(header_nonce,
428                                              fixture->cmp_ctx->senderNonce)))
429        return 0;
430    header_transactionID = OSSL_CMP_HDR_get0_transactionID(fixture->hdr);
431    if (!TEST_true(0 == ASN1_OCTET_STRING_cmp(header_transactionID,
432                                              fixture->cmp_ctx->transactionID)))
433        return 0;
434
435    header_nonce = OSSL_CMP_HDR_get0_recipNonce(fixture->hdr);
436    ctx_nonce = fixture->cmp_ctx->recipNonce;
437    if (ctx_nonce != NULL
438            && (!TEST_ptr(header_nonce)
439                    || !TEST_int_eq(0, ASN1_OCTET_STRING_cmp(header_nonce,
440                                                             ctx_nonce))))
441        return 0;
442
443    return 1;
444}
445
446static int test_HDR_init_with_ref(void)
447{
448    unsigned char ref[CMP_TEST_REFVALUE_LENGTH];
449
450    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
451
452    fixture->expected = 1;
453    if (!TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))
454            || !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
455                                                           ref, sizeof(ref)))) {
456        tear_down(fixture);
457        fixture = NULL;
458    }
459    EXECUTE_TEST(execute_HDR_init_test, tear_down);
460    return result;
461}
462
463static int test_HDR_init_with_subject(void)
464{
465    X509_NAME *subject = NULL;
466
467    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
468    fixture->expected = 1;
469    if (!TEST_ptr(subject = X509_NAME_new())
470            || !TEST_true(X509_NAME_ADD(subject, "CN", "Common Name"))
471            || !TEST_true(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx,
472                                                        subject))) {
473        tear_down(fixture);
474        fixture = NULL;
475    }
476    X509_NAME_free(subject);
477    EXECUTE_TEST(execute_HDR_init_test, tear_down);
478    return result;
479}
480
481
482void cleanup_tests(void)
483{
484    return;
485}
486
487int setup_tests(void)
488{
489    RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
490    /* Message header tests */
491    ADD_TEST(test_HDR_set_get_pvno);
492    ADD_TEST(test_HDR_get0_senderNonce);
493    ADD_TEST(test_HDR_set1_sender);
494    ADD_TEST(test_HDR_set1_recipient);
495    ADD_TEST(test_HDR_update_messageTime);
496    ADD_TEST(test_HDR_set1_senderKID);
497    ADD_TEST(test_HDR_push0_freeText);
498    /* indirectly tests ossl_cmp_pkifreetext_push_str(): */
499    ADD_TEST(test_HDR_push1_freeText);
500    ADD_TEST(test_HDR_generalInfo_push0_item);
501    ADD_TEST(test_HDR_generalInfo_push1_items);
502    ADD_TEST(test_HDR_set_and_check_implicit_confirm);
503    /* also tests public function OSSL_CMP_HDR_get0_transactionID(): */
504    /* also tests public function OSSL_CMP_HDR_get0_recipNonce(): */
505    /* also tests internal function ossl_cmp_hdr_get_pvno(): */
506    ADD_TEST(test_HDR_init_with_ref);
507    ADD_TEST(test_HDR_init_with_subject);
508    return 1;
509}
510