Skip to content

Commit 60f6e68

Browse files
Update TLS profiles to Mozilla guidelines v6.0
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent fd25bf7 commit 60f6e68

4 files changed

Lines changed: 117 additions & 18 deletions

File tree

hack/tools/update-tls-profiles.sh

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,23 @@ curl -L -s ${INPUT} > ${TMPFILE}
1717

1818
version=$(${JQ} -r '.version' ${TMPFILE})
1919

20+
# Check if old profile exists (used for both header note and profile generation)
21+
has_old_profile=false
22+
if ${JQ} -e '.configurations.old' ${TMPFILE} > /dev/null 2>&1; then
23+
has_old_profile=true
24+
old_profile_note=""
25+
else
26+
old_profile_note="
27+
// NOTE: The \"old\" profile is preserved from Mozilla v5.8 for backwards compatibility,
28+
// as it was removed from Mozilla guidelines v${version}."
29+
fi
30+
2031
cat > ${OUTPUT} <<EOF
2132
package tlsprofiles
2233
2334
// DO NOT EDIT, GENERATED BY ${0}
2435
// DATA SOURCE: ${INPUT}
25-
// DATA VERSION: ${version}
36+
// DATA VERSION: ${version}${old_profile_note}
2637
2738
import (
2839
"crypto/tls"
@@ -38,7 +49,7 @@ cipherNums: []uint16{
3849
EOF
3950

4051
${JQ} -r ".configurations.$1.ciphersuites.[] | . |= \"tls.\" + . + \",\"" ${TMPFILE} >> ${OUTPUT}
41-
${JQ} -r ".configurations.$1.ciphers.go[] | . |= \"tls.\" + . + \",\"" ${TMPFILE} >> ${OUTPUT}
52+
${JQ} -r ".configurations.$1.ciphers.iana[] | . |= \"tls.\" + . + \",\"" ${TMPFILE} >> ${OUTPUT}
4253

4354
cat >> ${OUTPUT} <<EOF
4455
},
@@ -63,7 +74,54 @@ EOF
6374

6475
generate_profile "modern"
6576
generate_profile "intermediate"
66-
generate_profile "old"
77+
# Only generate old profile if it exists in the guidelines
78+
if [ "$has_old_profile" = true ]; then
79+
generate_profile "old"
80+
else
81+
# Old profile removed from Mozilla guidelines v6.0
82+
# Preserving v5.8 definition for backwards compatibility
83+
# Note: Some v5.8 ciphers (TLS_*_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256)
84+
# are not available in Go's crypto/tls package, so we use a curated subset
85+
cat >> ${OUTPUT} <<'EOF'
86+
87+
var oldTLSProfile = tlsProfile{
88+
ciphers: cipherSlice{
89+
cipherNums: []uint16{
90+
tls.TLS_AES_128_GCM_SHA256,
91+
tls.TLS_AES_256_GCM_SHA384,
92+
tls.TLS_CHACHA20_POLY1305_SHA256,
93+
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
94+
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
95+
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
96+
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
97+
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
98+
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
99+
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
100+
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
101+
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
102+
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
103+
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
104+
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
105+
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
106+
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
107+
tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
108+
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
109+
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
110+
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
111+
},
112+
},
113+
curves: curveSlice{
114+
curveNums: []tls.CurveID{
115+
X25519MLKEM768,
116+
X25519,
117+
prime256v1,
118+
secp384r1,
119+
},
120+
},
121+
minTLSVersion: tls.VersionTLS10,
122+
}
123+
EOF
124+
fi
67125

68126
# Make go happy
69127
go fmt ${OUTPUT}

internal/shared/util/tlsprofiles/mozilla_data.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package tlsprofiles
22

33
// DO NOT EDIT, GENERATED BY hack/tools/update-tls-profiles.sh
44
// DATA SOURCE: https://ssl-config.mozilla.org/guidelines/latest.json
5-
// DATA VERSION: 5.7
5+
// DATA VERSION: 6
6+
// NOTE: The "old" profile is preserved from Mozilla v5.8 for backwards compatibility,
7+
// as it was removed from Mozilla guidelines v6.
68

79
import (
810
"crypto/tls"
@@ -18,6 +20,7 @@ var modernTLSProfile = tlsProfile{
1820
},
1921
curves: curveSlice{
2022
curveNums: []tls.CurveID{
23+
X25519MLKEM768,
2124
X25519,
2225
prime256v1,
2326
secp384r1,
@@ -36,12 +39,13 @@ var intermediateTLSProfile = tlsProfile{
3639
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3740
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
3841
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
39-
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
40-
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
42+
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
43+
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
4144
},
4245
},
4346
curves: curveSlice{
4447
curveNums: []tls.CurveID{
48+
X25519MLKEM768,
4549
X25519,
4650
prime256v1,
4751
secp384r1,
@@ -60,8 +64,8 @@ var oldTLSProfile = tlsProfile{
6064
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
6165
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
6266
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
63-
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
64-
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
67+
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
68+
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
6569
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
6670
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
6771
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
@@ -78,6 +82,7 @@ var oldTLSProfile = tlsProfile{
7882
},
7983
curves: curveSlice{
8084
curveNums: []tls.CurveID{
85+
X25519MLKEM768,
8186
X25519,
8287
prime256v1,
8388
secp384r1,

internal/shared/util/tlsprofiles/tlsprofiles.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,19 @@ func cipherSuiteId(name string) uint16 {
6969

7070
// This is primarily so that we don't have to rewrite curve values in mozilla_data.go
7171
const (
72-
X25519 tls.CurveID = tls.X25519
73-
prime256v1 tls.CurveID = tls.CurveP256
74-
secp384r1 tls.CurveID = tls.CurveP384
75-
secp521r1 tls.CurveID = tls.CurveP521
72+
X25519MLKEM768 tls.CurveID = tls.X25519MLKEM768
73+
X25519 tls.CurveID = tls.X25519
74+
prime256v1 tls.CurveID = tls.CurveP256
75+
secp384r1 tls.CurveID = tls.CurveP384
76+
secp521r1 tls.CurveID = tls.CurveP521
7677
)
7778

7879
var curves = map[string]tls.CurveID{
79-
"X25519": tls.X25519,
80-
"prime256v1": tls.CurveP256,
81-
"secp384r1": tls.CurveP384,
82-
"secp521r1": tls.CurveP521,
80+
"X25519MLKEM768": tls.X25519MLKEM768,
81+
"X25519": tls.X25519,
82+
"prime256v1": tls.CurveP256,
83+
"secp384r1": tls.CurveP384,
84+
"secp521r1": tls.CurveP521,
8385
}
8486

8587
// Returns 0 for an invalid curve name

internal/shared/util/tlsprofiles/tlsprofiles_test.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tlsprofiles
22

33
import (
4+
"crypto/tls"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -114,13 +115,15 @@ func TestSetCustomCurves(t *testing.T) {
114115
name string
115116
result bool
116117
}{
118+
{"X25519MLKEM768", true},
117119
{"X25519", true},
118120
{"prime256v1", true},
119121
{"secp384r1", true},
120122
{"secp521r1", true},
121123
{"unknown-cuve", false},
122-
{"X448", false}, // Valid OpenSSL curve, not implemented
123-
{"X25519,prime256v1", true}, // Multiple
124+
{"X448", false}, // Valid OpenSSL curve, not implemented
125+
{"X25519,prime256v1", true}, // Multiple
126+
{"X25519MLKEM768,X25519,prime256v1", true}, // Multiple with new curve
124127
}
125128

126129
for _, test := range tests {
@@ -158,3 +161,34 @@ func TestSetCustomVersion(t *testing.T) {
158161
}
159162
}
160163
}
164+
165+
func TestModernProfileContents(t *testing.T) {
166+
// Verify modern profile contains X25519MLKEM768 (new in Mozilla v6.0)
167+
require.Contains(t, modernTLSProfile.curves.curveNums, X25519MLKEM768, "modern profile should include X25519MLKEM768 curve")
168+
require.Contains(t, modernTLSProfile.curves.curveNums, X25519, "modern profile should include X25519 curve")
169+
170+
// Verify modern profile ciphers
171+
require.NotEmpty(t, modernTLSProfile.ciphers.cipherNums, "modern profile should have ciphers")
172+
require.Contains(t, modernTLSProfile.ciphers.cipherNums, tls.TLS_AES_128_GCM_SHA256, "modern profile should include TLS_AES_128_GCM_SHA256")
173+
require.Contains(t, modernTLSProfile.ciphers.cipherNums, tls.TLS_CHACHA20_POLY1305_SHA256, "modern profile should include TLS_CHACHA20_POLY1305_SHA256")
174+
}
175+
176+
func TestIntermediateProfileContents(t *testing.T) {
177+
// Verify intermediate profile contains X25519MLKEM768 (new in Mozilla v6.0)
178+
require.Contains(t, intermediateTLSProfile.curves.curveNums, X25519MLKEM768, "intermediate profile should include X25519MLKEM768 curve")
179+
require.Contains(t, intermediateTLSProfile.curves.curveNums, X25519, "intermediate profile should include X25519 curve")
180+
181+
// Verify intermediate profile has TLS 1.2 ciphers
182+
require.NotEmpty(t, intermediateTLSProfile.ciphers.cipherNums, "intermediate profile should have ciphers")
183+
require.Greater(t, len(intermediateTLSProfile.ciphers.cipherNums), len(modernTLSProfile.ciphers.cipherNums), "intermediate profile should have more ciphers than modern")
184+
}
185+
186+
func TestOldProfileContents(t *testing.T) {
187+
// Verify old profile is preserved from Mozilla v5.8
188+
require.Contains(t, oldTLSProfile.curves.curveNums, X25519MLKEM768, "old profile should include X25519MLKEM768 (from v5.8)")
189+
require.Contains(t, oldTLSProfile.curves.curveNums, X25519, "old profile should include X25519 curve")
190+
191+
// Verify old profile has legacy ciphers
192+
require.NotEmpty(t, oldTLSProfile.ciphers.cipherNums, "old profile should have ciphers")
193+
require.Greater(t, len(oldTLSProfile.ciphers.cipherNums), len(intermediateTLSProfile.ciphers.cipherNums), "old profile should have more ciphers than intermediate")
194+
}

0 commit comments

Comments
 (0)