fix(proxy): support OpenSSL TLS cipher aliases

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-04 22:26:42 +00:00
parent e594b04d7c
commit 0c746e4ea7
2 changed files with 78 additions and 4 deletions

View file

@ -476,6 +476,20 @@ func applyTLSCiphers(tlsConfig *tls.Config, ciphers string) {
if tlsConfig == nil || strings.TrimSpace(ciphers) == "" {
return
}
parts := splitTLSConfigList(ciphers)
for _, part := range parts {
if id, ok := lookupTLSCipherSuite(part); ok {
tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, id)
}
}
}
func lookupTLSCipherSuite(value string) (uint16, bool) {
name := strings.ToLower(strings.TrimSpace(value))
if name == "" {
return 0, false
}
allowed := map[string]uint16{}
for _, suite := range tls.CipherSuites() {
allowed[strings.ToLower(suite.Name)] = suite.ID
@ -483,12 +497,36 @@ func applyTLSCiphers(tlsConfig *tls.Config, ciphers string) {
for _, suite := range tls.InsecureCipherSuites() {
allowed[strings.ToLower(suite.Name)] = suite.ID
}
parts := splitTLSConfigList(ciphers)
for _, part := range parts {
if id, ok := allowed[strings.ToLower(part)]; ok {
tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, id)
if id, ok := allowed[name]; ok {
return id, true
}
if alias, ok := tlsCipherSuiteAliases[name]; ok {
if id, ok := allowed[strings.ToLower(alias)]; ok {
return id, true
}
}
return 0, false
}
var tlsCipherSuiteAliases = map[string]string{
"ecdhe-ecdsa-aes128-gcm-sha256": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"ecdhe-rsa-aes128-gcm-sha256": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"ecdhe-ecdsa-aes256-gcm-sha384": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"ecdhe-rsa-aes256-gcm-sha384": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"ecdhe-ecdsa-chacha20-poly1305": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"ecdhe-rsa-chacha20-poly1305": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"dhe-rsa-aes128-gcm-sha256": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
"dhe-rsa-aes256-gcm-sha384": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"aes128-gcm-sha256": "TLS_RSA_WITH_AES_128_GCM_SHA256",
"aes256-gcm-sha384": "TLS_RSA_WITH_AES_256_GCM_SHA384",
"aes128-sha": "TLS_RSA_WITH_AES_128_CBC_SHA",
"aes256-sha": "TLS_RSA_WITH_AES_256_CBC_SHA",
"ecdhe-ecdsa-aes128-sha256": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"ecdhe-rsa-aes128-sha256": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"ecdhe-ecdsa-aes256-sha384": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
"ecdhe-rsa-aes256-sha384": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
}
func splitTLSConfigList(value string) []string {

36
tls_test.go Normal file
View file

@ -0,0 +1,36 @@
package proxy
import (
"crypto/tls"
"testing"
)
func TestTLS_applyTLSCiphers_Good(t *testing.T) {
cfg := &tls.Config{}
applyTLSCiphers(cfg, "ECDHE-RSA-AES128-GCM-SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")
if len(cfg.CipherSuites) != 2 {
t.Fatalf("expected two recognised cipher suites, got %d", len(cfg.CipherSuites))
}
}
func TestTLS_applyTLSCiphers_Bad(t *testing.T) {
cfg := &tls.Config{}
applyTLSCiphers(cfg, "made-up-cipher-one:made-up-cipher-two")
if len(cfg.CipherSuites) != 0 {
t.Fatalf("expected unknown cipher names to be ignored, got %#v", cfg.CipherSuites)
}
}
func TestTLS_applyTLSCiphers_Ugly(t *testing.T) {
cfg := &tls.Config{}
applyTLSCiphers(cfg, " aes128-sha | ECDHE-RSA-AES256-GCM-SHA384 ; tls_ecdhe_ecdsa_with_aes_256_gcm_sha384 ")
if len(cfg.CipherSuites) != 3 {
t.Fatalf("expected mixed separators and casing to be accepted, got %d", len(cfg.CipherSuites))
}
}