Skip to content

Instantly share code, notes, and snippets.

@vaughany
Created May 25, 2023 09:05
Show Gist options
  • Save vaughany/4354ddde74c9231f13ff7bb6330ad3f9 to your computer and use it in GitHub Desktop.
Save vaughany/4354ddde74c9231f13ff7bb6330ad3f9 to your computer and use it in GitHub Desktop.
Minimum code required to use Go library 'essentialkaos/sslscan' to programatically scan a URL using Qualys SSL Labs.
package main
// Qualys' SSL Labs is a great tool for testing a URL's security: https://www.ssllabs.com/ssltest/
// They provide an API so you can test URLs programatically: https://www.ssllabs.com/projects/ssllabs-apis/
//
// Essential Kaos created and maintains a Go library to interface to the SSL Labs API: https://github.com/essentialkaos/sslscan
// There were no examples of use for the above library.
//
// Essential Kaos created and maintains a CLI application to scan URLs, which uses his library: https://github.com/essentialkaos/sslcli
//
// This file is the minimum needed to scan a URL using EK's library and produce an alphabetical grade, cribbed from the `sslcli` repository.
// I thoroughly recommend checking out the `sslcli`` repostiory for fuller examples of how to use the `sslscan` library.
import (
"fmt"
"strings"
"time"
"github.com/essentialkaos/sslscan/v13"
)
type HostCheckInfo struct {
Host string `json:"host"`
Endpoints []EndpointCheckInfo `json:"endpoints"`
}
type EndpointCheckInfo struct {
Grade string `json:"grade"`
}
func main() {
var (
api *sslscan.API
checkInfo HostCheckInfo
)
host := "google.com"
api, err := sslscan.NewAPI("example-qualys-ssl-labs-testing", "0.0.1")
if err != nil {
panic(err)
}
checkInfo, err = checkHost(api, host)
if err != nil {
panic(err)
}
grades := []string{}
for _, endpoint := range checkInfo.Endpoints {
grades = append(grades, endpoint.Grade)
}
fmt.Printf("%s %s\n", checkInfo.Host, strings.Join(grades, ","))
// Debugging.
// fmt.Printf("%#v\n", checkInfo)
}
func checkHost(api *sslscan.API, host string) (HostCheckInfo, error) {
var (
info *sslscan.AnalyzeInfo
checkInfo = HostCheckInfo{
Host: host,
Endpoints: make([]EndpointCheckInfo, 0),
}
)
params := sslscan.AnalyzeParams{
Public: false, // Prevents the scan being listed on the SSL Labs website.
FromCache: true, // Will pull results from the SSL Labs cache, if present.
IgnoreMismatch: false, // If true, will ignore when the server certificate doesn't match the assessment hostname.
}
progress, err := api.Analyze(host, params)
if err != nil {
return checkInfo, err
}
for {
info, err = progress.Info(false, params.FromCache)
if err != nil {
return checkInfo, err
}
// Debugging.
// fmt.Printf("%#v\n", info)
if info.Status == sslscan.STATUS_ERROR {
return checkInfo, err
} else if info.Status == sslscan.STATUS_READY {
break
}
// Check the API every so often.
time.Sleep(5 * time.Second)
}
for _, endpoint := range info.Endpoints {
checkInfo.Endpoints = append(checkInfo.Endpoints, EndpointCheckInfo{
Grade: endpoint.Grade,
})
}
return checkInfo, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment