Skip to content

Commit

Permalink
Unify storing certificates in LDAP
Browse files Browse the repository at this point in the history
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
  • Loading branch information
stlaz committed Aug 23, 2017
1 parent 928374c commit 9f3562b
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 34 deletions.
16 changes: 7 additions & 9 deletions ipalib/install/certstore.py
Expand Up @@ -68,7 +68,7 @@ def init_ca_entry(entry, cert, nickname, trusted, ext_key_usage):
entry['ipaCertSubject'] = [subject]
entry['ipaCertIssuerSerial'] = [issuer_serial]
entry['ipaPublicKey'] = [public_key]
entry['cACertificate;binary'] = [cert.public_bytes(x509.Encoding.DER)]
entry['cACertificate;binary'] = [cert]

if trusted is not None:
entry['ipaKeyTrust'] = ['trusted' if trusted else 'distrusted']
Expand All @@ -84,16 +84,15 @@ def update_compat_ca(ldap, base_dn, cert):
Update the CA certificate in cn=CAcert,cn=ipa,cn=etc,SUFFIX.
"""
dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), base_dn)
dercert = cert.public_bytes(x509.Encoding.DER)
try:
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)
except errors.NotFound:
entry = ldap.make_entry(dn)
entry['objectClass'] = ['nsContainer', 'pkiCA']
entry.single_value['cn'] = 'CAcert'
entry.single_value['cACertificate;binary'] = dercert
entry.single_value['cACertificate;binary'] = cert
ldap.add_entry(entry)
except errors.EmptyModlist:
pass
Expand Down Expand Up @@ -129,7 +128,7 @@ def clean_old_config(ldap, base_dn, dn, config_ipa, config_compat):
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):
"""
Add new entry for a CA certificate to the certificate store.
Expand All @@ -139,15 +138,15 @@ def add_ca_cert(ldap, base_dn, dercert, nickname, trusted=None,
dn = DN(('cn', nickname), container_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:
entry.setdefault('ipaConfigString', []).append('ipaCA')
if config_compat:
entry.setdefault('ipaConfigString', []).append('compatCA')

if config_compat:
update_compat_ca(ldap, base_dn, dercert)
update_compat_ca(ldap, base_dn, cert)

ldap.add_entry(entry)
clean_old_config(ldap, base_dn, dn, config_ipa, config_compat)
Expand Down Expand Up @@ -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:
raise ValueError("subject public key info mismatch")
entry['ipaCertIssuerSerial'].append(issuer_serial)
entry['cACertificate;binary'].append(
cert.public_bytes(x509.Encoding.DER))
entry['cACertificate;binary'].append(cert)

# Update key trust
if trusted is not None:
Expand Down
6 changes: 1 addition & 5 deletions ipaserver/install/cainstance.py
Expand Up @@ -40,7 +40,6 @@
# pylint: disable=import-error
from six.moves.configparser import RawConfigParser
# pylint: enable=import-error
from cryptography.hazmat.primitives import serialization

from ipalib import api
from ipalib import x509
Expand Down Expand Up @@ -730,9 +729,6 @@ def __create_ca_agent(self):
the appropriate groups for accessing CA services.
"""

# get RA certificate
cert_data = self.ra_cert.public_bytes(serialization.Encoding.DER)

# connect to CA database
conn = ldap2.ldap2(api)
conn.connect(autobind=True)
Expand All @@ -748,7 +744,7 @@ def __create_ca_agent(self):
cn=["ipara"],
usertype=["agentType"],
userstate=["1"],
userCertificate=[cert_data],
userCertificate=[self.ra_cert],
description=['2;%s;%s;%s' % (
self.ra_cert.serial_number,
DN(self.ca_subject),
Expand Down
5 changes: 2 additions & 3 deletions ipaserver/install/ipa_cacert_manage.py
Expand Up @@ -275,17 +275,16 @@ def renew_external_step_2(self, ca, old_cert):
dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)

new_cert_der = new_cert.public_bytes(x509.Encoding.DER)
try:
entry = conn.get_entry(dn, ['usercertificate'])
entry['usercertificate'] = [new_cert_der]
entry['usercertificate'] = [new_cert]
conn.update_entry(entry)
except errors.NotFound:
entry = conn.make_entry(
dn,
objectclass=['top', 'pkiuser', 'nscontainer'],
cn=[self.cert_nickname],
usercertificate=[new_cert_der])
usercertificate=[new_cert])
conn.add_entry(entry)
except errors.EmptyModlist:
pass
Expand Down
3 changes: 1 addition & 2 deletions ipaserver/install/krainstance.py
Expand Up @@ -306,7 +306,6 @@ def __create_kra_agent(self):

# get RA agent certificate
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
cert_data = cert.public_bytes(x509.Encoding.DER)

# connect to KRA database
conn = ldap2.ldap2(api)
Expand All @@ -322,7 +321,7 @@ def __create_kra_agent(self):
sn=["IPA KRA User"],
cn=["IPA KRA User"],
usertype=["undefined"],
userCertificate=[cert_data],
userCertificate=[cert],
description=['2;%s;%s;%s' % (
cert.serial_number,
DN(self.subject),
Expand Down
7 changes: 3 additions & 4 deletions ipaserver/install/plugins/upload_cacrt.py
Expand Up @@ -22,7 +22,7 @@
from ipalib.install import certstore
from ipaplatform.paths import paths
from ipaserver.install import certs
from ipalib import Registry, errors, x509
from ipalib import Registry, errors
from ipalib import Updater
from ipapython import certdb
from ipapython.dn import DN
Expand Down Expand Up @@ -90,7 +90,6 @@ def execute(self, **options):
pass

if ca_cert:
dercert = ca_cert.public_bytes(x509.Encoding.DER)
dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
self.api.env.basedn)
try:
Expand All @@ -99,11 +98,11 @@ def execute(self, **options):
entry = ldap.make_entry(dn)
entry['objectclass'] = ['nsContainer', 'pkiCA']
entry.single_value['cn'] = 'CAcert'
entry.single_value['cACertificate;binary'] = dercert
entry.single_value['cACertificate;binary'] = ca_cert
ldap.add_entry(entry)
else:
if b'' in entry['cACertificate;binary']:
entry.single_value['cACertificate;binary'] = dercert
entry.single_value['cACertificate;binary'] = ca_cert
ldap.update_entry(entry)

return False, []
5 changes: 2 additions & 3 deletions ipaserver/install/service.py
Expand Up @@ -32,7 +32,7 @@
from ipapython import ipautil
from ipapython.dn import DN
from ipapython import kerberos
from ipalib import api, errors, x509
from ipalib import api, errors
from ipaplatform import services
from ipaplatform.paths import paths

Expand Down Expand Up @@ -370,8 +370,7 @@ def add_cert_to_service(self):
dn = DN(('krbprincipalname', self.principal), ('cn', 'services'),
('cn', 'accounts'), self.suffix)
entry = api.Backend.ldap2.get_entry(dn)
entry.setdefault('userCertificate', []).append(
self.cert.public_bytes(x509.Encoding.DER))
entry.setdefault('userCertificate', []).append(self.cert)
try:
api.Backend.ldap2.update_entry(entry)
except Exception as e:
Expand Down
10 changes: 4 additions & 6 deletions ipaserver/plugins/host.py
Expand Up @@ -27,7 +27,6 @@
import six

from ipalib import api, errors, util
from ipalib.x509 import Encoding as x509_Encoding
from ipalib import messages
from ipalib import Str, Flag
from ipalib.parameters import Principal, Certificate
Expand Down Expand Up @@ -902,9 +901,9 @@ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
except errors.NotFound:
self.obj.handle_not_found(*keys)
old_certs = entry_attrs_old.get('usercertificate', [])
removed_certs_der = set(old_certs) - set(certs)
for der in removed_certs_der:
rm_certs = api.Command.cert_find(certificate=der)['result']
removed_certs = set(old_certs) - set(certs)
for cert in removed_certs:
rm_certs = api.Command.cert_find(certificate=cert)['result']
revoke_certs(rm_certs)

if certs:
Expand Down Expand Up @@ -1340,8 +1339,7 @@ def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)

for cert in options.get('usercertificate', []):
revoke_certs(api.Command.cert_find(
certificate=cert.public_bytes(x509_Encoding.DER))['result'])
revoke_certs(api.Command.cert_find(certificate=cert)['result'])

return dn

Expand Down
3 changes: 1 addition & 2 deletions ipaserver/plugins/service.py
Expand Up @@ -983,8 +983,7 @@ def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)

for cert in options.get('usercertificate', []):
revoke_certs(api.Command.cert_find(
certificate=cert.public_bytes(x509.Encoding.DER))['result'])
revoke_certs(api.Command.cert_find(certificate=cert)['result'])

return dn

Expand Down

0 comments on commit 9f3562b

Please sign in to comment.