From f379b0e43cfa0137379ad0f78f48223eba7db61a Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 13 Jun 2012 14:36:39 -0400 Subject: improved SSLCA verification routines and logging --- doc/server/plugins/generators/sslca.txt | 8 ++++++- src/lib/Server/Plugins/SSLCA.py | 42 +++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index 8e33148cb..d2b051535 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -33,7 +33,7 @@ must contain full (not relative) paths. #. Add SSLCA to the **plugins** line in ``/etc/bcfg2.conf`` and restart the server -- This enabled the SSLCA plugin on the Bcfg2 server. -#. Add a section to your ``/etc/bcfg2.conf`` called sslca_foo, replacing foo +#. Add a section to your ``/etc/bcfg2.conf`` called ``sslca_foo``, replacing foo with the name you wish to give your CA so you can reference it in certificate definitions. @@ -51,6 +51,12 @@ must contain full (not relative) paths. specification. If you're using a self signing CA this would be the CA cert that you generated. +#. Optionally, add ``verify_certs = false`` if you don't wish to + perform certificate verification on the certs SSLCA generates. + Verification includes ``openssl verify`` to verify the CA chain, + and ensuring that both the key file and certificate file contain + the same key. + #. Once all this is done, you should have a section in your ``/etc/bcfg2.conf`` that looks similar to the following:: diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index a50c003ae..dc0aea6d3 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -3,12 +3,15 @@ import Bcfg2.Options import lxml.etree import posixpath import tempfile -import pipes import os from subprocess import Popen, PIPE, STDOUT # Compatibility import from Bcfg2.Bcfg2Py3k import ConfigParser +try: + from hashlib import md5 +except ImportError: + from md5 import md5 class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ @@ -172,22 +175,29 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): Bcfg2.Server.Plugin.bind_info(entry, metadata) def verify_cert(self, filename, key_filename, entry): - if self.verify_cert_against_ca(filename, entry): - if self.verify_cert_against_key(filename, key_filename): - return True - return False + do_verify = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('verify_certs', True) + if do_verify: + return (self.verify_cert_against_ca(filename, entry) and + self.verify_cert_against_key(filename, key_filename)) + return True def verify_cert_against_ca(self, filename, entry): """ check that a certificate validates against the ca cert, and that it has not expired. """ - chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert') + chaincert = \ + self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert') cert = self.data + filename - res = Popen(["openssl", "verify", "-CAfile", chaincert, cert], + res = Popen(["openssl", "verify", "-untrusted", chaincert, "-purpose", + "sslserver", cert], stdout=PIPE, stderr=STDOUT).stdout.read() if res == cert + ": OK\n": + self.debug_log("SSLCA: %s verified successfully against CA" % + entry.get("name")) return True + self.logger.warning("SSLCA: %s failed verification against CA: %s" % + (entry.get("name"), res)) return False def verify_cert_against_key(self, filename, key_filename): @@ -196,14 +206,20 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ cert = self.data + filename key = self.data + key_filename - cmd = ("openssl x509 -noout -modulus -in %s | openssl md5" % - pipes.quote(cert)) - cert_md5 = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read() - cmd = ("openssl rsa -noout -modulus -in %s | openssl md5" % - pipes.quote(key)) - key_md5 = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read() + cert_md5 = \ + md5(Popen(["openssl", "x509", "-noout", "-modulus", "-in", cert], + stdout=PIPE, + stderr=STDOUT).stdout.read().strip()).hexdigest() + key_md5 = \ + md5(Popen(["openssl", "rsa", "-noout", "-modulus", "-in", key], + stdout=PIPE, + stderr=STDOUT).stdout.read().strip()).hexdigest() if cert_md5 == key_md5: + self.debug_log("SSLCA: %s verified successfully against key %s" % + (filename, key_filename)) return True + self.logger.warning("SSLCA: %s failed verification against key %s" % + (filename, key_filename)) return False def build_cert(self, key_filename, entry, metadata): -- cgit v1.2.3-1-g7c22