Skip to content

Commit

Permalink
Fix: compilation against OpenSSL 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ysbaddaden committed Mar 30, 2017
1 parent 917971d commit be8083e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 85 deletions.
89 changes: 40 additions & 49 deletions src/openssl/lib_crypto.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs libcrypto || printf %s '-lcrypto'`")]
lib LibCrypto
OPENSSL_102 = {% `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libcrypto && printf %s true` == "true" %}
OPENSSL_110 = {% `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libcrypto && printf %s true` == "true" %}

alias Char = LibC::Char
alias Int = LibC::Int
alias UInt = LibC::UInt
Expand Down Expand Up @@ -72,9 +75,6 @@ lib LibCrypto
fun evp_md4 = EVP_md4 : EVP_MD
fun evp_md5 = EVP_md5 : EVP_MD
fun evp_ripemd160 = EVP_ripemd160 : EVP_MD
{% if !flag?(:openbsd) %}
fun evp_sha = EVP_sha : EVP_MD
{% end %}
fun evp_sha1 = EVP_sha1 : EVP_MD
fun evp_sha224 = EVP_sha224 : EVP_MD
fun evp_sha256 = EVP_sha256 : EVP_MD
Expand Down Expand Up @@ -159,8 +159,6 @@ lib LibCrypto
fun rand_bytes = RAND_bytes(buf : Char*, num : Int) : Int
fun err_get_error = ERR_get_error : ULong
fun err_error_string = ERR_error_string(e : ULong, buf : Char*) : Char*
fun openssl_add_all_algorithms = OPENSSL_add_all_algorithms_noconf
fun err_load_crypto_strings = ERR_load_crypto_strings

struct MD5Context
a : UInt
Expand Down Expand Up @@ -237,50 +235,43 @@ lib LibCrypto
fun x509_extension_create_by_nid = X509_EXTENSION_create_by_NID(ex : X509_EXTENSION, nid : Int, crit : Int, data : ASN1_STRING) : X509_EXTENSION
fun x509v3_ext_nconf_nid = X509V3_EXT_nconf_nid(conf : Void*, ctx : Void*, ext_nid : Int, value : Char*) : X509_EXTENSION
fun x509v3_ext_print = X509V3_EXT_print(out : Bio*, ext : X509_EXTENSION, flag : Int, indent : Int) : Int
end

{% if `(command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libcrypto && printf %s true) || printf %s false` == "true" %}
lib LibCrypto
OPENSSL_102 = true
end
{% else %}
lib LibCrypto
OPENSSL_102 = false
end
{% end %}

{% if LibCrypto::OPENSSL_102 %}
lib LibCrypto
type X509VerifyParam = Void*

@[Flags]
enum X509VerifyFlags : ULong
CB_ISSUER_CHECK = 0x1
USE_CHECK_TIME = 0x2
CRL_CHECK = 0x4
CRL_CHECK_ALL = 0x8
IGNORE_CRITICAL = 0x10
X509_STRICT = 0x20
ALLOW_PROXY_CERTS = 0x40
POLICY_CHECK = 0x80
EXPLICIT_POLICY = 0x100
INHIBIT_ANY = 0x200
INHIBIT_MAP = 0x400
NOTIFY_POLICY = 0x800
EXTENDED_CRL_SUPPORT = 0x1000
USE_DELTAS = 0x2000
CHECK_SS_SIGNATURE = 0x4000
TRUSTED_FIRST = 0x8000
SUITEB_128_LOS_ONLY = 0x10000
SUITEB_192_LOS = 0x20000
SUITEB_128_LOS = 0x30000
PARTIAL_CHAIN = 0x80000
NO_ALT_CHAINS = 0x100000
end
{% unless OPENSSL_110 %}
fun err_load_crypto_strings = ERR_load_crypto_strings
fun openssl_add_all_algorithms = OPENSSL_add_all_algorithms_noconf
{% end %}

fun x509_verify_param_lookup = X509_VERIFY_PARAM_lookup(name : UInt8*) : X509VerifyParam
fun x509_verify_param_set1_host = X509_VERIFY_PARAM_set1_host(param : X509VerifyParam, name : UInt8*, len : SizeT) : Int
fun x509_verify_param_set1_ip_asc = X509_VERIFY_PARAM_set1_ip_asc(param : X509VerifyParam, ip : UInt8*) : Int
fun x509_verify_param_set_flags = X509_VERIFY_PARAM_set_flags(param : X509VerifyParam, flags : X509VerifyFlags) : Int
{% if OPENSSL_102 %}
type X509VerifyParam = Void*

@[Flags]
enum X509VerifyFlags : ULong
CB_ISSUER_CHECK = 0x1
USE_CHECK_TIME = 0x2
CRL_CHECK = 0x4
CRL_CHECK_ALL = 0x8
IGNORE_CRITICAL = 0x10
X509_STRICT = 0x20
ALLOW_PROXY_CERTS = 0x40
POLICY_CHECK = 0x80
EXPLICIT_POLICY = 0x100
INHIBIT_ANY = 0x200
INHIBIT_MAP = 0x400
NOTIFY_POLICY = 0x800
EXTENDED_CRL_SUPPORT = 0x1000
USE_DELTAS = 0x2000
CHECK_SS_SIGNATURE = 0x4000
TRUSTED_FIRST = 0x8000
SUITEB_128_LOS_ONLY = 0x10000
SUITEB_192_LOS = 0x20000
SUITEB_128_LOS = 0x30000
PARTIAL_CHAIN = 0x80000
NO_ALT_CHAINS = 0x100000
end

fun x509_verify_param_lookup = X509_VERIFY_PARAM_lookup(name : UInt8*) : X509VerifyParam
fun x509_verify_param_set1_host = X509_VERIFY_PARAM_set1_host(param : X509VerifyParam, name : UInt8*, len : SizeT) : Int
fun x509_verify_param_set1_ip_asc = X509_VERIFY_PARAM_set1_ip_asc(param : X509VerifyParam, ip : UInt8*) : Int
fun x509_verify_param_set_flags = X509_VERIFY_PARAM_set_flags(param : X509VerifyParam, flags : X509VerifyFlags) : Int
{% end %}
end
{% end %}
54 changes: 26 additions & 28 deletions src/openssl/lib_ssl.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ require "./lib_crypto"

@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs libssl || printf %s '-lssl -lcrypto'`")]
lib LibSSL
OPENSSL_102 = {% `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libssl && printf %s true` == "true" %}
OPENSSL_110 = {% `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libssl && printf %s true` == "true" %}

