Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 1960763 - Cannot set explicit GnuTLS priority to allow DTLSv1.0
Summary: Cannot set explicit GnuTLS priority to allow DTLSv1.0
Keywords:
Status: ON_QA
Alias: None
Product: Fedora
Classification: Fedora
Component: crypto-policies
Version: 33
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Red Hat Crypto Team
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-05-14 19:09 UTC by David Woodhouse
Modified: 2021-06-19 01:08 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description David Woodhouse 2021-05-14 19:09:54 UTC
OpenConnect is an open client for various SSL VPN protocols, many of which use DTLS. Many vendors use old versions of the DTLS protocol — the worst offender being Cisco AnyConnect, which has a pre-v1.0 version of DTLS which we specifically *added* to OpenSSL and GnuTLS for the purpose of supporting OpenConnect.

Users *need* to access their VPNs. If we don't support this in OpenConnect, they'll have to fall back to using the awful third-party proprietary clients that their vendor ships, with their own out of date crypto libraries.

It makes sense for things like DTLSv1.0 to be disabled by *default* so that applications don't accidentally use them. I approve of that. But the implementation we now have in Fedora seems to be attempting to *forbid* the older protocols, so that even when we *explicitly* set the GnuTLS prio string to be *exactly* what we need, it doesn't work.

See https://gitlab.com/openconnect/openconnect/-/issues/243 for example.

There are workarounds — like deinitialising GnuTLS, calling setenv() to change GNUTLS_SYSTEM_PRIORITY_FILE to /dev/null, and reinitialising GnuTLS again. It's not like you can *actually* ban us from doing these things; all you do is make it hard for us to do it *sanely*, using the supported and well-tested system library.

We already have to implement raw packet handling for ESP packets; assembling a DTLS packet isn't that much harder. The sequence number handling and replay protection in GnuTLS is *my* code anyway, lifted from OpenConnect to replace what GnuTLS had before. And I've already implemented the basic DTLSv1.0 handshake to implement an interop test and make sure OpenSSL remains compatible with the Cisco variant.

I do not think that the intended outcome of the crypto-policies package is "force Dave to roll his own crypto protocols instead of using the libraries that the system provides". But I don't see any *other* outcome from force-disabling these protocols.

Disable them by default, by all means. But when getting them back is just a setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null") away, marking them as *disabled* just seems entirely pointless and counterproductive. Please don't do that.

Comment 1 David Woodhouse 2021-05-14 19:14:36 UTC
Let me try that penultimate sentence again...

Disable them by default, by all means, But when getting them back is just a setenv() away, marking them as *forbidden* just seems entirely pointless and counterproductive.

Comment 2 Alexander Sosedkin 2021-05-14 19:26:24 UTC
Hello, David, many thanks for raising this topic.

We're uncomfortable aware that the current model of crypto-policies and gnutls interaction
that uses hard-disabling might not be ideal.
Feel free to check out https://gitlab.com/gnutls/gnutls/-/issues/1172 for more context or join the discussion.


Meanwhile, I find your ways of overriding the limitation in question rather invasive.
I'd like to clarify with you what kinds of solutions/workarounds you would deem acceptable for your case.

Have you tried re-enabling TLSv1 system-wide through a custom subpolicy?
Would that solve your problem?
Fedora 35 crypto-policies would likely allow limiting this change to just gnutls, would that be enough?
Or is the request specifically about the applications themselves re-enabling it through priority strings,
and you don't want to settle for anything wider than per-process?
I tend to interpret your report as the request-for-the-latter, but I'd like to set this straight.

Comment 3 Daniel Lenski 2021-05-14 19:44:04 UTC
Hi Alexander,

> Meanwhile, I find your ways of overriding the limitation in question rather invasive.

