summaryrefslogtreecommitdiffstats
path: root/ipaserver/install/certs.py
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2013-03-14 13:58:27 +0100
committerMartin Kosek <mkosek@redhat.com>2013-04-02 15:28:50 +0200
commit03a2c66eda695ad2d4bfe675fa2902035e6b37f0 (patch)
tree6f497733efb8da696a82730f455ad4b6310bb612 /ipaserver/install/certs.py
parenta03aba5704036e375fab36ed2b7cbbc31adf5411 (diff)
downloadfreeipa-03a2c66eda695ad2d4bfe675fa2902035e6b37f0.tar.gz
freeipa-03a2c66eda695ad2d4bfe675fa2902035e6b37f0.tar.xz
freeipa-03a2c66eda695ad2d4bfe675fa2902035e6b37f0.zip
Support installing with custom SSL certs, without a CA
Design: http://freeipa.org/page/V3/CA-less_install https://fedorahosted.org/freeipa/ticket/3363
Diffstat (limited to 'ipaserver/install/certs.py')
-rw-r--r--ipaserver/install/certs.py60
1 files changed, 54 insertions, 6 deletions
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 6d688b351..81f403df2 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -29,6 +29,8 @@ import base64
from hashlib import sha1
from ConfigParser import RawConfigParser, MissingSectionHeaderError
+from nss import nss
+
from ipapython import dogtag
from ipapython import sysrestore
from ipapython import ipautil
@@ -293,9 +295,11 @@ class NSSDatabase(object):
ipautil.run(args)
except ipautil.CalledProcessError, e:
if e.returncode == 17:
- raise RuntimeError("incorrect password for pkcs#12 file")
+ raise RuntimeError("incorrect password for pkcs#12 file %s" %
+ pkcs12_filename)
else:
- raise RuntimeError("unknown error import pkcs#12 file")
+ raise RuntimeError("unknown error import pkcs#12 file %s" %
+ pkcs12_filename)
def find_root_cert_from_pkcs12(self, pkcs12_fname, passwd_fname=None):
"""Given a PKCS#12 file, try to find any certificates that do
@@ -355,6 +359,53 @@ class NSSDatabase(object):
fd.write(cert)
os.chmod(location, 0444)
+ def import_pem_cert(self, nickname, flags, location):
+ """Import a cert form the given PEM file.
+
+ The file must contain exactly one certificate.
+ """
+ with open(location) as fd:
+ certs = fd.read()
+
+ cert, st = find_cert_from_txt(certs)
+ self.add_single_pem_cert(nickname, flags, cert)
+
+ try:
+ find_cert_from_txt(certs, st)
+ except RuntimeError:
+ pass
+ else:
+ raise ValueError('%s contains more than one certificate')
+
+ def add_single_pem_cert(self, nick, flags, cert):
+ """Import a cert in PEM format"""
+ self.run_certutil(["-A", "-n", nick,
+ "-t", flags,
+ "-a"],
+ stdin=cert)
+
+ def verify_server_cert_validity(self, nickname, hostname):
+ """Verify a certificate is valid for a SSL server with given hostname
+
+ Raises a ValueError if the certificate is invalid.
+ """
+ certdb = cert = None
+ nss.nss_init(self.secdir)
+ try:
+ certdb = nss.get_default_certdb()
+ cert = nss.find_cert_from_nickname(nickname)
+ intended_usage = nss.certificateUsageSSLServer
+ approved_usage = cert.verify_now(certdb, True, intended_usage)
+ if not approved_usage & intended_usage:
+ raise ValueError('invalid for a SSL server')
+ if not cert.verify_hostname(hostname):
+ raise ValueError('invalid for server %s' % hostname)
+ finally:
+ del certdb, cert
+ nss.nss_shutdown()
+
+ return None
+
class CertDB(object):
"""An IPA-server-specific wrapper around NSS
@@ -610,10 +661,7 @@ class CertDB(object):
nick = get_ca_nickname(self.realm)
else:
nick = str(subject_dn)
- self.run_certutil(["-A", "-n", nick,
- "-t", "CT,,C",
- "-a"],
- stdin=cert)
+ self.nssdb.add_single_pem_cert(nick, "CT,,C", cert)
except RuntimeError:
break