1*b0d17251Schristos /*
2*b0d17251Schristos * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
3*b0d17251Schristos *
4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5*b0d17251Schristos * this file except in compliance with the License. You can obtain a copy
6*b0d17251Schristos * in the file LICENSE in the source distribution or at
7*b0d17251Schristos * https://www.openssl.org/source/license.html
8*b0d17251Schristos */
9*b0d17251Schristos
10*b0d17251Schristos #include <openssl/crypto.h>
11*b0d17251Schristos #include <openssl/provider.h>
12*b0d17251Schristos #include <openssl/decoder.h>
13*b0d17251Schristos #include <openssl/encoder.h>
14*b0d17251Schristos #include <openssl/store.h>
15*b0d17251Schristos #include <openssl/rand.h>
16*b0d17251Schristos #include <openssl/core_names.h>
17*b0d17251Schristos #include "testutil.h"
18*b0d17251Schristos
dummy_decoder_decode(void * ctx,OSSL_CORE_BIO * cin,int selection,OSSL_CALLBACK * object_cb,void * object_cbarg,OSSL_PASSPHRASE_CALLBACK * pw_cb,void * pw_cbarg)19*b0d17251Schristos static int dummy_decoder_decode(void *ctx, OSSL_CORE_BIO *cin, int selection,
20*b0d17251Schristos OSSL_CALLBACK *object_cb, void *object_cbarg,
21*b0d17251Schristos OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
22*b0d17251Schristos {
23*b0d17251Schristos return 0;
24*b0d17251Schristos }
25*b0d17251Schristos
26*b0d17251Schristos static const OSSL_DISPATCH dummy_decoder_functions[] = {
27*b0d17251Schristos { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_decoder_decode },
28*b0d17251Schristos { 0, NULL }
29*b0d17251Schristos };
30*b0d17251Schristos
31*b0d17251Schristos static const OSSL_ALGORITHM dummy_decoders[] = {
32*b0d17251Schristos { "DUMMY", "provider=dummy,input=pem", dummy_decoder_functions },
33*b0d17251Schristos { NULL, NULL, NULL }
34*b0d17251Schristos };
35*b0d17251Schristos
dummy_encoder_encode(void * ctx,OSSL_CORE_BIO * out,const void * obj_raw,const OSSL_PARAM obj_abstract[],int selection,OSSL_PASSPHRASE_CALLBACK * cb,void * cbarg)36*b0d17251Schristos static int dummy_encoder_encode(void *ctx, OSSL_CORE_BIO *out,
37*b0d17251Schristos const void *obj_raw,
38*b0d17251Schristos const OSSL_PARAM obj_abstract[], int selection,
39*b0d17251Schristos OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
40*b0d17251Schristos {
41*b0d17251Schristos return 0;
42*b0d17251Schristos }
43*b0d17251Schristos
44*b0d17251Schristos static const OSSL_DISPATCH dummy_encoder_functions[] = {
45*b0d17251Schristos { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_encoder_encode },
46*b0d17251Schristos { 0, NULL }
47*b0d17251Schristos };
48*b0d17251Schristos
49*b0d17251Schristos static const OSSL_ALGORITHM dummy_encoders[] = {
50*b0d17251Schristos { "DUMMY", "provider=dummy,output=pem", dummy_encoder_functions },
51*b0d17251Schristos { NULL, NULL, NULL }
52*b0d17251Schristos };
53*b0d17251Schristos
dummy_store_open(void * provctx,const char * uri)54*b0d17251Schristos static void *dummy_store_open(void *provctx, const char *uri)
55*b0d17251Schristos {
56*b0d17251Schristos return NULL;
57*b0d17251Schristos }
58*b0d17251Schristos
dummy_store_load(void * loaderctx,OSSL_CALLBACK * object_cb,void * object_cbarg,OSSL_PASSPHRASE_CALLBACK * pw_cb,void * pw_cbarg)59*b0d17251Schristos static int dummy_store_load(void *loaderctx, OSSL_CALLBACK *object_cb,
60*b0d17251Schristos void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb,
61*b0d17251Schristos void *pw_cbarg)
62*b0d17251Schristos {
63*b0d17251Schristos return 0;
64*b0d17251Schristos }
65*b0d17251Schristos
dumm_store_eof(void * loaderctx)66*b0d17251Schristos static int dumm_store_eof(void *loaderctx)
67*b0d17251Schristos {
68*b0d17251Schristos return 0;
69*b0d17251Schristos }
70*b0d17251Schristos
dummy_store_close(void * loaderctx)71*b0d17251Schristos static int dummy_store_close(void *loaderctx)
72*b0d17251Schristos {
73*b0d17251Schristos return 0;
74*b0d17251Schristos }
75*b0d17251Schristos
76*b0d17251Schristos static const OSSL_DISPATCH dummy_store_functions[] = {
77*b0d17251Schristos { OSSL_FUNC_STORE_OPEN, (void (*)(void))dummy_store_open },
78*b0d17251Schristos { OSSL_FUNC_STORE_LOAD, (void (*)(void))dummy_store_load },
79*b0d17251Schristos { OSSL_FUNC_STORE_EOF, (void (*)(void))dumm_store_eof },
80*b0d17251Schristos { OSSL_FUNC_STORE_CLOSE, (void (*)(void))dummy_store_close },
81*b0d17251Schristos { 0, NULL }
82*b0d17251Schristos };
83*b0d17251Schristos
84*b0d17251Schristos static const OSSL_ALGORITHM dummy_store[] = {
85*b0d17251Schristos { "DUMMY", "provider=dummy", dummy_store_functions },
86*b0d17251Schristos { NULL, NULL, NULL }
87*b0d17251Schristos };
88*b0d17251Schristos
dummy_rand_newctx(void * provctx,void * parent,const OSSL_DISPATCH * parent_calls)89*b0d17251Schristos static void *dummy_rand_newctx(void *provctx, void *parent,
90*b0d17251Schristos const OSSL_DISPATCH *parent_calls)
91*b0d17251Schristos {
92*b0d17251Schristos return provctx;
93*b0d17251Schristos }
94*b0d17251Schristos
dummy_rand_freectx(void * vctx)95*b0d17251Schristos static void dummy_rand_freectx(void *vctx)
96*b0d17251Schristos {
97*b0d17251Schristos }
98*b0d17251Schristos
dummy_rand_instantiate(void * vdrbg,unsigned int strength,int prediction_resistance,const unsigned char * pstr,size_t pstr_len,const OSSL_PARAM params[])99*b0d17251Schristos static int dummy_rand_instantiate(void *vdrbg, unsigned int strength,
100*b0d17251Schristos int prediction_resistance,
101*b0d17251Schristos const unsigned char *pstr, size_t pstr_len,
102*b0d17251Schristos const OSSL_PARAM params[])
103*b0d17251Schristos {
104*b0d17251Schristos return 1;
105*b0d17251Schristos }
106*b0d17251Schristos
dummy_rand_uninstantiate(void * vdrbg)107*b0d17251Schristos static int dummy_rand_uninstantiate(void *vdrbg)
108*b0d17251Schristos {
109*b0d17251Schristos return 1;
110*b0d17251Schristos }
111*b0d17251Schristos
dummy_rand_generate(void * vctx,unsigned char * out,size_t outlen,unsigned int strength,int prediction_resistance,const unsigned char * addin,size_t addin_len)112*b0d17251Schristos static int dummy_rand_generate(void *vctx, unsigned char *out, size_t outlen,
113*b0d17251Schristos unsigned int strength, int prediction_resistance,
114*b0d17251Schristos const unsigned char *addin, size_t addin_len)
115*b0d17251Schristos {
116*b0d17251Schristos size_t i;
117*b0d17251Schristos
118*b0d17251Schristos for (i = 0; i <outlen; i++)
119*b0d17251Schristos out[i] = (unsigned char)(i & 0xff);
120*b0d17251Schristos
121*b0d17251Schristos return 1;
122*b0d17251Schristos }
123*b0d17251Schristos
dummy_rand_gettable_ctx_params(void * vctx,void * provctx)124*b0d17251Schristos static const OSSL_PARAM *dummy_rand_gettable_ctx_params(void *vctx, void *provctx)
125*b0d17251Schristos {
126*b0d17251Schristos static const OSSL_PARAM known_gettable_ctx_params[] = {
127*b0d17251Schristos OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
128*b0d17251Schristos OSSL_PARAM_END
129*b0d17251Schristos };
130*b0d17251Schristos return known_gettable_ctx_params;
131*b0d17251Schristos }
132*b0d17251Schristos
dummy_rand_get_ctx_params(void * vctx,OSSL_PARAM params[])133*b0d17251Schristos static int dummy_rand_get_ctx_params(void *vctx, OSSL_PARAM params[])
134*b0d17251Schristos {
135*b0d17251Schristos OSSL_PARAM *p;
136*b0d17251Schristos
137*b0d17251Schristos p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
138*b0d17251Schristos if (p != NULL && !OSSL_PARAM_set_size_t(p, INT_MAX))
139*b0d17251Schristos return 0;
140*b0d17251Schristos
141*b0d17251Schristos return 1;
142*b0d17251Schristos }
143*b0d17251Schristos
dummy_rand_enable_locking(void * vtest)144*b0d17251Schristos static int dummy_rand_enable_locking(void *vtest)
145*b0d17251Schristos {
146*b0d17251Schristos return 1;
147*b0d17251Schristos }
148*b0d17251Schristos
dummy_rand_lock(void * vtest)149*b0d17251Schristos static int dummy_rand_lock(void *vtest)
150*b0d17251Schristos {
151*b0d17251Schristos return 1;
152*b0d17251Schristos }
153*b0d17251Schristos
dummy_rand_unlock(void * vtest)154*b0d17251Schristos static void dummy_rand_unlock(void *vtest)
155*b0d17251Schristos {
156*b0d17251Schristos }
157*b0d17251Schristos
158*b0d17251Schristos static const OSSL_DISPATCH dummy_rand_functions[] = {
159*b0d17251Schristos { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))dummy_rand_newctx },
160*b0d17251Schristos { OSSL_FUNC_RAND_FREECTX, (void (*)(void))dummy_rand_freectx },
161*b0d17251Schristos { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))dummy_rand_instantiate },
162*b0d17251Schristos { OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))dummy_rand_uninstantiate },
163*b0d17251Schristos { OSSL_FUNC_RAND_GENERATE, (void (*)(void))dummy_rand_generate },
164*b0d17251Schristos { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
165*b0d17251Schristos (void(*)(void))dummy_rand_gettable_ctx_params },
166*b0d17251Schristos { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))dummy_rand_get_ctx_params },
167*b0d17251Schristos { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))dummy_rand_enable_locking },
168*b0d17251Schristos { OSSL_FUNC_RAND_LOCK, (void(*)(void))dummy_rand_lock },
169*b0d17251Schristos { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))dummy_rand_unlock },
170*b0d17251Schristos { 0, NULL }
171*b0d17251Schristos };
172*b0d17251Schristos
173*b0d17251Schristos static const OSSL_ALGORITHM dummy_rand[] = {
174*b0d17251Schristos { "DUMMY", "provider=dummy", dummy_rand_functions },
175*b0d17251Schristos { NULL, NULL, NULL }
176*b0d17251Schristos };
177*b0d17251Schristos
dummy_query(void * provctx,int operation_id,int * no_cache)178*b0d17251Schristos static const OSSL_ALGORITHM *dummy_query(void *provctx, int operation_id,
179*b0d17251Schristos int *no_cache)
180*b0d17251Schristos {
181*b0d17251Schristos *no_cache = 0;
182*b0d17251Schristos switch (operation_id) {
183*b0d17251Schristos case OSSL_OP_DECODER:
184*b0d17251Schristos return dummy_decoders;
185*b0d17251Schristos case OSSL_OP_ENCODER:
186*b0d17251Schristos return dummy_encoders;
187*b0d17251Schristos case OSSL_OP_STORE:
188*b0d17251Schristos return dummy_store;
189*b0d17251Schristos case OSSL_OP_RAND:
190*b0d17251Schristos return dummy_rand;
191*b0d17251Schristos }
192*b0d17251Schristos return NULL;
193*b0d17251Schristos }
194*b0d17251Schristos
195*b0d17251Schristos static const OSSL_DISPATCH dummy_dispatch_table[] = {
196*b0d17251Schristos { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))dummy_query },
197*b0d17251Schristos { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free },
198*b0d17251Schristos { 0, NULL }
199*b0d17251Schristos };
200*b0d17251Schristos
dummy_provider_init(const OSSL_CORE_HANDLE * handle,const OSSL_DISPATCH * in,const OSSL_DISPATCH ** out,void ** provctx)201*b0d17251Schristos static int dummy_provider_init(const OSSL_CORE_HANDLE *handle,
202*b0d17251Schristos const OSSL_DISPATCH *in,
203*b0d17251Schristos const OSSL_DISPATCH **out,
204*b0d17251Schristos void **provctx)
205*b0d17251Schristos {
206*b0d17251Schristos OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_child(handle, in);
207*b0d17251Schristos unsigned char buf[32];
208*b0d17251Schristos
209*b0d17251Schristos *provctx = (void *)libctx;
210*b0d17251Schristos *out = dummy_dispatch_table;
211*b0d17251Schristos
212*b0d17251Schristos /*
213*b0d17251Schristos * Do some work using the child libctx, to make sure this is possible from
214*b0d17251Schristos * inside the init function.
215*b0d17251Schristos */
216*b0d17251Schristos if (RAND_bytes_ex(libctx, buf, sizeof(buf), 0) <= 0)
217*b0d17251Schristos return 0;
218*b0d17251Schristos
219*b0d17251Schristos return 1;
220*b0d17251Schristos }
221*b0d17251Schristos
222*b0d17251Schristos /*
223*b0d17251Schristos * Try fetching and freeing various things.
224*b0d17251Schristos * Test 0: Decoder
225*b0d17251Schristos * Test 1: Encoder
226*b0d17251Schristos * Test 2: Store loader
227*b0d17251Schristos * Test 3: EVP_RAND
228*b0d17251Schristos * Test 4-7: As above, but additionally with a query string
229*b0d17251Schristos */
fetch_test(int tst)230*b0d17251Schristos static int fetch_test(int tst)
231*b0d17251Schristos {
232*b0d17251Schristos OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
233*b0d17251Schristos OSSL_PROVIDER *dummyprov = NULL;
234*b0d17251Schristos OSSL_PROVIDER *nullprov = NULL;
235*b0d17251Schristos OSSL_DECODER *decoder = NULL;
236*b0d17251Schristos OSSL_ENCODER *encoder = NULL;
237*b0d17251Schristos OSSL_STORE_LOADER *loader = NULL;
238*b0d17251Schristos int testresult = 0;
239*b0d17251Schristos unsigned char buf[32];
240*b0d17251Schristos int query = tst > 3;
241*b0d17251Schristos
242*b0d17251Schristos if (!TEST_ptr(libctx))
243*b0d17251Schristos goto err;
244*b0d17251Schristos
245*b0d17251Schristos if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "dummy-prov",
246*b0d17251Schristos dummy_provider_init))
247*b0d17251Schristos || !TEST_ptr(nullprov = OSSL_PROVIDER_load(libctx, "default"))
248*b0d17251Schristos || !TEST_ptr(dummyprov = OSSL_PROVIDER_load(libctx, "dummy-prov")))
249*b0d17251Schristos goto err;
250*b0d17251Schristos
251*b0d17251Schristos switch (tst % 4) {
252*b0d17251Schristos case 0:
253*b0d17251Schristos decoder = OSSL_DECODER_fetch(libctx, "DUMMY",
254*b0d17251Schristos query ? "provider=dummy" : NULL);
255*b0d17251Schristos if (!TEST_ptr(decoder))
256*b0d17251Schristos goto err;
257*b0d17251Schristos break;
258*b0d17251Schristos case 1:
259*b0d17251Schristos encoder = OSSL_ENCODER_fetch(libctx, "DUMMY",
260*b0d17251Schristos query ? "provider=dummy" : NULL);
261*b0d17251Schristos if (!TEST_ptr(encoder))
262*b0d17251Schristos goto err;
263*b0d17251Schristos break;
264*b0d17251Schristos case 2:
265*b0d17251Schristos loader = OSSL_STORE_LOADER_fetch(libctx, "DUMMY",
266*b0d17251Schristos query ? "provider=dummy" : NULL);
267*b0d17251Schristos if (!TEST_ptr(loader))
268*b0d17251Schristos goto err;
269*b0d17251Schristos break;
270*b0d17251Schristos case 3:
271*b0d17251Schristos if (!TEST_true(RAND_set_DRBG_type(libctx, "DUMMY",
272*b0d17251Schristos query ? "provider=dummy" : NULL,
273*b0d17251Schristos NULL, NULL))
274*b0d17251Schristos || !TEST_int_ge(RAND_bytes_ex(libctx, buf, sizeof(buf), 0), 1))
275*b0d17251Schristos goto err;
276*b0d17251Schristos break;
277*b0d17251Schristos default:
278*b0d17251Schristos goto err;
279*b0d17251Schristos }
280*b0d17251Schristos
281*b0d17251Schristos testresult = 1;
282*b0d17251Schristos err:
283*b0d17251Schristos OSSL_DECODER_free(decoder);
284*b0d17251Schristos OSSL_ENCODER_free(encoder);
285*b0d17251Schristos OSSL_STORE_LOADER_free(loader);
286*b0d17251Schristos OSSL_PROVIDER_unload(dummyprov);
287*b0d17251Schristos OSSL_PROVIDER_unload(nullprov);
288*b0d17251Schristos OSSL_LIB_CTX_free(libctx);
289*b0d17251Schristos return testresult;
290*b0d17251Schristos }
291*b0d17251Schristos
setup_tests(void)292*b0d17251Schristos int setup_tests(void)
293*b0d17251Schristos {
294*b0d17251Schristos ADD_ALL_TESTS(fetch_test, 8);
295*b0d17251Schristos
296*b0d17251Schristos return 1;
297*b0d17251Schristos }
298