m/n/c/{cluster,roleserve}: implement Join Flow

This implements Join Flow for:
- Registered nodes attempting to re-join the cluster.
- Nodes bootstrapping the cluster.

See: Cluster Lifecycle and Integrity design document

Change-Id: I74ab98fdec650c4f6aa59e34a16c0f95745dc0e9
Reviewed-on: https://review.monogon.dev/c/monogon/+/556
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/core/roleserve/roleserve.go b/metropolis/node/core/roleserve/roleserve.go
index 2c2e885..667564d 100644
--- a/metropolis/node/core/roleserve/roleserve.go
+++ b/metropolis/node/core/roleserve/roleserve.go
@@ -118,14 +118,16 @@
 	return s
 }
 
-func (s *Service) ProvideBootstrapData(privkey ed25519.PrivateKey, iok, cuk []byte) {
+func (s *Service) ProvideBootstrapData(privkey ed25519.PrivateKey, iok, cuk, nuk, jkey []byte) {
 	s.ClusterMembership.set(&ClusterMembership{
 		pubkey: privkey.Public().(ed25519.PublicKey),
 	})
 	s.bootstrapData.set(&bootstrapData{
-		nodePrivateKey:   privkey,
-		initialOwnerKey:  iok,
-		clusterUnlockKey: cuk,
+		nodePrivateKey:     privkey,
+		initialOwnerKey:    iok,
+		clusterUnlockKey:   cuk,
+		nodeUnlockKey:      nuk,
+		nodePrivateJoinKey: jkey,
 	})
 }
 
@@ -137,6 +139,14 @@
 	})
 }
 
+func (s *Service) ProvideJoinData(credentials identity.NodeCredentials, directory *cpb.ClusterDirectory) {
+	s.ClusterMembership.set(&ClusterMembership{
+		remoteCurators: directory,
+		credentials:    &credentials,
+		pubkey:         credentials.PublicKey(),
+	})
+}
+
 // Run the Role Server service, which uses intermediary workload launchers to
 // start/stop subordinate services as the Node's roles change.
 func (s *Service) Run(ctx context.Context) error {