]>
Commit | Line | Data |
---|---|---|
9ad41d24 | 1 | /* |
a28d06f3 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
9ad41d24 RL |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * https://www.openssl.org/source/license.html | |
8 | * or in the file LICENSE in the source distribution. | |
9 | */ | |
10 | ||
11 | /* | |
12 | * This program tests the use of OSSL_PARAM, currently in raw form. | |
13 | */ | |
14 | ||
15 | #include <string.h> | |
16 | #include <openssl/bn.h> | |
17 | #include <openssl/core.h> | |
bc1e0be7 | 18 | #include <openssl/params.h> |
6251895c | 19 | #include "internal/numbers.h" |
9ad41d24 RL |
20 | #include "internal/nelem.h" |
21 | #include "testutil.h" | |
22 | ||
23 | /*- | |
24 | * PROVIDER SECTION | |
25 | * ================ | |
26 | * | |
27 | * Even though it's not necessarily ONLY providers doing this part, | |
28 | * they are naturally going to be the most common users of | |
29 | * set_params and get_params functions. | |
30 | */ | |
31 | ||
32 | /* | |
33 | * In real use cases, setters and getters would take an object with | |
34 | * which the parameters are associated. This structure is a cheap | |
35 | * simulation. | |
36 | */ | |
37 | struct object_st { | |
38 | /* | |
39 | * Documented as a native integer, of the size given by sizeof(int). | |
40 | * Assumed data type OSSL_PARAM_INTEGER | |
41 | */ | |
42 | int p1; | |
43 | /* | |
44 | * Documented as a native double, of the size given by sizeof(double). | |
45 | * Assumed data type OSSL_PARAM_REAL | |
46 | */ | |
47 | double p2; | |
48 | /* | |
49 | * Documented as an arbitrarly large unsigned integer. | |
c2969ff6 | 50 | * The data size must be large enough to accommodate. |
9ad41d24 RL |
51 | * Assumed data type OSSL_PARAM_UNSIGNED_INTEGER |
52 | */ | |
53 | BIGNUM *p3; | |
54 | /* | |
55 | * Documented as a C string. | |
c2969ff6 | 56 | * The data size must be large enough to accommodate. |
9ad41d24 RL |
57 | * Assumed data type OSSL_PARAM_UTF8_STRING |
58 | */ | |
59 | char *p4; | |
bc1e0be7 | 60 | size_t p4_l; |
fff68416 RL |
61 | /* |
62 | * Documented as a C string. | |
63 | * Assumed data type OSSL_PARAM_UTF8_STRING | |
64 | */ | |
65 | char p5[256]; | |
66 | size_t p5_l; | |
9ad41d24 RL |
67 | /* |
68 | * Documented as a pointer to a constant C string. | |
bc1e0be7 | 69 | * Assumed data type OSSL_PARAM_UTF8_PTR |
9ad41d24 | 70 | */ |
fff68416 RL |
71 | const char *p6; |
72 | size_t p6_l; | |
9ad41d24 RL |
73 | }; |
74 | ||
75 | #define p1_init 42 /* The ultimate answer */ | |
76 | #define p2_init 6.283 /* Magic number */ | |
77 | /* Stolen from evp_data, BLAKE2s256 test */ | |
78 | #define p3_init \ | |
79 | "4142434445464748494a4b4c4d4e4f50" \ | |
80 | "5152535455565758595a616263646566" \ | |
81 | "6768696a6b6c6d6e6f70717273747576" \ | |
82 | "7778797a30313233343536373839" | |
83 | #define p4_init "BLAKE2s256" /* Random string */ | |
fff68416 RL |
84 | #define p5_init "Hellow World" /* Random string */ |
85 | #define p6_init OPENSSL_FULL_VERSION_STR /* Static string */ | |
9ad41d24 RL |
86 | |
87 | static void cleanup_object(void *vobj) | |
88 | { | |
89 | struct object_st *obj = vobj; | |
90 | ||
91 | BN_free(obj->p3); | |
92 | obj->p3 = NULL; | |
93 | OPENSSL_free(obj->p4); | |
94 | obj->p4 = NULL; | |
95 | OPENSSL_free(obj); | |
96 | } | |
97 | ||
98 | static void *init_object(void) | |
99 | { | |
f06c5547 P |
100 | struct object_st *obj; |
101 | ||
102 | if (!TEST_ptr(obj = OPENSSL_zalloc(sizeof(*obj)))) | |
103 | return NULL; | |
9ad41d24 RL |
104 | |
105 | obj->p1 = p1_init; | |
106 | obj->p2 = p2_init; | |
107 | if (!TEST_true(BN_hex2bn(&obj->p3, p3_init))) | |
108 | goto fail; | |
109 | if (!TEST_ptr(obj->p4 = OPENSSL_strdup(p4_init))) | |
110 | goto fail; | |
fff68416 RL |
111 | strcpy(obj->p5, p5_init); |
112 | obj->p6 = p6_init; | |
9ad41d24 RL |
113 | |
114 | return obj; | |
115 | fail: | |
116 | cleanup_object(obj); | |
117 | obj = NULL; | |
118 | ||
119 | return NULL; | |
120 | } | |
121 | ||
122 | /* | |
123 | * RAW provider, which handles the parameters in a very raw manner, | |
124 | * with no fancy API and very minimal checking. The application that | |
125 | * calls these to set or request parameters MUST get its OSSL_PARAM | |
126 | * array right. | |
127 | */ | |
128 | ||
129 | static int raw_set_params(void *vobj, const OSSL_PARAM *params) | |
130 | { | |
131 | struct object_st *obj = vobj; | |
132 | ||
133 | for (; params->key != NULL; params++) | |
134 | if (strcmp(params->key, "p1") == 0) { | |
135 | obj->p1 = *(int *)params->data; | |
136 | } else if (strcmp(params->key, "p2") == 0) { | |
137 | obj->p2 = *(double *)params->data; | |
138 | } else if (strcmp(params->key, "p3") == 0) { | |
139 | BN_free(obj->p3); | |
140 | if (!TEST_ptr(obj->p3 = BN_native2bn(params->data, | |
141 | params->data_size, NULL))) | |
142 | return 0; | |
143 | } else if (strcmp(params->key, "p4") == 0) { | |
144 | OPENSSL_free(obj->p4); | |
145 | if (!TEST_ptr(obj->p4 = OPENSSL_strndup(params->data, | |
146 | params->data_size))) | |
147 | return 0; | |
247a1786 | 148 | obj->p4_l = strlen(obj->p4); |
9ad41d24 | 149 | } else if (strcmp(params->key, "p5") == 0) { |
247a1786 RL |
150 | /* |
151 | * Protect obj->p5 against too much data. This should not | |
152 | * happen, we don't use that long strings. | |
153 | */ | |
154 | size_t data_length = | |
155 | OPENSSL_strnlen(params->data, params->data_size); | |
156 | ||
157 | if (!TEST_size_t_lt(data_length, sizeof(obj->p5))) | |
158 | return 0; | |
159 | strncpy(obj->p5, params->data, data_length); | |
160 | obj->p5[data_length] = '\0'; | |
161 | obj->p5_l = strlen(obj->p5); | |
fff68416 RL |
162 | } else if (strcmp(params->key, "p6") == 0) { |
163 | obj->p6 = *(const char **)params->data; | |
bbcaef63 | 164 | obj->p6_l = params->data_size; |
9ad41d24 RL |
165 | } |
166 | ||
167 | return 1; | |
168 | } | |
169 | ||
4e7991b4 | 170 | static int raw_get_params(void *vobj, OSSL_PARAM *params) |
9ad41d24 RL |
171 | { |
172 | struct object_st *obj = vobj; | |
173 | ||
174 | for (; params->key != NULL; params++) | |
175 | if (strcmp(params->key, "p1") == 0) { | |
4e7991b4 | 176 | params->return_size = sizeof(obj->p1); |
9ad41d24 RL |
177 | *(int *)params->data = obj->p1; |
178 | } else if (strcmp(params->key, "p2") == 0) { | |
4e7991b4 | 179 | params->return_size = sizeof(obj->p2); |
9ad41d24 RL |
180 | *(double *)params->data = obj->p2; |
181 | } else if (strcmp(params->key, "p3") == 0) { | |
247a1786 RL |
182 | params->return_size = BN_num_bytes(obj->p3); |
183 | if (!TEST_size_t_ge(params->data_size, params->return_size)) | |
9ad41d24 | 184 | return 0; |
247a1786 | 185 | BN_bn2nativepad(obj->p3, params->data, params->return_size); |
9ad41d24 | 186 | } else if (strcmp(params->key, "p4") == 0) { |
247a1786 RL |
187 | params->return_size = strlen(obj->p4); |
188 | if (!TEST_size_t_gt(params->data_size, params->return_size)) | |
9ad41d24 RL |
189 | return 0; |
190 | strcpy(params->data, obj->p4); | |
191 | } else if (strcmp(params->key, "p5") == 0) { | |
247a1786 RL |
192 | params->return_size = strlen(obj->p5); |
193 | if (!TEST_size_t_gt(params->data_size, params->return_size)) | |
fff68416 RL |
194 | return 0; |
195 | strcpy(params->data, obj->p5); | |
196 | } else if (strcmp(params->key, "p6") == 0) { | |
247a1786 | 197 | params->return_size = strlen(obj->p6); |
fff68416 | 198 | *(const char **)params->data = obj->p6; |
9ad41d24 RL |
199 | } |
200 | ||
201 | return 1; | |
202 | } | |
203 | ||
bc1e0be7 RL |
204 | /* |
205 | * API provider, which handles the parameters using the API from params.h | |
206 | */ | |
207 | ||
208 | static int api_set_params(void *vobj, const OSSL_PARAM *params) | |
209 | { | |
210 | struct object_st *obj = vobj; | |
211 | const OSSL_PARAM *p = NULL; | |
212 | ||
4e7991b4 | 213 | if ((p = OSSL_PARAM_locate_const(params, "p1")) != NULL |
bc1e0be7 RL |
214 | && !TEST_true(OSSL_PARAM_get_int(p, &obj->p1))) |
215 | return 0; | |
4e7991b4 | 216 | if ((p = OSSL_PARAM_locate_const(params, "p2")) != NULL |
bc1e0be7 RL |
217 | && !TEST_true(OSSL_PARAM_get_double(p, &obj->p2))) |
218 | return 0; | |
4e7991b4 | 219 | if ((p = OSSL_PARAM_locate_const(params, "p3")) != NULL |
bc1e0be7 RL |
220 | && !TEST_true(OSSL_PARAM_get_BN(p, &obj->p3))) |
221 | return 0; | |
4e7991b4 | 222 | if ((p = OSSL_PARAM_locate_const(params, "p4")) != NULL) { |
bc1e0be7 RL |
223 | OPENSSL_free(obj->p4); |
224 | obj->p4 = NULL; | |
225 | /* If the value pointer is NULL, we get it automatically allocated */ | |
226 | if (!TEST_true(OSSL_PARAM_get_utf8_string(p, &obj->p4, 0))) | |
227 | return 0; | |
228 | } | |
4e7991b4 | 229 | if ((p = OSSL_PARAM_locate_const(params, "p5")) != NULL) { |
fff68416 RL |
230 | char *p5_ptr = obj->p5; |
231 | if (!TEST_true(OSSL_PARAM_get_utf8_string(p, &p5_ptr, sizeof(obj->p5)))) | |
232 | return 0; | |
247a1786 | 233 | obj->p5_l = strlen(obj->p5); |
bbcaef63 | 234 | } |
4e7991b4 | 235 | if ((p = OSSL_PARAM_locate_const(params, "p6")) != NULL) { |
bbcaef63 RL |
236 | if (!TEST_true(OSSL_PARAM_get_utf8_ptr(p, &obj->p6))) |
237 | return 0; | |
247a1786 | 238 | obj->p6_l = strlen(obj->p6); |
fff68416 | 239 | } |
bc1e0be7 RL |
240 | |
241 | return 1; | |
242 | } | |
243 | ||
4e7991b4 | 244 | static int api_get_params(void *vobj, OSSL_PARAM *params) |
bc1e0be7 RL |
245 | { |
246 | struct object_st *obj = vobj; | |
4e7991b4 | 247 | OSSL_PARAM *p = NULL; |
bc1e0be7 RL |
248 | |
249 | if ((p = OSSL_PARAM_locate(params, "p1")) != NULL | |
250 | && !TEST_true(OSSL_PARAM_set_int(p, obj->p1))) | |
251 | return 0; | |
252 | if ((p = OSSL_PARAM_locate(params, "p2")) != NULL | |
253 | && !TEST_true(OSSL_PARAM_set_double(p, obj->p2))) | |
254 | return 0; | |
255 | if ((p = OSSL_PARAM_locate(params, "p3")) != NULL | |
256 | && !TEST_true(OSSL_PARAM_set_BN(p, obj->p3))) | |
257 | return 0; | |
258 | if ((p = OSSL_PARAM_locate(params, "p4")) != NULL | |
259 | && !TEST_true(OSSL_PARAM_set_utf8_string(p, obj->p4))) | |
260 | return 0; | |
261 | if ((p = OSSL_PARAM_locate(params, "p5")) != NULL | |
fff68416 RL |
262 | && !TEST_true(OSSL_PARAM_set_utf8_string(p, obj->p5))) |
263 | return 0; | |
264 | if ((p = OSSL_PARAM_locate(params, "p6")) != NULL | |
265 | && !TEST_true(OSSL_PARAM_set_utf8_ptr(p, obj->p6))) | |
bc1e0be7 RL |
266 | return 0; |
267 | ||
268 | return 1; | |
269 | } | |
270 | ||
9ad41d24 RL |
271 | /* |
272 | * This structure only simulates a provider dispatch, the real deal is | |
273 | * a bit more code that's not necessary in these tests. | |
274 | */ | |
275 | struct provider_dispatch_st { | |
276 | int (*set_params)(void *obj, const OSSL_PARAM *params); | |
4e7991b4 | 277 | int (*get_params)(void *obj, OSSL_PARAM *params); |
9ad41d24 RL |
278 | }; |
279 | ||
280 | /* "raw" provider */ | |
281 | static const struct provider_dispatch_st provider_raw = { | |
282 | raw_set_params, raw_get_params | |
283 | }; | |
284 | ||
bc1e0be7 RL |
285 | /* "api" provider */ |
286 | static const struct provider_dispatch_st provider_api = { | |
287 | api_set_params, api_get_params | |
288 | }; | |
289 | ||
9ad41d24 RL |
290 | /*- |
291 | * APPLICATION SECTION | |
292 | * =================== | |
293 | */ | |
294 | ||
295 | /* In all our tests, these are variables that get manipulated as parameters | |
296 | * | |
c2969ff6 | 297 | * These arrays consistently do nothing with the "p2" parameter, and |
9ad41d24 RL |
298 | * always include a "foo" parameter. This is to check that the |
299 | * set_params and get_params calls ignore the lack of parameters that | |
300 | * the application isn't interested in, as well as ignore parameters | |
301 | * they don't understand (the application may have one big bag of | |
302 | * parameters). | |
303 | */ | |
304 | static int app_p1; /* "p1" */ | |
305 | static double app_p2; /* "p2" is ignored */ | |
306 | static BIGNUM *app_p3 = NULL; /* "p3" */ | |
307 | static unsigned char bignumbin[4096]; /* "p3" */ | |
9ad41d24 | 308 | static char app_p4[256]; /* "p4" */ |
fff68416 | 309 | static char app_p5[256]; /* "p5" */ |
fff68416 | 310 | static const char *app_p6 = NULL; /* "p6" */ |
9ad41d24 | 311 | static unsigned char foo[1]; /* "foo" */ |
9ad41d24 RL |
312 | |
313 | #define app_p1_init 17 /* A random number */ | |
314 | #define app_p2_init 47.11 /* Another random number */ | |
315 | #define app_p3_init "deadbeef" /* Classic */ | |
316 | #define app_p4_init "Hello" | |
317 | #define app_p5_init "World" | |
fff68416 | 318 | #define app_p6_init "Cookie" |
9ad41d24 RL |
319 | #define app_foo_init 'z' |
320 | ||
321 | static int cleanup_app_variables(void) | |
322 | { | |
323 | BN_free(app_p3); | |
324 | app_p3 = NULL; | |
325 | return 1; | |
326 | } | |
327 | ||
328 | static int init_app_variables(void) | |
329 | { | |
330 | int l = 0; | |
331 | ||
332 | cleanup_app_variables(); | |
333 | ||
334 | app_p1 = app_p1_init; | |
335 | app_p2 = app_p2_init; | |
336 | if (!BN_hex2bn(&app_p3, app_p3_init) | |
337 | || (l = BN_bn2nativepad(app_p3, bignumbin, sizeof(bignumbin))) < 0) | |
338 | return 0; | |
9ad41d24 | 339 | strcpy(app_p4, app_p4_init); |
fff68416 | 340 | strcpy(app_p5, app_p5_init); |
fff68416 | 341 | app_p6 = app_p6_init; |
9ad41d24 | 342 | foo[0] = app_foo_init; |
9ad41d24 RL |
343 | |
344 | return 1; | |
345 | } | |
346 | ||
347 | /* | |
348 | * Here, we define test OSSL_PARAM arrays | |
349 | */ | |
350 | ||
351 | /* An array of OSSL_PARAM, specific in the most raw manner possible */ | |
4e7991b4 P |
352 | static OSSL_PARAM static_raw_params[] = { |
353 | { "p1", OSSL_PARAM_INTEGER, &app_p1, sizeof(app_p1), 0 }, | |
354 | { "p3", OSSL_PARAM_UNSIGNED_INTEGER, &bignumbin, sizeof(bignumbin), 0 }, | |
355 | { "p4", OSSL_PARAM_UTF8_STRING, &app_p4, sizeof(app_p4), 0 }, | |
356 | { "p5", OSSL_PARAM_UTF8_STRING, &app_p5, sizeof(app_p5), 0 }, | |
247a1786 RL |
357 | /* sizeof(app_p6_init) - 1, because we know that's what we're using */ |
358 | { "p6", OSSL_PARAM_UTF8_PTR, &app_p6, sizeof(app_p6_init) - 1, 0 }, | |
4e7991b4 P |
359 | { "foo", OSSL_PARAM_OCTET_STRING, &foo, sizeof(foo), 0 }, |
360 | { NULL, 0, NULL, 0, 0 } | |
9ad41d24 RL |
361 | }; |
362 | ||
bc1e0be7 | 363 | /* The same array of OSSL_PARAM, specified with the macros from params.h */ |
4e7991b4 | 364 | static OSSL_PARAM static_api_params[] = { |
bc1e0be7 | 365 | OSSL_PARAM_int("p1", &app_p1), |
4e7991b4 P |
366 | OSSL_PARAM_BN("p3", &bignumbin, sizeof(bignumbin)), |
367 | OSSL_PARAM_DEFN("p4", OSSL_PARAM_UTF8_STRING, &app_p4, sizeof(app_p4)), | |
368 | OSSL_PARAM_DEFN("p5", OSSL_PARAM_UTF8_STRING, &app_p5, sizeof(app_p5)), | |
bbcaef63 | 369 | /* sizeof(app_p6_init), because we know that's what we're using */ |
247a1786 RL |
370 | OSSL_PARAM_DEFN("p6", OSSL_PARAM_UTF8_PTR, &app_p6, |
371 | sizeof(app_p6_init) - 1), | |
4e7991b4 | 372 | OSSL_PARAM_DEFN("foo", OSSL_PARAM_OCTET_STRING, &foo, sizeof(foo)), |
bc1e0be7 RL |
373 | OSSL_PARAM_END |
374 | }; | |
375 | ||
fff68416 RL |
376 | /* |
377 | * The same array again, but constructed at run-time | |
378 | * This exercises the OSSL_PARAM constructor functions | |
379 | */ | |
84727507 | 380 | static OSSL_PARAM *construct_api_params(void) |
fff68416 RL |
381 | { |
382 | size_t n = 0; | |
383 | static OSSL_PARAM params[10]; | |
fff68416 | 384 | |
4e7991b4 P |
385 | params[n++] = OSSL_PARAM_construct_int("p1", &app_p1); |
386 | params[n++] = OSSL_PARAM_construct_BN("p3", bignumbin, sizeof(bignumbin)); | |
387 | params[n++] = OSSL_PARAM_construct_utf8_string("p4", app_p4, | |
388 | sizeof(app_p4)); | |
fff68416 | 389 | params[n++] = OSSL_PARAM_construct_utf8_string("p5", app_p5, |
4e7991b4 | 390 | sizeof(app_p5)); |
bbcaef63 | 391 | /* sizeof(app_p6_init), because we know that's what we're using */ |
fff68416 | 392 | params[n++] = OSSL_PARAM_construct_utf8_ptr("p6", (char **)&app_p6, |
4e7991b4 P |
393 | sizeof(app_p6_init)); |
394 | params[n++] = OSSL_PARAM_construct_octet_string("foo", &foo, sizeof(foo)); | |
195852fe | 395 | params[n++] = OSSL_PARAM_construct_end(); |
fff68416 RL |
396 | |
397 | return params; | |
398 | } | |
399 | ||
400 | struct param_owner_st { | |
4e7991b4 | 401 | OSSL_PARAM *static_params; |
fff68416 RL |
402 | OSSL_PARAM *(*constructed_params)(void); |
403 | }; | |
404 | ||
932c3d0f | 405 | static const struct param_owner_st raw_params = { |
fff68416 RL |
406 | static_raw_params, NULL |
407 | }; | |
408 | ||
932c3d0f | 409 | static const struct param_owner_st api_params = { |
fff68416 RL |
410 | static_api_params, construct_api_params |
411 | }; | |
412 | ||
9ad41d24 RL |
413 | /*- |
414 | * TESTING | |
415 | * ======= | |
416 | */ | |
417 | ||
418 | /* | |
419 | * Test cases to combine parameters with "provider side" functions | |
420 | */ | |
421 | static struct { | |
422 | const struct provider_dispatch_st *prov; | |
fff68416 | 423 | const struct param_owner_st *app; |
9ad41d24 RL |
424 | const char *desc; |
425 | } test_cases[] = { | |
bc1e0be7 | 426 | /* Tests within specific methods */ |
fff68416 RL |
427 | { &provider_raw, &raw_params, "raw provider vs raw params" }, |
428 | { &provider_api, &api_params, "api provider vs api params" }, | |
bc1e0be7 RL |
429 | |
430 | /* Mixed methods */ | |
fff68416 RL |
431 | { &provider_raw, &api_params, "raw provider vs api params" }, |
432 | { &provider_api, &raw_params, "api provider vs raw params" }, | |
9ad41d24 RL |
433 | }; |
434 | ||
435 | /* Generic tester of combinations of "providers" and params */ | |
4e7991b4 | 436 | static int test_case_variant(OSSL_PARAM *params, const struct provider_dispatch_st *prov) |
9ad41d24 | 437 | { |
9ad41d24 RL |
438 | BIGNUM *verify_p3 = NULL; |
439 | void *obj = NULL; | |
440 | int errcnt = 0; | |
4e7991b4 | 441 | OSSL_PARAM *p; |
9ad41d24 | 442 | |
9ad41d24 RL |
443 | /* |
444 | * Initialize | |
445 | */ | |
446 | if (!TEST_ptr(obj = init_object()) | |
447 | || !TEST_true(BN_hex2bn(&verify_p3, p3_init))) { | |
448 | errcnt++; | |
449 | goto fin; | |
450 | } | |
451 | ||
452 | /* | |
453 | * Get parameters a first time, just to see that getting works and | |
454 | * gets us the values we expect. | |
455 | */ | |
456 | init_app_variables(); | |
457 | ||
458 | if (!TEST_true(prov->get_params(obj, params)) | |
459 | || !TEST_int_eq(app_p1, p1_init) /* "provider" value */ | |
d3620841 | 460 | || !TEST_double_eq(app_p2, app_p2_init) /* Should remain untouched */ |
edc62356 P |
461 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p3")) |
462 | || !TEST_ptr(BN_native2bn(bignumbin, p->return_size, app_p3)) | |
9ad41d24 RL |
463 | || !TEST_BN_eq(app_p3, verify_p3) /* "provider" value */ |
464 | || !TEST_str_eq(app_p4, p4_init) /* "provider" value */ | |
4e7991b4 | 465 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p5")) |
247a1786 RL |
466 | || !TEST_size_t_eq(p->return_size, |
467 | sizeof(p5_init) - 1) /* "provider" value */ | |
9ad41d24 | 468 | || !TEST_str_eq(app_p5, p5_init) /* "provider" value */ |
4e7991b4 | 469 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p6")) |
247a1786 RL |
470 | || !TEST_size_t_eq(p->return_size, |
471 | sizeof(p6_init) - 1) /* "provider" value */ | |
fff68416 | 472 | || !TEST_str_eq(app_p6, p6_init) /* "provider" value */ |
9ad41d24 | 473 | || !TEST_char_eq(foo[0], app_foo_init) /* Should remain untouched */ |
8d5fb648 | 474 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo"))) |
9ad41d24 RL |
475 | errcnt++; |
476 | ||
477 | /* | |
478 | * Set parameters, then sneak into the object itself and check | |
479 | * that its attributes got set (or ignored) properly. | |
480 | */ | |
481 | init_app_variables(); | |
482 | ||
483 | if (!TEST_true(prov->set_params(obj, params))) { | |
484 | errcnt++; | |
485 | } else { | |
486 | struct object_st *sneakpeek = obj; | |
487 | ||
488 | if (!TEST_int_eq(sneakpeek->p1, app_p1) /* app value set */ | |
d3620841 | 489 | || !TEST_double_eq(sneakpeek->p2, p2_init) /* Should remain untouched */ |
9ad41d24 RL |
490 | || !TEST_BN_eq(sneakpeek->p3, app_p3) /* app value set */ |
491 | || !TEST_str_eq(sneakpeek->p4, app_p4) /* app value set */ | |
bbcaef63 | 492 | || !TEST_str_eq(sneakpeek->p5, app_p5) /* app value set */ |
bbcaef63 | 493 | || !TEST_str_eq(sneakpeek->p6, app_p6)) /* app value set */ |
9ad41d24 RL |
494 | errcnt++; |
495 | } | |
496 | ||
497 | /* | |
498 | * Get parameters again, checking that we get different values | |
499 | * than earlier where relevant. | |
500 | */ | |
501 | BN_free(verify_p3); | |
502 | verify_p3 = NULL; | |
503 | ||
504 | if (!TEST_true(BN_hex2bn(&verify_p3, app_p3_init))) { | |
505 | errcnt++; | |
506 | goto fin; | |
507 | } | |
508 | ||
509 | if (!TEST_true(prov->get_params(obj, params)) | |
510 | || !TEST_int_eq(app_p1, app_p1_init) /* app value */ | |
d3620841 | 511 | || !TEST_double_eq(app_p2, app_p2_init) /* Should remain untouched */ |
edc62356 P |
512 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p3")) |
513 | || !TEST_ptr(BN_native2bn(bignumbin, p->return_size, app_p3)) | |
9ad41d24 RL |
514 | || !TEST_BN_eq(app_p3, verify_p3) /* app value */ |
515 | || !TEST_str_eq(app_p4, app_p4_init) /* app value */ | |
4e7991b4 P |
516 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p5")) |
517 | || !TEST_size_t_eq(p->return_size, | |
247a1786 | 518 | sizeof(app_p5_init) - 1) /* app value */ |
9ad41d24 | 519 | || !TEST_str_eq(app_p5, app_p5_init) /* app value */ |
4e7991b4 P |
520 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "p6")) |
521 | || !TEST_size_t_eq(p->return_size, | |
247a1786 | 522 | sizeof(app_p6_init) - 1) /* app value */ |
fff68416 | 523 | || !TEST_str_eq(app_p6, app_p6_init) /* app value */ |
9ad41d24 | 524 | || !TEST_char_eq(foo[0], app_foo_init) /* Should remain untouched */ |
8d5fb648 | 525 | || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo"))) |
9ad41d24 RL |
526 | errcnt++; |
527 | ||
528 | fin: | |
529 | BN_free(verify_p3); | |
530 | verify_p3 = NULL; | |
531 | cleanup_app_variables(); | |
532 | cleanup_object(obj); | |
533 | ||
534 | return errcnt == 0; | |
535 | } | |
536 | ||
fff68416 RL |
537 | static int test_case(int i) |
538 | { | |
539 | TEST_info("Case: %s", test_cases[i].desc); | |
540 | ||
541 | return test_case_variant(test_cases[i].app->static_params, | |
542 | test_cases[i].prov) | |
543 | && (test_cases[i].app->constructed_params == NULL | |
544 | || test_case_variant(test_cases[i].app->constructed_params(), | |
545 | test_cases[i].prov)); | |
546 | } | |
547 | ||
604b86d8 PG |
548 | /*- |
549 | * OSSL_PARAM_allocate_from_text() tests | |
550 | * ===================================== | |
551 | */ | |
552 | ||
553 | static const OSSL_PARAM params_from_text[] = { | |
554 | OSSL_PARAM_int32("int", NULL), | |
555 | OSSL_PARAM_DEFN("short", OSSL_PARAM_INTEGER, NULL, sizeof(int16_t)), | |
556 | OSSL_PARAM_DEFN("ushort", OSSL_PARAM_UNSIGNED_INTEGER, NULL, sizeof(uint16_t)), | |
557 | OSSL_PARAM_END, | |
558 | }; | |
559 | ||
560 | struct int_from_text_test_st { | |
561 | const char *argname; | |
562 | const char *strval; | |
563 | long int intval; | |
564 | int res; | |
565 | }; | |
566 | ||
567 | static struct int_from_text_test_st int_from_text_test_cases[] = { | |
568 | { "int", "", 0, 0 }, | |
569 | { "int", "0", 0, 1 }, | |
570 | { "int", "101", 101, 1 }, | |
571 | { "int", "-102", -102, 1 }, | |
572 | { "int", "12A", 12, 1 }, /* incomplete */ | |
573 | { "int", "0x12B", 0x12B, 1 }, | |
574 | { "hexint", "12C", 0x12C, 1 }, | |
575 | { "hexint", "0x12D", 0, 1 }, /* zero */ | |
576 | /* test check of the target buffer size */ | |
577 | { "int", "0x7fffffff", INT32_MAX, 1 }, | |
578 | { "int", "2147483647", INT32_MAX, 1 }, | |
579 | { "int", "2147483648", 0, 0 }, /* too small buffer */ | |
580 | { "int", "-2147483648", INT32_MIN, 1 }, | |
581 | { "int", "-2147483649", 0, 0 }, /* too small buffer */ | |
582 | { "short", "0x7fff", INT16_MAX, 1 }, | |
583 | { "short", "32767", INT16_MAX, 1 }, | |
584 | { "short", "32768", 0, 0 }, /* too small buffer */ | |
585 | { "ushort", "0xffff", UINT16_MAX, 1 }, | |
586 | { "ushort", "65535", UINT16_MAX, 1 }, | |
587 | { "ushort", "65536", 0, 0 }, /* too small buffer */ | |
588 | }; | |
589 | ||
590 | static int check_int_from_text(const struct int_from_text_test_st a) | |
591 | { | |
592 | OSSL_PARAM param; | |
593 | long int val = 0; | |
594 | int res; | |
595 | ||
596 | if (!OSSL_PARAM_allocate_from_text(¶m, params_from_text, | |
597 | a.argname, a.strval, 0, NULL)) { | |
598 | if (a.res) | |
599 | TEST_error("errant %s param \"%s\"", a.argname, a.strval); | |
600 | return !a.res; | |
601 | } | |
602 | ||
603 | res = OSSL_PARAM_get_long(¶m, &val); | |
604 | OPENSSL_free(param.data); | |
605 | ||
606 | if (res ^ a.res || val != a.intval) { | |
607 | TEST_error("errant %s \"%s\" %li != %li", | |
608 | a.argname, a.strval, a.intval, val); | |
609 | return 0; | |
610 | } | |
611 | ||
612 | return a.res; | |
613 | } | |
614 | ||
615 | static int test_allocate_from_text(int i) | |
616 | { | |
617 | return check_int_from_text(int_from_text_test_cases[i]); | |
618 | } | |
619 | ||
9ad41d24 RL |
620 | int setup_tests(void) |
621 | { | |
622 | ADD_ALL_TESTS(test_case, OSSL_NELEM(test_cases)); | |
604b86d8 | 623 | ADD_ALL_TESTS(test_allocate_from_text, OSSL_NELEM(int_from_text_test_cases)); |
9ad41d24 RL |
624 | return 1; |
625 | } |