Bug 1543335

Summary: rhel6 ipa-client fails to retrieve right CA certificates, particularly when external CA installed.
Product: Red Hat Enterprise Linux 6 Reporter: German Parente <gparente>
Component: ipaAssignee: IPA Maintainers <ipa-maint>
Status: CLOSED NOTABUG QA Contact: ipa-qe <ipa-qe>
Severity: high Docs Contact:
Priority: unspecified    
Version: 6.10CC: gparente, pvoborni, rcritten, tmihinto, tscherf
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-02-12 16:25:19 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description German Parente 2018-02-08 09:43:05 UTC
Description of problem:

we have some issues with RHEL6 clients to retrieve the CA certificates, when external CA installed but not only.

In fact, the RHEL6 clients are retrieving from LDAP only one CA certificate, the one stored in:

cn=CAcert,cn=ipa,cn=etc,<dc=domain,dc=name>

here we have only ONE ca certificate. When we have external CA, we need to retrieve the full CA chain.

We see in the code of RHEL6 client:

==============================================
def get_ca_cert_from_ldap(url, basedn, ca_file):
    '''
    Retrieve th CA cert from the LDAP server by binding to the
    server with GSSAPI using the current Kerberos credentials.
    Write the retrieved cert into the CACERT file.

    Raises errors.NoCertificateError if cert is not found.
    Raises errors.NetworkError if LDAP connection can't be established.
    Raises errors.LDAPError for any other generic LDAP error.
    Raises errors.OnlyOneValueAllowed if more than one cert is found.
    Raises errors.FileError if unable to write cert.
    '''

    ca_cert_attr = 'cAcertificate;binary'
    dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), basedn)

    SASL_GSSAPI = ldap.sasl.sasl({},'GSSAPI')

    root_logger.debug("trying to retrieve CA cert via LDAP from %s", url)
...
    if len(result) != 1:
        raise errors.OnlyOneValueAllowed(attr=ca_cert_attr)

    attrs = result[0][1]

==============================================

And it's expecting to find only one certificate.

This fails in two scenarios:

1) external CA. We have a full chain and the chain is not stored anymore in cn=CAcert but rather in cn=certificates

2) in case of certificate expiration and resubmition, it seems this entry (cn=CAcert,...) is not updated. So, the expired certificate is still stored there.

What is the consequence ? 

ipa-client-install in RHEL6 could, in some cases be successfully installed, since the certificate is retrieved and stored. But a ssl authentication will not work.

And if we re-install the client, without deleting the /etc/ipa/ca.crt we won't be able to do a right authentication at re running ipa-client-install


In RHEL7, we have changed completely the retrieval by using this subtree:

===================
    config_dn = DN(('cn', 'ipa'), ('cn', 'etc'), base_dn)
    container_dn = DN(('cn', 'certificates'), config_dn)
    try:
===================


Version-Release number of selected component (if applicable): ipa-client-3.0.0-51.el6.x86_64


How reproducible: always


Steps to Reproduce: install external CA + RHEL6 client.

Actual results:

only the root CA of the chain is retrieved. But it could be an expired version of the root CA.


Expected results:

The full chain has to be retrieved and stored as in RHEL7.



Additional info:

The workaround is to manually copy the /etc/ipa/ca.crt certificate from the master to the client before install. But this is NOT always working. Why ?

Because the certificate retrieved from LDAP will be compared with the first certificate in /etc/ipa/ca.crt (of the chain). So, we could have this issue, for instance:

====================================================
The CA cert available from the IPA server does not match the
local certificate available at /etc/ipa/ca.crt
Existing CA cert:
    Subject:     CN=mycacertificate
    Issuer:      CN=mycacertificate
    Valid From:  Wed Feb 07 14:24:45 2018 UTC
    Valid Until: Mon May 07 14:24:45 2018 UTC

Retrieved CA cert:
    Subject:     CN=Certificate Authority,O=PARENTE.LOCAL
    Issuer:      CN=mycacertificate
    Valid From:  Wed Feb 07 14:24:45 2018 UTC
    Valid Until: Mon May 07 14:24:45 2018 UTC

Do you want to replace the local certificate with the CA
certificate retrieved from the IPA server? [yes]: no
Cannot obtain CA certificate
'ldap://newserver.parente.local' doesn't have a certificate.
======================================================

So, the real workaround is to copy the /etc/ipa/ca.crt from the master but change the order of the certificates to make the first one in the file, the one that matches with the one stored in ldap under cn=caCert.

Comment 2 Rob Crittenden 2018-02-08 16:38:18 UTC
Does it not succeed if you answer yes at the prompt when providing a local copy of the chain?

Comment 5 German Parente 2018-02-08 17:07:43 UTC
In fact, even if install succeeds, there's only one certificate of the chain is downloaded. So, the install remains broken (in external ca).

Comment 6 Rob Crittenden 2018-02-08 20:19:32 UTC
I don't understand. If you provide then chain then it should continue to use that chain if you answer yes.