summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-04-19 14:50:18 -0500
committerLuke Kanies <luke@madstop.com>2008-04-19 14:50:18 -0500
commit809fc77bc767fb3acabc83d55183686200b1e384 (patch)
tree26f0fa4954f693168f7f366c5ea8653531de3ac6
parent16056a24c65a7c6485b65f15700ff3971781031b (diff)
downloadpuppet-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.rb140
-rw-r--r--lib/puppet/ssl/certificate_revocation_list.rb4
-rw-r--r--lib/puppet/ssl/host.rb23
-rw-r--r--lib/puppet/ssl/inventory.rb11
-rwxr-xr-xspec/integration/ssl/certificate_authority.rb16
-rwxr-xr-xspec/unit/ssl/certificate_authority.rb229
-rwxr-xr-xspec/unit/ssl/certificate_revocation_list.rb10
-rwxr-xr-xspec/unit/ssl/host.rb27
-rwxr-xr-xspec/unit/ssl/inventory.rb23
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