summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2006-08-21 21:54:13 +0000
committerlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2006-08-21 21:54:13 +0000
commit7ade561e75853116baef15f3750e3563e6a6faaf (patch)
treea64b6e3f1cb2038386f60fb2774bb5a191ebc24e /test
parentc6fc6c56cea381c7bdf15e8610a28a4c6924ecf5 (diff)
downloadpuppet-7ade561e75853116baef15f3750e3563e6a6faaf.tar.gz
puppet-7ade561e75853116baef15f3750e3563e6a6faaf.tar.xz
puppet-7ade561e75853116baef15f3750e3563e6a6faaf.zip
Support for certificate revocation and checking connections on the server against the CRL
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1475 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'test')
-rwxr-xr-xtest/certmgr/certmgr.rb55
-rw-r--r--test/server/server.rb115
2 files changed, 139 insertions, 31 deletions
diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb
index 8c88fe4d6..66376fcea 100755
--- a/test/certmgr/certmgr.rb
+++ b/test/certmgr/certmgr.rb
@@ -261,4 +261,59 @@ class TestCertMgr < Test::Unit::TestCase
}
assert_nil(cert)
end
+
+ def test_crl
+ ca = mkCA()
+ h1 = mkSignedCert(ca, "host1.example.com")
+ h2 = mkSignedCert(ca, "host2.example.com")
+
+ assert(ca.cert.verify(ca.cert.public_key))
+ assert(h1.verify(ca.cert.public_key))
+ assert(h2.verify(ca.cert.public_key))
+
+ crl = ca.crl
+ assert_not_nil(crl)
+
+ store = mkStore(ca)
+ assert( store.verify(ca.cert))
+ assert( store.verify(h1, [ca.cert]))
+ assert( store.verify(h2, [ca.cert]))
+
+ ca.revoke(h1.serial)
+
+ # Recreate the CA from disk
+ ca = mkCA()
+ store = mkStore(ca)
+ assert( store.verify(ca.cert))
+ assert(!store.verify(h1, [ca.cert]))
+ assert( store.verify(h2, [ca.cert]))
+
+ ca.revoke(h2.serial)
+ assert_equal(1, ca.crl.extensions.size)
+
+ File::open("/tmp/crl.pem", "w") { |f| f.write(ca.crl.to_pem) }
+ # Recreate the CA from disk
+ ca = mkCA()
+ store = mkStore(ca)
+ assert( store.verify(ca.cert))
+ assert(!store.verify(h1, [ca.cert]))
+ assert(!store.verify(h2, [ca.cert]))
+ end
+
+ def mkSignedCert(ca, host)
+ cert = mkcert(host)
+ assert_nothing_raised {
+ signedcert, cacert = ca.sign(cert.mkcsr)
+ return signedcert
+ }
+ end
+
+ def mkStore(ca)
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
+ store.add_cert(ca.cert)
+ store.add_crl(ca.crl)
+ store
+ end
end
diff --git a/test/server/server.rb b/test/server/server.rb
index ea74a0a1c..e279d8440 100644
--- a/test/server/server.rb
+++ b/test/server/server.rb
@@ -24,44 +24,16 @@ class TestServer < Test::Unit::TestCase
# we have to use fork here, because we apparently can't use threads
# to talk to other threads
def test_connect_with_fork
- server = nil
Puppet[:autosign] = true
-
- # create a server just serving status
- assert_nothing_raised() {
- server = Puppet::Server.new(
- :Port => @@port,
- :Handlers => {
- :CA => {}, # so that certs autogenerate
- :Status => nil
- }
- )
-
- }
-
- # and fork
- serverpid = fork {
- assert_nothing_raised() {
- trap(:INT) { server.shutdown }
- server.start
- }
- }
- @@tmppids << serverpid
+ serverpid, server = mk_status_server
# create a status client, and verify it can talk
- client = nil
- assert_nothing_raised() {
- client = Puppet::Client::StatusClient.new(
- :Server => "localhost",
- :Port => @@port
- )
- }
- retval = nil
+ client = mk_status_client
+ retval = nil
assert_nothing_raised() {
retval = client.status
}
-
assert_equal(1, retval)
end
@@ -145,4 +117,85 @@ class TestServer < Test::Unit::TestCase
}
assert(FileTest.exists?(server.pidfile), "PID file was not created")
end
+
+
+ # Test that a client whose cert has been revoked really can't connect
+ def test_certificate_revocation
+ Puppet[:autosign] = true
+
+ serverpid, server = mk_status_server
+
+ client = mk_status_client
+
+ status = nil
+ assert_nothing_raised() {
+ status = client.status
+ }
+ assert_equal(1, status)
+ client.shutdown
+
+ # Revoke the client's cert
+ ca = Puppet::SSLCertificates::CA.new()
+ fqdn = client.fqdn
+ ca.revoke(ca.getclientcert(fqdn)[0].serial)
+
+ # Restart the server
+ @@port += 1
+ Puppet[:autosign] = false
+ kill_and_wait(serverpid, server.pidfile)
+ serverpid, server = mk_status_server
+
+ client = mk_status_client
+ # This time the client should be denied
+ assert_raise(Puppet::NetworkClientError) {
+ client.status
+ }
+ end
+
+ def mk_status_client
+ client = nil
+ # Otherwise, the client initalization will trip over itself
+ # since elements created in the last run are still around
+ Puppet::Type::allclear
+
+ assert_nothing_raised() {
+ client = Puppet::Client::StatusClient.new(
+ :Server => "localhost",
+ :Port => @@port
+ )
+ }
+ client
+ end
+
+ def mk_status_server
+ server = nil
+ assert_nothing_raised() {
+ server = Puppet::Server.new(
+ :Port => @@port,
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :Status => nil
+ }
+ )
+
+ }
+ pid = fork {
+ assert_nothing_raised() {
+ trap(:INT) { server.shutdown }
+ server.start
+ }
+ }
+ @@tmppids << pid
+ [pid, server]
+ end
+
+ def kill_and_wait(pid, file)
+ %x{kill -INT #{pid} 2>/dev/null}
+ count = 0
+ while count < 30 && File::exist?(file)
+ count += 1
+ sleep(1)
+ end
+ assert(count < 30, "Killing server #{pid} failed")
+ end
end