Commit a163626d authored by ale's avatar ale

Check for CA validity when verifying a certificate

In 'x509ca check', add an option to pass the CA certificate so that
the tool can verify that it actually signed the service
certificate (used to detect CA changes).
parent c896ea03
Pipeline #984 failed with stages
in 20 seconds
......@@ -14,13 +14,14 @@ import (
)
type checkCmd struct {
subject pkixNameFlag
certPath string
sanList stringListFlag
ipList ipListFlag
isClient bool
isServer bool
renewDays int
subject pkixNameFlag
certPath string
caCertPath string
sanList stringListFlag
ipList ipListFlag
isClient bool
isServer bool
renewDays int
}
func (c *checkCmd) Name() string { return "check" }
......@@ -37,6 +38,7 @@ or IP lists) and expiration time.
func (c *checkCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&c.certPath, "cert", "", "Certificate `path`")
f.StringVar(&c.caCertPath, "ca-cert", "", "CA certificate path")
f.Var(&c.subject, "subject", "Certificate subject (in CN=.../OU=.../etc format)")
f.Var(&c.sanList, "alt", "Add `subjectAltName` to the certificate")
f.Var(&c.ipList, "ip", "Add an `IP` to the certificate")
......@@ -57,12 +59,25 @@ func (c *checkCmd) Execute(ctx context.Context, _ *flag.FlagSet, _ ...interface{
return subcommands.ExitFailure
}
var caCert *x509.Certificate
if c.caCertPath != "" {
caCert, err = loadCertificate(c.caCertPath)
if err != nil {
log.Printf("ERROR: could not load CA certificate: %v", err)
return subcommands.ExitFailure
}
}
switch {
case aboutToExpire(cert, c.renewDays):
fmt.Printf("certificate must be renewed (about to expire)\n")
case !certificateMetadataEqual(cert, c.subject.Name, c.sanList, c.ipList, c.isClient, c.isServer):
fmt.Printf("certificate must be renewed (metadata change)\n")
case caCert != nil && !isSignedBy(cert, caCert):
fmt.Printf("certificate must be renewed (signed by a different CA)\n")
default:
return subcommands.ExitSuccess
}
......@@ -89,6 +104,12 @@ func certificateMetadataEqual(cert *x509.Certificate, subject *pkix.Name, sanLis
(hasExtUsage(cert, x509.ExtKeyUsageServerAuth) == isServer))
}
func isSignedBy(cert, ca *x509.Certificate) bool {
return cert.CheckSignatureFrom(ca) == nil
}
// TODO: add "signedByCA()" check to verify that the certificate has been signed by the CA we have.
func pkixEqual(a, b pkix.Name) bool {
return (a.CommonName == b.CommonName &&
compareStringList(a.Country, b.Country) &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment