From 3b7675bebb804a46392ad74f559fbe93afdbe40b Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 18 Jun 2015 11:41:53 -0700 Subject: [PATCH] Added option for an SSL certificate chain to lumberjack server Not sure if the client needs any changes, I tested it with logstash-forwarder and it worked well --- lib/lumberjack/server.rb | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/lumberjack/server.rb b/lib/lumberjack/server.rb index 416a703..057d2cd 100644 --- a/lib/lumberjack/server.rb +++ b/lib/lumberjack/server.rb @@ -23,7 +23,8 @@ def initialize(options={}) :address => "0.0.0.0", :ssl_certificate => nil, :ssl_key => nil, - :ssl_key_passphrase => nil + :ssl_key_passphrase => nil, + :ssl_cert_chain => nil }.merge(options) [:ssl_certificate, :ssl_key].each do |k| @@ -41,9 +42,46 @@ def initialize(options={}) @ssl.cert = OpenSSL::X509::Certificate.new(File.read(@options[:ssl_certificate])) @ssl.key = OpenSSL::PKey::RSA.new(File.read(@options[:ssl_key]), @options[:ssl_key_passphrase]) + if @options[:ssl_cert_chain] != nil + @ssl.extra_chain_cert = cert_chain(File.read(@options[:ssl_cert_chain])) + end @ssl_server = OpenSSL::SSL::SSLServer.new(@tcp_server, @ssl) end # def initialize + + ## Borrowed from packettheif/uti.rb: + ## https://github.com/iSECPartners/tlspretense/blob/master/lib/packetthief/util.rb + # Extracts all PEM encoded certs from a raw string and returns a list of + # X509 certificate objects in the order they appear in the file. + # + # This can be helpful for loading a chain of certificates, eg for a + # server. + # + # Usage: + # + # chain = cert_chain(File.read("chain.pem")) + # p chain # => [#, + # #] + def cert_chain(raw) + rawchain = split_chain(raw) + rawchain.map { |rawcert| OpenSSL::X509::Certificate.new(rawcert) } + end + + ## Continuing borrowing from packetthief/util.rb + ## https://github.com/iSECPartners/tlspretense/blob/master/lib/packetthief/util.rb + # Extracts all PEM encoded certificates out of a raw string and returns + # each raw PEM encoded certificate in an array. + def split_chain(raw) + chain = [] + remaining = raw + certpat = /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/m + while m = certpat.match(remaining) + remaining = m.post_match + chain << m[0].strip + end + chain + end + def run(&block) while true connection = accept