Overriding the limitation by setting the system policy path to /dev/null, and reinitializing the crypto library, that was my “innovation” (https://gitlab.com/openconnect/openconnect/blob/master/gnutls.c#L79-89). Basically arrived at out of desperation, due to not finding a more reliable way to do this.

> I'd like to clarify with you what kinds of solutions/workarounds you would deem acceptable for your case.

My opinion is that there needs to be either a system-wide or crypto-library-specific function: yes_really_disable_minimum_crypto_policy_so_I_can_connect_to_an_old_crappy_server().

If “naming and shaming” is desired, perhaps this function could mark the system as “insecure” (sort of like kernel tainting).

> you don't want to settle for anything wider than per-process?

We don't actually *want* to be using DTLS 0.9 or 3DES or whatever in OpenConnect. Bypassing the minimum crypto policy is much more secure if it can be done on a per-process basis.

As I wrote in https://gitlab.com/openconnect/openconnect/-/issues/243, which David linked to above:

> [The lack of a straightforward way to disable system-wide crypto policies] is encouraging open source software to reimplement old crypto, or vend in old versions of libraries. Not good for encouraging reuse of well-maintained, well-implemented crypto libraries.

Comment 4 David Woodhouse 2021-05-14 20:10:45 UTC
Hi Alexander, thanks for the prompt response.

I'm open to any solution which lets it work.

OpenConnect does have its own crypto @OPENCONNECT crypto policy and uses that, but my understanding is that it can only do those things which a GnuTLS priority string can do 

When there is a system-wide absolute disable for DTLSv1, GnuTLS reports an error when we try to set the priority string enabling only DTLSv1.

On my own system In have re-enabled DTLSv1 system-wide, but that isn't a solution for the general case. Even if I could ship a file in the Fedora OpenConnect package which does so, I don't think that would be the right approach.

Comment 5 David Woodhouse 2021-05-15 07:35:18 UTC
> My opinion is that there needs to be either a system-wide or crypto-library-specific function:
> yes_really_disable_minimum_crypto_policy_so_I_can_connect_to_an_old_crappy_server()

But as I noted in our own GitLab issue, there already *is* precisely such a function. That's what the priority strings do: let us use protocols and ciphersuites which are disabled by default in the @NORMAL policy.

We *do* use that, consistently and explicitly.

And Fedora just started making it *fail*.

I am more than happy to show nasty warnings to users that their commercial VPN is using out of date crypto, and require an explicitnclick-through to connect, much like an "untrusted certificate" warning. But after that, I do need a way to make it *work*, preferably without requiring the system admin to make changes which allow it for *every* application in the system.

Comment 6 Alexander Sosedkin 2021-05-15 11:28:07 UTC
> OpenConnect does have its own crypto @OPENCONNECT crypto policy and uses that, but my understanding is that it can only do those things which a GnuTLS priority string can do

Where can I take a look at it? It's not something that's part of fedora-crypto-policies.

By the way, listing the possible options, maybe we can make openconnect yet another crypto-policies backend?
This way we could have `protocol@openconnect = DTLS0.9+ DTLS1.0+` subpolicy,
and make the reenabling happen per-protocol.

Comment 7 Daniel Lenski 2021-05-15 19:57:40 UTC
> > My opinion is that there needs to be either a system-wide or crypto-library-specific function:
> > yes_really_disable_minimum_crypto_policy_so_I_can_connect_to_an_old_crappy_server()
> 
> But as I noted in our own GitLab issue, there already *is* precisely such a function. That's what the priority strings do: let us use protocols and ciphersuites which are disabled by default in the @NORMAL policy.

I think we're getting a little wrapped up in definitional issues here.

Yes, there is a mechanism that we expected WOULD accomplish this (explicit inclusion of disabled-by-default protocols in priority strings).

But no, this mechanism does not work reliably anymore. Because system crypto policies.

So… do we need a *new* mechanism to accomplish this reliably? I think so.

> I am more than happy to show nasty warnings to users that their commercial VPN is using out of date crypto, and require an explicitnclick-through to connect, much like an "untrusted certificate" warning. But after that, I do need a way to make it *work*, preferably without requiring the system admin to make changes which allow it for *every* application in the system.

100% this.

Comment 8 Daniel Lenski 2021-05-15 20:08:01 UTC
> By the way, listing the possible options, maybe we can make openconnect yet another crypto-policies backend?
> This way we could have `protocol@openconnect = DTLS0.9+ DTLS1.0+` subpolicy,
> and make the reenabling happen per-protocol.

To be clear, we would also have to do `3DES+ RC4+ MD5+ TLS1.0+ HMAC-SHA1+ MD5-SIGNED-CERTS+` and possibly even `SSL3.0+` (🤢) to support all of the ancient, unpatched VPN servers that are still out there and in use, with no possibility of the end users to fix them. It'd be a rogues' gallery of bad crypto.

This would mean relying on the OpenConnect application/library not to use those algorithms except when explicitly enabled. I'm fine with that, myself.

Comment 9 Simo Sorce 2021-05-17 16:42:00 UTC
It would be nice if the *default* configuration of the package would be consistent with the system-wide crypto-policies.
And if something fails due to that it would be fine to document how to re-enable broken stuff either via setting LEGACY system-wide policy, or (even better) per-application policy.

Other than that, as long as the crypto library does have support for the protocol you should definitely be able to use it, once you jump through the hoops of explicitly enabling it.

Comment 10 Luk Claes 2021-05-17 16:59:35 UTC
I think being able to set a per-application policy is the actual question. If that is already possible, what steps need to be taken to do that?

Comment 11 Alexander Sosedkin 2021-05-17 18:19:53 UTC
A per-backend policy will be possible soon (already merged upstream, "scoped policies").
To make use of that, crypto-policies must be extended with yet another backend to generate yet another configuration file, and the application in question will have to be patched to use this file. Then it will be possible to add directives to (sub)policies which affect this backend only.

I'm not entirely sure what you mean by per-application policy, though I'm open to suggestions, especially if they'll also cover how is this going to work.

Comment 12 David Woodhouse 2021-05-17 19:20:08 UTC
> It would be nice if the *default* configuration of the package would be consistent with the system-wide crypto-policies.

I'm 100% up for that.

Give me a nice explicit error code returned from GnuTLS: GNUTLS_E_SYSTEM_POLICY_VIOLATION. I'll handle it much like I do invalid server certs: give the user a click-through to accept it anyway, which these days is hidden behind an 'I really know what I'm doing' and can be disabled in the VPN client provisioning too. Then let me know how to proceed anyway, which I understand isn't implemented yet.

Then when I *try* DTLSv1.2 and the server downgrades to DTLSv1.0, I can accept it at runtime and continue, just as I do for bad certs.

Comment 13 Daniel Lenski 2021-05-17 19:50:48 UTC
> Give me a nice explicit error code returned from GnuTLS: GNUTLS_E_SYSTEM_POLICY_VIOLATION.

I like this idea a lot too.

In order to resolve the issue fully for OpenConnect, the changes we are hoping for are…

1. An error code that indicates that a connection could not be established specifically because it violates a system crypto policy (called GNUTLS_E_SYSTEM_POLICY_VIOLATION, or something like that)

2. Having determined that a system crypto policy is the reason we can't connect, and having determined that the end user truly intends to override that policy… a reliable mechanism to bypass/override the system crypto policy for the current process.

If that's right, then I think we should create this as a new GnuTLS issue.

Comment 14 David Woodhouse 2021-05-17 20:30:20 UTC
In the meantime I think the only viable option for the Fedora OpenConnect package is to set SYSTEM_GNUTLS_PRIORITY_FILE to point to /dev/null as soon as possible during init, and in the case of libopenconnect being used from other processes as with KDE Plasma-NM, to hope that libgnutls hasn't already been initialised before we get there.

Once the system policy stuff has been properly thought through and fully implemented, we'll be happy to use it and comply. But until it's complete, there's not a lot we can do except try to escape the breakage.

Comment 15 Alexander Sosedkin 2021-05-25 16:50:16 UTC
I recognize your request to enable custom algorithms as valid and I currently see 3 ways out of this:

1) Quick-and-dirty one: set SYSTEM_GNUTLS_PRIORITY_FILE as specified in comment 14, make it explicit to the user.
   No modification to crypto-policies or gnutls is required,
   but I'm not thrilled by this hack and probably neither are you.

