serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1748673 - in /serf/trunk: buckets/ssl_buckets.c test/MockHTTPinC/MockHTTP_server.c
Date Thu, 16 Jun 2016 09:47:56 GMT
Author: rhuijben
Date: Thu Jun 16 09:47:56 2016
New Revision: 1748673

URL: http://svn.apache.org/viewvc?rev=1748673&view=rev
Log:
Adapt to OpenSSL 1.1.x API changes.

OpenSSL 1.1.x makes various types opaque, requiring the use of
accessors, and rewrote the state machine describing the handshake
process.  Of particular interest to serf are the BIO, BIO_METHOD, and
X509_STORE types.

Patch by: 'James McCoy' <jamessan{_AT_}debian.org>

* buckets/ssl_buckets.c
  (): New USE_LEGACY_OPENSSL define
  (): New X509_STORE_get0_param() define for use with pre-1.1.x OpenSSL
  (detect_renegotiate): Use SSL_get_state to check for the
    TLS_ST_SW_HELLO_REQ state, indicating the server is starting a new
    negotiation.
  (bio_set_data, bio_get_data): New functions to abstract access to
    the BIO data.
  (bio_bucket_read, bio_bucket_write, bio_file_read, bio_file_write,
   bio_file_gets): Use bio_get_data.
  (bio_bucket_create): Use BIO accessor functions when available.
  (bio_meth_bucket_new, bio_meth_file_new): New functions to abstract
    creation of BIO_METHOD.  With OpenSSL 1.1.x or newer, the BIO_meth_*
    functions are used to allocate a new BIO_METOD and set the
    callbacks, otherwise the pointers to the statically defined structs
    are used.
  (bio_meth_free): New function.
  (ocsp_callback): Use OCSP_response_status to get status instead of
    accessing internals of OCSP_RESPONSE struct.  Remove unused
    OCSP_RESPBYTES variable.
  (ssl_decrypt): Use SSL_get_state to check for the TLS_ST_OK state,
    indicating completed handshake.
  (init_ssl_libraries): Exclude threading code when OpenSSL 1.1.x is in
    use since OpenSSL now handles this appropriately without users of
    the library setting up locking functions.
  (ssl_need_client_cert, ssl_init_context, serf_ssl_load_cert_file,
   serf_ssl_add_crl_from_file): Use new bio_meth_*_new functions to
   provide the BIO_METHOD* to BIO_new().  Also use the bio_set_data
   function to set the data for the callback.

* test/MockHTTPinC/MockHTTP_server.c
  (): New USE_OPENSSL_1_1_API define
  (bio_set_data, bio_get_data): New functions to abstract access to
    the BIO data.
  (bio_apr_socket_read, bio_apr_socket_write): Use bio_get_data.
  (bio_apr_socket_create): Use BIO accessor functions when available.
  (bio_meth_apr_socket_new): New function to abstract creation of
    BIO_METHOD.  With OpenSSL 1.1.x or newer, the BIO_meth_* functions
    are used to allocate a new BIO_METOD and set the callbacks,
    otherwise the pointer to the statically defined struct is used.
  (initSSLCtx): Use new bio_meth_apr_socket_new function to
   provide the BIO_METHOD* to BIO_new().  Also use the bio_set_data
   function to set the data for the callback.

Modified:
    serf/trunk/buckets/ssl_buckets.c
    serf/trunk/test/MockHTTPinC/MockHTTP_server.c

Modified: serf/trunk/buckets/ssl_buckets.c
URL: http://svn.apache.org/viewvc/serf/trunk/buckets/ssl_buckets.c?rev=1748673&r1=1748672&r2=1748673&view=diff
==============================================================================
--- serf/trunk/buckets/ssl_buckets.c (original)
+++ serf/trunk/buckets/ssl_buckets.c Thu Jun 16 09:47:56 2016
@@ -49,6 +49,11 @@
 #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
 #endif
 
