From 0c4d7dabf3e3642451ecaac7837f08011ac772dd Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Sep 30 2014 06:51:21 +0000 Subject: Do stricter validation of CA certificates Every CA certificate must have non-empty subject and basic constraints extension with the CA flag set. https://fedorahosted.org/freeipa/ticket/4477 Reviewed-By: Petr Viktorin --- diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 82d8290..55feb65 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -490,6 +490,10 @@ class NSSDatabase(object): try: certdb = nss.get_default_certdb() cert = nss.find_cert_from_nickname(nickname) + if not cert.subject: + raise ValueError("has empty subject") + if not cert.is_ca_cert(): + raise ValueError("not a CA certificate") intended_usage = nss.certificateUsageSSLCA try: approved_usage = cert.verify_now(certdb, True, intended_usage) diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index 6a7fd05..1acc623 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -215,8 +215,6 @@ class CACertManage(admintool.AdminTool): #pylint: enable=E1101 nss_cert = x509.load_certificate_from_file(cert_file.name) - if not nss_cert.is_ca_cert(): - raise admintool.ScriptError("Not a CA certificate") if nss_cert.subject != subject: raise admintool.ScriptError("Subject name mismatch") #pylint: disable=E1101 @@ -319,8 +317,6 @@ class CACertManage(admintool.AdminTool): "Can't open \"%s\": %s" % (cert_filename, e)) except (TypeError, NSPRError), e: raise admintool.ScriptError("Not a valid certificate: %s" % e) - if not nss_cert.is_ca_cert(): - raise admintool.ScriptError("Not a CA certificate") subject = nss_cert.subject cert = nss_cert.der_data finally: @@ -328,6 +324,17 @@ class CACertManage(admintool.AdminTool): nickname = options.nickname or str(subject) + with certs.NSSDatabase() as tmpdb: + pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) + tmpdb.create_db(pw.name) + tmpdb.add_cert(cert, nickname, 'C,,') + + try: + tmpdb.verify_ca_cert_validity(nickname) + except ValueError, e: + raise admintool.ScriptError( + "Not a valid CA certificate: %s" % e) + trust_flags = options.trust_flags if ((set(trust_flags) - set(',CPTcgpuw')) or len(trust_flags.split(',')) != 3):