diff options
| author | Luke Kanies <luke@madstop.com> | 2008-04-19 14:50:18 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2008-04-19 14:50:18 -0500 |
| commit | 809fc77bc767fb3acabc83d55183686200b1e384 (patch) | |
| tree | 26f0fa4954f693168f7f366c5ea8653531de3ac6 | |
| parent | 16056a24c65a7c6485b65f15700ff3971781031b (diff) | |
| download | puppet-809fc77bc767fb3acabc83d55183686200b1e384.tar.gz puppet-809fc77bc767fb3acabc83d55183686200b1e384.tar.xz puppet-809fc77bc767fb3acabc83d55183686200b1e384.zip | |
Finishing the interface between the CA and the CRL.
Certificate revocation now works, the CA knows how
to generate the CRL, and the SSL::Host class knows
how to configure the CRL class for indirection.
| -rw-r--r-- | lib/puppet/ssl/certificate_authority.rb | 140 | ||||
| -rw-r--r-- | lib/puppet/ssl/certificate_revocation_list.rb | 4 | ||||
| -rw-r--r-- | lib/puppet/ssl/host.rb | 23 | ||||
| -rw-r--r-- | lib/puppet/ssl/inventory.rb | 11 | ||||
| -rwxr-xr-x | spec/integration/ssl/certificate_authority.rb | 16 | ||||
| -rwxr-xr-x | spec/unit/ssl/certificate_authority.rb | 229 | ||||
| -rwxr-xr-x | spec/unit/ssl/certificate_revocation_list.rb | 10 | ||||
| -rwxr-xr-x | spec/unit/ssl/host.rb | 27 | ||||
| -rwxr-xr-x | spec/unit/ssl/inventory.rb | 23 |
9 files changed, 405 insertions, 78 deletions
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 7b30e08f7..62e799ef6 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -12,8 +12,41 @@ require 'puppet/ssl/certificate_request' class Puppet::SSL::CertificateAuthority require 'puppet/ssl/certificate_factory' require 'puppet/ssl/inventory' + require 'puppet/ssl/certificate_revocation_list' - attr_reader :name, :host, :inventory + attr_reader :name, :host + + # Retrieve (or create, if necessary) the certificate revocation list. + def crl + unless defined?(@crl) + # The crl is disabled. + if ["false", false].include?(Puppet[:cacrl]) + @crl = nil + return @crl + end + + unless @crl = Puppet::SSL::CertificateRevocationList.find("whatever") + @crl = Puppet::SSL::CertificateRevocationList.new("whatever") + @crl.generate(host.certificate.content) + end + end + @crl + end + + # Delegate this to our Host class. + def destroy(name) + Puppet::SSL::Host.destroy(name) + end + + # Generate a new certificate. + def generate(name) + raise ArgumentError, "A Certificate already exists for %s" % name if Puppet::SSL::Certificate.find(name) + host = Puppet::SSL::Host.new(name) + + host.generate_certificate_request + + sign(name) + end # Generate our CA certificate. def generate_ca_certificate @@ -37,41 +70,14 @@ class Puppet::SSL::CertificateAuthority @name = Puppet[:certname] @host = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name) - - @inventory = Puppet::SSL::Inventory.new end - # Sign a given certificate request. - def sign(hostname, cert_type = :server, self_signing_csr = nil) - # This is a self-signed certificate - if self_signing_csr - csr = self_signing_csr - issuer = csr.content - else - generate_ca_certificate unless host.certificate - - unless csr = Puppet::SSL::CertificateRequest.find(hostname) - raise ArgumentError, "Could not find certificate request for %s" % hostname - end - issuer = host.certificate.content + # Retrieve (or create, if necessary) our inventory manager. + def inventory + unless defined?(@inventory) + @inventory = Puppet::SSL::Inventory.new end - - cert = Puppet::SSL::Certificate.new(hostname) - cert.content = Puppet::SSL::CertificateFactory.new(cert_type, csr.content, issuer, next_serial).result - cert.content.sign(host.key.content, OpenSSL::Digest::SHA1.new) - - Puppet.notice "Signed certificate request for %s" % hostname - - # Add the cert to the inventory before we save it, since - # otherwise we could end up with it being duplicated, if - # this is the first time we build the inventory file. - inventory.add(cert) - - # Save the now-signed cert. This should get routed correctly depending - # on the certificate type. - cert.save - - return cert + @inventory end # Generate a new password for the CA. @@ -112,4 +118,72 @@ class Puppet::SSL::CertificateAuthority def password? FileTest.exist? Puppet[:capass] end + + # Revoke a given certificate. + def revoke(name) + raise ArgumentError, "Cannot revoke certificates when the CRL is disabled" unless crl + + if cert = Puppet::SSL::Certificate.find(name) + serial = cert.content.serial + elsif ! serial = inventory.serial(name) + raise ArgumentError, "Could not find a serial number for %s" % name + end + crl.revoke(serial, host.key.content) + end + + # Sign a given certificate request. + def sign(hostname, cert_type = :server, self_signing_csr = nil) + # This is a self-signed certificate + if self_signing_csr + csr = self_signing_csr + issuer = csr.content + else + generate_ca_certificate unless host.certificate + + unless csr = Puppet::SSL::CertificateRequest.find(hostname) + raise ArgumentError, "Could not find certificate request for %s" % hostname + end + issuer = host.certificate.content + end + + cert = Puppet::SSL::Certificate.new(hostname) + cert.content = Puppet::SSL::CertificateFactory.new(cert_type, csr.content, issuer, next_serial).result + cert.content.sign(host.key.content, OpenSSL::Digest::SHA1.new) + + Puppet.notice "Signed certificate request for %s" % hostname + + # Add the cert to the inventory before we save it, since + # otherwise we could end up with it being duplicated, if + # this is the first time we build the inventory file. + inventory.add(cert) + + # Save the now-signed cert. This should get routed correctly depending + # on the certificate type. + cert.save + + # And remove the CSR if this wasn't self signed. + Puppet::SSL::CertificateRequest.destroy(csr.name) unless self_signing_csr + + return cert + end + + # Verify a given host's certificate. + def verify(name) + unless cert = Puppet::SSL::Certificate.find(name) + raise ArgumentError, "Could not find a certificate for %s" % name + end + store = OpenSSL::X509::Store.new + store.add_file Puppet[:cacert] + store.add_crl Puppet[:cacrl] if self.crl + store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT + + unless store.verify(cert.content) + raise "Certificate for %s failed verification" % name + end + end + + # List the waiting certificate requests. + def waiting? + Puppet::SSL::CertificateRequest.search("*").collect { |r| r.name } + end end diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb index aab1ec5ec..ca7b7db65 100644 --- a/lib/puppet/ssl/certificate_revocation_list.rb +++ b/lib/puppet/ssl/certificate_revocation_list.rb @@ -18,7 +18,9 @@ class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base @content end - def initialize + # The name doesn't actually matter; there's only one CRL. + # We just need the name so our Indirector stuff all works more easily. + def initialize(fakename) raise Puppet::Error, "Cannot manage the CRL when :cacrl is set to false" if [false, "false"].include?(Puppet[:cacrl]) @name = "crl" diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb index 9c7ca767e..c1dac2050 100644 --- a/lib/puppet/ssl/host.rb +++ b/lib/puppet/ssl/host.rb @@ -2,6 +2,7 @@ require 'puppet/ssl' require 'puppet/ssl/key' require 'puppet/ssl/certificate' require 'puppet/ssl/certificate_request' +require 'puppet/ssl/certificate_revocation_list' require 'puppet/util/constant_inflector' # The class that manages all aspects of our SSL certificates -- @@ -9,8 +10,9 @@ require 'puppet/util/constant_inflector' class Puppet::SSL::Host # Yay, ruby's strange constant lookups. Key = Puppet::SSL::Key - CertificateRequest = Puppet::SSL::CertificateRequest Certificate = Puppet::SSL::Certificate + CertificateRequest = Puppet::SSL::CertificateRequest + CertificateRevocationList = Puppet::SSL::CertificateRevocationList extend Puppet::Util::ConstantInflector @@ -35,9 +37,10 @@ class Puppet::SSL::Host def self.configure_indirection(terminus, cache = nil) Certificate.terminus_class = terminus CertificateRequest.terminus_class = terminus + CertificateRevocationList.terminus_class = terminus if cache - # This is weird; we don't actually cache our keys, we + # This is weird; we don't actually cache our keys or CRL, we # use what would otherwise be the cache as our normal # terminus. Key.terminus_class = cache @@ -48,12 +51,13 @@ class Puppet::SSL::Host if cache Certificate.cache_class = cache CertificateRequest.cache_class = cache + CertificateRevocationList.cache_class = cache end end # Specify how we expect to interact with our certificate authority. def self.ca_location=(mode) - raise ArgumentError, "CA Mode can only be :local, :remote, or :none" unless [:local, :remote, :only, :none].include?(mode) + raise ArgumentError, "CA Mode can only be :local, :remote, or :none" unless [:local, :remote, :none].include?(mode) @ca_mode = mode @@ -64,25 +68,12 @@ class Puppet::SSL::Host configure_indirection :ca_file, :file when :remote: configure_indirection :rest, :file - when :only: - # We are the CA, so we just interact with CA stuff. - configure_indirection :ca_file when :none: # We have no CA, so we just look in the local file store. configure_indirection :file end end - # Set the cache class for the files we manage. - def self.cache_class=(value) - [Key, CertificateRequest, Certificate].each { |klass| klass.terminus_class = value } - end - - # Set the terminus class for the files we manage. - def self.terminus_class=(value) - [Key, CertificateRequest, Certificate].each { |klass| klass.terminus_class = value } - end - # Search for more than one host, optionally only specifying # an interest in hosts with a given file type. # This just allows our non-indirected class to have one of diff --git a/lib/puppet/ssl/inventory.rb b/lib/puppet/ssl/inventory.rb index 3b32b6d7b..38cbf46e9 100644 --- a/lib/puppet/ssl/inventory.rb +++ b/lib/puppet/ssl/inventory.rb @@ -38,4 +38,15 @@ class Puppet::SSL::Inventory Puppet::SSL::Certificate.search("*").each { |cert| add(cert) } end + + # Find the serial number for a given certificate. + def serial(name) + return nil unless FileTest.exist?(@path) + + File.readlines(@path).each do |line| + next unless line =~ /^(\S+).+\/CN=#{name}$/ + + return Integer($1) + end + end end diff --git a/spec/integration/ssl/certificate_authority.rb b/spec/integration/ssl/certificate_authority.rb index 9d331ac91..d70800737 100755 --- a/spec/integration/ssl/certificate_authority.rb +++ b/spec/integration/ssl/certificate_authority.rb @@ -18,7 +18,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings[:confdir] = @dir Puppet.settings[:vardir] = @dir - Puppet::SSL::Host.ca_location = :only + Puppet::SSL::Host.ca_location = :local @ca = Puppet::SSL::CertificateAuthority.new end @@ -44,6 +44,20 @@ describe Puppet::SSL::CertificateAuthority do @ca.host.certificate.should be_instance_of(Puppet::SSL::Certificate) end + it "should be able to generate a new host certificate" do + @ca.generate("newhost") + + Puppet::SSL::Certificate.find("newhost").should be_instance_of(Puppet::SSL::Certificate) + end + + it "should be able to revoke a host certificate" do + @ca.generate("newhost") + + @ca.revoke("newhost") + + lambda { @ca.verify("newhost") }.should raise_error + end + describe "when signing certificates" do before do @host = Puppet::SSL::Host.new("luke.madstop.com") diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb index c102d05fe..a4d8568fe 100755 --- a/spec/unit/ssl/certificate_authority.rb +++ b/spec/unit/ssl/certificate_authority.rb @@ -40,6 +40,62 @@ describe Puppet::SSL::CertificateAuthority do end end + describe "when retrieving the certificate revocation list" do + before do + Puppet.settings.stubs(:use) + Puppet.settings.stubs(:value).returns "whatever" + + Puppet::SSL::CertificateAuthority.any_instance.stubs(:generate_ca_certificate) + @ca = Puppet::SSL::CertificateAuthority.new + end + + describe "and the CRL is disabled" do + it "should return nil when the :cacrl is false" do + Puppet.settings.stubs(:value).with(:cacrl).returns false + + Puppet::SSL::CertificateRevocationList.expects(:new).never + + @ca.crl.should be_nil + end + + it "should return nil when the :cacrl is 'false'" do + Puppet.settings.stubs(:value).with(:cacrl).returns 'false' + + Puppet::SSL::CertificateRevocationList.expects(:new).never + + @ca.crl.should be_nil + end + end + + describe "and the CRL is enabled" do + before do + Puppet.settings.stubs(:value).with(:cacrl).returns "/my/crl" + + cert = stub("certificate", :content => "real_cert") + @host = stub 'host', :certificate => cert, :name => "hostname" + + @ca.stubs(:host).returns @host + end + + it "should return any found CRL instance" do + crl = mock 'crl' + Puppet::SSL::CertificateRevocationList.expects(:find).returns crl + @ca.crl.should equal(crl) + end + + it "should create and generate a new CRL instance of no CRL can be found" do + crl = mock 'crl' + Puppet::SSL::CertificateRevocationList.expects(:find).returns nil + + Puppet::SSL::CertificateRevocationList.expects(:new).returns crl + + crl.expects(:generate).with(@ca.host.certificate.content) + + @ca.crl.should equal(crl) + end + end + end + describe "when generating a self-signed CA certificate" do before do Puppet.settings.stubs(:use) @@ -121,11 +177,13 @@ describe Puppet::SSL::CertificateAuthority do @factory = stub 'factory', :result => "my real cert" Puppet::SSL::CertificateFactory.stubs(:new).returns @factory - @request = stub 'request', :content => "myrequest" + @request = stub 'request', :content => "myrequest", :name => @name # And the inventory @inventory = stub 'inventory', :add => nil @ca.stubs(:inventory).returns @inventory + + Puppet::SSL::CertificateRequest.stubs(:destroy) end describe "and calculating the next certificate serial number" do @@ -275,6 +333,12 @@ describe Puppet::SSL::CertificateAuthority do @cert.expects(:save) @ca.sign(@name) end + + it "should remove the host's certificate request" do + Puppet::SSL::CertificateRequest.expects(:destroy).with(@name) + + @ca.sign(@name) + end end it "should create a certificate instance with the content set to the newly signed x509 certificate" do @@ -315,16 +379,169 @@ describe Puppet::SSL::CertificateAuthority do Puppet::SSL::CertificateAuthority.any_instance.stubs(:key).returns @key @cacert = mock 'certificate' @cacert.stubs(:content).returns "cacertificate" - Puppet::SSL::CertificateAuthority.any_instance.stubs(:certificate).returns @cacert @ca = Puppet::SSL::CertificateAuthority.new end + + it "should be able to list waiting certificate requests" do + req1 = stub 'req1', :name => "one" + req2 = stub 'req2', :name => "two" + Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2] + + @ca.waiting?.should == %w{one two} + end + + it "should delegate removing hosts to the Host class" do + Puppet::SSL::Host.expects(:destroy).with("myhost") + + @ca.destroy("myhost") + end + + it "should be able to verify certificates" do + @ca.should respond_to(:verify) + end + + describe "and verifying certificates" do + before do + @store = stub 'store', :verify => true, :add_file => nil, :purpose= => nil, :add_crl => true + + OpenSSL::X509::Store.stubs(:new).returns @store + + Puppet.settings.stubs(:value).returns "crtstuff" + + @cert = stub 'cert', :content => "mycert" + Puppet::SSL::Certificate.stubs(:find).returns @cert + + @crl = mock('crl') + + @ca.stubs(:crl).returns @crl + end + + it "should fail if the host's certificate cannot be found" do + Puppet::SSL::Certificate.expects(:find).with("me").returns(nil) + + lambda { @ca.verify("me") }.should raise_error(ArgumentError) + end + + it "should create an SSL Store to verify" do + OpenSSL::X509::Store.expects(:new).returns @store + + @ca.verify("me") + end + + it "should add the CA Certificate to the store" do + Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" + @store.expects(:add_file).with "/ca/cert" + + @ca.verify("me") + end + + it "should add the CRL to the store if the crl is enabled" do + @store.expects(:add_crl).with @crl + + @ca.verify("me") + end + + it "should set the store purpose to OpenSSL::X509::PURPOSE_SSL_CLIENT" do + Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" + @store.expects(:add_file).with "/ca/cert" + + @ca.verify("me") + end + + it "should use the store to verify the certificate" do + @cert.expects(:content).returns "mycert" + + @store.expects(:verify).with("mycert").returns true + + @ca.verify("me") + end + + it "should fail if the verification returns false" do + @cert.expects(:content).returns "mycert" + + @store.expects(:verify).with("mycert").returns false + + lambda { @ca.verify("me") }.should raise_error + end + end + + describe "and revoking certificates" do + before do + @crl = mock 'crl' + @ca.stubs(:crl).returns @crl + end + + it "should fail if the certificate revocation list is disabled" do + @ca.stubs(:crl).returns false + + lambda { @ca.revoke('whatever') }.should raise_error(ArgumentError) + + end + + it "should delegate the revocation to its CRL" do + @ca.crl.expects(:revoke) + + @ca.revoke('host') + end + + it "should get the serial number from the local certificate if it exists" do + real_cert = stub 'real_cert', :serial => 15 + cert = stub 'cert', :content => real_cert + Puppet::SSL::Certificate.expects(:find).with("host").returns cert + + @ca.crl.expects(:revoke).with { |serial, key| serial == 15 } + + @ca.revoke('host') + end + + it "should get the serial number from inventory if no local certificate exists" do + real_cert = stub 'real_cert', :serial => 15 + cert = stub 'cert', :content => real_cert + Puppet::SSL::Certificate.expects(:find).with("host").returns nil + + @ca.inventory.expects(:serial).with("host").returns 16 + + @ca.crl.expects(:revoke).with { |serial, key| serial == 16 } + @ca.revoke('host') + end + end - describe "when revoking certificates" do - it "should fail if the certificate revocation list is disabled" + it "should be able to generate a complete new SSL host" do + @ca.should respond_to(:generate) + end - it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the reason" + describe "and generating certificates" do + before do + @host = stub 'host', :generate_certificate_request => nil + Puppet::SSL::Host.stubs(:new).returns @host + Puppet::SSL::Certificate.stubs(:find).returns nil - it "should require a serial number" + @ca.stubs(:sign) + end + + it "should fail if a certificate already exists for the host" do + Puppet::SSL::Certificate.expects(:find).with("him").returns "something" + + lambda { @ca.generate("him") }.should raise_error(ArgumentError) + end + + it "should create a new Host instance with the correct name" do + Puppet::SSL::Host.expects(:new).with("him").returns @host + + @ca.generate("him") + end + + it "should use the Host to generate the certificate request" do + @host.expects :generate_certificate_request + + @ca.generate("him") + end + + it "should sign the generated request" do + @ca.expects(:sign).with("him") + + @ca.generate("him") + end end end end diff --git a/spec/unit/ssl/certificate_revocation_list.rb b/spec/unit/ssl/certificate_revocation_list.rb index 3513607d9..042a12e15 100755 --- a/spec/unit/ssl/certificate_revocation_list.rb +++ b/spec/unit/ssl/certificate_revocation_list.rb @@ -19,7 +19,7 @@ describe Puppet::SSL::CertificateRevocationList do before do @class.any_instance.stubs(:read_or_generate) - @crl = @class.new + @crl = @class.new("whatever") end it "should always use 'crl' for its name" do @@ -34,12 +34,12 @@ describe Puppet::SSL::CertificateRevocationList do describe "when initializing" do it "should fail if :cacrl is set to false" do Puppet.settings.expects(:value).with(:cacrl).returns false - lambda { @class.new }.should raise_error(Puppet::Error) + lambda { @class.new("crl") }.should raise_error(Puppet::Error) end it "should fail if :cacrl is set to the string 'false'" do Puppet.settings.expects(:value).with(:cacrl).returns "false" - lambda { @class.new }.should raise_error(Puppet::Error) + lambda { @class.new("crl") }.should raise_error(Puppet::Error) end end @@ -52,7 +52,7 @@ describe Puppet::SSL::CertificateRevocationList do @class.any_instance.stubs(:read_or_generate) - @crl = @class.new + @crl = @class.new("crl") end it "should set its issuer to the subject of the passed certificate" do @@ -89,7 +89,7 @@ describe Puppet::SSL::CertificateRevocationList do before do @class.wrapped_class.any_instance.stubs(:issuer=) - @crl = @class.new + @crl = @class.new("crl") @crl.generate(@cert) @crl.content.stubs(:sign) diff --git a/spec/unit/ssl/host.rb b/spec/unit/ssl/host.rb index 743d1dcef..d3756a016 100755 --- a/spec/unit/ssl/host.rb +++ b/spec/unit/ssl/host.rb @@ -43,7 +43,7 @@ describe Puppet::SSL::Host do describe "when specifying the CA location" do before do - [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest].each do |klass| + [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass| klass.stubs(:terminus_class=) klass.stubs(:cache_class=) end @@ -66,9 +66,10 @@ describe Puppet::SSL::Host do end describe "as 'local'" do - it "should set the cache class for Certificate and CertificateRequest as :file" do + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Certificate.expects(:cache_class=).with :file Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file Puppet::SSL::Host.ca_location = :local end @@ -79,18 +80,20 @@ describe Puppet::SSL::Host do Puppet::SSL::Host.ca_location = :local end - it "should set the terminus class for Certificate and CertificateRequest as :ca_file" do + it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca_file" do Puppet::SSL::Certificate.expects(:terminus_class=).with :ca_file Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca_file + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca_file Puppet::SSL::Host.ca_location = :local end end describe "as 'remote'" do - it "should set the cache class for Certificate and CertificateRequest as :file" do + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Certificate.expects(:cache_class=).with :file Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file Puppet::SSL::Host.ca_location = :remote end @@ -101,29 +104,21 @@ describe Puppet::SSL::Host do Puppet::SSL::Host.ca_location = :remote end - it "should set the terminus class for Certificate and CertificateRequest as :rest" do + it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do Puppet::SSL::Certificate.expects(:terminus_class=).with :rest Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest Puppet::SSL::Host.ca_location = :remote end end - describe "as 'only'" do - it "should set the terminus class for Key, Certificate, and CertificateRequest as :ca_file" do - Puppet::SSL::Key.expects(:terminus_class=).with :ca_file - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca_file - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca_file - - Puppet::SSL::Host.ca_location = :only - end - end - describe "as 'none'" do - it "should set the terminus class for Key, Certificate, and CertificateRequest as :file" do + it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Key.expects(:terminus_class=).with :file Puppet::SSL::Certificate.expects(:terminus_class=).with :file Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file Puppet::SSL::Host.ca_location = :none end diff --git a/spec/unit/ssl/inventory.rb b/spec/unit/ssl/inventory.rb index 10eb42d95..bf1dbfb48 100755 --- a/spec/unit/ssl/inventory.rb +++ b/spec/unit/ssl/inventory.rb @@ -153,5 +153,28 @@ describe Puppet::SSL::Inventory do @inventory.format(@cert).should =~ /^0x.+mycert$/ end end + + it "should be able to find a given host's serial number" do + @inventory.should respond_to(:serial) + end + + describe "and finding a serial number" do + it "should return nil if the inventory file is missing" do + FileTest.expects(:exist?).with("/inven/tory").returns false + @inventory.serial(:whatever).should be_nil + end + + it "should return the serial number from the line matching the provided name" do + File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] + + @inventory.serial("me").should == 15 + end + + it "should return the number as an integer" do + File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] + + @inventory.serial("me").should == 15 + end + end end end |
