Skip to content

Commit

Permalink
Add support for OpenSSL 1.1.0.
Browse files Browse the repository at this point in the history
This release hides many struct members which provides easier forward
compatibility but is a break from previous releases. A few small macros
provide compatibility between both 1.1.0 and 1.0.x.

Fixes #8624.
  • Loading branch information
QuLogic committed Sep 24, 2017
1 parent 9b3215b commit 00c03bd
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 29 deletions.
60 changes: 49 additions & 11 deletions modules/openssl/stream_peer_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@
/*************************************************************************/
#include "stream_peer_openssl.h"

// Compatibility with OpenSSL 1.1.0.
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#define BIO_set_num(b, n)
#else
#define BIO_set_num(b, n) ((b)->num = (n))

#define BIO_set_init(b, i) ((b)->init = (i))
#define BIO_set_data(b, p) ((b)->ptr = (p))
#define BIO_get_data(b) ((b)->ptr)
#endif

//hostname matching code from curl

bool StreamPeerOpenSSL::_match_host_name(const char *name, const char *hostname) {
Expand Down Expand Up @@ -157,28 +168,28 @@ int StreamPeerOpenSSL::_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg
}

int StreamPeerOpenSSL::_bio_create(BIO *b) {
b->init = 1;
b->num = 0;
b->ptr = NULL;
b->flags = 0;
BIO_set_init(b, 1);
BIO_set_num(b, 0);
BIO_set_data(b, NULL);
BIO_clear_flags(b, ~0);
return 1;
}

int StreamPeerOpenSSL::_bio_destroy(BIO *b) {
if (b == NULL)
return 0;

b->ptr = NULL; /* sb_tls_remove() will free it */
b->init = 0;
b->flags = 0;
BIO_set_data(b, NULL); /* sb_tls_remove() will free it */
BIO_set_init(b, 0);
BIO_clear_flags(b, ~0);
return 1;
}

int StreamPeerOpenSSL::_bio_read(BIO *b, char *buf, int len) {

if (buf == NULL || len <= 0) return 0;

StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)b->ptr;
StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)BIO_get_data(b);

ERR_FAIL_COND_V(sp == NULL, 0);

Expand Down Expand Up @@ -212,7 +223,7 @@ int StreamPeerOpenSSL::_bio_write(BIO *b, const char *buf, int len) {

if (buf == NULL || len <= 0) return 0;

StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)b->ptr;
StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)BIO_get_data(b);

ERR_FAIL_COND_V(sp == NULL, 0);

Expand Down Expand Up @@ -258,6 +269,26 @@ int StreamPeerOpenSSL::_bio_puts(BIO *b, const char *str) {
return _bio_write(b, str, strlen(str));
}

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
BIO_METHOD *StreamPeerOpenSSL::_bio_method = NULL;

BIO_METHOD *StreamPeerOpenSSL::_get_bio_method() {
if (_bio_method) // already initialized.
return _bio_method;

/* it's a source/sink BIO */
_bio_method = BIO_meth_new(100 | 0x400, "streampeer glue");
BIO_meth_set_write(_bio_method, _bio_write);
BIO_meth_set_read(_bio_method, _bio_read);
BIO_meth_set_puts(_bio_method, _bio_puts);
BIO_meth_set_gets(_bio_method, _bio_gets);
BIO_meth_set_ctrl(_bio_method, _bio_ctrl);
BIO_meth_set_create(_bio_method, _bio_create);
BIO_meth_set_destroy(_bio_method, _bio_destroy);

return _bio_method;
}
#else
BIO_METHOD StreamPeerOpenSSL::_bio_method = {
/* it's a source/sink BIO */
(100 | 0x400),
Expand All @@ -271,6 +302,11 @@ BIO_METHOD StreamPeerOpenSSL::_bio_method = {
_bio_destroy
};

BIO_METHOD *StreamPeerOpenSSL::_get_bio_method() {
return &_bio_method;
}
#endif

Error StreamPeerOpenSSL::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) {

if (connected)
Expand Down Expand Up @@ -330,8 +366,8 @@ Error StreamPeerOpenSSL::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
}

ssl = SSL_new(ctx);
bio = BIO_new(&_bio_method);
bio->ptr = this;
bio = BIO_new(_get_bio_method());
BIO_set_data(bio, this);
SSL_set_bio(ssl, bio, bio);

if (p_for_hostname != String()) {
Expand Down Expand Up @@ -532,7 +568,9 @@ void StreamPeerOpenSSL::initialize_ssl() {
load_certs_func = _load_certs;

_create = _create_func;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
#endif
SSL_library_init(); // Initialize OpenSSL's SSL libraries
SSL_load_error_strings(); // Load SSL error strings
ERR_load_BIO_strings(); // Load BIO error strings
Expand Down
5 changes: 5 additions & 0 deletions modules/openssl/stream_peer_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ class StreamPeerOpenSSL : public StreamPeerSSL {
static int _bio_gets(BIO *b, char *buf, int len);
static int _bio_puts(BIO *b, const char *str);

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
static BIO_METHOD *_bio_method;
#else
static BIO_METHOD _bio_method;
#endif
static BIO_METHOD *_get_bio_method();

static bool _match_host_name(const char *name, const char *hostname);
static Error _match_common_name(const char *hostname, const X509 *server_cert);
Expand Down
9 changes: 0 additions & 9 deletions platform/server/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,6 @@ def configure(env):
# FIXME: Check for existence of the libs before parsing their flags with pkg-config

if (env['builtin_openssl'] == 'no'):
# Currently not compatible with OpenSSL 1.1.0+
# https://github.com/godotengine/godot/issues/8624
import subprocess
openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n')
if (openssl_version >= "1.1.0"):
print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version)
print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n")
sys.exit(255)

env.ParseConfig('pkg-config openssl --cflags --libs')

if (env['builtin_libwebp'] == 'no'):
Expand Down
9 changes: 0 additions & 9 deletions platform/x11/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,6 @@ def configure(env):
# FIXME: Check for existence of the libs before parsing their flags with pkg-config

if (env['builtin_openssl'] == 'no'):
# Currently not compatible with OpenSSL 1.1.0+
# https://github.com/godotengine/godot/issues/8624
import subprocess
openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n')
if (openssl_version >= "1.1.0"):
print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version)
print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n")
sys.exit(255)

env.ParseConfig('pkg-config openssl --cflags --libs')

if (env['builtin_libwebp'] == 'no'):
Expand Down

0 comments on commit 00c03bd

Please sign in to comment.