I'm coming from Ruby and looking at Go at the moment. I start writing a little bit of code to check TLS support for a given host.
var tls_versions = map[uint16]string{
tls.VersionSSL30: "SSLv3",
tls.VersionTLS10: "TLSv1.0",
tls.VersionTLS11: "TLSv1.1",
tls.VersionTLS12: "TLSv1.2",
}
var refused_re = regexp.MustCompile(": connection refused")
var nodns_re = regexp.MustCompile(": no such host")
var versionnotsupported_re = regexp.MustCompile(": protocol version not supported")
func checkversion(host string) (map[string]bool, error) { // {{
ret := map[string]bool{}
for version := tls.VersionSSL30; version <= tls.VersionTLS12; version++ {
conn, err := tls.Dial("tcp", host+":443", &tls.Config{
MinVersion: uint16(version),
})
if err != nil &&
(refused_re.MatchString(err.Error()) == true || nodns_re.MatchString(err.Error()) == true) {
log.Println(err)
return ret, err
}
if err != nil && versionnotsupported_re.MatchString(err.Error()) == true {
ret[tls_versions[uint16(version)]] = false
log.Println("Not supported: "+host+" "+tls_versions[uint16(version)])
}
ret[tls_versions[uint16(version)]] = true
if conn != nil {
conn.Close()
}
}
return ret, nil
}
Coming from Ruby I found the error management in this code pretty ugly as I'm one typo/change away from not getting the right reason for the error. I tried to play with reflect but couldn't get it to do what I wanted. I was wondering if I was missing something obvious or if it was the go way? Or is it specific to the crypto/tls library to avoid recovering from any issue?
Thanks for your help.