From 66fe4ffd6b49c0dd6b0d949e19afe6d06aefc03f Mon Sep 17 00:00:00 2001 From: Jack Doan Date: Thu, 12 Dec 2024 10:20:30 -0500 Subject: [PATCH] cert-v2: verify all certificates provided to us. If one or more certs fail, report which ones. --- cert/ca_pool.go | 2 +- cert/errors.go | 1 + cmd/nebula-cert/verify.go | 31 +++++++++++++++++++++---------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/cert/ca_pool.go b/cert/ca_pool.go index d52583035..2bf480f22 100644 --- a/cert/ca_pool.go +++ b/cert/ca_pool.go @@ -213,7 +213,7 @@ func (ncp *CAPool) GetCAForCert(c Certificate) (*CachedCertificate, error) { return signer, nil } - return nil, fmt.Errorf("could not find ca for the certificate") + return nil, ErrCaNotFound } // GetFingerprints returns an array of trusted CA fingerprints diff --git a/cert/errors.go b/cert/errors.go index ab18cf25f..60273a99d 100644 --- a/cert/errors.go +++ b/cert/errors.go @@ -17,6 +17,7 @@ var ( ErrInvalidPrivateKey = errors.New("invalid private key") ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve") ErrPublicPrivateKeyMismatch = errors.New("public key and private key are not a pair") + ErrCaNotFound = errors.New("could not find ca for the certificate") ErrPrivateKeyEncrypted = errors.New("private key must be decrypted") diff --git a/cmd/nebula-cert/verify.go b/cmd/nebula-cert/verify.go index 80cfef3c0..43930044a 100644 --- a/cmd/nebula-cert/verify.go +++ b/cmd/nebula-cert/verify.go @@ -1,6 +1,7 @@ package main import ( + "errors" "flag" "fmt" "io" @@ -60,18 +61,28 @@ func verify(args []string, out io.Writer, errOut io.Writer) error { if err != nil { return fmt.Errorf("unable to read crt; %s", err) } - - c, _, err := cert.UnmarshalCertificateFromPEM(rawCert) - if err != nil { - return fmt.Errorf("error while parsing crt: %s", err) - } - - _, err = caPool.VerifyCertificate(time.Now(), c) - if err != nil { - return err + var errs []error + for { + if len(rawCert) == 0 { + break + } + c, extra, err := cert.UnmarshalCertificateFromPEM(rawCert) + if err != nil { + return fmt.Errorf("error while parsing crt: %s", err) + } + rawCert = extra + _, err = caPool.VerifyCertificate(time.Now(), c) + if err != nil { + switch { + case errors.Is(err, cert.ErrCaNotFound): + errs = append(errs, fmt.Errorf("error while verifying certificate v%d %s with issuer %s: %s", c.Version(), c.Name(), c.Issuer(), err)) + default: + errs = append(errs, fmt.Errorf("error while verifying certificate %+v: %s", c, err)) + } + } } - return nil + return errors.Join(errs...) } func verifySummary() string {