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

Allow cert chains in client auth #2930

Merged
merged 1 commit into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 19 additions & 1 deletion lib/fluent/plugin_helper/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,15 @@ def socket_create_tls(
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
context.cert_store = cert_store
context.verify_hostname = true if verify_fqdn && fqdn && context.respond_to?(:verify_hostname=)
context.cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) if cert_path
context.key = OpenSSL::PKey::read(File.read(private_key_path), private_key_passphrase) if private_key_path

if cert_path
certs = socket_certificates_from_file(cert_path)
context.cert = certs.shift
unless certs.empty?
context.extra_chain_cert = certs
end
end
end
Fluent::TLS.set_version_to_context(context, version, min_version, max_version)

Expand Down Expand Up @@ -186,6 +193,17 @@ def socket_create_tls(
end
end

def socket_certificates_from_file(path)
data = File.read(path)
pattern = Regexp.compile('-+BEGIN CERTIFICATE-+\r?\n(?:[^-]*\r?\n)+-+END CERTIFICATE-+\r?\n?', Regexp::MULTILINE)
list = []
data.scan(pattern) { |match| list << OpenSSL::X509::Certificate.new(match) }
if list.length == 0
log.warn "cert_path does not contain a valid certificate"
end
list
end

def self.tls_verify_result_name(code)
case code
when OpenSSL::X509::V_OK then 'V_OK'
Expand Down
27 changes: 27 additions & 0 deletions test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA21in8qRqBrfYlRHr1N6eGq3d4CnKe+lTt0sGbab1670s0+h1
lGtjWny6gLSnt5PBY36CUoFB8MtRciVG2zUhB+dAZe4Mst5dzJO6cONT/l/USbCV
rQ/x8m3YzeJNj89fCZ7/7po8CpEfn16BMAd6TMXZZ8O+DCgv3SliEyxpi9CLg2PK
wAV4lwktbGenYadWLFWjv5a+QElFGH/tu5jUDhggoisoQGyZCls2Vmbr6RH+uiy8
js3gxy+5YgbuwkrQtjbfwxe5yEsd6RgzO8oLqlowCwCrn4CNaXFwaZa/vqcWzY4L
qiEWLfmFpFcSZdoWjr1WHsJS/PM3AyJea8nAnQIDAQABAoIBAGkMpaqsmWbMR7rl
EVgqoffPCzMfcK01ivV+xf5f9ulG+aAndaB2aefdUojvfF+MMRNQdGPFKeqDxWbw
eWXkpQQe+ZWXk5darfubSLBl/0UVahs8qgJvX4WmnC3GUzUrsK1v68y/K0A4TrfJ
z/9LpYP9QWjTs0IpQPsfpavfGlFt1TJvPxmomn7D+n0N6zzD3kFlGdeCSYwtPURR
dJ7ifX2vU4E8UtSm7gLrXlmAl1O7bJjFvL3+QlzKDM4M1WJpA9MkmM2icKxdYpew
biRmIiUHdV4soad2Aq58v4q5UgdMqGI8f+fWPO9qgXN7AKbT9NkXr1w/pziOt5rq
/77lbKECgYEA9bmOSA1LfRRclJCaoWWu4PiaXdvMHvsNC9r8NUGuwmiosEMKHFEJ
z8wvzVXprziXAwDTwqkPJmKseNPC8WCq2GfNu7lqJ1V1wHxpzHKhiAWhs7rE7skW
mF2xn2Tocba/L3Nb+K0tXhOZ7daduz94YXFhmRtsutZ9JvFv3G+QmHkCgYEA5IS4
+cOFyha486U9jXyLcPmZXZY9ql4ILuKuQ5pHA7CBO/zU2behuwcainW6P0WzbhKs
CP8xR5W/otqcaHZxy6hg9/nUFVVZIR/0jgKyxCqJA1W49jt23gykmU6q0vj7haZJ
QMhcAbleHBC7YvYoMTpTMe7tZP4YsFNysBn76EUCgYBqtFAn07YjM7NcREsRqSE+
ylXmSisijOxGaKq6ybIE9APEvufmEf7LwKRFa3hVwaI6CKLsVhOhHJo+wd5WiR7H
aJQ7X7HMMN04YA5lXKXudluYu5MHCkWIlq8qQ1x4/N2a0mJu42ze/G4MjPTjuhUh
Y2X5YaJepAOm5JMpyzykKQKBgQDj9eaU+dBgLdSo8UD7ALAVrlio/HRdnNoq82SF
+cQ30P7KucgXvFDxQv/d+d0mu0BoYOYPP4uIbsEyE0SODQIt+LVrCmTgNzjni3op
pFVyzT/K/Nu7fsxwbEpSySAtv8UhqSVQI89sxN81vhdAfHDR0u4lVMSqx7QXSdeS
Bwm9xQKBgQDSeoHoXbmiqRBss9Em69JPwWRZOc9eLns+fFJ1x/WkhY4bnnVXTYkZ
LzRN4ICq18xHy8egbl93uxDcjkMxi3Wj64QZcygI9gWmDBW2hdMpEArR/grsM/FH
DYu9KUMhm5T1KtXtV3izSVCprthdGjbKSbmR6hGw3n9Z1uP6V1rnXQ==
-----END RSA PRIVATE KEY-----
20 changes: 20 additions & 0 deletions test/plugin_helper/data/cert/cert_chains/ca-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDPTCCAiWgAwIBAgILAJJ76Kpa6DYtsncwDQYJKoZIhvcNAQELBQAwUzELMAkG
A1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8w
HQYDVQQDDBZjYS50ZXN0aW5nLmZsdWVudGQub3JnMCAXDTcwMDEwMTAwMDAwMFoY
DzIxMTgxMDI3MDgwNjU3WjBTMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAU
BgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAMMFmNhLnRlc3RpbmcuZmx1ZW50
ZC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbWKfypGoGt9iV
EevU3p4ard3gKcp76VO3SwZtpvXrvSzT6HWUa2NafLqAtKe3k8FjfoJSgUHwy1Fy
JUbbNSEH50Bl7gyy3l3Mk7pw41P+X9RJsJWtD/HybdjN4k2Pz18Jnv/umjwKkR+f
XoEwB3pMxdlnw74MKC/dKWITLGmL0IuDY8rABXiXCS1sZ6dhp1YsVaO/lr5ASUUY
f+27mNQOGCCiKyhAbJkKWzZWZuvpEf66LLyOzeDHL7liBu7CStC2Nt/DF7nISx3p
GDM7yguqWjALAKufgI1pcXBplr++pxbNjguqIRYt+YWkVxJl2haOvVYewlL88zcD
Il5rycCdAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
AGPhEAc+vb9PHyet9t5gKJTZF7S4x207hKZ0zLqCQCLM7VjrTVBh/TUFT+saiPsv
4k2TYSZKInYXh6tkSzdGlRyzk166hF1eOTOae/92Da5PEQMT0AC+SDRDHXrNTyD8
ZxP2xOl0j+FNeKQDdNL+PCU56PYehY40dYZ/EjRyu4VjKaSCMHcVx7eMTyxU3wtB
HbOa8UJdUXEjn4h7icz4aca22aqLedXNaDr6YX+mo25t1jsTO7cEMfr4Ce7GvxdA
msey/b5jnsKcpL7/2uYz5+owD39JZQBRQt+1YAzIU+BNiz8yzdXJO4aQpGWTflIB
jO31o7x4loEvaBTQbX3iP2g=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions test/plugin_helper/data/cert/cert_chains/cert-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAzQtGZgClcBIDKC0U1sQpznVV9HzAZANDVazrDGA8Euf8Kx4X
dnVoE+HzwAviL4VLDPzNBLyoZ2wf3wg6D+1UAhA0DqPRCihhfJqBX0WgewakSl5a
wrc1XIXtiMxcWE/5+XtodjO71gECBgmd/l0UtdFY7mMt/gArH8PQf29ABGiB1zzn
d0MNgA0r2OlXICe4kDzTHqDBv7nFgQFro2vkI/QJD5fABbb62HRWgUfQ13DUShSG
H5FPkMxTkCs5GShyjYCC5IhI+AKx5RWvb4kuMRsxWC7JHc/XKPdbeLkNWRCFzTnO
OR09Qdp45tBbXtX0IjInxsnNOBzW0zTSg0xUtwIDAQABAoIBAG4N5zNIlYOZp2gh
ClZb47SU9hXL/9euiK2rql1yKcxcB9V8yUsjqUFCvfoOZtDq0mWeKsyoFhusxU6I
s+FomPaii85vzvuMwQaIR3hDfueJoRTpn/1zKIkIuX37cnVUN+/YdTE8g01SLSvg
bZThkQQl4X3SbhUvMfZSu84qgEncdtJ08zx81CB1Fpn0HIjpmpRM1F9jjDwtkVUw
1gVQm9g7fwbgRfqSUyKkEqKvCVYnLQx3X5inuAEps4zIzAXF8RtxFymyHfExzZqr
Pj5uYjTbf/wkaU9nWQzXeCbRTz3ZrjvFnisFt1HI2uijd1DjJ7CB7Ls752RWekXS
Yc9FFwECgYEA/gZ3Hx4dIb6NW6UmPKjiQex/tVqwCRaxGtpA7qensf187N2nn4FD
jdQJ69XmoDRKr2X+e7tsgKpETGufdDQ8MNBHz2krfqXVSlsEIOjeLfRRqhh+8Bcr
flri0sumVbk0X9bnXzyCc4AGcRhtT9U69HCMTlly2z0pjIlVvmFXARECgYEAzqNV
FSHHbEU+5zToJK0jyTaE/F+u9n5YKDcRN9RrKrEYcoUzKbIYJrUulbRGfsqAxY5L
KtIDRI9NmPDBYqBwqSFnm9LcLn8CgQH/rRSFJv1Iw+sPHd/Nrk1KWjpO0OYRgfiB
oxcgGSzHp0OZP+e7Trtq1TKW6VyadEsPZ7oKeUcCgYB9TiMkrm4gXybLtkOOWKCD
dG3qv7lmQlNKs66kCv+lxS0CirRM8i6on5flRbZmAGV28BEAaAu1zEe0isI1SC8I
xTUnEvHpn1P/QbZfpX8zm/lMtpinRkamJZ8N7Hc4ggtb2152lBqlbtm+oBYL81sJ
iRss6uLFUv5T3Mr3Bn0sgQKBgGr4xQf+h6V2J307t12dQCRfE/MueX3jpDGVaFV1
otDkAxrt97GDH9uR+f7H56KlpIohAqq1M7nfUbV2FTbAhfIYd/GD9DYhzCMK7Ngm
AlRP1MaPvjCh9nFgU7hn7PtZzwBwrHPIefZuZyEg7onVpfK5NTIPUW6XYOIJJX12
IwvrAoGAGwg2Cq6Vs/KkiCDxoy42HVZLS/DS/iHfUTAXtekF88qwT1zHFqF1ImvO
+FEUx8IbxY1oifSQc3Jw9HYnmYqmFW1PThNG3CwyaOGgtlEFcvhHsNjLRGJSQbN2
cUYBe2hHXii7OL8T8kIvLlCAKGA8IIfPGhsu3uUtrvMBo5c0WmQ=
-----END RSA PRIVATE KEY-----
40 changes: 40 additions & 0 deletions test/plugin_helper/data/cert/cert_chains/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgILANkmymLgb5e04tcwDQYJKoZIhvcNAQELBQAwVDELMAkG
A1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSAw
HgYDVQQDDBdjYTIudGVzdGluZy5mbHVlbnRkLm9yZzAgFw03MDAxMDEwMDAwMDBa
GA8yMTE4MTAyNzA4MDY1N1owVzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYw
FAYDVQQHDA1Nb3VudGFpbiBWaWV3MSMwIQYDVQQDDBpzZXJ2ZXIudGVzdGluZy5m
bHVlbnRkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0LRmYA
pXASAygtFNbEKc51VfR8wGQDQ1Ws6wxgPBLn/CseF3Z1aBPh88AL4i+FSwz8zQS8
qGdsH98IOg/tVAIQNA6j0QooYXyagV9FoHsGpEpeWsK3NVyF7YjMXFhP+fl7aHYz
u9YBAgYJnf5dFLXRWO5jLf4AKx/D0H9vQARogdc853dDDYANK9jpVyAnuJA80x6g
wb+5xYEBa6Nr5CP0CQ+XwAW2+th0VoFH0Ndw1EoUhh+RT5DMU5ArORkoco2AguSI
SPgCseUVr2+JLjEbMVguyR3P1yj3W3i5DVkQhc05zjkdPUHaeObQW17V9CIyJ8bJ
zTgc1tM00oNMVLcCAwEAAaMQMA4wDAYDVR0TBAUwAwEBADANBgkqhkiG9w0BAQsF
AAOCAQEAMzoxZJqhu8zyKI20Hz5SAqva+jcHbZbR9AXlt4LWQEttsXy4S52XLZBB
4Es/Fah4lyou9R1xdUfF6iGBV6HgDMIuh+QYfqA/jJ4HXNMKLtDXakS8xYp2A0Wn
g0EnjGx44DNweBkKGB9asldgwOM7MYMoQvS3Nkyu3oFqpfLpuWpWB/3Vw3PMGEdx
r/c8Ev5XoVtl2+dXszsEp2jwUOFo8+DZzFdBZdA2F7RmcP+zxbAHIw/jHf/ptDGg
NtzHmLhxiLblGlJHw/4a0HhXa453jzLsD1+hQpqBRUNbXBp1qpjqEr5SF1iVNGpZ
peWFawp53MkIBXRls66ViJsl//fPBg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDPTCCAiWgAwIBAgIKRbRr9ZfmrY72TjANBgkqhkiG9w0BAQsFADBTMQswCQYD
VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAd
BgNVBAMMFmNhLnRlc3RpbmcuZmx1ZW50ZC5vcmcwIBcNNzAwMTAxMDAwMDAwWhgP
MjExODEwMjcwODA2NTdaMFQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQG
A1UEBwwNTW91bnRhaW4gVmlldzEgMB4GA1UEAwwXY2EyLnRlc3RpbmcuZmx1ZW50
ZC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6gnGxD4RQuAA1
fQNMl9mctiIvcJ0Dz5f3JtCJlKKqBDKJ17py7tjFZ2MZ5vytIl1DUU2oxHew8F/u
U8s+8ljmL3seiXx2kMCOxCvSW3JYUQrzbTHKszna7Ffy94SzpRDh/4/2RGatnSqi
n4fRpalrchhH6Ds6v486o7YcwEKPR2dlD+Ltd/V3lMAOAmoRoe2aQlLudOUQjHJU
YWGim8XS2dNAEy4WR5DvjYEA+CwKEX7f9p0Dihs8FKBjB2TvBwUkdfILLEnwA1rs
r0coUt3kwYt9TYNYv6/SZYvFtaYjM3BmLVHI3mtEchaA+Tij4V4gRZ573Ai1+Fb8
rxn+oTsVAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
AHID7VD2PS7svmCXRg4qe7MkhA0veIadZRE6WZgJo3Z64p9jUWu/Y3ZrlZuDg0qI
yV65UgWrgUOiGN6RZmI5A850DH3ryjvQElPHWjRavm0GtrOxFhHYpX8N7DRFW7t0
7mld7YvbKRj0BrovU3avPC1P9w8FpegMKh48HsoRCO3NhHvYwtAf2B767UuAaqnI
DW9rMPRTZv+Pv+G+kJN+updOs6HiHFxeS8Bwb8GlADcwWNGMqyJJyKmaefYVzDKt
xfBiKiwev6Hm8RVTk1H3rKVZox/ZkDiZfZhmBJqO4mdDR4LLFIRIPqjUPxENsKFJ
MyrDcwH+0Aq9ZSiRaVyfCkQ=
-----END CERTIFICATE-----
38 changes: 38 additions & 0 deletions test/plugin_helper/data/cert/generate_cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module CertUtil

WITHOUT_CA_DIR = './without_ca'.freeze
WITH_CA_DIR = './with_ca'.freeze
WITH_CERT_CHAIN_DIR = './cert_chains'.freeze

CA_OPTION = {
private_key_length: 2048,
Expand Down Expand Up @@ -83,5 +84,42 @@ def create_with_ca
create_server_pair_signed_by_ca(ca_cert_pass_path, ca_key_pass_path, 'orange', cert_pass_path, cert_key_pass_path, 'apple')
end

def create_cert_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, passphrase)
root_cert, root_key, _ = CertUtil.cert_option_generate_ca_pair_self_signed(CA_OPTION)
write_cert_and_key(ca_cert_path, root_cert, ca_key_path, root_key, ca_key_passphrase)

intermediate_ca_options = CA_OPTION.dup
intermediate_ca_options[:common_name] = 'ca2.testing.fluentd.org'
chain_cert, chain_key = CertUtil.cert_option_generate_pair(intermediate_ca_options, root_cert.subject)
chain_cert.add_extension(OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)])))
chain_cert.sign(root_key, 'sha256')