alias Int = LibC::Int
alias Char = LibC::Char
alias Long = LibC::Long
Expand Down Expand Up @@ -118,14 +121,11 @@ lib LibSSL
SSL_TLSEXT_ERR_ALERT_FATAL = 2
SSL_TLSEXT_ERR_NOACK = 3

fun sslv23_method = SSLv23_method : SSLMethod
fun tlsv1_method = TLSv1_method : SSLMethod
fun tlsv1_1_method = TLSv1_1_method : SSLMethod
fun tlsv1_2_method = TLSv1_2_method : SSLMethod

fun ssl_load_error_strings = SSL_load_error_strings
fun ssl_get_error = SSL_get_error(handle : SSL, ret : Int) : SSLError
fun ssl_library_init = SSL_library_init
fun ssl_set_bio = SSL_set_bio(handle : SSL, rbio : LibCrypto::Bio*, wbio : LibCrypto::Bio*)
fun ssl_select_next_proto = SSL_select_next_proto(output : Char**, output_len : Char*, input : Char*, input_len : Int, client : Char*, client_len : Int) : Int
fun ssl_ctrl = SSL_ctrl(handle : SSL, cmd : Int, larg : Long, parg : Void*) : Long
Expand Down Expand Up @@ -164,32 +164,30 @@ lib LibSSL

# Hostname validation for OpenSSL <= 1.0.1
fun ssl_ctx_set_cert_verify_callback = SSL_CTX_set_cert_verify_callback(ctx : SSLContext, callback : CertVerifyCallback, arg : Void*)
end

{% if `(command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libssl && printf %s true) || printf %s false` == "true" %}
lib LibSSL
OPENSSL_102 = true
end
{% else %}
lib LibSSL
OPENSSL_102 = false
{% if OPENSSL_110 %}
fun tls_method = TLS_method : SSLMethod
{% else %}
fun ssl_library_init = SSL_library_init
fun ssl_load_error_strings = SSL_load_error_strings
fun sslv23_method = SSLv23_method : SSLMethod
{% end %}

{% if OPENSSL_102 %}
alias ALPNCallback = (SSL, Char**, Char*, Char*, Int, Void*) -> Int
alias X509VerifyParam = LibCrypto::X509VerifyParam

fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
fun ssl_get0_alpn_selected = SSL_get0_alpn_selected(handle : SSL, data : Char**, len : LibC::UInt*) : Void
fun ssl_ctx_set_alpn_select_cb = SSL_CTX_set_alpn_select_cb(ctx : SSLContext, cb : ALPNCallback, arg : Void*) : Void
fun ssl_ctx_get0_param = SSL_CTX_get0_param(ctx : SSLContext) : X509VerifyParam
fun ssl_ctx_set1_param = SSL_CTX_set1_param(ctx : SSLContext, param : X509VerifyParam) : Int
{% end %}
end
{% end %}

