Skip to content

Commit ce69897

Browse files
committed
show certs even when invalid remote cert (show warning)
1 parent d550b55 commit ce69897

File tree

6 files changed

+49
-35
lines changed

6 files changed

+49
-35
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ that consumes many of the functionalities of the library:
1818

1919
```
2020
$ ./certmin
21-
certmin, 0.5.7. A minimalist certificate utility.
21+
certmin, 0.5.9. A minimalist certificate utility.
2222
See https://github.com/nxadm/certmin for more information.
2323
2424
Usage:

cmd/certmin/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ go get github.com/nxadm/certmin/cmd/certmin
3030

3131
```
3232
$ ./certmin
33-
certmin, 0.5.7. A minimalist certificate utility.
33+
certmin, 0.5.9. A minimalist certificate utility.
3434
See https://github.com/nxadm/certmin for more information.
3535
3636
Usage:

cmd/certmin/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
const (
12-
version = "0.5.7"
12+
version = "0.5.9"
1313
website = "https://github.com/nxadm/certmin"
1414
timeOut = 5 * time.Second
1515
)

cmd/certmin/util.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func getCerts(input string, sb *strings.Builder) ([]*x509.Certificate, error) {
7575
if remote {
7676
certs, warn, err = certmin.RetrieveCertsFromAddr(loc, timeOut)
7777
if warn != nil {
78-
sb.WriteString(color.YellowString(warn.Error()))
78+
sb.WriteString(color.YellowString(warn.Error()) + "\n\n")
7979
}
8080
if err != nil {
8181
return nil, err

net.go

+34-31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/tls"
55
"crypto/x509"
66
"errors"
7+
"fmt"
78
"io/ioutil"
89
"net"
910
"net/http"
@@ -18,40 +19,17 @@ import (
1819
// of the server), an error with a warning (e.g. mismatch between the hostname and the CN or DNS alias
1920
// in the certificate) and an error in case of failure.
2021
func RetrieveCertsFromAddr(addr string, timeOut time.Duration) ([]*x509.Certificate, error, error) {
21-
conn, err := net.DialTimeout("tcp", addr, timeOut)
22-
if err != nil {
23-
return nil, nil, err
24-
}
25-
26-
var warning error
27-
rx := regexp.MustCompile(":\\d+$")
28-
tlsConn := tls.Client(conn, &tls.Config{ServerName: rx.ReplaceAllString(addr, "")})
29-
err = tlsConn.SetDeadline(time.Now().Add(timeOut))
30-
if err != nil {
31-
return nil, nil, err
32-
}
33-
err = tlsConn.Handshake()
34-
if err != nil {
35-
tlsConn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
36-
err2 := tlsConn.SetDeadline(time.Now().Add(timeOut))
37-
if err2 != nil {
38-
return nil, nil, err2
39-
}
40-
err2 = tlsConn.Handshake()
41-
if err2 != nil {
42-
return nil, nil, err2
22+
var certs []*x509.Certificate
23+
var err, warn error
24+
certs, warn = connectAndRetrieve(addr, timeOut, false)
25+
if warn != nil {
26+
certs, err = connectAndRetrieve(addr, timeOut, true)
27+
if err != nil {
28+
warn = nil
4329
}
44-
warning = err
45-
}
46-
defer tlsConn.Close()
47-
defer conn.Close()
48-
49-
if len(tlsConn.ConnectionState().PeerCertificates) == 0 {
50-
err := errors.New("no certificates found")
51-
return nil, warning, err
5230
}
5331

54-
return tlsConn.ConnectionState().PeerCertificates, warning, nil
32+
return certs, warn, err
5533
}
5634

5735
// RetrieveChainFromIssuerURLs retrieves the chain for a certificate by following the
@@ -67,6 +45,30 @@ func RetrieveChainFromIssuerURLs(cert *x509.Certificate, timeOut time.Duration)
6745
return chain, lastErr
6846
}
6947

48+
// connectAndRetrieve does the actual TLS calls
49+
func connectAndRetrieve(addr string, timeOut time.Duration, skipVerify bool) ([]*x509.Certificate, error) {
50+
serverName := regexp.MustCompile(":\\d+$").ReplaceAllString(addr, "")
51+
var tlsConfig tls.Config
52+
if skipVerify {
53+
tlsConfig.InsecureSkipVerify = true
54+
} else {
55+
tlsConfig.ServerName = serverName
56+
}
57+
58+
dialer := &net.Dialer{Timeout: timeOut}
59+
conn, err := tls.DialWithDialer(dialer, "tcp", addr, &tlsConfig)
60+
if err != nil {
61+
return nil, fmt.Errorf("[%s] %s", serverName, err)
62+
}
63+
defer conn.Close()
64+
65+
if len(conn.ConnectionState().PeerCertificates) == 0 {
66+
return nil, errors.New("no certificates found")
67+
}
68+
69+
return conn.ConnectionState().PeerCertificates, nil
70+
}
71+
7072
// recursiveHopCerts follows the URL links recursively
7173
func recursiveHopCerts(
7274
cert *x509.Certificate, chain *[]*x509.Certificate, lastErr *error, timeOut time.Duration) *x509.Certificate {
@@ -102,3 +104,4 @@ func recursiveHopCerts(
102104

103105
return nil
104106
}
107+

net_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ func TestRetrieveChainFromIssuerURLs(t *testing.T) {
5050
}
5151
}
5252

53+
54+
func TestConnectAndRetrieve(t *testing.T) {
55+
if os.Getenv("AUTHOR_TESTING") != "" {
56+
if os.Getenv("AUTHOR_TESTING") != "" {
57+
certs, err := connectAndRetrieve("github.com:443", 5*time.Second, false)
58+
assert.NoError(t, err)
59+
assert.True(t, len(certs) >= 2)
60+
}
61+
}
62+
}
63+
5364
func TestRecursiveHopCerts(t *testing.T) {
5465
if os.Getenv("AUTHOR_TESTING") != "" {
5566
certs, err := DecodeCertFile("t/kuleuven-be.pem", "")

0 commit comments

Comments
 (0)