RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1992432 - Add client certificate validation D-Bus API (dependency of cockpit CVE-2021-3698 fix)
Summary: Add client certificate validation D-Bus API (dependency of cockpit CVE-2021-3...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 9
Classification: Red Hat
Component: sssd
Version: 9.0
Hardware: Unspecified
OS: Unspecified
high
high
Target Milestone: beta
: ---
Assignee: Iker Pedrosa
QA Contact: Scott Poore
URL:
Whiteboard: sync-to-jira
Depends On: 2011224
Blocks: CVE-2021-3698 1992620 1998513
TreeView+ depends on / blocked
 
Reported: 2021-08-11 05:21 UTC by Martin Pitt
Modified: 2022-05-17 16:34 UTC (History)
16 users (show)

Fixed In Version: sssd-2.6.2-1.el9
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-05-17 16:00:30 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Github 5911 0 None None None 2021-12-10 08:10:41 UTC
Github SSSD sssd issues 5224 0 None None None 2021-08-11 05:22:52 UTC
Red Hat Issue Tracker RHELPLAN-93176 0 None None None 2021-08-11 05:24:25 UTC
Red Hat Issue Tracker SSSD-3774 0 None None None 2021-10-06 10:17:02 UTC
Red Hat Product Errata RHBA-2022:4015 0 None None None 2022-05-17 16:01:08 UTC

Description Martin Pitt 2021-08-11 05:21:58 UTC
Description of problem:

Cockpit has initial support for client certificate (aka smart card) logins. This is currently only supported for machines joined to IdM (FreeIPA or AD) where you import and compare against the full client certificate with org.freedesktop.sssd.infopipe.Users.FindByCertificate(). There is no further validation of the certificate right now.

We'd like to make this both more robust and also allow this with certmap matchrules. For the latter it's absolutely crucial to ensure that the certificate is signed by an admin-specified CA, plus the usual extra checks (CRL file or OCSP, as configured). It's not strictly necessary for full certificate imports, but it'd be a desirable hardening step anyway.

For that we would like to have a D-Bus API that exposes sssd's cert validation. Right now that's done internally by pam_sss and the like, they apparently do cert validation and cert mapping as two distinct steps. There are reasons why they are separate (@sumit-bose mentioned on the meeting that mapping is done more often and is much cheaper than validation), so it should have a separate API as well. Something like org.freedesktop.sssd.infopipe.Users.ValidateCertificate s → void which gets the certificate PEM and throws a DbusError on failures, or alternatively returns a success/error code.

cockpit could then attempt to use that new API, and if the method does not exist, fall back to the current behaviour or do something more heuristic (like, erroring out when the mapped user is local, as then it's most likely a certmap one), and eventually require the new API.

The most important aspect of this is that this keeps the configuration like pam_cert_db_path, crl_file, ocsp_* etc. in sssd.conf and conf.d. cockpit-tls neither should (too complex) nor could (files are readable for root only) inspect these. It also avoids code duplication, as sssd already has all that validation logic.

As a kind of bonus it would be nice to expose the CA as a property on the InfoPipe object (or a GetCA() method), if it was set in the config. This would allow the server to send the expected CAs (or at least its properties) with the TLS handshake, using gnutls-x509-trust-list-add-cas() or a similar function. This may allow the web browser a more intelligent pre-selection of available certificates. But that's not crucial, and I'm also happy to split that out into a separate issue.


Version-Release number of selected component (if applicable):


sssd-2.5.2-2.el8.x86_64

Comment 3 Martin Pitt 2021-08-27 16:10:15 UTC
Allison is looking into this, to help out the sssd team. It's not that trivial.

Comment 4 Sumit Bose 2021-08-27 17:27:16 UTC
(In reply to Martin Pitt from comment #3)
> Allison is looking into this, to help out the sssd team. It's not that
> trivial.

Hi Martin,

please let me know if this is really urgent for cockpit, in this case I can prepare a patch if we agree on the interface. I wonder if a org.freedesktop.sssd.infopipe.Users.FindByCertificateIfVaild() interface would be more easy for your use case?

bye,
Sumit

Comment 5 Martin Pitt 2021-08-30 04:06:57 UTC
It's not "really urgent", we have a few months to fix this (as we just moved past the 8.5/9.0beta freeze anyway). So let's make sure we have a good design.

Allison and I discussed that a little bit last week. Some notes:

 - We discussed letting cockpit-tls do the actual CA/CRL checks (through GnuTLS API), and only let sssd tell us the cert paths (i.e. parse its configuration). This does not work because (1) cockpit-tls gets involved both too early and also too often, and (2) is not running as root.
 - So we went back to the original proposal of doing the call in cockpit-session (which does not use GnuTLS, and as suid root program we also want to avoid that), and calling out to infopipe.
 - infopipe is single-threaded, so must not block for too long. Hence this new API should *not* do OCSP. It's questionable whether any customer wants to have OCSP in the first place (my gut feeling is "no"), and it is also a big privacy problem if it's an external provider. So for now, *if* OCSP is enabled, let's just return that fact through an extra dict flag in the return value.
 - So a FindByCertificateIfValid(cert: s) -> (username: s, info: a{sv}) API should work well for us; in the initial implementation, the returned info dict can just be empty, but it's a place to inform about OCSP or other steps to be done in the future. However, it is not clear to me yet whether this can be implemented in sssd in a straightforward way.
 - Having a separate ValidateCertificate() which just does the validation, but not the mapping, would work equally well, and perhaps make the API nicer and more orthogonal.

I suggest Allison and you discuss the details directly.

Thanks!

Comment 6 Allison Karlitskaya 2021-08-30 08:23:05 UTC
The main issue is that online (OCSP) checks (as done by the pam module, for example) involve IO and potentially long waits.  In the pam module those are done from the pkcs11 helper, which can block for as long as it wants to (and for which there is a timeout).  If we do that with OpenSSL, then we have the choice between a blocking (forever) call or a "non-blocking" variant which presents an API which might theoretically be possible to wrap in a mainloop, but with a lot of work. It seems like this is probably a bad fit for the infopipe service, which is where we started to get the idea of the client becoming responsible for performing some of the checks.

I do think (due to the architecture of cockpit: our point of contact with SSSD is from a place where we have no crypto library) that the CA and CRL checks absolutely should be performed inside of SSSD.

And maybe also OCSP: that's gonna be a bit of research, though.

Comment 7 Sumit Bose 2021-08-30 08:59:33 UTC
(In reply to Martin Pitt from comment #5)
> It's not "really urgent", we have a few months to fix this (as we just moved
> past the 8.5/9.0beta freeze anyway). So let's make sure we have a good
> design.
> 
> Allison and I discussed that a little bit last week. Some notes:
> 
>  - We discussed letting cockpit-tls do the actual CA/CRL checks (through
> GnuTLS API), and only let sssd tell us the cert paths (i.e. parse its
> configuration). This does not work because (1) cockpit-tls gets involved
> both too early and also too often, and (2) is not running as root.

Hi,

you do not have to be root to call SSSD via DBus, as long as the user is added to the 'allowed_uids' in sssd.conf.

>  - So we went back to the original proposal of doing the call in
> cockpit-session (which does not use GnuTLS, and as suid root program we also
> want to avoid that), and calling out to infopipe.
>  - infopipe is single-threaded, so must not block for too long. Hence this
> new API should *not* do OCSP. It's questionable whether any customer wants
> to have OCSP in the first place (my gut feeling is "no"), and it is also a
> big privacy problem if it's an external provider. So for now, *if* OCSP is
> enabled, let's just return that fact through an extra dict flag in the
> return value.

The validation wouldn't be done inside of the infopipe process, but by the p11_child helper process. So delays during OCSP are not an issue. OCSP is enabled by default if the certificate has the related extension.


>  - So a FindByCertificateIfValid(cert: s) -> (username: s, info: a{sv}) API
> should work well for us; in the initial implementation, the returned info
> dict can just be empty, but it's a place to inform about OCSP or other steps
> to be done in the future. However, it is not clear to me yet whether this
> can be implemented in sssd in a straightforward way.

Since SSSD can handle OCSP I think there is no need for any additional information.

>  - Having a separate ValidateCertificate() which just does the validation,
> but not the mapping, would work equally well, and perhaps make the API nicer
> and more orthogonal.

Whatever works best for you.

bye,
Sumit

> 
> I suggest Allison and you discuss the details directly.
> 
> Thanks!

Comment 8 Sumit Bose 2021-08-30 09:01:27 UTC
(In reply to Allison Karlitskaya from comment #6)
> The main issue is that online (OCSP) checks (as done by the pam module, for
> example) involve IO and potentially long waits.  In the pam module those are
> done from the pkcs11 helper, which can block for as long as it wants to (and
> for which there is a timeout).  If we do that with OpenSSL, then we have the
> choice between a blocking (forever) call or a "non-blocking" variant which
> presents an API which might theoretically be possible to wrap in a mainloop,
> but with a lot of work. It seems like this is probably a bad fit for the
> infopipe service, which is where we started to get the idea of the client
> becoming responsible for performing some of the checks.
> 
> I do think (due to the architecture of cockpit: our point of contact with
> SSSD is from a place where we have no crypto library) that the CA and CRL
> checks absolutely should be performed inside of SSSD.
> 
> And maybe also OCSP: that's gonna be a bit of research, though.

Hi,

see my reply to Martin's questions, doing OCSP in SSSD is not an issue, it's enabled by default.

HTH

bye,
Sumit

Comment 9 Martin Pitt 2021-08-30 10:49:11 UTC
> The validation wouldn't be done inside of the infopipe process, but by the p11_child helper process.

And infopipe handles this asynchronously, so that it doesn't block until the p11_child process finishes? My concern is mostly that infopipe (like all D-Bus servers) must be able to handle other method calls in parallel, even while a long-running one is being handled asynchronously. To clarify, it's *not* a problem if calling FindByCertificateIfValid() takes some time; it is a problem if during that time nothing else can talk to the infopipe service as it's blocked on that method call. This needs to be done with async programming or threads.

Comment 10 Allison Karlitskaya 2021-08-30 13:29:35 UTC
(In reply to Sumit Bose from comment #7)
> The validation wouldn't be done inside of the infopipe process, but by the
> p11_child helper process. So delays during OCSP are not an issue. OCSP is
> enabled by default if the certificate has the related extension.

My understanding from having read the code here is that this process exists to perform a certificate validation against the smartcard via PKCS11 and return the result of that to the PAM module.  In the cockpit case, we don't have the smartcard connected to the machine, but rather receive it as a browser client certificate (which we validate ourselves).  In order to use p11_child as part of this process, we'd need to have a way to tell the PAM module "we've already validated that the user is in possession of the private key for this certificate", and pass the certificate itself in.

That's not currently supported in p11_child, as far as I understand it, but it would be a fascinating idea, because what we're also trying to do is to start a PAM session...

Otherwise, it's going to look like one of:

 1) copy the logic from the PAM module to the infopipe, and make a note to keep the two copies in sync

 2) copy it to a neutral place and restructure the PAM module to use that place

Comment 11 Sumit Bose 2021-08-31 05:48:44 UTC
Hi,

@Martin, infopipe works completely asynchronous, calling a child process and waiting for a reply won't block the main process.

@Allison, p11_child already has the options --verification and --certificate to verify a random certificate given as base64 encoded string on the command line.

As already said, adding this verification to infopipe is not difficult and straight forward. I only need a time frame for planning, basically, do you need this during the next month or is it ok if it happens in the last quarter of this year?

bye,
Sumit

Comment 12 Martin Pitt 2021-08-31 05:55:40 UTC
> infopipe works completely asynchronous

Nice! That will make things much easier indeed.

> ok if it happens in the last quarter of this year?

That's sufficient, due to how RHEL releases align. Thanks!

Comment 15 Sumit Bose 2021-08-31 10:27:32 UTC
(In reply to Martin Pitt from comment #12)
> > infopipe works completely asynchronous
> 
> Nice! That will make things much easier indeed.
> 
> > ok if it happens in the last quarter of this year?
> 
> That's sufficient, due to how RHEL releases align. Thanks!

Hi Martin,

which RHEL release to you have in mind?

bye,
Sumit

Comment 21 Iker Pedrosa 2021-10-29 09:28:21 UTC
Upstream PR: https://github.com/SSSD/sssd/pull/5852

@mpitt can you take a look at the interface that I've proposed in the aforementioned PR? It would be nice to know if it fills your expectations. By the way, if you want to start working on your side of the solution I can provide you with a sssd build that includes the changes.

@sgadekar can you review the test provided in the second commit of the PR? Link: https://github.com/SSSD/sssd/pull/5852/commits/9699a4bd42bfc2490a30fab9ec179d84e38f1688

Comment 22 Martin Pitt 2021-10-29 13:30:47 UTC
Thanks a lot Iker for working on this!

The API is certainly very convenient, I am just not sure about how useful the error message is with a "real" but untrusted certificate. I followed up on https://github.com/SSSD/sssd/pull/5852#pullrequestreview-793030991 , let's discuss the finer details there to keep it in one place?

Comment 23 Alexey Tikhonov 2021-11-09 14:36:39 UTC
Pushed PR: https://github.com/SSSD/sssd/pull/5852

* `master`
    * 50e6070e4784e4a9a01ce26bd08229a07557948a - Tests: ifp interface to validate certificate
    * cf75d897b8ef03fdc471059214e86824f19b1bd1 - ifp: new interface to validate a certificate

Comment 24 shridhar 2021-11-10 20:16:56 UTC
@ipedrosa I've emailed you with the test-results I'm noticing. Please check it.

Comment 28 Martin Pitt 2021-12-07 13:32:49 UTC
I tested this in https://github.com/SSSD/sssd/issues/5224#issuecomment-987917472 ff. This generally works, but there's still two hiccups. The fatal one is that (1) it is impossibly hard to tell from outside if a CA database was configured in sssd (as that doesn't happen by default when joining an IPA domain), and (2) FindByValidCertificate() does not have an usable error code in this case. (2) feels like the much simpler bug, so I filed this as https://github.com/SSSD/sssd/issues/5911 .

Comment 29 Sumit Bose 2021-12-07 17:15:44 UTC
(In reply to Martin Pitt from comment #28)
> I tested this in
> https://github.com/SSSD/sssd/issues/5224#issuecomment-987917472 ff. This
> generally works, but there's still two hiccups. The fatal one is that (1) it
> is impossibly hard to tell from outside if a CA database was configured in
> sssd (as that doesn't happen by default when joining an IPA domain), and (2)

Hi,

I just want to point out that Smartcard authentication is not enabled on IPA clients by default, you have to run a dedicated script to enable Smartcard authentication on IPA servers and clients which then will create the CA certficate file as well.

I'm not sure what would be best with respect to Cockpit, always try to offer Smartcard authentication or only offer it if the system has it enabled as well?

bye,
Sumit



> FindByValidCertificate() does not have an usable error code in this case.
> (2) feels like the much simpler bug, so I filed this as
> https://github.com/SSSD/sssd/issues/5911 .

Comment 30 Martin Pitt 2021-12-07 18:13:30 UTC
Sumit: One has to explicitly enable cert authentication.  So we'll certainly update the documentation to point out that you need to do that "cp /etc/ipa/ca.crt /etc/sssd/pki/sssd_auth_ca_db.pem" step after the "realm join". That should take care of most use cases, it's just another step which is easy to forget/get wrong and then debug.

However, my big concern (the "fatal") is not actually new installs -- these can be taken care of with documentation. But moving from FindByCertificate() to FindByValidCertificate() (as required to solve this CVE) will also affect existing systems, and I'm quite sure that many/most of them will not have a properly configured sssd_auth_ca_db.pem. So for these, auth would stop working on upgrades, without a clear error message.

Comment 32 Martin Pitt 2021-12-10 05:43:31 UTC
I sent https://github.com/cockpit-project/cockpit/pull/16703 which uses this new API. I made it such that I added documentation that admins have to tell sssd about the user certificate with this new version. I'm not sure if we can get away with that, or if it's considered too much of a regression on upgrades (mostly on RHEL) -- but I think I'd like to land this at least upstream and in Fedora, and in RHEL 9. More fine-grained error messages are a possible follow-up for 8.6.

Comment 34 Alexey Tikhonov 2021-12-20 10:09:56 UTC
Pushed PR: https://github.com/SSSD/sssd/pull/5918

* `master`
    * fd0f087ada2f4a59d4b22846d06f1b19fd522e11 - ifp: improve FindByValidCertificate() error
    * 8d54b8c029d276801b323dfe045a155a4311ee49 - man: update ifp options for FindByValidCertificate

Comment 43 errata-xmlrpc 2022-05-17 16:00:30 UTC
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 (new packages: sssd), 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-2022:4015


Note You need to log in before you can comment on or make changes to this bug.