@@ -89,9 +89,6 @@ def self.BIO_pending(bio)
8989 # PutCiphertext
9090 attach_function :BIO_write , [ :bio , :buffer_in , :buffer_length ] , :int
9191
92- # SelectALPNCallback
93- # TODO:: SSL_select_next_proto
94-
9592 # Deconstructor
9693 attach_function :SSL_get_shutdown , [ :ssl ] , :int
9794 attach_function :SSL_shutdown , [ :ssl ] , :int
@@ -106,9 +103,6 @@ def self.BIO_pending(bio)
106103 # r, w
107104 attach_function :SSL_set_bio , [ :ssl , :bio , :bio ] , :void
108105
109- # TODO:: SSL_CTX_set_alpn_select_cb
110- # Will have to put a try catch around these and support when available
111-
112106 attach_function :SSL_set_ex_data , [ :ssl , :int , :string ] , :int
113107 callback :verify_callback , [ :int , :x509 ] , :int
114108 attach_function :SSL_set_verify , [ :ssl , :int , :verify_callback ] , :void
@@ -120,11 +114,33 @@ def self.BIO_pending(bio)
120114 attach_function :X509_STORE_CTX_get_ex_data , [ :pointer , :int ] , :ssl
121115 attach_function :PEM_write_bio_X509 , [ :bio , :x509 ] , :int
122116
123-
124117 # SSL Context Class
125- # Constructor
126- attach_function :SSLv23_server_method , [ ] , :pointer
127- attach_function :SSLv23_client_method , [ ] , :pointer
118+ # OpenSSL before 1.1.0 do not have these methods
119+ # https://www.openssl.org/docs/man1.1.0/ssl/TLSv1_2_server_method.html
120+ begin
121+ attach_function :TLS_server_method , [ ] , :pointer
122+ attach_function :TLS_client_method , [ ] , :pointer
123+
124+ VERSION_SUPPORTED = true
125+
126+ SSL3_VERSION = 0x0300
127+ TLS1_VERSION = 0x0301
128+ TLS1_1_VERSION = 0x0302
129+ TLS1_2_VERSION = 0x0303
130+ TLS1_3_VERSION = 0x0304
131+ TLS_MAX_VERSION = TLS1_3_VERSION
132+ ANY_VERSION = 0
133+ attach_function :SSL_CTX_set_min_proto_version , [ :ssl_ctx , :int ] , :int
134+ attach_function :SSL_CTX_set_max_proto_version , [ :ssl_ctx , :int ] , :int
135+ rescue FFI ::NotFoundError
136+ attach_function :SSLv23_server_method , [ ] , :pointer
137+ attach_function :SSLv23_client_method , [ ] , :pointer
138+
139+ def self . TLS_server_method ; self . SSLv23_server_method ; end
140+ def self . TLS_client_method ; self . SSLv23_client_method ; end
141+
142+ VERSION_SUPPORTED = false
143+ end
128144 attach_function :SSL_CTX_new , [ :pointer ] , :ssl_ctx
129145
130146 attach_function :SSL_CTX_ctrl , [ :ssl_ctx , :int , :ulong , :pointer ] , :long
@@ -176,6 +192,7 @@ def self.SSL_CTX_set_tlsext_servername_callback(ctx, callback)
176192 attach_function :SSL_CTX_set_session_id_context , [ :ssl_ctx , :string , :buffer_length ] , :int
177193 attach_function :SSL_load_client_CA_file , [ :string ] , :pointer
178194 attach_function :SSL_CTX_set_client_CA_list , [ :ssl_ctx , :pointer ] , :void
195+ attach_function :SSL_CTX_load_verify_locations , [ :ssl_ctx , :pointer ] , :int , :blocking => true
179196
180197 # OpenSSL before 1.0.2 do not have these methods
181198 begin
@@ -342,12 +359,12 @@ def initialize(server, options = {})
342359 @is_server = server
343360
344361 if @is_server
345- @ssl_ctx = SSL . SSL_CTX_new ( SSL . SSLv23_server_method )
362+ @ssl_ctx = SSL . SSL_CTX_new ( SSL . TLS_server_method )
346363 set_private_key ( options [ :private_key ] || SSL ::DEFAULT_PRIVATE )
347364 set_certificate ( options [ :cert_chain ] || SSL ::DEFAULT_CERT )
348365 set_client_ca ( options [ :client_ca ] )
349366 else
350- @ssl_ctx = SSL . SSL_CTX_new ( SSL . SSLv23_client_method )
367+ @ssl_ctx = SSL . SSL_CTX_new ( SSL . TLS_client_method )
351368 end
352369
353370 SSL . SSL_CTX_set_options ( @ssl_ctx , SSL ::SSL_OP_ALL )
@@ -356,6 +373,12 @@ def initialize(server, options = {})
356373 SSL . SSL_CTX_set_cipher_list ( @ssl_ctx , options [ :ciphers ] || CIPHERS )
357374 @alpn_set = false
358375
376+ version = options [ :version ]
377+ if version
378+ vresult = set_min_proto_version ( version )
379+ raise "#{ version } is unsupported" unless vresult
380+ end
381+
359382 if @is_server
360383 SSL . SSL_CTX_sess_set_cache_size ( @ssl_ctx , 128 )
361384 SSL . SSL_CTX_set_session_id_context ( @ssl_ctx , SESSION , 8 )
@@ -377,6 +400,24 @@ def initialize(server, options = {})
377400 end
378401 end
379402
403+ # Version can be one of:
404+ # :SSL3, :TLS1, :TLS1_1, :TLS1_2, :TLS1_3, :TLS_MAX
405+ def set_min_proto_version ( version )
406+ return false unless VERSION_SUPPORTED
407+ num = SSL . const_get ( "#{ version } _VERSION" )
408+ SSL . SSL_CTX_set_min_proto_version ( @ssl_ctx , num ) == 1
409+ rescue NameError
410+ false
411+ end
412+
413+ def set_max_proto_version ( version )
414+ return false unless VERSION_SUPPORTED
415+ num = SSL . const_get ( "#{ version } _VERSION" )
416+ SSL . SSL_CTX_set_max_proto_version ( @ssl_ctx , num ) == 1
417+ rescue NameError
418+ false
419+ end
420+
380421 def cleanup
381422 if @ssl_ctx
382423 SSL . SSL_CTX_free ( @ssl_ctx )
0 commit comments