Module: Arachni::RPC::EM::SSL
Overview
Adds support for SSL and peer verification.
To be included by EventMachine::Connection classes.
@author: Tasos “Zapotek” Laskos <[email protected]>
Instance Method Summary collapse
- #are_we_a_client? ⇒ Boolean
-
#ca_store ⇒ OpenSSL::X509::Store
Certificate store.
-
#end_ssl ⇒ Object
Cleans up any SSL related resources.
-
#log(severity, progname, msg) ⇒ Object
To be implemented by the parent.
-
#ssl_handshake_completed ⇒ Object
Checks for an appropriate server cert hostname if run from the client-side.
- #ssl_opts? ⇒ Boolean
-
#ssl_verify_peer(cert_string) ⇒ Object
Verifies the peer cert based on the #ca_store.
-
#start_ssl ⇒ Object
Starts SSL with the supplied keys, certs etc.
- #verified_peer? ⇒ Boolean
Methods included from ConnectionUtilities
Instance Method Details
#are_we_a_client? ⇒ Boolean
157 158 159 |
# File 'lib/arachni/rpc/em/ssl.rb', line 157 def are_we_a_client? @opts[:role] == :client end |
#ca_store ⇒ OpenSSL::X509::Store
Returns certificate store.
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/arachni/rpc/em/ssl.rb', line 97 def ca_store if !@ca_store if file = @opts[:ssl_ca] @ca_store = OpenSSL::X509::Store.new @ca_store.add_file( file ) else fail "No CA certificate has been provided." end end @ca_store end |
#end_ssl ⇒ Object
Cleans up any SSL related resources.
76 77 |
# File 'lib/arachni/rpc/em/ssl.rb', line 76 def end_ssl end |
#log(severity, progname, msg) ⇒ Object
To be implemented by the parent.
By default, it will ‘warn’ if the severity is :error and will ‘raise’ if the severity if :fatal.
89 90 91 92 |
# File 'lib/arachni/rpc/em/ssl.rb', line 89 def log( severity, progname, msg ) warn "#{progname}: #{msg}" if severity == :error fail "#{progname}: #{msg}" if severity == :fatal end |
#ssl_handshake_completed ⇒ Object
Checks for an appropriate server cert hostname if run from the client-side.
Does nothing when on the server-side.
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/arachni/rpc/em/ssl.rb', line 146 def ssl_handshake_completed return if !are_we_a_client? || !ssl_opts? || OpenSSL::SSL.verify_certificate_identity( @last_seen_cert, @opts[:host] ) log( :error, 'SSL', "The hostname '#{@opts[:host]}' does not match the server certificate." ) close_connection end |
#ssl_opts? ⇒ Boolean
161 162 163 |
# File 'lib/arachni/rpc/em/ssl.rb', line 161 def ssl_opts? @opts[:ssl_ca] && @opts[:ssl_pkey] && @opts[:ssl_cert] end |
#ssl_verify_peer(cert_string) ⇒ Object
Verifies the peer cert based on the #ca_store.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/arachni/rpc/em/ssl.rb', line 115 def ssl_verify_peer( cert_string ) cert = OpenSSL::X509::Certificate.new( cert_string ) # Some servers send the same certificate multiple times. I'm not even # joking... (gmail.com) return true if cert == @last_seen_cert if ca_store.verify( cert ) @last_seen_cert = cert # A server may send the root certificate, which we already have and thus # should not be added to the store again. ca_store.add_cert( @last_seen_cert ) if !@last_seen_cert.root? @verified_peer = true true else log( :error, 'SSL', "#{ca_store.error_string.capitalize} ['#{peer_ip_addr}']." ) false end end |
#start_ssl ⇒ Object
Starts SSL with the supplied keys, certs etc.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/arachni/rpc/em/ssl.rb', line 51 def start_ssl @verified_peer = false @ssl_requested = true ssl_opts = {} if ssl_opts? ssl_opts = { private_key_file: @opts[:ssl_pkey], cert_chain_file: @opts[:ssl_cert], verify_peer: true } @last_seen_cert = nil end # ap ssl_opts start_tls( ssl_opts ) end |
#verified_peer? ⇒ Boolean
69 70 71 |
# File 'lib/arachni/rpc/em/ssl.rb', line 69 def verified_peer? @verified_peer end |