cert, server_key, _ = CertUtil.cert_option_generate_pair(SERVER_OPTION, chain_cert.subject)
cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(false)]))
cert.sign(chain_key, 'sha256')

# write chained cert
File.open(cert_path, 'w') do |f|
f.write(cert.to_pem)
f.write(chain_cert.to_pem)
end

key_str = passphrase ? server_key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase) : server_key.export
File.open(private_key_path, "w") { |f| f.write(key_str) }
File.chmod(0600, cert_path, private_key_path)
end

def create_cert_chain
FileUtils.mkdir_p(WITH_CERT_CHAIN_DIR)
ca_cert_path = File.join(WITH_CERT_CHAIN_DIR, 'ca-cert.pem')
ca_key_path = File.join(WITH_CERT_CHAIN_DIR, 'ca-cert-key.pem')

cert_path = File.join(WITH_CERT_CHAIN_DIR, 'cert.pem')
private_key_path = File.join(WITH_CERT_CHAIN_DIR, 'cert-key.pem')

create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, nil, cert_path, private_key_path, nil)
end

create_without_ca
create_with_ca
create_cert_chain
131 changes: 131 additions & 0 deletions test/plugin_helper/test_socket.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
require_relative '../helper'
require 'fluent/plugin_helper/socket'
require 'fluent/plugin/base'

