Home | History | Annotate | Line # | Download | only in test
      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