From: Jude Nagurney Date: Sun, 11 Oct 2015 20:28:06 +0000 (-0400) Subject: sha1 supprt checkpoint X-Git-Tag: v0.29~2 X-Git-Url: https://pwan.org/git/?p=certmaster.git;a=commitdiff_plain;h=67e8a55e10f81105cb76e7c1ff9d0615cf97dff5 sha1 supprt checkpoint --- diff --git a/MANIFEST.in b/MANIFEST.in index 9633326..928aa6c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,5 +7,5 @@ recursive-include po *.pot recursive-include triggers * include AUTHORS include LICENSE -include README +include README.md diff --git a/certmaster.spec b/certmaster.spec index 1b51c5b..0e68308 100644 --- a/certmaster.spec +++ b/certmaster.spec @@ -111,7 +111,7 @@ rm -fr $RPM_BUILD_ROOT %dir /var/lib/certmaster/triggers/remove/post /var/lib/certmaster/triggers/sign/post/certmaster-sync /var/lib/certmaster/triggers/remove/post/certmaster-sync -%doc AUTHORS README LICENSE +%doc AUTHORS README.md LICENSE %{_mandir}/man1/*.1.gz diff --git a/certmaster/certmaster.py b/certmaster/certmaster.py index 36f2bc4..5947362 100644 --- a/certmaster/certmaster.py +++ b/certmaster/certmaster.py @@ -21,6 +21,7 @@ import sys import traceback import os import os.path +import warnings from OpenSSL import crypto try: @@ -32,6 +33,8 @@ except ImportError: @staticmethod def new(algo): if algo == 'sha1': + # TODO: jude: was warnings even available in 2.4 ? + warnings.warn("sha1 is deprecated", DeprecationWarning) return sha.new() raise ValueError, "Bad checksum type" @@ -82,7 +85,7 @@ class CertMaster(object): if not os.path.exists(s_cadir): os.makedirs(s_cadir) if not os.path.exists(s_ca_key_file) and not os.path.exists(s_ca_cert_file): - certs.create_ca(CN=mycn, ca_key_file=s_ca_key_file, ca_cert_file=s_ca_cert_file) + certs.create_ca(CN=mycn, ca_key_file=s_ca_key_file, ca_cert_file=s_ca_cert_file, hash_function=a_ca.hash_function) except (IOError, OSError), e: print 'Cannot make certmaster certificate authority keys/certs for CA %s, aborting: %s' % (s_caname, e) sys.exit(1) @@ -153,10 +156,10 @@ class CertMaster(object): if os.path.exists(csrfile): oldfo = open(csrfile) oldcsrbuf = oldfo.read() - oldsha = hashlib.new('sha1') + oldsha = hashlib.new(certauth.hash_function) oldsha.update(oldcsrbuf) olddig = oldsha.hexdigest() - newsha = hashlib.new('sha1') + newsha = hashlib.new(certauth.hash_function) newsha.update(csrbuf) newdig = newsha.hexdigest() if not newdig == olddig: @@ -268,7 +271,7 @@ class CertMaster(object): certfile = '%s/%s.cert' % (certauth.certroot, requesting_host) self.logger.info("Signing for csr %s requested" % certfile) - thiscert = certs.create_slave_certificate(csrreq, certauth.cakey, certauth.cacert, certauth.cadir) + thiscert = certs.create_slave_certificate(csrreq, certauth.cakey, certauth.cacert, certauth.cadir, certauth.hash_function) destfo = open(certfile, 'w') destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, thiscert)) diff --git a/certmaster/certs.py b/certmaster/certs.py index d6f8b14..5771691 100644 --- a/certmaster/certs.py +++ b/certmaster/certs.py @@ -89,7 +89,7 @@ def retrieve_cert_from_file(certfile): return cert -def create_ca(CN="Certmaster Certificate Authority", ca_key_file=None, ca_cert_file=None): +def create_ca(CN="Certmaster Certificate Authority", ca_key_file=None, ca_cert_file=None, hash_function='sha256'): cakey = make_keypair(dest=ca_key_file) careq = make_csr(cakey, cn=CN) cacert = crypto.X509() @@ -103,7 +103,7 @@ def create_ca(CN="Certmaster Certificate Authority", ca_key_file=None, ca_cert_f xt = crypto.X509Extension('basicConstraints',1,'CA:TRUE') # FIXME - add subjectkeyidentifier and authoritykeyidentifier extensions, too) cacert.add_extensions((xt,)) - cacert.sign(cakey, 'sha1') + cacert.sign(cakey, hash_function) if ca_cert_file: destfo = open(ca_cert_file, 'w') destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cacert)) @@ -133,7 +133,7 @@ def _set_serial_number(cadir, last): f.close() -def create_slave_certificate(csr, cakey, cacert, cadir, slave_cert_file=None): +def create_slave_certificate(csr, cakey, cacert, cadir, slave_cert_file=None, hash_function='sha256'): cert = crypto.X509() cert.set_serial_number(_get_serial_number(cadir)) cert.gmtime_adj_notBefore(0) @@ -145,7 +145,7 @@ def create_slave_certificate(csr, cakey, cacert, cadir, slave_cert_file=None): xt = crypto.X509Extension('basicConstraints', False ,'CA:FALSE') # FIXME - add subjectkeyidentifier and authoritykeyidentifier extensions, too) cert.add_extensions((xt,)) - cert.sign(cakey, 'sha1') + cert.sign(cakey, hash_function) if slave_cert_file: destfo = open(slave_cert_file, 'w') destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) diff --git a/certmaster/commonconfig.py b/certmaster/commonconfig.py index 5d0361e..c062d28 100644 --- a/certmaster/commonconfig.py +++ b/certmaster/commonconfig.py @@ -29,6 +29,7 @@ class CMConfig(BaseConfig): sync_certs = BoolOption(False) peering = BoolOption(True) peerroot = Option('/var/lib/certmaster/peers') + hash_function = Option('sha256') class MinionConfig(BaseConfig): log_level = Option('INFO') diff --git a/certmaster/config.py b/certmaster/config.py index 2cec66f..c6e9174 100644 --- a/certmaster/config.py +++ b/certmaster/config.py @@ -17,7 +17,6 @@ import os import sys -import warnings import copy import urlparse from ConfigParser import NoSectionError, NoOptionError, ConfigParser @@ -448,7 +447,7 @@ class BaseConfig(object): self.cfg.write(fileobj) def getConfigOption(self, option, default=None): - warnings.warn('getConfigOption() will go away in a future version of Yum.\n' + warnings.warn('getConfigOption() will go away in a future version of certmaster.\n' 'Please access option values as attributes or using getattr().', DeprecationWarning) if hasattr(self, option): @@ -456,7 +455,7 @@ class BaseConfig(object): return default def setConfigOption(self, option, value): - warnings.warn('setConfigOption() will go away in a future version of Yum.\n' + warnings.warn('setConfigOption() will go away in a future version of certmaster.\n' 'Please set option values as attributes or using setattr().', DeprecationWarning) if hasattr(self, option): @@ -481,16 +480,28 @@ def read_config(config_file, BaseConfigDerived): ## Add the default items when just using a single ca opts.ca[''] = BaseConfigDerived() + opts.ca[''].hash_function = None opts.ca[''].populate(confparser,'main') + if opts.ca[''].hash_function == 'sha1': + log.warning('hash_function value of sha1 is deprecated', DeprecationWarning) + elif opts.ca[''].hash_function == 'md5': + print >> sys.stderr, "Error: hash_function of md5 is not supported" + ## Add additonal ca sections sections = confparser.sections() for a_section in sections: if a_section.startswith('ca:'): ca_name = a_section[3:] opts.ca[ca_name] = BaseConfigDerived() + opts.ca[ca_name].hash_function = None opts.ca[ca_name].populate(confparser,a_section) opts.ca[ca_name].cakey = None opts.ca[ca_name].cacert = None + + if opts.ca[ca_name].hash_function == 'sha1': + warnings.warn('hash_function value of sha1 is deprecated in ca:%s section' % ca_name, DeprecationWarning) + elif opts.ca[ca_name].hash_function == 'md5': + print >> sys.stderr, "Error: hash_function of md5 is not supported in ca:% section" % ca_name return opts diff --git a/scripts/certmaster-sync b/scripts/certmaster-sync index ca7710e..8e6db44 100644 --- a/scripts/certmaster-sync +++ b/scripts/certmaster-sync @@ -7,6 +7,7 @@ import os import sys +import warning try: import hashlib except ImportError: @@ -16,6 +17,7 @@ except ImportError: @staticmethod def new(algo): if algo == 'sha1': + warnings.warn('sha1 is deprecated',DeprecationWarning) return sha.new() raise ValueError, "Bad checksum type" @@ -76,7 +78,7 @@ def remote_peers(hosts): def local_certs(): """ - Returns (hostname, sha1) hash of local certs + Returns (hostname, hashval) hash of local certs """ globby = '*.%s' % cm.cfg.cert_extension globby = os.path.join(cm.cfg.certroot, globby) @@ -85,12 +87,12 @@ def local_certs(): for f in files: hostname = os.path.basename(f).replace('.' + cm.cfg.cert_extension, '') dirname = os.path.dirname(f) - digest = checksum(f) + digest = checksum(f,cm.cfg.hashfunc) results.append([hostname, digest, dirname]) return results -def checksum(f): - thissum = hashlib.new('sha1') +def checksum(f,hashfunc): + thissum = hashlib.new(hashfunc) if os.path.exists(f): fo = open(f, 'r') data = fo.read() diff --git a/tests/certmaster.conf.tst b/tests/certmaster.conf.tst index e0188b5..e4c294b 100644 --- a/tests/certmaster.conf.tst +++ b/tests/certmaster.conf.tst @@ -21,3 +21,19 @@ cert_dir = /etc/pki/certmaster/test certroot = /var/lib/certmaster/test/certs csrroot = /var/lib/certmaster/test/csrs +[ca:sha1] +autosign = yes +cadir = /etc/pki/certmaster/sha1-ca +cert_dir = /etc/pki/certmaster/sha1 +certroot = /var/lib/certmaster/sha1/certs +csrroot = /var/lib/certmaster/sha1/csrs +hash_function = sha224 + +[ca:sha224] +autosign = yes +cadir = /etc/pki/certmaster/sha224-ca +cert_dir = /etc/pki/certmaster/sha224 +certroot = /var/lib/certmaster/sha224/certs +csrroot = /var/lib/certmaster/sha224/csrs +hash_function = sha224 + diff --git a/tests/minion.conf.tst b/tests/minion.conf.tst index 9e44013..f8fd330 100644 --- a/tests/minion.conf.tst +++ b/tests/minion.conf.tst @@ -9,4 +9,13 @@ cert_dir = /etc/pki/certmaster [ca:test] cert_dir = /etc/pki/certmaster-test +hash_function = sha256 + +[ca:sha1] +cert_dir = /etc/pki/certmaster-sha1 +hash_function = sha1 + +[ca:sha224] +cert_dir = /etc/pki/certmaster-sha224 +hash_function = sha224 diff --git a/tests/test-certmaster.sh b/tests/test-certmaster.sh index b9c6be1..11e7565 100755 --- a/tests/test-certmaster.sh +++ b/tests/test-certmaster.sh @@ -178,6 +178,9 @@ test_TestCA_Autosigning() subject=`openssl x509 -in /etc/pki/certmaster-test/testcert.pwan.co.cert -subject -noout` [[ $subject == *"CN=testcert.pwan.co"* ]] + openssl x509 -in /etc/pki/certmaster-test/testcert.pwan.co.cert -text | grep Signature | grep sha256 + assertTrue "testcert.pwan.co.cert has a sha256 hash" $? + openssl rsa -in /etc/pki/certmaster-test/testcert.pwan.co.pem -check > /dev/null 2>&1 assertTrue "test.pwan.co.pem OK" $? openssl req -text -noout -verify -in /etc/pki/certmaster-test/testcert.pwan.co.csr > /dev/null 2>&1 @@ -199,6 +202,31 @@ test_TestCA_Autosigning() } +test_MD5CA_Attempy() { + + # TODO: Verify attempts to create MD5 certs fail + assertTrue "TODO" false +} + +test_Sha1CA_Autosigning() { + + # TODO: Verify a deprecation warning was issued ? + + certmaster-request --hostname testcert.pwan.co --ca sha1 + openssl x509 -in /etc/pki/certmaster-sha1/testcert.pwan.co.cert -text | grep Signature | grep sha1 + assertTrue "testcert.pwan.co.cert has a sha1 hash" $? + +} + +test_Sha224CA_Autosigning() { + + # TODO: Verify /etc/pki/certmaster-test/testcert.pwan.co.cert is using sha224 + certmaster-request --hostname testcert.pwan.co --ca sha224 + openssl x509 -in /etc/pki/certmaster-sha224/testcert.pwan.co.cert -text | grep Signature | grep sha224 + assertTrue "testcert.pwan.co.cert has a sha224 hash" $? + +} + test_DefaultCA_NonAutosigning() { # Turn on job control, so 'fg' is available