libssl_compat.c revision 316068
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	return calloc(1, sizeof(EVP_MD_CTX));
78}
79
80void
81sslshim_EVP_MD_CTX_free(
82	EVP_MD_CTX *	pctx
83	)
84{
85	free(pctx);
86}
87
88/* --------------------------------------------------------------------
89 * get EVP keys and key type
90 */
91int
92sslshim_EVP_PKEY_id(
93	const EVP_PKEY *pkey
94	)
95{
96	return (pkey) ? pkey->type : EVP_PKEY_NONE;
97}
98
99int
100sslshim_EVP_PKEY_base_id(
101	const EVP_PKEY *pkey
102	)
103{
104	return (pkey) ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
105}
106
107RSA*
108sslshim_EVP_PKEY_get0_RSA(
109	EVP_PKEY *	pkey
110	)
111{
112	return (pkey) ? pkey->pkey.rsa : NULL;
113}
114
115DSA*
116sslshim_EVP_PKEY_get0_DSA(
117	EVP_PKEY *	pkey
118	)
119{
120	return (pkey) ? pkey->pkey.dsa : NULL;
121}
122
123/* --------------------------------------------------------------------
124 * set/get RSA params
125 */
126void
127sslshim_RSA_get0_key(
128	const RSA *	prsa,
129	const BIGNUM **	pn,
130	const BIGNUM **	pe,
131	const BIGNUM **	pd
132	)
133{
134	REQUIRE(prsa != NULL);
135
136	if (pn)
137		*pn = prsa->n;
138	if (pe)
139		*pe = prsa->e;
140	if (pd)
141		*pd = prsa->d;
142}
143
144int
145sslshim_RSA_set0_key(
146	RSA *		prsa,
147	BIGNUM *	n,
148	BIGNUM *	e,
149	BIGNUM *	d
150	)
151{
152	REQUIRE(prsa != NULL);
153	if (!((prsa->n || n) && (prsa->e || e)))
154		return 0;
155
156	replace_bn_nn(&prsa->n, n);
157	replace_bn_nn(&prsa->e, e);
158	replace_bn_nn(&prsa->d, d);
159
160	return 1;
161}
162
163void
164sslshim_RSA_get0_factors(
165	const RSA *	prsa,
166	const BIGNUM **	pp,
167	const BIGNUM **	pq
168	)
169{
170	REQUIRE(prsa != NULL);
171
172	if (pp)
173		*pp = prsa->p;
174	if (pq)
175		*pq = prsa->q;
176}
177
178int
179sslshim_RSA_set0_factors(
180	RSA    *	prsa,
181	BIGNUM *	p,
182	BIGNUM *	q
183	)
184{
185	REQUIRE(prsa != NULL);
186	if (!((prsa->p || p) && (prsa->q || q)))
187		return 0;
188
189	replace_bn_nn(&prsa->p, p);
190	replace_bn_nn(&prsa->q, q);
191
192	return 1;
193}
194
195int
196sslshim_RSA_set0_crt_params(
197	RSA    *	prsa,
198	BIGNUM *	dmp1,
199	BIGNUM *	dmq1,
200	BIGNUM *	iqmp
201	)
202{
203	REQUIRE(prsa != NULL);
204	if (!((prsa->dmp1 || dmp1) &&
205	      (prsa->dmq1 || dmq1) &&
206	      (prsa->iqmp || iqmp) ))
207		return 0;
208
209	replace_bn_nn(&prsa->dmp1, dmp1);
210	replace_bn_nn(&prsa->dmq1, dmq1);
211	replace_bn_nn(&prsa->iqmp, iqmp);
212
213	return 1;
214}
215
216/* --------------------------------------------------------------------
217 * set/get DSA signature parameters
218 */
219void
220sslshim_DSA_SIG_get0(
221	const DSA_SIG *	psig,
222	const BIGNUM **	pr,
223	const BIGNUM **	ps
224	)
225{
226	REQUIRE(psig != NULL);
227
228	if (pr != NULL)
229		*pr = psig->r;
230	if (ps != NULL)
231		*ps = psig->s;
232}
233
234int
235sslshim_DSA_SIG_set0(
236	DSA_SIG *	psig,
237	BIGNUM *	r,
238	BIGNUM *	s
239	)
240{
241	REQUIRE(psig != NULL);
242	if (!(r && s))
243		return 0;
244
245	replace_bn_nn(&psig->r, r);
246	replace_bn_nn(&psig->s, s);
247
248	return 1;
249}
250
251/* --------------------------------------------------------------------
252 * get/set DSA parameters
253 */
254void
255sslshim_DSA_get0_pqg(
256	const DSA *	pdsa,
257	const BIGNUM **	pp,
258	const BIGNUM **	pq,
259	const BIGNUM **	pg
260	)
261{
262	REQUIRE(pdsa != NULL);
263
264	if (pp != NULL)
265		*pp = pdsa->p;
266	if (pq != NULL)
267		*pq = pdsa->q;
268	if (pg != NULL)
269		*pg = pdsa->g;
270}
271
272int
273sslshim_DSA_set0_pqg(
274	DSA *		pdsa,
275	BIGNUM *	p,
276	BIGNUM *	q,
277	BIGNUM *	g
278	)
279{
280	if (!((pdsa->p || p) && (pdsa->q || q) && (pdsa->g || g)))
281		return 0;
282
283	replace_bn_nn(&pdsa->p, p);
284	replace_bn_nn(&pdsa->q, q);
285	replace_bn_nn(&pdsa->g, g);
286
287	return 1;
288}
289
290void
291sslshim_DSA_get0_key(
292	const DSA *	pdsa,
293	const BIGNUM **	ppub_key,
294	const BIGNUM **	ppriv_key
295	)
296{
297	REQUIRE(pdsa != NULL);
298
299	if (ppub_key != NULL)
300		*ppub_key = pdsa->pub_key;
301	if (ppriv_key != NULL)
302		*ppriv_key = pdsa->priv_key;
303}
304
305int
306sslshim_DSA_set0_key(
307	DSA *		pdsa,
308	BIGNUM *	pub_key,
309	BIGNUM *	priv_key
310	)
311{
312	REQUIRE(pdsa != NULL);
313	if (!(pdsa->pub_key || pub_key))
314		return 0;
315
316	replace_bn_nn(&pdsa->pub_key, pub_key);
317	replace_bn_nn(&pdsa->priv_key, priv_key);
318
319	return 1;
320}
321
322int
323sslshim_X509_get_signature_nid(
324	const X509 *x
325	)
326{
327	return OBJ_obj2nid(x->sig_alg->algorithm);
328}
329
330/* ----------------------------------------------------------------- */
331#else /* OPENSSL && OPENSSL_VERSION_NUMBER >= v1.1.0 */
332/* ----------------------------------------------------------------- */
333
334NONEMPTY_TRANSLATION_UNIT
335
336/* ----------------------------------------------------------------- */
337#endif
338/* ----------------------------------------------------------------- */
339