diff options
| author | Luke Kanies <luke@madstop.com> | 2008-04-17 14:47:27 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2008-04-17 14:47:27 -0500 |
| commit | daa8cd57b9f61c40c1b4e6954533f197ee5a2f1d (patch) | |
| tree | 995e10e5727ee9bccc54b209cac834a223f69338 /spec/unit/ssl | |
| parent | 7d2c05e86eb14bc7600dcf1d61ba447cd9b4cab8 (diff) | |
| download | puppet-daa8cd57b9f61c40c1b4e6954533f197ee5a2f1d.tar.gz puppet-daa8cd57b9f61c40c1b4e6954533f197ee5a2f1d.tar.xz puppet-daa8cd57b9f61c40c1b4e6954533f197ee5a2f1d.zip | |
Changing all of the SSL terminus classes to treat CA files specially.
This is a kind of weird design situation. For instance, we've got a
collection of certificates in the :certdir, but then there's a special
CA certificate off by itself. Rather than build a whole separate
infrastructure for managing those separate files (cert and key, at least),
I decided to add special support for specifying where to find the CA-specific
bits, and then code for handling them when necessary.
This requires that we have a standard way of knowing whether we should be
managing the CA bits or normal host files. The Puppet::SSL::Host class now has
a 'ca_name' method that returns the string we're using for the CA name; this
name is currently 'ca'. We have to use a name, because the name is the only
thing that all methods have access to (e.g., when trying to 'find' the right
cert, we only have the name available).
What this means is that if you want access to the CA key or cert, then create
a Puppet::SSL::Host instance with the name 'ca'.
You'll still get the CA cert created with the host's :certname; it will just
be stored in a different location.
Diffstat (limited to 'spec/unit/ssl')
| -rwxr-xr-x | spec/unit/ssl/certificate_revocation_list.rb | 145 | ||||
| -rwxr-xr-x | spec/unit/ssl/host.rb | 17 |
2 files changed, 74 insertions, 88 deletions
diff --git a/spec/unit/ssl/certificate_revocation_list.rb b/spec/unit/ssl/certificate_revocation_list.rb index 0281b0947..01c197b25 100755 --- a/spec/unit/ssl/certificate_revocation_list.rb +++ b/spec/unit/ssl/certificate_revocation_list.rb @@ -8,8 +8,6 @@ describe Puppet::SSL::CertificateRevocationList do before do @cert = stub 'cert', :subject => "mysubject" - @key = stub 'key' - @class = Puppet::SSL::CertificateRevocationList end @@ -17,84 +15,27 @@ describe Puppet::SSL::CertificateRevocationList do before do @class.any_instance.stubs(:read_or_generate) - @crl = @class.new("myname", @cert, @key) + @crl = @class.new end - it "should have a name attribute" do - @crl.name.should == "myname" + it "should always use 'crl' for its name" do + @crl.name.should == "crl" end it "should have a content attribute" do @crl.should respond_to(:content) end - - it "should be able to read the crl from disk" do - path = "/my/path" - File.expects(:read).with(path).returns("my crl") - crl = mock 'crl' - OpenSSL::X509::CRL.expects(:new).with("my crl").returns(crl) - @crl.read(path).should equal(crl) - @crl.content.should equal(crl) - end - - it "should return an empty string when converted to a string with no crl" do - @crl.to_s.should == "" - end - - it "should convert the crl to pem format when converted to a string" do - crl = mock 'crl', :to_pem => "pem" - @crl.content = crl - @crl.to_s.should == "pem" - end - - it "should have a :to_text method that it delegates to the actual crl" do - real_crl = mock 'crl' - real_crl.expects(:to_text).returns "crltext" - @crl.content = real_crl - @crl.to_text.should == "crltext" - end end describe "when initializing" do - it "should require the CA cert and key" do - lambda { @class.new("myname") }.should raise_error(ArgumentError) - end - it "should fail if :cacrl is set to false" do Puppet.settings.expects(:value).with(:cacrl).returns false - lambda { @class.new("myname", @cert, @key) }.should raise_error(Puppet::Error) + lambda { @class.new }.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("myname", @cert, @key) }.should raise_error(Puppet::Error) - end - - it "should read the CRL from disk" do - Puppet.settings.stubs(:value).with(:cacrl).returns "/path/to/crl" - @class.any_instance.expects(:read).with("/path/to/crl").returns("my key") - - @class.new("myname", @cert, @key) - end - - describe "and no CRL exists on disk" do - before do - @class.any_instance.stubs(:read).returns(false) - @class.any_instance.stubs(:generate) - @class.any_instance.stubs(:save) - end - - it "should generate a new CRL" do - @class.any_instance.expects(:generate).with(@cert, @key) - - @class.new("myname", @cert, @key) - end - - it "should save the CRL" do - @class.any_instance.expects(:save).with(@key) - - @class.new("myname", @cert, @key) - end + lambda { @class.new }.should raise_error(Puppet::Error) end end @@ -107,61 +48,91 @@ describe Puppet::SSL::CertificateRevocationList do @class.any_instance.stubs(:read_or_generate) - @crl = @class.new("myname", @cert, @key) + @crl = @class.new end it "should set its issuer to the subject of the passed certificate" do @real_crl.expects(:issuer=).with(@cert.subject) - @crl.generate(@cert, @key) + @crl.generate(@cert) end it "should set its version to 1" do @real_crl.expects(:version=).with(1) - @crl.generate(@cert, @key) + @crl.generate(@cert) end it "should create an instance of OpenSSL::X509::CRL" do OpenSSL::X509::CRL.expects(:new).returns(@real_crl) - @crl.generate(@cert, @key) + @crl.generate(@cert) end it "should set the content to the generated crl" do - @crl.generate(@cert, @key) + @crl.generate(@cert) @crl.content.should equal(@real_crl) end it "should return the generated crl" do - @crl.generate(@cert, @key).should equal(@real_crl) - end - - it "should return the crl in pem format" do - @crl.generate(@cert, @key) - @crl.content.expects(:to_pem).returns "my normal crl" - @crl.to_s.should == "my normal crl" + @crl.generate(@cert).should equal(@real_crl) end end - describe "when saving the CRL" do + # This test suite isn't exactly complete, because the + # SSL stuff is very complicated. It just hits the high points. + describe "when revoking a certificate" do before do - @class.any_instance.stubs(:read_or_generate) @class.wrapped_class.any_instance.stubs(:issuer=) - @crl = @class.new("myname", @cert, @key) - @crl.generate(@cert, @key) + @crl = @class.new + @crl.generate(@cert) + @crl.content.stubs(:sign) + + @crl.stubs :save + + @key = mock 'key' + end + + it "should require a serial number and the CA's private key" do + lambda { @crl.revoke }.should raise_error(ArgumentError) end - it "should use the Settings#write method to write the file" do - pending("Not fully ported") do - fh = mock 'filehandle' - Puppet.settings.expects(:write).with(:cacrl).yields fh + it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the revocation reason" do + # This makes it a bit more of an integration test than we'd normally like, but that's life + # with openssl. + reason = OpenSSL::ASN1::Enumerated(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE) + OpenSSL::ASN1.expects(:Enumerated).with(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE).returns reason + + @crl.revoke(1, @key) + end - fh.expects :print + it "should mark the CRL as updated" do + time = Time.now + Time.expects(:now).returns time + + @crl.content.expects(:last_update=).with(time) + + @crl.revoke(1, @key) + end + + it "should mark the CRL valid for five years" do + time = Time.now + Time.expects(:now).returns time + + @crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60)) + + @crl.revoke(1, @key) + end + + it "should sign the CRL with the CA's private key and a digest instance" do + @crl.content.expects(:sign).with { |key, digest| key == @key and digest.is_a?(OpenSSL::Digest::SHA1) } + @crl.revoke(1, @key) + end - @crl.save(@key) - end + it "should save the CRL" do + @crl.expects :save + @crl.revoke(1, @key) end end end diff --git a/spec/unit/ssl/host.rb b/spec/unit/ssl/host.rb index e82971683..97d6c27d8 100755 --- a/spec/unit/ssl/host.rb +++ b/spec/unit/ssl/host.rb @@ -30,7 +30,11 @@ describe Puppet::SSL::Host do it "should be able to be a ca host" do @host.ca = true - @host.ca.should be_true + @host.ca?.should be_true + end + + it "should support having a password file set" do + lambda { @host.password_file = "/my/file" }.should_not raise_error end describe "when managing its private key" do @@ -59,6 +63,17 @@ describe Puppet::SSL::Host do @host.key.should equal(@realkey) end + it "should pass its password file on to the key if one is set" do + @host.password_file = "/my/password" + Puppet::SSL::Key.expects(:new).with("myname").returns(@key) + + @key.stub_everything + + @key.expects(:password_file=).with("/my/password") + + @host.generate_key + end + it "should return any previously found key without requerying" do Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once @host.key.should equal(@realkey) |
