Class: CertificateDepot
- Inherits:
-
Object
- Object
- CertificateDepot
- Defined in:
- lib/certificate_depot.rb,
lib/certificate_depot/log.rb,
lib/certificate_depot/store.rb,
lib/certificate_depot/runner.rb,
lib/certificate_depot/server.rb,
lib/certificate_depot/worker.rb,
lib/certificate_depot/keypair.rb,
lib/certificate_depot/certificate.rb
Overview
CertificateDepot
The CertificateDepot manages a single depot of certificates. For more than a casual understanding of these terms we need to explain a bit more about certificates first. If you already know how PKI works, you can skip the following paragraphs.
Certificate Authorities
“[A] certificate authority or certification authority (CA) is an entity that issues digital certificates for use by other parties.” – en.wikipedia.org/wiki/Certificate_authority
When a CA says that party A is who they say they are and you trust the CA then you can assume they are in fact party A.
In a Public Key Infrastructure this means that the CA has a private key which only he knows. He uses this key to sign certificates stating that the person owning the certificate is who the certificate says they are. Because there is a public key associated with the certificate anyone can use a crytographic challenge to make sure the owner has the private key to this certificate.
For example: I have a certificate that says that I’m the person with the email address [email protected]. I show my certificate to Rick. Rick gets my public key from the certificate and sends me a challenge. I compute the right response and send it to Rick. Rick checks the response and knows I’m the rightful owner of the certificate.
A PKI infrastructure has many more uses, but we will only focus on authentication in our examples.
There are two ways in which a CA can make sure his trust network stays valid. Each certificate has a limited period in which it’s valid. Even if the CA forgets that he has issued the certificate it will stop being valid after a while. Large CA’s claim this also protects against evolving attack vectors against the crytography used behind the certificates. Each certificate can be revoked by the CA. A publicly available list of revoked certificates makes it possible to check whether a certain certificate is still valid according to the CA.
Certificate types
Certificate authorities came up with lots of additional features. One of these is a certificate type. To be more precise, there is an extension to the certificate that tells in which cases you should accept the key contained in the certificate. This allows the CA to limit the use of a certificate to just digital signatures, encipherment, or certain types of authentication.
For simplicity Certificate Depot only knows three types; CA, Server, and Client.
A certificate depot
We’ve named the collection of all information needed to run a CA a certificate depot. It holds the CA certificate and private key, all issued certificates, the revokation list, and several files need to manage these.
Defined Under Namespace
Classes: Certificate, Keypair, Log, Runner, Server, Store, Worker
Class Method Summary collapse
-
.certificate_path(path) ⇒ Object
Returns the path to the CA’s certificate given the depot path.
-
.certificates_path(path) ⇒ Object
Returns the path to the generated certificates given the depot path.
-
.configuration_example(path) ⇒ Object
Returns a string with an Apache configuration example for using TLS client certificate authentication.
-
.create(path, label, options = {}) ⇒ Object
Creates a new depot on disk.
-
.create_ca_certificate(path, label) ⇒ Object
Creates a CA certificate and keypair and writes it to disk.
-
.create_configuration(path, label) ⇒ Object
Writes a configuration file to disk containing the path to the depot and its name.
- .create_directories(path) ⇒ Object
-
.crl_path(path) ⇒ Object
Returns the path to the certificate revokation list given the depot path.
-
.generate_keypair_and_certificate(path, options = {}) ⇒ Object
Generates a new RSA keypair and certificate.
-
.key_path(path) ⇒ Object
Returns the path to the CA’s private key given the depot path.
-
.openssl_config_path(path) ⇒ Object
Returns the path to the configuration file given the depot path.
-
.private_path(path) ⇒ Object
Returns the path to the directory with private data given the depot path.
-
.run(argv) ⇒ Object
Runs a command to the depot.
-
.start(path, options = {}) ⇒ Object
Starts a server.
-
.stop(options = {}) ⇒ Object
Stops a running server.
Instance Method Summary collapse
-
#ca_certificate ⇒ Object
Returns an instance of CertificateDepot::Certificate containing the certificate of the certificate authority.
-
#ca_private_key ⇒ Object
Returns an instance of OpenSSL::PKey::RSA containing the private key of the certificate authority.
-
#certificates ⇒ Object
Returns an instance of CertificateDepot::Store representing all certificates in the depot.
-
#generate_keypair_and_certificate(options = {}) ⇒ Object
Generates a new RSA keypair and certificate.
-
#initialize(path) ⇒ CertificateDepot
constructor
Initialize a new depot with the path to the depot directory.
-
#label ⇒ Object
Returns the label with a descriptive name for the depot.
-
#path ⇒ Object
Path to the depot directory.
Constructor Details
#initialize(path) ⇒ CertificateDepot
Initialize a new depot with the path to the depot directory.
depot = CertificateDepot.new('/var/lib/certificate-depot/example')
75 76 77 |
# File 'lib/certificate_depot.rb', line 75 def initialize(path) @config = OpenSSL::Config.load(self.class.openssl_config_path(path)) end |
Class Method Details
.certificate_path(path) ⇒ Object
Returns the path to the CA’s certificate given the depot path.
258 259 260 |
# File 'lib/certificate_depot.rb', line 258 def self.certificate_path(path) File.join(certificates_path(path), 'ca.crt') end |
.certificates_path(path) ⇒ Object
Returns the path to the generated certificates given the depot path.
243 244 245 |
# File 'lib/certificate_depot.rb', line 243 def self.certificates_path(path) File.join(path, 'certificates') end |
.configuration_example(path) ⇒ Object
Returns a string with an Apache configuration example for using TLS client certificate authentication.
204 205 206 207 208 209 210 |
# File 'lib/certificate_depot.rb', line 204 def self.configuration_example(path) "SSLEngine on SSLOptions +StdEnvVars SSLCertificateFile \"/etc/apache/ssl/certificates/example.com.pem\" SSLVerifyClient require SSLCACertificateFile \"#{certificate_path(path)}\"" end |
.create(path, label, options = {}) ⇒ Object
Creates a new depot on disk.
depot = CertificateDepot.create('/var/lib/certificate-depot/example')
176 177 178 179 180 181 182 |
# File 'lib/certificate_depot.rb', line 176 def self.create(path, label, ={}) attributes = create_directories(path) create_configuration(path, label) create_ca_certificate(path, label) new(path) end |
.create_ca_certificate(path, label) ⇒ Object
Creates a CA certificate and keypair and writes it to disk.
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/certificate_depot.rb', line 160 def self.create_ca_certificate(path, label) keypair = CertificateDepot::Keypair.generate keypair.write_to(key_path(path)) attributes = {} attributes[:type] = :ca attributes[:public_key] = keypair.public_key attributes[:private_key] = keypair.private_key attributes[:organization] = label certificate = CertificateDepot::Certificate.generate(attributes) certificate.write_to(certificate_path(path)) end |
.create_configuration(path, label) ⇒ Object
Writes a configuration file to disk containing the path to the depot and its name.
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/certificate_depot.rb', line 148 def self.create_configuration(path, label) File.open(openssl_config_path(path), 'w') do |file| file.write("[ ca ] label = #{label} [ #{label} ] path = #{path} ") end end |
.create_directories(path) ⇒ Object
139 140 141 142 143 144 |
# File 'lib/certificate_depot.rb', line 139 def self.create_directories(path) FileUtils.mkdir_p(certificates_path(path)) FileUtils.mkdir_p(private_path(path)) FileUtils.chmod(0700, private_path(path)) FileUtils.chmod(0755, path) end |
.crl_path(path) ⇒ Object
Returns the path to the certificate revokation list given the depot path.
248 249 250 |
# File 'lib/certificate_depot.rb', line 248 def self.crl_path(path) File.join(path, 'crl.pem') end |
.generate_keypair_and_certificate(path, options = {}) ⇒ Object
Generates a new RSA keypair and certificate. See CertificateDepot#generate_keypair_and_certificate and CertificateDepot::Certificate.new for more information and possible options.
keypair, certificate =
CertificateDepot.generate_keypair_and_certificate(
'/var/lib/certificate-depot/example', {
:type => :client,
:common_name => 'Robert Verkey',
:email_address => '[email protected]'
}
)
197 198 199 200 |
# File 'lib/certificate_depot.rb', line 197 def self.generate_keypair_and_certificate(path, ={}) depot = new(path) depot.generate_keypair_and_certificate() end |
.key_path(path) ⇒ Object
Returns the path to the CA’s private key given the depot path.
253 254 255 |
# File 'lib/certificate_depot.rb', line 253 def self.key_path(path) File.join(private_path(path), 'ca.key') end |
.openssl_config_path(path) ⇒ Object
Returns the path to the configuration file given the depot path.
233 234 235 |
# File 'lib/certificate_depot.rb', line 233 def self.openssl_config_path(path) File.join(path, 'depot.cnf') end |
.private_path(path) ⇒ Object
Returns the path to the directory with private data given the depot path.
238 239 240 |
# File 'lib/certificate_depot.rb', line 238 def self.private_path(path) File.join(path, 'private') end |
.run(argv) ⇒ Object
Runs a command to the depot. Used by the command line tool to run commands.
226 227 228 229 230 |
# File 'lib/certificate_depot.rb', line 226 def self.run(argv) runner = ::CertificateDepot::Runner.new(argv) runner.run runner end |
.start(path, options = {}) ⇒ Object
Starts a server. For available options see CertificateDepot::Server.new.
213 214 215 |
# File 'lib/certificate_depot.rb', line 213 def self.start(path, ={}) CertificateDepot::Server.start(new(path), ) end |
.stop(options = {}) ⇒ Object
Stops a running server. Using the options you can specify where to look for the pid file. See CertificateDepot::Server.new for more information about the options.
220 221 222 |
# File 'lib/certificate_depot.rb', line 220 def self.stop(={}) CertificateDepot::Server.stop() end |
Instance Method Details
#ca_certificate ⇒ Object
Returns an instance of CertificateDepot::Certificate containing the certificate of the certificate authority.
92 93 94 |
# File 'lib/certificate_depot.rb', line 92 def ca_certificate @ca_certificate ||= CertificateDepot::Certificate.from_file(self.class.certificate_path(path)) end |
#ca_private_key ⇒ Object
Returns an instance of OpenSSL::PKey::RSA containing the private key of the certificate authority.
98 99 100 |
# File 'lib/certificate_depot.rb', line 98 def ca_private_key @ca_private_key ||= OpenSSL::PKey::RSA.new(File.read(self.class.key_path(path))) end |
#certificates ⇒ Object
Returns an instance of CertificateDepot::Store representing all certificates in the depot.
132 133 134 135 136 137 |
# File 'lib/certificate_depot.rb', line 132 def certificates if @certificates.nil? @certificates = CertificateDepot::Store.new(self.class.certificates_path(path)) @certificates.extend(MonitorMixin) end; @certificates end |
#generate_keypair_and_certificate(options = {}) ⇒ Object
Generates a new RSA keypair and certificate.
Defaults
By default the certificate issuer is the CA of the depot and it’s also signed by the CA. The serial number is the next available serial number in the depot.
See CertificateDepot::Certificate#generate for all available options.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/certificate_depot.rb', line 111 def generate_keypair_and_certificate(={}) keypair = CertificateDepot::Keypair.generate certificate = nil certificates.synchronize do attributes = attributes[:ca_certificate] = ca_certificate attributes[:public_key] = keypair.public_key attributes[:private_key] = ca_private_key attributes[:serial_number] = certificates.next_serial_number certificate = CertificateDepot::Certificate.generate(attributes) certificates << certificate certificates.sync end [keypair, certificate] end |
#label ⇒ Object
Returns the label with a descriptive name for the depot. This is usually the common name of the CA.
81 82 83 |
# File 'lib/certificate_depot.rb', line 81 def label @config['ca']['label'] end |
#path ⇒ Object
Path to the depot directory.
86 87 88 |
# File 'lib/certificate_depot.rb', line 86 def path @config[label]['path'] end |