]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/evp_fetch_prov_test.c
threads_pthread.c: change inline to ossl_inline
[thirdparty/openssl.git] / test / evp_fetch_prov_test.c
CommitLineData
7bb82f92 1/*
fecb3aae 2 * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
7bb82f92
SL
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
85d843c8
P
10/*
11 * SHA256 low level APIs are deprecated for public use, but still ok for
12 * internal use. Note, that due to symbols not being exported, only the
13 * #defines can be accessed. In this case SHA256_CBLOCK.
14 */
15#include "internal/deprecated.h"
16
7bb82f92
SL
17#include <string.h>
18#include <openssl/sha.h>
19#include <openssl/evp.h>
20#include <openssl/provider.h>
ebb3c82b 21#include "internal/sizes.h"
7bb82f92
SL
22#include "testutil.h"
23
22e27978 24static char *config_file = NULL;
7bb82f92
SL
25static char *alg = "digest";
26static int use_default_ctx = 0;
27static char *fetch_property = NULL;
28static int expected_fetch_result = 1;
29
30typedef enum OPTION_choice {
31 OPT_ERR = -1,
32 OPT_EOF = 0,
33 OPT_ALG_FETCH_TYPE,
34 OPT_FETCH_PROPERTY,
35 OPT_FETCH_FAILURE,
36 OPT_USE_DEFAULTCTX,
22e27978 37 OPT_CONFIG_FILE,
7bb82f92
SL
38 OPT_TEST_ENUM
39} OPTION_CHOICE;
40
41const OPTIONS *test_get_options(void)
42{
43 static const OPTIONS test_options[] = {
44 OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[provname...]\n"),
22e27978 45 { "config", OPT_CONFIG_FILE, '<', "The configuration file to use for the libctx" },
7bb82f92 46 { "type", OPT_ALG_FETCH_TYPE, 's', "The fetch type to test" },
745fc918 47 { "property", OPT_FETCH_PROPERTY, 's', "The fetch property e.g. provider=fips" },
7bb82f92
SL
48 { "fetchfail", OPT_FETCH_FAILURE, '-', "fetch is expected to fail" },
49 { "defaultctx", OPT_USE_DEFAULTCTX, '-',
50 "Use the default context if this is set" },
f56c9c7c 51 { OPT_HELP_STR, 1, '-', "file\tProvider names to explicitly load\n" },
7bb82f92
SL
52 { NULL }
53 };
54 return test_options;
55}
56
57static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
58 const unsigned char *exptd)
59{
60 unsigned char out[SHA256_DIGEST_LENGTH];
61 EVP_MD_CTX *ctx;
62 int ret = 0;
63
64 if (!TEST_ptr(ctx = EVP_MD_CTX_new())
65 || !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
66 || !TEST_true(EVP_DigestUpdate(ctx, msg, len))
67 || !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
68 || !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
69 SHA256_DIGEST_LENGTH)
f6c95e46 70 || !TEST_true(md == EVP_MD_CTX_get0_md(ctx)))
7bb82f92
SL
71 goto err;
72
73 ret = 1;
74 err:
75 EVP_MD_CTX_free(ctx);
76 return ret;
77}
78
b4250010 79static int load_providers(OSSL_LIB_CTX **libctx, OSSL_PROVIDER *prov[])
7bb82f92 80{
b4250010 81 OSSL_LIB_CTX *ctx = NULL;
7bb82f92
SL
82 int ret = 0;
83 size_t i;
84
b4250010 85 ctx = OSSL_LIB_CTX_new();
7bb82f92
SL
86 if (!TEST_ptr(ctx))
87 goto err;
88
b4250010 89 if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, config_file)))
22e27978 90 goto err;
7bb82f92
SL
91 if (test_get_argument_count() > 2)
92 goto err;
93
94 for (i = 0; i < test_get_argument_count(); ++i) {
95 char *provname = test_get_argument(i);
96 prov[i] = OSSL_PROVIDER_load(ctx, provname);
97 if (!TEST_ptr(prov[i]))
98 goto err;
99 }
22e27978 100
7bb82f92
SL
101 ret = 1;
102 *libctx = ctx;
103err:
22e27978 104 if (ret == 0)
b4250010 105 OSSL_LIB_CTX_free(ctx);
7bb82f92
SL
106 return ret;
107}
108
ebb3c82b
RL
109static void unload_providers(OSSL_LIB_CTX **libctx, OSSL_PROVIDER *prov[])
110{
111 if (prov[0] != NULL)
112 OSSL_PROVIDER_unload(prov[0]);
113 if (prov[1] != NULL)
114 OSSL_PROVIDER_unload(prov[1]);
115 /* Not normally needed, but we would like to test that
116 * OPENSSL_thread_stop_ex() behaves as expected.
117 */
118 if (libctx != NULL && *libctx != NULL) {
119 OPENSSL_thread_stop_ex(*libctx);
120 OSSL_LIB_CTX_free(*libctx);
121 }
122}
123
506ff206
NH
124static int test_legacy_provider_unloaded(void)
125{
126 OSSL_LIB_CTX *ctx = NULL;
127 int rc = 0;
128
129 ctx = OSSL_LIB_CTX_new();
130 if (!TEST_ptr(ctx))
131 goto err;
132
133 if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, config_file)))
134 goto err;
135
136 if (!TEST_int_eq(OSSL_PROVIDER_available(ctx, "legacy"), 0))
137 goto err;
138
139 rc = 1;
140err:
141 OSSL_LIB_CTX_free(ctx);
142 return rc;
143}
144
ebb3c82b
RL
145static X509_ALGOR *make_algor(int nid)
146{
147 X509_ALGOR *algor;
148
149 if (!TEST_ptr(algor = X509_ALGOR_new())
150 || !TEST_true(X509_ALGOR_set0(algor, OBJ_nid2obj(nid),
151 V_ASN1_UNDEF, NULL))) {
152 X509_ALGOR_free(algor);
153 return NULL;
154 }
155 return algor;
156}
157
7bb82f92
SL
158/*
159 * Test EVP_MD_fetch()
160 */
ebb3c82b 161static int test_md(const EVP_MD *md)
7bb82f92 162{
7bb82f92
SL
163 const char testmsg[] = "Hello world";
164 const unsigned char exptd[] = {
165 0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
166 0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
167 0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
168 };
169
ebb3c82b
RL
170 return TEST_ptr(md)
171 && TEST_true(EVP_MD_is_a(md, "SHA256"))
172 && TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
ed576acd
TM
173 && TEST_int_eq(EVP_MD_get_size(md), SHA256_DIGEST_LENGTH)
174 && TEST_int_eq(EVP_MD_get_block_size(md), SHA256_CBLOCK);
ebb3c82b
RL
175}
176
177static int test_implicit_EVP_MD_fetch(void)
178{
179 OSSL_LIB_CTX *ctx = NULL;
180 OSSL_PROVIDER *prov[2] = {NULL, NULL};
181 int ret = 0;
182
183 ret = (use_default_ctx == 0 || load_providers(&ctx, prov))
184 && test_md(EVP_sha256());
7bb82f92 185
ebb3c82b
RL
186 unload_providers(&ctx, prov);
187 return ret;
188}
189
190static int test_explicit_EVP_MD_fetch(const char *id)
191{
192 OSSL_LIB_CTX *ctx = NULL;
193 EVP_MD *md = NULL;
194 OSSL_PROVIDER *prov[2] = {NULL, NULL};
195 int ret = 0;
196
197 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
7bb82f92
SL
198 goto err;
199
ebb3c82b 200 md = EVP_MD_fetch(ctx, id, fetch_property);
7bb82f92 201 if (expected_fetch_result != 0) {
ebb3c82b
RL
202 if (!test_md(md))
203 goto err;
7bb82f92
SL
204
205 /* Also test EVP_MD_up_ref() while we're doing this */
206 if (!TEST_true(EVP_MD_up_ref(md)))
207 goto err;
208 /* Ref count should now be 2. Release first one here */
41bbba53 209 EVP_MD_free(md);
7bb82f92
SL
210 } else {
211 if (!TEST_ptr_null(md))
212 goto err;
213 }
214 ret = 1;
215
ebb3c82b 216 err:
41bbba53 217 EVP_MD_free(md);
ebb3c82b
RL
218 unload_providers(&ctx, prov);
219 return ret;
220}
221
222static int test_explicit_EVP_MD_fetch_by_name(void)
223{
224 return test_explicit_EVP_MD_fetch("SHA256");
225}
226
227/*
228 * idx 0: Allow names from OBJ_obj2txt()
229 * idx 1: Force an OID in text form from OBJ_obj2txt()
230 */
231static int test_explicit_EVP_MD_fetch_by_X509_ALGOR(int idx)
232{
233 int ret = 0;
234 X509_ALGOR *algor = make_algor(NID_sha256);
235 const ASN1_OBJECT *obj;
3e35d3a4 236 char id[OSSL_MAX_NAME_SIZE] = { 0 };
ebb3c82b
RL
237
238 if (algor == NULL)
239 return 0;
240
241 X509_ALGOR_get0(&obj, NULL, NULL, algor);
242 switch (idx) {
243 case 0:
2349d7ba 244 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 0), 0))
ebb3c82b
RL
245 goto end;
246 break;
247 case 1:
2349d7ba 248 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 1), 0))
ebb3c82b
RL
249 goto end;
250 break;
7bb82f92 251 }
ebb3c82b
RL
252
253 ret = test_explicit_EVP_MD_fetch(id);
254 end:
255 X509_ALGOR_free(algor);
7bb82f92
SL
256 return ret;
257}
258
ebb3c82b
RL
259/*
260 * Test EVP_CIPHER_fetch()
261 */
7bb82f92
SL
262static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
263 size_t len)
264{
265 int ret = 0, ctlen, ptlen;
266 EVP_CIPHER_CTX *ctx = NULL;
267 unsigned char key[128 / 8];
268 unsigned char ct[64], pt[64];
269
270 memset(key, 0, sizeof(key));
271 if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
272 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
273 || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
274 || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
275 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
276 || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
277 || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
278 || !TEST_mem_eq(pt, ptlen, msg, len))
279 goto err;
280
281 ret = 1;
282err:
283 EVP_CIPHER_CTX_free(ctx);
284 return ret;
285}
286
ebb3c82b
RL
287static int test_cipher(const EVP_CIPHER *cipher)
288{
289 const unsigned char testmsg[] = "Hello world";
290
291 return TEST_ptr(cipher)
292 && TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)));
293}
294
295static int test_implicit_EVP_CIPHER_fetch(void)
296{
297 OSSL_LIB_CTX *ctx = NULL;
298 OSSL_PROVIDER *prov[2] = {NULL, NULL};
299 int ret = 0;
300
301 ret = (use_default_ctx == 0 || load_providers(&ctx, prov))
302 && test_cipher(EVP_aes_128_cbc());
303
304 unload_providers(&ctx, prov);
305 return ret;
306}
307
308static int test_explicit_EVP_CIPHER_fetch(const char *id)
7bb82f92 309{
b4250010 310 OSSL_LIB_CTX *ctx = NULL;
7bb82f92
SL
311 EVP_CIPHER *cipher = NULL;
312 OSSL_PROVIDER *prov[2] = {NULL, NULL};
313 int ret = 0;
7bb82f92
SL
314
315 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
316 goto err;
317
ebb3c82b 318 cipher = EVP_CIPHER_fetch(ctx, id, fetch_property);
7bb82f92 319 if (expected_fetch_result != 0) {
ebb3c82b
RL
320 if (!test_cipher(cipher))
321 goto err;
322
323 if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
324 goto err;
325 /* Ref count should now be 2. Release first one here */
326 EVP_CIPHER_free(cipher);
7bb82f92
SL
327 } else {
328 if (!TEST_ptr_null(cipher))
329 goto err;
330 }
331 ret = 1;
332err:
41bbba53 333 EVP_CIPHER_free(cipher);
ebb3c82b
RL
334 unload_providers(&ctx, prov);
335 return ret;
336}
337
338static int test_explicit_EVP_CIPHER_fetch_by_name(void)
339{
340 return test_explicit_EVP_CIPHER_fetch("AES-128-CBC");
341}
342
343/*
344 * idx 0: Allow names from OBJ_obj2txt()
345 * idx 1: Force an OID in text form from OBJ_obj2txt()
346 */
347static int test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR(int idx)
348{
349 int ret = 0;
350 X509_ALGOR *algor = make_algor(NID_aes_128_cbc);
351 const ASN1_OBJECT *obj;
3e35d3a4 352 char id[OSSL_MAX_NAME_SIZE] = { 0 };
ebb3c82b
RL
353
354 if (algor == NULL)
355 return 0;
356
357 X509_ALGOR_get0(&obj, NULL, NULL, algor);
358 switch (idx) {
359 case 0:
2349d7ba 360 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 0), 0))
ebb3c82b
RL
361 goto end;
362 break;
363 case 1:
2349d7ba 364 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 1), 0))
ebb3c82b
RL
365 goto end;
366 break;
367 }
368
369 ret = test_explicit_EVP_CIPHER_fetch(id);
370 end:
371 X509_ALGOR_free(algor);
7bb82f92
SL
372 return ret;
373}
374
375int setup_tests(void)
376{
377 OPTION_CHOICE o;
378
379 while ((o = opt_next()) != OPT_EOF) {
380 switch (o) {
22e27978
SL
381 case OPT_CONFIG_FILE:
382 config_file = opt_arg();
383 break;
7bb82f92
SL
384 case OPT_ALG_FETCH_TYPE:
385 alg = opt_arg();
386 break;
387 case OPT_FETCH_PROPERTY:
388 fetch_property = opt_arg();
389 break;
390 case OPT_FETCH_FAILURE:
391 expected_fetch_result = 0;
392 break;
393 case OPT_USE_DEFAULTCTX:
394 use_default_ctx = 1;
395 break;
396 case OPT_TEST_CASES:
397 break;
398 default:
399 case OPT_ERR:
400 return 0;
401 }
402 }
506ff206 403 ADD_TEST(test_legacy_provider_unloaded);
ebb3c82b
RL
404 if (strcmp(alg, "digest") == 0) {
405 ADD_TEST(test_implicit_EVP_MD_fetch);
406 ADD_TEST(test_explicit_EVP_MD_fetch_by_name);
407 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_MD_fetch_by_X509_ALGOR, 2);
408 } else {
409 ADD_TEST(test_implicit_EVP_CIPHER_fetch);
410 ADD_TEST(test_explicit_EVP_CIPHER_fetch_by_name);
411 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR, 2);
412 }
7bb82f92
SL
413 return 1;
414}