client-hello-mirror/clienthello/cipher_suites.go

114 lines
2.3 KiB
Go

// SPDX-FileCopyrightText: 2023 nervuri <https://nervuri.net/contact>
//
// SPDX-License-Identifier: BSD-3-Clause
// Inspired by Andrew Ayer's tlshacks:
// https://github.com/AGWA/tlshacks/blob/main/generate_ciphersuites.go
package clienthello
import (
_ "embed"
"encoding/csv"
"fmt"
"io"
"log"
"strconv"
"strings"
)
// https://www.iana.org/assignments/tls-parameters/tls-parameters-4.csv
//
//go:embed cipher-suites.csv
var cipherSuitesCSV string
var CipherSuiteList = parseCipherSuitesCSV()
type CipherSuite any // (uint16 | CipherSuiteInfo)
type CipherSuiteInfo = struct {
Code uint16 `json:"code"`
HexCode string `json:"hex_code"`
Name string `json:"name"`
Recommended bool `json:"recommended"`
Reference string `json:"-"`
}
// TLS signaling cipher suite values
const (
scsvRenegotiation uint16 = 0x00ff
)
func parseCipherSuitesCSV() map[uint16]CipherSuiteInfo {
cipherSuites := map[uint16]CipherSuiteInfo{}
r := csv.NewReader(strings.NewReader(cipherSuitesCSV))
// Skip CSV header.
_, err := r.Read()
if err != nil {
log.Fatal(err)
}
for {
row, err := r.Read()
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
var (
val = row[0]
desc = row[1]
rec = row[3]
ref = row[4]
)
if desc == "Unassigned" {
continue
}
if strings.HasPrefix(desc, "Reserved") && ref != "[RFC8701]" {
continue
}
val = strings.Replace(val, ",", "", 1)
val = strings.Replace(val, "0x", "", 2)
code, err := strconv.ParseUint(val, 16, 16)
if err != nil {
log.Println(err)
}
suite := CipherSuiteInfo{
Code: uint16(code),
HexCode: val,
Name: desc,
Reference: ref,
}
if rec == "Y" {
suite.Recommended = true
}
if ref == "[RFC8701]" {
suite.Name = "GREASE"
}
cipherSuites[suite.Code] = suite
}
return cipherSuites
}
func GetCipherSuiteInfo(cipherSuiteCode uint16, mustName bool) CipherSuiteInfo {
info, found := CipherSuiteList[cipherSuiteCode]
if !found {
info = CipherSuiteInfo{
Code: cipherSuiteCode,
HexCode: fmt.Sprintf("%04X", cipherSuiteCode),
}
}
if mustName && info.Name == "" {
info.Name = "0x" + info.HexCode
}
return info
}
func (m *ClientHelloMsg) AddCipherSuiteInfo() {
for i, suite := range m.CipherSuites {
m.CipherSuites[i] = GetCipherSuiteInfo(suite.(uint16), false)
}
}