Skip to content

Commit

Permalink
Accept private key for TLS server without passphrase
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuki Ito committed May 22, 2017
1 parent 155ceac commit d094045
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 33 deletions.
4 changes: 2 additions & 2 deletions lib/fluent/plugin_helper/cert_option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ def cert_option_server_validate!(conf)
case
when conf.cert_path
raise Fluent::ConfigError, "private_key_path is required when cert_path is specified" unless conf.private_key_path
raise Fluent::ConfigError, "private_key_passphrase is required when cert_path is specified" unless conf.private_key_passphrase
log.warn "For security reason, setting private_key_passphrase is recommended when cert_path is specified" unless conf.private_key_passphrase
cert_option_load(conf.cert_path, conf.private_key_path, conf.private_key_passphrase)

when conf.ca_cert_path
raise Fluent::ConfigError, "ca_private_key_path is required when ca_cert_path is specified" unless conf.ca_private_key_path
raise Fluent::ConfigError, "ca_private_key_passphrase is required when ca_cert_path is specified" unless conf.ca_private_key_passphrase
log.warn "For security reason, setting ca_private_key_passphrase is recommended when ca_cert_path is specified" unless conf.ca_private_key_passphrase
generate_opts = cert_option_cert_generation_opts_from_conf(conf)
cert_option_generate_server_pair_by_ca(
conf.ca_cert_path,
Expand Down
68 changes: 37 additions & 31 deletions test/plugin_helper/test_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -767,8 +767,9 @@ def create_server_options

def write_cert_and_key(cert_path, cert, key_path, key, passphrase)
File.open(cert_path, "w"){|f| f.write(cert.to_pem) }
# Encrypt secret key by AES256, and write it in PEM format
File.open(key_path, "w"){|f| f.write(key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase)) }
# Write the secret key (raw or ecnrypted by AES256) in PEM format
key_str = passphrase ? key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase) : key.export
File.open(key_path, "w"){|f| f.write(key_str) }
File.chmod(0600, cert_path, key_path)
end

Expand Down Expand Up @@ -807,7 +808,8 @@ def create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_pa
f.write server_cert.to_pem
f.write chain_cert.to_pem
end
File.open(private_key_path, "w"){|f| f.write(server_key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase)) }
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

Expand Down Expand Up @@ -889,10 +891,11 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load self-signed cert/key pair (files), verified from clients using cert files' do
data('with passphrase' => 'yaaaaaaaaaaaaaaaaaaay',
'without passphrase' => nil)
test 'load self-signed cert/key pair (files), verified from clients using cert files' do |private_key_passphrase|
cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_signed_by_self(cert_path, private_key_path, private_key_passphrase)

tls_options = {
Expand All @@ -902,8 +905,8 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
insecure: false,
cert_path: cert_path,
private_key_path: private_key_path,
private_key_passphrase: private_key_passphrase,
}
tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
received = ""
@d.server_create_tls(:s, PORT, tls_options: tls_options) do |data, conn|
received << data
Expand All @@ -922,10 +925,11 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do
data('with passphrase' => "fooooooooooooooooooooooooo",
'without passphrase' => nil)
test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do |ca_key_passphrase|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "fooooooooooooooooooooooooo"
create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)

tls_options = {
Expand All @@ -935,9 +939,9 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
insecure: false,
ca_cert_path: ca_cert_path,
ca_private_key_path: ca_key_path,
ca_private_key_passphrase: ca_key_passphrase,
generate_private_key_length: 2048,
}
tls_options[:ca_private_key_passphrase] = ca_key_passphrase if ca_key_passphrase
received = ""
@d.server_create_tls(:s, PORT, tls_options: tls_options) do |data, conn|
received << data
Expand All @@ -950,15 +954,15 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load static server cert by private CA cert file, verified from clients using CA cert file' do
data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
'without passphrase' => [nil, nil])
test 'load static server cert by private CA cert file, verified from clients using CA cert file' do |(ca_key_passphrase, private_key_passphrase)|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "foooooooo"
create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)

cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)

tls_options = {
Expand All @@ -968,8 +972,8 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
insecure: false,
cert_path: cert_path,
private_key_path: private_key_path,
private_key_passphrase: private_key_passphrase,
}
tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
received = ""
@d.server_create_tls(:s, PORT, tls_options: tls_options) do |data, conn|
received << data
Expand All @@ -982,13 +986,13 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do
data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
'without passphrase' => [nil, nil])
test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do |(ca_key_passphrase, private_key_passphrase)|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "foooooooo"
cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)

tls_options = {
Expand All @@ -998,8 +1002,8 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
insecure: false,
cert_path: cert_path,
private_key_path: private_key_path,
private_key_passphrase: private_key_passphrase,
}
tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
received = ""
@d.server_create_tls(:s, PORT, tls_options: tls_options) do |data, conn|
received << data
Expand Down Expand Up @@ -1042,17 +1046,18 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load self-signed cert/key pair (files), verified from clients using cert files' do
data('with passphrase' => "yaaaaaaaaaaaaaaaaaaay",
'without passphrase' => nil)
test 'load self-signed cert/key pair (files), verified from clients using cert files' do |private_key_passphrase|
cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_signed_by_self(cert_path, private_key_path, private_key_passphrase)

transport_opts = {
'cert_path' => cert_path,
'private_key_path' => private_key_path,
'private_key_passphrase' => private_key_passphrase,
}
transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
transport_conf = config_element('transport', 'tls', transport_opts)
conf = config_element('match', 'tag.*', {}, [transport_conf])

Expand All @@ -1076,17 +1081,18 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do
data('with passphrase' => "fooooooooooooooooooooooooo",
'without passphrase' => nil)
test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do |ca_key_passphrase|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "fooooooooooooooooooooooooo"
create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)

transport_opts = {
'ca_cert_path' => ca_cert_path,
'ca_private_key_path' => ca_key_path,
'ca_private_key_passphrase' => ca_key_passphrase,
}
transport_opts['ca_private_key_passphrase'] = ca_key_passphrase if ca_key_passphrase
transport_conf = config_element('transport', 'tls', transport_opts)
conf = config_element('match', 'tag.*', {}, [transport_conf])

Expand All @@ -1104,22 +1110,22 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load static server cert by private CA cert file, verified from clients using CA cert file' do
data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
'without passphrase' => [nil, nil])
test 'load static server cert by private CA cert file, verified from clients using CA cert file' do |(ca_key_passphrase, private_key_passphrase)|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "foooooooo"
create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)

cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)

transport_opts = {
'cert_path' => cert_path,
'private_key_path' => private_key_path,
'private_key_passphrase' => private_key_passphrase,
}
transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
transport_conf = config_element('transport', 'tls', transport_opts)
conf = config_element('match', 'tag.*', {}, [transport_conf])

Expand All @@ -1137,20 +1143,20 @@ def open_tls_session(addr, port, verify: true, cert_path: nil, selfsigned: true,
assert_equal "yay\nfoo\n", received
end

test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do
data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
'without passphrase' => [nil, nil])
test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do |(ca_key_passphrase, private_key_passphrase)|
ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
ca_key_path = File.join(@certs_dir, "ca.key.pem")
ca_key_passphrase = "foooooooo"
cert_path = File.join(@server_cert_dir, "cert.pem")
private_key_path = File.join(@certs_dir, "server.key.pem")
private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)

transport_opts = {
'cert_path' => cert_path,
'private_key_path' => private_key_path,
'private_key_passphrase' => private_key_passphrase,
}
transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
transport_conf = config_element('transport', 'tls', transport_opts)
conf = config_element('match', 'tag.*', {}, [transport_conf])

Expand Down

0 comments on commit d094045

Please sign in to comment.