From 190f29e2a471bbd263521b5bd5db57b659f30cc3 Mon Sep 17 00:00:00 2001 From: hc-github-team-secure-vault-core <82990506+hc-github-team-secure-vault-core@users.noreply.github.com> Date: Mon, 4 Dec 2023 18:00:39 -0500 Subject: [PATCH] backport of commit 91ec1a788b46c0bf12a3351e5e3339474400eee9 (#24363) Co-authored-by: Scott Miller --- changelog/24336.txt | 3 +++ vault/barrier_aes_gcm.go | 33 ++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 changelog/24336.txt diff --git a/changelog/24336.txt b/changelog/24336.txt new file mode 100644 index 000000000..63594dc6c --- /dev/null +++ b/changelog/24336.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix a timeout initializing Vault by only using a short timeout persisting barrier keyring encryption counts. +``` diff --git a/vault/barrier_aes_gcm.go b/vault/barrier_aes_gcm.go index 5627e7cf8..ced1a7907 100644 --- a/vault/barrier_aes_gcm.go +++ b/vault/barrier_aes_gcm.go @@ -37,6 +37,8 @@ const ( autoRotateCheckInterval = 5 * time.Minute legacyRotateReason = "legacy rotation" + // The keyring is persisted before the root key. + keyringTimeout = 1 * time.Second ) // Versions of the AESGCM storage methodology @@ -211,11 +213,18 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, rea // persistKeyring is used to write out the keyring using the // root key to encrypt it. func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) error { - const ( - // The keyring is persisted before the root key. - keyringTimeout = 1 * time.Second - ) + return b.persistKeyringInternal(ctx, keyring, false) +} +// persistKeyringBestEffort is like persistKeyring but 'best effort', ie times out early +// for non critical keyring writes (encryption/rotation tracking) +func (b *AESGCMBarrier) persistKeyringBestEffort(ctx context.Context, keyring *Keyring) error { + return b.persistKeyringInternal(ctx, keyring, true) +} + +// persistKeyring is used to write out the keyring using the +// root key to encrypt it. +func (b *AESGCMBarrier) persistKeyringInternal(ctx context.Context, keyring *Keyring, bestEffort bool) error { // Create the keyring entry keyringBuf, err := keyring.Serialize() defer memzero(keyringBuf) @@ -241,10 +250,16 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er Value: value, } - // We reduce the timeout on the initial 'put' but if this succeeds we will - // allow longer later on when we try to persist the root key . - ctxKeyring, cancelKeyring := context.WithTimeout(ctx, keyringTimeout) - defer cancelKeyring() + ctxKeyring := ctx + + if bestEffort { + // We reduce the timeout on the initial 'put' but if this succeeds we will + // allow longer later on when we try to persist the root key . + var cancelKeyring func() + ctxKeyring, cancelKeyring = context.WithTimeout(ctx, keyringTimeout) + defer cancelKeyring() + } + if err := b.backend.Put(ctxKeyring, pe); err != nil { return fmt.Errorf("failed to persist keyring: %w", err) } @@ -1231,7 +1246,7 @@ func (b *AESGCMBarrier) persistEncryptions(ctx context.Context) error { newEncs := upe + 1 activeKey.Encryptions += uint64(newEncs) newKeyring := b.keyring.Clone() - err := b.persistKeyring(ctx, newKeyring) + err := b.persistKeyringBestEffort(ctx, newKeyring) if err != nil { return err }