Applying system-wide crypto policies to crypto/tls

363 views
Skip to first unread message

Derek Parker

unread,
Jun 16, 2020, 2:43:42 PM6/16/20
to golang-dev
I wanted to open the discussion on this topic here regarding the usage of a configuration file to control the behavior of the crypto/tls stack.

(Please note this is just a discussion on the feature without an actual proposal. The hope being the discussion going favorably and resulting in a more concrete proposal)

Some Linux distributions (RHEL, Fedora, Ubuntu) offer a way to set system-wide crypto policies to ensure that all applications using crypto adhere to the same security settings. The end goal would be to support something like this: https://access.redhat.com/articles/3666211.
The intention would be that the configuration would be applied without any code changes for users.

I wanted to submit this to get the opinion of core maintainers and the community for such a feature.

Levi Corcoran

unread,
Jun 26, 2020, 3:47:02 PM6/26/20
to golang-dev
This could certainly simplify compliance audits, and may obviate the need to maintain forks in situations where third-party modules don't expose TLS configs to enable enforcing cipher limitations or other crypto policies.  I'd be curious to see a more detailed implementation proposal (presumably any explicit TLS config in code would only be allowed to restrict policy further than the system-wide policy, but wouldn't be entirely ignored) - but at a high level count this as a +1 for community interest.

Filippo Valsorda

unread,
Jun 29, 2020, 11:53:30 AM6/29/20
to Derek Parker, golang-dev, Levi Corcoran
I don't think this can be discussed at such a high level: I can imagine implementations at different levels of complexity and have no idea what's the simplest solution that would still meet the requirements.  Without needing to go into a full proposal, can you share some details on what exactly would be configurable, how you imagine forward compatibility (i.e., how does a policy written for Go 1.14 apply to Go 1.16 which has new features), and what mechanism would be used to define the policy (e.g., an environment variable)?

To be upfront, this is the kind of complexity that I have seen cause significant drag and issues in other cryptography implementations, so I am very skeptical of implementing it in Go. For example, it makes it hard to test packages with a full array of possible policies, and puts the burden on the application to tolerate working with different "versions" of the standard library, which defeats the goal of the Go 1 compatibility promise.

--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/7e9cf909-178b-4f97-b090-ea57279602b6o%40googlegroups.com.

depa...@redhat.com

unread,
Aug 31, 2020, 12:48:34 PM8/31/20
to golang-dev
Hey!

Thanks for your response, and I'm sorry for the delay in responding, I was getting pulled in a few other directions.

I passed some of your concerns off to a colleague of mine who packages and maintains OpenSSL, who had this response:

```
I am not using Google Groups so I cannot reply to the e-mail directly
but here is my opinion:

We are (at least for now) aiming at making the enabled algorithms and
other parameters in the TLS stack implementation configurable. There is
no requirement to disallow applications to use some algorithm outside
of TLS that is disallowed by the policy if that application forcibly
chooses it.

I do not know the details of the TLS stack in go so I do not know if it
provides any configuration knobs in form of API calls at all. I.e.
whether you can choose which ciphersuites are used/enabled, which
signature algorithms are allowed, which groups for ECDH and DH are
allowed, what is the minimum key size and DH parameter size, which TLS
protocol version are enabled, etc. in a connection. If there are no
such knobs, I understand that implementing the configurability is a
non-trivial task.

The mechanism is already implemented in the three main TLS
implementations that we have in RHEL - openssl, gnutls, and nss. All
these three libraries load a configuration file on their initialization
that selects the default set of algorithms used and allowed in TLS. The
support in these three libraries slightly differs but the basic
principle is the same.

As for having newer versions of Go support for newer algorithms - yes,
that is of course a slight complication. However our use in crypto-
policies in RHEL (or other Linux based OSes) and having the crypto-
policies being part of the OS ensures that we always have the policy
consistent with the library version that we ship.

In general two possible approaches can be taken in the policy
configuration - either start from no algorithms and add enabled ones,
or start from the default set and subtract algorithms that should be
disabled. Either of these have its pros/cons and both of them would be
acceptable.

To avoid completely breaking things on mismatches between the crypto
policy configuration and the go TLS library version the loading/parsing
of the configuration should tolerate old algorithms that are no longer
support or in general any unknown algorithms. This is how for example
the OpenSSL configuration works. However as I said it is a role of the
OS crypto policy vendor to avoid shipping old/broken crypto policy with
the go stack so other behavior such as completely breaking the TLS
stack or having an error logged and ignoring the policy if it is broken
is also acceptable.

I hope this explanation helps.
```
Reply all
Reply to author
Forward
0 new messages