Skip to content

Commit

Permalink
Merge pull request #4 from sonatype-nexus-community/feat/support-non-…
Browse files Browse the repository at this point in the history
…http-endpoints

feat: move from http specific testing to TCP
  • Loading branch information
madpah authored Oct 18, 2024
2 parents 1225f93 + 0b9380a commit c7a058c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 50 deletions.
57 changes: 23 additions & 34 deletions ssl-inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"errors"
"flag"
"fmt"
"net/http"
"net/url"
"os"
"runtime"
Expand Down Expand Up @@ -55,7 +54,6 @@ func main() {
} else {
log.SetLevel(log.InfoLevel)
}
// log.SetFormatter(&util.LogFormatter{Module: "SCANNER"})

flag.Usage = usage
flag.Parse()
Expand All @@ -69,6 +67,8 @@ func main() {
if err != nil {
println("Supplied endpoint is not well formed")
os.Exit(1)
} else {
println("Validated - conducting test against: " + *validatedEndpoint)
}

// Load System Root CAs
Expand All @@ -77,7 +77,7 @@ func main() {
// rootCAs = x509.NewCertPool()
// }

valid, messages, err := checkSSL(fmt.Sprintf("https://%s", *validatedEndpoint))
valid, messages, err := checkSSL(*validatedEndpoint)
if err != nil {
println(fmt.Sprintf("Error performing checks: %v", err))
os.Exit(1)
Expand Down Expand Up @@ -109,48 +109,37 @@ func checkSSL(endpoint string) (bool, []string, error) {
// RootCAs: rootCAs,
}

tr := &http.Transport{TLSClientConfig: config}
client := &http.Client{Transport: tr}
_, err := tls.Dial("tcp", endpoint, config)

req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
return false, messages, err
}
var certValidationError *tls.CertificateVerificationError
if errors.As(err, &certValidationError) {
//println("tls.CertificateVerificationError")
handled := false
if hostnameError, ok := certValidationError.Err.(x509.HostnameError); ok {
messages = append(messages, fmt.Sprintf("Certifcate for %s is not valid for %s", hostnameError.Certificate.Subject, endpoint))
handled = true
}

_, err = client.Do(req)
if certInvalidError, ok := certValidationError.Err.(x509.CertificateInvalidError); ok {
messages = append(messages, fmt.Sprintf("Certifcate for %s is invalid because: %s", certInvalidError.Cert.Subject, getInvalidReason(int(certInvalidError.Reason))))
handled = true
}

if err != nil {
var certValidationError *tls.CertificateVerificationError
var netUrlError *url.Error
if errors.As(err, &netUrlError) {
//println("url.Error")
if errors.As(netUrlError.Err, &certValidationError) {
//println("tls.CertificateVerificationError")
handled := false
if hostnameError, ok := certValidationError.Err.(x509.HostnameError); ok {
messages = append(messages, fmt.Sprintf("Certifcate for %s is not valid for %s", hostnameError.Certificate.Subject, endpoint))
handled = true
}

if certInvalidError, ok := certValidationError.Err.(x509.CertificateInvalidError); ok {
messages = append(messages, fmt.Sprintf("Certifcate for %s is invalid because: %s", certInvalidError.Cert.Subject, getInvalidReason(int(certInvalidError.Reason))))
handled = true
}

if unknownAuthorityError, ok := certValidationError.Err.(x509.UnknownAuthorityError); ok {
messages = append(messages, fmt.Sprintf(`Certifcate for %s is not trusted. This could be because:
if unknownAuthorityError, ok := certValidationError.Err.(x509.UnknownAuthorityError); ok {
messages = append(messages, fmt.Sprintf(`Certifcate for %s is not trusted. This could be because:
1. It is self-signed
2. It is signed by an unknown authority
3. The CA that signed this certificate is not a invalid Certificate Authority
It was signed by: %s`, unknownAuthorityError.Cert.Subject, unknownAuthorityError.Cert.Issuer.CommonName))
handled = true
}
handled = true
}

if !handled {
messages = append(messages, fmt.Sprintf("Certifcate for %s is invalid because: %s", endpoint, certValidationError.Error()))
}
if !handled {
messages = append(messages, fmt.Sprintf("Certifcate for %s is invalid because: %s", endpoint, certValidationError.Error()))
}
// }
} else {
println("Failed making request")
println(err.Error)
Expand Down
43 changes: 27 additions & 16 deletions ssl-inspector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,46 @@ import (

func TestCheckSSL(t *testing.T) {
t.Run("validAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://badssl.com")
valid, messages, err := checkSSL("badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 0, len(messages))
assert.True(t, valid)
})

t.Run("expiredAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://expired.badssl.com")
valid, messages, err := checkSSL("expired.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.Equal(t, "Certifcate for CN=*.badssl.com,OU=Domain Control Validated+OU=PositiveSSL Wildcard is invalid because: Certificate expired", messages[0])
assert.False(t, valid)
})

t.Run("expiredAndTrustedByOSWithPort", func(t *testing.T) {
valid, messages, err := checkSSL("https://expired.badssl.com:443")
valid, messages, err := checkSSL("expired.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.Equal(t, "Certifcate for CN=*.badssl.com,OU=Domain Control Validated+OU=PositiveSSL Wildcard is invalid because: Certificate expired", messages[0])
assert.False(t, valid)
})

t.Run("wrongHostAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://wrong.host.badssl.com")
valid, messages, err := checkSSL("wrong.host.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.Equal(t, "Certifcate for CN=*.badssl.com is not valid for wrong.host.badssl.com:443", messages[0])
assert.False(t, valid)
})

t.Run("unknownAuthorityAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://self-signed.badssl.com")
valid, messages, err := checkSSL("self-signed.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.Equal(t, "Certifcate for CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US is not trusted. This could be because:\n\t1. It is self-signed\n\t2. It is signed by an unknown authority\n\t3. The CA that signed this certificate is not a invalid Certificate Authority\n\t\n\tIt was signed by: *.badssl.com", messages[0])
assert.False(t, valid)
})

t.Run("untrustedRootAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://untrusted-root.badssl.com")
valid, messages, err := checkSSL("untrusted-root.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.False(t, valid)
Expand All @@ -69,23 +73,24 @@ func TestCheckSSL(t *testing.T) {
if runtime.GOOS == "darwin" {
// Looks like Windows and Linux do not do realtime CRL checks
t.Run("revokedAndTrustedByOS", func(t *testing.T) {
valid, messages, err := checkSSL("https://revoked.badssl.com")
valid, messages, err := checkSSL("revoked.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
assert.Equal(t, "Certifcate for revoked.badssl.com:443 is invalid because: tls: failed to verify certificate: x509: “revoked.badssl.com” certificate is revoked", messages[0])
assert.False(t, valid)
})
}
}

// func TestSingleCert(t *testing.T) {
// valid, messages, err := checkSSL("https://revoked.badssl.com")
// assert.NoError(t, err)
// assert.Equal(t, 1, len(messages))
// for _, m := range messages {
// println(m)
// }
// assert.False(t, valid)
// }
func TestSingleCert(t *testing.T) {
valid, messages, err := checkSSL("expired.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, 1, len(messages))
for _, m := range messages {
println(m)
}
assert.False(t, valid)
}

func TestParseEndpoints(t *testing.T) {
t.Run("httpsNoPortSpecified", func(t *testing.T) {
Expand All @@ -111,4 +116,10 @@ func TestParseEndpoints(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "badssl.com:555", *domain)
})

t.Run("ldapsPortSpecified", func(t *testing.T) {
domain, err := validateEndpoint("ldaps://revoked.badssl.com:443")
assert.NoError(t, err)
assert.Equal(t, "revoked.badssl.com:443", *domain)
})
}

0 comments on commit c7a058c

Please sign in to comment.