{% if LibSSL::OPENSSL_102 %}
lib LibSSL
alias ALPNCallback = (SSL, Char**, Char*, Char*, Int, Void*) -> Int
alias X509VerifyParam = LibCrypto::X509VerifyParam

fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
fun ssl_get0_alpn_selected = SSL_get0_alpn_selected(handle : SSL, data : Char**, len : LibC::UInt*) : Void
fun ssl_ctx_set_alpn_select_cb = SSL_CTX_set_alpn_select_cb(ctx : SSLContext, cb : ALPNCallback, arg : Void*) : Void
fun ssl_ctx_get0_param = SSL_CTX_get0_param(ctx : SSLContext) : X509VerifyParam
fun ssl_ctx_set1_param = SSL_CTX_set1_param(ctx : SSLContext, param : X509VerifyParam) : Int
end
{% unless LibSSL::OPENSSL_110 %}
LibSSL.ssl_library_init
LibSSL.ssl_load_error_strings
LibCrypto.openssl_add_all_algorithms
LibCrypto.err_load_crypto_strings
{% end %}

LibSSL.ssl_library_init
LibSSL.ssl_load_error_strings
LibCrypto.openssl_add_all_algorithms
LibCrypto.err_load_crypto_strings
25 changes: 17 additions & 8 deletions src/openssl/ssl/context.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
abstract class OpenSSL::SSL::Context
# :nodoc:
def self.default_method
{% if LibSSL::OPENSSL_110 %}
LibSSL.tls_method
{% else %}
LibSSL.sslv23_method
{% end %}
end

# The list of secure ciphers (intermediate security) as of May 2016 as per
# https://wiki.mozilla.org/Security/Server_Side_TLS
CIPHERS = %w(
Expand Down Expand Up @@ -47,8 +56,8 @@ abstract class OpenSSL::SSL::Context
class Client < Context
# Generates a new TLS client context with sane defaults for a client connection.
#
# By default it defaults to the `SSLv23_method` which actually means that
# OpenSSL will negotiate the TLS or SSL protocol to use with the remote
# Defaults to `TLS_method` or `SSLv23_method` (depending on OpenSSL version)
# which tells OpenSSL to negotiate the TLS or SSL protocol with the remote
# endpoint.
#
# Don't change the method unless you must restrict a specific protocol to be
Expand All @@ -63,7 +72,7 @@ abstract class OpenSSL::SSL::Context
# context = OpenSSL::SSL::Context::Client.new
# context.add_options(OpenSSL::SSL::Options::NO_SSLV2 | OpenSSL::SSL::Options::NO_SSLV3)
# ```
def initialize(method : LibSSL::SSLMethod = LibSSL.sslv23_method)
def initialize(method : LibSSL::SSLMethod = Context.default_method)
super(method)

self.verify_mode = OpenSSL::SSL::VerifyMode::PEER
Expand All @@ -76,7 +85,7 @@ abstract class OpenSSL::SSL::Context
#
# For everything else this uses the defaults of your OpenSSL.
# Use this only if undoing the defaults that `new` sets is too much hassle.
def self.insecure(method : LibSSL::SSLMethod = LibSSL.sslv23_method)
def self.insecure(method : LibSSL::SSLMethod = Context.default_method)
super(method)
end

Expand All @@ -102,8 +111,8 @@ abstract class OpenSSL::SSL::Context
class Server < Context
# Generates a new TLS server context with sane defaults for a server connection.
#
# By default it defaults to the `SSLv23_method` which actually means that
# OpenSSL will negotiate the TLS or SSL protocol to use with the remote
# Defaults to `TLS_method` or `SSLv23_method` (depending on OpenSSL version)
# which tells OpenSSL to negotiate the TLS or SSL protocol with the remote
# endpoint.
#
# Don't change the method unless you must restrict a specific protocol to be
Expand All @@ -116,7 +125,7 @@ abstract class OpenSSL::SSL::Context
# context = OpenSSL::SSL::Context::Server.new
# context.add_options(OpenSSL::SSL::Options::NO_SSLV2 | OpenSSL::SSL::Options::NO_SSLV3)
# ```
def initialize(method : LibSSL::SSLMethod = LibSSL.sslv23_method)
def initialize(method : LibSSL::SSLMethod = Context.default_method)
super(method)

add_options(OpenSSL::SSL::Options::CIPHER_SERVER_PREFERENCE)
Expand All @@ -129,7 +138,7 @@ abstract class OpenSSL::SSL::Context
#
# For everything else this uses the defaults of your OpenSSL.
# Use this only if undoing the defaults that `new` sets is too much hassle.
def self.insecure(method : LibSSL::SSLMethod = LibSSL.sslv23_method)
def self.insecure(method : LibSSL::SSLMethod = Context.default_method)
super(method)
end
end
Expand Down

0 comments on commit be8083e

Please sign in to comment.