]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/keymgmt_internal_test.c
Update copyright year
[thirdparty/openssl.git] / test / keymgmt_internal_test.c
1 /*
2 * Copyright 2019-2021 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 /*
11 * RSA low level APIs are deprecated for public use, but still ok for
12 * internal use.
13 */
14 #include "internal/deprecated.h"
15
16 #include <string.h>
17
18 #include <openssl/bio.h>
19 #include <openssl/bn.h>
20 #include <openssl/rsa.h>
21 #include <openssl/evp.h>
22 #include <openssl/provider.h>
23 #include <openssl/core_names.h>
24 #include "internal/core.h"
25 #include "internal/nelem.h"
26 #include "crypto/evp.h" /* For the internal API */
27 #include "testutil.h"
28
29 typedef struct {
30 OSSL_LIB_CTX *ctx1;
31 OSSL_PROVIDER *prov1;
32 OSSL_LIB_CTX *ctx2;
33 OSSL_PROVIDER *prov2;
34 } FIXTURE;
35
36 static void tear_down(FIXTURE *fixture)
37 {
38 if (fixture != NULL) {
39 OSSL_PROVIDER_unload(fixture->prov1);
40 OSSL_PROVIDER_unload(fixture->prov2);
41 OSSL_LIB_CTX_free(fixture->ctx1);
42 OSSL_LIB_CTX_free(fixture->ctx2);
43 OPENSSL_free(fixture);
44 }
45 }
46
47 static FIXTURE *set_up(const char *testcase_name)
48 {
49 FIXTURE *fixture;
50
51 if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
52 || !TEST_ptr(fixture->ctx1 = OSSL_LIB_CTX_new())
53 || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1,
54 "default"))
55 || !TEST_ptr(fixture->ctx2 = OSSL_LIB_CTX_new())
56 || !TEST_ptr(fixture->prov2 = OSSL_PROVIDER_load(fixture->ctx2,
57 "default"))) {
58 tear_down(fixture);
59 return NULL;
60 }
61 return fixture;
62 }
63
64 /* Array indexes */
65 #define N 0
66 #define E 1
67 #define D 2
68 #define P 3
69 #define Q 4
70 #define F3 5 /* Extra factor */
71 #define DP 6
72 #define DQ 7
73 #define E3 8 /* Extra exponent */
74 #define QINV 9
75 #define C2 10 /* Extra coefficient */
76
77 /*
78 * We have to do this because OSSL_PARAM_get_ulong() can't handle params
79 * holding data that isn't exactly sizeof(uint32_t) or sizeof(uint64_t),
80 * and because the other end deals with BIGNUM, the resulting param might
81 * be any size. In this particular test, we know that the expected data
82 * fits within an unsigned long, and we want to get the data in that form
83 * to make testing of values easier.
84 */
85 static int get_ulong_via_BN(const OSSL_PARAM *p, unsigned long *goal)
86 {
87 BIGNUM *n = NULL;
88 int ret = 1; /* Ever so hopeful */
89
90 if (!TEST_true(OSSL_PARAM_get_BN(p, &n))
91 || !TEST_true(BN_bn2nativepad(n, (unsigned char *)goal, sizeof(*goal))))
92 ret = 0;
93 BN_free(n);
94 return ret;
95 }
96
97 static int export_cb(const OSSL_PARAM *params, void *arg)
98 {
99 unsigned long *keydata = arg;
100 const OSSL_PARAM *p = NULL;
101
102 if (keydata == NULL)
103 return 0;
104
105 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N))
106 || !TEST_true(get_ulong_via_BN(p, &keydata[N]))
107 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E))
108 || !TEST_true(get_ulong_via_BN(p, &keydata[E]))
109 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
110 || !TEST_true(get_ulong_via_BN(p, &keydata[D])))
111 return 0;
112
113 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1))
114 || !TEST_true(get_ulong_via_BN(p, &keydata[P]))
115 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2))
116 || !TEST_true(get_ulong_via_BN(p, &keydata[Q]))
117 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR3))
118 || !TEST_true(get_ulong_via_BN(p, &keydata[F3])))
119 return 0;
120
121 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT1))
122 || !TEST_true(get_ulong_via_BN(p, &keydata[DP]))
123 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT2))
124 || !TEST_true(get_ulong_via_BN(p, &keydata[DQ]))
125 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT3))
126 || !TEST_true(get_ulong_via_BN(p, &keydata[E3])))
127 return 0;
128
129 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1))
130 || !TEST_true(get_ulong_via_BN(p, &keydata[QINV]))
131 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT2))
132 || !TEST_true(get_ulong_via_BN(p, &keydata[C2])))
133 return 0;
134
135 return 1;
136 }
137
138 static int test_pass_rsa(FIXTURE *fixture)
139 {
140 size_t i;
141 int ret = 0;
142 RSA *rsa = NULL;
143 BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL;
144 EVP_PKEY *pk = NULL, *dup_pk = NULL;
145 EVP_KEYMGMT *km = NULL, *km1 = NULL, *km2 = NULL, *km3 = NULL;
146 void *provkey = NULL, *provkey2 = NULL;
147 BIGNUM *bn_primes[1] = { NULL };
148 BIGNUM *bn_exps[1] = { NULL };
149 BIGNUM *bn_coeffs[1] = { NULL };
150 /*
151 * 32-bit RSA key, extracted from this command,
152 * executed with OpenSSL 1.0.2:
153 * An extra factor was added just for testing purposes.
154 *
155 * openssl genrsa 32 | openssl rsa -text
156 */
157 static BN_ULONG expected[] = {
158 0xbc747fc5, /* N */
159 0x10001, /* E */
160 0x7b133399, /* D */
161 0xe963, /* P */
162 0xceb7, /* Q */
163 1, /* F3 */
164 0x8599, /* DP */
165 0xbd87, /* DQ */
166 2, /* E3 */
167 0xcc3b, /* QINV */
168 3, /* C3 */
169 0 /* Extra, should remain zero */
170 };
171 static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
172
173 if (!TEST_ptr(rsa = RSA_new()))
174 goto err;
175
176 if (!TEST_ptr(bn1 = BN_new())
177 || !TEST_true(BN_set_word(bn1, expected[N]))
178 || !TEST_ptr(bn2 = BN_new())
179 || !TEST_true(BN_set_word(bn2, expected[E]))
180 || !TEST_ptr(bn3 = BN_new())
181 || !TEST_true(BN_set_word(bn3, expected[D]))
182 || !TEST_true(RSA_set0_key(rsa, bn1, bn2, bn3)))
183 goto err;
184
185 if (!TEST_ptr(bn1 = BN_new())
186 || !TEST_true(BN_set_word(bn1, expected[P]))
187 || !TEST_ptr(bn2 = BN_new())
188 || !TEST_true(BN_set_word(bn2, expected[Q]))
189 || !TEST_true(RSA_set0_factors(rsa, bn1, bn2)))
190 goto err;
191
192 if (!TEST_ptr(bn1 = BN_new())
193 || !TEST_true(BN_set_word(bn1, expected[DP]))
194 || !TEST_ptr(bn2 = BN_new())
195 || !TEST_true(BN_set_word(bn2, expected[DQ]))
196 || !TEST_ptr(bn3 = BN_new())
197 || !TEST_true(BN_set_word(bn3, expected[QINV]))
198 || !TEST_true(RSA_set0_crt_params(rsa, bn1, bn2, bn3)))
199 goto err;
200 bn1 = bn2 = bn3 = NULL;
201
202 if (!TEST_ptr(bn_primes[0] = BN_new())
203 || !TEST_true(BN_set_word(bn_primes[0], expected[F3]))
204 || !TEST_ptr(bn_exps[0] = BN_new())
205 || !TEST_true(BN_set_word(bn_exps[0], expected[E3]))
206 || !TEST_ptr(bn_coeffs[0] = BN_new())
207 || !TEST_true(BN_set_word(bn_coeffs[0], expected[C2]))
208 || !TEST_true(RSA_set0_multi_prime_params(rsa, bn_primes, bn_exps,
209 bn_coeffs, 1)))
210 goto err;
211
212 if (!TEST_ptr(pk = EVP_PKEY_new())
213 || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
214 goto err;
215 rsa = NULL;
216
217 if (!TEST_ptr(km1 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA", NULL))
218 || !TEST_ptr(km2 = EVP_KEYMGMT_fetch(fixture->ctx2, "RSA", NULL))
219 || !TEST_ptr(km3 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA-PSS", NULL))
220 || !TEST_ptr_ne(km1, km2))
221 goto err;
222
223 while (dup_pk == NULL) {
224 ret = 0;
225 km = km3;
226 /* Check that we can't export an RSA key into a RSA-PSS keymanager */
227 if (!TEST_ptr_null(provkey2 = evp_pkey_export_to_provider(pk, NULL,
228 &km,
229 NULL)))
230 goto err;
231
232 if (!TEST_ptr(provkey = evp_pkey_export_to_provider(pk, NULL, &km1,
233 NULL))
234 || !TEST_true(evp_keymgmt_export(km2, provkey,
235 OSSL_KEYMGMT_SELECT_KEYPAIR,
236 &export_cb, keydata)))
237 goto err;
238
239 /*
240 * At this point, the hope is that keydata will have all the numbers
241 * from the key.
242 */
243
244 for (i = 0; i < OSSL_NELEM(expected); i++) {
245 int rv = TEST_int_eq(expected[i], keydata[i]);
246
247 if (!rv)
248 TEST_info("i = %zu", i);
249 else
250 ret++;
251 }
252
253 ret = (ret == OSSL_NELEM(expected));
254 if (!ret || !TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
255 goto err;
256
257 ret = TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
258 EVP_PKEY_free(pk);
259 pk = dup_pk;
260 if (!ret)
261 goto err;
262 }
263
264 err:
265 RSA_free(rsa);
266 BN_free(bn1);
267 BN_free(bn2);
268 BN_free(bn3);
269 EVP_PKEY_free(pk);
270 EVP_KEYMGMT_free(km1);
271 EVP_KEYMGMT_free(km2);
272 EVP_KEYMGMT_free(km3);
273
274 return ret;
275 }
276
277 static int (*tests[])(FIXTURE *) = {
278 test_pass_rsa
279 };
280
281 static int test_pass_key(int n)
282 {
283 SETUP_TEST_FIXTURE(FIXTURE, set_up);
284 EXECUTE_TEST(tests[n], tear_down);
285 return result;
286 }
287
288 int setup_tests(void)
289 {
290 ADD_ALL_TESTS(test_pass_key, 1);
291 return 1;
292 }