From 32e3ebd57f80284fb96c14fcca39c2cd11eebf60 Mon Sep 17 00:00:00 2001 From: genkiroid Date: Sun, 22 Sep 2019 01:03:49 +0900 Subject: [PATCH 1/4] Support specify cipher suite --- cert.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ cert_test.go | 16 ++++++++++++++++ cmd/cert/main.go | 4 ++++ 3 files changed, 70 insertions(+) diff --git a/cert.go b/cert.go index 7586b36..1d12682 100644 --- a/cert.go +++ b/cert.go @@ -19,6 +19,36 @@ var SkipVerify = false var UTC = false +var CipherSuite = "" + +var cipherSuites = map[string]uint16{ + "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + "TLS_AES_128_GCM_SHA256": tls.TLS_AES_128_GCM_SHA256, + "TLS_AES_256_GCM_SHA384": tls.TLS_AES_256_GCM_SHA384, + "TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256, +} + var userTempl string var TimeoutSeconds = 3 @@ -78,12 +108,32 @@ type Cert struct { certChain []*x509.Certificate } +func cipherSuite() ([]uint16, error) { + if CipherSuite == "" { + return nil, nil + } + + var cs []uint16 + cs = []uint16{cipherSuites[CipherSuite]} + if cs[0] == 0 { + return nil, fmt.Errorf("%s is unsupported cipher suite.", CipherSuite) + } + return cs, nil +} + var serverCert = func(host, port string) ([]*x509.Certificate, string, error) { d := &net.Dialer{ Timeout: time.Duration(TimeoutSeconds) * time.Second, } + + cs, err := cipherSuite() + if err != nil { + return []*x509.Certificate{&x509.Certificate{}}, "", err + } + conn, err := tls.DialWithDialer(d, "tcp", host+":"+port, &tls.Config{ InsecureSkipVerify: SkipVerify, + CipherSuites: cs, }) if err != nil { return []*x509.Certificate{&x509.Certificate{}}, "", err diff --git a/cert_test.go b/cert_test.go index cbb4215..ffe2a43 100644 --- a/cert_test.go +++ b/cert_test.go @@ -265,6 +265,22 @@ func TestCertChain(t *testing.T) { } } +func TestCipherSuite(t *testing.T) { + CipherSuite = "TLS_CHACHA20_POLY1305_SHA256" + if _, err := cipherSuite(); err != nil { + t.Errorf(`unexpected err %s, want nil`, err.Error()) + } +} + +func TestCipherSuiteError(t *testing.T) { + CipherSuite = "UNSUPPORTED_CIPHER_SUITE" + if _, err := cipherSuite(); err == nil { + t.Error(`unexpected nil, want error`) + } else if err.Error() != "UNSUPPORTED_CIPHER_SUITE is unsupported cipher suite." { + t.Errorf(`unexpected err message, want %q`, "UNSUPPORTED_CIPHER_SUITE is unsupported cipher suite.") + } +} + func TestMain(m *testing.M) { setup() os.Exit(m.Run()) diff --git a/cmd/cert/main.go b/cmd/cert/main.go index c0d999c..b72fea7 100644 --- a/cmd/cert/main.go +++ b/cmd/cert/main.go @@ -17,6 +17,7 @@ func main() { var utc bool var timeout int var showVersion bool + var cipherSuite string flag.StringVar(&format, "f", "simple table", "Output format. md: as markdown, json: as JSON. ") flag.StringVar(&format, "format", "simple table", "Output format. md: as markdown, json: as JSON. ") @@ -30,6 +31,8 @@ func main() { flag.IntVar(&timeout, "timeout", 3, "Timeout seconds.") flag.BoolVar(&showVersion, "v", false, "Show version.") flag.BoolVar(&showVersion, "version", false, "Show version.") + flag.StringVar(&cipherSuite, "c", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher cuites.") + flag.StringVar(&cipherSuite, "cipher", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher cuites.") flag.Parse() if showVersion { @@ -43,6 +46,7 @@ func main() { cert.SkipVerify = skipVerify cert.UTC = utc cert.TimeoutSeconds = timeout + cert.CipherSuite = cipherSuite certs, err = cert.NewCerts(flag.Args()) if err != nil { From dbb5f1509e65b661f1b6b690eaa8953af5b4a050 Mon Sep 17 00:00:00 2001 From: genkiroid Date: Sun, 22 Sep 2019 14:15:53 +0900 Subject: [PATCH 2/4] Typo --- cmd/cert/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/cert/main.go b/cmd/cert/main.go index b72fea7..bc5f362 100644 --- a/cmd/cert/main.go +++ b/cmd/cert/main.go @@ -31,8 +31,8 @@ func main() { flag.IntVar(&timeout, "timeout", 3, "Timeout seconds.") flag.BoolVar(&showVersion, "v", false, "Show version.") flag.BoolVar(&showVersion, "version", false, "Show version.") - flag.StringVar(&cipherSuite, "c", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher cuites.") - flag.StringVar(&cipherSuite, "cipher", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher cuites.") + flag.StringVar(&cipherSuite, "c", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher suites.") + flag.StringVar(&cipherSuite, "cipher", "", "Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher suites.") flag.Parse() if showVersion { From 2befa06217b91e0d7bbaec9d913da9d1a80b5fd5 Mon Sep 17 00:00:00 2001 From: genkiroid Date: Sun, 22 Sep 2019 14:22:36 +0900 Subject: [PATCH 3/4] Fix example command for Windows cmd --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af9a0c5..abe73fb 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ Use `cert -t`. By direct string. ```sh -$ cert -t '{{range .}}{{.Issuer}}{{end}}' github.com +$ cert -t "{{range .}}{{.Issuer}}{{end}}" github.com DigiCert SHA2 Extended Validation Server CA ``` From 5d33fcfb776d5714a83f9cba0f3ac20bfd2035d3 Mon Sep 17 00:00:00 2001 From: genkiroid Date: Sun, 22 Sep 2019 14:44:31 +0900 Subject: [PATCH 4/4] Update README --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/README.md b/README.md index abe73fb..df1bb77 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,10 @@ Error: ```sh $ cert --help Usage of cert: + -c string + Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher suites. + -cipher string + Specify cipher suite. Refer to https://golang.org/pkg/crypto/tls/#pkg-constants for supported cipher suites. -f string Output format. md: as markdown, json: as JSON. (default "simple table") -format string @@ -172,6 +176,40 @@ Issuer: DigiCert High Assurance EV Root CA ``` +### Specify cipher suite + +see https://github.com/genkiroid/cert/issues/13 + +You can specify cipher suite. +As a result, you can get the information of each certificate. + +Note that the issuers are different in the following example. + +```sh +# Get information of the certificate using RSA public key algorithm. +$ cert -cipher TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 cloudflaressl.com +DomainName: cloudflaressl.com +IP: 104.20.47.142 +Issuer: COMODO RSA Domain Validation Secure Server CA 2 +NotBefore: 2019-08-23 09:00:00 +0900 JST +NotAfter: 2020-03-01 08:59:59 +0900 JST +CommonName: ssl509631.cloudflaressl.com +SANs: [ssl509631.cloudflaressl.com *.cloudflaressl.com cloudflaressl.com] +Error: + +# Get information of the certificate using ECDSA public key algorithm. +$ cert -cipher TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 cloudflaressl.com +DomainName: cloudflaressl.com +IP: 104.20.48.142 +Issuer: COMODO ECC Domain Validation Secure Server CA 2 +NotBefore: 2019-08-23 09:00:00 +0900 JST +NotAfter: 2020-03-01 08:59:59 +0900 JST +CommonName: ssl509632.cloudflaressl.com +SANs: [ssl509632.cloudflaressl.com *.cloudflaressl.com cloudflaressl.com] +Error: + +``` + ## License [MIT](https://github.com/genkiroid/cert/blob/master/LICENSE)