Skip to content

Commit

Permalink
Upstream client SSL configuration for Rex sockets
Browse files Browse the repository at this point in the history
This is a rehash of a very old change which was likely dropped in
one of the abominable PRs which was not landed due to complexity,
breakage, or gross overreach of the PR's scope...

Add client configuration options for Rex Sockets to use client
certificates along with appropriate setters and getters during
Rex::Socket::TcpSsl configuration.

Testing:
  In fork context only, not used all too often, needs eyes on.
  • Loading branch information
RageLtMan committed Jun 27, 2017
1 parent df91f32 commit 86a1843
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
42 changes: 40 additions & 2 deletions lib/rex/socket/parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,38 @@ def initialize(hash)
end
end

if (hash['SSLClientCert'] and ::File.file?(hash['SSLClientCert']))
begin
self.ssl_client_cert = ::File.read(hash['SSLClientCert'])
rescue ::Exception => e
elog("Failed to read client cert: #{e.class}: #{e}", LogSource)
end
end

if (hash['SSLClientKey'] and ::File.file?(hash['SSLClientKey']))
begin
self.ssl_client_key = ::File.read(hash['SSLClientKey'])
rescue ::Exception => e
elog("Failed to read client key: #{e.class}: #{e}", LogSource)
end
end

if (hash['SSLClientCert'] and ::File.file?(hash['SSLClientCert']))
begin
self.ssl_client_cert = ::File.read(hash['SSLClientCert'])
rescue ::Exception => e
elog("Failed to read client cert: #{e.class}: #{e}", LogSource)
end
end

if (hash['SSLClientKey'] and ::File.file?(hash['SSLClientKey']))
begin
self.ssl_client_key = ::File.read(hash['SSLClientKey'])
rescue ::Exception => e
elog("Failed to read client key: #{e.class}: #{e}", LogSource)
end
end

if hash['Proxies']
self.proxies = hash['Proxies'].split(',').map{|a| a.strip}.map{|a| a.split(':').map{|b| b.strip}}
end
Expand Down Expand Up @@ -353,10 +385,16 @@ def v6?
attr_accessor :ssl_compression

#
# The SSL context verification mechanism
# The client SSL certificate
#
attr_accessor :ssl_client_cert
#
# The client SSL key
#
attr_accessor :ssl_client_key
#
# SSL certificate verification mode for SSL context
attr_accessor :ssl_verify_mode

#
# Whether we should use IPv6
# @return [Bool]
Expand Down
28 changes: 27 additions & 1 deletion lib/rex/socket/ssl_tcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def self.create(hash = {})
end

#
# Set the SSL flag to true and call the base class's create_param routine.
# Set the SSL flag to true,
# create placeholders for client certs,
# call the base class's create_param routine.
#
def self.create_param(param)
param.ssl = true
Expand Down Expand Up @@ -95,6 +97,16 @@ def initsock_with_ssl_version(params, version)
# Build the SSL connection
self.sslctx = OpenSSL::SSL::SSLContext.new(version)

# Configure client certificate
if params and params.ssl_client_cert
self.sslctx.cert = OpenSSL::X509::Certificate.new(params.ssl_client_cert)
end

# Configure client key
if params and params.ssl_client_key
self.sslctx.key = OpenSSL::PKey::RSA.new(params.ssl_client_key)
end

# Configure the SSL context
# TODO: Allow the user to specify the verify mode callback
# Valid modes:
Expand Down Expand Up @@ -319,6 +331,20 @@ def peer_cert_chain
sslsock.peer_cert_chain if sslsock
end

#
# Access to client cert
#
def client_cert
sslsock.sslctx.cert if sslsock
end

#
# Access to client key
#
def client_key
sslsock.sslctx.key if sslsock
end

#
# Access to the current cipher
#
Expand Down

0 comments on commit 86a1843

Please sign in to comment.