ADDED:
* cryptparse/ParseTlsCipherStrict()
* cryptparse/ParseTlsCipherSuiteStrict()
This commit is contained in:
brent saner 2024-09-09 13:06:07 -04:00
parent 1a93d5d9f3
commit 0318a9759b
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
2 changed files with 80 additions and 4 deletions

View File

@ -5,8 +5,9 @@ import (
) )


var ( var (
ErrBadTlsCipher error = errors.New("invalid TLS cipher suite") ErrBadTlsCipher error = errors.New("invalid TLS cipher suite")
ErrBadTlsCurve error = errors.New("invalid TLS curve") ErrBadTlsCurve error = errors.New("invalid TLS curve")
ErrBadTlsVer error = errors.New("invalid TLS version") ErrBadTlsVer error = errors.New("invalid TLS version")
ErrUnknownKey error = errors.New("unknown key type") ErrUnknownCipher error = errors.New("unknown TLS cipher")
ErrUnknownKey error = errors.New("unknown key type")
) )

View File

@ -142,6 +142,56 @@ func ParseTlsCipher(s string) (cipherSuite uint16, err error) {
return return
} }


// ParseTlsCipherStrict is like ParseTlsCipher, but an ErrUnknownCipher error will be raised if no matching cipher is found.
func ParseTlsCipherStrict(s string) (cipherSuite uint16, err error) {

var nm string
var n uint64
var i uint16
var ok bool

if n, err = strconv.ParseUint(s, 10, 16); err != nil {
if errors.Is(err, strconv.ErrSyntax) {
// It's a name; parse below.
err = nil
} else {
return
}
} else {
// It's a number.
if nm = tls.CipherSuiteName(uint16(n)); strings.HasPrefix(nm, "0x") {
// ...but invalid.
err = ErrBadTlsCipher
return
} else {
// Valid (as number). Return it.
cipherSuite = uint16(n)
return
}
}

s = strings.ToUpper(s)
s = strings.ReplaceAll(s, " ", "_")

// We build a dynamic map of cipher suite names to uint16s (if not already created).
if tlsCipherNmToUint == nil {
tlsCipherNmToUint = make(map[string]uint16)
for i = 0; i <= MaxTlsCipher; i++ {
if nm = tls.VersionName(i); !strings.HasPrefix(nm, "0x") {
tlsCipherNmToUint[nm] = i
}
}
}

if i, ok = tlsCipherNmToUint[s]; ok {
cipherSuite = i
} else {
err = ErrUnknownCipher
}

return
}

/* /*
ParseTlsCiphers parses s as a comma-separated list of cipher suite names/integers and returns a slice of suites. ParseTlsCiphers parses s as a comma-separated list of cipher suite names/integers and returns a slice of suites.


@ -198,6 +248,31 @@ func ParseTlsCipherSuite(s string) (cipherSuite *tls.CipherSuite, err error) {
return return
} }


// ParseTlsCipherSuiteStrict is like ParseTlsCipherSuite, but an ErrUnknownCipher error will be raised if no matching cipher is found.
func ParseTlsCipherSuiteStrict(s string) (cipherSuite *tls.CipherSuite, err error) {

var cipherId uint16

if cipherId, err = ParseTlsCipherStrict(s); err != nil {
return
}

for _, v := range tls.CipherSuites() {
if v.ID == cipherId {
cipherSuite = v
return
}
}
for _, v := range tls.InsecureCipherSuites() {
if v.ID == cipherId {
cipherSuite = v
return
}
}

return
}

// ParseTlsCipherSuites is like ParseTlsCiphers but returns a []*tls.CipherSuite instead of a []uint16 of TLS cipher identifiers. // ParseTlsCipherSuites is like ParseTlsCiphers but returns a []*tls.CipherSuite instead of a []uint16 of TLS cipher identifiers.
func ParseTlsCipherSuites(s string) (cipherSuites []*tls.CipherSuite, err error) { func ParseTlsCipherSuites(s string) (cipherSuites []*tls.CipherSuite, err error) {