1310419Sdelphij/*
2310419Sdelphij * libssl_compat.c -- OpenSSL v1.1 compatibility functions
3310419Sdelphij *
4310419Sdelphij * ---------------------------------------------------------------------
5310419Sdelphij * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
6310419Sdelphij *
7310419Sdelphij * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
8310419Sdelphij *
9310419Sdelphij * ---------------------------------------------------------------------
10310419Sdelphij * This is a clean room implementation of shim functions that have
11310419Sdelphij * counterparts in the OpenSSL v1.1 API but not in earlier versions. So
12310419Sdelphij * while OpenSSL broke binary compatibility with v1.1, this shim module
13310419Sdelphij * should provide the necessary source code compatibility with older
14310419Sdelphij * versions of OpenSSL.
15310419Sdelphij * ---------------------------------------------------------------------
16310419Sdelphij */
17310419Sdelphij#include "config.h"
18310419Sdelphij
19310419Sdelphij#include <string.h>
20310419Sdelphij#include <openssl/bn.h>
21310419Sdelphij#include <openssl/evp.h>
22310419Sdelphij
23310419Sdelphij#include "ntp_types.h"
24310419Sdelphij
25310419Sdelphij/* ----------------------------------------------------------------- */
26310419Sdelphij#if OPENSSL_VERSION_NUMBER < 0x10100000L
27310419Sdelphij/* ----------------------------------------------------------------- */
28310419Sdelphij
29310419Sdelphij#include "libssl_compat.h"
30310419Sdelphij#include "ntp_assert.h"
31310419Sdelphij
32310419Sdelphij/* --------------------------------------------------------------------
33310419Sdelphij * replace a BIGNUM owned by the caller with another one if it's not
34310419Sdelphij * NULL, taking over the ownership of the new value. This clears & frees
35310419Sdelphij * the old value -- the clear might be overkill, but it's better to err
36310419Sdelphij * on the side of paranoia here.
37310419Sdelphij */
38310419Sdelphijstatic void
39310419Sdelphijreplace_bn_nn(
40310419Sdelphij	BIGNUM **	ps,
41310419Sdelphij	BIGNUM *	n
42310419Sdelphij	)
43310419Sdelphij{
44310419Sdelphij	if (n) {
45310419Sdelphij		REQUIRE(*ps != n);
46310419Sdelphij		BN_clear_free(*ps);
47310419Sdelphij		*ps = n;
48310419Sdelphij	}
49310419Sdelphij}
50310419Sdelphij
51310419Sdelphij/* --------------------------------------------------------------------
52310419Sdelphij * allocation and deallocation of prime number callbacks
53310419Sdelphij */
54310419SdelphijBN_GENCB*
55310419SdelphijsslshimBN_GENCB_new(void)
56310419Sdelphij{
57310419Sdelphij	return calloc(1,sizeof(BN_GENCB));
58310419Sdelphij}
59310419Sdelphij
60310419Sdelphijvoid
61310419SdelphijsslshimBN_GENCB_free(
62310419Sdelphij	BN_GENCB	*cb
63310419Sdelphij	)
64310419Sdelphij{
65310419Sdelphij	free(cb);
66310419Sdelphij}
67310419Sdelphij
68310419Sdelphij/* --------------------------------------------------------------------
69310419Sdelphij * allocation and deallocation of message digests
70310419Sdelphij */
71310419SdelphijEVP_MD_CTX*
72310419Sdelphijsslshim_EVP_MD_CTX_new(void)
73310419Sdelphij{
74310419Sdelphij	return calloc(1, sizeof(EVP_MD_CTX));
75310419Sdelphij}
76310419Sdelphij
77310419Sdelphijvoid
78310419Sdelphijsslshim_EVP_MD_CTX_free(
79310419Sdelphij	EVP_MD_CTX *	pctx
80310419Sdelphij	)
81310419Sdelphij{
82310419Sdelphij	free(pctx);
83310419Sdelphij}
84310419Sdelphij
85310419Sdelphij/* --------------------------------------------------------------------
86310419Sdelphij * get EVP keys and key type
87310419Sdelphij */
88310419Sdelphijint
89310419Sdelphijsslshim_EVP_PKEY_id(
90310419Sdelphij	const EVP_PKEY *pkey
91310419Sdelphij	)
92310419Sdelphij{
93310419Sdelphij	return (pkey) ? pkey->type : EVP_PKEY_NONE;
94310419Sdelphij}
95310419Sdelphij
96310419Sdelphijint
97310419Sdelphijsslshim_EVP_PKEY_base_id(
98310419Sdelphij	const EVP_PKEY *pkey
99310419Sdelphij	)
100310419Sdelphij{
101310419Sdelphij	return (pkey) ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
102310419Sdelphij}
103310419Sdelphij
104310419SdelphijRSA*
105310419Sdelphijsslshim_EVP_PKEY_get0_RSA(
106310419Sdelphij	EVP_PKEY *	pkey
107310419Sdelphij	)
108310419Sdelphij{
109310419Sdelphij	return (pkey) ? pkey->pkey.rsa : NULL;
110310419Sdelphij}
111310419Sdelphij
112310419SdelphijDSA*
113310419Sdelphijsslshim_EVP_PKEY_get0_DSA(
114310419Sdelphij	EVP_PKEY *	pkey
115310419Sdelphij	)
116310419Sdelphij{
117310419Sdelphij	return (pkey) ? pkey->pkey.dsa : NULL;
118310419Sdelphij}
119310419Sdelphij
120310419Sdelphij/* --------------------------------------------------------------------
121310419Sdelphij * set/get RSA params
122310419Sdelphij */
123310419Sdelphijvoid
124310419Sdelphijsslshim_RSA_get0_key(
125310419Sdelphij	const RSA *	prsa,
126310419Sdelphij	const BIGNUM **	pn,
127310419Sdelphij	const BIGNUM **	pe,
128310419Sdelphij	const BIGNUM **	pd
129310419Sdelphij	)
130310419Sdelphij{
131310419Sdelphij	REQUIRE(prsa != NULL);
132310419Sdelphij
133310419Sdelphij	if (pn)
134310419Sdelphij		*pn = prsa->n;
135310419Sdelphij	if (pe)
136310419Sdelphij		*pe = prsa->e;
137310419Sdelphij	if (pd)
138310419Sdelphij		*pd = prsa->d;
139310419Sdelphij}
140310419Sdelphij
141310419Sdelphijint
142310419Sdelphijsslshim_RSA_set0_key(
143310419Sdelphij	RSA *		prsa,
144310419Sdelphij	BIGNUM *	n,
145310419Sdelphij	BIGNUM *	e,
146310419Sdelphij	BIGNUM *	d
147310419Sdelphij	)
148310419Sdelphij{
149310419Sdelphij	REQUIRE(prsa != NULL);
150310419Sdelphij	if (!((prsa->n || n) && (prsa->e || e)))
151310419Sdelphij		return 0;
152310419Sdelphij
153310419Sdelphij	replace_bn_nn(&prsa->n, n);
154310419Sdelphij	replace_bn_nn(&prsa->e, e);
155310419Sdelphij	replace_bn_nn(&prsa->d, d);
156310419Sdelphij
157310419Sdelphij	return 1;
158310419Sdelphij}
159310419Sdelphij
160310419Sdelphijvoid
161310419Sdelphijsslshim_RSA_get0_factors(
162310419Sdelphij	const RSA *	prsa,
163310419Sdelphij	const BIGNUM **	pp,
164310419Sdelphij	const BIGNUM **	pq
165310419Sdelphij	)
166310419Sdelphij{
167310419Sdelphij	REQUIRE(prsa != NULL);
168310419Sdelphij
169310419Sdelphij	if (pp)
170310419Sdelphij		*pp = prsa->p;
171310419Sdelphij	if (pq)
172310419Sdelphij		*pq = prsa->q;
173310419Sdelphij}
174310419Sdelphij
175310419Sdelphijint
176310419Sdelphijsslshim_RSA_set0_factors(
177310419Sdelphij	RSA    *	prsa,
178310419Sdelphij	BIGNUM *	p,
179310419Sdelphij	BIGNUM *	q
180310419Sdelphij	)
181310419Sdelphij{
182310419Sdelphij	REQUIRE(prsa != NULL);
183310419Sdelphij	if (!((prsa->p || p) && (prsa->q || q)))
184310419Sdelphij		return 0;
185310419Sdelphij
186310419Sdelphij	replace_bn_nn(&prsa->p, p);
187310419Sdelphij	replace_bn_nn(&prsa->q, q);
188310419Sdelphij
189310419Sdelphij	return 1;
190310419Sdelphij}
191310419Sdelphij
192310419Sdelphijint
193310419Sdelphijsslshim_RSA_set0_crt_params(
194310419Sdelphij	RSA    *	prsa,
195310419Sdelphij	BIGNUM *	dmp1,
196310419Sdelphij	BIGNUM *	dmq1,
197310419Sdelphij	BIGNUM *	iqmp
198310419Sdelphij	)
199310419Sdelphij{
200310419Sdelphij	REQUIRE(prsa != NULL);
201310419Sdelphij	if (!((prsa->dmp1 || dmp1) &&
202310419Sdelphij	      (prsa->dmq1 || dmq1) &&
203310419Sdelphij	      (prsa->iqmp || iqmp) ))
204310419Sdelphij		return 0;
205310419Sdelphij
206310419Sdelphij	replace_bn_nn(&prsa->dmp1, dmp1);
207310419Sdelphij	replace_bn_nn(&prsa->dmq1, dmq1);
208310419Sdelphij	replace_bn_nn(&prsa->iqmp, iqmp);
209310419Sdelphij
210310419Sdelphij	return 1;
211310419Sdelphij}
212310419Sdelphij
213310419Sdelphij/* --------------------------------------------------------------------
214310419Sdelphij * set/get DSA signature parameters
215310419Sdelphij */
216310419Sdelphijvoid
217310419Sdelphijsslshim_DSA_SIG_get0(
218310419Sdelphij	const DSA_SIG *	psig,
219310419Sdelphij	const BIGNUM **	pr,
220310419Sdelphij	const BIGNUM **	ps
221310419Sdelphij	)
222310419Sdelphij{
223310419Sdelphij	REQUIRE(psig != NULL);
224310419Sdelphij
225310419Sdelphij	if (pr != NULL)
226310419Sdelphij		*pr = psig->r;
227310419Sdelphij	if (ps != NULL)
228310419Sdelphij		*ps = psig->s;
229310419Sdelphij}
230310419Sdelphij
231310419Sdelphijint
232310419Sdelphijsslshim_DSA_SIG_set0(
233310419Sdelphij	DSA_SIG *	psig,
234310419Sdelphij	BIGNUM *	r,
235310419Sdelphij	BIGNUM *	s
236310419Sdelphij	)
237310419Sdelphij{
238310419Sdelphij	REQUIRE(psig != NULL);
239310419Sdelphij	if (!(r && s))
240310419Sdelphij		return 0;
241310419Sdelphij
242310419Sdelphij	replace_bn_nn(&psig->r, r);
243310419Sdelphij	replace_bn_nn(&psig->s, s);
244310419Sdelphij
245310419Sdelphij	return 1;
246310419Sdelphij}
247310419Sdelphij
248310419Sdelphij/* --------------------------------------------------------------------
249310419Sdelphij * get/set DSA parameters
250310419Sdelphij */
251310419Sdelphijvoid
252310419Sdelphijsslshim_DSA_get0_pqg(
253310419Sdelphij	const DSA *	pdsa,
254310419Sdelphij	const BIGNUM **	pp,
255310419Sdelphij	const BIGNUM **	pq,
256310419Sdelphij	const BIGNUM **	pg
257310419Sdelphij	)
258310419Sdelphij{
259310419Sdelphij	REQUIRE(pdsa != NULL);
260310419Sdelphij
261310419Sdelphij	if (pp != NULL)
262310419Sdelphij		*pp = pdsa->p;
263310419Sdelphij	if (pq != NULL)
264310419Sdelphij		*pq = pdsa->q;
265310419Sdelphij	if (pg != NULL)
266310419Sdelphij		*pg = pdsa->g;
267310419Sdelphij}
268310419Sdelphij
269310419Sdelphijint
270310419Sdelphijsslshim_DSA_set0_pqg(
271310419Sdelphij	DSA *		pdsa,
272310419Sdelphij	BIGNUM *	p,
273310419Sdelphij	BIGNUM *	q,
274310419Sdelphij	BIGNUM *	g
275310419Sdelphij	)
276310419Sdelphij{
277310419Sdelphij	if (!((pdsa->p || p) && (pdsa->q || q) && (pdsa->g || g)))
278310419Sdelphij		return 0;
279310419Sdelphij
280310419Sdelphij	replace_bn_nn(&pdsa->p, p);
281310419Sdelphij	replace_bn_nn(&pdsa->q, q);
282310419Sdelphij	replace_bn_nn(&pdsa->g, g);
283310419Sdelphij
284310419Sdelphij	return 1;
285310419Sdelphij}
286310419Sdelphij
287310419Sdelphijvoid
288310419Sdelphijsslshim_DSA_get0_key(
289310419Sdelphij	const DSA *	pdsa,
290310419Sdelphij	const BIGNUM **	ppub_key,
291310419Sdelphij	const BIGNUM **	ppriv_key
292310419Sdelphij	)
293310419Sdelphij{
294310419Sdelphij	REQUIRE(pdsa != NULL);
295310419Sdelphij
296310419Sdelphij	if (ppub_key != NULL)
297310419Sdelphij		*ppub_key = pdsa->pub_key;
298310419Sdelphij	if (ppriv_key != NULL)
299310419Sdelphij		*ppriv_key = pdsa->priv_key;
300310419Sdelphij}
301310419Sdelphij
302310419Sdelphijint
303310419Sdelphijsslshim_DSA_set0_key(
304310419Sdelphij	DSA *		pdsa,
305310419Sdelphij	BIGNUM *	pub_key,
306310419Sdelphij	BIGNUM *	priv_key
307310419Sdelphij	)
308310419Sdelphij{
309310419Sdelphij	REQUIRE(pdsa != NULL);
310310419Sdelphij	if (!(pdsa->pub_key || pub_key))
311310419Sdelphij		return 0;
312310419Sdelphij
313310419Sdelphij	replace_bn_nn(&pdsa->pub_key, pub_key);
314310419Sdelphij	replace_bn_nn(&pdsa->priv_key, priv_key);
315310419Sdelphij
316310419Sdelphij	return 1;
317310419Sdelphij}
318310419Sdelphij
319310419Sdelphijint
320310419Sdelphijsslshim_X509_get_signature_nid(
321310419Sdelphij	const X509 *x
322310419Sdelphij	)
323310419Sdelphij{
324310419Sdelphij	return OBJ_obj2nid(x->sig_alg->algorithm);
325310419Sdelphij}
326310419Sdelphij
327310419Sdelphij/* ----------------------------------------------------------------- */
328310419Sdelphij#else /* OPENSSL_VERSION_NUMBER >= v1.1.0 */
329310419Sdelphij/* ----------------------------------------------------------------- */
330310419Sdelphij
331310419SdelphijNONEMPTY_TRANSLATION_UNIT
332310419Sdelphij
333310419Sdelphij/* ----------------------------------------------------------------- */
334310419Sdelphij#endif
335310419Sdelphij/* ----------------------------------------------------------------- */
336