Skip to content

Instantly share code, notes, and snippets.

Last active April 28, 2022 13:45
Show Gist options
  • Save devtdeng/4f6adcb5a306f2ae035a2e7d9f724d17 to your computer and use it in GitHub Desktop.
Save devtdeng/4f6adcb5a306f2ae035a2e7d9f724d17 to your computer and use it in GitHub Desktop.
Verify a certificate with chain with golang crypto library
package main
import (
func main() {
log.Printf("Usage: verify_certificate SERVER_NAME CERT.pem CHAIN.pem")
serverName := os.Args[1]
certPEM, err := ioutil.ReadFile(os.Args[2])
if err != nil {
rootPEM, err := ioutil.ReadFile(os.Args[3])
if err != nil {
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(rootPEM))
if !ok {
panic("failed to parse root certificate")
block, _ := pem.Decode([]byte(certPEM))
if block == nil {
panic("failed to parse certificate PEM")
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
panic("failed to parse certificate: " + err.Error())
opts := x509.VerifyOptions{
Roots: roots,
DNSName: serverName,
Intermediates: x509.NewCertPool(),
if _, err := cert.Verify(opts); err != nil {
panic("failed to verify certificate: " + err.Error())
log.Printf("verification succeeds")
Copy link

This example is not solving what people are searching for when they find it. The so-called "chain" in this example is trusted and all of its certs are put into the root store. While it is common to place some intermediate certs into a root store for faster verification, certs in the root store do not form a chain. Any certificate in the root store is trusted absolutely without having traverse further up a chain. Hence the word "root".

Can you modify the example to do what the title says? Start with a root certificate and verify a certificate that has one or more intermediate certificates attached to it as a chain.

Copy link

davbo commented Aug 21, 2019

This example from the docs is likely what people landing here are looking for:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment