diff --git a/lib/rex/socket/parameters.rb b/lib/rex/socket/parameters.rb index 5b4cd3b..aa3e7d9 100644 --- a/lib/rex/socket/parameters.rb +++ b/lib/rex/socket/parameters.rb @@ -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 @@ -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] diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb index f37ee3f..9c47cb7 100644 --- a/lib/rex/socket/ssl_tcp.rb +++ b/lib/rex/socket/ssl_tcp.rb @@ -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 @@ -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: @@ -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 #