Unify storing certificates in LDAP

Recent certificate refactoring left the system in a state where
the certificates are somewhere converted to DER format, somewhere
directly sent to ipaldap as IPACertificate objects. The latter
is the desirable way, make sure it's the one commonly used.

https://pagure.io/freeipa/issue/4985

Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
This commit is contained in:
Stanislav Laznicka 2017-08-23 15:23:43 +02:00 committed by Pavel Vomacka
parent 2151ab02c1
commit 31142ead83
8 changed files with 21 additions and 34 deletions

View File

@ -68,7 +68,7 @@ def init_ca_entry(entry, cert, nickname, trusted, ext_key_usage):
entry['ipaCertSubject'] = [subject] entry['ipaCertSubject'] = [subject]
entry['ipaCertIssuerSerial'] = [issuer_serial] entry['ipaCertIssuerSerial'] = [issuer_serial]
entry['ipaPublicKey'] = [public_key] entry['ipaPublicKey'] = [public_key]
entry['cACertificate;binary'] = [cert.public_bytes(x509.Encoding.DER)] entry['cACertificate;binary'] = [cert]
if trusted is not None: if trusted is not None:
entry['ipaKeyTrust'] = ['trusted' if trusted else 'distrusted'] entry['ipaKeyTrust'] = ['trusted' if trusted else 'distrusted']
@ -84,16 +84,15 @@ def update_compat_ca(ldap, base_dn, cert):
Update the CA certificate in cn=CAcert,cn=ipa,cn=etc,SUFFIX. Update the CA certificate in cn=CAcert,cn=ipa,cn=etc,SUFFIX.
""" """
dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), base_dn) dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), base_dn)
dercert = cert.public_bytes(x509.Encoding.DER)
try: try:
entry = ldap.get_entry(dn, attrs_list=['cACertificate;binary']) entry = ldap.get_entry(dn, attrs_list=['cACertificate;binary'])
entry.single_value['cACertificate;binary'] = dercert entry.single_value['cACertificate;binary'] = cert
ldap.update_entry(entry) ldap.update_entry(entry)
except errors.NotFound: except errors.NotFound:
entry = ldap.make_entry(dn) entry = ldap.make_entry(dn)
entry['objectClass'] = ['nsContainer', 'pkiCA'] entry['objectClass'] = ['nsContainer', 'pkiCA']
entry.single_value['cn'] = 'CAcert' entry.single_value['cn'] = 'CAcert'
entry.single_value['cACertificate;binary'] = dercert entry.single_value['cACertificate;binary'] = cert
ldap.add_entry(entry) ldap.add_entry(entry)
except errors.EmptyModlist: except errors.EmptyModlist:
pass pass
@ -129,7 +128,7 @@ def clean_old_config(ldap, base_dn, dn, config_ipa, config_compat):
pass pass
def add_ca_cert(ldap, base_dn, dercert, nickname, trusted=None, def add_ca_cert(ldap, base_dn, cert, nickname, trusted=None,
ext_key_usage=None, config_ipa=False, config_compat=False): ext_key_usage=None, config_ipa=False, config_compat=False):
""" """
Add new entry for a CA certificate to the certificate store. Add new entry for a CA certificate to the certificate store.
@ -139,7 +138,7 @@ def add_ca_cert(ldap, base_dn, dercert, nickname, trusted=None,
dn = DN(('cn', nickname), container_dn) dn = DN(('cn', nickname), container_dn)
entry = ldap.make_entry(dn) entry = ldap.make_entry(dn)
init_ca_entry(entry, dercert, nickname, trusted, ext_key_usage) init_ca_entry(entry, cert, nickname, trusted, ext_key_usage)
if config_ipa: if config_ipa:
entry.setdefault('ipaConfigString', []).append('ipaCA') entry.setdefault('ipaConfigString', []).append('ipaCA')
@ -147,7 +146,7 @@ def add_ca_cert(ldap, base_dn, dercert, nickname, trusted=None,
entry.setdefault('ipaConfigString', []).append('compatCA') entry.setdefault('ipaConfigString', []).append('compatCA')
if config_compat: if config_compat:
update_compat_ca(ldap, base_dn, dercert) update_compat_ca(ldap, base_dn, cert)
ldap.add_entry(entry) ldap.add_entry(entry)
clean_old_config(ldap, base_dn, dn, config_ipa, config_compat) clean_old_config(ldap, base_dn, dn, config_ipa, config_compat)
@ -182,8 +181,7 @@ def update_ca_cert(ldap, base_dn, cert, trusted=None, ext_key_usage=None,
if entry.single_value['ipaPublicKey'] != public_key: if entry.single_value['ipaPublicKey'] != public_key:
raise ValueError("subject public key info mismatch") raise ValueError("subject public key info mismatch")
entry['ipaCertIssuerSerial'].append(issuer_serial) entry['ipaCertIssuerSerial'].append(issuer_serial)
entry['cACertificate;binary'].append( entry['cACertificate;binary'].append(cert)
cert.public_bytes(x509.Encoding.DER))
# Update key trust # Update key trust
if trusted is not None: if trusted is not None:

View File

@ -40,7 +40,6 @@ import six
# pylint: disable=import-error # pylint: disable=import-error
from six.moves.configparser import RawConfigParser from six.moves.configparser import RawConfigParser
# pylint: enable=import-error # pylint: enable=import-error
from cryptography.hazmat.primitives import serialization
from ipalib import api from ipalib import api
from ipalib import x509 from ipalib import x509
@ -730,9 +729,6 @@ class CAInstance(DogtagInstance):
the appropriate groups for accessing CA services. the appropriate groups for accessing CA services.
""" """
# get RA certificate
cert_data = self.ra_cert.public_bytes(serialization.Encoding.DER)
# connect to CA database # connect to CA database
conn = ldap2.ldap2(api) conn = ldap2.ldap2(api)
conn.connect(autobind=True) conn.connect(autobind=True)
@ -748,7 +744,7 @@ class CAInstance(DogtagInstance):
cn=["ipara"], cn=["ipara"],
usertype=["agentType"], usertype=["agentType"],
userstate=["1"], userstate=["1"],
userCertificate=[cert_data], userCertificate=[self.ra_cert],
description=['2;%s;%s;%s' % ( description=['2;%s;%s;%s' % (
self.ra_cert.serial_number, self.ra_cert.serial_number,
DN(self.ca_subject), DN(self.ca_subject),

View File

@ -275,17 +275,16 @@ class CACertManage(admintool.AdminTool):
dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'), dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
new_cert_der = new_cert.public_bytes(x509.Encoding.DER)
try: try:
entry = conn.get_entry(dn, ['usercertificate']) entry = conn.get_entry(dn, ['usercertificate'])
entry['usercertificate'] = [new_cert_der] entry['usercertificate'] = [new_cert]
conn.update_entry(entry) conn.update_entry(entry)
except errors.NotFound: except errors.NotFound:
entry = conn.make_entry( entry = conn.make_entry(
dn, dn,
objectclass=['top', 'pkiuser', 'nscontainer'], objectclass=['top', 'pkiuser', 'nscontainer'],
cn=[self.cert_nickname], cn=[self.cert_nickname],
usercertificate=[new_cert_der]) usercertificate=[new_cert])
conn.add_entry(entry) conn.add_entry(entry)
except errors.EmptyModlist: except errors.EmptyModlist:
pass pass

View File

@ -306,7 +306,6 @@ class KRAInstance(DogtagInstance):
# get RA agent certificate # get RA agent certificate
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM) cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
cert_data = cert.public_bytes(x509.Encoding.DER)
# connect to KRA database # connect to KRA database
conn = ldap2.ldap2(api) conn = ldap2.ldap2(api)
@ -322,7 +321,7 @@ class KRAInstance(DogtagInstance):
sn=["IPA KRA User"], sn=["IPA KRA User"],
cn=["IPA KRA User"], cn=["IPA KRA User"],
usertype=["undefined"], usertype=["undefined"],
userCertificate=[cert_data], userCertificate=[cert],
description=['2;%s;%s;%s' % ( description=['2;%s;%s;%s' % (
cert.serial_number, cert.serial_number,
DN(self.subject), DN(self.subject),

View File

@ -22,7 +22,7 @@ import logging
from ipalib.install import certstore from ipalib.install import certstore
from ipaplatform.paths import paths from ipaplatform.paths import paths
from ipaserver.install import certs from ipaserver.install import certs
from ipalib import Registry, errors, x509 from ipalib import Registry, errors
from ipalib import Updater from ipalib import Updater
from ipapython import certdb from ipapython import certdb
from ipapython.dn import DN from ipapython.dn import DN
@ -90,7 +90,6 @@ class update_upload_cacrt(Updater):
pass pass
if ca_cert: if ca_cert:
dercert = ca_cert.public_bytes(x509.Encoding.DER)
dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
self.api.env.basedn) self.api.env.basedn)
try: try:
@ -99,11 +98,11 @@ class update_upload_cacrt(Updater):
entry = ldap.make_entry(dn) entry = ldap.make_entry(dn)
entry['objectclass'] = ['nsContainer', 'pkiCA'] entry['objectclass'] = ['nsContainer', 'pkiCA']
entry.single_value['cn'] = 'CAcert' entry.single_value['cn'] = 'CAcert'
entry.single_value['cACertificate;binary'] = dercert entry.single_value['cACertificate;binary'] = ca_cert
ldap.add_entry(entry) ldap.add_entry(entry)
else: else:
if b'' in entry['cACertificate;binary']: if b'' in entry['cACertificate;binary']:
entry.single_value['cACertificate;binary'] = dercert entry.single_value['cACertificate;binary'] = ca_cert
ldap.update_entry(entry) ldap.update_entry(entry)
return False, [] return False, []

View File

@ -32,7 +32,7 @@ from ipalib.install import certstore, sysrestore
from ipapython import ipautil from ipapython import ipautil
from ipapython.dn import DN from ipapython.dn import DN
from ipapython import kerberos from ipapython import kerberos
from ipalib import api, errors, x509 from ipalib import api, errors
from ipaplatform import services from ipaplatform import services
from ipaplatform.paths import paths from ipaplatform.paths import paths
@ -370,8 +370,7 @@ class Service(object):
dn = DN(('krbprincipalname', self.principal), ('cn', 'services'), dn = DN(('krbprincipalname', self.principal), ('cn', 'services'),
('cn', 'accounts'), self.suffix) ('cn', 'accounts'), self.suffix)
entry = api.Backend.ldap2.get_entry(dn) entry = api.Backend.ldap2.get_entry(dn)
entry.setdefault('userCertificate', []).append( entry.setdefault('userCertificate', []).append(self.cert)
self.cert.public_bytes(x509.Encoding.DER))
try: try:
api.Backend.ldap2.update_entry(entry) api.Backend.ldap2.update_entry(entry)
except Exception as e: except Exception as e:

View File

@ -27,7 +27,6 @@ import dns.resolver
import six import six
from ipalib import api, errors, util from ipalib import api, errors, util
from ipalib.x509 import Encoding as x509_Encoding
from ipalib import messages from ipalib import messages
from ipalib import Str, Flag from ipalib import Str, Flag
from ipalib.parameters import Principal, Certificate from ipalib.parameters import Principal, Certificate
@ -902,9 +901,9 @@ class host_mod(LDAPUpdate):
except errors.NotFound: except errors.NotFound:
self.obj.handle_not_found(*keys) self.obj.handle_not_found(*keys)
old_certs = entry_attrs_old.get('usercertificate', []) old_certs = entry_attrs_old.get('usercertificate', [])
removed_certs_der = set(old_certs) - set(certs) removed_certs = set(old_certs) - set(certs)
for der in removed_certs_der: for cert in removed_certs:
rm_certs = api.Command.cert_find(certificate=der)['result'] rm_certs = api.Command.cert_find(certificate=cert)['result']
revoke_certs(rm_certs) revoke_certs(rm_certs)
if certs: if certs:
@ -1340,8 +1339,7 @@ class host_remove_cert(LDAPRemoveAttributeViaOption):
assert isinstance(dn, DN) assert isinstance(dn, DN)
for cert in options.get('usercertificate', []): for cert in options.get('usercertificate', []):
revoke_certs(api.Command.cert_find( revoke_certs(api.Command.cert_find(certificate=cert)['result'])
certificate=cert.public_bytes(x509_Encoding.DER))['result'])
return dn return dn

View File

@ -983,8 +983,7 @@ class service_remove_cert(LDAPRemoveAttributeViaOption):
assert isinstance(dn, DN) assert isinstance(dn, DN)
for cert in options.get('usercertificate', []): for cert in options.get('usercertificate', []):
revoke_certs(api.Command.cert_find( revoke_certs(api.Command.cert_find(certificate=cert)['result'])
certificate=cert.public_bytes(x509.Encoding.DER))['result'])
return dn return dn