Skip to content

Commit

Permalink
show certs even when invalid remote cert (show warning)
Browse files Browse the repository at this point in the history
  • Loading branch information
nxadm committed Jan 26, 2021
1 parent d550b55 commit ce69897
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ that consumes many of the functionalities of the library:

```
$ ./certmin
certmin, 0.5.7. A minimalist certificate utility.
certmin, 0.5.9. A minimalist certificate utility.
See https://github.com/nxadm/certmin for more information.
Usage:
Expand Down
2 changes: 1 addition & 1 deletion cmd/certmin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ go get github.com/nxadm/certmin/cmd/certmin

```
$ ./certmin
certmin, 0.5.7. A minimalist certificate utility.
certmin, 0.5.9. A minimalist certificate utility.
See https://github.com/nxadm/certmin for more information.
Usage:
Expand Down
2 changes: 1 addition & 1 deletion cmd/certmin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

const (
version = "0.5.7"
version = "0.5.9"
website = "https://github.com/nxadm/certmin"
timeOut = 5 * time.Second
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/certmin/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func getCerts(input string, sb *strings.Builder) ([]*x509.Certificate, error) {
if remote {
certs, warn, err = certmin.RetrieveCertsFromAddr(loc, timeOut)
if warn != nil {
sb.WriteString(color.YellowString(warn.Error()))
sb.WriteString(color.YellowString(warn.Error()) + "\n\n")
}
if err != nil {
return nil, err
Expand Down
65 changes: 34 additions & 31 deletions net.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
Expand All @@ -18,40 +19,17 @@ import (
// of the server), an error with a warning (e.g. mismatch between the hostname and the CN or DNS alias
// in the certificate) and an error in case of failure.
func RetrieveCertsFromAddr(addr string, timeOut time.Duration) ([]*x509.Certificate, error, error) {
conn, err := net.DialTimeout("tcp", addr, timeOut)
if err != nil {
return nil, nil, err
}

var warning error
rx := regexp.MustCompile(":\\d+$")
tlsConn := tls.Client(conn, &tls.Config{ServerName: rx.ReplaceAllString(addr, "")})
err = tlsConn.SetDeadline(time.Now().Add(timeOut))
if err != nil {
return nil, nil, err
}
err = tlsConn.Handshake()
if err != nil {
tlsConn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
err2 := tlsConn.SetDeadline(time.Now().Add(timeOut))
if err2 != nil {
return nil, nil, err2
}
err2 = tlsConn.Handshake()
if err2 != nil {
return nil, nil, err2
var certs []*x509.Certificate
var err, warn error
certs, warn = connectAndRetrieve(addr, timeOut, false)
if warn != nil {
certs, err = connectAndRetrieve(addr, timeOut, true)
if err != nil {
warn = nil
}
warning = err
}
defer tlsConn.Close()
defer conn.Close()

if len(tlsConn.ConnectionState().PeerCertificates) == 0 {
err := errors.New("no certificates found")
return nil, warning, err
}

return tlsConn.ConnectionState().PeerCertificates, warning, nil
return certs, warn, err
}

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

// connectAndRetrieve does the actual TLS calls
func connectAndRetrieve(addr string, timeOut time.Duration, skipVerify bool) ([]*x509.Certificate, error) {
serverName := regexp.MustCompile(":\\d+$").ReplaceAllString(addr, "")
var tlsConfig tls.Config
if skipVerify {
tlsConfig.InsecureSkipVerify = true
} else {
tlsConfig.ServerName = serverName
}

dialer := &net.Dialer{Timeout: timeOut}
conn, err := tls.DialWithDialer(dialer, "tcp", addr, &tlsConfig)
if err != nil {
return nil, fmt.Errorf("[%s] %s", serverName, err)
}
defer conn.Close()

if len(conn.ConnectionState().PeerCertificates) == 0 {
return nil, errors.New("no certificates found")
}

return conn.ConnectionState().PeerCertificates, nil
}

// recursiveHopCerts follows the URL links recursively
func recursiveHopCerts(
cert *x509.Certificate, chain *[]*x509.Certificate, lastErr *error, timeOut time.Duration) *x509.Certificate {
Expand Down Expand Up @@ -102,3 +104,4 @@ func recursiveHopCerts(

return nil
}

11 changes: 11 additions & 0 deletions net_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ func TestRetrieveChainFromIssuerURLs(t *testing.T) {
}
}


func TestConnectAndRetrieve(t *testing.T) {
if os.Getenv("AUTHOR_TESTING") != "" {
if os.Getenv("AUTHOR_TESTING") != "" {
certs, err := connectAndRetrieve("github.com:443", 5*time.Second, false)
assert.NoError(t, err)
assert.True(t, len(certs) >= 2)
}
}
}

func TestRecursiveHopCerts(t *testing.T) {
if os.Getenv("AUTHOR_TESTING") != "" {
certs, err := DecodeCertFile("t/kuleuven-be.pem", "")
Expand Down

0 comments on commit ce69897

Please sign in to comment.