Skip to content

Commit

Permalink
Fix: OpenSSL 1.1.0 changed context options
Browse files Browse the repository at this point in the history
SSLv2 support was removed, some context options were disabled, and
the following symbols were previously macros:

- SSL_CTX_get_options
- SSL_CTX_set_options
- SSL_CTX_clear_options
  • Loading branch information
ysbaddaden committed Apr 4, 2017
1 parent 854cdce commit 3119e59
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 24 deletions.
28 changes: 21 additions & 7 deletions spec/std/openssl/ssl/context_spec.cr
Expand Up @@ -4,9 +4,14 @@ require "openssl"
describe OpenSSL::SSL::Context do
it "new for client" do
context = OpenSSL::SSL::Context::Client.new
context.options.should eq(OpenSSL::SSL::Options.flags(
ALL, NO_SSLV2, NO_SSLV3, NO_SESSION_RESUMPTION_ON_RENEGOTIATION, SINGLE_ECDH_USE, SINGLE_DH_USE
))

(context.options & OpenSSL::SSL::Options::ALL).should eq(OpenSSL::SSL::Options::ALL)
(context.options & OpenSSL::SSL::Options::NO_SSLV2).should eq(OpenSSL::SSL::Options::NO_SSLV2)
(context.options & OpenSSL::SSL::Options::NO_SSLV3).should eq(OpenSSL::SSL::Options::NO_SSLV3)
(context.options & OpenSSL::SSL::Options::NO_SESSION_RESUMPTION_ON_RENEGOTIATION).should eq(OpenSSL::SSL::Options::NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
(context.options & OpenSSL::SSL::Options::SINGLE_ECDH_USE).should eq(OpenSSL::SSL::Options::SINGLE_ECDH_USE)
(context.options & OpenSSL::SSL::Options::SINGLE_DH_USE).should eq(OpenSSL::SSL::Options::SINGLE_DH_USE)

context.modes.should eq(OpenSSL::SSL::Modes.flags(AUTO_RETRY, RELEASE_BUFFERS))
context.verify_mode.should eq(OpenSSL::SSL::VerifyMode::PEER)

Expand All @@ -15,9 +20,15 @@ describe OpenSSL::SSL::Context do

it "new for server" do
context = OpenSSL::SSL::Context::Server.new
context.options.should eq(OpenSSL::SSL::Options.flags(
ALL, NO_SSLV2, NO_SSLV3, NO_SESSION_RESUMPTION_ON_RENEGOTIATION, SINGLE_ECDH_USE, SINGLE_DH_USE, CIPHER_SERVER_PREFERENCE
))

(context.options & OpenSSL::SSL::Options::ALL).should eq(OpenSSL::SSL::Options::ALL)
(context.options & OpenSSL::SSL::Options::NO_SSLV2).should eq(OpenSSL::SSL::Options::NO_SSLV2)
(context.options & OpenSSL::SSL::Options::NO_SSLV3).should eq(OpenSSL::SSL::Options::NO_SSLV3)
(context.options & OpenSSL::SSL::Options::NO_SESSION_RESUMPTION_ON_RENEGOTIATION).should eq(OpenSSL::SSL::Options::NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
(context.options & OpenSSL::SSL::Options::SINGLE_ECDH_USE).should eq(OpenSSL::SSL::Options::SINGLE_ECDH_USE)
(context.options & OpenSSL::SSL::Options::SINGLE_DH_USE).should eq(OpenSSL::SSL::Options::SINGLE_DH_USE)
(context.options & OpenSSL::SSL::Options::CIPHER_SERVER_PREFERENCE).should eq(OpenSSL::SSL::Options::CIPHER_SERVER_PREFERENCE)

context.modes.should eq(OpenSSL::SSL::Modes.flags(AUTO_RETRY, RELEASE_BUFFERS))
context.verify_mode.should eq(OpenSSL::SSL::VerifyMode::NONE)

Expand Down Expand Up @@ -81,7 +92,10 @@ describe OpenSSL::SSL::Context do
context = OpenSSL::SSL::Context::Client.new
context.remove_options(context.options) # reset
default_options = context.options # options we can't unset
context.add_options(OpenSSL::SSL::Options::ALL).should eq(default_options | OpenSSL::SSL::Options::ALL)

context.add_options(OpenSSL::SSL::Options::ALL)
.should eq(default_options | OpenSSL::SSL::Options::ALL)

context.add_options(OpenSSL::SSL::Options.flags(NO_SSLV2, NO_SSLV3))
.should eq(OpenSSL::SSL::Options.flags(ALL, NO_SSLV2, NO_SSLV3))
end
Expand Down
49 changes: 35 additions & 14 deletions src/openssl/lib_ssl.cr
Expand Up @@ -64,17 +64,9 @@ lib LibSSL
SSL_CTRL_CLEAR_MODE = 78

enum Options : ULong
MICROSOFT_SESS_ID_BUG = 0x00000001
NETSCAPE_CHALLENGE_BUG = 0x00000002
LEGACY_SERVER_CONNECT = 0x00000004
NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000008
SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000010
MICROSOFT_BIG_SSLV3_BUFFER = 0x00000020
SAFARI_ECDHE_ECDSA_BUG = 0x00000040
SSLEAY_080_CLIENT_DH_BUG = 0x00000080
TLS_D5_BUG = 0x00000100
TLS_BLOCK_PADDING_BUG = 0x00000200
DONT_INSERT_EMPTY_FRAGMENTS = 0x00000800
LEGACY_SERVER_CONNECT = 0x00000004
SAFARI_ECDHE_ECDSA_BUG = 0x00000040
DONT_INSERT_EMPTY_FRAGMENTS = 0x00000800

# Various bug workarounds that should be rather harmless.
# This used to be `0x000FFFFF` before 0.9.7
Expand All @@ -88,12 +80,9 @@ lib LibSSL
NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000
NO_COMPRESSION = 0x00020000
ALLOW_UNSAFE_LEGACY_RENEGOTIATION = 0x00040000
SINGLE_ECDH_USE = 0x00080000
SINGLE_DH_USE = 0x00100000
CIPHER_SERVER_PREFERENCE = 0x00400000
TLS_ROLLBACK_BUG = 0x00800000

NO_SSLV2 = 0x01000000
NO_SSLV3 = 0x02000000
NO_TLSV1 = 0x04000000
NO_TLSV1_2 = 0x08000000
Expand All @@ -102,6 +91,32 @@ lib LibSSL
NETSCAPE_CA_DN_BUG = 0x20000000
NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x40000000
CRYPTOPRO_TLSEXT_BUG = 0x80000000

{% if OPENSSL_110 %}
MICROSOFT_SESS_ID_BUG = 0x00000000
NETSCAPE_CHALLENGE_BUG = 0x00000000
NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000000
SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000000
MICROSOFT_BIG_SSLV3_BUFFER = 0x00000000
SSLEAY_080_CLIENT_DH_BUG = 0x00000000
TLS_D5_BUG = 0x00000000
TLS_BLOCK_PADDING_BUG = 0x00000000
NO_SSLV2 = 0x00000000
SINGLE_ECDH_USE = 0x00000000
SINGLE_DH_USE = 0x00000000
{% else %}
MICROSOFT_SESS_ID_BUG = 0x00000001
NETSCAPE_CHALLENGE_BUG = 0x00000002
NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000008
SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000010
MICROSOFT_BIG_SSLV3_BUFFER = 0x00000020
SSLEAY_080_CLIENT_DH_BUG = 0x00000080
TLS_D5_BUG = 0x00000100
TLS_BLOCK_PADDING_BUG = 0x00000200
NO_SSLV2 = 0x01000000
SINGLE_ECDH_USE = 0x00080000
SINGLE_DH_USE = 0x00100000
{% end %}
end

@[Flags]
Expand Down Expand Up @@ -163,6 +178,12 @@ lib LibSSL
fun ssl_ctx_set_default_verify_paths = SSL_CTX_set_default_verify_paths(ctx : SSLContext) : Int
fun ssl_ctx_ctrl = SSL_CTX_ctrl(ctx : SSLContext, cmd : Int, larg : ULong, parg : Void*) : ULong

{% if OPENSSL_110 %}
fun ssl_ctx_get_options = SSL_CTX_get_options(ctx : SSLContext) : ULong
fun ssl_ctx_set_options = SSL_CTX_set_options(ctx : SSLContext, larg : ULong) : ULong
fun ssl_ctx_clear_options = SSL_CTX_clear_options(ctx : SSLContext, larg : ULong) : ULong
{% end %}

@[Raises]
fun ssl_ctx_load_verify_locations = SSL_CTX_load_verify_locations(ctx : SSLContext, ca_file : UInt8*, ca_path : UInt8*) : Int

Expand Down
21 changes: 18 additions & 3 deletions src/openssl/ssl/context.cr
Expand Up @@ -252,7 +252,12 @@ abstract class OpenSSL::SSL::Context

# Returns the current options set on the TLS context.
def options
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_OPTIONS, 0, nil)
opts = {% if LibSSL::OPENSSL_110 %}
LibSSL.ssl_ctx_get_options(@handle)
{% else %}
LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_OPTIONS, 0, nil)
{% end %}
OpenSSL::SSL::Options.new(opts)
end

