Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand NotAfter limit enforcement behavior #15152

Merged

Conversation

cipherboy
Copy link
Contributor

Vault previously strictly enforced NotAfter/ttl values on certificate
requests, erring if the requested TTL extended past the NotAfter date of
the issuer. In the event of issuing an intermediate, this behavior was
ignored, instead permitting the issuance.

Users generally do not think to check their issuer's NotAfter date when
requesting a certificate; thus this behavior was generally surprising.

Per RFC 5280 however, issuers need to maintain status information
throughout the life cycle of the issued cert. If this leaf cert were to
be issued for a longer duration than the parent issuer, the CA must
still maintain revocation information past its expiration.

Thus, we add an option to the issuer to change the desired behavior:

  • err, to err out,
  • permit, to permit the longer NotAfter date, or
  • truncate, to silently truncate the expiration to the issuer's
    NotAfter date.

Since expiration of certificates in the system's trust store are not
generally validated (when validating an arbitrary leaf, e.g., during TLS
validation), permit should generally only be used in that case. However,
browsers usually validate intermediate's validity periods, and thus
truncate should likely be used (as with permit, the leaf's chain will
not validate towards the end of the issuance period).

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

@cipherboy
Copy link
Contributor Author

cipherboy commented Apr 25, 2022

Can be tested with:

source devvault
vault secrets enable pki 
vault write pki/root/generate/internal common_name="root example.com" issuer_name=root  ttl=15s
vault write /pki/roles/local-testing allow_any_name=true enforce_hostnames=false no_store=true
sleep 16s # let the root expire
vault write pki/issue/local-testing common_name=hello # should err
vault write pki/issuer/root issuer_name=root leaf_not_after_behavior=permit 
vault write pki/issue/local-testing common_name=hello # should be default ttl of a month or so
vault write pki/issuer/root issuer_name=root leaf_not_after_behavior=truncate
vault write pki/issue/local-testing common_name=hello # should be expired
vault write pki/issuer/root issuer_name=root leaf_not_after_behavior=err
vault write pki/issue/local-testing common_name=hello # should err

@cipherboy cipherboy force-pushed the cipherboy-remove-ttl-issuance-restrictions branch 2 times, most recently from a83f5f5 to b1dab4f Compare April 25, 2022 14:20
@stevendpclark stevendpclark force-pushed the stevendpclark/vault-5748-read-legacy-on-secondary branch from 19a2981 to 0c53f24 Compare April 25, 2022 16:25
Base automatically changed from stevendpclark/vault-5748-read-legacy-on-secondary to pki-pod-rotation April 25, 2022 18:51
@cipherboy cipherboy force-pushed the cipherboy-remove-ttl-issuance-restrictions branch from b1dab4f to cd3229a Compare April 25, 2022 18:58
@cipherboy cipherboy marked this pull request as ready for review April 25, 2022 18:58
Copy link
Contributor

@stevendpclark stevendpclark left a comment

Choose a reason for hiding this comment

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

Overall 👍, I just have two comments that I believe might need some tweaks.

builtin/logical/pki/path_fetch_issuers.go Show resolved Hide resolved
@@ -150,21 +150,27 @@ func setLegacyBundleMigrationLog(ctx context.Context, s logical.Storage, lbm *le
return s.Put(ctx, json)
}

func getLegacyCertBundle(ctx context.Context, s logical.Storage) (*certutil.CertBundle, error) {
func getLegacyCertBundle(ctx context.Context, s logical.Storage) (*issuerEntry, *certutil.CertBundle, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit?: The migration works properly, matches with legacy behaviour, due to the iota definition of NotAfterBehavior the value ErrNotAfterBehavior comes first. Should we either be explicit within the migration perhaps of the value we want or test that ErrNotAfterBehavior. == 0?

Copy link
Contributor Author

@cipherboy cipherboy Apr 25, 2022

Choose a reason for hiding this comment

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

Would ImportIssuer... be the correct place to set this explicitly? Not sure what makes import on migration different than others, but yes, zero value being err was intentional :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

Well the others to my knowledge have the value set through either the default on the parameter definition or end-user values, this one really is just up to the iota. I don't think we can put it within importIssuer as there are so many end-users of that function.

How about just adding a check within storage_migrations_test.go that a migrated issuer has a value of ErrNotAfterBehavior set? I'd just want something to break if that iota accidently gets re-ordered.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

importIssuer is already opinionated though, in other forms: we automatically construct a chain (rather than giving the option to specify a manual chain at import time), and when calling e.g., /config/ca, we allow importing multiple issuers, and so there's really no way to control name either.

Copy link
Contributor Author

@cipherboy cipherboy Apr 26, 2022

Choose a reason for hiding this comment

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

Updated with tests and the updated ImportIssuer behavior :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Good points, let's go with adding it to importIssuer.

Vault previously strictly enforced NotAfter/ttl values on certificate
requests, erring if the requested TTL extended past the NotAfter date of
the issuer. In the event of issuing an intermediate, this behavior was
ignored, instead permitting the issuance.

Users generally do not think to check their issuer's NotAfter date when
requesting a certificate; thus this behavior was generally surprising.

Per RFC 5280 however, issuers need to maintain status information
throughout the life cycle of the issued cert. If this leaf cert were to
be issued for a longer duration than the parent issuer, the CA must
still maintain revocation information past its expiration.

Thus, we add an option to the issuer to change the desired behavior:

 - err, to err out,
 - permit, to permit the longer NotAfter date, or
 - truncate, to silently truncate the expiration to the issuer's
   NotAfter date.

Since expiration of certificates in the system's trust store are not
generally validated (when validating an arbitrary leaf, e.g., during TLS
validation), permit should generally only be used in that case. However,
browsers usually validate intermediate's validity periods, and thus
truncate should likely be used (as with permit, the leaf's chain will
not validate towards the end of the issuance period).

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
@cipherboy cipherboy force-pushed the cipherboy-remove-ttl-issuance-restrictions branch from cd3229a to a12457f Compare April 26, 2022 13:14
@cipherboy cipherboy merged commit a12457f into pki-pod-rotation Apr 26, 2022
@cipherboy
Copy link
Contributor Author

Thanks @stevendpclark!

@cipherboy cipherboy deleted the cipherboy-remove-ttl-issuance-restrictions branch May 17, 2022 14:33
@cipherboy
Copy link
Contributor Author

This PR was merged in #15277. See that PR and the relevant docs PR #15238 for more information about this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants