Skip to content

Option to validate only CA and Issuer rather than entire SCEP cert#700

Merged
grahamgilbert merged 5 commits intomainfrom
scep_logging
Aug 14, 2020
Merged

Option to validate only CA and Issuer rather than entire SCEP cert#700
grahamgilbert merged 5 commits intomainfrom
scep_logging

Conversation

@grahamgilbert
Copy link
Contributor

Currently we're only verifying whether the cert presented is present in the database. For reasons I don't understand / have time to investigate, clients have valid SCEP certificates which aren't stored in the database. This PR adds an option to validate only the Issuer and the CA that signed the cert.

}

func VerifyCertificateMiddleware(store ScepVerifyDepot, logger log.Logger) mdm.Middleware {
func VerifyCertificateMiddleware(validateSCEPIssuer bool, scepIssuer string, scepDepot *boltdepot.Depot, store ScepVerifyDepot, logger log.Logger) mdm.Middleware {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this dependency, modify the ScepVerifyDepot interface to add the missing CA method.
We already pass the depot as the store argument, it's just missing a method.


if expiration.After(time.Now()) {
err := errors.New("device certificate is expired")
return false, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just return false, errors.New(the text). same for all the other instances where you create err := just to return it on the next line.

if mw.validateSCEPIssuer {
verifiedIssuer, err = verifyIssuer(devcert, mw.scepIssuer, mw.scepDepot)
if err != nil {
_ = level.Info(mw.logger).Log("err", err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the _ =, it's not necessary to check for the error on the logs.

verifiedIssuer, err = verifyIssuer(devcert, mw.scepIssuer, mw.scepDepot)
if err != nil {
_ = level.Info(mw.logger).Log("err", err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
return nil, errors.Wrap(err, "error verifying CN")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave the returned error as errors.New("unauthorized client"), and only expand on logs.

The actual error goes to the client, which would leak too much details to an attacker about why the validation is failing.

@@ -41,9 +85,20 @@ func (mw *verifyCertificateMiddleware) Acknowledge(ctx context.Context, req mdm.
return nil, errors.Wrap(err, "error checking device certificate")
}
if !hasCN {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use an early return here which allows you to use the scep issuer validation without the extra conditionals.

if !hasCN && !validate // return

@@ -58,9 +113,20 @@ func (mw *verifyCertificateMiddleware) Checkin(ctx context.Context, req mdm.Chec
return errors.Wrap(err, "error checking device certificate")
}
if !hasCN {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comments about flow here as in the other verify function.

issuer := devcert.Issuer.String()
expiration := devcert.NotAfter

if time.Now().After(expiration) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would either add an option to not validate the device certificate expiry or don't do it by default. This will, effectively, "lock out" devices from being remediated by re-enrollment if they ever expire and, by default, MicroMDM has a 1yr expiration on the device cert — this could catch many folks off-guard and be in an unfixable state.

Copy link
Member

@groob groob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with the comment from Jesse, otherwise I'm happy with this. Can you also update CHANGELOG for the release notes?

@grahamgilbert
Copy link
Contributor Author

Changelog updated, added a flag to opt in to checking if the cert is expired.

@grahamgilbert grahamgilbert merged commit 1b75588 into main Aug 14, 2020
@grahamgilbert grahamgilbert deleted the scep_logging branch August 14, 2020 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants