зеркало из https://github.com/microsoft/CCF.git
Verify quote (#1842)
This commit is contained in:
Родитель
44eb752bf3
Коммит
8d798d8a2f
|
@ -238,7 +238,8 @@ namespace ccf
|
|||
#ifdef GET_QUOTE
|
||||
if (network.consensus_type != ConsensusType::BFT)
|
||||
{
|
||||
auto quote_opt = QuoteGenerator::get_quote(node_cert);
|
||||
auto quote_opt =
|
||||
QuoteGenerator::get_quote(node_sign_kp->public_key_pem());
|
||||
if (!quote_opt.has_value())
|
||||
{
|
||||
return Fail<CreateNew::Out>("Quote could not be retrieved");
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace ccf
|
|||
static std::optional<std::vector<uint8_t>> get_quote(const tls::Pem& cert)
|
||||
{
|
||||
std::vector<uint8_t> raw_quote;
|
||||
crypto::Sha256Hash h{cert.raw()};
|
||||
crypto::Sha256Hash h{cert.contents()};
|
||||
uint8_t* quote;
|
||||
size_t quote_len = 0;
|
||||
|
||||
|
@ -127,7 +127,7 @@ namespace ccf
|
|||
static QuoteVerificationResult verify_quoted_certificate(
|
||||
const tls::Pem& cert, const oe_report_t& parsed_quote)
|
||||
{
|
||||
crypto::Sha256Hash hash{cert.raw()};
|
||||
crypto::Sha256Hash hash{cert.contents()};
|
||||
|
||||
if (
|
||||
parsed_quote.report_data_size != OE_REPORT_DATA_SIZE ||
|
||||
|
|
|
@ -89,9 +89,11 @@ namespace ccf
|
|||
#ifdef GET_QUOTE
|
||||
if (network.consensus_type != ConsensusType::BFT)
|
||||
{
|
||||
auto pk_pem = public_key_pem_from_cert(caller_pem);
|
||||
|
||||
QuoteVerificationResult verify_result =
|
||||
QuoteVerifier::verify_quote_against_store(
|
||||
tx, this->network.node_code_ids, in.quote, caller_pem);
|
||||
tx, this->network.node_code_ids, in.quote, pk_pem);
|
||||
|
||||
if (verify_result != QuoteVerificationResult::VERIFIED)
|
||||
{
|
||||
|
|
|
@ -856,4 +856,29 @@ namespace tls
|
|||
return std::make_shared<KeyPair>(std::move(key));
|
||||
}
|
||||
}
|
||||
|
||||
static inline tls::Pem public_key_pem_from_cert(const tls::Pem& cert)
|
||||
{
|
||||
mbedtls_x509_crt c;
|
||||
mbedtls_x509_crt_init(&c);
|
||||
int rc = mbedtls_x509_crt_parse(&c, cert.data(), cert.size());
|
||||
if (rc != 0)
|
||||
{
|
||||
mbedtls_x509_crt_free(&c);
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Failed to parse certificate, mbedtls_x509_crt_parse: {}", rc));
|
||||
}
|
||||
uint8_t data[2048];
|
||||
rc = mbedtls_pk_write_pubkey_pem(&c.pk, data, max_pem_key_size);
|
||||
if (rc != 0)
|
||||
{
|
||||
mbedtls_x509_crt_free(&c);
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Failed to serialise public key, mbedtls_pk_write_pubkey_pem: {}", rc));
|
||||
}
|
||||
|
||||
size_t len = strlen((char const*)data);
|
||||
mbedtls_x509_crt_free(&c);
|
||||
return tls::Pem(data, len);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace tls
|
|||
|
||||
Pem(const std::string& s_) : s(s_) {}
|
||||
|
||||
Pem(size_t size) : s(size, '0') {}
|
||||
|
||||
Pem(const uint8_t* data, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
|
@ -78,6 +80,12 @@ namespace tls
|
|||
return {data(), data() + size()};
|
||||
}
|
||||
|
||||
// Not null-terminated
|
||||
std::vector<uint8_t> contents() const
|
||||
{
|
||||
return {data(), data() + s.size()};
|
||||
}
|
||||
|
||||
MSGPACK_DEFINE(s);
|
||||
};
|
||||
|
||||
|
@ -102,4 +110,4 @@ namespace tls
|
|||
fmt::format("Unable to parse pem from this JSON: {}", j.dump()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -388,4 +388,18 @@ TEST_CASE("Wrap, unwrap with RSAKeyPair")
|
|||
auto unwrapped = rsa_kp->unwrap(wrapped, label);
|
||||
REQUIRE(input == unwrapped);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Extract public key from cert")
|
||||
{
|
||||
for (const auto curve : supported_curves)
|
||||
{
|
||||
INFO("With curve: " << labels[static_cast<size_t>(curve) - 1]);
|
||||
auto kp = tls::make_key_pair(curve);
|
||||
auto pk = kp->public_key_pem();
|
||||
auto cert = kp->self_sign("CN=name");
|
||||
|
||||
auto pubk = tls::public_key_pem_from_cert(cert);
|
||||
REQUIRE(pk == pubk);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,12 @@ import infra.net
|
|||
import infra.e2e_args
|
||||
import suite.test_requirements as reqs
|
||||
import infra.logging_app as app
|
||||
import ssl
|
||||
import hashlib
|
||||
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from loguru import logger as LOG
|
||||
|
||||
|
||||
|
@ -49,9 +54,42 @@ def test_quote(network, args, verify=True):
|
|||
r = c.get("/node/quotes")
|
||||
quotes = r.body.json()["quotes"]
|
||||
assert len(quotes) == len(network.find_nodes())
|
||||
|
||||
for quote in quotes:
|
||||
mrenclave = quote["mrenclave"]
|
||||
assert mrenclave == expected_mrenclave, (mrenclave, expected_mrenclave)
|
||||
qpath = os.path.join(network.common_dir, f"quote{quote['node_id']}")
|
||||
|
||||
with open(qpath, "wb") as q:
|
||||
q.write(bytes.fromhex(quote["raw"]))
|
||||
oed = subprocess.run(
|
||||
[
|
||||
os.path.join(args.oe_binary, "oeverify"),
|
||||
"-r",
|
||||
qpath,
|
||||
"-f",
|
||||
"LEGACY_REPORT_REMOTE",
|
||||
],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
out = oed.stdout.decode().split(os.linesep)
|
||||
for line in out:
|
||||
if line.startswith("Enclave sgx_report_data:"):
|
||||
report_digest = line.split(" ")[-1][2:]
|
||||
assert "Evidence verification succeeded (0)." in out
|
||||
|
||||
node = network.nodes[quote["node_id"]]
|
||||
node_cert = ssl.get_server_certificate((node.pubhost, node.rpc_port))
|
||||
public_key = x509.load_pem_x509_certificate(
|
||||
node_cert.encode(), default_backend()
|
||||
).public_key()
|
||||
pub_key = public_key.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
key_digest = hashlib.sha256(pub_key).hexdigest()
|
||||
assert report_digest[: len(key_digest)] == key_digest
|
||||
|
||||
return network
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче