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