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 OPENSSL_COMPAT_H
20#define OPENSSL_COMPAT_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
50extern "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 *
301 {
302 return ssl->param;
303 }
304#endif
305} /* extern "C" */
306
307inline 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 /* OPENSSL_COMPAT_H */
321
void error(char *format,...)
#define assert(EX)
Definition: assert.h:17
A const & min(A const &lhs, A const &rhs)
const SSL_CIPHER * SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
Definition: openssl.h:139
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
Definition: openssl.h:292
void * BIO_get_data(BIO *table)
Definition: openssl.h:62
void SQUID_OPENSSL_init_ssl(void)
Definition: openssl.h:308
X509_VERIFY_PARAM * SSL_get0_param(SSL *ssl)
Definition: openssl.h:300
const unsigned char * SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
Definition: openssl.h:147
void BIO_set_init(BIO *table, int init)
Definition: openssl.h:74
size_t SSL_get_client_random(const SSL *ssl, unsigned char *outStart, size_t outSizeMax)
Definition: openssl.h:157
void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x)
Definition: openssl.h:219
STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
Definition: openssl.h:237
X509 * X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
Definition: openssl.h:230
const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
Definition: openssl.h:54
void BIO_set_data(BIO *table, void *data)
Definition: openssl.h:68
RSA * EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
Definition: openssl.h:104
int BIO_get_init(BIO *table)
Definition: openssl.h:82
size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *outStart, size_t outSizeMax)
Definition: openssl.h:178

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors