1 /* 2 * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stddef.h> 11 #include <string.h> 12 #include <openssl/provider.h> 13 #include <openssl/params.h> 14 #include <openssl/core_names.h> 15 #include <openssl/evp.h> 16 #include <openssl/store.h> 17 #include <openssl/ui.h> 18 #include "testutil.h" 19 #include "fake_rsaprov.h" 20 21 static OSSL_LIB_CTX *libctx = NULL; 22 extern int key_deleted; /* From fake_rsaprov.c */ 23 24 /* Fetch SIGNATURE method using a libctx and propq */ 25 static int fetch_sig(OSSL_LIB_CTX *ctx, const char *alg, const char *propq, 26 OSSL_PROVIDER *expected_prov) 27 { 28 OSSL_PROVIDER *prov; 29 EVP_SIGNATURE *sig = EVP_SIGNATURE_fetch(ctx, "RSA", propq); 30 int ret = 0; 31 32 if (!TEST_ptr(sig)) 33 return 0; 34 35 if (!TEST_ptr(prov = EVP_SIGNATURE_get0_provider(sig))) 36 goto end; 37 38 if (!TEST_ptr_eq(prov, expected_prov)) { 39 TEST_info("Fetched provider: %s, Expected provider: %s", 40 OSSL_PROVIDER_get0_name(prov), 41 OSSL_PROVIDER_get0_name(expected_prov)); 42 goto end; 43 } 44 45 ret = 1; 46 end: 47 EVP_SIGNATURE_free(sig); 48 return ret; 49 } 50 51 52 static int test_pkey_sig(void) 53 { 54 OSSL_PROVIDER *deflt = NULL; 55 OSSL_PROVIDER *fake_rsa = NULL; 56 int i, ret = 0; 57 EVP_PKEY *pkey = NULL; 58 EVP_PKEY_CTX *ctx = NULL; 59 60 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 61 return 0; 62 63 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 64 goto end; 65 66 /* Do a direct fetch to see it works */ 67 if (!TEST_true(fetch_sig(libctx, "RSA", "provider=fake-rsa", fake_rsa)) 68 || !TEST_true(fetch_sig(libctx, "RSA", "?provider=fake-rsa", fake_rsa))) 69 goto end; 70 71 /* Construct a pkey using precise propq to use our provider */ 72 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 73 "provider=fake-rsa")) 74 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 75 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, NULL)) 76 || !TEST_ptr(pkey)) 77 goto end; 78 79 EVP_PKEY_CTX_free(ctx); 80 ctx = NULL; 81 82 /* try exercising signature_init ops a few times */ 83 for (i = 0; i < 3; i++) { 84 size_t siglen; 85 86 /* 87 * Create a signing context for our pkey with optional propq. 88 * The sign init should pick both keymgmt and signature from 89 * fake-rsa as the key is not exportable. 90 */ 91 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, 92 "?provider=default"))) 93 goto end; 94 95 /* 96 * If this picks the wrong signature without realizing it 97 * we can get a segfault or some internal error. At least watch 98 * whether fake-rsa sign_init is exercised by calling sign. 99 */ 100 if (!TEST_int_eq(EVP_PKEY_sign_init(ctx), 1)) 101 goto end; 102 103 if (!TEST_int_eq(EVP_PKEY_sign(ctx, NULL, &siglen, NULL, 0), 1) 104 || !TEST_size_t_eq(siglen, 256)) 105 goto end; 106 107 EVP_PKEY_CTX_free(ctx); 108 ctx = NULL; 109 } 110 111 ret = 1; 112 113 end: 114 fake_rsa_finish(fake_rsa); 115 OSSL_PROVIDER_unload(deflt); 116 EVP_PKEY_CTX_free(ctx); 117 EVP_PKEY_free(pkey); 118 return ret; 119 } 120 121 static int test_alternative_keygen_init(void) 122 { 123 EVP_PKEY_CTX *ctx = NULL; 124 OSSL_PROVIDER *deflt = NULL; 125 OSSL_PROVIDER *fake_rsa = NULL; 126 const OSSL_PROVIDER *provider; 127 const char *provname; 128 int ret = 0; 129 130 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 131 goto end; 132 133 /* first try without the fake RSA provider loaded */ 134 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL))) 135 goto end; 136 137 if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)) 138 goto end; 139 140 if (!TEST_ptr(provider = EVP_PKEY_CTX_get0_provider(ctx))) 141 goto end; 142 143 if (!TEST_ptr(provname = OSSL_PROVIDER_get0_name(provider))) 144 goto end; 145 146 if (!TEST_str_eq(provname, "default")) 147 goto end; 148 149 EVP_PKEY_CTX_free(ctx); 150 ctx = NULL; 151 152 /* now load fake RSA and try again */ 153 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 154 return 0; 155 156 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 157 "?provider=fake-rsa"))) 158 goto end; 159 160 if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)) 161 goto end; 162 163 if (!TEST_ptr(provider = EVP_PKEY_CTX_get0_provider(ctx))) 164 goto end; 165 166 if (!TEST_ptr(provname = OSSL_PROVIDER_get0_name(provider))) 167 goto end; 168 169 if (!TEST_str_eq(provname, "fake-rsa")) 170 goto end; 171 172 ret = 1; 173 174 end: 175 fake_rsa_finish(fake_rsa); 176 OSSL_PROVIDER_unload(deflt); 177 EVP_PKEY_CTX_free(ctx); 178 return ret; 179 } 180 181 static int test_pkey_eq(void) 182 { 183 OSSL_PROVIDER *deflt = NULL; 184 OSSL_PROVIDER *fake_rsa = NULL; 185 EVP_PKEY *pkey_fake = NULL; 186 EVP_PKEY *pkey_dflt = NULL; 187 EVP_PKEY_CTX *ctx = NULL; 188 OSSL_PARAM *params = NULL; 189 int ret = 0; 190 191 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 192 return 0; 193 194 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 195 goto end; 196 197 /* Construct a public key for fake-rsa */ 198 if (!TEST_ptr(params = fake_rsa_key_params(0)) 199 || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 200 "provider=fake-rsa")) 201 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 202 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY, 203 params)) 204 || !TEST_ptr(pkey_fake)) 205 goto end; 206 207 EVP_PKEY_CTX_free(ctx); 208 ctx = NULL; 209 OSSL_PARAM_free(params); 210 params = NULL; 211 212 /* Construct a public key for default */ 213 if (!TEST_ptr(params = fake_rsa_key_params(0)) 214 || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 215 "provider=default")) 216 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 217 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_dflt, EVP_PKEY_PUBLIC_KEY, 218 params)) 219 || !TEST_ptr(pkey_dflt)) 220 goto end; 221 222 EVP_PKEY_CTX_free(ctx); 223 ctx = NULL; 224 OSSL_PARAM_free(params); 225 params = NULL; 226 227 /* now test for equality */ 228 if (!TEST_int_eq(EVP_PKEY_eq(pkey_fake, pkey_dflt), 1)) 229 goto end; 230 231 ret = 1; 232 end: 233 fake_rsa_finish(fake_rsa); 234 OSSL_PROVIDER_unload(deflt); 235 EVP_PKEY_CTX_free(ctx); 236 EVP_PKEY_free(pkey_fake); 237 EVP_PKEY_free(pkey_dflt); 238 OSSL_PARAM_free(params); 239 return ret; 240 } 241 242 static int test_pkey_store(int idx) 243 { 244 OSSL_PROVIDER *deflt = NULL; 245 OSSL_PROVIDER *fake_rsa = NULL; 246 int ret = 0; 247 EVP_PKEY *pkey = NULL; 248 OSSL_STORE_LOADER *loader = NULL; 249 OSSL_STORE_CTX *ctx = NULL; 250 OSSL_STORE_INFO *info; 251 const char *propq = idx == 0 ? "?provider=fake-rsa" 252 : "?provider=default"; 253 254 /* It's important to load the default provider first for this test */ 255 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 256 goto end; 257 258 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 259 goto end; 260 261 if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", 262 propq))) 263 goto end; 264 265 OSSL_STORE_LOADER_free(loader); 266 267 if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, 268 NULL, NULL, NULL, NULL, NULL))) 269 goto end; 270 271 while (!OSSL_STORE_eof(ctx) 272 && (info = OSSL_STORE_load(ctx)) != NULL 273 && pkey == NULL) { 274 if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) 275 pkey = OSSL_STORE_INFO_get1_PKEY(info); 276 OSSL_STORE_INFO_free(info); 277 info = NULL; 278 } 279 280 if (!TEST_ptr(pkey) || !TEST_int_eq(EVP_PKEY_is_a(pkey, "RSA"), 1)) 281 goto end; 282 283 ret = 1; 284 285 end: 286 fake_rsa_finish(fake_rsa); 287 OSSL_PROVIDER_unload(deflt); 288 OSSL_STORE_close(ctx); 289 EVP_PKEY_free(pkey); 290 return ret; 291 } 292 293 static int test_pkey_delete(void) 294 { 295 OSSL_PROVIDER *deflt = NULL; 296 OSSL_PROVIDER *fake_rsa = NULL; 297 int ret = 0; 298 EVP_PKEY *pkey = NULL; 299 OSSL_STORE_LOADER *loader = NULL; 300 OSSL_STORE_CTX *ctx = NULL; 301 OSSL_STORE_INFO *info; 302 const char *propq = "?provider=fake-rsa"; 303 304 /* It's important to load the default provider first for this test */ 305 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 306 goto end; 307 308 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 309 goto end; 310 311 if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", 312 propq))) 313 goto end; 314 315 OSSL_STORE_LOADER_free(loader); 316 317 /* First iteration: load key, check it, delete it */ 318 if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, 319 NULL, NULL, NULL, NULL, NULL))) 320 goto end; 321 322 while (!OSSL_STORE_eof(ctx) 323 && (info = OSSL_STORE_load(ctx)) != NULL 324 && pkey == NULL) { 325 if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) 326 pkey = OSSL_STORE_INFO_get1_PKEY(info); 327 OSSL_STORE_INFO_free(info); 328 info = NULL; 329 } 330 331 if (!TEST_ptr(pkey) || !TEST_int_eq(EVP_PKEY_is_a(pkey, "RSA"), 1)) 332 goto end; 333 EVP_PKEY_free(pkey); 334 pkey = NULL; 335 336 if (!TEST_int_eq(OSSL_STORE_delete("fake_rsa:test", libctx, propq, 337 NULL, NULL, NULL), 1)) 338 goto end; 339 if (!TEST_int_eq(OSSL_STORE_close(ctx), 1)) 340 goto end; 341 342 /* Second iteration: load key should fail */ 343 if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, 344 NULL, NULL, NULL, NULL, NULL))) 345 goto end; 346 347 while (!OSSL_STORE_eof(ctx)) { 348 info = OSSL_STORE_load(ctx); 349 if (!TEST_ptr_null(info)) 350 goto end; 351 } 352 353 ret = 1; 354 355 end: 356 fake_rsa_finish(fake_rsa); 357 OSSL_PROVIDER_unload(deflt); 358 OSSL_STORE_close(ctx); 359 fake_rsa_restore_store_state(); 360 return ret; 361 } 362 363 static int fake_pw_read_string(UI *ui, UI_STRING *uis) 364 { 365 const char *passphrase = FAKE_PASSPHRASE; 366 367 if (UI_get_string_type(uis) == UIT_PROMPT) { 368 UI_set_result(ui, uis, passphrase); 369 return 1; 370 } 371 372 return 0; 373 } 374 375 static int test_pkey_store_open_ex(void) 376 { 377 OSSL_PROVIDER *deflt = NULL; 378 OSSL_PROVIDER *fake_rsa = NULL; 379 int ret = 0; 380 EVP_PKEY *pkey = NULL; 381 OSSL_STORE_LOADER *loader = NULL; 382 OSSL_STORE_CTX *ctx = NULL; 383 const char *propq = "?provider=fake-rsa"; 384 UI_METHOD *ui_method = NULL; 385 386 /* It's important to load the default provider first for this test */ 387 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 388 goto end; 389 390 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 391 goto end; 392 393 if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", 394 propq))) 395 goto end; 396 397 OSSL_STORE_LOADER_free(loader); 398 399 if (!TEST_ptr(ui_method= UI_create_method("PW Callbacks"))) 400 goto end; 401 402 if (UI_method_set_reader(ui_method, fake_pw_read_string)) 403 goto end; 404 405 if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, propq, 406 ui_method, NULL, NULL, NULL, NULL))) 407 goto end; 408 409 /* retry w/o ui_method to ensure we actually enter pw checks and fail */ 410 OSSL_STORE_close(ctx); 411 if (!TEST_ptr_null(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, 412 propq, NULL, NULL, NULL, NULL, 413 NULL))) 414 goto end; 415 416 ret = 1; 417 418 end: 419 UI_destroy_method(ui_method); 420 fake_rsa_finish(fake_rsa); 421 OSSL_PROVIDER_unload(deflt); 422 OSSL_STORE_close(ctx); 423 EVP_PKEY_free(pkey); 424 return ret; 425 } 426 427 int setup_tests(void) 428 { 429 libctx = OSSL_LIB_CTX_new(); 430 if (libctx == NULL) 431 return 0; 432 433 ADD_TEST(test_pkey_sig); 434 ADD_TEST(test_alternative_keygen_init); 435 ADD_TEST(test_pkey_eq); 436 ADD_ALL_TESTS(test_pkey_store, 2); 437 ADD_TEST(test_pkey_delete); 438 ADD_TEST(test_pkey_store_open_ex); 439 440 return 1; 441 } 442 443 void cleanup_tests(void) 444 { 445 OSSL_LIB_CTX_free(libctx); 446 } 447