require 'socket'
require 'openssl'

class SocketHelperTest < Test::Unit::TestCase
PORT = unused_port
CERT_DIR = File.expand_path(File.dirname(__FILE__) + '/data/cert/without_ca')
CA_CERT_DIR = File.expand_path(File.dirname(__FILE__) + '/data/cert/with_ca')
CERT_CHAINS_DIR = File.expand_path(File.dirname(__FILE__) + '/data/cert/cert_chains')

class SocketHelperTestPlugin < Fluent::Plugin::TestBase
helpers :socket
end

class EchoTLSServer
def initialize(host = '127.0.0.1', port = PORT, cert_path: nil, private_key_path: nil, ca_path: nil)
server = TCPServer.open(host, port)
ctx = OpenSSL::SSL::SSLContext.new
ctx.cert = OpenSSL::X509::Certificate.new(File.open(cert_path)) if cert_path

cert_store = OpenSSL::X509::Store.new
cert_store.set_default_paths
cert_store.add_file(ca_path) if ca_path
ctx.cert_store = cert_store

ctx.key = OpenSSL::PKey::RSA.new(File.open(private_key_path)) if private_key_path
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.verify_hostname = false

@server = OpenSSL::SSL::SSLServer.new(server, ctx)
@thread = nil
@r, @w = IO.pipe
end

