refactor isGREASE8 and isGREASE16 into isGREASE
This commit is contained in:
parent
b1e820afcf
commit
763458fbf1
|
@ -18,33 +18,31 @@ import (
|
|||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
||||
// Check if this is a 16-bit GREASE value (RFC 8701).
|
||||
func isGREASE16(value uint16) bool {
|
||||
// Check if this is a GREASE value (RFC 8701).
|
||||
func isGREASE[N uint16 | uint8](val N) bool {
|
||||
// Values for: cipher suites, ALPN,
|
||||
// extensions, named groups, signature algorithms and TLS versions:
|
||||
greaseValues := [16]uint16{
|
||||
greaseValues16 := [16]uint16{
|
||||
0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a,
|
||||
0x8a8a, 0x9a9a, 0xaaaa, 0xbaba, 0xcaca, 0xdada, 0xeaea, 0xfafa,
|
||||
}
|
||||
// Run the check
|
||||
for _, greaseValue := range greaseValues {
|
||||
if value == greaseValue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if this is an 8-bit GREASE value (PskKeyExchangeModes) (RFC 8701).
|
||||
func isGREASE8(value uint8) bool {
|
||||
// Values for PskKeyExchangeModes:
|
||||
greaseValues := [8]uint8{
|
||||
greaseValues8 := [8]uint8{
|
||||
0x0B, 0x2A, 0x49, 0x68, 0x87, 0xA6, 0xC5, 0xE4,
|
||||
}
|
||||
// Run the check
|
||||
for _, greaseValue := range greaseValues {
|
||||
if value == greaseValue {
|
||||
return true
|
||||
switch any(val).(type) {
|
||||
case uint16:
|
||||
for _, greaseValue := range greaseValues16 {
|
||||
if any(val).(uint16) == greaseValue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case uint8:
|
||||
for _, greaseValue := range greaseValues8 {
|
||||
if any(val).(uint8) == greaseValue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -12,28 +12,21 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func toString[N uint8 | uint16](val N) string {
|
||||
func toString[N uint16 | uint8](val N) string {
|
||||
return strconv.FormatUint(uint64(val), 10)
|
||||
}
|
||||
|
||||
func deGREASE16(val uint16, greaseReplacement string) string {
|
||||
if isGREASE16(val) {
|
||||
if greaseReplacement == "" {
|
||||
return ""
|
||||
func deGREASE[N uint16 | uint8](val N, replace bool) string {
|
||||
if isGREASE(val) {
|
||||
if replace {
|
||||
switch any(val).(type) {
|
||||
case uint16:
|
||||
return "2570-" // generic 16-bit GREASE code 0x0A0A (2570)
|
||||
default: // uint8
|
||||
return "11-" // generic 8-bit GREASE code 0x0B (11)
|
||||
}
|
||||
} else {
|
||||
return greaseReplacement + "-"
|
||||
}
|
||||
} else {
|
||||
return toString(val) + "-"
|
||||
}
|
||||
}
|
||||
|
||||
func deGREASE8(val uint8, greaseReplacement string) string {
|
||||
if isGREASE8(val) {
|
||||
if greaseReplacement == "" {
|
||||
return ""
|
||||
} else {
|
||||
return greaseReplacement + "-"
|
||||
}
|
||||
} else {
|
||||
return toString(val) + "-"
|
||||
|
@ -44,14 +37,14 @@ func (m *ClientHelloMsg) ja3() {
|
|||
var codeGroups [5]string
|
||||
codeGroups[0] = toString(m.TLSVersion.(uint16))
|
||||
for _, cs := range m.CipherSuites {
|
||||
codeGroups[1] += deGREASE16(cs.(uint16), "")
|
||||
codeGroups[1] += deGREASE(cs.(uint16), false)
|
||||
}
|
||||
for _, e := range m.Extensions {
|
||||
codeGroups[2] += deGREASE16(e.Code, "")
|
||||
codeGroups[2] += deGREASE(e.Code, false)
|
||||
switch e.Code {
|
||||
case extensionSupportedGroups:
|
||||
for _, g := range e.Data.SupportedGroups {
|
||||
codeGroups[3] += deGREASE16(g.(uint16), "")
|
||||
codeGroups[3] += deGREASE(g.(uint16), false)
|
||||
}
|
||||
case extensionSupportedPointFormats:
|
||||
for _, pf := range e.Data.SupportedPointFormats {
|
||||
|
@ -69,15 +62,12 @@ func (m *ClientHelloMsg) ja3() {
|
|||
|
||||
func (m *ClientHelloMsg) nja3() {
|
||||
const genericGREASECode16 = uint16(0x0a0a) // 2570
|
||||
const genericGREASECode8 = uint8(0x0B) // 11
|
||||
var genericGreaseString16 = toString(genericGREASECode16)
|
||||
var genericGreaseString8 = toString(genericGREASECode8)
|
||||
var codeGroups [10]string
|
||||
var extCodes []uint16
|
||||
codeGroups[0] = toString(m.RecordHeaderTLSVersion.(uint16))
|
||||
codeGroups[1] = toString(m.TLSVersion.(uint16))
|
||||
for _, cs := range m.CipherSuites {
|
||||
codeGroups[2] += deGREASE16(cs.(uint16), genericGreaseString16)
|
||||
codeGroups[2] += deGREASE(cs.(uint16), true)
|
||||
}
|
||||
for _, e := range m.Extensions {
|
||||
// Ignore conditional extensions.
|
||||
|
@ -92,14 +82,14 @@ func (m *ClientHelloMsg) nja3() {
|
|||
e.Code == extensionChannelIDOld {
|
||||
continue
|
||||
}
|
||||
if isGREASE16(e.Code) {
|
||||
if isGREASE(e.Code) {
|
||||
e.Code = genericGREASECode16
|
||||
}
|
||||
extCodes = append(extCodes, e.Code)
|
||||
switch e.Code {
|
||||
case extensionSupportedGroups:
|
||||
for _, g := range e.Data.SupportedGroups {
|
||||
codeGroups[4] += deGREASE16(g.(uint16), genericGreaseString16)
|
||||
codeGroups[4] += deGREASE(g.(uint16), true)
|
||||
}
|
||||
case extensionSupportedPointFormats:
|
||||
for _, pf := range e.Data.SupportedPointFormats {
|
||||
|
@ -107,15 +97,15 @@ func (m *ClientHelloMsg) nja3() {
|
|||
}
|
||||
case extensionSupportedVersions:
|
||||
for _, v := range e.Data.SupportedVersions {
|
||||
codeGroups[6] += deGREASE16(v.(uint16), genericGreaseString16)
|
||||
codeGroups[6] += deGREASE(v.(uint16), true)
|
||||
}
|
||||
case extensionSignatureAlgorithms:
|
||||
for _, sa := range e.Data.SupportedSignatureAlgorithms {
|
||||
codeGroups[7] += deGREASE16(sa.(uint16), genericGreaseString16)
|
||||
codeGroups[7] += deGREASE(sa.(uint16), true)
|
||||
}
|
||||
case extensionPSKModes:
|
||||
for _, mode := range e.Data.PSKModes {
|
||||
codeGroups[8] += deGREASE8(mode.(uint8), genericGreaseString8)
|
||||
codeGroups[8] += deGREASE(mode.(uint8), true)
|
||||
}
|
||||
case extensionCompressCertificate:
|
||||
for _, algo := range e.Data.CertificateCompressionAlgos {
|
||||
|
@ -127,7 +117,7 @@ func (m *ClientHelloMsg) nja3() {
|
|||
sort.Slice(extCodes, func(i, j int) bool { return extCodes[i] < extCodes[j] })
|
||||
// Add sorted extension codes to NJA3 string.
|
||||
for _, code := range extCodes {
|
||||
codeGroups[3] += deGREASE16(code, genericGreaseString16)
|
||||
codeGroups[3] += deGREASE(code, true)
|
||||
}
|
||||
for i, cg := range codeGroups {
|
||||
codeGroups[i] = strings.TrimSuffix(cg, "-")
|
||||
|
|
|
@ -125,7 +125,7 @@ func GetSignatureSchemeInfo(sigSchemeCode uint16, mustName bool) SignatureScheme
|
|||
Code: sigSchemeCode,
|
||||
HexCode: fmt.Sprintf("%04X", sigSchemeCode),
|
||||
}
|
||||
if isGREASE16(sigSchemeCode) {
|
||||
if isGREASE(sigSchemeCode) {
|
||||
// As of September 2023, the IANA signature scheme registry
|
||||
// doesn't include GREASE values, so we need to check here.
|
||||
info.Name = "GREASE"
|
||||
|
|
Loading…
Reference in New Issue