Skip to content

Commit

Permalink
Add check for certificate validity
Browse files Browse the repository at this point in the history
go test -v -run TestCerts
  • Loading branch information
dolmen committed Sep 21, 2021
1 parent 431795d commit 238c70f
Showing 1 changed file with 94 additions and 1 deletion.
95 changes: 94 additions & 1 deletion certifi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,104 @@

package gocertifi

import "testing"
import (
"crypto/x509"
"encoding/pem"
"testing"
"time"
)

func TestGetCerts(t *testing.T) {
certPool, err := CACerts()
if certPool == nil || err != nil || len(certPool.Subjects()) == 0 {
t.Errorf("Failed to return the certificates.")
}
}

func parsePEM(pemCerts []byte) (certs []*x509.Certificate, err error) {
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
certs = append(certs, cert)
}
return
}

func checkRootCertsPEM(t *testing.T, pemCerts []byte, when time.Time) (ok bool) {
now := time.Now()
t.Logf("Checking certificate validity on %s...", when)
certs, err := parsePEM(pemCerts)
if err != nil {
t.Error(err)
return false
}

roots := x509.NewCertPool()
for _, cert := range certs {
roots.AddCert(cert)
}

var minExpires time.Time
ok = true
for _, cert := range certs {
if !cert.IsCA {
t.Errorf("\u274C %s: not a certificate authority", cert.Subject)
}
// This check of keyusage is based on my understanding of key usage purposes
// https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.8.0.pdf
// Section 1.4.2 has no usage restrictions
if cert.KeyUsage&(x509.KeyUsage(-1)^(x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature)) != 0 {
t.Logf("\u26A0 %s key usage %#x (see constants at https://golang.org/pkg/crypto/x509/#KeyUsage)", cert.Subject, cert.KeyUsage)
} else if cert.KeyUsage&(x509.KeyUsageCertSign|x509.KeyUsageCRLSign) == 0 {
// If the certificate authority is not allowed to sign certificates, why is it here?
// https://cabforum.org/baseline-requirements-certificate-contents/#CA-Certificates
t.Logf("\u26A0 %s key usage %#x (see constants at https://golang.org/pkg/crypto/x509/#KeyUsage)", cert.Subject, cert.KeyUsage)
}
if minExpires.IsZero() || cert.NotAfter.Before(minExpires) {
minExpires = cert.NotAfter
}
// Check that the certificate is valid now
if cert.NotBefore.After(now) {
t.Errorf("\u274C %s: fails NotBefore check: %s", cert.Subject, cert.NotBefore)
continue
}
if cert.NotAfter.Before(now) {
t.Errorf("\u274C %s: fails NotAfter check: \033[31m%s\033[m", cert.Subject, cert.NotAfter)
// ... and that it will still be valid later
} else if cert.NotAfter.Before(when) {
t.Logf("\u26A0 %s: fails NotAfter check: \033[31m%s\033[m", cert.Subject, cert.NotAfter)
continue
}
_, err := cert.Verify(x509.VerifyOptions{
Roots: roots,
CurrentTime: when,
})
if err != nil {
t.Errorf("\u274C %s: %s", cert.Subject, err)
ok = false
} else {
t.Logf("\u2705 %s (expires: %s)", cert.Subject, cert.NotAfter)
}
}
if ok {
t.Log("Success.")
t.Logf("MinExpire: %s", minExpires)
}
return
}

func TestCerts(t *testing.T) {
// Check that certificates will still be valid in 3 months
checkRootCertsPEM(t, []byte(pemcerts), time.Now().AddDate(0, 3, 0))
}

0 comments on commit 238c70f

Please sign in to comment.