pam_pkcs11 0.6.12
pam-pkcs11-ossl-compat.h
Go to the documentation of this file.
1/*
2 * sc-ossl-compat.h: OpenSC ecompatability for older OpenSSL versions
3 *
4 * Copyright (C) 2016 Douglas E. Engert <deengert@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _PAM_PKCS11_OSSL_COMPAT_H
22#define _PAM_PKCS11_OSSL_COMPAT_H
23
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include <openssl/opensslv.h>
30#include <openssl/opensslconf.h>
31/*
32 * Provide backward compatability to older versions of OpenSSL
33 * while using most of OpenSSL 1.1 API
34 */
35
36/*
37 * EVP_CIPHER_CTX functions:
38 * EVP_CIPHER_CTX_new not in 0.9.7
39 * EVP_CIPHER_CTX_free not in 0.9.7
40 * EVP_CIPHER_CTX_init in 0.9.7 to 1.0.2. defined in 1.1 as EVP_CIPHER_CTX_reset
41 * EVP_CIPHER_CTX_cleanup in 0.9.7 to 1.0.2, defined in 1.1 as EVP_CIPHER_CTX_reset
42 * EVP_CIPHER_CTX_reset only in 1.1
43 *
44 * EVP_CIPHER_CTX_new does a EVP_CIPHER_CTX_init
45 * EVP_CIPHER_CTX_free does a EVP_CIPHER_CTX_cleanup
46 * EVP_CIPHER_CTX_cleanup does equivelent of a EVP_CIPHER_CTX_init
47 * Use EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free, and EVP_CIPHER_CTX_cleanup between operations
48 */
49
50#if OPENSSL_VERSION_NUMBER <= 0x009070dfL
51
52/* in 0.9.7 EVP_CIPHER_CTX was always allocated inline or in other structures */
53
54#define EVP_CIPHER_CTX_new() ({ \
55 EVP_CIPHER_CTX * tmp = NULL; \
56 tmp = OPENSSL_malloc(sizeof(struct evp_cipher_ctx_st)); \
57 if (tmp) { \
58 EVP_CIPHER_CTX_init(tmp); \
59 } \
60 tmp; \
61 })
62
63#define EVP_CIPHER_CTX_free(x) ({ \
64 if (x) { \
65 EVP_CIPHER_CTX_cleanup(x); \
66 OPENSSL_free(x); \
67 } \
68 })
69#endif /* OPENSSL_VERSION_NUMBER =< 0x00907000L */
70
71/*
72 * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL
73 * use RSA_PKCS1_OpenSSL
74 * Previous versions are missing a number of functions to access
75 * some hidden structures. Define them here:
76 */
77
78/* EVP_PKEY_base_id introduced in 1.0.1 */
79#if OPENSSL_VERSION_NUMBER < 0x10001000L
80#define EVP_PKEY_base_id(x) (x->type)
81#endif
82
83#if OPENSSL_VERSION_NUMBER < 0x10100000L
84#define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
85#define OPENSSL_malloc_init CRYPTO_malloc_init
86
87#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa)
88#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa)
89#define X509_get_extension_flags(x) (x->ex_flags)
90#define X509_get_key_usage(x) (x->ex_kusage)
91#define X509_get_extended_key_usage(x) (x->ex_xkusage)
92#define EVP_MD_CTX_new EVP_MD_CTX_create
93#define EVP_MD_CTX_free EVP_MD_CTX_destroy
94#define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY)
95#define X509_up_ref(cert) CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509)
96#define X509_get0_tbs_sigalg(x) (x->cert_info->key->algor)
97#define X509_OBJECT_get0_X509(x) (x->data.x509)
98#define X509_OBJECT_get0_X509_CRL(x) (x->data.crl)
99#define RSA_get0_e(x) (x->e)
100#define RSA_get0_n(x) (x->n)
101#define ECDSA_SIG_get0_r(x) (x->r)
102#define ECDSA_SIG_get0_s(x) (x->s)
103
104#define X509_OBJECT_free(x) ({ \
105 if (x) { \
106 X509_OBJECT_free_contents(x); \
107 OPENSSL_free(x); \
108 } \
109 })
110#endif
111
112
113/*
114 * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures
115 * One can no longer use statements like rsa->n = ...
116 * Macros and defines don't work on all systems, so use inline versions
117 * If that is not good enough, vsersions could be added to libopensc
118 */
119
120#if OPENSSL_VERSION_NUMBER < 0x10100000L
121/* based on OpenSSL-1.1.0 e_os2.h */
122/* pam_pkcs11_ossl_inline: portable inline definition usable in public headers */
123# if !defined(inline) && !defined(__cplusplus)
124# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
125 /* just use inline */
126# define pam_pkcs11_ossl_inline inline
127# elif defined(__GNUC__) && __GNUC__>=2
128# define pam_pkcs11_ossl_inline __inline__
129# elif defined(_MSC_VER)
130# define pam_pkcs11_ossl_inline __inline
131# else
132# define pam_pkcs11_ossl_inline
133# endif
134# else
135# define pam_pkcs11_ossl_inline inline
136# endif
137#endif
138
139#if OPENSSL_VERSION_NUMBER < 0x10100000L
140
141#define RSA_bits(R) (BN_num_bits(R->n))
142
143#include <openssl/bn.h>
144#ifndef OPENSSL_NO_RSA
145#include <openssl/rsa.h>
146#endif
147#ifndef OPENSSL_NO_DSA
148#include <openssl/dsa.h>
149#endif
150
151#if 1
152#ifndef OPENSSL_NO_RSA
153static pam_pkcs11_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
154{
155 /* d is the private component and may be NULL */
156 if (n == NULL || e == NULL)
157 return 0;
158
159 BN_free(r->n);
160 BN_free(r->e);
161 BN_free(r->d);
162 r->n = n;
163 r->e = e;
164 r->d = d;
165
166 return 1;
167}
168
169static pam_pkcs11_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
170{
171 if (p == NULL || q == NULL)
172 return 0;
173
174 BN_free(r->p);
175 BN_free(r->q);
176 r->p = p;
177 r->q = q;
178
179 return 1;
180}
181
182static pam_pkcs11_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
183{
184 if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL)
185 return 0;
186
187 BN_free(r->dmp1);
188 BN_free(r->dmq1);
189 BN_free(r->iqmp);
190 r->dmp1 = dmp1;
191 r->dmq1 = dmq1;
192 r->iqmp = iqmp;
193
194 return 1;
195}
196
197static pam_pkcs11_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
198{
199 if (n != NULL)
200 *n = r->n;
201 if (e != NULL)
202 *e = r->e;
203 if (d != NULL)
204 *d = r->d;
205}
206
207static pam_pkcs11_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
208{
209 if (p != NULL)
210 *p = r->p;
211 if (q != NULL)
212 *q = r->q;
213}
214
216 const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
217{
218 if (dmp1 != NULL)
219 *dmp1 = r->dmp1;
220 if (dmq1 != NULL)
221 *dmq1 = r->dmq1;
222 if (iqmp != NULL)
223 *iqmp = r->iqmp;
224}
225
226#endif /* OPENSSL_NO_RSA */
227
228#ifndef OPENSSL_NO_DSA
229static pam_pkcs11_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
230{
231 if (p != NULL)
232 *p = d->p;
233 if (q != NULL)
234 *q = d->q;
235 if (g != NULL)
236 *g = d->g;
237}
238
239static pam_pkcs11_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
240{
241 if (pub_key != NULL)
242 *pub_key = d->pub_key;
243 if (priv_key != NULL)
244 *priv_key = d->priv_key;
245}
246
247/* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */
248#endif /* OPENSSL_NO_DSA */
249
250#else /* if we used macros */
251
252#define RSA_set0_key(R, N, E, D) \
253 ({ \
254 int ret = 0; \
255 if (!(N) || !(E)) { \
256 ret = 0; \
257 } else { \
258 BN_free(R->n); \
259 BN_free(R->e); \
260 BN_free(R->d); \
261 R->n = (N); \
262 R->e = (E); \
263 R->d = (D); \
264 ret = 1; \
265 } \
266 ret; \
267 })
268
269#define RSA_set0_factors(R, P, Q) \
270 ({ \
271 int ret= 0; \
272 if (!P || !Q) { \
273 ret = 0; \
274 } else { \
275 BN_free(R->p); \
276 BN_free(R->q); \
277 R->p = P; \
278 R->q = Q; \
279 ret = 1; \
280 } \
281 ret; \
282 })
283
284#define RSA_set0_crt_params(R, DMP1, DMQ1, IQMP) \
285 ({ \
286 int ret = 0; \
287 if (!DMP1 || !DMQ1 || !IQMP) { \
288 ret = 0; \
289 } else { \
290 BN_free(R->dmp1); \
291 BN_free(R->dmq1); \
292 BN_free(R->iqmp); \
293 R->dmp1 = DMP1; \
294 R->dmq1 = DMQ1; \
295 R->iqmp = IQMP; \
296 ret = 1; \
297 } \
298 ret; \
299 })
300
301#define RSA_get0_key(R, N, E, D) { \
302 BIGNUM **n = N; \
303 BIGNUM **e = E; \
304 BIGNUM **d = D; \
305 if (n) *(n) = R->n; \
306 if (e) *(e) = R->e; \
307 if (d) *(d) = R->d; \
308 }
309
310#define RSA_get0_factors(R, P, Q) {\
311 BIGNUM **p = P; \
312 BIGNUM **q = Q; \
313 if (p) *(p) = R->p; \
314 if (q) *(q) = R->q; \
315 }
316
317#define RSA_get0_crt_params(R, DMP1, DMQ1, IQMP) { \
318 BIGNUM **dmp1 = DMP1; \
319 BIGNUM **dmq1 = DMQ1; \
320 BIGNUM **iqmp = IQMP; \
321 if (dmp1) *(dmp1) = R->dmp1; \
322 if (dmq1) *(dmq1) = R->dmq1; \
323 if (iqmp) *(iqmp) = R->iqmp; \
324 }
325
326#define DSA_get0_key(D, PUB, PRIV) { \
327 BIGNUM **pub = PUB; \
328 BIGNUM **priv = PRIV; \
329 if (pub) *(pub) = D->pub_key; \
330 if (priv) *(priv) = D->priv_key; \
331 }
332
333#define DSA_get0_pqg(D, P, Q, G) { \
334 BIGNUM **p = P; \
335 BIGNUM **q = Q; \
336 BIGNUM **g = G; \
337 if (p) *(p) = D->p; \
338 if (q) *(q) = D->q; \
339 if (g) *(g) = D->g; \
340 }
341
342/* NOTE: DSA_set0_* functions not defined because they are not used in OpenSC */
343#endif /* 0 */
344#endif
345
346#ifdef __cplusplus
347}
348#endif
349
350#endif
static pam_pkcs11_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
static pam_pkcs11_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
static pam_pkcs11_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
#define pam_pkcs11_ossl_inline
static pam_pkcs11_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
static pam_pkcs11_ossl_inline void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
static pam_pkcs11_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
static pam_pkcs11_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
static pam_pkcs11_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)