Skip to content

Commit 72ce28f

Browse files
Ata Kuyumcusdogruyol
Ata Kuyumcu
authored andcommitted
Fixed OpenSSL bindings to recognize LibreSSL (#5676)
* Fixed OpenSSL bindings to recognize LibreSSL * Fixed OpenSSL header parsing macros to work with OS X * Fixed OpenSSL linking on OS X * Added ALPN support for LibreSSL >= 2.5.0 * Added a compilation flag to NOT use OpenSSL libs supplied by homebrew * Added a compilation flag to use homebrew's LibreSSL instead of OpenSSL * Replaced homebrew specific hacks with pkg-config
1 parent 27cfeb3 commit 72ce28f

File tree

5 files changed

+33
-11
lines changed

5 files changed

+33
-11
lines changed

bin/ci

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ prepare_build() {
8484

8585
on_linux docker pull "jhass/crystal-build-$ARCH"
8686

87-
on_osx brew install crystal-lang
87+
on_osx brew install crystal-lang pkg-config
8888

8989
# Make sure binaries from llvm are available in PATH
9090
on_osx brew install jq
@@ -123,6 +123,7 @@ with_build_env() {
123123
on_osx sudo systemsetup -settimezone $TZ
124124
on_osx PATH="/usr/local/opt/llvm/bin:\$PATH" \
125125
CRYSTAL_CACHE_DIR="/tmp/crystal" \
126+
PKG_CONFIG_PATH="$(brew --prefix)/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" \
126127
/bin/sh -c "'$command'"
127128

128129
}

src/openssl/lib_crypto.cr

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
{% begin %}
22
lib LibCrypto
3-
OPENSSL_110 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libcrypto || printf %s false`.stringify != "false" }}
4-
OPENSSL_102 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libcrypto || printf %s false`.stringify != "false" }}
3+
# An extra zero is appended to the output of LIBRESSL_VERSION to make it 0 when LibreSSL does not exist on the system.
4+
# Any comparisons to it should be affixed with an extra zero as well e.g. `(LIBRESSL_VERSION_NUMBER >= 0x2050500F0)`.
5+
LIBRESSL_VERSION = {{ system("echo \"#include <openssl/opensslv.h>\nLIBRESSL_VERSION_NUMBER\" | " +
6+
(env("CC") || "cc") + " " + `pkg-config --cflags --silence-errors libssl || true`.chomp.stringify + " -E -").chomp.split('\n').last.split('L').first.id + "0" }}
7+
OPENSSL_VERSION = {{ system("echo \"#include <openssl/opensslv.h>\nOPENSSL_VERSION_NUMBER\" | " +
8+
(env("CC") || "cc") + " " + `pkg-config --cflags --silence-errors libssl || true`.chomp.stringify + " -E -").chomp.split('\n').last.split('L').first.id }}
59
end
610
{% end %}
711

8-
@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'`")]
12+
{% begin %}
13+
lib LibCrypto
14+
OPENSSL_110 = {{ (LibCrypto::LIBRESSL_VERSION == 0) && (LibCrypto::OPENSSL_VERSION >= 0x10101000) }}
15+
OPENSSL_102 = {{ (LibCrypto::LIBRESSL_VERSION == 0) && (LibCrypto::OPENSSL_VERSION >= 0x10002000) }}
16+
LIBRESSL_250 = {{ LibCrypto::LIBRESSL_VERSION >= 0x205000000 }}
17+
end
18+
{% end %}
19+
20+
@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s ' -lcrypto'`")]
921
lib LibCrypto
1022
alias Char = LibC::Char
1123
alias Int = LibC::Int

src/openssl/lib_ssl.cr

+10-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ require "./lib_crypto"
22

33
{% begin %}
44
lib LibSSL
5-
OPENSSL_110 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libssl || printf %s false`.stringify != "false" }}
6-
OPENSSL_102 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libssl || printf %s false`.stringify != "false" }}
5+
OPENSSL_110 = {{ LibCrypto::OPENSSL_110 }}
6+
OPENSSL_102 = {{ LibCrypto::OPENSSL_102 }}
7+
LIBRESSL_250 = {{ LibCrypto::LIBRESSL_250 }}
78
end
89
{% end %}
910

@@ -198,13 +199,17 @@ lib LibSSL
198199
fun sslv23_method = SSLv23_method : SSLMethod
199200
{% end %}
200201

201-
{% if OPENSSL_102 %}
202+
{% if OPENSSL_102 || LIBRESSL_250 %}
202203
alias ALPNCallback = (SSL, Char**, Char*, Char*, Int, Void*) -> Int
203-
alias X509VerifyParam = LibCrypto::X509VerifyParam
204204

205-
fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
206205
fun ssl_get0_alpn_selected = SSL_get0_alpn_selected(handle : SSL, data : Char**, len : LibC::UInt*) : Void
207206
fun ssl_ctx_set_alpn_select_cb = SSL_CTX_set_alpn_select_cb(ctx : SSLContext, cb : ALPNCallback, arg : Void*) : Void
207+
{% end %}
208+
209+
{% if OPENSSL_102 %}
210+
alias X509VerifyParam = LibCrypto::X509VerifyParam
211+
212+
fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
208213
fun ssl_ctx_get0_param = SSL_CTX_get0_param(ctx : SSLContext) : X509VerifyParam
209214
fun ssl_ctx_set1_param = SSL_CTX_set1_param(ctx : SSLContext, param : X509VerifyParam) : Int
210215
{% end %}

src/openssl/ssl/context.cr

+5-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ abstract class OpenSSL::SSL::Context
305305
LibSSL.ssl_ctx_set_verify(@handle, mode, nil)
306306
end
307307

308-
{% if LibSSL::OPENSSL_102 %}
308+
{% if LibSSL::OPENSSL_102 || LibSSL::LIBRESSL_250 %}
309309

310310
@alpn_protocol : Pointer(Void)?
311311

@@ -338,6 +338,10 @@ abstract class OpenSSL::SSL::Context
338338
LibSSL.ssl_ctx_set_alpn_select_cb(@handle, alpn_cb, alpn_protocol)
339339
end
340340

341+
{% end %}
342+
343+
{% if LibSSL::OPENSSL_102 %}
344+
341345
# Set this context verify param to the default one of the given name.
342346
#
343347
# Depending on the OpenSSL version, the available defaults are

src/openssl/ssl/socket.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ abstract class OpenSSL::SSL::Socket < IO
119119
@bio.io.flush
120120
end
121121

122-
{% if LibSSL::OPENSSL_102 %}
122+
{% if LibSSL::OPENSSL_102 || LibSSL::LIBRESSL_250 %}
123123
# Returns the negotiated ALPN protocol (eg: `"h2"`) of `nil` if no protocol was
124124
# negotiated.
125125
def alpn_protocol

0 commit comments

Comments
 (0)