summaryrefslogtreecommitdiffstats
path: root/lib/puppet/ssl/certificate_authority.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/ssl/certificate_authority.rb')
-rw-r--r--lib/puppet/ssl/certificate_authority.rb140
1 files changed, 107 insertions, 33 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