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