diff options
author | Seth Chisamore <schisamo@opscode.com> | 2012-10-29 16:10:43 -0400 |
---|---|---|
committer | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 09:47:38 -0400 |
commit | 77093d85fd8b3a3f97e8a74ed7db5390e51d8dcb (patch) | |
tree | efd03dcba4f35ae96e70aff9bf830a94a879b6bb | |
parent | 8f2b289f56db71c3509c521cd9959298fa0ee9bb (diff) | |
download | chef-77093d85fd8b3a3f97e8a74ed7db5390e51d8dcb.tar.gz |
[OC-3564] remove Chef::Certificate
This class was only used by Chef server components and has been
succeeded by Erchef.
-rw-r--r-- | chef/lib/chef/api_client.rb | 12 | ||||
-rw-r--r-- | chef/lib/chef/certificate.rb | 161 | ||||
-rw-r--r-- | chef/spec/unit/api_client_spec.rb | 35 | ||||
-rw-r--r-- | chef/spec/unit/certificate_spec.rb | 76 |
4 files changed, 7 insertions, 277 deletions
diff --git a/chef/lib/chef/api_client.rb b/chef/lib/chef/api_client.rb index e2a0a41096..b3b51bc41d 100644 --- a/chef/lib/chef/api_client.rb +++ b/chef/lib/chef/api_client.rb @@ -21,7 +21,6 @@ require 'chef/config' require 'chef/mixin/params_validate' require 'chef/mixin/from_file' require 'chef/couchdb' -require 'chef/certificate' require 'chef/mash' require 'chef/json_compat' require 'chef/search/query' @@ -119,17 +118,6 @@ class Chef ) end - # Creates a new public/private key pair, and populates the public_key and - # private_key attributes. - # - # @return [True] - def create_keys - results = Chef::Certificate.gen_keypair(self.name) - self.public_key(results[0].to_s) - self.private_key(results[1].to_s) - true - end - # The hash representation of the object. Includes the name and public_key, # but never the private key. # diff --git a/chef/lib/chef/certificate.rb b/chef/lib/chef/certificate.rb deleted file mode 100644 index 7943589c8e..0000000000 --- a/chef/lib/chef/certificate.rb +++ /dev/null @@ -1,161 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Author:: Christopher Brown (<cb@opscode.com>) -# Copyright:: Copyright (c) 2009 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/log' -require 'chef/config' -require 'chef/api_client' -require 'openssl' -require 'fileutils' - -class Chef - class Certificate - class << self - - # Generates a new CA Certificate and Key, and writes them out to - # Chef::Config[:signing_ca_cert] and Chef::Config[:signing_ca_key]. - def generate_signing_ca - ca_cert_file = Chef::Config[:signing_ca_cert] - ca_keypair_file = Chef::Config[:signing_ca_key] - - unless File.exists?(ca_cert_file) && File.exists?(ca_keypair_file) - Chef::Log.info("Creating new signing certificate") - - [ ca_cert_file, ca_keypair_file ].each do |f| - ca_basedir = File.dirname(f) - FileUtils.mkdir_p ca_basedir - end - - keypair = OpenSSL::PKey::RSA.generate(1024) - - ca_cert = OpenSSL::X509::Certificate.new - ca_cert.version = 3 - ca_cert.serial = 1 - info = [ - ["C", Chef::Config[:signing_ca_country]], - ["ST", Chef::Config[:signing_ca_state]], - ["L", Chef::Config[:signing_ca_location]], - ["O", Chef::Config[:signing_ca_org]], - ["OU", "Certificate Service"], - ["CN", "#{Chef::Config[:signing_ca_domain]}/emailAddress=#{Chef::Config[:signing_ca_email]}"] - ] - ca_cert.subject = ca_cert.issuer = OpenSSL::X509::Name.new(info) - ca_cert.not_before = Time.now - ca_cert.not_after = Time.now + 10 * 365 * 24 * 60 * 60 # 10 years - ca_cert.public_key = keypair.public_key - - ef = OpenSSL::X509::ExtensionFactory.new - ef.subject_certificate = ca_cert - ef.issuer_certificate = ca_cert - ca_cert.extensions = [ - ef.create_extension("basicConstraints", "CA:TRUE", true), - ef.create_extension("subjectKeyIdentifier", "hash"), - ef.create_extension("keyUsage", "cRLSign,keyCertSign", true), - ] - ca_cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") - ca_cert.sign keypair, OpenSSL::Digest::SHA1.new - - File.open(ca_cert_file, "w") { |f| f.write ca_cert.to_pem } - File.open(ca_keypair_file, File::WRONLY|File::EXCL|File::CREAT, 0600) { |f| f.write keypair.to_pem } - if (Chef::Config[:signing_ca_user] && Chef::Config[:signing_ca_group]) - FileUtils.chown(Chef::Config[:signing_ca_user], Chef::Config[:signing_ca_group], ca_keypair_file) - end - end - self - end - - # Creates a new key pair, and signs them with the signing certificate - # and key generated from generate_signing_ca above. - # - # All arguments are unused, though two arguments are accepted for compatibility. - # - # returns an array of [public_key, private_key] - def gen_keypair(common_name=nil, subject_alternative_name = nil) - - Chef::Log.info("Creating new key pair for #{common_name}") - - # generate client keypair - client_keypair = OpenSSL::PKey::RSA.generate(2048) - - return client_keypair.public_key, client_keypair - end - - def gen_validation_key(name=Chef::Config[:validation_client_name], key_file=Chef::Config[:validation_key], admin=false) - # Create the validation key - api_client = Chef::ApiClient.new - api_client.name(name) - api_client.admin(admin) - - begin - # If both the couch record and file exist, don't do anything. Otherwise, - # re-generate the validation key. - Chef::ApiClient.cdb_load(name) - - # The couch document was loaded successfully if we got to here; if we - # can't also load the file on the filesystem, we'll regenerate it all. - File.open(key_file, "r") do |file| - end - rescue Chef::Exceptions::CouchDBNotFound - create_validation_key(api_client, key_file) - rescue - if $!.class.name =~ /Errno::/ - Chef::Log.error("Error opening validation key: #{$!} -- destroying and regenerating") - begin - api_client.cdb_destroy - rescue Bunny::ServerDownError => e - # create_validation_key is gonna fail anyway, so let's just bail out. - Chef::Log.fatal("Could not de-index (to rabbitmq) previous validation key - rabbitmq is down! Start rabbitmq then restart chef-server to re-generate it") - raise - end - - create_validation_key(api_client, key_file) - else - raise - end - end - end - - private - def create_validation_key(api_client, key_file) - Chef::Log.info("Creating validation key...") - - api_client.create_keys - begin - api_client.cdb_save - rescue Bunny::ServerDownError => e - # If rabbitmq is down, the client will have been saved in CouchDB, - # but not in the index. - Chef::Log.fatal("Could not index (to rabbitmq) validation key - rabbitmq is down! Start rabbitmq then restart chef-server to re-generate it") - - # re-raise so the error bubbles out and nukes chef-server - raise e - end - - key_dir = File.dirname(key_file) - FileUtils.mkdir_p(key_dir) unless File.directory?(key_dir) - File.open(key_file, File::WRONLY|File::CREAT, 0600) do |f| - f.print(api_client.private_key) - end - if (Chef::Config[:signing_ca_user] && Chef::Config[:signing_ca_group]) - FileUtils.chown(Chef::Config[:signing_ca_user], Chef::Config[:signing_ca_group], key_file) - end - end - - end - end -end diff --git a/chef/spec/unit/api_client_spec.rb b/chef/spec/unit/api_client_spec.rb index b9d9cecc01..e01243152e 100644 --- a/chef/spec/unit/api_client_spec.rb +++ b/chef/spec/unit/api_client_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -57,8 +57,8 @@ describe Chef::ApiClient do end it "should return the current admin value" do - @client.admin true - @client.admin.should == true + @client.admin true + @client.admin.should == true end it "should default to false" do @@ -82,7 +82,7 @@ describe Chef::ApiClient do it "should throw an ArgumentError if you feed it something lame" do lambda { @client.public_key Hash.new }.should raise_error(ArgumentError) - end + end end describe "private_key" do @@ -97,27 +97,6 @@ describe Chef::ApiClient do it "should throw an ArgumentError if you feed it something lame" do lambda { @client.private_key Hash.new }.should raise_error(ArgumentError) - end - end - - describe "create_keys" do - before(:each) do - Chef::Certificate.stub!(:gen_keypair).and_return(["cert", "key"]) - end - - it "should create a certificate based on the client name" do - Chef::Certificate.should_receive(:gen_keypair).with(@client.name) - @client.create_keys - end - - it "should set the private key" do - @client.create_keys - @client.private_key.should == "key" - end - - it "should set the public key" do - @client.create_keys - @client.public_key.should == "cert" end end @@ -136,7 +115,7 @@ describe Chef::ApiClient do %w{ name public_key - }.each do |t| + }.each do |t| it "should include '#{t}'" do @serial.should =~ /"#{t}":"#{@client.send(t.to_sym)}"/ end @@ -168,7 +147,7 @@ describe Chef::ApiClient do name public_key admin - }.each do |t| + }.each do |t| it "should match '#{t}'" do @deserial.send(t.to_sym).should == @client.send(t.to_sym) end diff --git a/chef/spec/unit/certificate_spec.rb b/chef/spec/unit/certificate_spec.rb deleted file mode 100644 index 4f0b07519f..0000000000 --- a/chef/spec/unit/certificate_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Copyright:: Copyright (c) 2009 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'spec_helper' - -require 'chef/certificate' -require 'ostruct' -require 'tempfile' - -class FakeFile - attr_accessor :data - - def write(arg) - @data = arg - end -end - -describe Chef::Certificate do - describe "generate_signing_ca" do - before(:each) do - Chef::Config[:signing_ca_user] = nil - Chef::Config[:signing_ca_group] = nil - FileUtils.stub!(:mkdir_p).and_return(true) - FileUtils.stub!(:chown).and_return(true) - File.stub!(:open).and_return(true) - File.stub!(:exists?).and_return(false) - @ca_cert = FakeFile.new - @ca_key = FakeFile.new - end - - it "should generate a ca certificate" do - File.should_receive(:open).with(Chef::Config[:signing_ca_cert], "w").and_yield(@ca_cert) - Chef::Certificate.generate_signing_ca - @ca_cert.data.should =~ /BEGIN CERTIFICATE/ - end - - it "should generate an RSA private key" do - File.should_receive(:open).with(Chef::Config[:signing_ca_key], File::WRONLY|File::EXCL|File::CREAT, 0600).and_yield(@ca_key) - FileUtils.should_not_receive(:chown) - Chef::Certificate.generate_signing_ca - @ca_key.data.should =~ /BEGIN RSA PRIVATE KEY/ - end - - it "should generate an RSA private key with user and group" do - Chef::Config[:signing_ca_user] = "funky" - Chef::Config[:signing_ca_group] = "fresh" - File.should_receive(:open).with(Chef::Config[:signing_ca_key], File::WRONLY|File::EXCL|File::CREAT, 0600).and_yield(@ca_key) - FileUtils.should_receive(:chown).with(Chef::Config[:signing_ca_user], Chef::Config[:signing_ca_group], Chef::Config[:signing_ca_key]) - Chef::Certificate.generate_signing_ca - @ca_key.data.should =~ /BEGIN RSA PRIVATE KEY/ - end - end - - describe "generate_keypair" do - it "should return a client certificate" do - public_key, private_key = Chef::Certificate.gen_keypair("oasis") - public_key.to_s.should =~ /(BEGIN RSA PUBLIC KEY|BEGIN PUBLIC KEY)/ - private_key.to_s.should =~ /BEGIN RSA PRIVATE KEY/ - end - end -end |