1/*
2 * libssl_compat.c -- OpenSSL v1.1 compatibility functions
3 *
4 * ---------------------------------------------------------------------
5 * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
6 *
7 * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
8 *
9 * ---------------------------------------------------------------------
10 * This is a clean room implementation of shim functions that have
11 * counterparts in the OpenSSL v1.1 API but not in earlier versions. So
12 * while OpenSSL broke binary compatibility with v1.1, this shim module
13 * should provide the necessary source code compatibility with older
14 * versions of OpenSSL.
15 * ---------------------------------------------------------------------
16 */
17#include "config.h"
18#include "ntp_types.h"
19
20/* ----------------------------------------------------------------- */
21#ifdef OPENSSL
22# include <string.h>
23# include <openssl/bn.h>
24# include <openssl/evp.h>
25#endif
26/* ----------------------------------------------------------------- */
27
28/* ----------------------------------------------------------------- */
29#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
30/* ----------------------------------------------------------------- */
31
32#include "libssl_compat.h"
33#include "ntp_assert.h"
34
35/* --------------------------------------------------------------------
36 * replace a BIGNUM owned by the caller with another one if it's not
37 * NULL, taking over the ownership of the new value. This clears & frees
38 * the old value -- the clear might be overkill, but it's better to err
39 * on the side of paranoia here.
40 */
41static void
42replace_bn_nn(
43	BIGNUM **	ps,
44	BIGNUM *	n
45	)
46{
47	if (n) {
48		REQUIRE(*ps != n);
49		BN_clear_free(*ps);
50		*ps = n;
51	}
52}
53
54/* --------------------------------------------------------------------
55 * allocation and deallocation of prime number callbacks
56 */
57BN_GENCB*
58sslshimBN_GENCB_new(void)
59{
60	return calloc(1,sizeof(BN_GENCB));
61}
62
63void
64sslshimBN_GENCB_free(
65	BN_GENCB	*cb
66	)
67{
68	free(cb);
69}
70
71/* --------------------------------------------------------------------
72 * allocation and deallocation of message digests
73 */
74EVP_MD_CTX*
75sslshim_EVP_MD_CTX_new(void)
76{
77	EVP_MD_CTX *	ctx;
78	if (NULL != (ctx = calloc(1, sizeof(EVP_MD_CTX))))
79		EVP_MD_CTX_init(ctx);
80	return ctx;
81}
82
83void
84sslshim_EVP_MD_CTX_free(
85	EVP_MD_CTX *	pctx
86	)
87{
88	free(pctx);
89}
90
91/* --------------------------------------------------------------------
92 * get EVP keys and key type
93 */
94int
95sslshim_EVP_PKEY_id(
96	const EVP_PKEY *pkey
97	)
98{
99	return (pkey) ? pkey->type : EVP_PKEY_NONE;
100}
101
102int
103sslshim_EVP_PKEY_base_id(
104	const EVP_PKEY *pkey
105	)
106{
107	return (pkey) ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
108}
109
110RSA*
111sslshim_EVP_PKEY_get0_RSA(
112	EVP_PKEY *	pkey
113	)
114{
115	return (pkey) ? pkey->pkey.rsa : NULL;
116}
117
118DSA*
119sslshim_EVP_PKEY_get0_DSA(
120	EVP_PKEY *	pkey
121	)
122{
123	return (pkey) ? pkey->pkey.dsa : NULL;
124}
125
126/* --------------------------------------------------------------------
127 * set/get RSA params
128 */
129void
130sslshim_RSA_get0_key(
131	const RSA *	prsa,
132	const BIGNUM **	pn,
133	const BIGNUM **	pe,
134	const BIGNUM **	pd
135	)
136{
137	REQUIRE(prsa != NULL);
138
139	if (pn)
140		*pn = prsa->n;
141	if (pe)
142		*pe = prsa->e;
143	if (pd)
144		*pd = prsa->d;
145}
146
147int
148sslshim_RSA_set0_key(
149	RSA *		prsa,
150	BIGNUM *	n,
151	BIGNUM *	e,
152	BIGNUM *	d
153	)
154{
155	REQUIRE(prsa != NULL);
156	if (!((prsa->n || n) && (prsa->e || e)))
157		return 0;
158
159	replace_bn_nn(&prsa->n, n);
160	replace_bn_nn(&prsa->e, e);
161	replace_bn_nn(&prsa->d, d);
162
163	return 1;
164}
165
166void
167sslshim_RSA_get0_factors(
168	const RSA *	prsa,
169	const BIGNUM **	pp,
170	const BIGNUM **	pq
171	)
172{
173	REQUIRE(prsa != NULL);
174
175	if (pp)
176		*pp = prsa->p;
177	if (pq)
178		*pq = prsa->q;
179}
180
181int
182sslshim_RSA_set0_factors(
183	RSA    *	prsa,
184	BIGNUM *	p,
185	BIGNUM *	q
186	)
187{
188	REQUIRE(prsa != NULL);
189	if (!((prsa->p || p) && (prsa->q || q)))
190		return 0;
191
192	replace_bn_nn(&prsa->p, p);
193	replace_bn_nn(&prsa->q, q);
194
195	return 1;
196}
197
198int
199sslshim_RSA_set0_crt_params(
200	RSA    *	prsa,
201	BIGNUM *	dmp1,
202	BIGNUM *	dmq1,
203	BIGNUM *	iqmp
204	)
205{
206	REQUIRE(prsa != NULL);
207	if (!((prsa->dmp1 || dmp1) &&
208	      (prsa->dmq1 || dmq1) &&
209	      (prsa->iqmp || iqmp) ))
210		return 0;
211
212	replace_bn_nn(&prsa->dmp1, dmp1);
213	replace_bn_nn(&prsa->dmq1, dmq1);
214	replace_bn_nn(&prsa->iqmp, iqmp);
215
216	return 1;
217}
218
219/* --------------------------------------------------------------------
220 * set/get DSA signature parameters
221 */
222void
223sslshim_DSA_SIG_get0(
224	const DSA_SIG *	psig,
225	const BIGNUM **	pr,
226	const BIGNUM **	ps
227	)
228{
229	REQUIRE(psig != NULL);
230
231	if (pr != NULL)
232		*pr = psig->r;
233	if (ps != NULL)
234		*ps = psig->s;
235}
236
237int
238sslshim_DSA_SIG_set0(
239	DSA_SIG *	psig,
240	BIGNUM *	r,
241	BIGNUM *	s
242	)
243{
244	REQUIRE(psig != NULL);
245	if (!(r && s))
246		return 0;
247
248	replace_bn_nn(&psig->r, r);
249	replace_bn_nn(&psig->s, s);
250
251	return 1;
252}
253
254/* --------------------------------------------------------------------
255 * get/set DSA parameters
256 */
257void
258sslshim_DSA_get0_pqg(
259	const DSA *	pdsa,
260	const BIGNUM **	pp,
261	const BIGNUM **	pq,
262	const BIGNUM **	pg
263	)
264{
265	REQUIRE(pdsa != NULL);
266
267	if (pp != NULL)
268		*pp = pdsa->p;
269	if (pq != NULL)
270		*pq = pdsa->q;
271	if (pg != NULL)
272		*pg = pdsa->g;
273}
274
275int
276sslshim_DSA_set0_pqg(
277	DSA *		pdsa,
278	BIGNUM *	p,
279	BIGNUM *	q,
280	BIGNUM *	g
281	)
282{
283	if (!((pdsa->p || p) && (pdsa->q || q) && (pdsa->g || g)))
284		return 0;
285
286	replace_bn_nn(&pdsa->p, p);
287	replace_bn_nn(&pdsa->q, q);
288	replace_bn_nn(&pdsa->g, g);
289
290	return 1;
291}
292
293void
294sslshim_DSA_get0_key(
295	const DSA *	pdsa,
296	const BIGNUM **	ppub_key,
297	const BIGNUM **	ppriv_key
298	)
299{
300	REQUIRE(pdsa != NULL);
301
302	if (ppub_key != NULL)
303		*ppub_key = pdsa->pub_key;
304	if (ppriv_key != NULL)
305		*ppriv_key = pdsa->priv_key;
306}
307
308int
309sslshim_DSA_set0_key(
310	DSA *		pdsa,
311	BIGNUM *	pub_key,
312	BIGNUM *	priv_key
313	)
314{
315	REQUIRE(pdsa != NULL);
316	if (!(pdsa->pub_key || pub_key))
317		return 0;
318
319	replace_bn_nn(&pdsa->pub_key, pub_key);
320	replace_bn_nn(&pdsa->priv_key, priv_key);
321
322	return 1;
323}
324
325int
326sslshim_X509_get_signature_nid(
327	const X509 *x
328	)
329{
330	return OBJ_obj2nid(x->sig_alg->algorithm);
331}
332
333/* ----------------------------------------------------------------- */
334#else /* OPENSSL && OPENSSL_VERSION_NUMBER >= v1.1.0 */
335/* ----------------------------------------------------------------- */
336
337NONEMPTY_TRANSLATION_UNIT
338
339/* ----------------------------------------------------------------- */
340#endif
341/* ----------------------------------------------------------------- */
342