Skip to content

main: Use latest Go 1.25 features if possible. - #3504

Merged
davecgh merged 1 commit into
decred:masterfrom
davecgh:main_go1_25_godebug
Aug 19, 2025
Merged

main: Use latest Go 1.25 features if possible.#3504
davecgh merged 1 commit into
decred:masterfrom
davecgh:main_go1_25_godebug

Conversation

@davecgh

@davecgh davecgh commented Aug 19, 2025

Copy link
Copy Markdown
Member

In order to avoid breaking backwards compatibility, newer versions of Go toolchains automatically set GODEBUG flags to disable any changes that are not strictly backwards compatible when compiling old code. However, it is often the case that older code will work properly with the new features and security updates enabled and those updates are generally desirable.

The existing code in the main module will all work properly with all changes in Go 1.25, so this adds a directive when building with Go 1.25 or newer to override and remove the default GODEBUG flags which disable newer features and security updates that are not strictly backwards compatible. In other words, it ensures the new features and security updates implemented in Go 1.25 are enabled when building with Go 1.25 or newer.

The specific GODEBUG flags removed are:

  • asynctimerchan=1
  • containermaxprocs=0
  • decoratemappings=0
  • gotestjsonbuildtext=1
  • gotypesalias=0
  • httplaxcontentlength=1
  • httpmuxgo121=1
  • httpservecontentkeepheaders=1
  • multipathtcp=0
  • panicnil=1
  • randseednop=0
  • rsa1024min=0
  • tls10server=1
  • tls3des=1
  • tlsmlkem=0
  • tlsrsakex=1
  • tlssha1=1
  • tlsunsafeekm=1
  • updatemaxprocs=0
  • winreadlinkvolume=0
  • winsymlink=0
  • x509keypairleaf=0
  • x509negativeserial=1
  • x509rsacrt=0
  • x509sha256skid=0
  • x509usepolicies=0

The only notable change that could potential affect existing deployments is that it is no longer possible to use certificates that use RSA keys with less than 1024 bits. This is very unlikely to affect anyone in practice because the default generated certificates use ECC and there is not even an option to generate RSA certificates with dcrd itself. Further, the separate gencerts utility does support generating RSA certs, but those use 4096-bit RSA keys. In other words, a user would have needed to generate such a certificate with external tools, such as openssl, which would require them to know exactly what they're doing and so it would be easy for them to generate new certs if the change were to actually affect them.

@davecgh davecgh added this to the 2.1.0 milestone Aug 19, 2025
@davecgh
davecgh force-pushed the main_go1_25_godebug branch from c4e41c3 to 9eee05d Compare August 19, 2025 01:38
@davecgh davecgh changed the title main/build: Use latest Go1.25 features if possible. main: Use latest Go 1.25 features if possible. Aug 19, 2025
@davecgh
davecgh force-pushed the main_go1_25_godebug branch 2 times, most recently from aa9d32e to efa3666 Compare August 19, 2025 01:44
@jrick

jrick commented Aug 19, 2025

Copy link
Copy Markdown
Member

