From c368df917ad8febfd0469f3e7dbe3a699f42f55b Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Sun, 19 Feb 2017 13:35:38 -0800 Subject: [PATCH 1/8] Allow SSL 3.0, so we can see old and bad servers. --- starttls/starttls.go | 1 + 1 file changed, 1 insertion(+) diff --git a/starttls/starttls.go b/starttls/starttls.go index 1c227a1..a1308db 100644 --- a/starttls/starttls.go +++ b/starttls/starttls.go @@ -31,6 +31,7 @@ func tlsConfigForConnect(connectName, clientCert, clientKey string) (*tls.Config // We verify later manually so we can print results InsecureSkipVerify: true, ServerName: connectName, + MinVersion: tls.VersionSSL30, } if clientCert != "" { From 7262504ad9265ab4b8e568c18c83e67fd9b6db75 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Sun, 19 Feb 2017 14:33:24 -0800 Subject: [PATCH 2/8] Require Go 1.8 for new cipher suites --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 849326d..6477d5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: go go: - - 1.7.5 - 1.8 install: From 2a02e76a1903d506e01858eb90b94a86bfe8028c Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Sun, 19 Feb 2017 02:25:05 -0800 Subject: [PATCH 3/8] [WIP] Print TLS version & cipher suite when connecting --- .gitignore | 1 + lib/tls.go | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 2 + verify.go | 10 ++++- 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 lib/tls.go diff --git a/.gitignore b/.gitignore index f35548d..95864b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ certigo +certigo.exe \ No newline at end of file diff --git a/lib/tls.go b/lib/tls.go new file mode 100644 index 0000000..54faa59 --- /dev/null +++ b/lib/tls.go @@ -0,0 +1,107 @@ +package lib + +import ( + "bufio" + "bytes" + "crypto/tls" + "text/template" + + "github.com/fatih/color" +) + +// TLSDescription has the basic information about a TLS connection +type TLSDescription struct { + Version string + Cipher string +} + +var tlsLayout = `** TLS Connection ** +Version: {{.Version}} +Cipher Suite: {{.Cipher}}` + +func tlscolor(d description) string { + c, ok := qualityColors[d.Quality] + if !ok { + return d.Name + } + return c.SprintFunc()(d.Name) +} + +// EncodeTLSToText returns a human readable string, suitable for certigo console output. +func EncodeTLSToText(tcs *tls.ConnectionState) string { + version := tlsVersions[tcs.Version] + cipher := cipherSuites[tcs.CipherSuite] + description := TLSDescription{ + Version: tlscolor(version), + Cipher: tlscolor(cipher), + } + t := template.New("TLS template") + t, err := t.Parse(tlsLayout) + if err != nil { + // Should never happen + panic(err) + } + var buffer bytes.Buffer + w := bufio.NewWriter(&buffer) + err = t.Execute(w, description) + if err != nil { + // Should never happen + panic(err) + } + w.Flush() + return string(buffer.Bytes()) +} + +// EncodeTLSToObject returns a JSON-marshallable description of a TLS connection +func EncodeTLSToObject(t *tls.ConnectionState) interface{} { + version := tlsVersions[t.Version] + cipher := cipherSuites[t.CipherSuite] + return &TLSDescription{ + version.Slug, + cipher.Slug, + } +} + +type description struct { + Name string // a human-friendly string + Slug string // a machine-friendly string + Quality uint8 // 0 = insecure, 1 = ok, 2 = good +} + +var qualityColors = map[uint8]*color.Color{ + 0: red, + 1: yellow, + 2: green, +} + +var tlsVersions = map[uint16]description{ + tls.VersionSSL30: {"SSL 3.0", "ssl_3_0", 0}, + tls.VersionTLS10: {"TLS 1.0", "tls_1_0", 0}, + tls.VersionTLS11: {"TLS 1.1", "tls_1_1", 1}, + tls.VersionTLS12: {"TLS 1.2", "tls_1_2", 2}, +} + +var cipherSuites = map[uint16]description{ + tls.TLS_RSA_WITH_RC4_128_SHA: {"TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_RC4_128_SHA", 0}, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 0}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA: {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", 0}, + tls.TLS_RSA_WITH_AES_256_CBC_SHA: {"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", 0}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", 0}, + tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {"TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", 0}, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", 0}, + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0}, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", 0}, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", 0}, +} diff --git a/main.go b/main.go index 05a0f88..a002c6a 100644 --- a/main.go +++ b/main.go @@ -101,6 +101,7 @@ func main() { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) os.Exit(1) } + result.TLSConnectionState = connState for _, cert := range connState.PeerCertificates { if *connectPem { pem.Encode(os.Stdout, lib.EncodeX509ToPEM(cert, nil)) @@ -124,6 +125,7 @@ func main() { blob, _ := json.Marshal(result) fmt.Println(string(blob)) } else if !*connectPem { + fmt.Fprintf(stdout, "%s\n", lib.EncodeTLSToText(result.TLSConnectionState)) for i, cert := range result.Certificates { fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1) fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert)) diff --git a/verify.go b/verify.go index 519bb22..6766b05 100644 --- a/verify.go +++ b/verify.go @@ -26,6 +26,8 @@ import ( "os" "strconv" + "crypto/tls" + "github.com/fatih/color" "github.com/square/certigo/lib" ) @@ -72,8 +74,9 @@ type simpleVerification struct { } type simpleResult struct { - Certificates []*x509.Certificate `json:"certificates"` - VerifyResult *simpleVerification `json:"verify_result,omitempty"` + Certificates []*x509.Certificate `json:"certificates"` + VerifyResult *simpleVerification `json:"verify_result,omitempty"` + TLSConnectionState *tls.ConnectionState } func (s simpleResult) MarshalJSON() ([]byte, error) { @@ -87,6 +90,9 @@ func (s simpleResult) MarshalJSON() ([]byte, error) { if s.VerifyResult != nil { out["verify_result"] = s.VerifyResult } + if s.TLSConnectionState != nil { + out["tls_connection"] = lib.EncodeTLSToObject(s.TLSConnectionState) + } return json.Marshal(out) } From 2a61c3e010cbf6c3a4f07be4d116a632315c253f Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Sun, 19 Feb 2017 18:03:50 -0800 Subject: [PATCH 4/8] Update README for starttls and go 1.8 Note we support more STARTTLS protocols, and require go 1.8 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b81d561..007d02c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Certigo is a utility to examine and validate certificates to help with debugging **Validation and linting**: Not sure if your generated certificate is valid? Certigo can connect to remote servers to display and validate their certificate chains. It can also point out common errors on certififcates, such as using an older X.509 format, signatures with outdated hashes, or keys that are too small. -**Supports MySQL and PostgreSQL**: Trying to debug SSL/TLS connections on a database? Certigo supports establishing connections via StartTLS protocols for MySQL and PostgreSQL, making it possible debug connection issues or scan for expired certificates more easily. +**Supports STARTTLS Protocols**: Trying to debug SSL/TLS connections on a database or mail server? Certigo supports establishing connections via StartTLS protocols for MySQL, PostgreSQL, SMTP, and LDAP, making it possible debug connection issues or scan for expired certificates more easily. **Scripting support**: All commands in certigo have support for optional JSON output, which can be used in shell scripts to analyze or filter output. Combine certigo with [jq](https://stedolan.github.io/jq) to find all certificates in a bundle that are signed with SHA1-RSA, or filter for CA certificates, or whatever you need! @@ -27,7 +27,7 @@ On macOS you can also use homebrew to install: brew install certigo -Note that certigo requires Go 1.5 or later to build. +Note that certigo requires Go 1.8 or later to build. ### Develop From a2d32441fcb4854f5fa23a19a5f06908e29f6682 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Sun, 19 Feb 2017 18:06:57 -0800 Subject: [PATCH 5/8] Update README with TLS connect output --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 007d02c..23c62d3 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,9 @@ Display & validate certificates from a remote server (also supports `--start-tls ``` $ certigo connect squareup.com:443 +** TLS Connection ** +Version: TLS 1.2 +Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ** CERTIFICATE 1 ** Serial: 260680855742043049380997676879525498489 Not Before: 2016-07-15 20:15:52 +0000 UTC From 5d84bacd4ffc717fc6acc4f6450efabd0b29dc0d Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 21 Feb 2017 11:55:56 -0800 Subject: [PATCH 6/8] Add quality tags RC4 and 3DES get 0. ECDHE and GCM or CHACHA get 2. Everything else is a 1 --- lib/tls.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/tls.go b/lib/tls.go index 54faa59..2e3a76c 100644 --- a/lib/tls.go +++ b/lib/tls.go @@ -84,24 +84,24 @@ var tlsVersions = map[uint16]description{ var cipherSuites = map[uint16]description{ tls.TLS_RSA_WITH_RC4_128_SHA: {"TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_RC4_128_SHA", 0}, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 0}, - tls.TLS_RSA_WITH_AES_128_CBC_SHA: {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", 0}, - tls.TLS_RSA_WITH_AES_256_CBC_SHA: {"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", 0}, - tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", 0}, - tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {"TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", 0}, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", 0}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA: {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_RSA_WITH_AES_256_CBC_SHA: {"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", 1}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", 1}, + tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {"TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", 1}, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", 1}, tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 1}, tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0}, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0}, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", 0}, - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 1}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 1}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1}, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 2}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 2}, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 2}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 2}, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", 2}, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", 2}, } From f5c61e3ffcca057f52a828bdc2db8905356b2104 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 21 Feb 2017 12:19:16 -0800 Subject: [PATCH 7/8] Add fallback for unknown TLS and cipher suites --- lib/tls.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/tls.go b/lib/tls.go index 2e3a76c..884092b 100644 --- a/lib/tls.go +++ b/lib/tls.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "crypto/tls" + "fmt" "text/template" "github.com/fatih/color" @@ -29,8 +30,8 @@ func tlscolor(d description) string { // EncodeTLSToText returns a human readable string, suitable for certigo console output. func EncodeTLSToText(tcs *tls.ConnectionState) string { - version := tlsVersions[tcs.Version] - cipher := cipherSuites[tcs.CipherSuite] + version := lookup(tlsVersions, tcs.Version) + cipher := lookup(cipherSuites, tcs.CipherSuite) description := TLSDescription{ Version: tlscolor(version), Cipher: tlscolor(cipher), @@ -54,14 +55,24 @@ func EncodeTLSToText(tcs *tls.ConnectionState) string { // EncodeTLSToObject returns a JSON-marshallable description of a TLS connection func EncodeTLSToObject(t *tls.ConnectionState) interface{} { - version := tlsVersions[t.Version] - cipher := cipherSuites[t.CipherSuite] + version := lookup(tlsVersions, t.Version) + cipher := lookup(cipherSuites, t.CipherSuite) return &TLSDescription{ version.Slug, cipher.Slug, } } +// Just a map lookup with a default +func lookup(descriptions map[uint16]description, what uint16) description { + v, ok := descriptions[what] + if !ok { + unknown := fmt.Sprintf("UNKNOWN_%x", what) + return description{unknown, unknown, 0} + } + return v +} + type description struct { Name string // a human-friendly string Slug string // a machine-friendly string From b9352020ee116a16d7937cb1c2c4340942b98c3e Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 21 Feb 2017 12:20:25 -0800 Subject: [PATCH 8/8] go fmt --- lib/tls.go | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/tls.go b/lib/tls.go index 884092b..9daafd3 100644 --- a/lib/tls.go +++ b/lib/tls.go @@ -93,26 +93,26 @@ var tlsVersions = map[uint16]description{ } var cipherSuites = map[uint16]description{ - tls.TLS_RSA_WITH_RC4_128_SHA: {"TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_RC4_128_SHA", 0}, - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 0}, - tls.TLS_RSA_WITH_AES_128_CBC_SHA: {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", 1}, - tls.TLS_RSA_WITH_AES_256_CBC_SHA: {"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", 1}, - tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", 1}, - tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {"TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", 1}, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", 1}, - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0}, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 1}, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 1}, - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0}, - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 1}, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 1}, + tls.TLS_RSA_WITH_RC4_128_SHA: {"TLS_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_RC4_128_SHA", 0}, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 0}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA: {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_RSA_WITH_AES_256_CBC_SHA: {"TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", 1}, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", 1}, + tls.TLS_RSA_WITH_AES_128_GCM_SHA256: {"TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", 1}, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384: {"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", 1}, + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0}, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 1}, + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 1}, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 1}, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 1}, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1}, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 2}, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1}, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 2}, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 2}, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 2}, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 2}, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 2}, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", 2}, - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", 2}, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", 2}, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", 2}, }