Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Last active October 11, 2022 04:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hnakamur/cc513f7f12b020d8e13db0680728e238 to your computer and use it in GitHub Desktop.
Save hnakamur/cc513f7f12b020d8e13db0680728e238 to your computer and use it in GitHub Desktop.
Validate certificate key pair and hostname in Go
package main
import (
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
"log"
"golang.org/x/net/idna"
)
func main() {
var (
certFile string
keyFile string
hostname string
)
flag.StringVar(&certFile, "cert", "", "certificate file path")
flag.StringVar(&keyFile, "key", "", "key file path")
flag.StringVar(&hostname, "hostname", "", "hostname")
flag.Parse()
err := ValidateCertificateKeyPairAndHostname(certFile, keyFile, hostname)
if err != nil {
log.Fatal(err)
}
}
func ValidateCertificateKeyPairAndHostname(certFile, keyFile, hostname string) error {
pair, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return fmt.Errorf("failed to load certificate and key file; %s", err)
}
cert, err := x509.ParseCertificate(pair.Certificate[0])
if err != nil {
return fmt.Errorf("failed to parse certificate; %s", err)
}
roots, err := x509.SystemCertPool()
if err != nil {
return fmt.Errorf("failed to get system certificate pool; %s", err)
}
intermediates := x509.NewCertPool()
for i := 1; i < len(pair.Certificate); i++ {
inter, err := x509.ParseCertificate(pair.Certificate[1])
if err != nil {
return fmt.Errorf("failed to parse intermediate certificate; %s", err)
}
intermediates.AddCert(inter)
}
asciiHostname, err := idna.ToASCII(hostname)
if err != nil {
return fmt.Errorf("fail to convert to punycode; %s", err)
}
opts := x509.VerifyOptions{
DNSName: asciiHostname,
Intermediates: intermediates,
Roots: roots,
}
_, err = cert.Verify(opts)
if err != nil {
return fmt.Errorf("failed to verify certificate; %s", err.Error())
}
return nil
}
@hnakamur
Copy link
Author

example outputs:

$ sudo ~admin/gocode/bin/validate-certificate -cert /etc/startssl/xn--gckc5l.naruh.com_with_root.crt -key /etc/startssl/xn--gckc5l.naruh.com.key -hostname ウェブ.naruh.com
$ sudo ~admin/gocode/bin/validate-certificate -cert /etc/startssl/xn--gckc5l.naruh.com_with_root.crt -key /etc/startssl/xn--gckc5l.naruh.com.key -hostname なる.naruh.com                         
2016/09/29 11:33:29 failed to verify certificate; x509: certificate is valid for xn--gckc5l.naruh.com, not xn--q9j6c.naruh.com

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