Skip to content

Commit

Permalink
vcsim: Gen enc key w default provider on createvm
Browse files Browse the repository at this point in the history
This patch adds support to vcsim for generating encryption keys
using the default provider (if one exists) for new VMs that
specify they are to be encrypted, but do not specify a key ID or
provider ID.
  • Loading branch information
akutz committed Sep 18, 2024
1 parent 3450f77 commit cddbe1f
Show file tree
Hide file tree
Showing 4 changed files with 518 additions and 10 deletions.
76 changes: 76 additions & 0 deletions simulator/crypto_manager_kmip.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,79 @@ func (m *CryptoManagerKmip) ListKeys(

return &body
}

func getDefaultProvider(
ctx *Context,
vm *VirtualMachine,
generateKey bool) (string, string) {

m := ctx.Map.CryptoManager()
if m == nil {
return "", ""
}

var (
providerID string
keyID string
)

ctx.WithLock(m, func() {
// Lookup the default provider ID via the VM's parent entities:
// host, host folder, cluster.
if host := vm.Runtime.Host; host != nil {
for i := range m.KmipServers {
kmipCluster := m.KmipServers[i]
for j := range kmipCluster.UseAsEntityDefault {
parent := host
for providerID == "" && parent != nil {
if kmipCluster.UseAsEntityDefault[j] == *parent {
providerID = kmipCluster.ClusterId.Id
break
} else {
// TODO (akutz): Support looking up the
// default entity via the host
// folder and cluster.
parent = nil
}
}
if providerID != "" {
break
}
}
if providerID != "" {
break
}
}
}

// If the default provider ID has not been discovered, see if
// any of the providers are the global default.
if providerID == "" {
for i := range m.KmipServers {
if providerID == "" && m.KmipServers[i].UseAsDefault {
providerID = m.KmipServers[i].ClusterId.Id
break
}
}
}
})

if providerID != "" && generateKey {
keyID = generateKeyForProvider(ctx, providerID)
}

return providerID, keyID
}

func generateKeyForProvider(ctx *Context, providerID string) string {
m := ctx.Map.CryptoManager()
if m == nil {
return ""
}
var keyID string
ctx.WithLock(m, func() {
keyID = uuid.NewString()
m.keyIDToProviderID[keyID] = providerID
})
return keyID
}
30 changes: 28 additions & 2 deletions simulator/folder.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
Copyright (c) 2017-2024 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -402,6 +402,32 @@ func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
vm.Runtime.Host = c.req.Host
}

if cryptoSpec, ok := c.req.Config.Crypto.(*types.CryptoSpecEncrypt); ok {
if cryptoSpec.CryptoKeyId.KeyId == "" {
if cryptoSpec.CryptoKeyId.ProviderId == nil {
providerID, keyID := getDefaultProvider(c.ctx, vm, true)
if providerID == "" {
return nil, &types.InvalidVmConfig{Property: "configSpec.crypto"}
}
vm.Config.KeyId = &types.CryptoKeyId{
KeyId: keyID,
ProviderId: &types.KeyProviderId{
Id: providerID,
},
}
} else {
providerID := cryptoSpec.CryptoKeyId.ProviderId.Id
keyID := generateKeyForProvider(c.ctx, providerID)
vm.Config.KeyId = &types.CryptoKeyId{
KeyId: keyID,
ProviderId: &types.KeyProviderId{
Id: providerID,
},
}
}
}
}

vm.Guest = &types.GuestInfo{
ToolsStatus: types.VirtualMachineToolsStatusToolsNotInstalled,
ToolsVersion: "0",
Expand Down
33 changes: 27 additions & 6 deletions simulator/virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1662,23 +1662,32 @@ func (vm *VirtualMachine) updateCrypto(
if err := assertEncrypted(); err != nil {
return err
}

var providerID *types.KeyProviderId
if pid := vm.Config.KeyId.ProviderId; pid != nil {
if pid := newKeyID.ProviderId; pid != nil {
providerID = &types.KeyProviderId{
Id: pid.Id,
}
}
if pid := newKeyID.ProviderId; pid != nil {
providerID = &types.KeyProviderId{
Id: pid.Id,

keyID := newKeyID.KeyId
if providerID == nil {
if p, k := getDefaultProvider(ctx, vm, true); p != "" && k != "" {
providerID = &types.KeyProviderId{
Id: p,
}
keyID = k
}
} else if keyID == "" {
keyID = generateKeyForProvider(ctx, providerID.Id)
}

ctx.Map.Update(vm, []types.PropertyChange{
{
Name: configKeyId,
Op: types.PropertyChangeOpAssign,
Val: &types.CryptoKeyId{
KeyId: newKeyID.KeyId,
KeyId: keyID,
ProviderId: providerID,
},
},
Expand Down Expand Up @@ -1738,12 +1747,24 @@ func (vm *VirtualMachine) updateCrypto(
}
}

keyID := tspec.CryptoKeyId.KeyId
if providerID == nil {
if p, k := getDefaultProvider(ctx, vm, true); p != "" && k != "" {
providerID = &types.KeyProviderId{
Id: p,
}
keyID = k
}
} else if keyID == "" {
keyID = generateKeyForProvider(ctx, providerID.Id)
}

ctx.Map.Update(vm, []types.PropertyChange{
{
Name: configKeyId,
Op: types.PropertyChangeOpAssign,
Val: &types.CryptoKeyId{
KeyId: tspec.CryptoKeyId.KeyId,
KeyId: keyID,
ProviderId: providerID,
},
},
Expand Down
Loading

0 comments on commit cddbe1f

Please sign in to comment.