# Adds options to the TLS context.
Expand All @@ -266,7 +271,12 @@ abstract class OpenSSL::SSL::Context
# )
# ```
def add_options(options : OpenSSL::SSL::Options)
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_OPTIONS, options, nil)
opts = {% if LibSSL::OPENSSL_110 %}
LibSSL.ssl_ctx_set_options(@handle, options)
{% else %}
LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_OPTIONS, options, nil)
{% end %}
OpenSSL::SSL::Options.new(opts)
end

# Removes options from the TLS context.
Expand All @@ -276,7 +286,12 @@ abstract class OpenSSL::SSL::Context
# context.remove_options(OpenSSL::SSL::Options::NO_SSLV3)
# ```
def remove_options(options : OpenSSL::SSL::Options)
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_CLEAR_OPTIONS, options, nil)
opts = {% if LibSSL::OPENSSL_110 %}
LibSSL.ssl_ctx_clear_options(@handle, options)
{% else %}
LibSSL.ssl_ctx_ctrl(@handle, LibSSL::SSL_CTRL_CLEAR_OPTIONS, options, nil)
{% end %}
OpenSSL::SSL::Options.new(opts)
end

# Returns the current verify mode. See the `SSL_CTX_set_verify(3)` manpage for more details.
Expand Down

0 comments on commit 3119e59

Please sign in to comment.