2) Implement a separate openconnect backend in some way, generating the right config just for it.
   requires a change in crypto-policies.
   I have zero experience with openconnect, but I can probably work on it
   if I have the technical requirements laid out, specifically:
   a) what must the resulting config files be for DEFAULT
   b) which modifications of interest should result in which config changes
   c) how to lint the resulting files in an automated manner
   Requires modifying both crypto-policies (new backend) and openconnect (config location)

3) Wait until gnutls implements soft-disabling with the same granularity as hard-disabling,
   propose switching crypto-policies to use soft-disabling,
   if it's accepted, switch crypto-policies to use soft-disabling
   and then modifications through priority strings should start working again.
   Even if that switch-over happens, that's definitely not Fedora 34 timeframe, maybe even not 35.

Are there any other good options I've overlooked?
Is option 2 viable?

Comment 16 David Woodhouse 2021-06-11 13:21:50 UTC
(In reply to Alexander Sosedkin from comment #6)
> > OpenConnect does have its own crypto @OPENCONNECT crypto policy and uses that, but my understanding is that it can only do those things which a GnuTLS priority string can do
> 
> Where can I take a look at it? It's not something that's part of
> fedora-crypto-policies.

Er... good question. I've never really paid too much attention. Nikos added it to the Fedora openconnect package in
https://src.fedoraproject.org/rpms/openconnect/c/f834f4de5f7bd9ff517c6ce7cc11885aebaffa20?branch=rawhide
and I've always kind of *assumed* that it matched up with something on the crypto-policies side.

Comment 17 David Woodhouse 2021-06-11 13:33:41 UTC
(In reply to Alexander Sosedkin from comment #15)
> I recognize your request to enable custom algorithms as valid and I
> currently see 3 ways out of this:
> 
> 1) Quick-and-dirty one: set SYSTEM_GNUTLS_PRIORITY_FILE as specified in
> comment 14, make it explicit to the user.
>    No modification to crypto-policies or gnutls is required,
>    but I'm not thrilled by this hack and probably neither are you.
> 
> 2) Implement a separate openconnect backend in some way, generating the
> right config just for it.
>    requires a change in crypto-policies.
>    I have zero experience with openconnect, but I can probably work on it
>    if I have the technical requirements laid out, specifically:
>    a) what must the resulting config files be for DEFAULT
>    b) which modifications of interest should result in which config changes
>    c) how to lint the resulting files in an automated manner
>    Requires modifying both crypto-policies (new backend) and openconnect
> (config location)
> 
> 3) Wait until gnutls implements soft-disabling with the same granularity as
> hard-disabling,
>    propose switching crypto-policies to use soft-disabling,
>    if it's accepted, switch crypto-policies to use soft-disabling
>    and then modifications through priority strings should start working
> again.
>    Even if that switch-over happens, that's definitely not Fedora 34
> timeframe, maybe even not 35.
> 
> Are there any other good options I've overlooked?
> Is option 2 viable?

