1*e0c4386eSCy Schubert /*
2*e0c4386eSCy Schubert * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
3*e0c4386eSCy Schubert * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
4*e0c4386eSCy Schubert *
5*e0c4386eSCy Schubert * Licensed under the Apache License 2.0 (the "License"). You may not use
6*e0c4386eSCy Schubert * this file except in compliance with the License. You can obtain a copy
7*e0c4386eSCy Schubert * in the file LICENSE in the source distribution or at
8*e0c4386eSCy Schubert * https://www.openssl.org/source/license.html
9*e0c4386eSCy Schubert */
10*e0c4386eSCy Schubert
11*e0c4386eSCy Schubert #include <stdarg.h>
12*e0c4386eSCy Schubert #include <openssl/evp.h>
13*e0c4386eSCy Schubert #include "testutil.h"
14*e0c4386eSCy Schubert #include "internal/nelem.h"
15*e0c4386eSCy Schubert #include "internal/property.h"
16*e0c4386eSCy Schubert #include "../crypto/property/property_local.h"
17*e0c4386eSCy Schubert
18*e0c4386eSCy Schubert /*
19*e0c4386eSCy Schubert * We make our OSSL_PROVIDER for testing purposes. All we really need is
20*e0c4386eSCy Schubert * a pointer. We know that as long as we don't try to use the method
21*e0c4386eSCy Schubert * cache flush functions, the provider pointer is merely a pointer being
22*e0c4386eSCy Schubert * passed around, and used as a tag of sorts.
23*e0c4386eSCy Schubert */
24*e0c4386eSCy Schubert struct ossl_provider_st {
25*e0c4386eSCy Schubert int x;
26*e0c4386eSCy Schubert };
27*e0c4386eSCy Schubert
add_property_names(const char * n,...)28*e0c4386eSCy Schubert static int add_property_names(const char *n, ...)
29*e0c4386eSCy Schubert {
30*e0c4386eSCy Schubert va_list args;
31*e0c4386eSCy Schubert int res = 1;
32*e0c4386eSCy Schubert
33*e0c4386eSCy Schubert va_start(args, n);
34*e0c4386eSCy Schubert do {
35*e0c4386eSCy Schubert if (!TEST_int_ne(ossl_property_name(NULL, n, 1), 0))
36*e0c4386eSCy Schubert res = 0;
37*e0c4386eSCy Schubert } while ((n = va_arg(args, const char *)) != NULL);
38*e0c4386eSCy Schubert va_end(args);
39*e0c4386eSCy Schubert return res;
40*e0c4386eSCy Schubert }
41*e0c4386eSCy Schubert
up_ref(void * p)42*e0c4386eSCy Schubert static int up_ref(void *p)
43*e0c4386eSCy Schubert {
44*e0c4386eSCy Schubert return 1;
45*e0c4386eSCy Schubert }
46*e0c4386eSCy Schubert
down_ref(void * p)47*e0c4386eSCy Schubert static void down_ref(void *p)
48*e0c4386eSCy Schubert {
49*e0c4386eSCy Schubert }
50*e0c4386eSCy Schubert
test_property_string(void)51*e0c4386eSCy Schubert static int test_property_string(void)
52*e0c4386eSCy Schubert {
53*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
54*e0c4386eSCy Schubert int res = 0;
55*e0c4386eSCy Schubert OSSL_PROPERTY_IDX i, j;
56*e0c4386eSCy Schubert
57*e0c4386eSCy Schubert if (TEST_ptr(store = ossl_method_store_new(NULL))
58*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_name(NULL, "fnord", 0), 0)
59*e0c4386eSCy Schubert && TEST_int_ne(ossl_property_name(NULL, "fnord", 1), 0)
60*e0c4386eSCy Schubert && TEST_int_ne(ossl_property_name(NULL, "name", 1), 0)
61*e0c4386eSCy Schubert /* Property value checks */
62*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_value(NULL, "fnord", 0), 0)
63*e0c4386eSCy Schubert && TEST_int_ne(i = ossl_property_value(NULL, "no", 0), 0)
64*e0c4386eSCy Schubert && TEST_int_ne(j = ossl_property_value(NULL, "yes", 0), 0)
65*e0c4386eSCy Schubert && TEST_int_ne(i, j)
66*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_value(NULL, "yes", 1), j)
67*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_value(NULL, "no", 1), i)
68*e0c4386eSCy Schubert && TEST_int_ne(i = ossl_property_value(NULL, "illuminati", 1), 0)
69*e0c4386eSCy Schubert && TEST_int_eq(j = ossl_property_value(NULL, "fnord", 1), i + 1)
70*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_value(NULL, "fnord", 1), j)
71*e0c4386eSCy Schubert /* Check name and values are distinct */
72*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_value(NULL, "cold", 0), 0)
73*e0c4386eSCy Schubert && TEST_int_ne(ossl_property_name(NULL, "fnord", 0),
74*e0c4386eSCy Schubert ossl_property_value(NULL, "fnord", 0)))
75*e0c4386eSCy Schubert res = 1;
76*e0c4386eSCy Schubert ossl_method_store_free(store);
77*e0c4386eSCy Schubert return res;
78*e0c4386eSCy Schubert }
79*e0c4386eSCy Schubert
80*e0c4386eSCy Schubert static const struct {
81*e0c4386eSCy Schubert const char *defn;
82*e0c4386eSCy Schubert const char *query;
83*e0c4386eSCy Schubert int e;
84*e0c4386eSCy Schubert } parser_tests[] = {
85*e0c4386eSCy Schubert { "", "sky=blue", -1 },
86*e0c4386eSCy Schubert { "", "sky!=blue", 1 },
87*e0c4386eSCy Schubert { "groan", "", 0 },
88*e0c4386eSCy Schubert { "cold=yes", "cold=yes", 1 },
89*e0c4386eSCy Schubert { "cold=yes", "cold", 1 },
90*e0c4386eSCy Schubert { "cold=yes", "cold!=no", 1 },
91*e0c4386eSCy Schubert { "groan", "groan=yes", 1 },
92*e0c4386eSCy Schubert { "groan", "groan=no", -1 },
93*e0c4386eSCy Schubert { "groan", "groan!=yes", -1 },
94*e0c4386eSCy Schubert { "cold=no", "cold", -1 },
95*e0c4386eSCy Schubert { "cold=no", "?cold", 0 },
96*e0c4386eSCy Schubert { "cold=no", "cold=no", 1 },
97*e0c4386eSCy Schubert { "groan", "cold", -1 },
98*e0c4386eSCy Schubert { "groan", "cold=no", 1 },
99*e0c4386eSCy Schubert { "groan", "cold!=yes", 1 },
100*e0c4386eSCy Schubert { "groan=blue", "groan=yellow", -1 },
101*e0c4386eSCy Schubert { "groan=blue", "?groan=yellow", 0 },
102*e0c4386eSCy Schubert { "groan=blue", "groan!=yellow", 1 },
103*e0c4386eSCy Schubert { "groan=blue", "?groan!=yellow", 1 },
104*e0c4386eSCy Schubert { "today=monday, tomorrow=3", "today!=2", 1 },
105*e0c4386eSCy Schubert { "today=monday, tomorrow=3", "today!='monday'", -1 },
106*e0c4386eSCy Schubert { "today=monday, tomorrow=3", "tomorrow=3", 1 },
107*e0c4386eSCy Schubert { "n=0x3", "n=3", 1 },
108*e0c4386eSCy Schubert { "n=0x3", "n=-3", -1 },
109*e0c4386eSCy Schubert { "n=0x33", "n=51", 1 },
110*e0c4386eSCy Schubert { "n=0x123456789abcdef", "n=0x123456789abcdef", 1 },
111*e0c4386eSCy Schubert { "n=0x7fffffffffffffff", "n=0x7fffffffffffffff", 1 }, /* INT64_MAX */
112*e0c4386eSCy Schubert { "n=9223372036854775807", "n=9223372036854775807", 1 }, /* INT64_MAX */
113*e0c4386eSCy Schubert { "n=0777777777777777777777", "n=0777777777777777777777", 1 }, /* INT64_MAX */
114*e0c4386eSCy Schubert { "n=033", "n=27", 1 },
115*e0c4386eSCy Schubert { "n=0", "n=00", 1 },
116*e0c4386eSCy Schubert { "n=0x0", "n=0", 1 },
117*e0c4386eSCy Schubert { "n=0, sky=blue", "?n=0, sky=blue", 2 },
118*e0c4386eSCy Schubert { "n=1, sky=blue", "?n=0, sky=blue", 1 },
119*e0c4386eSCy Schubert };
120*e0c4386eSCy Schubert
test_property_parse(int n)121*e0c4386eSCy Schubert static int test_property_parse(int n)
122*e0c4386eSCy Schubert {
123*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
124*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *p = NULL, *q = NULL;
125*e0c4386eSCy Schubert int r = 0;
126*e0c4386eSCy Schubert
127*e0c4386eSCy Schubert if (TEST_ptr(store = ossl_method_store_new(NULL))
128*e0c4386eSCy Schubert && add_property_names("sky", "groan", "cold", "today", "tomorrow", "n",
129*e0c4386eSCy Schubert NULL)
130*e0c4386eSCy Schubert && TEST_ptr(p = ossl_parse_property(NULL, parser_tests[n].defn))
131*e0c4386eSCy Schubert && TEST_ptr(q = ossl_parse_query(NULL, parser_tests[n].query, 0))
132*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_match_count(q, p), parser_tests[n].e))
133*e0c4386eSCy Schubert r = 1;
134*e0c4386eSCy Schubert ossl_property_free(p);
135*e0c4386eSCy Schubert ossl_property_free(q);
136*e0c4386eSCy Schubert ossl_method_store_free(store);
137*e0c4386eSCy Schubert return r;
138*e0c4386eSCy Schubert }
139*e0c4386eSCy Schubert
test_property_query_value_create(void)140*e0c4386eSCy Schubert static int test_property_query_value_create(void)
141*e0c4386eSCy Schubert {
142*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
143*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *p = NULL, *q = NULL, *o = NULL;
144*e0c4386eSCy Schubert int r = 0;
145*e0c4386eSCy Schubert
146*e0c4386eSCy Schubert /* The property value used here must not be used in other test cases */
147*e0c4386eSCy Schubert if (TEST_ptr(store = ossl_method_store_new(NULL))
148*e0c4386eSCy Schubert && add_property_names("wood", NULL)
149*e0c4386eSCy Schubert && TEST_ptr(p = ossl_parse_query(NULL, "wood=oak", 0)) /* undefined */
150*e0c4386eSCy Schubert && TEST_ptr(q = ossl_parse_query(NULL, "wood=oak", 1)) /* creates */
151*e0c4386eSCy Schubert && TEST_ptr(o = ossl_parse_query(NULL, "wood=oak", 0)) /* defined */
152*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_match_count(q, p), -1)
153*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_match_count(q, o), 1))
154*e0c4386eSCy Schubert r = 1;
155*e0c4386eSCy Schubert ossl_property_free(o);
156*e0c4386eSCy Schubert ossl_property_free(p);
157*e0c4386eSCy Schubert ossl_property_free(q);
158*e0c4386eSCy Schubert ossl_method_store_free(store);
159*e0c4386eSCy Schubert return r;
160*e0c4386eSCy Schubert }
161*e0c4386eSCy Schubert
162*e0c4386eSCy Schubert static const struct {
163*e0c4386eSCy Schubert int query;
164*e0c4386eSCy Schubert const char *ps;
165*e0c4386eSCy Schubert } parse_error_tests[] = {
166*e0c4386eSCy Schubert { 0, "n=1, n=1" }, /* duplicate name */
167*e0c4386eSCy Schubert { 0, "n=1, a=hi, n=1" }, /* duplicate name */
168*e0c4386eSCy Schubert { 1, "n=1, a=bye, ?n=0" }, /* duplicate name */
169*e0c4386eSCy Schubert { 0, "a=abc,#@!, n=1" }, /* non-ASCII character located */
170*e0c4386eSCy Schubert { 1, "a='Hello" }, /* Unterminated string */
171*e0c4386eSCy Schubert { 0, "a=\"World" }, /* Unterminated string */
172*e0c4386eSCy Schubert { 0, "a=_abd_" }, /* Unquoted string not starting with alphabetic */
173*e0c4386eSCy Schubert { 1, "a=2, n=012345678" }, /* Bad octal digit */
174*e0c4386eSCy Schubert { 0, "n=0x28FG, a=3" }, /* Bad hex digit */
175*e0c4386eSCy Schubert { 0, "n=145d, a=2" }, /* Bad decimal digit */
176*e0c4386eSCy Schubert { 0, "n=0x8000000000000000, a=3" }, /* Hex overflow */
177*e0c4386eSCy Schubert { 0, "n=922337203000000000d, a=2" }, /* Decimal overflow */
178*e0c4386eSCy Schubert { 0, "a=2, n=1000000000000000000000" }, /* Octal overflow */
179*e0c4386eSCy Schubert { 1, "@='hello'" }, /* Invalid name */
180*e0c4386eSCy Schubert { 1, "n0123456789012345678901234567890123456789"
181*e0c4386eSCy Schubert "0123456789012345678901234567890123456789"
182*e0c4386eSCy Schubert "0123456789012345678901234567890123456789"
183*e0c4386eSCy Schubert "0123456789012345678901234567890123456789=yes" }, /* Name too long */
184*e0c4386eSCy Schubert { 0, ".n=3" }, /* Invalid name */
185*e0c4386eSCy Schubert { 1, "fnord.fnord.=3" } /* Invalid name */
186*e0c4386eSCy Schubert };
187*e0c4386eSCy Schubert
test_property_parse_error(int n)188*e0c4386eSCy Schubert static int test_property_parse_error(int n)
189*e0c4386eSCy Schubert {
190*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
191*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *p = NULL;
192*e0c4386eSCy Schubert int r = 0;
193*e0c4386eSCy Schubert const char *ps;
194*e0c4386eSCy Schubert
195*e0c4386eSCy Schubert if (!TEST_ptr(store = ossl_method_store_new(NULL))
196*e0c4386eSCy Schubert || !add_property_names("a", "n", NULL))
197*e0c4386eSCy Schubert goto err;
198*e0c4386eSCy Schubert ps = parse_error_tests[n].ps;
199*e0c4386eSCy Schubert if (parse_error_tests[n].query) {
200*e0c4386eSCy Schubert if (!TEST_ptr_null(p = ossl_parse_query(NULL, ps, 1)))
201*e0c4386eSCy Schubert goto err;
202*e0c4386eSCy Schubert } else if (!TEST_ptr_null(p = ossl_parse_property(NULL, ps))) {
203*e0c4386eSCy Schubert goto err;
204*e0c4386eSCy Schubert }
205*e0c4386eSCy Schubert r = 1;
206*e0c4386eSCy Schubert err:
207*e0c4386eSCy Schubert ossl_property_free(p);
208*e0c4386eSCy Schubert ossl_method_store_free(store);
209*e0c4386eSCy Schubert return r;
210*e0c4386eSCy Schubert }
211*e0c4386eSCy Schubert
212*e0c4386eSCy Schubert static const struct {
213*e0c4386eSCy Schubert const char *q_global;
214*e0c4386eSCy Schubert const char *q_local;
215*e0c4386eSCy Schubert const char *prop;
216*e0c4386eSCy Schubert } merge_tests[] = {
217*e0c4386eSCy Schubert { "", "colour=blue", "colour=blue" },
218*e0c4386eSCy Schubert { "colour=blue", "", "colour=blue" },
219*e0c4386eSCy Schubert { "colour=red", "colour=blue", "colour=blue" },
220*e0c4386eSCy Schubert { "clouds=pink, urn=red", "urn=blue, colour=green",
221*e0c4386eSCy Schubert "urn=blue, colour=green, clouds=pink" },
222*e0c4386eSCy Schubert { "pot=gold", "urn=blue", "pot=gold, urn=blue" },
223*e0c4386eSCy Schubert { "night", "day", "day=yes, night=yes" },
224*e0c4386eSCy Schubert { "day", "night", "day=yes, night=yes" },
225*e0c4386eSCy Schubert { "", "", "" },
226*e0c4386eSCy Schubert /*
227*e0c4386eSCy Schubert * The following four leave 'day' unspecified in the query, and will match
228*e0c4386eSCy Schubert * any definition
229*e0c4386eSCy Schubert */
230*e0c4386eSCy Schubert { "day=yes", "-day", "day=no" },
231*e0c4386eSCy Schubert { "day=yes", "-day", "day=yes" },
232*e0c4386eSCy Schubert { "day=yes", "-day", "day=arglebargle" },
233*e0c4386eSCy Schubert { "day=yes", "-day", "pot=sesquioxidizing" },
234*e0c4386eSCy Schubert { "day, night", "-night, day", "day=yes, night=no" },
235*e0c4386eSCy Schubert { "-day", "day=yes", "day=yes" },
236*e0c4386eSCy Schubert };
237*e0c4386eSCy Schubert
test_property_merge(int n)238*e0c4386eSCy Schubert static int test_property_merge(int n)
239*e0c4386eSCy Schubert {
240*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
241*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *q_global = NULL, *q_local = NULL;
242*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *q_combined = NULL, *prop = NULL;
243*e0c4386eSCy Schubert int r = 0;
244*e0c4386eSCy Schubert
245*e0c4386eSCy Schubert if (TEST_ptr(store = ossl_method_store_new(NULL))
246*e0c4386eSCy Schubert && add_property_names("colour", "urn", "clouds", "pot", "day", "night",
247*e0c4386eSCy Schubert NULL)
248*e0c4386eSCy Schubert && TEST_ptr(prop = ossl_parse_property(NULL, merge_tests[n].prop))
249*e0c4386eSCy Schubert && TEST_ptr(q_global = ossl_parse_query(NULL, merge_tests[n].q_global,
250*e0c4386eSCy Schubert 0))
251*e0c4386eSCy Schubert && TEST_ptr(q_local = ossl_parse_query(NULL, merge_tests[n].q_local, 0))
252*e0c4386eSCy Schubert && TEST_ptr(q_combined = ossl_property_merge(q_local, q_global))
253*e0c4386eSCy Schubert && TEST_int_ge(ossl_property_match_count(q_combined, prop), 0))
254*e0c4386eSCy Schubert r = 1;
255*e0c4386eSCy Schubert ossl_property_free(q_global);
256*e0c4386eSCy Schubert ossl_property_free(q_local);
257*e0c4386eSCy Schubert ossl_property_free(q_combined);
258*e0c4386eSCy Schubert ossl_property_free(prop);
259*e0c4386eSCy Schubert ossl_method_store_free(store);
260*e0c4386eSCy Schubert return r;
261*e0c4386eSCy Schubert }
262*e0c4386eSCy Schubert
test_property_defn_cache(void)263*e0c4386eSCy Schubert static int test_property_defn_cache(void)
264*e0c4386eSCy Schubert {
265*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
266*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *red = NULL, *blue = NULL, *blue2 = NULL;
267*e0c4386eSCy Schubert int r;
268*e0c4386eSCy Schubert
269*e0c4386eSCy Schubert r = TEST_ptr(store = ossl_method_store_new(NULL))
270*e0c4386eSCy Schubert && add_property_names("red", "blue", NULL)
271*e0c4386eSCy Schubert && TEST_ptr(red = ossl_parse_property(NULL, "red"))
272*e0c4386eSCy Schubert && TEST_ptr(blue = ossl_parse_property(NULL, "blue"))
273*e0c4386eSCy Schubert && TEST_ptr_ne(red, blue)
274*e0c4386eSCy Schubert && TEST_true(ossl_prop_defn_set(NULL, "red", &red));
275*e0c4386eSCy Schubert
276*e0c4386eSCy Schubert if (!r) {
277*e0c4386eSCy Schubert ossl_property_free(red);
278*e0c4386eSCy Schubert red = NULL;
279*e0c4386eSCy Schubert ossl_property_free(blue);
280*e0c4386eSCy Schubert blue = NULL;
281*e0c4386eSCy Schubert }
282*e0c4386eSCy Schubert
283*e0c4386eSCy Schubert r = r && TEST_true(ossl_prop_defn_set(NULL, "blue", &blue));
284*e0c4386eSCy Schubert if (!r) {
285*e0c4386eSCy Schubert ossl_property_free(blue);
286*e0c4386eSCy Schubert blue = NULL;
287*e0c4386eSCy Schubert }
288*e0c4386eSCy Schubert
289*e0c4386eSCy Schubert r = r && TEST_ptr_eq(ossl_prop_defn_get(NULL, "red"), red)
290*e0c4386eSCy Schubert && TEST_ptr_eq(ossl_prop_defn_get(NULL, "blue"), blue)
291*e0c4386eSCy Schubert && TEST_ptr(blue2 = ossl_parse_property(NULL, "blue"))
292*e0c4386eSCy Schubert && TEST_ptr_ne(blue2, blue)
293*e0c4386eSCy Schubert && TEST_true(ossl_prop_defn_set(NULL, "blue", &blue2));
294*e0c4386eSCy Schubert if (!r) {
295*e0c4386eSCy Schubert ossl_property_free(blue2);
296*e0c4386eSCy Schubert blue2 = NULL;
297*e0c4386eSCy Schubert }
298*e0c4386eSCy Schubert
299*e0c4386eSCy Schubert r = r && TEST_ptr_eq(blue2, blue)
300*e0c4386eSCy Schubert && TEST_ptr_eq(ossl_prop_defn_get(NULL, "blue"), blue);
301*e0c4386eSCy Schubert
302*e0c4386eSCy Schubert ossl_method_store_free(store);
303*e0c4386eSCy Schubert return r;
304*e0c4386eSCy Schubert }
305*e0c4386eSCy Schubert
306*e0c4386eSCy Schubert static const struct {
307*e0c4386eSCy Schubert const char *defn;
308*e0c4386eSCy Schubert const char *query;
309*e0c4386eSCy Schubert int e;
310*e0c4386eSCy Schubert } definition_tests[] = {
311*e0c4386eSCy Schubert { "alpha", "alpha=yes", 1 },
312*e0c4386eSCy Schubert { "alpha=no", "alpha", -1 },
313*e0c4386eSCy Schubert { "alpha=1", "alpha=1", 1 },
314*e0c4386eSCy Schubert { "alpha=2", "alpha=1",-1 },
315*e0c4386eSCy Schubert { "alpha", "omega", -1 },
316*e0c4386eSCy Schubert { "alpha", "?omega", 0 },
317*e0c4386eSCy Schubert { "alpha", "?omega=1", 0 },
318*e0c4386eSCy Schubert { "alpha", "?omega=no", 1 },
319*e0c4386eSCy Schubert { "alpha", "?omega=yes", 0 },
320*e0c4386eSCy Schubert { "alpha, omega", "?omega=yes", 1 },
321*e0c4386eSCy Schubert { "alpha, omega", "?omega=no", 0 }
322*e0c4386eSCy Schubert };
323*e0c4386eSCy Schubert
test_definition_compares(int n)324*e0c4386eSCy Schubert static int test_definition_compares(int n)
325*e0c4386eSCy Schubert {
326*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
327*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *d = NULL, *q = NULL;
328*e0c4386eSCy Schubert int r;
329*e0c4386eSCy Schubert
330*e0c4386eSCy Schubert r = TEST_ptr(store = ossl_method_store_new(NULL))
331*e0c4386eSCy Schubert && add_property_names("alpha", "omega", NULL)
332*e0c4386eSCy Schubert && TEST_ptr(d = ossl_parse_property(NULL, definition_tests[n].defn))
333*e0c4386eSCy Schubert && TEST_ptr(q = ossl_parse_query(NULL, definition_tests[n].query, 0))
334*e0c4386eSCy Schubert && TEST_int_eq(ossl_property_match_count(q, d), definition_tests[n].e);
335*e0c4386eSCy Schubert
336*e0c4386eSCy Schubert ossl_property_free(d);
337*e0c4386eSCy Schubert ossl_property_free(q);
338*e0c4386eSCy Schubert ossl_method_store_free(store);
339*e0c4386eSCy Schubert return r;
340*e0c4386eSCy Schubert }
341*e0c4386eSCy Schubert
test_register_deregister(void)342*e0c4386eSCy Schubert static int test_register_deregister(void)
343*e0c4386eSCy Schubert {
344*e0c4386eSCy Schubert static const struct {
345*e0c4386eSCy Schubert int nid;
346*e0c4386eSCy Schubert const char *prop;
347*e0c4386eSCy Schubert char *impl;
348*e0c4386eSCy Schubert } impls[] = {
349*e0c4386eSCy Schubert { 6, "position=1", "a" },
350*e0c4386eSCy Schubert { 6, "position=2", "b" },
351*e0c4386eSCy Schubert { 6, "position=3", "c" },
352*e0c4386eSCy Schubert { 6, "position=4", "d" },
353*e0c4386eSCy Schubert };
354*e0c4386eSCy Schubert size_t i;
355*e0c4386eSCy Schubert int ret = 0;
356*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
357*e0c4386eSCy Schubert OSSL_PROVIDER prov = { 1 };
358*e0c4386eSCy Schubert
359*e0c4386eSCy Schubert if (!TEST_ptr(store = ossl_method_store_new(NULL))
360*e0c4386eSCy Schubert || !add_property_names("position", NULL))
361*e0c4386eSCy Schubert goto err;
362*e0c4386eSCy Schubert
363*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(impls); i++)
364*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_add(store, &prov, impls[i].nid,
365*e0c4386eSCy Schubert impls[i].prop, impls[i].impl,
366*e0c4386eSCy Schubert &up_ref, &down_ref))) {
367*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
368*e0c4386eSCy Schubert goto err;
369*e0c4386eSCy Schubert }
370*e0c4386eSCy Schubert
371*e0c4386eSCy Schubert /* Deregister in a different order to registration */
372*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(impls); i++) {
373*e0c4386eSCy Schubert const size_t j = (1 + i * 3) % OSSL_NELEM(impls);
374*e0c4386eSCy Schubert int nid = impls[j].nid;
375*e0c4386eSCy Schubert void *impl = impls[j].impl;
376*e0c4386eSCy Schubert
377*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_remove(store, nid, impl))
378*e0c4386eSCy Schubert || !TEST_false(ossl_method_store_remove(store, nid, impl))) {
379*e0c4386eSCy Schubert TEST_note("iteration %zd, position %zd", i + 1, j + 1);
380*e0c4386eSCy Schubert goto err;
381*e0c4386eSCy Schubert }
382*e0c4386eSCy Schubert }
383*e0c4386eSCy Schubert
384*e0c4386eSCy Schubert if (TEST_false(ossl_method_store_remove(store, impls[0].nid, impls[0].impl)))
385*e0c4386eSCy Schubert ret = 1;
386*e0c4386eSCy Schubert err:
387*e0c4386eSCy Schubert ossl_method_store_free(store);
388*e0c4386eSCy Schubert return ret;
389*e0c4386eSCy Schubert }
390*e0c4386eSCy Schubert
test_property(void)391*e0c4386eSCy Schubert static int test_property(void)
392*e0c4386eSCy Schubert {
393*e0c4386eSCy Schubert static OSSL_PROVIDER fake_provider1 = { 1 };
394*e0c4386eSCy Schubert static OSSL_PROVIDER fake_provider2 = { 2 };
395*e0c4386eSCy Schubert static const OSSL_PROVIDER *fake_prov1 = &fake_provider1;
396*e0c4386eSCy Schubert static const OSSL_PROVIDER *fake_prov2 = &fake_provider2;
397*e0c4386eSCy Schubert static const struct {
398*e0c4386eSCy Schubert const OSSL_PROVIDER **prov;
399*e0c4386eSCy Schubert int nid;
400*e0c4386eSCy Schubert const char *prop;
401*e0c4386eSCy Schubert char *impl;
402*e0c4386eSCy Schubert } impls[] = {
403*e0c4386eSCy Schubert { &fake_prov1, 1, "fast=no, colour=green", "a" },
404*e0c4386eSCy Schubert { &fake_prov1, 1, "fast, colour=blue", "b" },
405*e0c4386eSCy Schubert { &fake_prov1, 1, "", "-" },
406*e0c4386eSCy Schubert { &fake_prov2, 9, "sky=blue, furry", "c" },
407*e0c4386eSCy Schubert { &fake_prov2, 3, NULL, "d" },
408*e0c4386eSCy Schubert { &fake_prov2, 6, "sky.colour=blue, sky=green, old.data", "e" },
409*e0c4386eSCy Schubert };
410*e0c4386eSCy Schubert static struct {
411*e0c4386eSCy Schubert const OSSL_PROVIDER **prov;
412*e0c4386eSCy Schubert int nid;
413*e0c4386eSCy Schubert const char *prop;
414*e0c4386eSCy Schubert char *expected;
415*e0c4386eSCy Schubert } queries[] = {
416*e0c4386eSCy Schubert { &fake_prov1, 1, "fast", "b" },
417*e0c4386eSCy Schubert { &fake_prov1, 1, "fast=yes", "b" },
418*e0c4386eSCy Schubert { &fake_prov1, 1, "fast=no, colour=green", "a" },
419*e0c4386eSCy Schubert { &fake_prov1, 1, "colour=blue, fast", "b" },
420*e0c4386eSCy Schubert { &fake_prov1, 1, "colour=blue", "b" },
421*e0c4386eSCy Schubert { &fake_prov2, 9, "furry", "c" },
422*e0c4386eSCy Schubert { &fake_prov2, 6, "sky.colour=blue", "e" },
423*e0c4386eSCy Schubert { &fake_prov2, 6, "old.data", "e" },
424*e0c4386eSCy Schubert { &fake_prov2, 9, "furry=yes, sky=blue", "c" },
425*e0c4386eSCy Schubert { &fake_prov1, 1, "", "a" },
426*e0c4386eSCy Schubert { &fake_prov2, 3, "", "d" },
427*e0c4386eSCy Schubert };
428*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
429*e0c4386eSCy Schubert size_t i;
430*e0c4386eSCy Schubert int ret = 0;
431*e0c4386eSCy Schubert void *result;
432*e0c4386eSCy Schubert
433*e0c4386eSCy Schubert if (!TEST_ptr(store = ossl_method_store_new(NULL))
434*e0c4386eSCy Schubert || !add_property_names("fast", "colour", "sky", "furry", NULL))
435*e0c4386eSCy Schubert goto err;
436*e0c4386eSCy Schubert
437*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(impls); i++)
438*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_add(store, *impls[i].prov,
439*e0c4386eSCy Schubert impls[i].nid, impls[i].prop,
440*e0c4386eSCy Schubert impls[i].impl,
441*e0c4386eSCy Schubert &up_ref, &down_ref))) {
442*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
443*e0c4386eSCy Schubert goto err;
444*e0c4386eSCy Schubert }
445*e0c4386eSCy Schubert /*
446*e0c4386eSCy Schubert * The first check of queries is with NULL given as provider. All
447*e0c4386eSCy Schubert * queries are expected to succeed.
448*e0c4386eSCy Schubert */
449*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(queries); i++) {
450*e0c4386eSCy Schubert const OSSL_PROVIDER *nullprov = NULL;
451*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *pq = NULL;
452*e0c4386eSCy Schubert
453*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_fetch(store,
454*e0c4386eSCy Schubert queries[i].nid, queries[i].prop,
455*e0c4386eSCy Schubert &nullprov, &result))
456*e0c4386eSCy Schubert || !TEST_str_eq((char *)result, queries[i].expected)) {
457*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
458*e0c4386eSCy Schubert ossl_property_free(pq);
459*e0c4386eSCy Schubert goto err;
460*e0c4386eSCy Schubert }
461*e0c4386eSCy Schubert ossl_property_free(pq);
462*e0c4386eSCy Schubert }
463*e0c4386eSCy Schubert /*
464*e0c4386eSCy Schubert * The second check of queries is with &address1 given as provider.
465*e0c4386eSCy Schubert */
466*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(queries); i++) {
467*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *pq = NULL;
468*e0c4386eSCy Schubert
469*e0c4386eSCy Schubert result = NULL;
470*e0c4386eSCy Schubert if (queries[i].prov == &fake_prov1) {
471*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_fetch(store,
472*e0c4386eSCy Schubert queries[i].nid,
473*e0c4386eSCy Schubert queries[i].prop,
474*e0c4386eSCy Schubert &fake_prov1, &result))
475*e0c4386eSCy Schubert || !TEST_ptr_eq(fake_prov1, &fake_provider1)
476*e0c4386eSCy Schubert || !TEST_str_eq((char *)result, queries[i].expected)) {
477*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
478*e0c4386eSCy Schubert ossl_property_free(pq);
479*e0c4386eSCy Schubert goto err;
480*e0c4386eSCy Schubert }
481*e0c4386eSCy Schubert } else {
482*e0c4386eSCy Schubert if (!TEST_false(ossl_method_store_fetch(store,
483*e0c4386eSCy Schubert queries[i].nid,
484*e0c4386eSCy Schubert queries[i].prop,
485*e0c4386eSCy Schubert &fake_prov1, &result))
486*e0c4386eSCy Schubert || !TEST_ptr_eq(fake_prov1, &fake_provider1)
487*e0c4386eSCy Schubert || !TEST_ptr_null(result)) {
488*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
489*e0c4386eSCy Schubert ossl_property_free(pq);
490*e0c4386eSCy Schubert goto err;
491*e0c4386eSCy Schubert }
492*e0c4386eSCy Schubert }
493*e0c4386eSCy Schubert ossl_property_free(pq);
494*e0c4386eSCy Schubert }
495*e0c4386eSCy Schubert /*
496*e0c4386eSCy Schubert * The third check of queries is with &address2 given as provider.
497*e0c4386eSCy Schubert */
498*e0c4386eSCy Schubert for (i = 0; i < OSSL_NELEM(queries); i++) {
499*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *pq = NULL;
500*e0c4386eSCy Schubert
501*e0c4386eSCy Schubert result = NULL;
502*e0c4386eSCy Schubert if (queries[i].prov == &fake_prov2) {
503*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_fetch(store,
504*e0c4386eSCy Schubert queries[i].nid,
505*e0c4386eSCy Schubert queries[i].prop,
506*e0c4386eSCy Schubert &fake_prov2, &result))
507*e0c4386eSCy Schubert || !TEST_ptr_eq(fake_prov2, &fake_provider2)
508*e0c4386eSCy Schubert || !TEST_str_eq((char *)result, queries[i].expected)) {
509*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
510*e0c4386eSCy Schubert ossl_property_free(pq);
511*e0c4386eSCy Schubert goto err;
512*e0c4386eSCy Schubert }
513*e0c4386eSCy Schubert } else {
514*e0c4386eSCy Schubert if (!TEST_false(ossl_method_store_fetch(store,
515*e0c4386eSCy Schubert queries[i].nid,
516*e0c4386eSCy Schubert queries[i].prop,
517*e0c4386eSCy Schubert &fake_prov2, &result))
518*e0c4386eSCy Schubert || !TEST_ptr_eq(fake_prov2, &fake_provider2)
519*e0c4386eSCy Schubert || !TEST_ptr_null(result)) {
520*e0c4386eSCy Schubert TEST_note("iteration %zd", i + 1);
521*e0c4386eSCy Schubert ossl_property_free(pq);
522*e0c4386eSCy Schubert goto err;
523*e0c4386eSCy Schubert }
524*e0c4386eSCy Schubert }
525*e0c4386eSCy Schubert ossl_property_free(pq);
526*e0c4386eSCy Schubert }
527*e0c4386eSCy Schubert ret = 1;
528*e0c4386eSCy Schubert err:
529*e0c4386eSCy Schubert ossl_method_store_free(store);
530*e0c4386eSCy Schubert return ret;
531*e0c4386eSCy Schubert }
532*e0c4386eSCy Schubert
test_query_cache_stochastic(void)533*e0c4386eSCy Schubert static int test_query_cache_stochastic(void)
534*e0c4386eSCy Schubert {
535*e0c4386eSCy Schubert const int max = 10000, tail = 10;
536*e0c4386eSCy Schubert OSSL_METHOD_STORE *store;
537*e0c4386eSCy Schubert int i, res = 0;
538*e0c4386eSCy Schubert char buf[50];
539*e0c4386eSCy Schubert void *result;
540*e0c4386eSCy Schubert int errors = 0;
541*e0c4386eSCy Schubert int v[10001];
542*e0c4386eSCy Schubert OSSL_PROVIDER prov = { 1 };
543*e0c4386eSCy Schubert
544*e0c4386eSCy Schubert if (!TEST_ptr(store = ossl_method_store_new(NULL))
545*e0c4386eSCy Schubert || !add_property_names("n", NULL))
546*e0c4386eSCy Schubert goto err;
547*e0c4386eSCy Schubert
548*e0c4386eSCy Schubert for (i = 1; i <= max; i++) {
549*e0c4386eSCy Schubert v[i] = 2 * i;
550*e0c4386eSCy Schubert BIO_snprintf(buf, sizeof(buf), "n=%d\n", i);
551*e0c4386eSCy Schubert if (!TEST_true(ossl_method_store_add(store, &prov, i, buf, "abc",
552*e0c4386eSCy Schubert &up_ref, &down_ref))
553*e0c4386eSCy Schubert || !TEST_true(ossl_method_store_cache_set(store, &prov, i,
554*e0c4386eSCy Schubert buf, v + i,
555*e0c4386eSCy Schubert &up_ref, &down_ref))
556*e0c4386eSCy Schubert || !TEST_true(ossl_method_store_cache_set(store, &prov, i,
557*e0c4386eSCy Schubert "n=1234", "miss",
558*e0c4386eSCy Schubert &up_ref, &down_ref))) {
559*e0c4386eSCy Schubert TEST_note("iteration %d", i);
560*e0c4386eSCy Schubert goto err;
561*e0c4386eSCy Schubert }
562*e0c4386eSCy Schubert }
563*e0c4386eSCy Schubert for (i = 1; i <= max; i++) {
564*e0c4386eSCy Schubert BIO_snprintf(buf, sizeof(buf), "n=%d\n", i);
565*e0c4386eSCy Schubert if (!ossl_method_store_cache_get(store, NULL, i, buf, &result)
566*e0c4386eSCy Schubert || result != v + i)
567*e0c4386eSCy Schubert errors++;
568*e0c4386eSCy Schubert }
569*e0c4386eSCy Schubert /* There is a tiny probability that this will fail when it shouldn't */
570*e0c4386eSCy Schubert res = TEST_int_gt(errors, tail) && TEST_int_lt(errors, max - tail);
571*e0c4386eSCy Schubert
572*e0c4386eSCy Schubert err:
573*e0c4386eSCy Schubert ossl_method_store_free(store);
574*e0c4386eSCy Schubert return res;
575*e0c4386eSCy Schubert }
576*e0c4386eSCy Schubert
test_fips_mode(void)577*e0c4386eSCy Schubert static int test_fips_mode(void)
578*e0c4386eSCy Schubert {
579*e0c4386eSCy Schubert int ret = 0;
580*e0c4386eSCy Schubert OSSL_LIB_CTX *ctx = NULL;
581*e0c4386eSCy Schubert
582*e0c4386eSCy Schubert if (!TEST_ptr(ctx = OSSL_LIB_CTX_new()))
583*e0c4386eSCy Schubert goto err;
584*e0c4386eSCy Schubert
585*e0c4386eSCy Schubert ret = TEST_true(EVP_set_default_properties(ctx, "default=yes,fips=yes"))
586*e0c4386eSCy Schubert && TEST_true(EVP_default_properties_is_fips_enabled(ctx))
587*e0c4386eSCy Schubert && TEST_true(EVP_set_default_properties(ctx, "fips=no,default=yes"))
588*e0c4386eSCy Schubert && TEST_false(EVP_default_properties_is_fips_enabled(ctx))
589*e0c4386eSCy Schubert && TEST_true(EVP_set_default_properties(ctx, "fips=no"))
590*e0c4386eSCy Schubert && TEST_false(EVP_default_properties_is_fips_enabled(ctx))
591*e0c4386eSCy Schubert && TEST_true(EVP_set_default_properties(ctx, "fips!=no"))
592*e0c4386eSCy Schubert && TEST_true(EVP_default_properties_is_fips_enabled(ctx))
593*e0c4386eSCy Schubert && TEST_true(EVP_set_default_properties(ctx, "fips=no"))
594*e0c4386eSCy Schubert && TEST_false(EVP_default_properties_is_fips_enabled(ctx))
595*e0c4386eSCy Schubert && TEST_true(EVP_set_default_properties(ctx, "fips=no,default=yes"))
596*e0c4386eSCy Schubert && TEST_true(EVP_default_properties_enable_fips(ctx, 1))
597*e0c4386eSCy Schubert && TEST_true(EVP_default_properties_is_fips_enabled(ctx))
598*e0c4386eSCy Schubert && TEST_true(EVP_default_properties_enable_fips(ctx, 0))
599*e0c4386eSCy Schubert && TEST_false(EVP_default_properties_is_fips_enabled(ctx));
600*e0c4386eSCy Schubert err:
601*e0c4386eSCy Schubert OSSL_LIB_CTX_free(ctx);
602*e0c4386eSCy Schubert return ret;
603*e0c4386eSCy Schubert }
604*e0c4386eSCy Schubert
605*e0c4386eSCy Schubert static struct {
606*e0c4386eSCy Schubert const char *in;
607*e0c4386eSCy Schubert const char *out;
608*e0c4386eSCy Schubert } to_string_tests[] = {
609*e0c4386eSCy Schubert { "fips=yes", "fips=yes" },
610*e0c4386eSCy Schubert { "fips!=yes", "fips!=yes" },
611*e0c4386eSCy Schubert { "fips = yes", "fips=yes" },
612*e0c4386eSCy Schubert { "fips", "fips=yes" },
613*e0c4386eSCy Schubert { "fips=no", "fips=no" },
614*e0c4386eSCy Schubert { "-fips", "-fips" },
615*e0c4386eSCy Schubert { "?fips=yes", "?fips=yes" },
616*e0c4386eSCy Schubert { "fips=yes,provider=fips", "fips=yes,provider=fips" },
617*e0c4386eSCy Schubert { "fips = yes , provider = fips", "fips=yes,provider=fips" },
618*e0c4386eSCy Schubert { "fips=yes,provider!=fips", "fips=yes,provider!=fips" },
619*e0c4386eSCy Schubert { "fips=yes,?provider=fips", "fips=yes,?provider=fips" },
620*e0c4386eSCy Schubert { "fips=yes,-provider", "fips=yes,-provider" },
621*e0c4386eSCy Schubert /* foo is an unknown internal name */
622*e0c4386eSCy Schubert { "foo=yes,fips=yes", "fips=yes"},
623*e0c4386eSCy Schubert { "", "" },
624*e0c4386eSCy Schubert { "fips=3", "fips=3" },
625*e0c4386eSCy Schubert { "fips=-3", "fips=-3" },
626*e0c4386eSCy Schubert { "provider='foo bar'", "provider='foo bar'" },
627*e0c4386eSCy Schubert { "provider=\"foo bar'\"", "provider=\"foo bar'\"" },
628*e0c4386eSCy Schubert { "provider=abc***", "provider='abc***'" },
629*e0c4386eSCy Schubert { NULL, "" }
630*e0c4386eSCy Schubert };
631*e0c4386eSCy Schubert
test_property_list_to_string(int i)632*e0c4386eSCy Schubert static int test_property_list_to_string(int i)
633*e0c4386eSCy Schubert {
634*e0c4386eSCy Schubert OSSL_PROPERTY_LIST *pl = NULL;
635*e0c4386eSCy Schubert int ret = 0;
636*e0c4386eSCy Schubert size_t bufsize;
637*e0c4386eSCy Schubert char *buf = NULL;
638*e0c4386eSCy Schubert
639*e0c4386eSCy Schubert if (to_string_tests[i].in != NULL
640*e0c4386eSCy Schubert && !TEST_ptr(pl = ossl_parse_query(NULL, to_string_tests[i].in, 1)))
641*e0c4386eSCy Schubert goto err;
642*e0c4386eSCy Schubert bufsize = ossl_property_list_to_string(NULL, pl, NULL, 0);
643*e0c4386eSCy Schubert if (!TEST_size_t_gt(bufsize, 0))
644*e0c4386eSCy Schubert goto err;
645*e0c4386eSCy Schubert buf = OPENSSL_malloc(bufsize);
646*e0c4386eSCy Schubert if (!TEST_ptr(buf)
647*e0c4386eSCy Schubert || !TEST_size_t_eq(ossl_property_list_to_string(NULL, pl, buf,
648*e0c4386eSCy Schubert bufsize),
649*e0c4386eSCy Schubert bufsize)
650*e0c4386eSCy Schubert || !TEST_str_eq(to_string_tests[i].out, buf)
651*e0c4386eSCy Schubert || !TEST_size_t_eq(bufsize, strlen(to_string_tests[i].out) + 1))
652*e0c4386eSCy Schubert goto err;
653*e0c4386eSCy Schubert
654*e0c4386eSCy Schubert ret = 1;
655*e0c4386eSCy Schubert err:
656*e0c4386eSCy Schubert OPENSSL_free(buf);
657*e0c4386eSCy Schubert ossl_property_free(pl);
658*e0c4386eSCy Schubert return ret;
659*e0c4386eSCy Schubert }
660*e0c4386eSCy Schubert
setup_tests(void)661*e0c4386eSCy Schubert int setup_tests(void)
662*e0c4386eSCy Schubert {
663*e0c4386eSCy Schubert ADD_TEST(test_property_string);
664*e0c4386eSCy Schubert ADD_TEST(test_property_query_value_create);
665*e0c4386eSCy Schubert ADD_ALL_TESTS(test_property_parse, OSSL_NELEM(parser_tests));
666*e0c4386eSCy Schubert ADD_ALL_TESTS(test_property_parse_error, OSSL_NELEM(parse_error_tests));
667*e0c4386eSCy Schubert ADD_ALL_TESTS(test_property_merge, OSSL_NELEM(merge_tests));
668*e0c4386eSCy Schubert ADD_TEST(test_property_defn_cache);
669*e0c4386eSCy Schubert ADD_ALL_TESTS(test_definition_compares, OSSL_NELEM(definition_tests));
670*e0c4386eSCy Schubert ADD_TEST(test_register_deregister);
671*e0c4386eSCy Schubert ADD_TEST(test_property);
672*e0c4386eSCy Schubert ADD_TEST(test_query_cache_stochastic);
673*e0c4386eSCy Schubert ADD_TEST(test_fips_mode);
674*e0c4386eSCy Schubert ADD_ALL_TESTS(test_property_list_to_string, OSSL_NELEM(to_string_tests));
675*e0c4386eSCy Schubert return 1;
676*e0c4386eSCy Schubert }
677