mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
keyring: Fix a panic when decrypting aead with empty RSA block. (#24442)
Clusters that have gone through several upgrades have be found to include keyring material which has an empty RSA block. In more recent versions of Nomad, an empty RSA block is omitted from being written to disk. This results in the panic not being present. Older versions, however, did not have this struct tag meaning we wrote an empty JSON block which is not accounted for in the current version.
This commit is contained in:
3
.changelog/24442.txt
Normal file
3
.changelog/24442.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
keyring: Fixed a bug when decrypting aead with an empty RSA block on state upserts
|
||||
```
|
||||
@@ -477,7 +477,7 @@ func (e *Encrypter) decryptWrappedKeyTask(ctx context.Context, cancel context.Ca
|
||||
// Decrypt RSAKey for Workload Identity JWT signing if one exists. Prior to
|
||||
// 1.7 an ed25519 key derived from the root key was used instead of an RSA
|
||||
// key.
|
||||
if wrappedKey.WrappedRSAKey != nil {
|
||||
if wrappedKey.WrappedRSAKey != nil && len(wrappedKey.WrappedRSAKey.Ciphertext) > 0 {
|
||||
rsaKey, err = wrapper.Decrypt(e.srv.shutdownCtx, wrappedKey.WrappedRSAKey)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("%w (rsa key): %w", ErrDecryptFailed, err)
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3/jwt"
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc/v2"
|
||||
"github.com/hashicorp/nomad/ci"
|
||||
"github.com/hashicorp/nomad/helper/pointer"
|
||||
@@ -834,3 +835,42 @@ func TestEncrypter_TransitConfigFallback(t *testing.T) {
|
||||
fallbackVaultConfig(providers[2], &config.VaultConfig{})
|
||||
must.Eq(t, expect, providers[2].Config, must.Sprint("expected fallback to env"))
|
||||
}
|
||||
|
||||
func TestEncrypter_decryptWrappedKeyTask(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
srv := &Server{
|
||||
logger: testlog.HCLogger(t),
|
||||
config: &Config{},
|
||||
}
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
key, err := structs.NewUnwrappedRootKey(structs.EncryptionAlgorithmAES256GCM)
|
||||
must.NoError(t, err)
|
||||
|
||||
encrypter, err := NewEncrypter(srv, tmpDir)
|
||||
must.NoError(t, err)
|
||||
|
||||
wrappedKey, err := encrypter.encryptDEK(key, &structs.KEKProviderConfig{})
|
||||
must.NotNil(t, wrappedKey)
|
||||
must.NoError(t, err)
|
||||
|
||||
// Purposely empty the RSA key, but do not nil it, so we can test for a
|
||||
// panic where the key doesn't contain the ciphertext.
|
||||
wrappedKey.WrappedRSAKey = &wrapping.BlobInfo{}
|
||||
|
||||
provider, ok := encrypter.providerConfigs[string(structs.KEKProviderAEAD)]
|
||||
must.True(t, ok)
|
||||
must.NotNil(t, provider)
|
||||
|
||||
KMSWrapper, err := encrypter.newKMSWrapper(provider, key.Meta.KeyID, wrappedKey.KeyEncryptionKey)
|
||||
must.NoError(t, err)
|
||||
must.NotNil(t, KMSWrapper)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
err = encrypter.decryptWrappedKeyTask(ctx, cancel, KMSWrapper, provider, key.Meta, wrappedKey)
|
||||
must.NoError(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user