Skip to content

Commit

Permalink
Merge pull request #14 from genkiroid/support-specify-cipher-suite
Browse files Browse the repository at this point in the history
Enable to specify cipher suite
  • Loading branch information
genkiroid committed Sep 23, 2019
2 parents 7c2eaa0 + 5d33fcf commit 3b2e52a
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
40 changes: 39 additions & 1 deletion README.md
Expand Up @@ -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
Expand Down Expand Up @@ -155,7 +159,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
```

Expand All @@ -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)
Expand Down
50 changes: 50 additions & 0 deletions cert.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions cert_test.go
Expand Up @@ -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())
Expand Down
4 changes: 4 additions & 0 deletions cmd/cert/main.go
Expand Up @@ -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. ")
Expand All @@ -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 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 {
Expand All @@ -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 {
Expand Down

0 comments on commit 3b2e52a

Please sign in to comment.