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

Permit reading private key from environment variable #294

Merged
merged 2 commits into from
Jan 30, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ The permissions for this folder should allow the puppet user (normally 'puppet')
-r-------- 1 puppet puppet 1.7K Sep 24 16:24 private_key.pkcs7.pem
-r-------- 1 puppet puppet 1.1K Sep 24 16:24 public_key.pkcs7.pem

You may also load the keypair into an environment variable and use the `pkcs7_private_key_env_var` and `pkcs7_public_key_env_var` options to specify the environment variable names to avoid writing the secret key to disk.


Basic usage
-----------
Expand Down Expand Up @@ -203,7 +205,7 @@ Hierarchy levels that use eyaml must set the following keys:
* `lookup_key` (must be set to `eyaml_lookup_key`).
* `path`/`paths`/`glob`/`globs` (choose one).
* `datadir` (can be omitted if you've set a default).
* `options` — a hash of eyaml-specific settings; by default, this should include `pkcs7_private_key` and `pkcs7_public_key`, but alternate encryption plugins use alternate options. Anything from the old `:eyaml` config section (except `datadir`) goes here.
* `options` — a hash of eyaml-specific settings; by default, this should include `pkcs7_private_key` and `pkcs7_public_key`, or `pkcs7_public_key_env_var` and `pkcs7_private_key_env_var`, but alternate encryption plugins use alternate options. Anything from the old `:eyaml` config section (except `datadir`) goes here.

You do not need to specify key names as `:symbols`; normal strings are fine.

Expand Down
13 changes: 13 additions & 0 deletions features/parser.feature
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ Feature: Parser
Then token 2 should decrypt to start with "planet of the apes"
Then token 2 should decrypt to a string with UTF-8 encodings

Scenario: Parse encrypted yaml with keypair as envvars
Given I make a parser instance with the ENC regexs
And I configure the keypair using envvars
And I load the keypair into envvars
And I load a file called test_input.yaml
When I parse the content
Then I should have 35 tokens
Then token 1 should be a NonMatchToken
Then token 2 should be a EncToken
Then token 2 should start with "ENC[PKCS7,MIIBiQYJKoZIhvcNAQ"
Then token 2 should decrypt to start with "planet of the apes"
Then token 2 should decrypt to a string with UTF-8 encodings

Scenario: Parse decrypted yaml
Given I make a parser instance with the DEC regexs
And I load a file called test_plain.yaml
Expand Down
18 changes: 15 additions & 3 deletions features/puppet.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: eyaml hiera integration
I want to verify that hiera-eyaml works within puppet and hiera

Scenario: verify puppet with hiera can use hiera-eyaml to decrypt data
When I run `rm -f /tmp/eyaml_puppettest.* 2>/dev/null`
When I run `bash -c 'rm -f /tmp/eyaml_puppettest.*' 2>/dev/null`
When I run `puppet apply --disable_warnings deprecations --confdir ./puppet --node_name_value localhost puppet/manifests/init.pp`
Then the output should contain "/tmp/eyaml_puppettest"
Then the file "/tmp/eyaml_puppettest.1" should match /^good night$/
Expand All @@ -15,9 +15,21 @@ Feature: eyaml hiera integration
Then the file "/tmp/eyaml_puppettest.5" should match /^gangs of new york$/


Scenario: verify puppet with hiera can use hiera-eyaml to decrypt data with keys as environment variables
Given I load the keypair into envvars
When I run `bash -c 'rm -f /tmp/eyaml_puppettest.*' 2>/dev/null`
When I run `puppet apply --disable_warnings deprecations --confdir ./puppet-envvar --node_name_value localhost puppet-envvar/manifests/init.pp`
Then the output should contain "/tmp/eyaml_puppettest"
Then the file "/tmp/eyaml_puppettest.1" should match /^good night$/
Then the file "/tmp/eyaml_puppettest.2" should match /^and good luck$/
Then the file "/tmp/eyaml_puppettest.3" should match /^and good luck$/
Then the file "/tmp/eyaml_puppettest.4" should match /^and good luck$/
Then the file "/tmp/eyaml_puppettest.5" should match /^gangs of new york$/


Scenario: verify puppet and facter for correct hash merge with incorrect fact
Given I set FACTER_fact to "not-existcity"
When I run `rm -f /tmp/eyaml_puppettest.* 2>/dev/null`
When I run `bash -c 'rm -f /tmp/eyaml_puppettest.*' 2>/dev/null`
When I run `puppet apply --disable_warnings deprecations --confdir ./puppet-hiera-merge --node_name_value localhost puppet-hiera-merge/manifests/init.pp`
Then the output should contain "/tmp/eyaml_puppettest"
Then the file "/tmp/eyaml_puppettest.1" should match /^good night$/
Expand All @@ -28,7 +40,7 @@ Feature: eyaml hiera integration

Scenario: verify puppet and facter for correct hash merge
Given I set FACTER_fact to "city"
When I run `rm -f /tmp/eyaml_puppettest.* 2>/dev/null`
When I run `bash -c 'rm -f /tmp/eyaml_puppettest.*' 2>/dev/null`
When I run `puppet apply --disable_warnings deprecations --confdir ./puppet-hiera-merge --node_name_value localhost puppet-hiera-merge/manifests/init.pp`
Then the output should contain "/tmp/eyaml_puppettest"
Then the file "/tmp/eyaml_puppettest.1" should match /^rise and shine$/
Expand Down
13 changes: 13 additions & 0 deletions features/recrypt.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ Feature: Recrypt
Then the tokens at 1 should match
Then the tokens at 5 should match

Scenario: Recrypt encrypted yaml with keypair as envvars
Given I recrypt a file
And I configure the keypair using envvars
And I load the keypair into envvars
And I load a file called test_input.yaml
And I recrypt it twice
Then I should have 35 tokens
Then the recrypted tokens should match
Then the recrypted decrypted content should match
Then the recrypted contents should differ
Then the tokens at 1 should match
Then the tokens at 5 should match

Scenario: Recrypt encrypted yaml using the eyaml tool
When I run `bash -c 'cp test_input.yaml test_input.eyaml'`
And I run `eyaml recrypt test_input.yaml`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This is configuration for the puppet master
# It tells the puppet master how to use the contents of this repo

modulepath = modules
manifest = manifests/init.pp

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class test::run {

file { "/tmp/eyaml_puppettest.1":
ensure => present,
content => hiera("plaintext_string"),
}

file { "/tmp/eyaml_puppettest.2":
ensure => present,
content => hiera("encrypted_string"),
}

# Ugly hack to call hiera() from puppet >= 4
file { "/tmp/eyaml_puppettest.3":
ensure => present,
content => inline_template("<%= scope.compiler.loaders.private_environment_loader.load(:function,'hiera').call(scope, 'encrypted_string') %>"),
}

file { "/tmp/eyaml_puppettest.4":
ensure => present,
content => hiera("default_encrypted_string"),
}

file { "/tmp/eyaml_puppettest.5":
ensure => present,
content => hiera("encrypted_block"),
}

}
13 changes: 13 additions & 0 deletions features/sandbox/puppet-envvar/environments/local/test.eyaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plaintext_string: good night
encrypted_string: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQAwDQYJKoZIhvcNAQEBBQAEggEAQoDt5EgMoJUpsqgcH7OdGJ3d9LzSpaAsgnPuyDHRaHRFHpOmeUk4J4qwHqlNDqD+AMkydaGlNswA/bLdoBwofZGZAUoly/Vkt3ciB4sw0pWlezEUx0dUfWGB95qOJwTqyXhQ4b4fcgCMUbwwCCombN5/LVwjxKHmC9knLNCDkUU5VNDy5Lanh3y8S2XwCJpjArhEcJNfwrf4yz3luQcKD3x91FR3NUYPjJOiTHl9lzxEJm4Mod7ioSj62FcP79qgULWqTKpxMpG4LPwCo/J84jhTkl+fhL/Bs/tmujgpLqBO000kdg4ZmrYrwYqpK6vgcFzVtZJEB3Tq8nXD9hSuAzA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFKh+qgHj0ajgtgpsFq5NEgBB/nP/DgjeKtd+D2MX6sOTv]
default_encrypted_string: ENC[MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQAwDQYJKoZIhvcNAQEBBQAEggEAQoDt5EgMoJUpsqgcH7OdGJ3d9LzSpaAsgnPuyDHRaHRFHpOmeUk4J4qwHqlNDqD+AMkydaGlNswA/bLdoBwofZGZAUoly/Vkt3ciB4sw0pWlezEUx0dUfWGB95qOJwTqyXhQ4b4fcgCMUbwwCCombN5/LVwjxKHmC9knLNCDkUU5VNDy5Lanh3y8S2XwCJpjArhEcJNfwrf4yz3luQcKD3x91FR3NUYPjJOiTHl9lzxEJm4Mod7ioSj62FcP79qgULWqTKpxMpG4LPwCo/J84jhTkl+fhL/Bs/tmujgpLqBO000kdg4ZmrYrwYqpK6vgcFzVtZJEB3Tq8nXD9hSuAzA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFKh+qgHj0ajgtgpsFq5NEgBB/nP/DgjeKtd+D2MX6sOTv]
encrypted_block: >
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQAw
DQYJKoZIhvcNAQEBBQAEggEAYzeWn3MBLhOs4hokxMCWcDd9VuwCylQRUQ0w
KwCObeORw8PJkCDvi5ZIA2YkrvYTT6u3/7KfAiHd0Rg1WLb9et0Mg/Fd3DFF
7qhqOGHoQt3+4eKzlcikeR0/Lqrq2vTpqZ2Sw1CZ7Dn+Z4ll95p7lp97rb2J
kYTVroLYGWEcsS3JZLL4/l3z0bJbXNKKqJ1aHCAFq+wmWXeb6cDvvyHFg2N/
vGPFEQjP7AbWhxHxXDbYIGcU073u5NtE40JXL8SH82iHxqRF8s9g6Dh5cmjg
AY2pkBD9e6N78NNx+PAJswsFAV4DOCbXdf2BisyYbM3na35MVfyb6ggDegrE
ebOxxDBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCWeGlYS5cQoX78L6LK
/mczgCD/pI7usp1XPebnN8CngxHXuUjj5S+6IUpOW6l2JgUeWw==]
17 changes: 17 additions & 0 deletions features/sandbox/puppet-envvar/hiera.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
:backends:
- eyaml
- yaml