+#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#define USE_LEGACY_OPENSSL
+#define X509_STORE_get0_param(store) store->param
+#endif
+
 
 /*
  * Here's an overview of the SSL bucket's relationship to OpenSSL and serf.
@@ -128,6 +133,7 @@ struct serf_ssl_context_t {
     SSL_CTX *ctx;
     SSL *ssl;
     BIO *bio;
+    BIO_METHOD *biom;
 
     serf_ssl_stream_t encrypt;
     serf_ssl_stream_t decrypt;
@@ -294,7 +300,11 @@ detect_renegotiate(const SSL *s, int whe
 #endif
 
     /* The server asked to renegotiate the SSL session. */
+#ifndef USE_LEGACY_OPENSSL
+    if (SSL_get_state(s) == TLS_ST_SW_HELLO_REQ) {
+#else
     if (SSL_state(s) == SSL_ST_RENEGOTIATE) {
+#endif
         serf_ssl_context_t *ssl_ctx = SSL_get_app_data(s);
 
         ssl_ctx->renegotiation = 1;
@@ -310,10 +320,28 @@ static void log_ssl_error(serf_ssl_conte
 
 }
 
+static void bio_set_data(BIO *bio, void *data)
+{
+#ifndef USE_LEGACY_OPENSSL
+    BIO_set_data(bio, data);
+#else
+    bio->ptr = data;
+#endif
+}
+
+static void *bio_get_data(BIO *bio)
+{
+#ifndef USE_LEGACY_OPENSSL
+    return BIO_get_data(bio);
+#else
+    return bio->ptr;
+#endif
+}
+
 /* Returns the amount read. */
 static int bio_bucket_read(BIO *bio, char *in, int inlen)
 {
-    serf_ssl_context_t *ctx = bio->ptr;
+    serf_ssl_context_t *ctx = bio_get_data(bio);
     const char *data;
     apr_status_t status;
     apr_size_t len;
@@ -356,7 +384,7 @@ static int bio_bucket_read(BIO *bio, cha
 /* Returns the amount written. */
 static int bio_bucket_write(BIO *bio, const char *in, int inl)
 {
-    serf_ssl_context_t *ctx = bio->ptr;
+    serf_ssl_context_t *ctx = bio_get_data(bio);
     serf_bucket_t *tmp;
 
     serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
@@ -384,7 +412,7 @@ static int bio_bucket_write(BIO *bio, co
 /* Returns the amount read. */
 static int bio_file_read(BIO *bio, char *in, int inlen)
 {
-    apr_file_t *file = bio->ptr;
+    apr_file_t *file = bio_get_data(bio);
     apr_status_t status;
     apr_size_t len;
 
@@ -406,7 +434,7 @@ static int bio_file_read(BIO *bio, char
 /* Returns the amount written. */
 static int bio_file_write(BIO *bio, const char *in, int inl)
 {
-    apr_file_t *file = bio->ptr;
+    apr_file_t *file = bio_get_data(bio);
     apr_size_t nbytes;
 
     BIO_clear_retry_flags(bio);
@@ -419,7 +447,7 @@ static int bio_file_write(BIO *bio, cons
 
 static int bio_file_gets(BIO *bio, char *in, int inlen)
 {
-    apr_file_t *file = bio->ptr;
+    apr_file_t *file = bio_get_data(bio);
     apr_status_t status;
 
     status = apr_file_gets(in, inlen, file);
@@ -435,10 +463,16 @@ static int bio_file_gets(BIO *bio, char
 
 static int bio_bucket_create(BIO *bio)
 {
+#ifndef USE_LEGACY_OPENSSL
+    BIO_set_shutdown(bio, 1);
+    BIO_set_init(bio, 1);
+    BIO_set_data(bio, NULL);
+#else
     bio->shutdown = 1;
     bio->init = 1;
     bio->num = -1;
     bio->ptr = NULL;
+#endif
 
     return 1;
 }
@@ -472,6 +506,7 @@ static long bio_bucket_ctrl(BIO *bio, in
     return ret;
 }
 
+#ifdef USE_LEGACY_OPENSSL
 static BIO_METHOD bio_bucket_method = {
     BIO_TYPE_MEM,
     "Serf SSL encryption and decryption buckets",
@@ -501,6 +536,56 @@ static BIO_METHOD bio_file_method = {
     NULL /* sslc does not have the callback_ctrl field */
 #endif
 };
+#endif
+
+static BIO_METHOD *bio_meth_bucket_new(void)
+{
+    BIO_METHOD *biom = NULL;
+
+#ifndef USE_LEGACY_OPENSSL
+    biom = BIO_meth_new(BIO_TYPE_MEM,
+                        "Serf SSL encryption and decryption buckets");
+    if (biom) {
+        BIO_meth_set_write(biom, bio_bucket_write);
+        BIO_meth_set_read(biom, bio_bucket_read);
+        BIO_meth_set_ctrl(biom, bio_bucket_ctrl);
+        BIO_meth_set_create(biom, bio_bucket_create);
+        BIO_meth_set_destroy(biom, bio_bucket_destroy);
+    }
+#else
+    biom = &bio_bucket_method;
+#endif
+
+    return biom;
+}
+
+static BIO_METHOD *bio_meth_file_new(void)
+{
+    BIO_METHOD *biom = NULL;
+
+#ifndef USE_LEGACY_OPENSSL
+    biom = BIO_meth_new(BIO_TYPE_FILE, "Wrapper around APR file structures");
+    if (biom) {
+        BIO_meth_set_write(biom, bio_file_write);
+        BIO_meth_set_read(biom, bio_file_read);
+        BIO_meth_set_gets(biom, bio_file_gets);
+        BIO_meth_set_ctrl(biom, bio_bucket_ctrl);
+        BIO_meth_set_create(biom, bio_bucket_create);
+        BIO_meth_set_destroy(biom, bio_bucket_destroy);
+    }
+#else
+    biom = &bio_file_method;
+#endif
+
+    return biom;
+}
+
+static void bio_meth_free(BIO_METHOD *biom)
+{
+#ifndef USE_LEGACY_OPENSSL
+    BIO_meth_free(biom);
+#endif
+}
 
 #ifndef OPENSSL_NO_TLSEXT
 /* Callback called when the server response has some OCSP info.
@@ -511,7 +596,6 @@ static int ocsp_callback(SSL *ssl, void
 {
     serf_ssl_context_t *ctx = (serf_ssl_context_t*)baton;
     OCSP_RESPONSE *response;
-    OCSP_RESPBYTES *rb;
     const unsigned char *resp_der;
     int len;
     long resp_status;
@@ -533,10 +617,8 @@ static int ocsp_callback(SSL *ssl, void
         return SSL_TLSEXT_ERR_ALERT_FATAL;
     }
 
-    rb = response->responseBytes;
-
     /* Did the server get a valid response from the OCSP responder */
-    resp_status = ASN1_ENUMERATED_get(response->responseStatus);
+    resp_status = OCSP_response_status(response);
     switch (resp_status) {
         case OCSP_RESPONSE_STATUS_SUCCESSFUL:
             break;
@@ -1028,8 +1110,12 @@ static apr_status_t ssl_decrypt(void *ba
         /* Once we got through the initial handshake, we should have received
            the ALPN information if there is such information. */
         ctx->handshake_finished = SSL_is_init_finished(ctx->ssl)
+#ifndef USE_LEGACY_OPENSSL
+                                  || (SSL_get_state(ctx->ssl) == TLS_ST_OK);
+#else
                                   || (SSL_state(ctx->ssl)
                                       & SSL_CB_HANDSHAKE_DONE);
+#endif
 
         /* Call the protocol callback as soon as possible as this triggers
            pipelining data for the selected protocol. */
@@ -1226,7 +1312,7 @@ static apr_status_t ssl_encrypt(void *ba
     return status;
 }
 
-#if APR_HAS_THREADS
+#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
 static apr_pool_t *ssl_pool;
 static apr_thread_mutex_t **ssl_locks;
 
@@ -1313,7 +1399,7 @@ static void init_ssl_libraries(void)
     val = apr_atomic_cas32(&have_init_ssl, INIT_BUSY, INIT_UNINITIALIZED);
 
     if (!val) {
-#if APR_HAS_THREADS
+#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
         int i, numlocks;
 #endif
 
@@ -1330,13 +1416,17 @@ static void init_ssl_libraries(void)
         }
 #endif
 
+#ifndef USE_LEGACY_OPENSSL
+        OPENSSL_malloc_init();
+#else
         CRYPTO_malloc_init();
+#endif
         ERR_load_crypto_strings();
         SSL_load_error_strings();
         SSL_library_init();
         OpenSSL_add_all_algorithms();
 
-#if APR_HAS_THREADS
+#if APR_HAS_THREADS && defined(USE_LEGACY_OPENSSL)
         numlocks = CRYPTO_num_locks();
         apr_pool_create(&ssl_pool, NULL);
         ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
@@ -1392,6 +1482,7 @@ static int ssl_need_client_cert(SSL *ssl
         const char *cert_path;
         apr_file_t *cert_file;
         BIO *bio;
+        BIO_METHOD *biom;
         PKCS12 *p12;
         int i;
         int retrying_success = 0;
@@ -1418,8 +1509,9 @@ static int ssl_need_client_cert(SSL *ssl
             continue;
         }
 
-        bio = BIO_new(&bio_file_method);
-        bio->ptr = cert_file;
+        biom = bio_meth_file_new();
+        bio = BIO_new(biom);
+        bio_set_data(bio, cert_file);
 
         ctx->cert_path = cert_path;
         p12 = d2i_PKCS12_bio(bio, NULL);
@@ -1430,6 +1522,7 @@ static int ssl_need_client_cert(SSL *ssl
 
         if (i == 1) {
             PKCS12_free(p12);
+            bio_meth_free(biom);
             ctx->cached_cert = *cert;
             ctx->cached_cert_pw = *pkey;
             if (!retrying_success && ctx->cert_cache_pool) {
@@ -1465,6 +1558,7 @@ static int ssl_need_client_cert(SSL *ssl
                         i = PKCS12_parse(p12, password, pkey, cert, NULL);
                         if (i == 1) {
                             PKCS12_free(p12);
+                            bio_meth_free(biom);
                             ctx->cached_cert = *cert;
                             ctx->cached_cert_pw = *pkey;
                             if (!retrying_success && ctx->cert_cache_pool) {
@@ -1492,6 +1586,7 @@ static int ssl_need_client_cert(SSL *ssl
                     }
                 }
                 PKCS12_free(p12);
+                bio_meth_free(biom);
                 return 0;
             }
             else {
@@ -1500,6 +1595,7 @@ static int ssl_need_client_cert(SSL *ssl
                           ERR_GET_FUNC(err),
                           ERR_GET_REASON(err));
                 PKCS12_free(p12);
+                bio_meth_free(biom);
             }
         }
     }
@@ -1630,8 +1726,9 @@ static serf_ssl_context_t *ssl_init_cont
     disable_compression(ssl_ctx);
 
     ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
-    ssl_ctx->bio = BIO_new(&bio_bucket_method);
-    ssl_ctx->bio->ptr = ssl_ctx;
+    ssl_ctx->biom = bio_meth_bucket_new();
+    ssl_ctx->bio = BIO_new(ssl_ctx->biom);
+    bio_set_data(ssl_ctx->bio, ssl_ctx);
 
     SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
 
@@ -1677,6 +1774,7 @@ static apr_status_t ssl_free_context(
     /* SSL_free implicitly frees the underlying BIO. */
     SSL_free(ssl_ctx->ssl);
     SSL_CTX_free(ssl_ctx->ctx);
+    bio_meth_free(ssl_ctx->biom);
 
     serf_bucket_mem_free(ssl_ctx->allocator, ssl_ctx);
 
@@ -1822,6 +1920,7 @@ apr_status_t serf_ssl_load_cert_file(
     apr_file_t *cert_file;
     apr_status_t status;
     BIO *bio;
+    BIO_METHOD *biom;
     X509 *ssl_cert;
 
     /* We use an apr file instead of an stdio.h file to avoid usage problems
@@ -1835,13 +1934,15 @@ apr_status_t serf_ssl_load_cert_file(
 
     init_ssl_libraries();
 
-    bio = BIO_new(&bio_file_method);
-    bio->ptr = cert_file;
+    biom = bio_meth_file_new();
+    bio = BIO_new(biom);
+    bio_set_data(bio, cert_file);
 
     ssl_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
 
     apr_file_close(cert_file);
     BIO_free(bio);
+    bio_meth_free(biom);
 
     if (ssl_cert) {
         /* TODO: Setup pool cleanup to free certificate */
@@ -1880,7 +1981,7 @@ apr_status_t serf_ssl_check_crl(serf_ssl
         X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|
                              X509_V_FLAG_CRL_CHECK_ALL);
     } else {
-        X509_VERIFY_PARAM_clear_flags(store->param, X509_V_FLAG_CRL_CHECK|
+        X509_VERIFY_PARAM_clear_flags(X509_STORE_get0_param(store), X509_V_FLAG_CRL_CHECK|
                                       X509_V_FLAG_CRL_CHECK_ALL);
     }
     return APR_SUCCESS;
@@ -1894,6 +1995,7 @@ apr_status_t serf_ssl_add_crl_from_file(
     X509_CRL *crl = NULL;
     X509_STORE *store;
     BIO *bio;
+    BIO_METHOD *biom;
     int result;
     apr_status_t status;
 
@@ -1903,13 +2005,15 @@ apr_status_t serf_ssl_add_crl_from_file(
         return status;
     }
 
-    bio = BIO_new(&bio_file_method);
-    bio->ptr = crl_file;
+    biom = bio_meth_file_new();
+    bio = BIO_new(biom);
+    bio_set_data(bio, crl_file);
 
     crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
 
     apr_file_close(crl_file);
     BIO_free(bio);
+    bio_meth_free(biom);
 
     store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
 

Modified: serf/trunk/test/MockHTTPinC/MockHTTP_server.c
URL: http://svn.apache.org/viewvc/serf/trunk/test/MockHTTPinC/MockHTTP_server.c?rev=1748673&r1=1748672&r2=1748673&view=diff
==============================================================================
--- serf/trunk/test/MockHTTPinC/MockHTTP_server.c (original)
+++ serf/trunk/test/MockHTTPinC/MockHTTP_server.c Thu Jun 16 09:47:56 2016
@@ -2239,6 +2239,10 @@ mhSetServerEnableOCSP(mhServCtx_t *ctx)
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
+#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#define USE_LEGACY_OPENSSL
+#endif
+
 struct sslCtx_t {
     bool handshake_done;
     bool renegotiate;
@@ -2247,6 +2251,7 @@ struct sslCtx_t {
     SSL_CTX* ctx;
     SSL* ssl;
     BIO *bio;
+    BIO_METHOD *biom;
 
     char read_buffer[8192];
 };
@@ -2273,14 +2278,38 @@ static int pem_passwd_cb(char *buf, int
  */
 static int bio_apr_socket_create(BIO *bio)
 {
+#ifndef USE_LEGACY_OPENSSL
+    BIO_set_shutdown(bio, 1);
+    BIO_set_init(bio, 1);
+    BIO_set_data(bio, NULL);
+#else
     bio->shutdown = 1;
     bio->init = 1;
     bio->num = -1;
     bio->ptr = NULL;
+#endif
 
     return 1;
 }
 
+static void bio_set_data(BIO *bio, void *data)
+{
+#ifndef USE_LEGACY_OPENSSL
+    BIO_set_data(bio, data);
+#else
+    bio->ptr = data;
+#endif
+}
+
+static void *bio_get_data(BIO *bio)
+{
+#ifndef USE_LEGACY_OPENSSL
+    return BIO_get_data(bio);
+#else
+    return bio->ptr;
+#endif
+}
+
 /**
  * OpenSSL BIO callback. Cleans up the BIO structure.
  */
@@ -2322,7 +2351,7 @@ static long bio_apr_socket_ctrl(BIO *bio
 static int bio_apr_socket_read(BIO *bio, char *in, int inlen)
 {
     apr_size_t len = inlen;
-    _mhClientCtx_t *cctx = bio->ptr;
+    _mhClientCtx_t *cctx = bio_get_data(bio);
     sslCtx_t *ssl_ctx = cctx->ssl_ctx;
     apr_status_t status;
 
@@ -2351,7 +2380,7 @@ static int bio_apr_socket_read(BIO *bio,
 static int bio_apr_socket_write(BIO *bio, const char *in, int inlen)
 {
     apr_size_t len = inlen;
-    _mhClientCtx_t *cctx = bio->ptr;
+    _mhClientCtx_t *cctx = bio_get_data(bio);
     sslCtx_t *ssl_ctx = cctx->ssl_ctx;
     apr_status_t status;
 
@@ -2375,6 +2404,7 @@ static int bio_apr_socket_write(BIO *bio
 }
 
 
+#ifdef USE_LEGACY_OPENSSL
 static BIO_METHOD bio_apr_socket_method = {
     BIO_TYPE_SOCKET,
     "APR sockets",
@@ -2389,6 +2419,34 @@ static BIO_METHOD bio_apr_socket_method
     NULL /* sslc does not have the callback_ctrl field */
 #endif
 };
+#endif
+
+static BIO_METHOD *bio_meth_apr_socket_new(void)
+{
+    BIO_METHOD *biom = NULL;
+
+#ifndef USE_LEGACY_OPENSSL
+    biom = BIO_meth_new(BIO_TYPE_SOCKET, "APR sockets");
+    if (biom) {
+        BIO_meth_set_write(biom, bio_apr_socket_write);
+        BIO_meth_set_read(biom, bio_apr_socket_read);
+        BIO_meth_set_ctrl(biom, bio_apr_socket_ctrl);
+        BIO_meth_set_create(biom, bio_apr_socket_create);
+        BIO_meth_set_destroy(biom, bio_apr_socket_destroy);
+    }
+#else
+    biom = &bio_apr_socket_method;
+#endif
+
+    return biom;
+}
+
+static void bio_meth_free(BIO_METHOD *biom)
+{
+#ifndef USE_LEGACY_OPENSSL
+    BIO_meth_free(biom);
+#endif
+}
 
 static int ocspCreateResponse(OCSP_RESPONSE **resp, mhOCSPRespnseStatus_t status)
 {
@@ -2527,8 +2585,10 @@ static apr_status_t cleanupSSL(void *bat
     sslCtx_t *ssl_ctx = cctx->ssl_ctx;
 
     if (ssl_ctx) {
-        if (ssl_ctx->ssl)
+        if (ssl_ctx->ssl) {
             SSL_clear(ssl_ctx->ssl);
+            bio_meth_free(ssl_ctx->biom);
+        }
         SSL_CTX_free(ssl_ctx->ctx);
     }
 
@@ -2608,7 +2668,11 @@ static apr_status_t initSSLCtx(_mhClient
     /* Init OpenSSL globally */
     if (!init_done)
     {
+#ifndef USE_LEGACY_OPENSSL
+        OPENSSL_malloc_init();
+#else
         CRYPTO_malloc_init();
+#endif
         ERR_load_crypto_strings();
         SSL_load_error_strings();
         SSL_library_init();
@@ -2720,8 +2784,8 @@ static apr_status_t initSSLCtx(_mhClient
                                        | SSL_MODE_ENABLE_PARTIAL_WRITE
                                        | SSL_MODE_AUTO_RETRY);
 
-        ssl_ctx->bio = BIO_new(&bio_apr_socket_method);
-        ssl_ctx->bio->ptr = cctx;
+        ssl_ctx->bio = BIO_new(bio_meth_apr_socket_new());
+        bio_set_data(ssl_ctx->bio, cctx);
         initSSL(cctx);
 
         apr_pool_cleanup_register(cctx->pool, cctx,



Mime
View raw message