2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 * RSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
18 #include <openssl/bio.h>
19 #include <openssl/bn.h>
20 #include <openssl/rsa.h>
21 #include <openssl/evp.h>
22 #include <openssl/pem.h>
23 #include <openssl/provider.h>
24 #include <openssl/core_names.h>
25 #include "internal/core.h"
26 #include "internal/nelem.h"
27 #include "crypto/evp.h" /* For the internal API */
37 /* Collected arguments */
38 static const char *cert_filename
= NULL
;
40 static void tear_down(FIXTURE
*fixture
)
42 if (fixture
!= NULL
) {
43 OSSL_PROVIDER_unload(fixture
->prov1
);
44 OSSL_PROVIDER_unload(fixture
->prov2
);
45 OSSL_LIB_CTX_free(fixture
->ctx1
);
46 OSSL_LIB_CTX_free(fixture
->ctx2
);
47 OPENSSL_free(fixture
);
51 static FIXTURE
*set_up(const char *testcase_name
)
55 if (!TEST_ptr(fixture
= OPENSSL_zalloc(sizeof(*fixture
)))
56 || !TEST_ptr(fixture
->ctx1
= OSSL_LIB_CTX_new())
57 || !TEST_ptr(fixture
->prov1
= OSSL_PROVIDER_load(fixture
->ctx1
,
59 || !TEST_ptr(fixture
->ctx2
= OSSL_LIB_CTX_new())
60 || !TEST_ptr(fixture
->prov2
= OSSL_PROVIDER_load(fixture
->ctx2
,
74 #define F3 5 /* Extra factor */
77 #define E3 8 /* Extra exponent */
79 #define C2 10 /* Extra coefficient */
82 * We have to do this because OSSL_PARAM_get_ulong() can't handle params
83 * holding data that isn't exactly sizeof(uint32_t) or sizeof(uint64_t),
84 * and because the other end deals with BIGNUM, the resulting param might
85 * be any size. In this particular test, we know that the expected data
86 * fits within an unsigned long, and we want to get the data in that form
87 * to make testing of values easier.
89 static int get_ulong_via_BN(const OSSL_PARAM
*p
, unsigned long *goal
)
92 int ret
= 1; /* Ever so hopeful */
94 if (!TEST_true(OSSL_PARAM_get_BN(p
, &n
))
95 || !TEST_int_ge(BN_bn2nativepad(n
, (unsigned char *)goal
, sizeof(*goal
)), 0))
101 static int export_cb(const OSSL_PARAM
*params
, void *arg
)
103 unsigned long *keydata
= arg
;
104 const OSSL_PARAM
*p
= NULL
;
109 if (!TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_N
))
110 || !TEST_true(get_ulong_via_BN(p
, &keydata
[N
]))
111 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_E
))
112 || !TEST_true(get_ulong_via_BN(p
, &keydata
[E
]))
113 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_D
))
114 || !TEST_true(get_ulong_via_BN(p
, &keydata
[D
])))
117 if (!TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_FACTOR1
))
118 || !TEST_true(get_ulong_via_BN(p
, &keydata
[P
]))
119 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_FACTOR2
))
120 || !TEST_true(get_ulong_via_BN(p
, &keydata
[Q
]))
121 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_FACTOR3
))
122 || !TEST_true(get_ulong_via_BN(p
, &keydata
[F3
])))
125 if (!TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_EXPONENT1
))
126 || !TEST_true(get_ulong_via_BN(p
, &keydata
[DP
]))
127 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_EXPONENT2
))
128 || !TEST_true(get_ulong_via_BN(p
, &keydata
[DQ
]))
129 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_EXPONENT3
))
130 || !TEST_true(get_ulong_via_BN(p
, &keydata
[E3
])))
133 if (!TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_COEFFICIENT1
))
134 || !TEST_true(get_ulong_via_BN(p
, &keydata
[QINV
]))
135 || !TEST_ptr(p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_COEFFICIENT2
))
136 || !TEST_true(get_ulong_via_BN(p
, &keydata
[C2
])))
142 static int test_pass_rsa(FIXTURE
*fixture
)
147 BIGNUM
*bn1
= NULL
, *bn2
= NULL
, *bn3
= NULL
;
148 EVP_PKEY
*pk
= NULL
, *dup_pk
= NULL
;
149 EVP_KEYMGMT
*km
= NULL
, *km1
= NULL
, *km2
= NULL
, *km3
= NULL
;
150 void *provkey
= NULL
, *provkey2
= NULL
;
151 BIGNUM
*bn_primes
[1] = { NULL
};
152 BIGNUM
*bn_exps
[1] = { NULL
};
153 BIGNUM
*bn_coeffs
[1] = { NULL
};
155 * 32-bit RSA key, extracted from this command,
156 * executed with OpenSSL 1.0.2:
157 * An extra factor was added just for testing purposes.
159 * openssl genrsa 32 | openssl rsa -text
161 static BN_ULONG expected
[] = {
173 0 /* Extra, should remain zero */
175 static unsigned long keydata
[OSSL_NELEM(expected
)] = { 0, };
177 if (!TEST_ptr(rsa
= RSA_new()))
180 if (!TEST_ptr(bn1
= BN_new())
181 || !TEST_true(BN_set_word(bn1
, expected
[N
]))
182 || !TEST_ptr(bn2
= BN_new())
183 || !TEST_true(BN_set_word(bn2
, expected
[E
]))
184 || !TEST_ptr(bn3
= BN_new())
185 || !TEST_true(BN_set_word(bn3
, expected
[D
]))
186 || !TEST_true(RSA_set0_key(rsa
, bn1
, bn2
, bn3
)))
189 if (!TEST_ptr(bn1
= BN_new())
190 || !TEST_true(BN_set_word(bn1
, expected
[P
]))
191 || !TEST_ptr(bn2
= BN_new())
192 || !TEST_true(BN_set_word(bn2
, expected
[Q
]))
193 || !TEST_true(RSA_set0_factors(rsa
, bn1
, bn2
)))
196 if (!TEST_ptr(bn1
= BN_new())
197 || !TEST_true(BN_set_word(bn1
, expected
[DP
]))
198 || !TEST_ptr(bn2
= BN_new())
199 || !TEST_true(BN_set_word(bn2
, expected
[DQ
]))
200 || !TEST_ptr(bn3
= BN_new())
201 || !TEST_true(BN_set_word(bn3
, expected
[QINV
]))
202 || !TEST_true(RSA_set0_crt_params(rsa
, bn1
, bn2
, bn3
)))
204 bn1
= bn2
= bn3
= NULL
;
206 if (!TEST_ptr(bn_primes
[0] = BN_new())
207 || !TEST_true(BN_set_word(bn_primes
[0], expected
[F3
]))
208 || !TEST_ptr(bn_exps
[0] = BN_new())
209 || !TEST_true(BN_set_word(bn_exps
[0], expected
[E3
]))
210 || !TEST_ptr(bn_coeffs
[0] = BN_new())
211 || !TEST_true(BN_set_word(bn_coeffs
[0], expected
[C2
]))
212 || !TEST_true(RSA_set0_multi_prime_params(rsa
, bn_primes
, bn_exps
,
216 if (!TEST_ptr(pk
= EVP_PKEY_new())
217 || !TEST_true(EVP_PKEY_assign_RSA(pk
, rsa
)))
221 if (!TEST_ptr(km1
= EVP_KEYMGMT_fetch(fixture
->ctx1
, "RSA", NULL
))
222 || !TEST_ptr(km2
= EVP_KEYMGMT_fetch(fixture
->ctx2
, "RSA", NULL
))
223 || !TEST_ptr(km3
= EVP_KEYMGMT_fetch(fixture
->ctx1
, "RSA-PSS", NULL
))
224 || !TEST_ptr_ne(km1
, km2
))
227 while (dup_pk
== NULL
) {
230 /* Check that we can't export an RSA key into a RSA-PSS keymanager */
231 if (!TEST_ptr_null(provkey2
= evp_pkey_export_to_provider(pk
, NULL
,
236 if (!TEST_ptr(provkey
= evp_pkey_export_to_provider(pk
, NULL
, &km1
,
238 || !TEST_true(evp_keymgmt_export(km2
, provkey
,
239 OSSL_KEYMGMT_SELECT_KEYPAIR
,
240 &export_cb
, keydata
)))
244 * At this point, the hope is that keydata will have all the numbers
248 for (i
= 0; i
< OSSL_NELEM(expected
); i
++) {
249 int rv
= TEST_int_eq(expected
[i
], keydata
[i
]);
252 TEST_info("i = %zu", i
);
257 ret
= (ret
== OSSL_NELEM(expected
));
258 if (!ret
|| !TEST_ptr(dup_pk
= EVP_PKEY_dup(pk
)))
261 ret
= TEST_int_eq(EVP_PKEY_eq(pk
, dup_pk
), 1);
274 EVP_KEYMGMT_free(km1
);
275 EVP_KEYMGMT_free(km2
);
276 EVP_KEYMGMT_free(km3
);
281 static int (*tests
[])(FIXTURE
*) = {
285 static int test_pass_key(int n
)
287 SETUP_TEST_FIXTURE(FIXTURE
, set_up
);
288 EXECUTE_TEST(tests
[n
], tear_down
);
292 static int test_evp_pkey_export_to_provider(int n
)
294 OSSL_LIB_CTX
*libctx
= NULL
;
295 OSSL_PROVIDER
*prov
= NULL
;
298 X509_PUBKEY
*pubkey
= NULL
;
299 EVP_KEYMGMT
*keymgmt
= NULL
;
300 EVP_PKEY
*pkey
= NULL
;
301 void *keydata
= NULL
;
304 if (!TEST_ptr(libctx
= OSSL_LIB_CTX_new())
305 || !TEST_ptr(prov
= OSSL_PROVIDER_load(libctx
, "default")))
308 if ((bio
= BIO_new_file(cert_filename
, "r")) == NULL
) {
309 TEST_error("Couldn't open '%s' for reading\n", cert_filename
);
310 TEST_openssl_errors();
314 if ((cert
= PEM_read_bio_X509(bio
, NULL
, NULL
, NULL
)) == NULL
) {
315 TEST_error("'%s' doesn't appear to be a X.509 certificate in PEM format\n",
317 TEST_openssl_errors();
321 pubkey
= X509_get_X509_PUBKEY(cert
);
322 pkey
= X509_PUBKEY_get0(pubkey
);
325 if (!TEST_ptr(keydata
= evp_pkey_export_to_provider(pkey
, NULL
,
329 if (!TEST_ptr(keydata
= evp_pkey_export_to_provider(pkey
, NULL
,
333 keymgmt
= EVP_KEYMGMT_fetch(libctx
, "RSA", NULL
);
335 if (!TEST_ptr(keydata
= evp_pkey_export_to_provider(pkey
, NULL
,
344 EVP_KEYMGMT_free(keymgmt
);
345 OSSL_PROVIDER_unload(prov
);
346 OSSL_LIB_CTX_free(libctx
);
350 int setup_tests(void)
352 if (!TEST_ptr(cert_filename
= test_get_argument(0)))
355 ADD_ALL_TESTS(test_pass_key
, 1);
356 ADD_ALL_TESTS(test_evp_pkey_export_to_provider
, 3);