:hierarchy:
- environments/%{environment}/%{module_name}

:yaml:
:datadir: ./puppet-envvar

:logger: console

:eyaml:
:datadir: ./puppet-envvar
:pkcs7_private_key_env_var: EYAML_PRIVATE_KEY
:pkcs7_public_key_env_var: EYAML_PUBLIC_KEY
27 changes: 27 additions & 0 deletions features/sandbox/puppet-envvar/keys/private_key.pkcs7.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0kX0qkf4FOHXuFqlVmbgo+UDrJdneH8XnmWM+stAs0XpzEQq
ErelZUhEi2x5z16RAsEw3cjd2BG78WHz1lcu3NP25BM990YQDl6e9pvmeMNA+wCK
1bwD7fCWXrAKb7xIXPJVd0ivP82ZPe71CmkFtiFr14mqNWrEpP/d2eQ4PAaCimAE
bBKyRRHHJzU6X+hOnq8GRZBwKh6Ljl31JYE2DG3KQ+ydM+r411jY2sjSykOovbeR
b7FCyOPaLRgyNjiDIJSTRlWLVJbYj6KDSoUD2+R95Owb5Z1OUL9Yn/BRIv5RyDvf
Br42sp0KR7t3pWGiHEuRYZkGDU5jKB/8bK7DRwIDAQABAoIBAERJKZp/AsatTSP2
dAkqIbu37MiI5rZP97id2/m6NgnCI5oNbOhlMVZB8NiiYrCAUnFlkdwEll7L65AJ
MmmiKHrYby5EPXRnEWHJQrBtkpwXNKwO0gd1JoWIAx0+6DS/HXTp0e2J8jezKhfd
2UAHOS6bje0SLO9p+/Blk4NmRQjgsYk5nunl463+IkRGU8cna7GIOnvExrT6H3FD
UsL9hL1J/+f4cSmsJoNHtQfKV0OkmQhENpFFwVMunMJPDjGEbaliKqqX05ZnJ1Tu
kDKG+QL1wJbehDNNpiwTGo+Ei8EbP8LYsSkKtMl0zVED636AiuQ259oNDGXo2f+t
FG/1WOECgYEA8OTaHbWgUvtatGBsZ5PIw1VIRG7LZESF0HvlnkZOsCFg2NWrQ99U
sL2gLC0DVi80Yijjk0Kvrp5zU010uU4CuJHzT9ZN/nlPlwTteL6kr8XIh2sTpuE6
nfx4E309d366Hh5xy82AQ+jIeQZTAaPHlFmINrncS48WTfP6lxn5f3ECgYEA33WK
OtImhr4RYRmzcsfybW7PgxxpMSnrex/omZPWEHB14Fa2J6ny3KI9qBP1x6/h6Jfe
SonD4MZ48opiNljfWmgkJMSkqalpa3jDGc8vX1uWhn8NdAuFKAn5zLZC8mZ27VUI
LXLcChjyKPKVTwRnaNe0+rq7MgsqJJ4jo2atgjcCgYEAxPr9+IlKXlC3LQQj4NaR
tliITZ0jqAv4ODD35GKteYzxup2N/GQkxplo3na4YcMb3KB+5y4CppFe0GFn7xcB
VpfSFBizkkD0ehNHdBLAbBMZFNLUMQO/gOyv64/fsVTpMDPI7dRO7DjvpTcsrQyV
6JMFtWpp30dT/85fvSs6P6ECgYB2Sp2rN7ZHW/SNR3K0T15pSeC2EmMpMHzEyAZ0
zkrilvX/lUeGRbQX0hb7k91nIRdg7owxPy6fHdHG6zTEelV6YWjIwgQ9AD6bMult
Dz2PqEdN2ZJAnRyXLni7Qry73zwTtRDIJmaPPddrj8c0ditb19ypYhJYkopzqfdJ
t8AgDwKBgCyJLYU7pjhfJwOOVJjACa8ndtg0vIr+MGoe99/2hWm7QdX5PrOjDLOr
PeopgafeF1G6chhs4Qqh4LCmDA2NeX+zWcHkjLrKUIXMwb2YPuna7WToyCCeAm8+
K5Lnssm0P/UJI3CAef/4GXb30ZJYOhsU15/XwY5c8+f6IxRIpPEN
-----END RSA PRIVATE KEY-----
18 changes: 18 additions & 0 deletions features/sandbox/puppet-envvar/keys/public_key.pkcs7.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC2TCCAcGgAwIBAgIBADANBgkqhkiG9w0BAQUFADAAMCAXDTEzMDgwMTE3MzU0
NVoYDzIwNjMwNzIwMTczNTQ1WjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA0kX0qkf4FOHXuFqlVmbgo+UDrJdneH8XnmWM+stAs0XpzEQqErelZUhE
i2x5z16RAsEw3cjd2BG78WHz1lcu3NP25BM990YQDl6e9pvmeMNA+wCK1bwD7fCW
XrAKb7xIXPJVd0ivP82ZPe71CmkFtiFr14mqNWrEpP/d2eQ4PAaCimAEbBKyRRHH
JzU6X+hOnq8GRZBwKh6Ljl31JYE2DG3KQ+ydM+r411jY2sjSykOovbeRb7FCyOPa
LRgyNjiDIJSTRlWLVJbYj6KDSoUD2+R95Owb5Z1OUL9Yn/BRIv5RyDvfBr42sp0K
R7t3pWGiHEuRYZkGDU5jKB/8bK7DRwIDAQABo1wwWjAPBgNVHRMBAf8EBTADAQH/
MB0GA1UdDgQWBBR7PyZZ/WlaSjAf6GO2GLWXO5aINDAoBgNVHSMEITAfgBR7PyZZ
/WlaSjAf6GO2GLWXO5aINKEEpAIwAIIBADANBgkqhkiG9w0BAQUFAAOCAQEAspcX
VNb156OZqPxteosI2ijeewDH0sc3ogRDZnxbXqG6Pa44QzJNTUULaX3iEfmFw4TL
MW90NU4w4rzSIBGDGHTBOKZZBa2iTVRsYHuQ7Sd1A1MKc1dDFs9+Uj/6/vQ8Fkdx
v+iei5N/XFccgto4HiohXvEZhT4NjONIFR9UL+lWChp8OVb+ifOWCKF69iUUbMPC
uD7+UkrCYoVeVXkG1Rvw4E6BAbi75P6inX0lUnzNs4B0rvFynnV1Nsdb89cxI3pL
Q0yVE8/aIP9donqjXTu0h/GmOtVQH654NCQSs1dLD+K4+8mn591Nv4uLrCiNJzTM
zGRUV6zOPlUa3ye6Dg==
-----END CERTIFICATE-----
3 changes: 3 additions & 0 deletions features/sandbox/puppet-envvar/manifests/init.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node "localhost" {
include test::run
}
8 changes: 8 additions & 0 deletions features/sandbox/puppet-envvar/puppet.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[main]
vardir=puppet-envvar
ssldir=$vardir/ssl
logdir=$vardir/logs
pidfile=$vardir/puppet.pid
hiera_config=$vardir/hiera.yaml
environmentpath=$vardir/environments
environment=local
16 changes: 16 additions & 0 deletions features/step_definitions/parser_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@
And /^I configure the keypair$/ do
Hiera::Backend::Eyaml::Options[:pkcs7_public_key] = "features/sandbox/keys/public_key.pkcs7.pem"
Hiera::Backend::Eyaml::Options[:pkcs7_private_key] = "features/sandbox/keys/private_key.pkcs7.pem"
Hiera::Backend::Eyaml::Options[:pkcs7_public_key_env_var] = nil
Hiera::Backend::Eyaml::Options[:pkcs7_private_key_env_var] = nil
ENV.delete("EYAML_PUBLIC_KEY")
ENV.delete("EYAML_PRIVATE_KEY")
end