I'm not stunningly keen on option 2 because I actually *want* to use the standard system policy by default.
I'm *happy* to tell users that their crappy proprietary VPN server is using legacy insecure crypto, and that they should switch to ocserv :)

So I don't really want a *separate* policy for openconnect.

All I really need is that *after* I've warned the user about their crappy server, I give them a way to actually go ahead and connect anyway. Just as I give them a way to connect even when their SSL certificate isn't trusted, etc.

Because otherwise, we're just pushing them back to their crappy proprietary Linux clients which are even *worse*.

So I think I need to go with option 1 for now. I'll fix the Fedora build of openconnect just to unconditionally set GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null at startup.
You're right; I'm not thrilled by that hack, but it's necessary. 

With the benefit of hindsight, we can perhaps recognise that your #3 ought to have been called out as a requirement before this feature was ever shipped in Fedora, but it's too late for that now. I look forward to it being implemented, so I can remove the nasty setenv hack.

Comment 18 David Woodhouse 2021-06-11 13:43:03 UTC
(In reply to Daniel Lenski from comment #13)
> > Give me a nice explicit error code returned from GnuTLS: GNUTLS_E_SYSTEM_POLICY_VIOLATION.
> 
> I like this idea a lot too.
> 
> In order to resolve the issue fully for OpenConnect, the changes we are
> hoping for are…
> 
> 1. An error code that indicates that a connection could not be established
> specifically because it violates a system crypto policy (called
> GNUTLS_E_SYSTEM_POLICY_VIOLATION, or something like that)
> 
> 2. Having determined that a system crypto policy is the reason we can't
> connect, and having determined that the end user truly intends to override
> that policy… a reliable mechanism to bypass/override the system crypto
> policy for the current process.
> 
> If that's right, then I think we should create this as a new GnuTLS issue.

I don't know, I quite like the idea of hooking this into the certificate validation.

"Server has untrusted certificate"
"Server's certificate is only signed with SHA1"
"Server's certificate is fine, but it would only agree to talk AES128-SHA"
"Server is using DTLSv1.0 instead of DTLSv1.2"

All of those are good reasons to abort the connection, but we *also* need to carefully give users a way to connect anyway.

Comment 19 Fedora Update System 2021-06-12 18:43:25 UTC
FEDORA-2021-45ce34c43d has been submitted as an update to Fedora 34. https://bodhi.fedoraproject.org/updates/FEDORA-2021-45ce34c43d

Comment 20 Fedora Update System 2021-06-13 01:03:53 UTC
FEDORA-2021-45ce34c43d has been pushed to the Fedora 34 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2021-45ce34c43d`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2021-45ce34c43d

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 21 David Woodhouse 2021-06-15 12:56:53 UTC
Hm, this isn't sufficient. I have a user whose Cisco server will *only* accept DTLSv1.2 connections with the non-AEAD ciphersuites like AES256-SHA, but I can't make that work even when I override GNUTLS_SYSTEM_PRIORITY_FILE:


$ GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null gnutls-cli --priority NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-CBC:+SHA1:+RSA -u localhost:443
Processed 189 CA certificate(s).
Resolving 'localhost:443'...
Connecting to '127.0.0.1:443'...
Error in priorities: No or insufficient priorities were set.

Comment 22 David Woodhouse 2021-06-15 13:33:03 UTC
Ah, that one's different and can be handled in client. Apparently we need to add +SIGN-RSA-SHA1 (or just +SIGN-ALL).

Comment 23 Fedora Update System 2021-06-19 01:08:46 UTC
FEDORA-2021-45ce34c43d has been pushed to the Fedora 34 stable repository.
If problem still persists, please make note of it in this bug report.


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