Change looks fine but there are many more compatibility flags that this removes (everything since the main module's declared Go 1.19):

$ go version -m ./dcrd | grep DefaultGODEBUG
	build	DefaultGODEBUG=containermaxprocs=0,decoratemappings=0,gotestjsonbuildtext=1,multipathtcp=0,randseednop=0,rsa1024min=0,tlsmlkem=0,tlssha1=1,updatemaxprocs=0,x509rsacrt=0,x509sha256skid=0,x509usepolicies=0

@davecgh
davecgh force-pushed the main_go1_25_godebug branch from efa3666 to 5337399 Compare August 19, 2025 01:45
@davecgh

davecgh commented Aug 19, 2025

Copy link
Copy Markdown
Member Author

EDIT: Nevermind. it's my go.work. Let me analyze the other flags too and get this updated. Thanks for pointing it out.


Change looks fine but there are many more compatibility flags that this removes (everything since the main module's declared Go 1.19):

$ go version -m ./dcrd | grep DefaultGODEBUG
	build	DefaultGODEBUG=containermaxprocs=0,decoratemappings=0,gotestjsonbuildtext=1,multipathtcp=0,randseednop=0,rsa1024min=0,tlsmlkem=0,tlssha1=1,updatemaxprocs=0,x509rsacrt=0,x509sha256skid=0,x509usepolicies=0

Hmm, I must be missing something. Without these changes, I see:

$ go1.25.0 build && go version -m ./dcrd | grep DefaultGODEBUG
        build   DefaultGODEBUG=containermaxprocs=0,decoratemappings=0,tlssha1=1,updatemaxprocs=0,x509sha256skid=0

@jrick

jrick commented Aug 19, 2025

Copy link
Copy Markdown
Member

Yeah, and my go.work was at 1.23 so there are even more beyond that.

build DefaultGODEBUG=asynctimerchan=1,containermaxprocs=0,decoratemappings=0,gotestjsonbuildtext=1,gotypesalias=0,httplaxcontentlength=1,httpmuxgo121=1,httpservecontentkeepheaders=1,multipathtcp=0,panicnil=1,randseednop=0,rsa1024min=0,tls10server=1,tls3des=1,tlsmlkem=0,tlsrsakex=1,tlssha1=1,tlsunsafeekm=1,updatemaxprocs=0,winreadlinkvolume=0,winsymlink=0,x509keypairleaf=0,x509negativeserial=1,x509rsacrt=0,x509sha256skid=0,x509usepolicies=0

@davecgh
davecgh force-pushed the main_go1_25_godebug branch 2 times, most recently from 1867914 to 13cfd9e Compare August 19, 2025 03:37
@jrick

jrick commented Aug 19, 2025

Copy link
Copy Markdown
Member

Which debug flag is the new note from the commit message referring to? All the tls and x509 options I see don't appear to affect existing certificates. The tls options only affect the algorithms that the server will use to negotiate a symmetric key, and x509rsacrt=0 (this one looks the most suspect) only restores the previous behavior of ignoring the precomputed CRT values of a RSA private key (CRT != certificate).

If RSA certificates were really not usable anymore, we would want to nuke generating RSA4096 keys from gencerts, but these do still work:

$ gencerts -a RSA4096 /tmp/test.{crt,key}
$ dcrd --rpccert=/tmp/test.crt --rpckey=/tmp/test.key -u jrick -P sekrit
...
2025-08-19 08:53:15.373 [INF] RPCS: RPC server listening on 127.0.0.1:9109
2025-08-19 08:53:15.373 [INF] RPCS: RPC server listening on [::1]:9109
$ openssl s_client -connect 127.0.0.1:9109 -showcerts 
CONNECTED(00000003)
depth=0 O = gencerts, CN = gencerts
verify error:num=18:self signed certificate
verify return:1
---
Certificate chain
 0 s:/O=gencerts/CN=gencerts
   i:/O=gencerts/CN=gencerts
-----BEGIN CERTIFICATE-----
MIIFGTCCAwGgAwIBAgIRAKP726QUru8MdibnUU/xU0YwDQYJKoZIhvcNAQELBQAw
JjERMA8GA1UEChMIZ2VuY2VydHMxETAPBgNVBAMTCGdlbmNlcnRzMB4XDTI1MDgx
ODEyNTIxN1oXDTM1MDgxNzEyNTIxN1owJjERMA8GA1UEChMIZ2VuY2VydHMxETAP
BgNVBAMTCGdlbmNlcnRzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
t6dNuqwowNJvb9wvO/WLd164lhuT1ujmyv/L3u6Qt6WWrkUvLCv21KY1kiHkwufN
DNS+Oc/4TfOIy6wWlbbuuvQD7sH8EZ2VOXdCYbeX6YVzW3VhtVPH9aQKXMW+SA/m
7muET4pUBHbzCKgAydef4+l4/dwIp4FSbeKisBmSMcQ/vuJAUnOmUdfkcbS34u+e
v6FIZtFeMNxHW9geZajfMbgCtI8OYdPZrqCzbroLTe4m12Wi3VdocwshUatg665J
d3vX9DV7mBujJQun/TciOe1XbSwPm84cwnOv6LJVlWlf5V+LW/6+K4wH+byfB6HC
Y9ZSLxkieozhM2c2i6ZKpcZJJGTOidoMT9/Av8ZpxfL9dk48O77rzu3b+1pdBkgA
88T95gUmrV5e3UtQv6U/IOCCM+0FVwwFCH0cIY4+o9l62299Uh0eF/LnKQKP8064
eHQYSlnzpE1Y/e0u7nsUi7QK8TbGbMgHqG1g9CBZ8iGVqO7QqA2KGh8asrWKfa+U
i0dFGGFiTkvOKoyVO3PVslyYXSVKFMM99QEDDMLCihvDbCFMyzpQEHr59MwX64bB
aTyDTz9QXSw26P2tBZFU5H1kZ8WTBanx1yTI/bC+8Y/fZnnh3/xNe7bk2vCWAmLr
YGP2qOIhAMQEUyyNRXHk1cOSd2xDtAZ0Kcz7q0D+6lkCAwEAAaNCMEAwDgYDVR0P
AQH/BAQDAgKEMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNjqCAKNVFxNkhcw
ULrxISkEh2msMA0GCSqGSIb3DQEBCwUAA4ICAQA0qxaT1Sb/5SdXiFOiZ1dT8ibA
mumYBOa2Y4wxI/7mW6jmWIi0V0wMCKs1oFu87x2fSASzFke+UQQCYRh5UXGtNnHS
hXMm44nfOEszzef5QS+9zF/O+PdKbkM9O7xey7M9d9cEEAj0lUQgf7Ce0KgEoZSD
H3ElIpyH5tQ8By5r9agQL2DM/x7OntgixSIRw+aGxGWt3JcQhJFv6ulco1c5U7Js
vRKUTnc9s+RMKK0cNAjNf21GfQM1cP/hwqKxGpuWYY7FYrXzYf+dtSm0KZo/mNdg
KiQUbqwjbqt9PxsIWzT8fAoZIY0reSphitI+P8LwLoWO9wnkBOsy9l5zhMHpzLb6
B6US/Ec3aSWq0iADWacCybayZmGVm1Bu+LB8dwuUN3vh6/W+yQyiMwR1V0d3jLvR
9EDOkJMmcfERUOUvuMfAUOVUbdNLyRXElr1aajxbHeQPMI/uWX60m+Bcu4vS2tHQ
o+BqL6e2KtxKXQ30LLDNztmoMkzd3DEmOKuc0HBTG9GNRWsy8mDlI4e8qsf/VOqf
evgBEONC8v45p10cIBdWywsiLNGQ2aJ+6oTskP2Mv7cG1UZKTUh/JWtUB6MixuXC
KgnC4sJ9Hdb1nivOZfgn7Y28UrTm5zzUoRbKwHe1mEt7OF1FgqVfuJpS2q9rleta
BNJBEX8+DZvcgBJQWg==
-----END CERTIFICATE-----
---
Server certificate
subject=/O=gencerts/CN=gencerts
issuer=/O=gencerts/CN=gencerts
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 2105 bytes and written 341 bytes
---
New, TLSv1/SSLv3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_128_GCM_SHA256
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Start Time: 1755608066
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
---

@jrick

jrick commented Aug 19, 2025

Copy link
Copy Markdown
Member

I also modified gencerts to set tls.Certificate.SignatureAlgorithm = x509.SHA1WithRSA and dcrd still works fine with these certificates as well.

@davecgh

davecgh commented Aug 19, 2025

Copy link
Copy Markdown
Member Author

Which debug flag is the new note from the commit message referring to? All the tls and x509 options I see don't appear to affect existing certificates. The tls options only affect the algorithms that the server will use to negotiate a symmetric key, and x509rsacrt=0 (this one looks the most suspect) only restores the previous behavior of ignoring the precomputed CRT values of a RSA private key (CRT != certificate).

I'll detail it here, but after looking again, I conflated the summary I was looking at. It's the supported TLS 1.2 cipher suites (for kx) that removed RSA and SHA-1 algorithms instead of the supported cert keys. The note originally pointed out that the RSA keys in certs are now required to be at least 1024 bits, but I updated it to instead call out the RSA keys weren't supported at all due to the aforementioned conflation. I'll update it to revert to that here in a bit.

The flags in question are:

rsa1024min=0 - Go 1.24+ requires RSA keys to be at least 1024 bits unless rsa1024min=0.
tlsrsakex=1 - tls.Config.CipherSuites

	// If CipherSuites is nil, a safe default list is used. The default cipher
	// suites might change over time. In Go 1.22 RSA key exchange based cipher
	// suites were removed from the default list, but can be re-added with the
	// GODEBUG setting tlsrsakex=1. 

tlssha1=1 - Go 1.25+ disables SHA-1 signature algorithms in TLS 1.2 according to RFC 9155 unless tlssha1=1.

@davecgh
davecgh force-pushed the main_go1_25_godebug branch from 13cfd9e to 7f47d87 Compare August 19, 2025 14:34
In order to avoid breaking backwards compatibility, newer versions of Go
toolchains automatically set GODEBUG flags to disable any changes that
are not strictly backwards compatible when compiling old code.  However,
it is often the case that older code will work properly with the new
features and security updates enabled and those updates are generally
desirable.

The existing code in the main module will all work properly with all
changes in Go 1.25, so this adds a directive when building with Go 1.25
or newer to override and remove the default GODEBUG flags which disable
newer features and security updates that are not strictly backwards
compatible.  In other words, it ensures the new features and security
updates implemented in Go 1.25 are enabled when building with Go 1.25 or
newer.

The specific GODEBUG flags removed are:

- `asynctimerchan=1`
- `containermaxprocs=0`
- `decoratemappings=0`
- `gotestjsonbuildtext=1`
- `gotypesalias=0`
- `httplaxcontentlength=1`
- `httpmuxgo121=1`
- `httpservecontentkeepheaders=1`
- `multipathtcp=0`
- `panicnil=1`
- `randseednop=0`
- `rsa1024min=0`
- `tls10server=1`
- `tls3des=1`
- `tlsmlkem=0`
- `tlsrsakex=1`
- `tlssha1=1`
- `tlsunsafeekm=1`
- `updatemaxprocs=0`
- `winreadlinkvolume=0`
- `winsymlink=0`
- `x509keypairleaf=0`
- `x509negativeserial=1`
- `x509rsacrt=0`
- `x509sha256skid=0`
- `x509usepolicies=0`

The only notable change that could potential affect existing deployments
is that it is no longer possible to use certificates that use RSA keys
with less than 1024 bits.  This is very unlikely to affect anyone in
practice because the default generated certificates use ECC and there is
not even an option to generate RSA certificates with dcrd itself.
Further, the separate gencerts utility does support generating RSA
certs, but those use 4096-bit RSA keys.  In other words, a user would
have needed to generate such a certificate with external tools, such as
openssl, which would require them to know exactly what they're doing and
so it would be easy for them to generate new certs if the change were to
actually affect them.
@davecgh
davecgh force-pushed the main_go1_25_godebug branch from 7f47d87 to c2a2915 Compare August 19, 2025 15:00
@davecgh
davecgh merged commit c2a2915 into decred:master Aug 19, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants