pam_pkcs11  0.6.9
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
26 extern "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 
100 #define X509_OBJECT_free(x) ({ \
101  if (x) { \
102  X509_OBJECT_free_contents(x); \
103  OPENSSL_free(x); \
104  } \
105  })
106 #endif
107 
108 
109 /*
110  * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures
111  * One can no longer use statements like rsa->n = ...
112  * Macros and defines don't work on all systems, so use inline versions
113  * If that is not good enough, vsersions could be added to libopensc
114  */
115 
116 #if OPENSSL_VERSION_NUMBER < 0x10100000L
117 /* based on OpenSSL-1.1.0 e_os2.h */
118 /* pam_pkcs11_ossl_inline: portable inline definition usable in public headers */
119 # if !defined(inline) && !defined(__cplusplus)
120 # if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
121  /* just use inline */
122 # define pam_pkcs11_ossl_inline inline
123 # elif defined(__GNUC__) && __GNUC__>=2
124 # define pam_pkcs11_ossl_inline __inline__
125 # elif defined(_MSC_VER)
126 # define pam_pkcs11_ossl_inline __inline
127 # else
128 # define pam_pkcs11_ossl_inline
129 # endif
130 # else
131 # define pam_pkcs11_ossl_inline inline
132 # endif
133 #endif
134 
135 #if OPENSSL_VERSION_NUMBER < 0x10100000L
136 
137 #define RSA_bits(R) (BN_num_bits(R->n))
138 
139 #include <openssl/bn.h>
140 #ifndef OPENSSL_NO_RSA
141 #include <openssl/rsa.h>
142 #endif
143 #ifndef OPENSSL_NO_DSA
144 #include <openssl/dsa.h>
145 #endif
146 
147 #if 1
148 #ifndef OPENSSL_NO_RSA
149 static pam_pkcs11_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
150 {
151  /* d is the private component and may be NULL */
152  if (n == NULL || e == NULL)
153  return 0;
154 
155  BN_free(r->n);
156  BN_free(r->e);
157  BN_free(r->d);
158  r->n = n;
159  r->e = e;
160  r->d = d;
161 
162  return 1;
163 }
164 
165 static pam_pkcs11_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
166 {
167  if (p == NULL || q == NULL)
168  return 0;
169 
170  BN_free(r->p);
171  BN_free(r->q);
172  r->p = p;
173  r->q = q;
174 
175  return 1;
176 }
177 
178 static pam_pkcs11_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
179 {
180  if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL)
181  return 0;
182 
183  BN_free(r->dmp1);
184  BN_free(r->dmq1);
185  BN_free(r->iqmp);
186  r->dmp1 = dmp1;
187  r->dmq1 = dmq1;
188  r->iqmp = iqmp;
189 
190  return 1;
191 }
192 
193 static pam_pkcs11_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
194 {
195  if (n != NULL)
196  *n = r->n;
197  if (e != NULL)
198  *e = r->e;
199  if (d != NULL)
200  *d = r->d;
201 }
202 
203 static pam_pkcs11_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
204 {
205  if (p != NULL)
206  *p = r->p;
207  if (q != NULL)
208  *q = r->q;
209 }
210 
212  const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
213 {
214  if (dmp1 != NULL)
215  *dmp1 = r->dmp1;
216  if (dmq1 != NULL)
217  *dmq1 = r->dmq1;
218  if (iqmp != NULL)
219  *iqmp = r->iqmp;
220 }
221 
222 #endif /* OPENSSL_NO_RSA */
223 
224 #ifndef OPENSSL_NO_DSA
225 static pam_pkcs11_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
226 {
227  if (p != NULL)
228  *p = d->p;
229  if (q != NULL)
230  *q = d->q;
231  if (g != NULL)
232  *g = d->g;
233 }
234 
235 static pam_pkcs11_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
236 {
237  if (pub_key != NULL)
238  *pub_key = d->pub_key;
239  if (priv_key != NULL)
240  *priv_key = d->priv_key;
241 }
242 
243 /* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */
244 #endif /* OPENSSL_NO_DSA */
245 
246 #else /* if we used macros */
247 
248 #define RSA_set0_key(R, N, E, D) \
249  ({ \
250  int ret = 0; \
251  if (!(N) || !(E)) { \
252  ret = 0; \
253  } else { \
254  BN_free(R->n); \
255  BN_free(R->e); \
256  BN_free(R->d); \
257  R->n = (N); \
258  R->e = (E); \
259  R->d = (D); \
260  ret = 1; \
261  } \
262  ret; \
263  })
264 
265 #define RSA_set0_factors(R, P, Q) \
266  ({ \
267  int ret= 0; \
268  if (!P || !Q) { \
269  ret = 0; \
270  } else { \
271  BN_free(R->p); \
272  BN_free(R->q); \
273  R->p = P; \
274  R->q = Q; \
275  ret = 1; \
276  } \
277  ret; \
278  })
279 
280 #define RSA_set0_crt_params(R, DMP1, DMQ1, IQMP) \
281  ({ \
282  int ret = 0; \
283  if (!DMP1 || !DMQ1 || !IQMP) { \
284  ret = 0; \
285  } else { \
286  BN_free(R->dmp1); \
287  BN_free(R->dmq1); \
288  BN_free(R->iqmp); \
289  R->dmp1 = DMP1; \
290  R->dmq1 = DMQ1; \
291  R->iqmp = IQMP; \
292  ret = 1; \
293  } \
294  ret; \
295  })
296 
297 #define RSA_get0_key(R, N, E, D) { \
298  BIGNUM **n = N; \
299  BIGNUM **e = E; \
300  BIGNUM **d = D; \
301  if (n) *(n) = R->n; \
302  if (e) *(e) = R->e; \
303  if (d) *(d) = R->d; \
304  }
305 
306 #define RSA_get0_factors(R, P, Q) {\
307  BIGNUM **p = P; \
308  BIGNUM **q = Q; \
309  if (p) *(p) = R->p; \
310  if (q) *(q) = R->q; \
311  }
312 
313 #define RSA_get0_crt_params(R, DMP1, DMQ1, IQMP) { \
314  BIGNUM **dmp1 = DMP1; \
315  BIGNUM **dmq1 = DMQ1; \
316  BIGNUM **iqmp = IQMP; \
317  if (dmp1) *(dmp1) = R->dmp1; \
318  if (dmq1) *(dmq1) = R->dmq1; \
319  if (iqmp) *(iqmp) = R->iqmp; \
320  }
321 
322 #define DSA_get0_key(D, PUB, PRIV) { \
323  BIGNUM **pub = PUB; \
324  BIGNUM **priv = PRIV; \
325  if (pub) *(pub) = D->pub_key; \
326  if (priv) *(priv) = D->priv_key; \
327  }
328 
329 #define DSA_get0_pqg(D, P, Q, G) { \
330  BIGNUM **p = P; \
331  BIGNUM **q = Q; \
332  BIGNUM **g = G; \
333  if (p) *(p) = D->p; \
334  if (q) *(q) = D->q; \
335  if (g) *(g) = D->g; \
336  }
337 
338 /* NOTE: DSA_set0_* functions not defined because they are not used in OpenSC */
339 #endif /* 0 */
340 #endif
341 
342 #ifdef __cplusplus
343 }
344 #endif
345 
346 #endif
static pam_pkcs11_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
static pam_pkcs11_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
static pam_pkcs11_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
#define pam_pkcs11_ossl_inline
static pam_pkcs11_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
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 int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
static pam_pkcs11_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
static pam_pkcs11_ossl_inline void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)