Background

Windows provides a rich set of built-in features to configure and retrieve TLS settings, either locally via PowerShell scripts or remotely via Group Policies and (Mobile Device Management). See for example this documentation about how to manage TLS settings: https://learn.microsoft.com/windows-server/security/tls/manage-tls.

Many organizations tweak these settings on their production environments to be compliant with their internal policies, and it comes as a surprise when Go applications don't honor them.

My team (the Go team at Microsoft) has recently had to deal with different internal and external customers asking for this functionality. These is a sample of these request:

  • We want to prioritize AES-256 over AES-128 using Group Policies
  • We only want to allow a short list of TLS 1.2 cipher suites using Group Policies

As a result, and given that some important deals were blocked by this feature gap, we have implemented this functionality on the Microsoft build of Go (see patch here) as an opt-in experiment.

Note that the TLS configuration can be retrieved via the Win32 API BCryptEnumContextFunctions.

Keeping this functionality in the Microsoft build of Go is something that we are committed to do. It is not complex thanks to crypto/tls having most of the affected settings in crypto/tls/defaults.go. On the other hand, we think that this feature has value outside of our fork.

Proposal

Provide an opt-in GODEBUG setting, which could be named tls-config=windows, that would override the following hard-coded settings in crypto/tls (for all TLS versions and also for FIPS mode):

  • TLS versions enabled by default
  • Cipher suites preference order and enabled by default (see latest supported list here)
  • Curve preference order and enabled by default (see latest supported list here)
  • Signature algorithms preference order and enabled by default

The list of settings affected by this GODEBUG should be allowed to grow over time without breaking backwards compatibility. That is, it is intended to be used as a way to instruct crypto/tls to do whatever is necessary to comply with the Windows TLS settings.

Those settings supported by Windows but not by Go will be discarded, for example the TLS_RSA_WITH_NULL_SHA256 cipher suite. This introduces the risk of not having a common set of settings, but this risk is negligible in practice due to the fact that Windows supports many more cipher suites and curves than Go.

It is important to note that this feature is not intended to make Go applications more secure (given that Go default settings are already secure enough), but more compliant so that it can be deployed on more environments (akin to the FIPS 140 value proposition).

Note that this wouldn't be the first case of crypto/tls using TLS configuration from Windows: it already does so to get TLS certificates and for socket settings.

@golang/proposal-review @golang/security @golang/windows

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)