Class: HTTPX::TLS::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/httpx/io/tls/context.rb

Constant Summary collapse

CIPHERS =
"EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"
SESSION =
"ruby-tls"
ALPN_LOOKUP =
::Concurrent::Map.new
ALPN_Select_CB =
FFI::Function.new(:int, [
                                     # array of str, unit8 out,uint8 in,        *arg
                                     :pointer, :pointer, :pointer, :string, :uint, :pointer
                                   ]) do |ssl_p, out, outlen, inp, inlen, _arg|
  ssl = Box::InstanceLookup[ssl_p.address]
  return SSL::SSL_TLSEXT_ERR_ALERT_FATAL unless ssl

  protos = ssl.context.alpn_str
  status = SSL.SSL_select_next_proto(out, outlen, protos, protos.length, inp, inlen)
  ssl.alpn_negotiated

  case status
  when SSL::OPENSSL_NPN_UNSUPPORTED
    SSL::SSL_TLSEXT_ERR_ALERT_FATAL
  when SSL::OPENSSL_NPN_NEGOTIATED
    SSL::SSL_TLSEXT_ERR_OK
  when SSL::OPENSSL_NPN_NO_OVERLAP
    SSL::SSL_TLSEXT_ERR_ALERT_WARNING
  end
end
ServerNameCB =
FFI::Function.new(:int, %i[pointer pointer pointer]) do |ssl, _, _|
  ruby_ssl = Box::InstanceLookup[ssl.address]
  return SSL::SSL_TLSEXT_ERR_NOACK unless ruby_ssl

  ctx = ruby_ssl.hosts[SSL.SSL_get_servername(ssl, SSL::TLSEXT_NAMETYPE_host_name)]
  if ctx
    SSL.SSL_set_SSL_CTX(ssl, ctx.ssl_ctx)
    SSL::SSL_TLSEXT_ERR_OK
  else
    SSL::SSL_TLSEXT_ERR_ALERT_FATAL
  end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, options = {}) ⇒ Context

Returns a new instance of Context.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/httpx/io/tls/context.rb', line 55

def initialize(server, options = {})
  @is_server = server

  if @is_server
    @ssl_ctx = SSL.SSL_CTX_new(SSL.TLS_server_method)
    set_private_key(options[:private_key] || SSL::DEFAULT_PRIVATE)
    set_certificate(options[:cert_chain]  || SSL::DEFAULT_CERT)
    set_client_ca(options[:client_ca])
  else
    @ssl_ctx = SSL.SSL_CTX_new(SSL.TLS_client_method)
  end

  SSL.SSL_CTX_set_options(@ssl_ctx, SSL::SSL_OP_ALL)
  SSL.SSL_CTX_set_mode(@ssl_ctx, SSL::SSL_MODE_RELEASE_BUFFERS)

  SSL.SSL_CTX_set_cipher_list(@ssl_ctx, options[:ciphers] || CIPHERS)

  set_min_version(options[:version])

  if @is_server
    SSL.SSL_CTX_sess_set_cache_size(@ssl_ctx, 128)
    SSL.SSL_CTX_set_session_id_context(@ssl_ctx, SESSION, 8)
  else
    set_private_key(options[:private_key])
    set_certificate(options[:cert_chain])
  end
  set_alpn_negotiation(options[:protocols])
end

Instance Attribute Details

#alpn_setObject (readonly)

Returns the value of attribute alpn_set.



53
54
55
# File 'lib/httpx/io/tls/context.rb', line 53

def alpn_set
  @alpn_set
end

#alpn_strObject (readonly)

Returns the value of attribute alpn_str.



53
54
55
# File 'lib/httpx/io/tls/context.rb', line 53

def alpn_str
  @alpn_str
end

#is_serverObject (readonly)

Returns the value of attribute is_server.



53
54
55
# File 'lib/httpx/io/tls/context.rb', line 53

def is_server
  @is_server
end

#ssl_ctxObject (readonly)

Returns the value of attribute ssl_ctx.



53
54
55
# File 'lib/httpx/io/tls/context.rb', line 53

def ssl_ctx
  @ssl_ctx
end

Instance Method Details

#add_server_name_indicationObject

Raises:



91
92
93
94
95
# File 'lib/httpx/io/tls/context.rb', line 91

def add_server_name_indication
  raise Error, "only valid for server mode context" unless @is_server

  SSL.SSL_CTX_set_tlsext_servername_callback(@ssl_ctx, ServerNameCB)
end

#cleanupObject



84
85
86
87
88
89
# File 'lib/httpx/io/tls/context.rb', line 84

def cleanup
  return unless @ssl_ctx

  SSL.SSL_CTX_free(@ssl_ctx)
  @ssl_ctx = nil
end