Skip to content

Commit 064b889

Browse files
author
gitlab
committed
Merge branch 'remove-resource-keyref@@2' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<fix>[crypto]: keep TPM key ref until VM removed from DB See merge request zstackio/zstack!9540
2 parents bc12449 + 3a67455 commit 064b889

7 files changed

Lines changed: 101 additions & 2 deletions

File tree

compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.springframework.dao.DataIntegrityViolationException;
88
import org.springframework.transaction.annotation.Transactional;
99
import org.zstack.compute.allocator.HostAllocatorManager;
10+
import org.zstack.compute.vm.devices.TpmEncryptedResourceKeyBackend;
11+
import org.zstack.compute.vm.devices.VmTpmManager;
1012
import org.zstack.core.Platform;
1113
import org.zstack.core.asyncbatch.While;
1214
import org.zstack.core.cascade.CascadeConstant;
@@ -142,13 +144,28 @@ public class VmInstanceBase extends AbstractVmInstance {
142144
private VmInstanceResourceMetadataManager vidm;
143145
@Autowired
144146
private NetworkServiceManager nwServiceMgr;
147+
@Autowired
148+
private TpmEncryptedResourceKeyBackend tpmKeyBackend;
145149

146150
protected VmInstanceVO self;
147151
protected VmInstanceVO originalCopy;
148152
protected String syncThreadName;
149153
private final static StaticIpOperator ipOperator = new StaticIpOperator();
150154
private final static VmConfigSyncHelper vmConfigSyncHelper = new VmConfigSyncHelper();
151155

156+
private void detachTpmKeyProviderBestEffort(String tpmUuid) {
157+
if (tpmUuid == null) {
158+
return;
159+
}
160+
try {
161+
tpmKeyBackend.detachKeyProviderFromTpm(tpmUuid);
162+
} catch (Throwable t) {
163+
logger.warn(String.format(
164+
"failed to detach key provider from TPM[uuid:%s]: %s",
165+
tpmUuid, t.getMessage()), t);
166+
}
167+
}
168+
152169
protected void checkState(final String hostUuid, final NoErrorCompletion completion) {
153170
CheckVmStateOnHypervisorMsg msg = new CheckVmStateOnHypervisorMsg();
154171
msg.setVmInstanceUuids(list(self.getUuid()));
@@ -1272,6 +1289,8 @@ public void handle(Map data) {
12721289
CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmAfterExpungeExtensionPoint.class),
12731290
arg -> arg.vmAfterExpunge(inv));
12741291

1292+
final String tpmUuidForEncryptedKeyRef = VmTpmManager.findTpmUuidForVmOrNull(self.getUuid());
1293+
12751294
callVmJustBeforeDeleteFromDbExtensionPoint();
12761295

12771296
dbf.reload(self);
@@ -1283,6 +1302,7 @@ public void handle(Map data) {
12831302
if (inv.getRootVolumeUuid() != null) {
12841303
dbf.eoCleanup(VolumeVO.class, inv.getRootVolumeUuid());
12851304
}
1305+
detachTpmKeyProviderBestEffort(tpmUuidForEncryptedKeyRef);
12861306
completion.success();
12871307
}
12881308
}).error(new FlowErrorHandler(completion) {
@@ -2582,12 +2602,15 @@ public void success() {
25822602
if (self.getState() != VmInstanceState.Destroyed) {
25832603
changeVmStateInDb(VmInstanceStateEvent.destroyed);
25842604
}
2605+
final String tpmUuidForEncryptedKeyRef = VmTpmManager.findTpmUuidForVmOrNull(self.getUuid());
25852606
callVmJustBeforeDeleteFromDbExtensionPoint();
25862607
dbf.removeCollection(self.getVmCdRoms(), VmCdRomVO.class);
25872608
dbf.remove(getSelf());
25882609
dbf.eoCleanup(VmInstanceVO.class, self.getUuid());
2610+
detachTpmKeyProviderBestEffort(tpmUuidForEncryptedKeyRef);
25892611
} else if (deletionPolicy == VmInstanceDeletionPolicy.DBOnly || deletionPolicy == VmInstanceDeletionPolicy.KeepVolume) {
25902612
String accountUuid = acntMgr.getOwnerAccountUuidOfResource(inv.getUuid());
2613+
final String tpmUuidForEncryptedKeyRef = VmTpmManager.findTpmUuidForVmOrNull(self.getUuid());
25912614
new SQLBatch() {
25922615
@Override
25932616
protected void scripts() {
@@ -2601,6 +2624,7 @@ protected void scripts() {
26012624
sql(VmInstanceVO.class).eq(VmInstanceVO_.uuid, self.getUuid()).hardDelete();
26022625
}
26032626
}.execute();
2627+
detachTpmKeyProviderBestEffort(tpmUuidForEncryptedKeyRef);
26042628
callVmJustAfterDeleteFromDbExtensionPoint(inv, accountUuid);
26052629
} else if (deletionPolicy == VmInstanceDeletionPolicy.Delay) {
26062630
changeVmStateInDb(VmInstanceStateEvent.destroyed);

compute/src/main/java/org/zstack/compute/vm/devices/VmTpmManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ public void deleteTpmVO(String tpmUuid) {
4242
databaseFacade.removeByPrimaryKey(tpmUuid, TpmVO.class);
4343
}
4444

45+
public static String findTpmUuidForVmOrNull(String vmInstanceUuid) {
46+
return Q.New(TpmVO.class)
47+
.eq(TpmVO_.vmInstanceUuid, vmInstanceUuid)
48+
.select(TpmVO_.uuid)
49+
.findValue();
50+
}
51+
4552
/**
4653
* @param bootMode boot mode, null is Legacy
4754
*/

header/src/main/java/org/zstack/header/keyprovider/EncryptedResourceKeyManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class GetOrCreateResourceKeyContext {
3838
private String resourceUuid;
3939
private String resourceType;
4040
private String keyProviderUuid;
41+
private String keyProviderName;
4142
private String purpose;
4243

4344
public String getResourceUuid() {
@@ -64,6 +65,14 @@ public void setKeyProviderUuid(String keyProviderUuid) {
6465
this.keyProviderUuid = keyProviderUuid;
6566
}
6667

68+
public String getKeyProviderName() {
69+
return keyProviderName;
70+
}
71+
72+
public void setKeyProviderName(String keyProviderName) {
73+
this.keyProviderName = keyProviderName;
74+
}
75+
6776
public String getPurpose() {
6877
return purpose;
6978
}

plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public void fail(ErrorCode errorCode) {
173173
@Override
174174
public boolean skip(Map data) {
175175
boolean shouldSkip = VmGlobalConfig.ALLOWED_TPM_VM_WITHOUT_KMS.value(Boolean.class) &&
176-
(StringUtils.isBlank(context.providerUuid) || StringUtils.isBlank(context.providerName));
176+
(StringUtils.isBlank(context.providerUuid) && StringUtils.isBlank(context.providerName));
177177
if (shouldSkip) {
178178
logger.info("skip create-dek: allowed.tpm.vm.without.kms is enabled and no KMS provider bound");
179179
}
@@ -182,7 +182,7 @@ public boolean skip(Map data) {
182182

183183
@Override
184184
public void run(FlowTrigger trigger, Map data) {
185-
if (StringUtils.isBlank(context.providerUuid) || StringUtils.isBlank(context.providerName)) {
185+
if (StringUtils.isBlank(context.providerUuid) && StringUtils.isBlank(context.providerName)) {
186186
trigger.fail(operr("missing TPM resource key binding for tpm[uuid:%s], attachKeyProviderToTpm must run before create-dek", context.tpmUuid));
187187
return;
188188
}
@@ -191,13 +191,15 @@ public void run(FlowTrigger trigger, Map data) {
191191
keyCtx.setResourceUuid(context.tpmUuid);
192192
keyCtx.setResourceType(TpmVO.class.getSimpleName());
193193
keyCtx.setKeyProviderUuid(context.providerUuid);
194+
keyCtx.setKeyProviderName(context.providerName);
194195
keyCtx.setPurpose("vtpm");
195196

196197
resourceKeyManager.getOrCreateKey(keyCtx, new ReturnValueCompletion<ResourceKeyResult>(trigger) {
197198
@Override
198199
public void success(ResourceKeyResult result) {
199200
tpmSpec.setResourceKeyCreatedNew(result.isCreatedNewKey());
200201
tpmSpec.setResourceKeyProviderUuid(result.getKeyProviderUuid());
202+
context.providerUuid = result.getKeyProviderUuid();
201203
context.providerName = result.getKeyProviderName();
202204
context.dekBase64 = result.getDekBase64();
203205
trigger.next();

sdk/src/main/java/SourceClassMap.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public class SourceClassMap {
7070
put("org.zstack.core.jsonlabel.JsonLabelInventory", "org.zstack.sdk.JsonLabelInventory");
7171
put("org.zstack.crypto.ccs.CCSCertificateAccountRefInventory", "org.zstack.sdk.CCSCertificateAccountRefInventory");
7272
put("org.zstack.crypto.ccs.CCSCertificateInventory", "org.zstack.sdk.CCSCertificateInventory");
73+
put("org.zstack.crypto.keyprovider.api.RekeyFailedResource", "org.zstack.sdk.keyprovider.api.RekeyFailedResource");
7374
put("org.zstack.crypto.keyprovider.api.RekeySkippedResource", "org.zstack.sdk.keyprovider.api.RekeySkippedResource");
7475
put("org.zstack.crypto.securitymachine.thirdparty.aisino.AiSiNoSecretResourcePoolInventory", "org.zstack.sdk.AiSiNoSecretResourcePoolInventory");
7576
put("org.zstack.crypto.securitymachine.thirdparty.flkSec.FlkSecSecretResourcePoolInventory", "org.zstack.sdk.FlkSecSecretResourcePoolInventory");
@@ -1267,6 +1268,7 @@ public class SourceClassMap {
12671268
put("org.zstack.sdk.identity.ldap.entity.LdapServerInventory", "org.zstack.ldap.entity.LdapServerInventory");
12681269
put("org.zstack.sdk.identity.role.RoleAccountRefInventory", "org.zstack.header.identity.role.RoleAccountRefInventory");
12691270
put("org.zstack.sdk.identity.role.RoleInventory", "org.zstack.header.identity.role.RoleInventory");
1271+
put("org.zstack.sdk.keyprovider.api.RekeyFailedResource", "org.zstack.crypto.keyprovider.api.RekeyFailedResource");
12701272
put("org.zstack.sdk.keyprovider.api.RekeySkippedResource", "org.zstack.crypto.keyprovider.api.RekeySkippedResource");
12711273
put("org.zstack.sdk.license.entity.LicenseHistoryInventory", "org.zstack.license.entity.LicenseHistoryInventory");
12721274
put("org.zstack.sdk.license.entity.LicenseUsageView", "org.zstack.license.entity.LicenseUsageView");
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.zstack.sdk.keyprovider.api;
2+
3+
4+
5+
public class RekeyFailedResource {
6+
7+
public java.lang.Long keyRefId;
8+
public void setKeyRefId(java.lang.Long keyRefId) {
9+
this.keyRefId = keyRefId;
10+
}
11+
public java.lang.Long getKeyRefId() {
12+
return this.keyRefId;
13+
}
14+
15+
public java.lang.String resourceType;
16+
public void setResourceType(java.lang.String resourceType) {
17+
this.resourceType = resourceType;
18+
}
19+
public java.lang.String getResourceType() {
20+
return this.resourceType;
21+
}
22+
23+
public java.lang.String resourceUuid;
24+
public void setResourceUuid(java.lang.String resourceUuid) {
25+
this.resourceUuid = resourceUuid;
26+
}
27+
public java.lang.String getResourceUuid() {
28+
return this.resourceUuid;
29+
}
30+
31+
public java.lang.String reason;
32+
public void setReason(java.lang.String reason) {
33+
this.reason = reason;
34+
}
35+
public java.lang.String getReason() {
36+
return this.reason;
37+
}
38+
39+
}

sdk/src/main/java/org/zstack/sdk/keyprovider/api/RekeyKeyProviderRefsResult.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public int getSkippedCount() {
2727
return this.skippedCount;
2828
}
2929

30+
public int failedCount;
31+
public void setFailedCount(int failedCount) {
32+
this.failedCount = failedCount;
33+
}
34+
public int getFailedCount() {
35+
return this.failedCount;
36+
}
37+
3038
public java.util.List skippedResources;
3139
public void setSkippedResources(java.util.List skippedResources) {
3240
this.skippedResources = skippedResources;
@@ -35,4 +43,12 @@ public java.util.List getSkippedResources() {
3543
return this.skippedResources;
3644
}
3745

46+
public java.util.List failedResources;
47+
public void setFailedResources(java.util.List failedResources) {
48+
this.failedResources = failedResources;
49+
}
50+
public java.util.List getFailedResources() {
51+
return this.failedResources;
52+
}
53+
3854
}

0 commit comments

Comments
 (0)