metropolis/node: fix non-secure TPM/storage policy codepaths
This fixes enoug things to pass manually ran E2E tests with the initial
cluster confiugration changed to a number of possible combinations
(with/without TPM, with authenticated/encrypted/insecure storage).
These should, of course, be automatically tested. However, that is
pending on the extension of E2E test system that will let it run
long-term tests against real clusters. Otherwise we'd just waste tons of
time running the entire matrix of possible combinations on every CR.
Change-Id: I71a56f9a31c738ee2b2d4dfa10d2a58fd5cb0554
Reviewed-on: https://review.monogon.dev/c/monogon/+/1810
Tested-by: Jenkins CI
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
diff --git a/metropolis/node/core/cluster/cluster.go b/metropolis/node/core/cluster/cluster.go
index 529120b..9cc3f6b 100644
--- a/metropolis/node/core/cluster/cluster.go
+++ b/metropolis/node/core/cluster/cluster.go
@@ -74,7 +74,7 @@
close(m.oneway)
// Try sealed configuration first.
- configuration, err := m.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal()
+ configuration, err := m.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal(cpb.NodeTPMUsage_NODE_TPM_PRESENT_AND_USED)
if err == nil {
supervisor.Logger(ctx).Info("Sealed configuration present. attempting to join cluster")
@@ -88,11 +88,11 @@
return m.join(ctx, configuration, cd, true)
}
- if !errors.Is(err, localstorage.ErrNoSealed) {
+ if !errors.Is(err, localstorage.ErrNoSealed) && !errors.Is(err, localstorage.ErrSealedCorrupted) {
return fmt.Errorf("unexpected sealed config error: %w", err)
}
- configuration, err = m.storageRoot.ESP.Metropolis.SealedConfiguration.ReadUnsafe()
+ configuration, err = m.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal(cpb.NodeTPMUsage_NODE_TPM_NOT_PRESENT)
if err == nil {
supervisor.Logger(ctx).Info("Non-sealed configuration present. attempting to join cluster")
diff --git a/metropolis/node/core/localstorage/directory_data.go b/metropolis/node/core/localstorage/directory_data.go
index c255089..5607e0a 100644
--- a/metropolis/node/core/localstorage/directory_data.go
+++ b/metropolis/node/core/localstorage/directory_data.go
@@ -67,9 +67,12 @@
}
d.mounted = true
- key := make([]byte, keySize)
- for i := uint16(0); i < keySize; i++ {
- key[i] = config.NodeUnlockKey[i] ^ clusterUnlockKey[i]
+ var key []byte
+ if mode != crypt.ModeInsecure {
+ key = make([]byte, keySize)
+ for i := uint16(0); i < keySize; i++ {
+ key[i] = config.NodeUnlockKey[i] ^ clusterUnlockKey[i]
+ }
}
target, err := crypt.Map("data", crypt.NodeDataRawPath, key, mode)
diff --git a/metropolis/node/core/localstorage/storage_esp.go b/metropolis/node/core/localstorage/storage_esp.go
index 9da948a..c1779e9 100644
--- a/metropolis/node/core/localstorage/storage_esp.go
+++ b/metropolis/node/core/localstorage/storage_esp.go
@@ -181,7 +181,7 @@
return nil
}
-func (e *ESPSealedConfiguration) Unseal() (*ppb.SealedConfiguration, error) {
+func (e *ESPSealedConfiguration) Unseal(tpmUsage cpb.NodeTPMUsage) (*ppb.SealedConfiguration, error) {
bytes, err := e.Read()
if err != nil {
if os.IsNotExist(err) {
@@ -190,27 +190,16 @@
return nil, fmt.Errorf("%w: when reading sealed data: %v", ErrSealedUnavailable, err)
}
- bytes, err = tpm.Unseal(bytes)
- if err != nil {
- return nil, fmt.Errorf("%w: when unsealing: %v", ErrSealedCorrupted, err)
- }
-
- config := ppb.SealedConfiguration{}
- err = proto.Unmarshal(bytes, &config)
- if err != nil {
- return nil, fmt.Errorf("%w: when unmarshaling: %v", ErrSealedCorrupted, err)
- }
-
- return &config, nil
-}
-
-func (e *ESPSealedConfiguration) ReadUnsafe() (*ppb.SealedConfiguration, error) {
- bytes, err := e.Read()
- if err != nil {
- if os.IsNotExist(err) {
- return nil, ErrNoSealed
+ switch tpmUsage {
+ case cpb.NodeTPMUsage_NODE_TPM_PRESENT_AND_USED:
+ bytes, err = tpm.Unseal(bytes)
+ if err != nil {
+ return nil, fmt.Errorf("%w: when unsealing: %v", ErrSealedCorrupted, err)
}
- return nil, fmt.Errorf("%w: when reading sealed data: %v", ErrSealedUnavailable, err)
+ case cpb.NodeTPMUsage_NODE_TPM_PRESENT_BUT_UNUSED:
+ case cpb.NodeTPMUsage_NODE_TPM_NOT_PRESENT:
+ default:
+ return nil, fmt.Errorf("unknown tpmUsage %d", tpmUsage)
}
config := ppb.SealedConfiguration{}
diff --git a/metropolis/node/core/roleserve/worker_controlplane.go b/metropolis/node/core/roleserve/worker_controlplane.go
index a49343f..b6846a0 100644
--- a/metropolis/node/core/roleserve/worker_controlplane.go
+++ b/metropolis/node/core/roleserve/worker_controlplane.go
@@ -300,7 +300,7 @@
if err = creds.Save(&s.storageRoot.Data.Node.Credentials); err != nil {
return fmt.Errorf("while saving node credentials: %w", err)
}
- sc, err := s.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal()
+ sc, err := s.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal(b.nodeTPMUsage)
if err != nil {
return fmt.Errorf("reading sealed configuration failed: %w", err)
}