1308954Sdelphij/*
2308954Sdelphij * libssl_compat.c -- OpenSSL v1.1 compatibility functions
3308954Sdelphij *
4308954Sdelphij * ---------------------------------------------------------------------
5308954Sdelphij * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
6308954Sdelphij *
7308954Sdelphij * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
8308954Sdelphij *
9308954Sdelphij * ---------------------------------------------------------------------
10308954Sdelphij * This is a clean room implementation of shim functions that have
11308954Sdelphij * counterparts in the OpenSSL v1.1 API but not in earlier versions. So
12308954Sdelphij * while OpenSSL broke binary compatibility with v1.1, this shim module
13308954Sdelphij * should provide the necessary source code compatibility with older
14308954Sdelphij * versions of OpenSSL.
15308954Sdelphij * ---------------------------------------------------------------------
16308954Sdelphij */
17308954Sdelphij#include "config.h"
18308954Sdelphij#include "ntp_types.h"
19308954Sdelphij
20308954Sdelphij/* ----------------------------------------------------------------- */
21316069Sdelphij#ifdef OPENSSL
22316069Sdelphij# include <string.h>
23316069Sdelphij# include <openssl/bn.h>
24316069Sdelphij# include <openssl/evp.h>
25316069Sdelphij#endif
26308954Sdelphij/* ----------------------------------------------------------------- */
27308954Sdelphij
28316069Sdelphij/* ----------------------------------------------------------------- */
29316069Sdelphij#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
30316069Sdelphij/* ----------------------------------------------------------------- */
31316069Sdelphij
32308954Sdelphij#include "libssl_compat.h"
33308954Sdelphij#include "ntp_assert.h"
34308954Sdelphij
35308954Sdelphij/* --------------------------------------------------------------------
36308954Sdelphij * replace a BIGNUM owned by the caller with another one if it's not
37308954Sdelphij * NULL, taking over the ownership of the new value. This clears & frees
38308954Sdelphij * the old value -- the clear might be overkill, but it's better to err
39308954Sdelphij * on the side of paranoia here.
40308954Sdelphij */
41308954Sdelphijstatic void
42308954Sdelphijreplace_bn_nn(
43308954Sdelphij	BIGNUM **	ps,
44308954Sdelphij	BIGNUM *	n
45308954Sdelphij	)
46308954Sdelphij{
47308954Sdelphij	if (n) {
48308954Sdelphij		REQUIRE(*ps != n);
49308954Sdelphij		BN_clear_free(*ps);
50308954Sdelphij		*ps = n;
51308954Sdelphij	}
52308954Sdelphij}
53308954Sdelphij
54308954Sdelphij/* --------------------------------------------------------------------
55308954Sdelphij * allocation and deallocation of prime number callbacks
56308954Sdelphij */
57308954SdelphijBN_GENCB*
58308954SdelphijsslshimBN_GENCB_new(void)
59308954Sdelphij{
60308954Sdelphij	return calloc(1,sizeof(BN_GENCB));
61308954Sdelphij}
62308954Sdelphij
63308954Sdelphijvoid
64308954SdelphijsslshimBN_GENCB_free(
65308954Sdelphij	BN_GENCB	*cb
66308954Sdelphij	)
67308954Sdelphij{
68308954Sdelphij	free(cb);
69308954Sdelphij}
70308954Sdelphij
71308954Sdelphij/* --------------------------------------------------------------------
72308954Sdelphij * allocation and deallocation of message digests
73308954Sdelphij */
74308954SdelphijEVP_MD_CTX*
75308954Sdelphijsslshim_EVP_MD_CTX_new(void)
76308954Sdelphij{
77330141Sdelphij	EVP_MD_CTX *	ctx;
78330141Sdelphij	if (NULL != (ctx = calloc(1, sizeof(EVP_MD_CTX))))
79330141Sdelphij		EVP_MD_CTX_init(ctx);
80330141Sdelphij	return ctx;
81308954Sdelphij}
82308954Sdelphij
83308954Sdelphijvoid
84308954Sdelphijsslshim_EVP_MD_CTX_free(
85308954Sdelphij	EVP_MD_CTX *	pctx
86308954Sdelphij	)
87308954Sdelphij{
88308954Sdelphij	free(pctx);
89308954Sdelphij}
90308954Sdelphij
91308954Sdelphij/* --------------------------------------------------------------------
92308954Sdelphij * get EVP keys and key type
93308954Sdelphij */
94308954Sdelphijint
95308954Sdelphijsslshim_EVP_PKEY_id(
96308954Sdelphij	const EVP_PKEY *pkey
97308954Sdelphij	)
98308954Sdelphij{
99308954Sdelphij	return (pkey) ? pkey->type : EVP_PKEY_NONE;
100308954Sdelphij}
101308954Sdelphij
102308954Sdelphijint
103308954Sdelphijsslshim_EVP_PKEY_base_id(
104308954Sdelphij	const EVP_PKEY *pkey
105308954Sdelphij	)
106308954Sdelphij{
107308954Sdelphij	return (pkey) ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
108308954Sdelphij}
109308954Sdelphij
110308954SdelphijRSA*
111308954Sdelphijsslshim_EVP_PKEY_get0_RSA(
112308954Sdelphij	EVP_PKEY *	pkey
113308954Sdelphij	)
114308954Sdelphij{
115308954Sdelphij	return (pkey) ? pkey->pkey.rsa : NULL;
116308954Sdelphij}
117308954Sdelphij
118308954SdelphijDSA*
119308954Sdelphijsslshim_EVP_PKEY_get0_DSA(
120308954Sdelphij	EVP_PKEY *	pkey
121308954Sdelphij	)
122308954Sdelphij{
123308954Sdelphij	return (pkey) ? pkey->pkey.dsa : NULL;
124308954Sdelphij}
125308954Sdelphij
126308954Sdelphij/* --------------------------------------------------------------------
127308954Sdelphij * set/get RSA params
128308954Sdelphij */
129308954Sdelphijvoid
130308954Sdelphijsslshim_RSA_get0_key(
131308954Sdelphij	const RSA *	prsa,
132308954Sdelphij	const BIGNUM **	pn,
133308954Sdelphij	const BIGNUM **	pe,
134308954Sdelphij	const BIGNUM **	pd
135308954Sdelphij	)
136308954Sdelphij{
137308954Sdelphij	REQUIRE(prsa != NULL);
138308954Sdelphij
139308954Sdelphij	if (pn)
140308954Sdelphij		*pn = prsa->n;
141308954Sdelphij	if (pe)
142308954Sdelphij		*pe = prsa->e;
143308954Sdelphij	if (pd)
144308954Sdelphij		*pd = prsa->d;
145308954Sdelphij}
146308954Sdelphij
147308954Sdelphijint
148308954Sdelphijsslshim_RSA_set0_key(
149308954Sdelphij	RSA *		prsa,
150308954Sdelphij	BIGNUM *	n,
151308954Sdelphij	BIGNUM *	e,
152308954Sdelphij	BIGNUM *	d
153308954Sdelphij	)
154308954Sdelphij{
155308954Sdelphij	REQUIRE(prsa != NULL);
156308954Sdelphij	if (!((prsa->n || n) && (prsa->e || e)))
157308954Sdelphij		return 0;
158308954Sdelphij
159308954Sdelphij	replace_bn_nn(&prsa->n, n);
160308954Sdelphij	replace_bn_nn(&prsa->e, e);
161308954Sdelphij	replace_bn_nn(&prsa->d, d);
162308954Sdelphij
163308954Sdelphij	return 1;
164308954Sdelphij}
165308954Sdelphij
166308954Sdelphijvoid
167308954Sdelphijsslshim_RSA_get0_factors(
168308954Sdelphij	const RSA *	prsa,
169308954Sdelphij	const BIGNUM **	pp,
170308954Sdelphij	const BIGNUM **	pq
171308954Sdelphij	)
172308954Sdelphij{
173308954Sdelphij	REQUIRE(prsa != NULL);
174308954Sdelphij
175308954Sdelphij	if (pp)
176308954Sdelphij		*pp = prsa->p;
177308954Sdelphij	if (pq)
178308954Sdelphij		*pq = prsa->q;
179308954Sdelphij}
180308954Sdelphij
181308954Sdelphijint
182308954Sdelphijsslshim_RSA_set0_factors(
183308954Sdelphij	RSA    *	prsa,
184308954Sdelphij	BIGNUM *	p,
185308954Sdelphij	BIGNUM *	q
186308954Sdelphij	)
187308954Sdelphij{
188308954Sdelphij	REQUIRE(prsa != NULL);
189308954Sdelphij	if (!((prsa->p || p) && (prsa->q || q)))
190308954Sdelphij		return 0;
191308954Sdelphij
192308954Sdelphij	replace_bn_nn(&prsa->p, p);
193308954Sdelphij	replace_bn_nn(&prsa->q, q);
194308954Sdelphij
195308954Sdelphij	return 1;
196308954Sdelphij}
197308954Sdelphij
198308954Sdelphijint
199308954Sdelphijsslshim_RSA_set0_crt_params(
200308954Sdelphij	RSA    *	prsa,
201308954Sdelphij	BIGNUM *	dmp1,
202308954Sdelphij	BIGNUM *	dmq1,
203308954Sdelphij	BIGNUM *	iqmp
204308954Sdelphij	)
205308954Sdelphij{
206308954Sdelphij	REQUIRE(prsa != NULL);
207308954Sdelphij	if (!((prsa->dmp1 || dmp1) &&
208308954Sdelphij	      (prsa->dmq1 || dmq1) &&
209308954Sdelphij	      (prsa->iqmp || iqmp) ))
210308954Sdelphij		return 0;
211308954Sdelphij
212308954Sdelphij	replace_bn_nn(&prsa->dmp1, dmp1);
213308954Sdelphij	replace_bn_nn(&prsa->dmq1, dmq1);
214308954Sdelphij	replace_bn_nn(&prsa->iqmp, iqmp);
215308954Sdelphij
216308954Sdelphij	return 1;
217308954Sdelphij}
218308954Sdelphij
219308954Sdelphij/* --------------------------------------------------------------------
220308954Sdelphij * set/get DSA signature parameters
221308954Sdelphij */
222308954Sdelphijvoid
223308954Sdelphijsslshim_DSA_SIG_get0(
224308954Sdelphij	const DSA_SIG *	psig,
225308954Sdelphij	const BIGNUM **	pr,
226308954Sdelphij	const BIGNUM **	ps
227308954Sdelphij	)
228308954Sdelphij{
229308954Sdelphij	REQUIRE(psig != NULL);
230308954Sdelphij
231308954Sdelphij	if (pr != NULL)
232308954Sdelphij		*pr = psig->r;
233308954Sdelphij	if (ps != NULL)
234308954Sdelphij		*ps = psig->s;
235308954Sdelphij}
236308954Sdelphij
237308954Sdelphijint
238308954Sdelphijsslshim_DSA_SIG_set0(
239308954Sdelphij	DSA_SIG *	psig,
240308954Sdelphij	BIGNUM *	r,
241308954Sdelphij	BIGNUM *	s
242308954Sdelphij	)
243308954Sdelphij{
244308954Sdelphij	REQUIRE(psig != NULL);
245308954Sdelphij	if (!(r && s))
246308954Sdelphij		return 0;
247308954Sdelphij
248308954Sdelphij	replace_bn_nn(&psig->r, r);
249308954Sdelphij	replace_bn_nn(&psig->s, s);
250308954Sdelphij
251308954Sdelphij	return 1;
252308954Sdelphij}
253308954Sdelphij
254308954Sdelphij/* --------------------------------------------------------------------
255308954Sdelphij * get/set DSA parameters
256308954Sdelphij */
257308954Sdelphijvoid
258308954Sdelphijsslshim_DSA_get0_pqg(
259308954Sdelphij	const DSA *	pdsa,
260308954Sdelphij	const BIGNUM **	pp,
261308954Sdelphij	const BIGNUM **	pq,
262308954Sdelphij	const BIGNUM **	pg
263308954Sdelphij	)
264308954Sdelphij{
265308954Sdelphij	REQUIRE(pdsa != NULL);
266308954Sdelphij
267308954Sdelphij	if (pp != NULL)
268308954Sdelphij		*pp = pdsa->p;
269308954Sdelphij	if (pq != NULL)
270308954Sdelphij		*pq = pdsa->q;
271308954Sdelphij	if (pg != NULL)
272308954Sdelphij		*pg = pdsa->g;
273308954Sdelphij}
274308954Sdelphij
275308954Sdelphijint
276308954Sdelphijsslshim_DSA_set0_pqg(
277308954Sdelphij	DSA *		pdsa,
278308954Sdelphij	BIGNUM *	p,
279308954Sdelphij	BIGNUM *	q,
280308954Sdelphij	BIGNUM *	g
281308954Sdelphij	)
282308954Sdelphij{
283308954Sdelphij	if (!((pdsa->p || p) && (pdsa->q || q) && (pdsa->g || g)))
284308954Sdelphij		return 0;
285308954Sdelphij
286308954Sdelphij	replace_bn_nn(&pdsa->p, p);
287308954Sdelphij	replace_bn_nn(&pdsa->q, q);
288308954Sdelphij	replace_bn_nn(&pdsa->g, g);
289308954Sdelphij
290308954Sdelphij	return 1;
291308954Sdelphij}
292308954Sdelphij
293308954Sdelphijvoid
294308954Sdelphijsslshim_DSA_get0_key(
295308954Sdelphij	const DSA *	pdsa,
296308954Sdelphij	const BIGNUM **	ppub_key,
297308954Sdelphij	const BIGNUM **	ppriv_key
298308954Sdelphij	)
299308954Sdelphij{
300308954Sdelphij	REQUIRE(pdsa != NULL);
301308954Sdelphij
302308954Sdelphij	if (ppub_key != NULL)
303308954Sdelphij		*ppub_key = pdsa->pub_key;
304308954Sdelphij	if (ppriv_key != NULL)
305308954Sdelphij		*ppriv_key = pdsa->priv_key;
306308954Sdelphij}
307308954Sdelphij
308308954Sdelphijint
309308954Sdelphijsslshim_DSA_set0_key(
310308954Sdelphij	DSA *		pdsa,
311308954Sdelphij	BIGNUM *	pub_key,
312308954Sdelphij	BIGNUM *	priv_key
313308954Sdelphij	)
314308954Sdelphij{
315308954Sdelphij	REQUIRE(pdsa != NULL);
316308954Sdelphij	if (!(pdsa->pub_key || pub_key))
317308954Sdelphij		return 0;
318308954Sdelphij
319308954Sdelphij	replace_bn_nn(&pdsa->pub_key, pub_key);
320308954Sdelphij	replace_bn_nn(&pdsa->priv_key, priv_key);
321308954Sdelphij
322308954Sdelphij	return 1;
323308954Sdelphij}
324308954Sdelphij
325308954Sdelphijint
326308954Sdelphijsslshim_X509_get_signature_nid(
327308954Sdelphij	const X509 *x
328308954Sdelphij	)
329308954Sdelphij{
330308954Sdelphij	return OBJ_obj2nid(x->sig_alg->algorithm);
331308954Sdelphij}
332308954Sdelphij
333308954Sdelphij/* ----------------------------------------------------------------- */
334316069Sdelphij#else /* OPENSSL && OPENSSL_VERSION_NUMBER >= v1.1.0 */
335308954Sdelphij/* ----------------------------------------------------------------- */
336308954Sdelphij
337308954SdelphijNONEMPTY_TRANSLATION_UNIT
338308954Sdelphij
339308954Sdelphij/* ----------------------------------------------------------------- */
340308954Sdelphij#endif
341308954Sdelphij/* ----------------------------------------------------------------- */
342