summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2014-08-05 09:06:39 +0200
committerPetr Viktorin <pviktori@dhcp-31-13.brq.redhat.com>2014-09-05 13:59:04 +0200
commit6ad8c464a43260f8f58dc262f841c35be35b57b5 (patch)
treed596fb119f94b21a2c01c839a0659b74a4aacf6f /ipaserver
parent418ce870bfbe13cea694a7b862cafe35c703f660 (diff)
downloadfreeipa-6ad8c464a43260f8f58dc262f841c35be35b57b5.tar.gz
freeipa-6ad8c464a43260f8f58dc262f841c35be35b57b5.tar.xz
freeipa-6ad8c464a43260f8f58dc262f841c35be35b57b5.zip
Make CA-less ipa-server-install option --root-ca-file optional.
The CA cert specified by --root-ca-file option must always be the CA cert of the CA which issued the server certificates in the PKCS#12 files. As the cert is not actually user selectable, use CA cert from the PKCS#12 files by default if it is present. Document --root-ca-file in ipa-server-install man page. https://fedorahosted.org/freeipa/ticket/4457 Reviewed-By: Petr Viktorin <pviktori@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/dsinstance.py15
-rw-r--r--ipaserver/install/installutils.py46
-rw-r--r--ipaserver/install/ipa_replica_prepare.py14
-rw-r--r--ipaserver/install/ipa_server_certinstall.py3
4 files changed, 45 insertions, 33 deletions
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 1719df46d..cc1d32709 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -223,14 +223,14 @@ info: IPA V2.0
class DsInstance(service.Service):
def __init__(self, realm_name=None, domain_name=None, dm_password=None,
- fstore=None, cert_nickname='Server-Cert'):
+ fstore=None):
service.Service.__init__(self, "dirsrv",
service_desc="directory server",
dm_password=dm_password,
ldapi=False,
autobind=service.DISABLED
)
- self.nickname = cert_nickname
+ self.nickname = 'Server-Cert'
self.dm_password = dm_password
self.realm = realm_name
self.sub_dict = None
@@ -641,24 +641,23 @@ class DsInstance(service.Service):
raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])
# We only handle one server cert
- nickname = server_certs[0][0]
- self.dercert = dsdb.get_cert_from_db(nickname, pem=False)
+ self.nickname = server_certs[0][0]
+ self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
else:
- nickname = self.nickname
cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base)
# FIXME, need to set this nickname in the RA plugin
cadb.export_ca_cert('ipaCert', False)
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
self.dercert = dsdb.create_server_cert(
- nickname, self.fqdn, cadb)
+ self.nickname, self.fqdn, cadb)
dsdb.create_pin_file()
self.cacert_name = dsdb.cacert_name
if self.ca_is_configured:
dsdb.track_server_cert(
- nickname, self.principal, dsdb.passwd_fname,
+ self.nickname, self.principal, dsdb.passwd_fname,
'restart_dirsrv %s' % self.serverid)
conn = ipaldap.IPAdmin(self.fqdn)
@@ -679,7 +678,7 @@ class DsInstance(service.Service):
DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
objectclass=["top", "nsEncryptionModule"],
cn=["RSA"],
- nsSSLPersonalitySSL=[nickname],
+ nsSSLPersonalitySSL=[self.nickname],
nsSSLToken=["internal (software)"],
nsSSLActivation=["on"],
)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 3b9138fef..e4cf5040f 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -800,8 +800,6 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
This is used for files given to --*_pkcs12 to ipa-server-install and
ipa-replica-prepare.
-
- Return a (server cert name, CA cert names) tuple
"""
pkcs12_filename, pkcs12_passwd = pkcs12_info
root_logger.debug('Checking PKCS#12 certificate %s', pkcs12_filename)
@@ -812,13 +810,18 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
# Import the CA cert first so it has a known nickname
# (if it's present in the PKCS#12 it won't be overwritten)
ca_cert_name = 'The Root CA'
- try:
- nssdb.import_pem_cert(ca_cert_name, "CT,C,C", ca_file)
- except (ValueError, RuntimeError) as e:
- raise ScriptError(str(e))
+ if ca_file:
+ try:
+ nssdb.import_pem_cert(ca_cert_name, "CT,C,C", ca_file)
+ except (ValueError, RuntimeError) as e:
+ raise ScriptError(str(e))
# Import everything in the PKCS#12
- nssdb.import_pkcs12(pkcs12_filename, db_pwd_file.name, pkcs12_passwd)
+ try:
+ nssdb.import_pkcs12(
+ pkcs12_filename, db_pwd_file.name, pkcs12_passwd)
+ except RuntimeError as e:
+ raise ScriptError(str(e))
# Check we have exactly one server cert (one with a private key)
server_certs = nssdb.find_server_certs()
@@ -833,21 +836,23 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
# Check we have the whole cert chain & the CA is in it
trust_chain = nssdb.get_trust_chain(server_cert_name)
- while trust_chain:
- if trust_chain[0] == ca_cert_name:
- break
- trust_chain = trust_chain[1:]
- else:
- raise ScriptError(
- '%s is not signed by %s, or the full certificate chain is not '
- 'present in the PKCS#12 file' % (pkcs12_filename, ca_file))
- if len(trust_chain) != 2:
+ if len(trust_chain) < 2:
+ if ca_file:
+ raise ScriptError(
+ '%s is not signed by %s, or the full certificate chain is '
+ 'not present in the PKCS#12 file' %
+ (pkcs12_filename, ca_file))
+ else:
+ raise ScriptError(
+ 'The full certificate chain is not present in %s' %
+ pkcs12_filename)
+ if ca_file and trust_chain[-2] != ca_cert_name:
raise ScriptError(
- 'trust chain of the server certificate in %s contains %s '
- 'certificates, expected 2' %
- (pkcs12_filename, len(trust_chain)))
+ '%s is not signed by %s' % (pkcs12_filename, ca_file))
+ ca_cert_name = trust_chain[-2]
# Check server validity
+ nssdb.trust_root_cert(ca_cert_name)
try:
nssdb.verify_server_cert_validity(server_cert_name, hostname)
except ValueError as e:
@@ -855,8 +860,7 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
'The server certificate in %s is not valid: %s' %
(pkcs12_filename, e))
- return server_cert_name
-
+ return nssdb.get_cert(ca_cert_name)
@contextmanager
def private_ccache(path=None):
diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index 1099046dd..c8a978dfa 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -139,7 +139,7 @@ class ReplicaPrepare(admintool.AdminTool):
"could not find directory instance: %s" % config_dir)
def check_pkcs12(self, pkcs12_file, pkcs12_pin):
- installutils.check_pkcs12(
+ return installutils.check_pkcs12(
pkcs12_info=(pkcs12_file, pkcs12_pin),
ca_file=CACERT,
hostname=self.replica_fqdn)
@@ -221,7 +221,8 @@ class ReplicaPrepare(admintool.AdminTool):
if options.http_pin is None:
raise admintool.ScriptError(
"%s unlock password required" % options.http_pkcs12)
- self.check_pkcs12(options.http_pkcs12, options.http_pin)
+ http_ca_cert = self.check_pkcs12(
+ options.http_pkcs12, options.http_pin)
if options.dirsrv_pkcs12:
if options.dirsrv_pin is None:
@@ -231,7 +232,8 @@ class ReplicaPrepare(admintool.AdminTool):
if options.dirsrv_pin is None:
raise admintool.ScriptError(
"%s unlock password required" % options.dirsrv_pkcs12)
- self.check_pkcs12(options.dirsrv_pkcs12, options.dirsrv_pin)
+ dirsrv_ca_cert = self.check_pkcs12(
+ options.dirsrv_pkcs12, options.dirsrv_pin)
if options.pkinit_pkcs12:
if options.pkinit_pin is None:
@@ -242,6 +244,12 @@ class ReplicaPrepare(admintool.AdminTool):
raise admintool.ScriptError(
"%s unlock password required" % options.pkinit_pkcs12)
+ if (options.http_pkcs12 and options.dirsrv_pkcs12 and
+ http_ca_cert != dirsrv_ca_cert):
+ raise admintool.ScriptError(
+ "%s and %s are not signed by the same CA certificate" %
+ (options.http_pkcs12, options.dirsrv_pkcs12))
+
if (not ipautil.file_exists(
dogtag.configured_constants().CS_CFG_PATH) and
options.dirsrv_pin is None):
diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
index af5d21a2a..6300a14ae 100644
--- a/ipaserver/install/ipa_server_certinstall.py
+++ b/ipaserver/install/ipa_server_certinstall.py
@@ -154,7 +154,7 @@ class ServerCertInstall(admintool.AdminTool):
os.chown(os.path.join(dirname, 'secmod.db'), 0, pent.pw_gid)
def import_cert(self, dirname, pkcs12_passwd, old_cert, principal, command):
- server_cert = installutils.check_pkcs12(
+ installutils.check_pkcs12(
pkcs12_info=(self.pkcs12_fname, pkcs12_passwd),
ca_file=CACERT,
hostname=api.env.host)
@@ -166,6 +166,7 @@ class ServerCertInstall(admintool.AdminTool):
cdb.delete_cert(old_cert)
cdb.import_pkcs12(self.pkcs12_fname, pkcs12_passwd)
+ server_cert = cdb.find_server_certs()[0][0]
if api.env.enable_ra:
cdb.track_server_cert(server_cert, principal, cdb.passwd_fname,