Skip to content

Commit 52600df

Browse files
zhong.zhouzhijian.liu
authored andcommitted
<fix>[crypto]: secret get in vm pre instantiate
Resolves: ZSV-11630 Change-Id: I616a776e78666179637976616c776162616c6577
1 parent 71fa939 commit 52600df

11 files changed

Lines changed: 315 additions & 38 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public String findKeyProviderNameByTpm(String tpmUuid) {
3333
return null;
3434
}
3535

36+
@Override
37+
public Integer findKeyVersionByTpm(String tpmUuid) {
38+
return null;
39+
}
40+
3641
@Override
3742
public String defaultKeyProviderUuid() {
3843
return null;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public interface TpmEncryptedResourceKeyBackend {
3535
*/
3636
String findKeyProviderNameByTpm(String tpmUuid);
3737

38+
/**
39+
* maybe null (when crypto module is not installed)
40+
*/
41+
Integer findKeyVersionByTpm(String tpmUuid);
42+
3843
/**
3944
* maybe null (when crypto module is not installed)
4045
*/

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class ResourceKeyResult {
8787
private String resourceType;
8888
private String keyProviderUuid;
8989
private String keyProviderName;
90+
private Integer keyVersion;
9091
private String dekBase64;
9192
private String secretRef;
9293
private boolean createdNewKey;
@@ -124,6 +125,14 @@ public void setKeyProviderName(String keyProviderName) {
124125
this.keyProviderName = keyProviderName;
125126
}
126127

128+
public Integer getKeyVersion() {
129+
return keyVersion;
130+
}
131+
132+
public void setKeyVersion(Integer keyVersion) {
133+
this.keyVersion = keyVersion;
134+
}
135+
127136
public String getDekBase64() {
128137
return dekBase64;
129138
}

header/src/main/java/org/zstack/header/secret/SecretHostDefineMsg.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
import org.zstack.header.message.NeedReplyMessage;
66

77
/**
8-
* Request to define secret on KVM host (for VM e.g. vTPM). Caller provides plaintext DEK (dekBase64).
9-
* Host seals it with host public key (HPKE) and sends envelope to agent.
10-
* vmUuid, purpose, providerName are required by key-agent for DEK cache key.
8+
* Request to ensure secret on KVM host (for VM e.g. vTPM).
9+
* Caller provides plaintext DEK (dekBase64), then host seals it with host public key
10+
* and forwards the envelope to key-agent.
1111
*/
1212
public class SecretHostDefineMsg extends NeedReplyMessage implements HostMessage {
1313
private String hostUuid;
1414
@NoLogging
1515
private String dekBase64;
1616
private String vmUuid;
1717
private String purpose;
18-
private String providerName;
18+
private Integer keyVersion;
1919
private String description;
2020

2121
@Override
@@ -51,12 +51,12 @@ public void setPurpose(String purpose) {
5151
this.purpose = purpose;
5252
}
5353

54-
public String getProviderName() {
55-
return providerName;
54+
public Integer getKeyVersion() {
55+
return keyVersion;
5656
}
5757

58-
public void setProviderName(String providerName) {
59-
this.providerName = providerName;
58+
public void setKeyVersion(Integer keyVersion) {
59+
this.keyVersion = keyVersion;
6060
}
6161

6262
public String getDescription() {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.zstack.header.secret;
2+
3+
import org.zstack.header.host.HostMessage;
4+
import org.zstack.header.message.NeedReplyMessage;
5+
6+
/**
7+
* Request to get an existing secret on KVM host by vmUuid, purpose and keyVersion.
8+
*/
9+
public class SecretHostGetMsg extends NeedReplyMessage implements HostMessage {
10+
private String hostUuid;
11+
private String vmUuid;
12+
private String purpose;
13+
private Integer keyVersion;
14+
15+
@Override
16+
public String getHostUuid() {
17+
return hostUuid;
18+
}
19+
20+
public void setHostUuid(String hostUuid) {
21+
this.hostUuid = hostUuid;
22+
}
23+
24+
public String getVmUuid() {
25+
return vmUuid;
26+
}
27+
28+
public void setVmUuid(String vmUuid) {
29+
this.vmUuid = vmUuid;
30+
}
31+
32+
public String getPurpose() {
33+
return purpose;
34+
}
35+
36+
public void setPurpose(String purpose) {
37+
this.purpose = purpose;
38+
}
39+
40+
public Integer getKeyVersion() {
41+
return keyVersion;
42+
}
43+
44+
public void setKeyVersion(Integer keyVersion) {
45+
this.keyVersion = keyVersion;
46+
}
47+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.zstack.header.secret;
2+
3+
import org.zstack.header.message.MessageReply;
4+
5+
/** Reply for SecretHostGetMsg. */
6+
public class SecretHostGetReply extends MessageReply {
7+
public static final String ERROR_CODE_SECRET_NOT_FOUND = "KEY_AGENT_SECRET_NOT_FOUND";
8+
9+
private String secretUuid;
10+
11+
public String getSecretUuid() {
12+
return secretUuid;
13+
}
14+
15+
public void setSecretUuid(String secretUuid) {
16+
this.secretUuid = secretUuid;
17+
}
18+
}

plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public static class SecretHostDefineCmd extends AgentCommand {
410410
private String encryptedDek;
411411
private String vmUuid;
412412
private String purpose;
413-
private String providerName;
413+
private Integer keyVersion;
414414
private String description;
415415

416416
public String getEncryptedDek() {
@@ -437,12 +437,12 @@ public void setPurpose(String purpose) {
437437
this.purpose = purpose;
438438
}
439439

440-
public String getProviderName() {
441-
return providerName;
440+
public Integer getKeyVersion() {
441+
return keyVersion;
442442
}
443443

444-
public void setProviderName(String providerName) {
445-
this.providerName = providerName;
444+
public void setKeyVersion(Integer keyVersion) {
445+
this.keyVersion = keyVersion;
446446
}
447447

448448
public String getDescription() {
@@ -466,6 +466,48 @@ public void setSecretUuid(String secretUuid) {
466466
}
467467
}
468468

469+
public static class SecretHostGetCmd extends AgentCommand {
470+
private String vmUuid;
471+
private String purpose;
472+
private Integer keyVersion;
473+
474+
public String getVmUuid() {
475+
return vmUuid;
476+
}
477+
478+
public void setVmUuid(String vmUuid) {
479+
this.vmUuid = vmUuid;
480+
}
481+
482+
public String getPurpose() {
483+
return purpose;
484+
}
485+
486+
public void setPurpose(String purpose) {
487+
this.purpose = purpose;
488+
}
489+
490+
public Integer getKeyVersion() {
491+
return keyVersion;
492+
}
493+
494+
public void setKeyVersion(Integer keyVersion) {
495+
this.keyVersion = keyVersion;
496+
}
497+
}
498+
499+
public static class SecretHostGetResponse extends AgentResponse {
500+
private String secretUuid;
501+
502+
public String getSecretUuid() {
503+
return secretUuid;
504+
}
505+
506+
public void setSecretUuid(String secretUuid) {
507+
this.secretUuid = secretUuid;
508+
}
509+
}
510+
469511
public static class PingCmd extends AgentCommand {
470512
public String hostUuid;
471513
public Map<String, Object> configs;

plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ public interface KVMConstant {
129129
String KVM_GET_ENVELOPE_KEY_PATH = "/host/key/envelope/getEnvelopePublicKey";
130130
String KVM_ROTATE_ENVELOPE_KEY_PATH = "/host/key/envelope/rotateEnvelopeKey";
131131
String KVM_VERIFY_ENVELOPE_KEY_PATH = "/host/key/envelope/checkEnvelopeKey";
132+
String KVM_GET_SECRET_PATH = "/host/key/envelope/getSecret";
132133
String KVM_ENSURE_SECRET_PATH = "/host/key/envelope/ensureSecret";
133134

134135
/** HTTP timeout in seconds for envelope key sync (verify/create/rotate/get) to agent. */

plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
import org.zstack.header.host.MigrateVmOnHypervisorMsg.StorageMigrationPolicy;
5858
import org.zstack.header.secret.SecretHostDefineMsg;
5959
import org.zstack.header.secret.SecretHostDefineReply;
60+
import org.zstack.header.secret.SecretHostGetMsg;
61+
import org.zstack.header.secret.SecretHostGetReply;
6062
import org.zstack.header.message.APIMessage;
6163
import org.zstack.header.message.Message;
6264
import org.zstack.header.message.MessageReply;
@@ -750,6 +752,8 @@ protected void handleLocalMessage(Message msg) {
750752
handle((GetFileDownloadProgressMsg) msg);
751753
} else if (msg instanceof RestartKvmAgentMsg) {
752754
handle((RestartKvmAgentMsg) msg);
755+
} else if (msg instanceof SecretHostGetMsg) {
756+
handle((SecretHostGetMsg) msg);
753757
} else if (msg instanceof SecretHostDefineMsg) {
754758
handle((SecretHostDefineMsg) msg);
755759
} else {
@@ -5310,15 +5314,52 @@ public void handle(ErrorCode errCode, Map data) {
53105314
}).start();
53115315
}
53125316

5317+
private void handle(SecretHostGetMsg msg) {
5318+
SecretHostGetReply reply = new SecretHostGetReply();
5319+
if (StringUtils.isBlank(msg.getVmUuid()) || StringUtils.isBlank(msg.getPurpose()) || msg.getKeyVersion() == null) {
5320+
reply.setError(operr("vmUuid, purpose and keyVersion are required for get secret"));
5321+
bus.reply(msg, reply);
5322+
return;
5323+
}
5324+
5325+
String url = buildUrl(KVMConstant.KVM_GET_SECRET_PATH);
5326+
KVMAgentCommands.SecretHostGetCmd cmd = new KVMAgentCommands.SecretHostGetCmd();
5327+
cmd.setVmUuid(msg.getVmUuid());
5328+
cmd.setPurpose(msg.getPurpose());
5329+
cmd.setKeyVersion(msg.getKeyVersion());
5330+
restf.asyncJsonPost(url, cmd, new JsonAsyncRESTCallback<KVMAgentCommands.SecretHostGetResponse>(msg, reply) {
5331+
@Override
5332+
public void fail(ErrorCode err) {
5333+
reply.setError(err != null ? err : operr("get secret on agent failed"));
5334+
bus.reply(msg, reply);
5335+
}
5336+
5337+
@Override
5338+
public void success(KVMAgentCommands.SecretHostGetResponse rsp) {
5339+
if (rsp != null && rsp.isSuccess()) {
5340+
reply.setSecretUuid(rsp.getSecretUuid());
5341+
} else {
5342+
reply.setError(buildSecretAgentError(rsp, "get secret failed"));
5343+
}
5344+
bus.reply(msg, reply);
5345+
}
5346+
5347+
@Override
5348+
public Class<KVMAgentCommands.SecretHostGetResponse> getReturnClass() {
5349+
return KVMAgentCommands.SecretHostGetResponse.class;
5350+
}
5351+
}, TimeUnit.SECONDS, KVMConstant.ENVELOPE_KEY_HTTP_TIMEOUT_SEC);
5352+
}
5353+
53135354
private void handle(SecretHostDefineMsg msg) {
53145355
SecretHostDefineReply reply = new SecretHostDefineReply();
53155356
if (org.apache.commons.lang.StringUtils.isBlank(msg.getDekBase64())) {
53165357
reply.setError(operr("dekBase64 is required"));
53175358
bus.reply(msg, reply);
53185359
return;
53195360
}
5320-
if (StringUtils.isBlank(msg.getVmUuid()) || StringUtils.isBlank(msg.getPurpose()) || StringUtils.isBlank(msg.getProviderName())) {
5321-
reply.setError(operr("vmUuid, purpose and providerName are required for ensure secret"));
5361+
if (StringUtils.isBlank(msg.getVmUuid()) || StringUtils.isBlank(msg.getPurpose()) || msg.getKeyVersion() == null) {
5362+
reply.setError(operr("vmUuid, purpose and keyVersion are required for ensure secret"));
53225363
bus.reply(msg, reply);
53235364
return;
53245365
}
@@ -5396,7 +5437,7 @@ private void handle(SecretHostDefineMsg msg) {
53965437
cmd.setEncryptedDek(envelopeDekBase64);
53975438
cmd.setVmUuid(msg.getVmUuid());
53985439
cmd.setPurpose(msg.getPurpose());
5399-
cmd.setProviderName(msg.getProviderName());
5440+
cmd.setKeyVersion(msg.getKeyVersion());
54005441
cmd.setDescription(msg.getDescription() != null ? msg.getDescription() : "");
54015442
restf.asyncJsonPost(url, cmd, new JsonAsyncRESTCallback<KVMAgentCommands.SecretHostDefineResponse>(msg, reply) {
54025443
@Override
@@ -5412,14 +5453,7 @@ public void success(KVMAgentCommands.SecretHostDefineResponse rsp) {
54125453
reply.setSecretUuid(rsp.getSecretUuid());
54135454
}
54145455
} else {
5415-
if (rsp != null && rsp.getError() != null) {
5416-
ErrorCode err = new ErrorCode();
5417-
err.setCode(rsp.getError());
5418-
err.setDetails(rsp.getError());
5419-
reply.setError(err);
5420-
} else {
5421-
reply.setError(operr(rsp != null ? rsp.getError() : "ensure secret failed"));
5422-
}
5456+
reply.setError(buildSecretAgentError(rsp, "ensure secret failed"));
54235457
}
54245458
bus.reply(msg, reply);
54255459
}
@@ -5431,6 +5465,16 @@ public Class<KVMAgentCommands.SecretHostDefineResponse> getReturnClass() {
54315465
}, TimeUnit.SECONDS, KVMConstant.ENVELOPE_KEY_HTTP_TIMEOUT_SEC);
54325466
}
54335467

5468+
private ErrorCode buildSecretAgentError(KVMAgentCommands.AgentResponse rsp, String defaultMessage) {
5469+
if (rsp != null && rsp.getError() != null) {
5470+
ErrorCode err = new ErrorCode();
5471+
err.setCode(rsp.getError());
5472+
err.setDetails(rsp.getError());
5473+
return err;
5474+
}
5475+
return operr(defaultMessage);
5476+
}
5477+
54345478
@Override
54355479
protected void deleteTakeOverFlag(Completion completion) {
54365480
if (CoreGlobalProperty.UNIT_TEST_ON) {

0 commit comments

Comments
 (0)