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.