1 /* 2 * Copyright 2021-2022 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 "testutil.h" 18 #include "fake_rsaprov.h" 19 20 static OSSL_LIB_CTX *libctx = NULL; 21 22 /* Fetch SIGNATURE method using a libctx and propq */ 23 static int fetch_sig(OSSL_LIB_CTX *ctx, const char *alg, const char *propq, 24 OSSL_PROVIDER *expected_prov) 25 { 26 OSSL_PROVIDER *prov; 27 EVP_SIGNATURE *sig = EVP_SIGNATURE_fetch(ctx, "RSA", propq); 28 int ret = 0; 29 30 if (!TEST_ptr(sig)) 31 return 0; 32 33 if (!TEST_ptr(prov = EVP_SIGNATURE_get0_provider(sig))) 34 goto end; 35 36 if (!TEST_ptr_eq(prov, expected_prov)) { 37 TEST_info("Fetched provider: %s, Expected provider: %s", 38 OSSL_PROVIDER_get0_name(prov), 39 OSSL_PROVIDER_get0_name(expected_prov)); 40 goto end; 41 } 42 43 ret = 1; 44 end: 45 EVP_SIGNATURE_free(sig); 46 return ret; 47 } 48 49 50 static int test_pkey_sig(void) 51 { 52 OSSL_PROVIDER *deflt = NULL; 53 OSSL_PROVIDER *fake_rsa = NULL; 54 int i, ret = 0; 55 EVP_PKEY *pkey = NULL; 56 EVP_PKEY_CTX *ctx = NULL; 57 58 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 59 return 0; 60 61 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 62 goto end; 63 64 /* Do a direct fetch to see it works */ 65 if (!TEST_true(fetch_sig(libctx, "RSA", "provider=fake-rsa", fake_rsa)) 66 || !TEST_true(fetch_sig(libctx, "RSA", "?provider=fake-rsa", fake_rsa))) 67 goto end; 68 69 /* Construct a pkey using precise propq to use our provider */ 70 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 71 "provider=fake-rsa")) 72 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 73 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, NULL)) 74 || !TEST_ptr(pkey)) 75 goto end; 76 77 EVP_PKEY_CTX_free(ctx); 78 ctx = NULL; 79 80 /* try exercising signature_init ops a few times */ 81 for (i = 0; i < 3; i++) { 82 size_t siglen; 83 84 /* 85 * Create a signing context for our pkey with optional propq. 86 * The sign init should pick both keymgmt and signature from 87 * fake-rsa as the key is not exportable. 88 */ 89 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, 90 "?provider=default"))) 91 goto end; 92 93 /* 94 * If this picks the wrong signature without realizing it 95 * we can get a segfault or some internal error. At least watch 96 * whether fake-rsa sign_init is is exercised by calling sign. 97 */ 98 if (!TEST_int_eq(EVP_PKEY_sign_init(ctx), 1)) 99 goto end; 100 101 if (!TEST_int_eq(EVP_PKEY_sign(ctx, NULL, &siglen, NULL, 0), 1) 102 || !TEST_size_t_eq(siglen, 256)) 103 goto end; 104 105 EVP_PKEY_CTX_free(ctx); 106 ctx = NULL; 107 } 108 109 ret = 1; 110 111 end: 112 fake_rsa_finish(fake_rsa); 113 OSSL_PROVIDER_unload(deflt); 114 EVP_PKEY_CTX_free(ctx); 115 EVP_PKEY_free(pkey); 116 return ret; 117 } 118 119 static int test_alternative_keygen_init(void) 120 { 121 EVP_PKEY_CTX *ctx = NULL; 122 OSSL_PROVIDER *deflt = NULL; 123 OSSL_PROVIDER *fake_rsa = NULL; 124 const OSSL_PROVIDER *provider; 125 const char *provname; 126 int ret = 0; 127 128 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 129 goto end; 130 131 /* first try without the fake RSA provider loaded */ 132 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL))) 133 goto end; 134 135 if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)) 136 goto end; 137 138 if (!TEST_ptr(provider = EVP_PKEY_CTX_get0_provider(ctx))) 139 goto end; 140 141 if (!TEST_ptr(provname = OSSL_PROVIDER_get0_name(provider))) 142 goto end; 143 144 if (!TEST_str_eq(provname, "default")) 145 goto end; 146 147 EVP_PKEY_CTX_free(ctx); 148 ctx = NULL; 149 150 /* now load fake RSA and try again */ 151 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 152 return 0; 153 154 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 155 "?provider=fake-rsa"))) 156 goto end; 157 158 if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)) 159 goto end; 160 161 if (!TEST_ptr(provider = EVP_PKEY_CTX_get0_provider(ctx))) 162 goto end; 163 164 if (!TEST_ptr(provname = OSSL_PROVIDER_get0_name(provider))) 165 goto end; 166 167 if (!TEST_str_eq(provname, "fake-rsa")) 168 goto end; 169 170 ret = 1; 171 172 end: 173 fake_rsa_finish(fake_rsa); 174 OSSL_PROVIDER_unload(deflt); 175 EVP_PKEY_CTX_free(ctx); 176 return ret; 177 } 178 179 static int test_pkey_eq(void) 180 { 181 OSSL_PROVIDER *deflt = NULL; 182 OSSL_PROVIDER *fake_rsa = NULL; 183 EVP_PKEY *pkey_fake = NULL; 184 EVP_PKEY *pkey_dflt = NULL; 185 EVP_PKEY_CTX *ctx = NULL; 186 OSSL_PARAM *params = NULL; 187 int ret = 0; 188 189 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 190 return 0; 191 192 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 193 goto end; 194 195 /* Construct a public key for fake-rsa */ 196 if (!TEST_ptr(params = fake_rsa_key_params(0)) 197 || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 198 "provider=fake-rsa")) 199 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 200 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY, 201 params)) 202 || !TEST_ptr(pkey_fake)) 203 goto end; 204 205 EVP_PKEY_CTX_free(ctx); 206 ctx = NULL; 207 OSSL_PARAM_free(params); 208 params = NULL; 209 210 /* Construct a public key for default */ 211 if (!TEST_ptr(params = fake_rsa_key_params(0)) 212 || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", 213 "provider=default")) 214 || !TEST_true(EVP_PKEY_fromdata_init(ctx)) 215 || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_dflt, EVP_PKEY_PUBLIC_KEY, 216 params)) 217 || !TEST_ptr(pkey_dflt)) 218 goto end; 219 220 EVP_PKEY_CTX_free(ctx); 221 ctx = NULL; 222 OSSL_PARAM_free(params); 223 params = NULL; 224 225 /* now test for equality */ 226 if (!TEST_int_eq(EVP_PKEY_eq(pkey_fake, pkey_dflt), 1)) 227 goto end; 228 229 ret = 1; 230 end: 231 fake_rsa_finish(fake_rsa); 232 OSSL_PROVIDER_unload(deflt); 233 EVP_PKEY_CTX_free(ctx); 234 EVP_PKEY_free(pkey_fake); 235 EVP_PKEY_free(pkey_dflt); 236 OSSL_PARAM_free(params); 237 return ret; 238 } 239 240 static int test_pkey_store(int idx) 241 { 242 OSSL_PROVIDER *deflt = NULL; 243 OSSL_PROVIDER *fake_rsa = NULL; 244 int ret = 0; 245 EVP_PKEY *pkey = NULL; 246 OSSL_STORE_LOADER *loader = NULL; 247 OSSL_STORE_CTX *ctx = NULL; 248 OSSL_STORE_INFO *info; 249 const char *propq = idx == 0 ? "?provider=fake-rsa" 250 : "?provider=default"; 251 252 /* It's important to load the default provider first for this test */ 253 if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) 254 goto end; 255 256 if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) 257 goto end; 258 259 if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", 260 propq))) 261 goto end; 262 263 OSSL_STORE_LOADER_free(loader); 264 265 if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, 266 NULL, NULL, NULL, NULL, NULL))) 267 goto end; 268 269 while (!OSSL_STORE_eof(ctx) 270 && (info = OSSL_STORE_load(ctx)) != NULL 271 && pkey == NULL) { 272 if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) 273 pkey = OSSL_STORE_INFO_get1_PKEY(info); 274 OSSL_STORE_INFO_free(info); 275 info = NULL; 276 } 277 278 if (!TEST_ptr(pkey) || !TEST_int_eq(EVP_PKEY_is_a(pkey, "RSA"), 1)) 279 goto end; 280 281 ret = 1; 282 283 end: 284 fake_rsa_finish(fake_rsa); 285 OSSL_PROVIDER_unload(deflt); 286 OSSL_STORE_close(ctx); 287 EVP_PKEY_free(pkey); 288 return ret; 289 } 290 291 int setup_tests(void) 292 { 293 libctx = OSSL_LIB_CTX_new(); 294 if (libctx == NULL) 295 return 0; 296 297 ADD_TEST(test_pkey_sig); 298 ADD_TEST(test_alternative_keygen_init); 299 ADD_TEST(test_pkey_eq); 300 ADD_ALL_TESTS(test_pkey_store, 2); 301 302 return 1; 303 } 304 305 void cleanup_tests(void) 306 { 307 OSSL_LIB_CTX_free(libctx); 308 } 309