def start
do_start

if block_given?
begin
yield
@thread.join(5)
ensure
stop
end
end
end

def stop
unless @w.closed?
@w.write('stop')
end

[@server, @w, @r].each do |s|
next if s.closed?
s.close
end

@thread.join(5)
end

private

def do_start
@thread = Thread.new(@server) do |s|
socks, _, _ = IO.select([s.accept, @r], nil, nil)

if socks.include?(@r)
break
end

sock = socks.first
buf = +''
loop do
b = sock.read_nonblock(1024, nil, exception: false)
if b == :wait_readable || b.nil?
break
end
buf << b
end

sock.write(buf)
sock.close
end
end
end

test 'with self-signed cert/key pair' do
cert_path = File.join(CERT_DIR, 'cert.pem')
private_key_path = File.join(CERT_DIR, 'cert-key.pem')

EchoTLSServer.new(cert_path: cert_path, private_key_path: private_key_path).start do
client = SocketHelperTestPlugin.new.socket_create_tls('127.0.0.1', PORT, verify_fqdn: false, cert_paths: [cert_path])
client.write('hello')
assert_equal 'hello', client.readpartial(100)
client.close
end
end

test 'with cert/key signed by self-signed CA' do
cert_path = File.join(CA_CERT_DIR, 'cert.pem')
private_key_path = File.join(CA_CERT_DIR, 'cert-key.pem')

