openssl.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* OpenSSL API changed dramatically between 1.0.2 and 1.1.0, and
10  * compatibility was broken. Most of the structures became opaque,
11  * and access functions were created. There's no (safe) way to
12  * access the struct members any more, so the solution is to use
13  * the new API in the main code, and add the functions for older
14  * versions in compat/openssl.h.
15  * Once all the supported library versions use the new API, the shim
16  * can be dropped.
17  */
18 
19 #ifndef SQUID_COMPAT_OPENSSL_H
20 #define SQUID_COMPAT_OPENSSL_H
21 
22 #if !USE_OPENSSL
23 #error compat/openssl.h depends on USE_OPENSSL
24 #endif
25 
26 #include <algorithm>
27 
28 #if HAVE_OPENSSL_ASN1_H
29 #include <openssl/asn1.h>
30 #endif
31 #if HAVE_OPENSSL_BIO_H
32 #include <openssl/bio.h>
33 #endif
34 #if HAVE_OPENSSL_DH_H
35 #include <openssl/dh.h>
36 #endif
37 #if HAVE_OPENSSL_EVP_H
38 #include <openssl/evp.h>
39 #endif
40 #if HAVE_OPENSSL_LHASH_H
41 #include <openssl/lhash.h>
42 #endif
43 #if HAVE_OPENSSL_SSL_H
44 #include <openssl/ssl.h>
45 #endif
46 #if HAVE_OPENSSL_X509_H
47 #include <openssl/x509.h>
48 #endif
49 
50 extern "C" {
51 
52 #if !HAVE_LIBCRYPTO_ASN1_STRING_GET0_DATA
53  inline const unsigned char *
54  ASN1_STRING_get0_data(const ASN1_STRING *x)
55  {
56  return x->data;
57  }
58 #endif
59 
60 #if !HAVE_LIBCRYPTO_BIO_GET_DATA
61  inline void *
62  BIO_get_data(BIO *table)
63  {
64  return table->ptr;
65  }
66 
67  inline void
68  BIO_set_data(BIO *table, void *data)
69  {
70  table->ptr = data;
71  }
72 
73  inline void
74  BIO_set_init(BIO *table, int init)
75  {
76  table->init = init;
77  }
78 #endif
79 
80 #if !HAVE_LIBCRYPTO_BIO_GET_INIT
81  inline int
82  BIO_get_init(BIO *table)
83  {
84  return table->init;
85  }
86 #endif
87 
88 #if !HAVE_LIBCRYPTO_DH_UP_REF // OpenSSL 1.1 API
89 #if defined(CRYPTO_LOCK_DH) // OpenSSL 1.0 API
90  inline int
91  DH_up_ref(DH *t)
92  {
93  if (t && (CRYPTO_add(&t->references, 1, CRYPTO_LOCK_DH) > 1))
94  return 1;
95  return 0;
96  }
97 #else
98 #error missing both OpenSSL API features DH_up_ref (v1.1) and CRYPTO_LOCK_DH (v1.0)
99 #endif /* OpenSSL 1.0 CRYPTO_LOCK_DH */
100 #endif /* OpenSSL 1.1 DH_up_ref */
101 
102 #if !HAVE_LIBCRYPTO_EVP_PKEY_GET0_RSA
103  inline RSA *
104  EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
105  {
106  if (pkey->type != EVP_PKEY_RSA)
107  return nullptr;
108  return pkey->pkey.rsa;
109  }
110 #endif
111 
112 #if !HAVE_LIBCRYPTO_EVP_PKEY_UP_REF
113 #if defined(CRYPTO_LOCK_EVP_PKEY) // OpenSSL 1.0
114  inline int
115  EVP_PKEY_up_ref(EVP_PKEY *t)
116  {
117  if (t && (CRYPTO_add(&t->references, 1, CRYPTO_LOCK_EVP_PKEY)) > 1)
118  return 1;
119  return 0;
120  }
121 
122 #else
123 #error missing both OpenSSL API features EVP_PKEY_up_ref (v1.1) and CRYPTO_LOCK_EVP_PKEY (v1.0)
124 #endif /* OpenSSL 1.0 CRYPTO_LOCK_EVP_PKEY */
125 #endif /* OpenSSL 1.1 EVP_PKEY_up_ref */
126 
127 #if !HAVE_LIBCRYPTO_OPENSSL_LH_STRHASH
128 #define OPENSSL_LH_delete lh_delete
129 #define OPENSSL_LH_strhash lh_strhash
130 #endif
131 
132 #if !defined OPENSSL_VERSION
133 #define OPENSSL_VERSION SSLEAY_VERSION
134 #define OpenSSL_version SSLeay_version
135 #endif
136 
137 #if !HAVE_LIBSSL_SSL_CIPHER_FIND
138  inline const SSL_CIPHER *
139  SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
140  {
141  return ssl->method->get_cipher_by_char(ptr);
142  }
143 #endif
144 
145 #if !HAVE_LIBSSL_SSL_SESSION_GET_ID
146  inline const unsigned char *
147  SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
148  {
149  if (len)
150  *len = s->session_id_length;
151  return s->session_id;
152  }
153 #endif
154 
155 #if !HAVE_LIBSSL_SSL_GET_CLIENT_RANDOM
156  inline size_t
157  SSL_get_client_random(const SSL *ssl, unsigned char *outStart, size_t outSizeMax)
158  {
159  if (!ssl || !ssl->s3)
160  return 0;
161 
162  const auto &source = ssl->s3->client_random;
163 
164  const auto sourceSize = sizeof(source);
165  if (!outSizeMax)
166  return sourceSize; // special API case for sourceSize discovery
167 
168  const auto sourceStart = reinterpret_cast<const char *>(source);
169  const auto outSize = std::min(sourceSize, outSizeMax);
170  assert(outStart);
171  memmove(outStart, sourceStart, outSize);
172  return outSize;
173  }
174 #endif /* HAVE_LIBSSL_SSL_GET_CLIENT_RANDOM */
175 
176 #if !HAVE_LIBSSL_SSL_SESSION_GET_MASTER_KEY
177  inline size_t
178  SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *outStart, size_t outSizeMax)
179  {
180  if (!session || session->master_key_length <= 0)
181  return 0;
182 
183  const auto sourceSize = static_cast<size_t>(session->master_key_length);
184  if (!outSizeMax)
185  return sourceSize; // special API case for sourceSize discovery
186 
187  const auto sourceStart = reinterpret_cast<const char *>(session->master_key);
188  const auto outSize = std::min(sourceSize, outSizeMax);
189  assert(outStart);
190  memmove(outStart, sourceStart, outSize);
191  return outSize;
192  }
193 #endif /* HAVE_LIBSSL_SSL_SESSION_GET_MASTER_KEY */
194 
195 #if !HAVE_OPENSSL_TLS_CLIENT_METHOD
196 #define TLS_client_method SSLv23_client_method
197 #endif
198 
199 #if !HAVE_OPENSSL_TLS_SERVER_METHOD
200 #define TLS_server_method SSLv23_server_method
201 #endif
202 
203 #if !HAVE_LIBCRYPTO_X509_CRL_UP_REF // OpenSSL 1.1 API
204 #if defined(CRYPTO_LOCK_X509_CRL) // OpenSSL 1.0 API
205  inline int
206  X509_CRL_up_ref(X509_CRL *t)
207  {
208  if (t && (CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509_CRL) > 1))
209  return 1;
210  return 0;
211  }
212 #else
213 #error missing both OpenSSL API features X509_up_ref (v1.1) and CRYPTO_LOCK_X509 (v1.0)
214 #endif /* CRYPTO_LOCK_X509_CRL */
215 #endif /* X509_CRL_up_ref */
216 
217 #if !HAVE_LIBCRYPTO_X509_GET0_SIGNATURE
218  inline void
219  X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x)
220  {
221  if (psig)
222  *psig = x->signature;
223  if (palg)
224  *palg = x->sig_alg;
225  }
226 #endif
227 
228 #if !HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_CERT
229  inline X509 *
230  X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
231  {
232  return ctx->cert;
233  }
234 #endif
235 
236 #if !HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_UNTRUSTED
237  inline STACK_OF(X509) *
238  X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
239  {
240  return ctx->untrusted;
241  }
242 
246 #define X509_STORE_CTX_set0_untrusted X509_STORE_CTX_set_chain
247 #define X509_getm_notAfter X509_get_notAfter
248 #define X509_getm_notBefore X509_get_notBefore
249 #define X509_set1_notAfter X509_set_notAfter
250 #define X509_set1_notBefore X509_set_notBefore
251 #endif /* !HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_UNTRUSTED */
252 
253 #if !HAVE_LIBCRYPTO_X509_UP_REF // OpenSSL 1.1 API
254 #if defined(CRYPTO_LOCK_X509) // OpenSSL 1.0 API
255  inline int
256  X509_up_ref(X509 *t)
257  {
258  if (t && (CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509)) > 1)
259  return 1;
260  return 0;
261  }
262 #else
263 #error missing both OpenSSL API features X509_up_ref (v1.1) and CRYPTO_LOCK_X509 (v1.0)
264 #endif /* CRYPTO_LOCK_X509 */
265 #endif /* X509_up_ref */
266 
267 #if !HAVE_LIBCRYPTO_X509_CHAIN_UP_REF
268  inline STACK_OF(X509) *
269  X509_chain_up_ref(STACK_OF(X509) *chain)
270  {
271  if (STACK_OF(X509) *newChain = sk_X509_dup(chain)) {
272  bool error = false;
273  int i;
274  for (i = 0; !error && i < sk_X509_num(newChain); i++) {
275  X509 *cert = sk_X509_value(newChain, i);
276  if (!X509_up_ref(cert))
277  error = true;
278  }
279  if (!error)
280  return newChain;
281 
282  for (int k = 0; k < i; k++)
283  X509_free(sk_X509_value(newChain, k));
284  sk_X509_free(newChain);
285  }
286  return nullptr;
287  }
288 #endif /* X509_chain_up_ref */
289 
290 #if !HAVE_LIBCRYPTO_X509_VERIFY_PARAM_GET_DEPTH
291  inline int
292  X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
293  {
294  return param->depth;
295  }
296 #endif
297 
298 #if !HAVE_SSL_GET0_PARAM
299  inline X509_VERIFY_PARAM *
300  SSL_get0_param(SSL *ssl)
301  {
302  return ssl->param;
303  }
304 #endif
305 } /* extern "C" */
306 
307 inline void
309 {
310 #if HAVE_LIBSSL_OPENSSL_INIT_SSL
311  // OpenSSL will properly auto-initialize itself (in Squid context).
312  // No explicit initialization is required.
313  //OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, nullptr);
314 #else
315  SSL_load_error_strings();
316  SSLeay_add_ssl_algorithms();
317 #endif
318 }
319 
320 #endif /* SQUID_COMPAT_OPENSSL_H */
321 
const SSL_CIPHER * SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
Definition: openssl.h:139
void error(char *format,...)
X509_VERIFY_PARAM * SSL_get0_param(SSL *ssl)
Definition: openssl.h:300
RSA * EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
Definition: openssl.h:104
void * BIO_get_data(BIO *table)
Definition: openssl.h:62
int BIO_get_init(BIO *table)
Definition: openssl.h:82
void BIO_set_data(BIO *table, void *data)
Definition: openssl.h:68
void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x)
Definition: openssl.h:219
size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *outStart, size_t outSizeMax)
Definition: openssl.h:178
X509 * X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
Definition: openssl.h:230
#define assert(EX)
Definition: assert.h:17
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
Definition: openssl.h:292
const unsigned char * SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
Definition: openssl.h:147
void SQUID_OPENSSL_init_ssl(void)
Definition: openssl.h:308
const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
Definition: openssl.h:54
size_t SSL_get_client_random(const SSL *ssl, unsigned char *outStart, size_t outSizeMax)
Definition: openssl.h:157
STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
Definition: openssl.h:237
void BIO_set_init(BIO *table, int init)
Definition: openssl.h:74
const A & min(A const &lhs, A const &rhs)

 

Introduction

Documentation

Support

Miscellaneous