зеркало из https://github.com/microsoft/CCF.git
Pin UVM roots of trust and add snp_uvm_endorsements_file to configuration (#5867)
This commit is contained in:
Родитель
085a22c81d
Коммит
7b3f22fb62
|
@ -2,4 +2,4 @@
|
||||||
(. =) Y (0 0) (x X) Y
|
(. =) Y (0 0) (x X) Y
|
||||||
O \ o | /
|
O \ o | /
|
||||||
/-xXx--//-----x=x--/-xXx--/---x---->>>--/
|
/-xXx--//-----x=x--/-xXx--/---x---->>>--/
|
||||||
...
|
......
|
|
@ -10,7 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
[5.0.0-dev10]: https://github.com/microsoft/CCF/releases/tag/ccf-5.0.0-dev10
|
[5.0.0-dev10]: https://github.com/microsoft/CCF/releases/tag/ccf-5.0.0-dev10
|
||||||
|
|
||||||
- The `url` field in `snp_endorsements_servers` can now contain environment variables that will be resolved at startup, such as "$Fabric_NodeIPOrFQDN:2377" (#5862).
|
- The `url` field in `snp_endorsements_servers` can now contain environment variables that will be resolved at startup, such as "$Fabric_NodeIPOrFQDN:2377" (#5862).
|
||||||
- Add a `new snp_security_policy_file` configuration value under `attestation`, superseding the lookup from `$UVM_SECURITY_CONTEXT_DIR`. The value can contain environment variables, for example: `"snp_security_policy_file": "$UVM_SECURITY_CONTEXT_DIR/security-policy-base64"`.
|
- Add a new `snp_security_policy_file` configuration value under `attestation`, superseding the lookup from `$UVM_SECURITY_CONTEXT_DIR`. The value can contain environment variables, for example: `"snp_security_policy_file": "$UVM_SECURITY_CONTEXT_DIR/security-policy-base64"`.
|
||||||
|
- Add a new `snp_uvm_endorsements_file` configuration value under `attestation`, superseding the lookup from `$UVM_SECURITY_CONTEXT_DIR`. The value can contain environment variables, for example: `"snp_uvm_endorsements_file": "$UVM_SECURITY_CONTEXT_DIR/reference-info-base64"`. This value can come from an untrusted location, like `snp_security_policy_file` and AMD endorsements (fetched from `snp_endorsements_servers`), because the CCF code contains pre-defined roots of trust.
|
||||||
|
|
||||||
## [5.0.0-dev9]
|
## [5.0.0-dev9]
|
||||||
|
|
||||||
|
|
|
@ -460,6 +460,10 @@
|
||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
"description": "Path to file containing the security policy (SEV-SNP only), can contain environment variables, such as $UVM_SECURITY_CONTEXT_DIR"
|
"description": "Path to file containing the security policy (SEV-SNP only), can contain environment variables, such as $UVM_SECURITY_CONTEXT_DIR"
|
||||||
},
|
},
|
||||||
|
"snp_uvm_endorsements_file": {
|
||||||
|
"type": ["string", "null"],
|
||||||
|
"description": "Path to file containing UVM endorsements as a base64-encoded COSE Sign1 (SEV-SNP only). Can contain environment variables, such as $UVM_SECURITY_CONTEXT_DIR"
|
||||||
|
},
|
||||||
"snp_endorsements_servers": {
|
"snp_endorsements_servers": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -61,6 +61,7 @@ For non-Azure deployments, the certificate chain for VCEK will need to be retrie
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"snp_security_policy_file": "/path/to/security-policy-base64",
|
"snp_security_policy_file": "/path/to/security-policy-base64",
|
||||||
|
"snp_uvm_endorsements_file": "/path/to/reference-info-base64"
|
||||||
}
|
}
|
||||||
|
|
||||||
.. tip:: See :ccf_repo:`samples/config/start_config_amd_sev_snp.json` for a sample node configuration for non-Azure deployments.
|
.. tip:: See :ccf_repo:`samples/config/start_config_amd_sev_snp.json` for a sample node configuration for non-Azure deployments.
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct CCFConfig
|
||||||
{
|
{
|
||||||
ccf::pal::snp::EndorsementsServers snp_endorsements_servers = {};
|
ccf::pal::snp::EndorsementsServers snp_endorsements_servers = {};
|
||||||
std::optional<std::string> snp_security_policy_file = std::nullopt;
|
std::optional<std::string> snp_security_policy_file = std::nullopt;
|
||||||
|
std::optional<std::string> snp_uvm_endorsements_file = std::nullopt;
|
||||||
|
|
||||||
struct Environment
|
struct Environment
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
"url": "169.254.169.254"
|
"url": "169.254.169.254"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"snp_security_policy_file": "$UVM_SECURITY_CONTEXT_DIR/security-policy-base64"
|
"snp_security_policy_file": "$UVM_SECURITY_CONTEXT_DIR/security-policy-base64",
|
||||||
|
"snp_uvm_endorsements_file": "$UVM_SECURITY_CONTEXT_DIR/reference-info-base64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attestation": {
|
"attestation": {
|
||||||
"environment": {
|
"snp_endorsements_servers": [
|
||||||
"security_context_directory": "UVM_SECURITY_CONTEXT_DIR"
|
{
|
||||||
}
|
"type": "THIM",
|
||||||
|
"url": "169.254.169.254"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"snp_security_policy_file": "/path/to/security-policy-base64",
|
||||||
|
"snp_uvm_endorsements_file": "/opt/confidential-containers/share/kata-containers/reference-info-base64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
"url": "kdsintf.amd.com"
|
"url": "kdsintf.amd.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"snp_security_policy_file": "/path/to/security-policy-base64"
|
"snp_security_policy_file": "/path/to/security-policy-base64",
|
||||||
|
"snp_uvm_endorsements_file": "/path/to/reference-info-base64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,8 @@ DECLARE_JSON_OPTIONAL_FIELDS(
|
||||||
CCFConfig::Attestation,
|
CCFConfig::Attestation,
|
||||||
snp_endorsements_servers,
|
snp_endorsements_servers,
|
||||||
environment,
|
environment,
|
||||||
snp_security_policy_file);
|
snp_security_policy_file,
|
||||||
|
snp_uvm_endorsements_file);
|
||||||
|
|
||||||
DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(CCFConfig);
|
DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(CCFConfig);
|
||||||
DECLARE_JSON_REQUIRED_FIELDS(CCFConfig, network);
|
DECLARE_JSON_REQUIRED_FIELDS(CCFConfig, network);
|
||||||
|
|
|
@ -559,6 +559,21 @@ int main(int argc, char** argv)
|
||||||
files::try_slurp_string(security_policy_file);
|
files::try_slurp_string(security_policy_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startup_config.attestation.snp_uvm_endorsements_file.has_value())
|
||||||
|
{
|
||||||
|
auto snp_uvm_endorsements_file =
|
||||||
|
startup_config.attestation.snp_uvm_endorsements_file.value();
|
||||||
|
LOG_DEBUG_FMT(
|
||||||
|
"Resolving snp_uvm_endorsements_file: {}", snp_uvm_endorsements_file);
|
||||||
|
snp_uvm_endorsements_file =
|
||||||
|
nonstd::expand_envvars_in_path(snp_uvm_endorsements_file);
|
||||||
|
LOG_DEBUG_FMT(
|
||||||
|
"Resolved snp_uvm_endorsements_file: {}", snp_uvm_endorsements_file);
|
||||||
|
|
||||||
|
startup_config.attestation.environment.uvm_endorsements =
|
||||||
|
files::try_slurp_string(snp_uvm_endorsements_file);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto endorsement_servers_it =
|
for (auto endorsement_servers_it =
|
||||||
startup_config.attestation.snp_endorsements_servers.begin();
|
startup_config.attestation.snp_endorsements_servers.begin();
|
||||||
endorsement_servers_it !=
|
endorsement_servers_it !=
|
||||||
|
|
|
@ -51,6 +51,34 @@ namespace ccf
|
||||||
std::string feed;
|
std::string feed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Roots of trust for UVM endorsements/measurement in AMD SEV-SNP attestations
|
||||||
|
static std::vector<UVMEndorsements> uvm_roots_of_trust = {
|
||||||
|
// Confidential Azure Kubertnetes Service (AKS)
|
||||||
|
{"did:x509:0:sha256:I__iuL25oXEVFdTP_aBLx_eT1RPHbCQ_ECBQfYZpt9s::eku:1.3.6."
|
||||||
|
"1.4.1.311.76.59.1.2",
|
||||||
|
"ContainerPlat-AMD-UVM",
|
||||||
|
"0"},
|
||||||
|
// Confidential Azure Container Instances (ACI)
|
||||||
|
{"did:x509:0:sha256:I__iuL25oXEVFdTP_aBLx_eT1RPHbCQ_ECBQfYZpt9s::eku:1.3.6."
|
||||||
|
"1.4.1.311.76.59.1.5",
|
||||||
|
"ConfAKS-AMD-UVM",
|
||||||
|
"0"}};
|
||||||
|
|
||||||
|
bool inline matches_uvm_roots_of_trust(const UVMEndorsements& endorsements)
|
||||||
|
{
|
||||||
|
for (const auto& uvm_root_of_trust : uvm_roots_of_trust)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
uvm_root_of_trust.did == endorsements.did &&
|
||||||
|
uvm_root_of_trust.feed == endorsements.feed &&
|
||||||
|
uvm_root_of_trust.svn <= endorsements.svn)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace cose
|
namespace cose
|
||||||
{
|
{
|
||||||
static constexpr auto HEADER_PARAM_ISSUER = "iss";
|
static constexpr auto HEADER_PARAM_ISSUER = "iss";
|
||||||
|
@ -311,6 +339,18 @@ namespace ccf
|
||||||
phdr.feed,
|
phdr.feed,
|
||||||
payload.sevsnpvm_guest_svn);
|
payload.sevsnpvm_guest_svn);
|
||||||
|
|
||||||
return {did, phdr.feed, payload.sevsnpvm_guest_svn};
|
UVMEndorsements end{did, phdr.feed, payload.sevsnpvm_guest_svn};
|
||||||
|
|
||||||
|
if (!matches_uvm_roots_of_trust(end))
|
||||||
|
{
|
||||||
|
throw std::logic_error(fmt::format(
|
||||||
|
"UVM endorsements did {}, feed {}, svn {} "
|
||||||
|
"do not match any of the known UVM roots of trust",
|
||||||
|
end.did,
|
||||||
|
end.feed,
|
||||||
|
end.svn));
|
||||||
|
}
|
||||||
|
|
||||||
|
return end;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,8 @@
|
||||||
"attestation":
|
"attestation":
|
||||||
{
|
{
|
||||||
"snp_endorsements_servers": {{ snp_endorsements_servers|tojson }},
|
"snp_endorsements_servers": {{ snp_endorsements_servers|tojson }},
|
||||||
"snp_security_policy_file": "{{ snp_security_policy_file }}"
|
"snp_security_policy_file": "{{ snp_security_policy_file }}",
|
||||||
|
"snp_uvm_endorsements_file": "{{ snp_uvm_endorsements_file }}"
|
||||||
},
|
},
|
||||||
"service_data_json_file": {{ service_data_json_file|tojson }},
|
"service_data_json_file": {{ service_data_json_file|tojson }},
|
||||||
"command": {
|
"command": {
|
||||||
|
|
|
@ -197,6 +197,7 @@ class Network:
|
||||||
"tick_ms",
|
"tick_ms",
|
||||||
"max_msg_size_bytes",
|
"max_msg_size_bytes",
|
||||||
"snp_security_policy_file",
|
"snp_security_policy_file",
|
||||||
|
"snp_uvm_endorsements_file",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Maximum delay (seconds) for updates to propagate from the primary to backups
|
# Maximum delay (seconds) for updates to propagate from the primary to backups
|
||||||
|
|
|
@ -620,6 +620,7 @@ class CCFRemote(object):
|
||||||
follow_redirect=True,
|
follow_redirect=True,
|
||||||
max_uncommitted_tx_count=0,
|
max_uncommitted_tx_count=0,
|
||||||
snp_security_policy_file=None,
|
snp_security_policy_file=None,
|
||||||
|
snp_uvm_endorsements_file=None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -742,6 +743,12 @@ class CCFRemote(object):
|
||||||
"$UVM_SECURITY_CONTEXT_DIR/security-policy-base64"
|
"$UVM_SECURITY_CONTEXT_DIR/security-policy-base64"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Default snp_uvm_endorsements_file if not set
|
||||||
|
if snp_uvm_endorsements_file is None:
|
||||||
|
snp_uvm_endorsements_file = (
|
||||||
|
"$UVM_SECURITY_CONTEXT_DIR/reference-info-base64"
|
||||||
|
)
|
||||||
|
|
||||||
# Validate consensus timers
|
# Validate consensus timers
|
||||||
if (
|
if (
|
||||||
election_timeout_ms is not None
|
election_timeout_ms is not None
|
||||||
|
@ -803,6 +810,7 @@ class CCFRemote(object):
|
||||||
follow_redirect=follow_redirect,
|
follow_redirect=follow_redirect,
|
||||||
max_uncommitted_tx_count=max_uncommitted_tx_count,
|
max_uncommitted_tx_count=max_uncommitted_tx_count,
|
||||||
snp_security_policy_file=snp_security_policy_file,
|
snp_security_policy_file=snp_security_policy_file,
|
||||||
|
snp_uvm_endorsements_file=snp_uvm_endorsements_file,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче