Skip to content

Commit

Permalink
PKI add ValidateStrict (#3531)
Browse files Browse the repository at this point in the history
* PKI add ValidateStrict

* update test
  • Loading branch information
gerardsn authored Nov 1, 2024
1 parent 8d74a2a commit 3859302
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
4 changes: 4 additions & 0 deletions pki/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,13 @@ type Validator interface {
// ErrCRLMissing and ErrCRLExpired signal that at least one of the certificates cannot be validated reliably.
// If the certificate was revoked on an expired CRL, it wil return ErrCertRevoked.
// Ignoring all errors except ErrCertRevoked changes the behavior from hard-fail to soft-fail. Without a truststore, the Validator is a noop if set to soft-fail
// Validate uses the configured soft-/hard-fail strategy
// The certificate chain is expected to be sorted leaf to root.
Validate(chain []*x509.Certificate) error

// ValidateStrict does the same as Validate, except it always uses the hard-fail strategy.
ValidateStrict(chain []*x509.Certificate) error

// SetVerifyPeerCertificateFunc sets config.ValidatePeerCertificate to use Validate.
SetVerifyPeerCertificateFunc(config *tls.Config) error

Expand Down
28 changes: 28 additions & 0 deletions pki/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion pki/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,22 @@ func (v *validator) syncLoop(ctx context.Context) {
}

func (v *validator) Validate(chain []*x509.Certificate) error {
return v.validate(chain, v.softfail)
}

func (v *validator) ValidateStrict(chain []*x509.Certificate) error {
return v.validate(chain, false)
}

func (v *validator) validate(chain []*x509.Certificate, softfail bool) error {
var cert *x509.Certificate
var err error
for i := range chain {
cert = chain[len(chain)-1-i]
// check in reverse order to prevent CRL expiration errors due to revoked CAs no longer issuing CRLs
if err = v.validateCert(cert); err != nil {
errOut := fmt.Errorf("%w: subject=%s, S/N=%s, issuer=%s", err, cert.Subject.String(), cert.SerialNumber.String(), cert.Issuer.String())
if v.softfail && !(errors.Is(err, ErrCertRevoked) || errors.Is(err, ErrCertBanned)) {
if softfail && !(errors.Is(err, ErrCertRevoked) || errors.Is(err, ErrCertBanned)) {
// Accept the certificate even if it cannot be properly validated
logger().WithError(errOut).Error("Certificate CRL check softfail bypass. Might be unsafe, find cause of failure!")
continue
Expand Down
10 changes: 10 additions & 0 deletions pki/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,21 @@ func TestValidator_Validate(t *testing.T) {
assert.ErrorIs(t, err, expected)
}
}
fnStrict := func(expected error) {
val.softfail = true // make sure it ignores the configured value
err = val.ValidateStrict([]*x509.Certificate{cert})
if expected == nil {
assert.NoError(t, err)
} else {
assert.ErrorIs(t, err, expected)
}
}
t.Run("softfail", func(t *testing.T) {
fn(true, softfailReturn)
})
t.Run("hardfail", func(t *testing.T) {
fn(false, hardfailReturn)
fnStrict(hardfailReturn)
})
}

Expand Down

0 comments on commit 3859302

Please sign in to comment.