added ssl/tls support

This commit is contained in:
kenna-bmcdevitt 2020-07-22 01:00:20 -05:00
parent 40a7ca0cdf
commit f88d44f813
5 changed files with 112 additions and 13 deletions

3
fake_tunnel_connector/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
certificate.pem
private_key.pem
public_key.pem

View file

@ -3,25 +3,35 @@ require './http.rb'
require 'time'
class FakeTunnelConnector
attr_accessor :port, :server
def initialize(port)
attr_accessor :port, :server, :ssl_context
def initialize(port, ssl_context = nil)
@port = port
@server = TCPServer.open(port)
@ssl_context = ssl_context
end
def listen_and_respond
tcp_socket = server.accept
if ssl_context
tls_server = ssl_server
tcp_socket = tls_server.accept
else
tcp_socket = server.accept
end
response = read_socket(tcp_socket)
location = response[:start_line][:location]
write_response(tcp_socket, location)
tcp_socket.close
end
def ssl_server
OpenSSL::SSL::SSLServer.new server, ssl_context if ssl_context
end
def read_socket(tcp_socket)
start_line = []
headers = []
puts "Request Incoming:"
puts "-------------------"
puts 'Request Incoming:'
puts '-------------------'
# read lines from socket
while (line = tcp_socket.gets) && (line.chomp.length > 0)
# check for a valid http verb sent
@ -30,11 +40,11 @@ class FakeTunnelConnector
headers << header_line unless header_line.nil?
end
puts start_line
puts "Request Headers:"
puts "-------------------"
puts 'Request Headers:'
puts '-------------------'
puts headers
puts "\r\n"
{:start_line => start_line, :headers => headers}
{ start_line: start_line, headers: headers }
end
def parse_http_start_request_line(line)
@ -68,14 +78,14 @@ class FakeTunnelConnector
tcp_socket.print(ok(route_response_string))
end
def ok(body='Success')
def ok(body = 'Success')
body + "\r"
end
def ok_headers
"HTTP/1.1 200 OK\r\n" +
"Date: #{Time.now.utc}\r\n" +
"\r\n"
"Date: #{Time.now.utc}\r\n" +
"\r\n"
end
def route_request(location)
@ -99,5 +109,4 @@ class FakeTunnelConnector
body = '{"token":"797118d801342a0c5c5be3ed5420782becbea2e3bceea9275543dff4ee62dfc4"}'
ok(body)
end
end

22
fake_tunnel_connector/server.rb Executable file
View file

@ -0,0 +1,22 @@
require 'pry'
require './ssl.rb'
require './http.rb'
require './fake_tunnel_connector.rb'
port = ARGV[0]
cert_path = './certificate.pem'
key_path = './private_key.pem'
# lib for easier ssl usage
ssl_helper = SSL.new
# load our self-signed certificate
cert = ssl_helper.load_cert(cert_path)
#binding.pry
key = ssl_helper.load_key(key_path)
# setup a new ssl context to be used with the tcp server
context = ssl_helper.new_ssl_context(cert, key)
# setup our server on the port that we pass into the script and listen for https calls.
server = FakeTunnelConnector.new(port, ssl_context=context)
loop { server.listen_and_respond }

View file

@ -0,0 +1,8 @@
require './ssl.rb'
ssl_helper = SSL.new
cert, name, key = ssl_helper.generate_cert
signed_key = ssl_helper.self_sign_key(cert, name, key)
puts "you should now have a certificate.pem in the current working directory"
puts "you should now have a public_key.pem and a private_key.pem in the current working directory."

View file

@ -0,0 +1,57 @@
require 'openssl'
class SSL
def initialize; end
def generate_cert
key = generate_keypair(2048)
name = OpenSSL::X509::Name.parse('/CN=nobody/DC=example')
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 0
cert.not_before = Time.now
cert.not_after = Time.now + 3600
cert.public_key = key.public_key
cert.subject = name
[cert, name, key]
end
def generate_keypair(size)
key = generate_key(size)
open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
key
end
def generate_key(size)
OpenSSL::PKey::RSA.new size
end
def load_key(path, passphrase = nil)
if passphrase
OpenSSL::PKey::RSA.new(File.read(path), passphrase)
else
OpenSSL::PKey::RSA.new(File.read(path))
end
end
# sign cert generated from generate_cert method.
# cert, name, key = generate_cert
def self_sign_key(cert, name, key)
cert.issuer = name
cert.sign key, OpenSSL::Digest.new('SHA1')
open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
end
def new_ssl_context(cert, key)
context = OpenSSL::SSL::SSLContext.new
context.cert = cert
context.key = key
context
end
def load_cert(path)
OpenSSL::X509::Certificate.new File.read path
end
end