pam_pkcs11  0.6.11
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 #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
153 static 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 
169 static 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 
182 static 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 
197 static 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 
207 static 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
229 static 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 
239 static 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 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)