]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/keymgmt_internal_test.c
Implement EVP_PKEY_dup() function
[thirdparty/openssl.git] / test / keymgmt_internal_test.c
CommitLineData
5a02d13d 1/*
33388b44 2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
5a02d13d
RL
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
d7e498ac
RL
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
5a02d13d
RL
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>
1640d48c 24#include "internal/core.h"
5a02d13d
RL
25#include "internal/nelem.h"
26#include "crypto/evp.h" /* For the internal API */
27#include "testutil.h"
28
29typedef struct {
b4250010 30 OSSL_LIB_CTX *ctx1;
5a02d13d 31 OSSL_PROVIDER *prov1;
b4250010 32 OSSL_LIB_CTX *ctx2;
5a02d13d
RL
33 OSSL_PROVIDER *prov2;
34} FIXTURE;
35
36static void tear_down(FIXTURE *fixture)
37{
38 if (fixture != NULL) {
39 OSSL_PROVIDER_unload(fixture->prov1);
40 OSSL_PROVIDER_unload(fixture->prov2);
b4250010
DMSP
41 OSSL_LIB_CTX_free(fixture->ctx1);
42 OSSL_LIB_CTX_free(fixture->ctx2);
5a02d13d
RL
43 OPENSSL_free(fixture);
44 }
45}
46
47static FIXTURE *set_up(const char *testcase_name)
48{
49 FIXTURE *fixture;
50
51 if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
b4250010 52 || !TEST_ptr(fixture->ctx1 = OSSL_LIB_CTX_new())
5a02d13d
RL
53 || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1,
54 "default"))
b4250010 55 || !TEST_ptr(fixture->ctx2 = OSSL_LIB_CTX_new())
5a02d13d
RL
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
1640d48c 64/* Array indexes */
5a02d13d
RL
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
96ebe52e 75#define C2 10 /* Extra coefficient */
5a02d13d 76
1640d48c
RL
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 */
85static 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
97static int export_cb(const OSSL_PARAM *params, void *arg)
98{
99 unsigned long *keydata = arg;
100 const OSSL_PARAM *p = NULL;
1640d48c
RL
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])))
96ebe52e 111 return 0;
1640d48c 112
96ebe52e
SL
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;
1640d48c
RL
136}
137
138static int test_pass_rsa(FIXTURE *fixture)
139{
5a02d13d
RL
140 size_t i;
141 int ret = 0;
142 RSA *rsa = NULL;
143 BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL;
2145ba5e 144 EVP_PKEY *pk = NULL, *dup_pk = NULL;
0fc39c90
SL
145 EVP_KEYMGMT *km = NULL, *km1 = NULL, *km2 = NULL, *km3 = NULL;
146 void *provkey = NULL, *provkey2 = NULL;
96ebe52e
SL
147 BIGNUM *bn_primes[1] = { NULL };
148 BIGNUM *bn_exps[1] = { NULL };
149 BIGNUM *bn_coeffs[1] = { NULL };
5a02d13d
RL
150 /*
151 * 32-bit RSA key, extracted from this command,
152 * executed with OpenSSL 1.0.2:
96ebe52e 153 * An extra factor was added just for testing purposes.
5a02d13d
RL
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 */
96ebe52e 163 1, /* F3 */
5a02d13d
RL
164 0x8599, /* DP */
165 0xbd87, /* DQ */
96ebe52e 166 2, /* E3 */
5a02d13d 167 0xcc3b, /* QINV */
96ebe52e 168 3, /* C3 */
5a02d13d
RL
169 0 /* Extra, should remain zero */
170 };
171 static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
5a02d13d
RL
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
96ebe52e
SL
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
5a02d13d
RL
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))
0fc39c90 219 || !TEST_ptr(km3 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA-PSS", NULL))
5a02d13d
RL
220 || !TEST_ptr_ne(km1, km2))
221 goto err;
222
2145ba5e
TM
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;
1640d48c 262 }
5a02d13d 263
5a02d13d
RL
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);
0fc39c90 272 EVP_KEYMGMT_free(km3);
5a02d13d
RL
273
274 return ret;
275}
276
277static int (*tests[])(FIXTURE *) = {
278 test_pass_rsa
279};
280
281static 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
288int setup_tests(void)
289{
290 ADD_ALL_TESTS(test_pass_key, 1);
291 return 1;
292}