summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/puppetca187
-rw-r--r--lib/puppet/ssl/certificate_authority.rb121
-rw-r--r--lib/puppet/ssl/certificate_revocation_list.rb1
-rwxr-xr-xspec/unit/ssl/certificate_authority.rb284
-rwxr-xr-xspec/unit/ssl/certificate_revocation_list.rb4
-rwxr-xr-xtest/executables/puppetca.rb115
6 files changed, 426 insertions, 286 deletions
diff --git a/bin/puppetca b/bin/puppetca
index 3ad896b55..ef29942ae 100755
--- a/bin/puppetca
+++ b/bin/puppetca
@@ -95,7 +95,7 @@
# Licensed under the GNU Public License
require 'puppet'
-require 'puppet/sslcertificates'
+require 'puppet/ssl/certificate_authority'
require 'getoptlong'
options = [
@@ -118,22 +118,20 @@ Puppet.settings.addargs(options)
result = GetoptLong.new(*options)
-mode = nil
-all = false
-generate = nil
+modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS
-modes = [:clean, :list, :revoke, :generate, :sign, :print, :verify]
+all = false
+mode = nil
begin
result.each { |opt,arg|
case opt
+ when "--clean"
+ mode = :destroy
when "--all"
all = true
when "--debug"
Puppet::Util::Log.level = :debug
- when "--generate"
- generate = arg
- mode = :generate
when "--help"
if Puppet.features.usage?
RDoc::usage && exit
@@ -141,12 +139,6 @@ begin
puts "No help available unless you have RDoc::usage installed"
exit
end
- when "--list"
- mode = :list
- when "--revoke"
- mode = :revoke
- when "--sign"
- mode = :sign
when "--version"
puts "%s" % Puppet.version
exit
@@ -172,12 +164,12 @@ Puppet.parse_config
Puppet.genconfig
Puppet.genmanifest
+Puppet::Util::Log.newdestination :console
+
begin
- ca = Puppet::SSLCertificates::CA.new()
+ ca = Puppet::SSL::CertificateAuthority.new
rescue => detail
- if Puppet[:debug]
- puts detail.backtrace
- end
+ puts detail.backtrace if Puppet[:trace]
puts detail.to_s
exit(23)
end
@@ -187,157 +179,16 @@ unless mode
exit(12)
end
-if [:verify, :print, :generate, :clean, :revoke, :list].include?(mode)
+if all
+ hosts = :all
+else
hosts = ARGV.collect { |h| h.downcase }
end
-if [:sign, :list].include?(mode)
- waiting = ca.list
- unless waiting.length > 0 or (mode == :list and all)
- puts "No certificates to sign"
- if ARGV.length > 0
- exit(17)
- else
- exit(0)
- end
- end
-end
-
-case mode
-when :list
- waiting = ca.list
- if waiting.length > 0
- puts waiting.join("\n")
- end
- if all
- puts ca.list_signed.collect { |cert | cert.sub(/^/,"+ ") }.join("\n")
- end
-when :clean
- if hosts.empty?
- $stderr.puts "You must specify one or more hosts to clean"
- exit(24)
- end
- cleaned = false
- hosts.each do |host|
- cert = ca.getclientcert(host)[0]
- if cert.nil?
- $stderr.puts "Could not find client certificate for %s" % host
- next
- end
- ca.clean(host)
- cleaned = true
- end
- unless cleaned
- exit(27)
- end
-when :sign
- to_sign = ARGV.collect { |h| h.downcase }
- unless to_sign.length > 0 or all
- $stderr.puts(
- "You must specify to sign all certificates or you must specify hostnames"
- )
- exit(24)
- end
-
- unless all
- to_sign.each { |host|
- unless waiting.include?(host)
- $stderr.puts "No waiting request for %s" % host
- end
- }
- waiting = waiting.find_all { |host|
- to_sign.include?(host)
- }
- end
-
- waiting.each { |host|
- begin
- csr = ca.getclientcsr(host)
- rescue => detail
- $stderr.puts "Could not retrieve request for %s: %s" % [host, detail]
- end
-
- begin
- ca.sign(csr)
- $stderr.puts "Signed %s" % host
- rescue => detail
- $stderr.puts "Could not sign request for %s: %s" % [host, detail]
- end
-
- begin
- ca.removeclientcsr(host)
- rescue => detail
- $stderr.puts "Could not remove request for %s: %s" % [host, detail]
- end
- }
-when :generate
- # we need to generate a certificate for a host
- hosts.each { |host|
- puts "Generating certificate for %s" % host
- cert = Puppet::SSLCertificates::Certificate.new(
- :name => host
- )
- cert.mkcsr
- signedcert, cacert = ca.sign(cert.csr)
-
- cert.cert = signedcert
- cert.cacert = cacert
- cert.write
- }
-when :print
- hosts.each { |h|
- cert = ca.getclientcert(h)[0]
- puts cert.to_text
- }
-when :revoke
- hosts.each { |h|
- serial = nil
- if h =~ /^0x[0-9a-f]+$/
- serial = h.to_i(16)
- elsif h =~ /^[0-9]+$/
- serial = h.to_i
- else
- cert = ca.getclientcert(h)[0]
- if cert.nil?
- $stderr.puts "Could not find client certificate for %s" % h
- else
- serial = cert.serial
- end
- end
- unless serial.nil?
- ca.revoke(serial)
- puts "Revoked certificate with serial #{serial}"
- end
- }
-when :verify
- unless ssl = %x{which openssl}.chomp
- raise "Can't verify certificates without the openssl binary and could not find one"
- end
- success = true
-
- cacert = Puppet[:localcacert]
-
- hosts.each do |host|
- print "%s: " % host
- file = ca.host2certfile(host)
- unless FileTest.exist?(file)
- puts "no certificate found"
- success = false
- next
- end
-
-
- command = %{#{ssl} verify -CAfile #{cacert} #{file}}
- output = %x{#{command}}
- if $? == 0
- puts "valid"
- else
- puts output
- success = false
- end
- end
-else
- $stderr.puts "Invalid mode %s" % mode
- exit(42)
+begin
+ ca.apply(mode, :to => hosts)
+rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ puts detail.to_s
+ exit(24)
end
-
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb
index 2399c7204..8785ee5b0 100644
--- a/lib/puppet/ssl/certificate_authority.rb
+++ b/lib/puppet/ssl/certificate_authority.rb
@@ -14,8 +14,129 @@ class Puppet::SSL::CertificateAuthority
require 'puppet/ssl/inventory'
require 'puppet/ssl/certificate_revocation_list'
+ # This class is basically a hidden class that knows how to act
+ # on the CA. It's only used by the 'puppetca' executable, and its
+ # job is to provide a CLI-like interface to the CA class.
+ class Interface
+ INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify]
+
+ class InterfaceError < ArgumentError; end
+
+ attr_reader :method, :subjects
+
+ # Actually perform the work.
+ def apply(ca)
+ unless subjects or method == :list
+ raise ArgumentError, "You must provide hosts or :all when using %s" % method
+ end
+
+ begin
+ if respond_to?(method)
+ return send(method, ca)
+ end
+
+ (subjects == :all ? ca.list : subjects).each do |host|
+ ca.send(method, host)
+ end
+ rescue InterfaceError
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not call %s: %s" % [method, detail]
+ end
+ end
+
+ def generate(ca)
+ raise InterfaceError, "It makes no sense to generate all hosts; you must specify a list" if subjects == :all
+
+ subjects.each do |host|
+ ca.generate(host)
+ end
+ end
+
+ def initialize(method, subjects)
+ self.method = method
+ self.subjects = subjects
+ end
+
+ # List the hosts.
+ def list(ca)
+ unless subjects
+ puts ca.waiting?.join("\n")
+ return nil
+ end
+
+ signed = ca.list
+ requests = ca.waiting?
+
+ if subjects == :all
+ hosts = [signed, requests].flatten
+ else
+ hosts = subjects
+ end
+
+ hosts.uniq.sort.each do |host|
+ if signed.include?(host)
+ puts "+ " + host
+ else
+ puts host
+ end
+ end
+ end
+
+ # Set the method to apply.
+ def method=(method)
+ raise ArgumentError, "Invalid method %s to apply" % method unless INTERFACE_METHODS.include?(method)
+ @method = method
+ end
+
+ # Print certificate information.
+ def print(ca)
+ (subjects == :all ? ca.list : subjects).each do |host|
+ if value = ca.print(host)
+ puts value
+ else
+ Puppet.err "Could not find certificate for %s" % host
+ end
+ end
+ end
+
+ # Sign a given certificate.
+ def sign(ca)
+ list = subjects == :all ? ca.waiting? : subjects
+ raise InterfaceError, "No waiting certificate requests to sign" if list.empty?
+ list.each do |host|
+ ca.sign(host)
+ end
+ end
+
+ # Set the list of hosts we're operating on. Also supports keywords.
+ def subjects=(value)
+ unless value == :all or value.is_a?(Array)
+ raise ArgumentError, "Subjects must be an array or :all; not %s" % value
+ end
+
+ if value.is_a?(Array) and value.empty?
+ value = nil
+ end
+
+ @subjects = value
+ end
+ end
+
attr_reader :name, :host
+ # Create and run an applicator. I wanted to build an interface where you could do
+ # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible.
+ def apply(method, options)
+ unless options[:to]
+ raise ArgumentError, "You must specify the hosts to apply to; valid values are an array or the symbol :all"
+ end
+ applier = Interface.new(method, options[:to])
+
+ applier.apply(self)
+ end
+
# Retrieve (or create, if necessary) the certificate revocation list.
def crl
unless defined?(@crl)
diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb
index ca7b7db65..96b71c7a3 100644
--- a/lib/puppet/ssl/certificate_revocation_list.rb
+++ b/lib/puppet/ssl/certificate_revocation_list.rb
@@ -30,6 +30,7 @@ class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base
# CA, then write the CRL back to disk. The REASON must be one of the
# OpenSSL::OCSP::REVOKED_* reasons
def revoke(serial, cakey, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
+ Puppet.notice "Revoked certificate with serial %s" % serial
time = Time.now
# Add our revocation to the CRL.
diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb
index 50f8cec9a..5a4e2d5e1 100755
--- a/spec/unit/ssl/certificate_authority.rb
+++ b/spec/unit/ssl/certificate_authority.rb
@@ -4,6 +4,28 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate_authority'
+describe "a normal interface method", :shared => true do
+ it "should call the method on the CA for each host specified if an array was provided" do
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
+
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, %w{host1 host2})
+
+ @applier.apply(@ca)
+ end
+
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ @ca.expects(:list).returns %w{host1 host2}
+
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
+
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :all)
+
+ @applier.apply(@ca)
+ end
+end
+
describe Puppet::SSL::CertificateAuthority do
describe "when initializing" do
before do
@@ -381,7 +403,29 @@ describe Puppet::SSL::CertificateAuthority do
@cacert.stubs(:content).returns "cacertificate"
@ca = Puppet::SSL::CertificateAuthority.new
end
-
+
+ it "should have a method for acting on the SSL files" do
+ @ca.should respond_to(:apply)
+ end
+
+ describe "when applying a method to a set of hosts" do
+ it "should fail if no subjects have been specified" do
+ lambda { @ca.apply(:generate) }.should raise_error(ArgumentError)
+ end
+
+ it "should create an Interface instance with the specified method and the subjects" do
+ Puppet::SSL::CertificateAuthority::Interface.expects(:new).with(:generate, :hosts).returns(stub('applier', :apply => nil))
+ @ca.apply(:generate, :to => :hosts)
+ end
+
+ it "should apply the Interface with itself as the argument" do
+ applier = stub('applier')
+ applier.expects(:apply).with(@ca)
+ Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier
+ @ca.apply(:generate, :to => :whatever)
+ end
+ end
+
it "should be able to list waiting certificate requests" do
req1 = stub 'req1', :name => "one"
req2 = stub 'req2', :name => "two"
@@ -565,3 +609,241 @@ describe Puppet::SSL::CertificateAuthority do
end
end
end
+
+describe Puppet::SSL::CertificateAuthority::Interface do
+ before do
+ @class = Puppet::SSL::CertificateAuthority::Interface
+ end
+ describe "when initializing" do
+ it "should set its method using its settor" do
+ @class.any_instance.expects(:method=).with(:generate)
+ @class.new(:generate, :all)
+ end
+
+ it "should set its subjects using the settor" do
+ @class.any_instance.expects(:subjects=).with(:all)
+ @class.new(:generate, :all)
+ end
+ end
+
+ describe "when setting the method" do
+ it "should set the method" do
+ @class.new(:generate, :all).method.should == :generate
+ end
+
+ it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
+
+ lambda { @class.new(:thing, :all) }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "when setting the subjects" do
+ it "should set the subjects" do
+ @class.new(:generate, :all).subjects.should == :all
+ end
+
+ it "should fail if the subjects setting isn't :all or an array" do
+ lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "should have a method for triggering the application" do
+ @class.new(:generate, :all).should respond_to(:apply)
+ end
+
+ describe "when applying" do
+ before do
+ # We use a real object here, because :verify can't be stubbed, apparently.
+ @ca = Object.new
+ end
+
+ it "should raise InterfaceErrors" do
+ @applier = @class.new(:revoke, :all)
+
+ @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
+
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
+ end
+
+ it "should log non-Interface failures rather than failing" do
+ @applier = @class.new(:revoke, :all)
+
+ @ca.expects(:list).raises ArgumentError
+
+ Puppet.expects(:err)
+
+ lambda { @applier.apply(@ca) }.should_not raise_error
+ end
+
+ describe "with an empty array specified and the method is not list" do
+ it "should fail" do
+ @applier = @class.new(:sign, [])
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe ":generate" do
+ it "should fail if :all was specified" do
+ @applier = @class.new(:generate, :all)
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
+
+ it "should call :generate on the CA for each host specified" do
+ @applier = @class.new(:generate, %w{host1 host2})
+
+ @ca.expects(:generate).with("host1")
+ @ca.expects(:generate).with("host2")
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe ":verify" do
+ before { @method = :verify }
+ #it_should_behave_like "a normal interface method"
+
+ it "should call the method on the CA for each host specified if an array was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
+
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
+ end
+
+ describe ":destroy" do
+ before { @method = :destroy }
+ it_should_behave_like "a normal interface method"
+ end
+
+ describe ":revoke" do
+ before { @method = :revoke }
+ it_should_behave_like "a normal interface method"
+ end
+
+ describe ":sign" do
+ describe "and an array of names was provided" do
+ before do
+ @applier = @class.new(:sign, %w{host1 host2})
+ end
+
+ it "should sign the specified waiting certificate requests" do
+ @ca.expects(:sign).with("host1")
+ @ca.expects(:sign).with("host2")
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and :all was provided" do
+ it "should sign all waiting certificate requests" do
+ @ca.stubs(:waiting?).returns(%w{cert1 cert2})
+
+ @ca.expects(:sign).with("cert1")
+ @ca.expects(:sign).with("cert2")
+
+ @applier = @class.new(:sign, :all)
+ @applier.apply(@ca)
+ end
+
+ it "should fail if there are no waiting certificate requests" do
+ @ca.stubs(:waiting?).returns([])
+
+ @applier = @class.new(:sign, :all)
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
+ end
+ end
+ end
+
+ describe ":list" do
+ describe "and an empty array was provided" do
+ it "should print a string containing all certificate requests" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+
+ @applier = @class.new(:list, [])
+
+ @applier.expects(:puts).with "host1\nhost2"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and :all was provided" do
+ it "should print a string containing all certificate requests and certificates" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+
+ @applier = @class.new(:list, :all)
+
+ @applier.expects(:puts).with "host1"
+ @applier.expects(:puts).with "host2"
+ @applier.expects(:puts).with "+ host3"
+ @applier.expects(:puts).with "+ host4"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and an array of names was provided" do
+ it "should print a string of all named hosts that have a waiting request" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+
+ @applier = @class.new(:list, %w{host1 host2 host3 host4})
+
+ @applier.expects(:puts).with "host1"
+ @applier.expects(:puts).with "host2"
+ @applier.expects(:puts).with "+ host3"
+ @applier.expects(:puts).with "+ host4"
+
+ @applier.apply(@ca)
+ end
+ end
+ end
+
+ describe ":print" do
+ describe "and :all was provided" do
+ it "should print all certificates" do
+ @ca.expects(:list).returns %w{host1 host2}
+
+ @applier = @class.new(:print, :all)
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and an array of names was provided" do
+ it "should print each named certificate if found" do
+ @applier = @class.new(:print, %w{host1 host2})
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
+
+ @applier.apply(@ca)
+ end
+
+ it "should log any named but not found certificates" do
+ @applier = @class.new(:print, %w{host1 host2})
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns nil
+ Puppet.expects(:err).with { |msg| msg.include?("host2") }
+
+ @applier.apply(@ca)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/unit/ssl/certificate_revocation_list.rb b/spec/unit/ssl/certificate_revocation_list.rb
index 042a12e15..2efdd187a 100755
--- a/spec/unit/ssl/certificate_revocation_list.rb
+++ b/spec/unit/ssl/certificate_revocation_list.rb
@@ -113,7 +113,7 @@ describe Puppet::SSL::CertificateRevocationList do
it "should mark the CRL as updated" do
time = Time.now
- Time.expects(:now).returns time
+ Time.stubs(:now).returns time
@crl.content.expects(:last_update=).with(time)
@@ -122,7 +122,7 @@ describe Puppet::SSL::CertificateRevocationList do
it "should mark the CRL valid for five years" do
time = Time.now
- Time.expects(:now).returns time
+ Time.stubs(:now).returns time
@crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60))
diff --git a/test/executables/puppetca.rb b/test/executables/puppetca.rb
deleted file mode 100755
index cdc827079..000000000
--- a/test/executables/puppetca.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/puppettest'
-
-require 'puppettest'
-require 'mocha'
-
-class TestPuppetCA < Test::Unit::TestCase
- include PuppetTest::ExeTest
-
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- end
-
- def gen_cert(ca, host)
- runca("-g #{host}")
- ca.getclientcert(host)[0]
- end
-
- def mkca
- Puppet::Network::Handler.ca.new()
- end
-
- def mkcert(hostname)
- cert = nil
- assert_nothing_raised {
- cert = Puppet::SSLCertificates::Certificate.new(
- :name => hostname
- )
- cert.mkcsr
- }
-
- return cert
- end
-
- def runca(args)
- debug = ""
- if Puppet[:debug]
- debug = "-d "
- end
- return %x{puppetca --user=#{Puppet[:user]} #{debug} --group=#{Puppet[:group]} --confdir=#{Puppet[:confdir]} --vardir=#{Puppet[:vardir]} #{args} 2>&1}
- end
-
- def test_signing
- ca = mkca
- Puppet[:autosign] = false
-
- %w{host.test.com Other.Testing.Com}.each do |host|
- cert = mkcert(host)
- resp = nil
- assert_nothing_raised {
- # We need to use a fake name so it doesn't think the cert is from
- # itself. Strangely, getcert stores the csr, because it's a server-side
- # method, not client.
- resp = ca.getcert(cert.csr.to_pem, host, "127.0.0.1")
- }
- assert_equal(["",""], resp)
-
- output = nil
- assert_nothing_raised {
- output = runca("--list").chomp.split("\n").reject { |line| line =~ /warning:/ } # stupid ssl.rb
- }
- assert_equal($?,0)
- assert_equal([host.downcase], output)
- assert_nothing_raised {
- output = runca("--sign -a").chomp.split("\n")
- }
-
-
- assert_equal($?,0)
- assert_equal(["Signed #{host.downcase}"], output)
-
-
- signedfile = ca.ca.host2certfile(host)
- assert(FileTest.exists?(signedfile), "cert does not exist")
- assert(! FileTest.executable?(signedfile), "cert is executable")
-
- uid = Puppet::Util.uid(Puppet[:user])
-
- if Puppet::Util::SUIDManager.uid == 0
- assert(! FileTest.owned?(signedfile), "cert is owned by root")
- end
- assert_nothing_raised {
- output = runca("--list").chomp.split("\n")
- }
- assert_equal($?,0)
- assert_equal(["No certificates to sign"], output)
- end
- end
-
- # This method takes a long time to run because of all of the external
- # executable calls.
- def test_revocation
- ca = Puppet::SSLCertificates::CA.new()
- host1 = gen_cert(ca, "host1.example.com")
- host2 = gen_cert(ca, "host2.example.com")
- host3 = gen_cert(ca, "host3.example.com")
- runca("-r host1.example.com")
- runca("-r #{host2.serial}")
- runca("-r 0x#{host3.serial.to_s(16)}")
- runca("-r 0xff")
-
- # Recreate CA to force reading of CRL
- ca = Puppet::SSLCertificates::CA.new()
- crl = ca.crl
- revoked = crl.revoked.collect { |r| r.serial }
- exp = [host1.serial, host2.serial, host3.serial, 255]
- assert_equal(exp, revoked)
- end
-
- def test_case_insensitive_sign
- end
-end
-