114 lines
2.3 KiB
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)
|
|
}
|
|
}
|