3 Commits

Author SHA1 Message Date
brent saner
0318a9759b v1.7.0
ADDED:
* cryptparse/ParseTlsCipherStrict()
* cryptparse/ParseTlsCipherSuiteStrict()
2024-09-09 13:06:07 -04:00
brent saner
1a93d5d9f3 v1.6.0
ADDED:
- env/DefEnv(), env/DefEnvBlank()
2024-09-06 12:50:23 -04:00
brent saner
5dc944cf21 v1.5.1
FIXES:
* cryptparse.TlsUri.ToConn and cryptparse.TlsUri.ToTlsConn would
  previously use incorrect "host" parameter during dial for UDS/IPC
  sockets.
2024-08-12 15:59:38 -04:00
4 changed files with 128 additions and 6 deletions

View File

@@ -8,5 +8,6 @@ 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")
ErrUnknownCipher error = errors.New("unknown TLS cipher")
ErrUnknownKey error = errors.New("unknown key type") 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) {

View File

@@ -38,6 +38,7 @@ func (t *TlsUri) WithConn(underlying net.Conn) (conn *tls.Conn, err error) {
func (t *TlsUri) ToConn() (conn net.Conn, err error) { func (t *TlsUri) ToConn() (conn net.Conn, err error) {
var ok bool var ok bool
var connHost string
var params map[string][]string var params map[string][]string
var netType string = DefaultNetType var netType string = DefaultNetType
@@ -48,8 +49,16 @@ func (t *TlsUri) ToConn() (conn net.Conn, err error) {
netType = params[TlsUriParamNet][0] netType = params[TlsUriParamNet][0]
} }
} }
netType = strings.ToLower(netType)
if conn, err = net.Dial(netType, t.Host); err != nil { switch netType {
case "unix", "unixgram", "unixpacket":
connHost = t.Path
default:
connHost = t.Host
}
if conn, err = net.Dial(netType, connHost); err != nil {
return return
} }
@@ -79,6 +88,7 @@ func (t *TlsUri) ToTlsConn() (conn *tls.Conn, err error) {
var ok bool var ok bool
var cfg *tls.Config var cfg *tls.Config
var connHost string
var params map[string][]string var params map[string][]string
var netType string = DefaultNetType var netType string = DefaultNetType
@@ -93,8 +103,16 @@ func (t *TlsUri) ToTlsConn() (conn *tls.Conn, err error) {
netType = params[TlsUriParamNet][0] netType = params[TlsUriParamNet][0]
} }
} }
netType = strings.ToLower(netType)
if conn, err = tls.Dial(netType, t.Host, cfg); err != nil { switch netType {
case "unix", "unixgram", "unixpacket":
connHost = t.Path
default:
connHost = t.Host
}
if conn, err = tls.Dial(netType, connHost, cfg); err != nil {
return return
} }

View File

@@ -17,6 +17,34 @@ import (
`r00t2.io/sysutils/paths` `r00t2.io/sysutils/paths`
) )
/*
DefEnv operates like Python's .get() method on dicts (maps);
if the environment variable specified by key does not exist/is not specified,
then the value specified by fallback will be returned instead
otherwise key's value is returned.
*/
func DefEnv(key, fallback string) (value string) {
var exists bool
if value, exists = os.LookupEnv(key); !exists {
value = fallback
}
return
}
// DefEnvBlank is like DefEnv but will ADDITIONALLY/ALSO apply fallback if key is *defined/exists but is an empty string*.
func DefEnvBlank(key, fallback string) (value string) {
value = DefEnv(key, fallback)
if value == "" {
value = fallback
}
return
}
// GetEnvMap returns a map of all environment variables. All values are strings. // GetEnvMap returns a map of all environment variables. All values are strings.
func GetEnvMap() (envVars map[string]string) { func GetEnvMap() (envVars map[string]string) {