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

add checking and error handling for encrypted keys and pass_phrases #10

Closed
wants to merge 1 commit into from
Closed
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 lib/chef/provider/private_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ def load_current_resource
if new_key
begin
key, key_format = Cheffish::KeyFormatter.decode(new_key, new_resource.pass_phrase, new_path)

if key
@current_private_key = key
resource.format key_format[:format]
Expand All @@ -205,7 +206,8 @@ def load_current_resource
resource.cipher key_format[:cipher]
end
rescue
# If there's an error reading, we assume format and type are wrong and don't futz with them
# promote a raised error up the stack
raise $!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases where we don't want to raise an error here--specifically, when regenerate_if_different is true, the resource should regenerate the key if it can't read the format (since it's clearly different). I have a patch for this part of the issue going in and will link it momentarily, but please don't let that stop you from the excellent error message goodness you have going on here!

end
else
resource.action :delete
Expand Down
28 changes: 23 additions & 5 deletions lib/cheffish/key_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ class KeyFormatter
# Returns nil or key, format
def self.decode(str, pass_phrase=nil, filename='')
key_format = {}
key_format[:format] = format_of(str)
key_format[:format], key_format[:encrypted] = format_of(str)

# make sure we have a pass phrase for an encrypted key
if key_format[:encrypted] && pass_phrase.nil?
raise "You are attempting to use an encrypted key but did not provide a password"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this :)

end

case key_format[:format]
when :openssh
Expand Down Expand Up @@ -83,13 +88,26 @@ def self.decode_openssh_key(str, filename='')
end

def self.format_of(key_contents)
if key_contents.start_with?('-----BEGIN ')
:pem

format = nil
encrypted = nil

if key_contents.include?('ENCRYPTED')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more specific way to test for this? The key_contents could contain the phrase ENCRYPTED in the key itself. Maybe make sure it's on the first line?

encrypted = true
end

if key_contents.start_with?('-----BEGIN RSA PRIVATE KEY')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there are multiple types of BEGIN line out there--BEGIN PRIVATE KEY is one of them--and that's why this was coded the way it was.

format = :pem
elsif key_contents.start_with?('ssh-rsa ') || key_contents.start_with?('ssh-dss ')
:openssh
format = :openssh
# TODO figure out der format
# else
# :der
else
:der
format = :unknown
end

[format, encrypted]
end

def self.type_of(key)
Expand Down
2 changes: 1 addition & 1 deletion lib/cheffish/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Cheffish
VERSION = '0.6.2'
VERSION = '0.6.3'
end