Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate certificates during WebSocket connections, even if they have expired cross-root certificates #2

Open
wants to merge 9 commits into
base: add-socket-mode
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions lib/faye/websocket/ssl_verifier_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module SslVerifierPatch
def initialize(hostname, ssl_opts)
@hostname = hostname
@ssl_opts = ssl_opts
@cert_store = OpenSSL::X509::Store.new

if dir = @ssl_opts[:root_ca_dir]
Dir.glob(File.join(dir, "*.pem")).each { |ca_path| @cert_store.add_file(ca_path) }
else
@cert_store.set_default_paths
end
end
def ssl_verify_peer(cert_text)
return true unless should_verify?

certificate = parse_cert(cert_text)
return false unless certificate

# check due to cross chain certificate is expired (e.g. LE - DST Root X3)
# if not expired, pass to store
if @cert_store.verify(certificate)
store_cert(certificate)
@last_cert = certificate
end

true
end

def identity_verified?
# verify last cert is valid (e.g. ISRG Root)
@cert_store.verify(@last_cert) && (@last_cert and OpenSSL::SSL.verify_certificate_identity(@last_cert, @hostname))
end

def ssl_handshake_completed
return unless should_verify?

unless identity_verified?
raise Faye::WebSocket::SSLError, "@cert_store.verify(@last_cert) => #{@cert_store.verify(@last_cert)}, OpenSSL::SSL.verify_certificate_identity(@last_cert, @hostname)) => #{OpenSSL::SSL.verify_certificate_identity(@last_cert, @hostname)}, cert => #{@last_cert}"
end
end
end

Faye::WebSocket::SslVerifier.prepend(SslVerifierPatch)
1 change: 1 addition & 0 deletions lib/lita/adapters/slack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Slack < Adapter
config :token, type: String, required: true
config :app_token, type: String, required: true
config :proxy, type: String
config :root_ca_dir, type: String
config :parse, type: [String]
config :link_names, type: [true, false]
config :unfurl_links, type: [true, false]
Expand Down
2 changes: 2 additions & 0 deletions lib/lita/adapters/slack/rtm_connection.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'faye/websocket'
require 'faye/websocket/ssl_verifier_patch'
require 'multi_json'

require 'lita/adapters/slack/api'
Expand Down Expand Up @@ -150,6 +151,7 @@ def safe_payload_for(channel, string)
def websocket_options
options = { ping: 10 }
options[:proxy] = { :origin => config.proxy } if config.proxy
options[:tls] = { :root_ca_dir => config.root_ca_dir } if config.root_ca_dir
options
end

Expand Down