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