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