How to perform https request with go against incomplete TLS certificate?
To resolve this, I just updated the system certificate store on the client to include the missing intermediate certificate.
The client was running on an Ubuntu based server, so this fixed the issue:
#download certificate
cd /usr/local/share/ca-certificates
curl -O https://symantec.tbs-certificats.com/SymantecSSG4.crt
#dump the fingerprint
openssl x509 -noout -fingerprint -sha256 -inform pem -in SymantecSSG4.crt
I checked the output matched the fingerprint the test tool reported I was missing:
SHA256 Fingerprint=EA:E7:2E:B4:54:BF:6C:39:77:EB:D2:89:E9:70:B2:F5:28:29:49:19:00:93:D0:D2:6F:98:D0:F0:D6:A9:CF:17
Then I updated the certificate store with this:
update-ca-certificates
I recently had a need for this and thought I would share my solution here. The reason browsers like Chrome can handle this is because they support the AIA extension of X.509, which provides the url to download a given certificates issuing certificate. Chrome then adds the issuing certificate to the chain and retries validation, walking up the path until it runs out of certificates or finds one issued by an approved root CA.
I've made a little library to support this in go. You can find it here: https://github.com/fcjr/aia-transport-go
Usage is as simple as using the provided custom configured http.Transport:
package main
import (
"fmt"
"log"
"net/http"
"github.com/fcjr/aia-transport-go"
)
func main() {
tr, err := aia.NewTransport()
if err != nil {
log.Fatal(err)
}
client := http.Client{
Transport: tr,
}
res, err := client.Get("https://incomplete-chain.badssl.com/")
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Status)
}