And /^I configure the keypair using envvars$/ do
Hiera::Backend::Eyaml::Options[:pkcs7_public_key] = nil
Hiera::Backend::Eyaml::Options[:pkcs7_private_key] = nil
Hiera::Backend::Eyaml::Options[:pkcs7_public_key_env_var] = "EYAML_PUBLIC_KEY"
Hiera::Backend::Eyaml::Options[:pkcs7_private_key_env_var] = "EYAML_PRIVATE_KEY"
end

And /^I load the keypair into envvars$/ do
ENV["EYAML_PUBLIC_KEY"] = File.read "features/sandbox/keys/public_key.pkcs7.pem"
ENV["EYAML_PRIVATE_KEY"] = File.read "features/sandbox/keys/private_key.pkcs7.pem"
end

When /^I parse the content$/ do
Expand Down
42 changes: 36 additions & 6 deletions lib/hiera/backend/eyaml/encryptors/pkcs7.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ class Pkcs7 < Encryptor
:public_key => { :desc => "Path to public key",
:type => :string,
:default => "./keys/public_key.pkcs7.pem" },
:private_key_env_var => { :desc => "Name of environment variable to read private key from",
:type => :string },
:public_key_env_var => { :desc => "Name of environment variable to read public key from",
:type => :string },
:subject => { :desc => "Subject to use for certificate when creating keys",
:type => :string,
:default => "/" },
Expand All @@ -36,9 +40,18 @@ def self.encrypt plaintext
LoggingHelper::trace 'PKCS7 encrypt'

public_key = self.option :public_key
raise StandardError, "pkcs7_public_key is not defined" unless public_key
public_key_env_var = self.option :public_key_env_var
raise StandardError, "pkcs7_public_key is not defined" unless public_key or public_key_env_var

public_key_pem = File.read public_key
if public_key and public_key_env_var
warn "both public_key and public_key_env_var specified, using public_key"
end

if public_key_env_var and ENV[public_key_env_var]
public_key_pem = ENV[public_key_env_var]
else
public_key_pem = File.read public_key
end
public_key_x509 = OpenSSL::X509::Certificate.new( public_key_pem )

cipher = OpenSSL::Cipher::AES.new(256, :CBC)
Expand All @@ -51,13 +64,30 @@ def self.decrypt ciphertext

public_key = self.option :public_key
private_key = self.option :private_key
raise StandardError, "pkcs7_public_key is not defined" unless public_key
raise StandardError, "pkcs7_private_key is not defined" unless private_key
public_key_env_var = self.option :public_key_env_var
private_key_env_var = self.option :private_key_env_var
raise StandardError, "pkcs7_public_key is not defined" unless public_key or public_key_env_var
raise StandardError, "pkcs7_private_key is not defined" unless private_key or private_key_env_var

if public_key and public_key_env_var
warn "both public_key and public_key_env_var specified, using public_key"
end
if private_key and private_key_env_var
warn "both private_key and private_key_env_var specified, using private_key"
end

private_key_pem = File.read private_key
if private_key_env_var and ENV[private_key_env_var]
private_key_pem = ENV[private_key_env_var]
else
private_key_pem = File.read private_key
end
private_key_rsa = OpenSSL::PKey::RSA.new( private_key_pem )

public_key_pem = File.read public_key
if public_key_env_var and ENV[public_key_env_var]
public_key_pem = ENV[public_key_env_var]
else
public_key_pem = File.read public_key
end
public_key_x509 = OpenSSL::X509::Certificate.new( public_key_pem )

pkcs7 = OpenSSL::PKCS7.new( ciphertext )
Expand Down