Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions python/ccf/proposal_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
from loguru import logger as LOG # type: ignore


CERT_OID_SGX_QUOTE = "1.2.840.113556.10.1.1"


def dump_to_file(output_path: str, obj: dict, dump_args: dict):
with open(output_path, "w") as f:
json.dump(obj, f, **dump_args)
Expand Down Expand Up @@ -428,20 +425,12 @@ def update_ca_cert(cert_name, cert_path, skip_checks=False, **kwargs):

if not skip_checks:
try:
cert = x509.load_pem_x509_certificate(
x509.load_pem_x509_certificate(
cert_pem.encode(), crypto_backends.default_backend()
)
except Exception as exc:
raise ValueError("Cannot parse PEM certificate") from exc

try:
oid = x509.ObjectIdentifier(CERT_OID_SGX_QUOTE)
_ = cert.extensions.get_extension_for_oid(oid)
except x509.ExtensionNotFound as exc:
raise ValueError(
"X.509 extension with SGX quote not found in certificate"
) from exc

args = {"name": cert_name, "cert": cert_pem}
return build_proposal("update_ca_cert", args, **kwargs)

Expand All @@ -454,6 +443,8 @@ def set_jwt_issuer(json_path: str, **kwargs):
"issuer": obj["issuer"],
"key_filter": obj.get("key_filter", "all"),
"key_policy": obj.get("key_policy"),
"ca_cert_name": obj.get("ca_cert_name"),
"auto_refresh": obj.get("auto_refresh", False),
"jwks": obj.get("jwks"),
}
return build_proposal("set_jwt_issuer", args, **kwargs)
Expand Down
5 changes: 4 additions & 1 deletion src/enclave/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ struct CCFConfig
std::string subject_name;
std::vector<tls::SubjectAltName> subject_alternative_names;

size_t jwt_key_refresh_interval_s;

MSGPACK_DEFINE(
consensus_config,
node_info_network,
Expand All @@ -90,7 +92,8 @@ struct CCFConfig
genesis,
joining,
subject_name,
subject_alternative_names);
subject_alternative_names,
jwt_key_refresh_interval_s);
};

/// General administrative messages
Expand Down
10 changes: 10 additions & 0 deletions src/host/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@ int main(int argc, char** argv)
"Subject Alternative Name in node certificate. Can be either "
"iPAddress:xxx.xxx.xxx.xxx, or dNSName:sub.domain.tld");

size_t jwt_key_refresh_interval_s = 1800;
Comment thread
jumaffre marked this conversation as resolved.
app
.add_option(
"--jwt-key-refresh-interval-s",
jwt_key_refresh_interval_s,
"Interval in seconds for JWT public signing key refresh.")
->capture_default_str();

size_t memory_reserve_startup = 0;
app
.add_option(
Expand Down Expand Up @@ -653,6 +661,8 @@ int main(int argc, char** argv)
ccf_config.subject_name = subject_name;
ccf_config.subject_alternative_names = subject_alternative_names;

ccf_config.jwt_key_refresh_interval_s = jwt_key_refresh_interval_s;

if (*start)
{
start_type = StartType::New;
Expand Down
34 changes: 33 additions & 1 deletion src/http/http_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,46 @@ namespace http
http_parser_parse_url(url.data(), url.size(), 0, &parser_url);
if (err != 0)
{
throw std::runtime_error(fmt::format("Error parsing url: {}", err));
throw std::invalid_argument(fmt::format("Error parsing url: {}", err));
}

return std::make_pair(
extract_url_field(parser_url, UF_PATH, url),
extract_url_field(parser_url, UF_QUERY, url));
}

struct URL
{
std::string_view schema;
std::string_view host;
std::string_view port;
std::string_view path;
std::string_view query;
std::string_view fragment;
};

inline URL parse_url_full(const std::string& url)
{
LOG_TRACE_FMT("Received url to parse: {}", url);

http_parser_url parser_url;
http_parser_url_init(&parser_url);

const auto err =
http_parser_parse_url(url.data(), url.size(), 0, &parser_url);
if (err != 0)
{
throw std::invalid_argument(fmt::format("Error parsing url: {}", err));
}

return {extract_url_field(parser_url, UF_SCHEMA, url),
extract_url_field(parser_url, UF_HOST, url),
extract_url_field(parser_url, UF_PORT, url),
extract_url_field(parser_url, UF_PATH, url),
extract_url_field(parser_url, UF_QUERY, url),
extract_url_field(parser_url, UF_FRAGMENT, url)};
}

class Parser
{
protected:
Expand Down
7 changes: 5 additions & 2 deletions src/node/jwt.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ namespace ccf
{
JwtIssuerKeyFilter key_filter;
std::optional<JwtIssuerKeyPolicy> key_policy;
std::optional<std::string> ca_cert_name;
bool auto_refresh = false;

MSGPACK_DEFINE(key_filter, key_policy);
MSGPACK_DEFINE(key_filter, key_policy, ca_cert_name, auto_refresh);
};

DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(JwtIssuerMetadata);
DECLARE_JSON_REQUIRED_FIELDS(JwtIssuerMetadata, key_filter);
DECLARE_JSON_OPTIONAL_FIELDS(JwtIssuerMetadata, key_policy);
DECLARE_JSON_OPTIONAL_FIELDS(
JwtIssuerMetadata, key_policy, ca_cert_name, auto_refresh);

using JwtIssuer = std::string;
using JwtKeyId = std::string;
Expand Down
Loading