m/n/core: save NUK and Node Credentials
This makes the node save its Node Unlock Key and Node Credentials after
registering.
Change-Id: Ie16e8fd149745e22a2c02e56ccf3c2d87d052079
Reviewed-on: https://review.monogon.dev/c/monogon/+/537
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/core/cluster/cluster_register.go b/metropolis/node/core/cluster/cluster_register.go
index 76458b8..7376b84 100644
--- a/metropolis/node/core/cluster/cluster_register.go
+++ b/metropolis/node/core/cluster/cluster_register.go
@@ -78,8 +78,10 @@
supervisor.Logger(ctx).Infof(" Node ID: %s, Addresses: %s", id, strings.Join(addresses, ","))
}
- // Mount new storage with generated CUK, and save LUK into sealed config proto.
- state.configuration = &ppb.SealedConfiguration{}
+ // Mount new storage with generated CUK, MountNew will save NUK into sc, to be
+ // saved into the ESP after successful registration.
+ var sc ppb.SealedConfiguration
+ state.configuration = &sc
supervisor.Logger(ctx).Infof("Registering: mounting new storage...")
cuk, err := m.storageRoot.Data.MountNew(state.configuration)
if err != nil {
@@ -139,9 +141,16 @@
if err != nil {
return fmt.Errorf("NewNodeCredentials failed after receiving certificate from cluster: %w", err)
}
-
m.roleServer.ProvideRegisterData(*creds, register.ClusterDirectory)
- // TODO(q3k): save keypair to localstorage
+
+ // Save NUK
+ if err = m.storageRoot.ESP.Metropolis.SealedConfiguration.SealSecureBoot(&sc); err != nil {
+ return fmt.Errorf("failed to seal and write configuration: %w", err)
+ }
+ // Save Node Credentials
+ if err = m.storageRoot.Data.Node.Credentials.WriteAll(certBytes, priv, caCertBytes); err != nil {
+ return fmt.Errorf("while writing node credentials: %w", err)
+ }
supervisor.Signal(ctx, supervisor.SignalHealthy)
supervisor.Signal(ctx, supervisor.SignalDone)
diff --git a/metropolis/node/core/localstorage/storage_esp.go b/metropolis/node/core/localstorage/storage_esp.go
index 329b357..e3d0d2a 100644
--- a/metropolis/node/core/localstorage/storage_esp.go
+++ b/metropolis/node/core/localstorage/storage_esp.go
@@ -86,6 +86,28 @@
return &config, nil
}
+func (e *ESPSealedConfiguration) SealSecureBoot(c *ppb.SealedConfiguration) error {
+ bytes, err := proto.Marshal(c)
+ if err != nil {
+ return fmt.Errorf("while marshaling: %w", err)
+ }
+
+ // Use Secure Boot PCRs to seal the configuration.
+ // See: TCG PC Client Platform Firmware Profile Specification v1.05,
+ // table 3.3.4.1
+ // See: https://trustedcomputinggroup.org/wp-content/uploads/
+ // TCG_PCClient_PFP_r1p05_v22_02dec2020.pdf
+ bytes, err = tpm.Seal(bytes, tpm.SecureBootPCRs)
+ if err != nil {
+ return fmt.Errorf("while using tpm: %w", err)
+ }
+
+ if err := e.Write(bytes, 0644); err != nil {
+ return fmt.Errorf("while writing: %w", err)
+ }
+ return nil
+}
+
func (e *ESPSealedConfiguration) Unseal() (*ppb.SealedConfiguration, error) {
bytes, err := e.Read()
if err != nil {