Skip to content

Commit

Permalink
Merge TLS verification patch from Faraday (#340)
Browse files Browse the repository at this point in the history
Closes #339, CVE-2020-13482

Credit to Mislav Marohnić for original implementation, merged from
Faraday.
  • Loading branch information
igrigorik authored Jun 1, 2020
1 parent 1d1f82f commit e5fa144
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/em-http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

require 'base64'
require 'socket'
require 'openssl'

require 'em-http/core_ext/bytesize'
require 'em-http/http_connection'
Expand Down
56 changes: 56 additions & 0 deletions lib/em-http/http_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,62 @@ def connection_completed
def unbind(reason=nil)
@parent.unbind(reason)
end

# TLS verification support, original implementation by Mislav Marohnić
# https://github.com/lostisland/faraday/blob/63cf47c95b573539f047c729bd9ad67560bc83ff/lib/faraday/adapter/em_http_ssl_patch.rb
def ssl_verify_peer(cert_string)
cert = nil
begin
cert = OpenSSL::X509::Certificate.new(cert_string)
rescue OpenSSL::X509::CertificateError
return false
end

@last_seen_cert = cert

if certificate_store.verify(@last_seen_cert)
begin
certificate_store.add_cert(@last_seen_cert)
rescue OpenSSL::X509::StoreError => e
raise e unless e.message == 'cert already in hash table'
end
true
else
raise OpenSSL::SSL::SSLError.new(%(unable to verify the server certificate for "#{host}"))
end
end

def ssl_handshake_completed
unless verify_peer?
warn "[WARNING; em-http-request] TLS hostname validation is disabled (use 'tls: {verify_peer: true}'), see" +
" CVE-2020-13482 and https://github.com/igrigorik/em-http-request/issues/339 for details"
return true
end

unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
raise OpenSSL::SSL::SSLError.new(%(host "#{host}" does not match the server certificate))
else
true
end
end

def verify_peer?
parent.connopts.tls[:verify_peer]
end

def host
parent.connopts.host
end

def certificate_store
@certificate_store ||= begin
store = OpenSSL::X509::Store.new
store.set_default_paths
ca_file = parent.connopts.tls[:cert_chain_file]
store.add_file(ca_file) if ca_file
store
end
end
end

class HttpConnection
Expand Down

0 comments on commit e5fa144

Please sign in to comment.