summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2011-07-11 17:39:30 -0400
committerRob Crittenden <rcritten@redhat.com>2011-07-17 22:14:24 -0400
commit2f650b60a4ce9c9b19a64b21ebe3051668efb4af (patch)
treed6280d7277eae4ab726a4c1a201130f9ea4f3a4d
parent038089a0c9160221d17796b8d6fd6e4f1fb67850 (diff)
downloadfreeipa-2f650b60a4ce9c9b19a64b21ebe3051668efb4af.tar.gz
freeipa-2f650b60a4ce9c9b19a64b21ebe3051668efb4af.tar.xz
freeipa-2f650b60a4ce9c9b19a64b21ebe3051668efb4af.zip
Use information from the certificate subject when setting the NSS nickname.
There were a few places in the code where certs were loaded from a PKCS#7 file or a chain in a PEM file. The certificates got very generic nicknames. We can instead pull the subject from the certificate and use that as the nickname. https://fedorahosted.org/freeipa/ticket/1141
-rwxr-xr-xinstall/tools/ipa-server-install2
-rw-r--r--ipalib/x509.py34
-rw-r--r--ipaserver/install/cainstance.py17
-rw-r--r--ipaserver/install/certs.py25
4 files changed, 57 insertions, 21 deletions
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index ca0d139b6..316fc67f7 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -94,7 +94,7 @@ def subject_callback(option, opt_str, value, parser):
raise ValueError('invalid attribute: %s' % dn[x][0].attr.lower())
except ValueError, e:
raise ValueError('Invalid subject base format: %s' % str(e))
- parser.values.subject = value
+ parser.values.subject = str(dn) # may as well normalize it
def parse_options():
# Guaranteed to give a random 200k range below the 2G mark (uint32_t limit)
diff --git a/ipalib/x509.py b/ipalib/x509.py
index 77d6aabf4..e757e1d1f 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -71,27 +71,45 @@ def load_certificate(data, datatype=PEM, dbdir=None):
data = base64.b64decode(data)
if dbdir is None:
- if api.env.in_tree:
- dbdir = api.env.dot_ipa + os.sep + 'alias'
+ if 'in_tree' in api.env:
+ if api.env.in_tree:
+ dbdir = api.env.dot_ipa + os.sep + 'alias'
+ else:
+ dbdir = "/etc/httpd/alias"
+ nss.nss_init(dbdir)
else:
- dbdir = "/etc/httpd/alias"
+ nss.nss_init_nodb()
+ else:
+ nss.nss_init(dbdir)
+
- nss.nss_init(dbdir)
return nss.Certificate(buffer(data))
-def get_subject(certificate, datatype=PEM):
+def load_certificate_from_file(filename, dbdir=None):
+ """
+ Load a certificate from a PEM file.
+
+ Returns a nss.Certificate type
+ """
+ fd = open(filename, 'r')
+ data = fd.read()
+ fd.close()
+
+ return load_certificate(file, PEM, dbdir)
+
+def get_subject(certificate, datatype=PEM, dbdir=None):
"""
Load an X509.3 certificate and get the subject.
"""
- nsscert = load_certificate(certificate, datatype)
+ nsscert = load_certificate(certificate, datatype, dbdir)
return nsscert.subject
-def get_serial_number(certificate, datatype=PEM):
+def get_serial_number(certificate, datatype=PEM, dbdir=None):
"""
Return the decimal value of the serial number.
"""
- nsscert = load_certificate(certificate, datatype)
+ nsscert = load_certificate(certificate, datatype, dbdir)
return nsscert.serial_number
def make_pem(data):
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index fbc566a28..121b651bc 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -39,6 +39,7 @@ import socket
from ipapython import dogtag
from ipapython.certdb import get_ca_nickname
from ipalib import pkcs10, x509
+from ipalib.dn import DN
import subprocess
from nss.error import NSPRError
@@ -919,7 +920,7 @@ class CAInstance(service.Service):
# makes openssl throw up.
data = base64.b64decode(chain)
- (certs, stderr, returncode) = ipautil.run(["/usr/bin/openssl",
+ (certlist, stderr, returncode) = ipautil.run(["/usr/bin/openssl",
"pkcs7",
"-inform",
"DER",
@@ -932,18 +933,20 @@ class CAInstance(service.Service):
st = 1
en = 0
subid = 0
+ normalized_base = str(DN(self.subject_base))
while st > 0:
- st = certs.find('-----BEGIN', en)
- en = certs.find('-----END', en+1)
+ st = certlist.find('-----BEGIN', en)
+ en = certlist.find('-----END', en+1)
if st > 0:
try:
(chain_fd, chain_name) = tempfile.mkstemp()
- os.write(chain_fd, certs[st:en+25])
+ os.write(chain_fd, certlist[st:en+25])
os.close(chain_fd)
- if subid == 0:
- nick = self.canickname
+ (rdn, subject) = certs.get_cert_nickname(certlist[st:en+25])
+ if subject.lower() == ('CN=Certificate Authority,%s' % normalized_base).lower():
+ nick = get_ca_nickname(self.realm)
else:
- nick = "%s sub %d" % (self.canickname, subid)
+ nick = subject
self.__run_certutil(
['-A', '-t', 'CT,C,C', '-n', nick, '-a',
'-i', chain_name]
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index ebe654dd3..522d3f576 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -38,6 +38,7 @@ from ipalib import pkcs10
from ConfigParser import RawConfigParser, MissingSectionHeaderError
import service
from ipalib import x509
+from ipalib.dn import DN
from ipalib.errors import CertificateOperationError
from nss.error import NSPRError
@@ -82,6 +83,20 @@ def find_cert_from_txt(cert, start=0):
cert = cert[s:e]
return (cert, e)
+def get_cert_nickname(cert):
+ """
+ Using the subject from cert come up with a nickname suitable
+ for NSS. The caller can decide whether to use just the RDN
+ or the whole subject.
+
+ Returns a tuple of (rdn, subject)
+ """
+ nsscert = x509.load_certificate(cert)
+ subject = str(nsscert.subject)
+ dn = DN(subject)
+
+ return (str(dn[0]), str(dn))
+
def next_serial(serial_file=CA_SERIALNO):
"""
Get the next serial number if we're using an NSS-based self-signed CA.
@@ -415,16 +430,16 @@ class CertDB(object):
certs = fd.read()
fd.close()
+ normalized_base = str(DN(self.subject_base))
st = 0
- subid=0
while True:
try:
(cert, st) = find_cert_from_txt(certs, st)
- if subid == 0:
- nick = self.cacert_name
+ (nick, subject) = get_cert_nickname(cert)
+ if subject.lower() == ('CN=Certificate Authority,%s' % normalized_base).lower():
+ nick = get_ca_nickname(self.realm)
else:
- nick = "%s sub %d" % (self.cacert_name, subid)
- subid = subid + 1
+ nick = subject
self.run_certutil(["-A", "-n", nick,
"-t", "CT,,C",
"-a"],