use prior and current worker auth keys (#2495)
* use prior and current worker auth keys
This commit is contained in:
1 parent
902ca3cccb
commit
4493dfd527
12 files changed
+392
-71
No files matched your search
@@ -369,6 +369,7 @@ func (r *WorkerAuthRepositoryStorage) Load(ctx context.Context, msg nodee.Messag
|
||||
// Node information is loaded in two parts:
|
||||
// * the workerAuth record
|
||||
// * its certificate bundles
|
||||
// * the prior encryption key, if present
|
||||
func (r *WorkerAuthRepositoryStorage) loadNodeInformation(ctx context.Context, node *types.NodeInformation) error {
|
||||
const op = "server.(WorkerAuthRepositoryStorage).loadNodeInformation"
|
||||
if node == nil {
|
||||
@@ -418,6 +419,15 @@ func (r *WorkerAuthRepositoryStorage) loadNodeInformation(ctx context.Context, n
|
||||
}
|
||||
node.CertificateBundles = certBundles
|
||||
|
||||
// Get prior encryption key, if available
|
||||
priorKey, err := r.findPriorEncryptionKey(ctx, authorizedWorker.GetWorkerId())
|
||||
if !errors.IsNotFoundError(err) {
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
node.PreviousEncryptionKey = priorKey
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -507,6 +517,36 @@ func (r *WorkerAuthRepositoryStorage) findWorkerAuth(ctx context.Context, node *
|
||||
return worker, nil
|
||||
}
|
||||
|
||||
func (r *WorkerAuthRepositoryStorage) findPriorEncryptionKey(ctx context.Context, workerId string) (*types.EncryptionKey, error) {
|
||||
const op = "server.(WorkerAuthRepositoryStorage).findPriorEncryptionKey"
|
||||
if workerId == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "empty workerId")
|
||||
}
|
||||
|
||||
workerAuthSet, err := r.FindWorkerAuthByWorkerId(ctx, workerId)
|
||||
if err != nil {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
if workerAuthSet.Previous == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Create the EncryptionKey using the prior worker auth record
|
||||
priorKey := &types.EncryptionKey{
|
||||
KeyId: workerAuthSet.Previous.WorkerKeyIdentifier,
|
||||
PrivateKeyPkcs8: workerAuthSet.Previous.ControllerEncryptionPrivKey,
|
||||
PrivateKeyType: types.KEYTYPE_X25519,
|
||||
PublicKeyPkix: workerAuthSet.Previous.WorkerEncryptionPubKey,
|
||||
PublicKeyType: types.KEYTYPE_X25519,
|
||||
}
|
||||
|
||||
return priorKey, nil
|
||||
}
|
||||
|
||||
func (r *WorkerAuthRepositoryStorage) loadRootCertificates(ctx context.Context, cert *types.RootCertificates) error {
|
||||
const op = "server.(WorkerAuthRepositoryStorage).loadRootCertificates"
|
||||
if cert == nil {
|
||||
@@ -879,22 +919,56 @@ func decrypt(ctx context.Context, value []byte, wrapper wrapping.Wrapper) ([]byt
|
||||
return marshaledInfo, nil
|
||||
}
|
||||
|
||||
// FindWorkerAuthByWorkerId takes a workerId and returns the WorkerAuth record associated with that worker.
|
||||
func (r *WorkerAuthRepositoryStorage) FindWorkerAuthByWorkerId(ctx context.Context, workerId string) (*WorkerAuth, error) {
|
||||
// FindWorkerAuthByWorkerId takes a workerId and returns the WorkerAuthSet for this worker.
|
||||
func (r *WorkerAuthRepositoryStorage) FindWorkerAuthByWorkerId(ctx context.Context, workerId string) (*WorkerAuthSet, error) {
|
||||
const op = "server.(WorkerAuthRepositoryStorage).FindWorkerAuthByWorkerId"
|
||||
if len(workerId) == 0 {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "empty worker ID")
|
||||
}
|
||||
|
||||
worker := allocWorkerAuth()
|
||||
worker.WorkerId = workerId
|
||||
err := r.reader.SearchWhere(ctx, &worker, "worker_id = ?", []interface{}{workerId})
|
||||
if err != nil {
|
||||
if errors.Is(err, dbw.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
var previousWorkerAuth *WorkerAuth
|
||||
var currentWorkerAuth *WorkerAuth
|
||||
|
||||
var workerAuths []*WorkerAuth
|
||||
if err := r.reader.SearchWhere(ctx, &workerAuths, "worker_id = ?", []interface{}{workerId}); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
return worker, nil
|
||||
workerAuthsFound := len(workerAuths)
|
||||
switch {
|
||||
case workerAuthsFound == 0:
|
||||
return nil, errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("did not find worker auth records for worker %s", workerId))
|
||||
case workerAuthsFound == 1:
|
||||
if workerAuths[0].State != currentWorkerAuthState {
|
||||
return nil, errors.New(ctx, errors.NotSpecificIntegrity, op,
|
||||
fmt.Sprintf("expected sole worker auth record to be in current state, found %s", workerAuths[0].State))
|
||||
} else {
|
||||
currentWorkerAuth = workerAuths[0]
|
||||
}
|
||||
case workerAuthsFound == 2:
|
||||
currentStateFound := false
|
||||
previousStateFound := false
|
||||
for _, w := range workerAuths {
|
||||
if w.State == currentWorkerAuthState {
|
||||
currentStateFound = true
|
||||
currentWorkerAuth = w
|
||||
} else if w.State == previousWorkerAuthState {
|
||||
previousStateFound = true
|
||||
previousWorkerAuth = w
|
||||
}
|
||||
}
|
||||
if !currentStateFound || !previousStateFound {
|
||||
return nil, errors.New(ctx, errors.NotSpecificIntegrity, op, fmt.Sprintf("worker auth records in invalid set of states"))
|
||||
}
|
||||
default:
|
||||
return nil, errors.New(ctx, errors.NotSpecificIntegrity, op,
|
||||
fmt.Sprintf("expected 2 or fewer worker auth records, found %d", workerAuthsFound))
|
||||
}
|
||||
|
||||
workerAuthSet := &WorkerAuthSet{
|
||||
Previous: previousWorkerAuth,
|
||||
Current: currentWorkerAuth,
|
||||
}
|
||||
|
||||
return workerAuthSet, nil
|
||||
}
|
||||
Reference in new issue
Block a user