mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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
This commit is contained in:
@@ -94,7 +94,7 @@ def subject_callback(option, opt_str, value, parser):
|
|||||||
raise ValueError('invalid attribute: %s' % dn[x][0].attr.lower())
|
raise ValueError('invalid attribute: %s' % dn[x][0].attr.lower())
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
raise ValueError('Invalid subject base format: %s' % str(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():
|
def parse_options():
|
||||||
# Guaranteed to give a random 200k range below the 2G mark (uint32_t limit)
|
# Guaranteed to give a random 200k range below the 2G mark (uint32_t limit)
|
||||||
|
@@ -71,27 +71,45 @@ def load_certificate(data, datatype=PEM, dbdir=None):
|
|||||||
data = base64.b64decode(data)
|
data = base64.b64decode(data)
|
||||||
|
|
||||||
if dbdir is None:
|
if dbdir is None:
|
||||||
if api.env.in_tree:
|
if 'in_tree' in api.env:
|
||||||
dbdir = api.env.dot_ipa + os.sep + 'alias'
|
if api.env.in_tree:
|
||||||
|
dbdir = api.env.dot_ipa + os.sep + 'alias'
|
||||||
|
else:
|
||||||
|
dbdir = "/etc/httpd/alias"
|
||||||
|
nss.nss_init(dbdir)
|
||||||
else:
|
else:
|
||||||
dbdir = "/etc/httpd/alias"
|
nss.nss_init_nodb()
|
||||||
|
else:
|
||||||
|
nss.nss_init(dbdir)
|
||||||
|
|
||||||
|
|
||||||
nss.nss_init(dbdir)
|
|
||||||
return nss.Certificate(buffer(data))
|
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.
|
Load an X509.3 certificate and get the subject.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nsscert = load_certificate(certificate, datatype)
|
nsscert = load_certificate(certificate, datatype, dbdir)
|
||||||
return nsscert.subject
|
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.
|
Return the decimal value of the serial number.
|
||||||
"""
|
"""
|
||||||
nsscert = load_certificate(certificate, datatype)
|
nsscert = load_certificate(certificate, datatype, dbdir)
|
||||||
return nsscert.serial_number
|
return nsscert.serial_number
|
||||||
|
|
||||||
def make_pem(data):
|
def make_pem(data):
|
||||||
|
@@ -39,6 +39,7 @@ import socket
|
|||||||
from ipapython import dogtag
|
from ipapython import dogtag
|
||||||
from ipapython.certdb import get_ca_nickname
|
from ipapython.certdb import get_ca_nickname
|
||||||
from ipalib import pkcs10, x509
|
from ipalib import pkcs10, x509
|
||||||
|
from ipalib.dn import DN
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from nss.error import NSPRError
|
from nss.error import NSPRError
|
||||||
@@ -919,7 +920,7 @@ class CAInstance(service.Service):
|
|||||||
# makes openssl throw up.
|
# makes openssl throw up.
|
||||||
data = base64.b64decode(chain)
|
data = base64.b64decode(chain)
|
||||||
|
|
||||||
(certs, stderr, returncode) = ipautil.run(["/usr/bin/openssl",
|
(certlist, stderr, returncode) = ipautil.run(["/usr/bin/openssl",
|
||||||
"pkcs7",
|
"pkcs7",
|
||||||
"-inform",
|
"-inform",
|
||||||
"DER",
|
"DER",
|
||||||
@@ -932,18 +933,20 @@ class CAInstance(service.Service):
|
|||||||
st = 1
|
st = 1
|
||||||
en = 0
|
en = 0
|
||||||
subid = 0
|
subid = 0
|
||||||
|
normalized_base = str(DN(self.subject_base))
|
||||||
while st > 0:
|
while st > 0:
|
||||||
st = certs.find('-----BEGIN', en)
|
st = certlist.find('-----BEGIN', en)
|
||||||
en = certs.find('-----END', en+1)
|
en = certlist.find('-----END', en+1)
|
||||||
if st > 0:
|
if st > 0:
|
||||||
try:
|
try:
|
||||||
(chain_fd, chain_name) = tempfile.mkstemp()
|
(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)
|
os.close(chain_fd)
|
||||||
if subid == 0:
|
(rdn, subject) = certs.get_cert_nickname(certlist[st:en+25])
|
||||||
nick = self.canickname
|
if subject.lower() == ('CN=Certificate Authority,%s' % normalized_base).lower():
|
||||||
|
nick = get_ca_nickname(self.realm)
|
||||||
else:
|
else:
|
||||||
nick = "%s sub %d" % (self.canickname, subid)
|
nick = subject
|
||||||
self.__run_certutil(
|
self.__run_certutil(
|
||||||
['-A', '-t', 'CT,C,C', '-n', nick, '-a',
|
['-A', '-t', 'CT,C,C', '-n', nick, '-a',
|
||||||
'-i', chain_name]
|
'-i', chain_name]
|
||||||
|
@@ -38,6 +38,7 @@ from ipalib import pkcs10
|
|||||||
from ConfigParser import RawConfigParser, MissingSectionHeaderError
|
from ConfigParser import RawConfigParser, MissingSectionHeaderError
|
||||||
import service
|
import service
|
||||||
from ipalib import x509
|
from ipalib import x509
|
||||||
|
from ipalib.dn import DN
|
||||||
from ipalib.errors import CertificateOperationError
|
from ipalib.errors import CertificateOperationError
|
||||||
|
|
||||||
from nss.error import NSPRError
|
from nss.error import NSPRError
|
||||||
@@ -82,6 +83,20 @@ def find_cert_from_txt(cert, start=0):
|
|||||||
cert = cert[s:e]
|
cert = cert[s:e]
|
||||||
return (cert, 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):
|
def next_serial(serial_file=CA_SERIALNO):
|
||||||
"""
|
"""
|
||||||
Get the next serial number if we're using an NSS-based self-signed CA.
|
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()
|
certs = fd.read()
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
|
normalized_base = str(DN(self.subject_base))
|
||||||
st = 0
|
st = 0
|
||||||
subid=0
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
(cert, st) = find_cert_from_txt(certs, st)
|
(cert, st) = find_cert_from_txt(certs, st)
|
||||||
if subid == 0:
|
(nick, subject) = get_cert_nickname(cert)
|
||||||
nick = self.cacert_name
|
if subject.lower() == ('CN=Certificate Authority,%s' % normalized_base).lower():
|
||||||
|
nick = get_ca_nickname(self.realm)
|
||||||
else:
|
else:
|
||||||
nick = "%s sub %d" % (self.cacert_name, subid)
|
nick = subject
|
||||||
subid = subid + 1
|
|
||||||
self.run_certutil(["-A", "-n", nick,
|
self.run_certutil(["-A", "-n", nick,
|
||||||
"-t", "CT,,C",
|
"-t", "CT,,C",
|
||||||
"-a"],
|
"-a"],
|
||||||
|
Reference in New Issue
Block a user