3 #From 03f3f8a6d56726bed26eb3202dfb1e485274ca90 Mon Sep 17 00:00:00 2001
4 #From: Bert Huijben <rhuijben@apache.org>
5 #Date: Thu, 16 Jun 2016 09:47:56 +0000
6 #Subject: [PATCH] Adapt to OpenSSL 1.1.x API changes.
8 #OpenSSL 1.1.x makes various types opaque, requiring the use of
9 #accessors, and rewrote the state machine describing the handshake
10 #process. Of particular interest to serf are the BIO, BIO_METHOD, and
13 #Patch by: 'James McCoy' <jamessan{_AT_}debian.org>
15 #* buckets/ssl_buckets.c
16 # (): New USE_LEGACY_OPENSSL define
17 # (): New X509_STORE_get0_param() define for use with pre-1.1.x OpenSSL
18 # (detect_renegotiate): Use SSL_get_state to check for the
19 # TLS_ST_SW_HELLO_REQ state, indicating the server is starting a new
21 # (bio_set_data, bio_get_data): New functions to abstract access to
23 # (bio_bucket_read, bio_bucket_write, bio_file_read, bio_file_write,
24 # bio_file_gets): Use bio_get_data.
25 # (bio_bucket_create): Use BIO accessor functions when available.
26 # (bio_meth_bucket_new, bio_meth_file_new): New functions to abstract
27 # creation of BIO_METHOD. With OpenSSL 1.1.x or newer, the BIO_meth_*
28 # functions are used to allocate a new BIO_METOD and set the
29 # callbacks, otherwise the pointers to the statically defined structs
31 # (bio_meth_free): New function.
32 # (ocsp_callback): Use OCSP_response_status to get status instead of
33 # accessing internals of OCSP_RESPONSE struct. Remove unused
34 # OCSP_RESPBYTES variable.
35 # (ssl_decrypt): Use SSL_get_state to check for the TLS_ST_OK state,
36 # indicating completed handshake.
37 # (init_ssl_libraries): Exclude threading code when OpenSSL 1.1.x is in
38 # use since OpenSSL now handles this appropriately without users of
39 # the library setting up locking functions.
40 # (ssl_need_client_cert, ssl_init_context, serf_ssl_load_cert_file,
41 # serf_ssl_add_crl_from_file): Use new bio_meth_*_new functions to
42 # provide the BIO_METHOD* to BIO_new(). Also use the bio_set_data
43 # function to set the data for the callback.
45 #* test/MockHTTPinC/MockHTTP_server.c
46 # (): New USE_OPENSSL_1_1_API define
47 # (bio_set_data, bio_get_data): New functions to abstract access to
49 # (bio_apr_socket_read, bio_apr_socket_write): Use bio_get_data.
50 # (bio_apr_socket_create): Use BIO accessor functions when available.
51 # (bio_meth_apr_socket_new): New function to abstract creation of
52 # BIO_METHOD. With OpenSSL 1.1.x or newer, the BIO_meth_* functions
53 # are used to allocate a new BIO_METOD and set the callbacks,
54 # otherwise the pointer to the statically defined struct is used.
55 # (initSSLCtx): Use new bio_meth_apr_socket_new function to
56 # provide the BIO_METHOD* to BIO_new(). Also use the bio_set_data
57 # function to set the data for the callback.
60 #git-svn-id: https://svn.apache.org/repos/asf/serf/trunk@1748673 13f79535-47bb-0310-9956-ffa450edef68
62 # buckets/ssl_buckets.c | 146 ++++++++++++++++++++++++-----
63 # test/MockHTTPinC/MockHTTP_server.c | 74 ++++++++++++++-
64 # 2 files changed, 194 insertions(+), 26 deletions(-)
66 --- modpagespeed-1.9.32.4/third_party/serf/instaweb_ssl_buckets.c.orig 2015-07-14 01:16:54.000000000 +0200
67 +++ modpagespeed-1.9.32.4/third_party/serf/instaweb_ssl_buckets.c 2019-04-17 06:45:35.833070953 +0200
69 #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
72 +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
73 +#define USE_LEGACY_OPENSSL
74 +#define X509_STORE_get0_param(store) store->param
78 /*#define SSL_VERBOSE*/
86 serf_ssl_stream_t encrypt;
87 serf_ssl_stream_t decrypt;
92 +static void bio_set_data(BIO *bio, void *data)
94 +#ifndef USE_LEGACY_OPENSSL
95 + BIO_set_data(bio, data);
101 +static void *bio_get_data(BIO *bio)
103 +#ifndef USE_LEGACY_OPENSSL
104 + return BIO_get_data(bio);
110 /* Returns the amount read. */
111 static int bio_bucket_read(BIO *bio, char *in, int inlen)
113 - serf_ssl_context_t *ctx = bio->ptr;
114 + serf_ssl_context_t *ctx = bio_get_data(bio);
119 /* Returns the amount written. */
120 static int bio_bucket_write(BIO *bio, const char *in, int inl)
122 - serf_ssl_context_t *ctx = bio->ptr;
123 + serf_ssl_context_t *ctx = bio_get_data(bio);
128 /* Returns the amount read. */
129 static int bio_file_read(BIO *bio, char *in, int inlen)
131 - apr_file_t *file = bio->ptr;
132 + apr_file_t *file = bio_get_data(bio);
137 /* Returns the amount written. */
138 static int bio_file_write(BIO *bio, const char *in, int inl)
140 - apr_file_t *file = bio->ptr;
141 + apr_file_t *file = bio_get_data(bio);
144 BIO_clear_retry_flags(bio);
145 @@ -324,10 +348,16 @@
147 static int bio_bucket_create(BIO *bio)
149 +#ifndef USE_LEGACY_OPENSSL
150 + BIO_set_shutdown(bio, 1);
151 + BIO_set_init(bio, 1);
152 + BIO_set_data(bio, NULL);
166 +#ifdef USE_LEGACY_OPENSSL
167 static BIO_METHOD bio_bucket_method = {
169 "Serf SSL encryption and decryption buckets",
171 NULL /* sslc does not have the callback_ctrl field */
176 +static BIO_METHOD *bio_meth_bucket_new(void)
178 + BIO_METHOD *biom = NULL;
180 +#ifndef USE_LEGACY_OPENSSL
181 + biom = BIO_meth_new(BIO_TYPE_MEM,
182 + "Serf SSL encryption and decryption buckets");
184 + BIO_meth_set_write(biom, bio_bucket_write);
185 + BIO_meth_set_read(biom, bio_bucket_read);
186 + BIO_meth_set_ctrl(biom, bio_bucket_ctrl);
187 + BIO_meth_set_create(biom, bio_bucket_create);
188 + BIO_meth_set_destroy(biom, bio_bucket_destroy);
191 + biom = &bio_bucket_method;
197 +static BIO_METHOD *bio_meth_file_new(void)
199 + BIO_METHOD *biom = NULL;
201 +#ifndef USE_LEGACY_OPENSSL
202 + biom = BIO_meth_new(BIO_TYPE_FILE, "Wrapper around APR file structures");
204 + BIO_meth_set_write(biom, bio_file_write);
205 + BIO_meth_set_read(biom, bio_file_read);
206 + BIO_meth_set_gets(biom, bio_file_gets);
207 + BIO_meth_set_ctrl(biom, bio_bucket_ctrl);
208 + BIO_meth_set_create(biom, bio_bucket_create);
209 + BIO_meth_set_destroy(biom, bio_bucket_destroy);
212 + biom = &bio_file_method;
218 +static void bio_meth_free(BIO_METHOD *biom)
220 +#ifndef USE_LEGACY_OPENSSL
221 + BIO_meth_free(biom);
226 validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx)
232 +#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
233 static apr_pool_t *ssl_pool;
234 static apr_thread_mutex_t **ssl_locks;
236 @@ -878,18 +959,22 @@
241 +#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
244 #ifndef OPENSSL_IS_BORINGSSL
245 +#ifndef USE_LEGACY_OPENSSL
246 + OPENSSL_malloc_init();
248 CRYPTO_malloc_init();
251 ERR_load_crypto_strings();
252 SSL_load_error_strings();
254 OpenSSL_add_all_algorithms();
257 +#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
258 numlocks = CRYPTO_num_locks();
259 apr_pool_create(&ssl_pool, NULL);
260 ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
262 const char *cert_path;
263 apr_file_t *cert_file;
268 int retrying_success = 0;
273 - bio = BIO_new(&bio_file_method);
274 - bio->ptr = cert_file;
275 + biom = bio_meth_file_new();
276 + bio = BIO_new(biom);
277 + bio_set_data(bio, cert_file);
279 ctx->cert_path = cert_path;
280 p12 = d2i_PKCS12_bio(bio, NULL);
285 + bio_meth_free(biom);
286 ctx->cached_cert = *cert;
287 ctx->cached_cert_pw = *pkey;
288 if (!retrying_success && ctx->cert_cache_pool) {
289 @@ -1005,6 +1093,7 @@
290 i = PKCS12_parse(p12, password, pkey, cert, NULL);
293 + bio_meth_free(biom);
294 ctx->cached_cert = *cert;
295 ctx->cached_cert_pw = *pkey;
296 if (!retrying_success && ctx->cert_cache_pool) {
297 @@ -1032,6 +1121,7 @@
301 + bio_meth_free(biom);
305 @@ -1039,6 +1129,7 @@
307 ERR_GET_REASON(err));
309 + bio_meth_free(biom);
313 @@ -1135,8 +1226,9 @@
314 SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
316 ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
317 - ssl_ctx->bio = BIO_new(&bio_bucket_method);
318 - ssl_ctx->bio->ptr = ssl_ctx;
319 + ssl_ctx->biom = bio_meth_bucket_new();
320 + ssl_ctx->bio = BIO_new(ssl_ctx->biom);
321 + bio_set_data(ssl_ctx->bio, ssl_ctx);
323 SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
325 @@ -1180,6 +1272,7 @@
327 SSL_CTX_free(ssl_ctx->ctx);
329 + bio_meth_free(ssl_ctx->biom);