Bug 1878808
| Summary: | [RFE] dsconf instance security ca-certificate add: Cannot load a certificate bundle | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Directory Server | Reporter: | Graham Leggett <minfrin> | ||||
| Component: | 389-ds-base | Assignee: | mreynolds | ||||
| Status: | CLOSED ERRATA | QA Contact: | LDAP QA Team <idm-ds-qe-bugs> | ||||
| Severity: | medium | Docs Contact: | Evgenia Martynyuk <emartyny> | ||||
| Priority: | high | ||||||
| Version: | 12.1 | CC: | bsmejkal, idm-ds-dev-bugs, jachapma, mreynolds, pasik, progier, sgouvern, spichugi, tbordaz, vashirov | ||||
| Target Milestone: | DS12.1 | Keywords: | FutureFeature, TestCaseProvided, Triaged | ||||
| Target Release: | dirsrv-12.2 | ||||||
| Hardware: | Unspecified | ||||||
| OS: | Unspecified | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | redhat-ds-12-9020020221130212339.1674d57 | Doc Type: | Enhancement | ||||
| Doc Text: |
.Directory Server can now import a certificate bundle
Previously, when you tried to add a certificate bundle by using the `dsconf` or `dsctl` utility, the procedure failed with an error, and the certificate bundle was not imported. Such behavior was caused by the `certutil` utility that could import only one certificate at a time. With this update, Directory Server works around the issue with the `certutil`, and a certificate bundle is added successfully.
|
Story Points: | --- | ||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2023-05-30 09:40:35 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: | |||||||
| Attachments: |
|
||||||
|
Description
Graham Leggett
2020-09-14 14:44:39 UTC
"dsconf security" is just a wrapper for certutil. So if certutl can not do it, then dsconf definitely can not either. There are also certificate tasks using dsctl, does that exhibit the same behavior? Probably but would be good to know:
# dsctl localhost tls import-server-cert ...
No luck: [root@gatekeeper ~]# dsctl gatekeeper tls import-ca /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem usage: dsctl [instance] tls import-ca [-h] cert_path nickname dsctl [instance] tls import-ca: error: the following arguments are required: nickname Adding a nickname means only one cert is imported, all others are ignored: [root@gatekeeper ~]# dsctl gatekeeper tls import-ca /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem test [root@gatekeeper ~]# dsctl gatekeeper tls list-ca test Looks like the missing piece of dsctl and dsconf is to parse each certificate in the incoming file one at a time, and then pass each certificate to NSS. Another option is to fix this is certutil - remove the restriction that only one certificate can be imported at a time. (In reply to Graham Leggett from comment #3) > Looks like the missing piece of dsctl and dsconf is to parse each > certificate in the incoming file one at a time, and then pass each > certificate to NSS. > > Another option is to fix this is certutil - remove the restriction that only > one certificate can be imported at a time. Yeah that should be doable. Changing bug to RFE, and adding acks... related upstream ticket: https://github.com/389ds/389-ds-base/issues/5162 Fixed CLI tools to allow CA certificate PEM file bundles. Automated test passed:
========================================== test session starts ===========================================
platform linux -- Python 3.9.16, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
389-ds-base: 2.2.6-1.module+el9dsrv+17949+63c5b04e
nss: 3.79.0-14.el9_0
nspr: 4.34.0-14.el9_0
openldap: 2.6.2-3.el9
cyrus-sasl: not installed
FIPS: disabled
rootdir: /root/ds/dirsrvtests, configfile: pytest.ini
collected 1 item
dirsrvtests/tests/suites/clu/ca_cert_bundle_test.py::test_ca_cert_bundle PASSED [100%]
=========================================== 1 passed in 38.20s ===========================================
Basic functionality works (loading a CA bundle is successful), but I found minor issues:
[1] Importing the same bundle under a different name is reported as successful, but the certificates are not actually imported:
# dsconf standalone1 security ca-certificate add --file bundle.pem --name CA1 CA2
Successfully added CA certificate (CA1)
Successfully added CA certificate (CA2)
# certutil -d /etc/dirsrv/slapd-standalone1/ -L
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
CA1 CT,,
CA2 CT,,
# dsconf standalone1 security ca-certificate add --file bundle.pem --name CA1 CA2
Error: Certificate already exists with the same name (CA1)
# dsconf standalone1 security ca-certificate add --file bundle.pem --name CA3 CA4
Successfully added CA certificate (CA3)
Successfully added CA certificate (CA4)
# certutil -d /etc/dirsrv/slapd-standalone1/ -L
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
CA1 CT,,
CA2 CT,,
This issue comes from certutil, that doesn't report a non-zero exit code if the certificate is already in the database.
# /usr/bin/certutil -A -d /etc/dirsrv/slapd-standalone1 -n CA999 -t CT,, -i bundle.pem-1 -a -f /etc/dirsrv/slapd-standalone1/pwdfile.txt
# echo $?
0
We should check if the certificate with the given name was imported. And if it's missing from the list of nicknames in the database and certutil's exit code was 0, print a better message.
[2] dsconf doesn't cleanup temporary files from the current working directory:
# ls -1 bundle*
bundle.pem
bundle.pem-0
bundle.pem-1
[3] dsconf doesn't check if the imported certificate is actually a CA certificate.
If a bundle contains a server certificate, it is also imported with CT,, trust flags.
We can check for key usage (cert sign) and basic constraints (CA) in the cert, and import it as CA only if the check is successful.
I think [1] and [2] should be fixed, and [3] is up for debate, because it might introduce additional dependency (python-cryptography) that won't be useful in 99% cases.
Moving to ASSIGNED.
As for [3] not sure how to tell if a cert is "server" or "ca" cert. I always thought it was just how you assign the trust flags that differentiated between the two (but I could definitely be wrong). The tooling assumes the user knows how they want to use the cert (server vs CA). Created attachment 1943332 [details]
check_cert.py
It can be done something like this using python-cryptography.
If we do not want to add new dependency, we can also check for the "Usages: Certificate Signing" in certutil -d ... -n certName output But before taking a decision we have to double check (I am not sure that the certificate extensions are mandatory (especially when the "verify cert" flag is disabled.) Maybe we should rather open a warning window and asking the user if we should proceed or not Automated test passed: ============================================================= test session starts ============================================================= platform linux -- Python 3.9.16, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3 cachedir: .pytest_cache 389-ds-base: 2.2.7-1.module+el9dsrv+18376+e226feec nss: 3.79.0-18.el9_1 nspr: 4.34.0-18.el9_1 openldap: 2.6.2-3.el9 cyrus-sasl: not installed FIPS: disabled rootdir: /root/ds/dirsrvtests, configfile: pytest.ini collected 1 item dirsrvtests/tests/suites/clu/ca_cert_bundle_test.py::test_ca_cert_bundle PASSED [100%] ============================================================= 1 passed in 16.64s ============================================================= Additional test cases from https://bugzilla.redhat.com/show_bug.cgi?id=1878808#c11 [1] Importing the same bundle under a different name is reported as successful, but the certificates are not actually imported: [root@localhost ds]# certutil -d /etc/dirsrv/slapd-standalone1/ -L Certificate Nickname Trust Attributes SSL,S/MIME,JAR/XPI CA_CERT_1 CT,, CA_CERT_2 CT,, [root@localhost ds]# dsconf standalone1 security ca-certificate add --file /tmp/ca-bundle.pem --name CA3 CA4 Successfully added CA certificate (CA3) Successfully added CA certificate (CA4) [root@localhost ds]# certutil -d /etc/dirsrv/slapd-standalone1/ -L Certificate Nickname Trust Attributes SSL,S/MIME,JAR/XPI CA_CERT_1 CT,, CA_CERT_2 CT,, [2] Fixed - temporary files are not present anymore. [3] Fixed - Non-CA certificates are not imported: # dsconf standalone1 security ca-certificate add --file Server-Cert.crt --name Server Error: Certificate (Server) is not a CA certificate Since [1] is not fixed, moving to ASSIGNED. > [1] Importing the same bundle under a different name is reported as successful, but the certificates are not actually imported:
> [root@localhost ds]# certutil -d /etc/dirsrv/slapd-standalone1/ -L
I think this is an issue with certutil, where if the certificate(s) itself are the same as what's in NSS db it treats it as a no-op (idempotent sort of). Only if the certs in the bundle are different than what's in the NSS db will it perform the op. This might require a lot of hoops to jump through to try and work around certutil's behavior...
I'm facing another issue with CA certificates. I have a self-signed certificate generated by openssl: openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -out my.crt -keyout my.key I'm trying to import it, but it fails with an error message: # dsconf localhost security ca-certificate add --name=myca --file=my.crt Error: No <ObjectIdentifier(oid=2.5.29.15, name=keyUsage)> extension was found My CA cert doesn't have key usage specified, but has a basic constraint to be used as a CA cert. Turns out some of the CA certs from the system CA bundle also don't have key usage specified, and they fail to be imported. Maybe we shouldn't be that strict or provide a "force" option to import the CA cert anyway. RN texted prepared in the DocText field. Moving to SME review RN text was reviewed by Viktor, moving to a peer review RN text was reviewed by a peer and release pending. Thanks, Masha! Build tested: 389-ds-base-2.2.7-3.module+el9dsrv+18864+4949f8c5.x86_64 Issue in https://bugzilla.redhat.com/show_bug.cgi?id=1878808#c22 was addressed: # openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -out my.crt -keyout my.key # dsconf localhost security ca-certificate add --name=myca --file=my.crt Successfully added CA certificate (myca) # certutil -d /etc/dirsrv/slapd-localhost/ -L | grep myca myca CT,, Marking as VERIFIED. Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (redhat-ds:12 bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2023:3344 |