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