ca_cert_path = File.join(CA_CERT_DIR, 'ca-cert.pem')

EchoTLSServer.new(cert_path: cert_path, private_key_path: private_key_path).start do
client = SocketHelperTestPlugin.new.socket_create_tls('127.0.0.1', PORT, verify_fqdn: false, cert_paths: [ca_cert_path])
client.write('hello')
assert_equal 'hello', client.readpartial(100)
client.close
end
end

test 'with cert/key signed by self-signed CA in server and client cert chain' do
cert_path = File.join(CERT_DIR, 'cert.pem')
private_key_path = File.join(CERT_DIR, 'cert-key.pem')

client_ca_cert_path = File.join(CERT_CHAINS_DIR, 'ca-cert.pem')
client_cert_path = File.join(CERT_CHAINS_DIR, 'cert.pem')
client_private_key_path = File.join(CERT_CHAINS_DIR, 'cert-key.pem')

EchoTLSServer.new(cert_path: cert_path, private_key_path: private_key_path, ca_path: client_ca_cert_path).start do
client = SocketHelperTestPlugin.new.socket_create_tls('127.0.0.1', PORT, verify_fqdn: false, cert_path: client_cert_path, private_key_path: client_private_key_path, cert_paths: [cert_path])
client.write('hello')
assert_equal 'hello', client.readpartial(100)
client.close
end
end
end