Skip to content

Commit

Permalink
Merge branch 'main' into gha_release
Browse files Browse the repository at this point in the history
  • Loading branch information
achamayou authored Jul 3, 2024
2 parents a15c8fe + 967a83e commit 37a963c
Show file tree
Hide file tree
Showing 22 changed files with 372 additions and 150 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- The `programmability` sample app now demonstrates how applications can define their own extensions, creating bindings between C++ and JS state, and allowing JS endpoints to call functions implemented in C++.
- Introduce `DynamicJSEndpointRegistry::record_action_for_audit_v1` and `DynamicJSEndpointRegistry::check_action_not_replayed_v1` to allow an application making use of the programmability feature to easily implement auditability, and protect users allowed to update the application against replay attacks (#6285).
- Endpoints now support a `ToBackup` redirection strategy, for requests which should never be executed on a primary. These must also be read-only. These are configured similar to `ToPrimary` endpoints, with a `to_backup` object (specifying by-role or statically-addressed targets) in each node's configuration.
- Introduced `ccf::historical::read_only_adapter_v4` and `ccf::historical::read_write_adapter_v4`. Users are now capable of passing a custom error handler to the adapter to customise RPC responses for internal historical queries errors, which are listed in `ccf::historical::HistoricalQueryErrorCode` enum.

## Changed
### Changed

- Updated Open Enclave to [0.19.7](https://github.com/openenclave/openenclave/releases/tag/v0.19.7).

### Deprecated

- `ccf::historical::adapter_v3` becomes deprecated in favour of `_v4` version.

### Removed

- Removed the existing metrics endpoint and API (`GET /api/metrics`, `get_metrics_v1`). Stats for request execution can instead be gathered by overriding the `EndpointRegistry::handle_event_request_completed()` method.
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,9 @@ if(BUILD_TESTS)
)
target_link_libraries(base64_test PRIVATE ${CMAKE_THREAD_LIBS_INIT})

add_unit_test(pem_test ${CMAKE_CURRENT_SOURCE_DIR}/src/crypto/test/pem.cpp)
target_link_libraries(pem_test PRIVATE ${CMAKE_THREAD_LIBS_INIT})

add_test_bin(
kp_cert_test ${CMAKE_CURRENT_SOURCE_DIR}/src/crypto/test/kp_cert.cpp
)
Expand Down
1 change: 1 addition & 0 deletions cmake/crypto.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(CCFCRYPTO_SRC
${CCF_DIR}/src/crypto/verifier.cpp
${CCF_DIR}/src/crypto/key_wrap.cpp
${CCF_DIR}/src/crypto/hmac.cpp
${CCF_DIR}/src/crypto/pem.cpp
${CCF_DIR}/src/crypto/ecdsa.cpp
${CCF_DIR}/src/crypto/openssl/symmetric_key.cpp
${CCF_DIR}/src/crypto/openssl/public_key.cpp
Expand Down
69 changes: 14 additions & 55 deletions include/ccf/crypto/pem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,84 +18,57 @@ namespace ccf::crypto
{
private:
std::string s;

void check_pem_format()
{
if (s.find("-----BEGIN") == std::string::npos)
{
throw std::runtime_error(
fmt::format("PEM constructed with non-PEM data: {}", s));
}
}
void check_pem_format();

public:
Pem() = default;

Pem(const std::string& s_) : s(s_)
{
check_pem_format();
}

Pem(const uint8_t* data, size_t size)
{
if (size == 0)
throw std::logic_error("Got PEM of size 0.");

// If it's already null-terminated, don't suffix again
const auto null_terminated = *(data + size - 1) == 0;
if (null_terminated)
size -= 1;

s.assign(reinterpret_cast<const char*>(data), size);

check_pem_format();
}
Pem(const std::string& s_);
Pem(const uint8_t* data, size_t size);

explicit Pem(std::span<const uint8_t> s) : Pem(s.data(), s.size()) {}

explicit Pem(const std::vector<uint8_t>& v) : Pem(v.data(), v.size()) {}

bool operator==(const Pem& rhs) const
inline bool operator==(const Pem& rhs) const
{
return s == rhs.s;
}

bool operator!=(const Pem& rhs) const
inline bool operator!=(const Pem& rhs) const
{
return !(*this == rhs);
}

bool operator<(const Pem& rhs) const
inline bool operator<(const Pem& rhs) const
{
return s < rhs.s;
}

const std::string& str() const
inline const std::string& str() const
{
return s;
}

uint8_t* data()
inline uint8_t* data()
{
return reinterpret_cast<uint8_t*>(s.data());
}

const uint8_t* data() const
inline const uint8_t* data() const
{
return reinterpret_cast<const uint8_t*>(s.data());
}

size_t size() const
inline size_t size() const
{
return s.size();
}

bool empty() const
inline bool empty() const
{
return s.empty();
}

std::vector<uint8_t> raw() const
inline std::vector<uint8_t> raw() const
{
return {data(), data() + size()};
}
Expand Down Expand Up @@ -128,22 +101,8 @@ namespace ccf::crypto
return "Pem";
}

static std::vector<ccf::crypto::Pem> split_x509_cert_bundle(
const std::string_view& pem)
{
std::string separator("-----END CERTIFICATE-----");
std::vector<ccf::crypto::Pem> pems;
auto separator_end = 0;
auto next_separator_start = pem.find(separator);
while (next_separator_start != std::string_view::npos)
{
pems.emplace_back(std::string(
pem.substr(separator_end, next_separator_start + separator.size())));
separator_end = next_separator_start + separator.size();
next_separator_start = pem.find(separator, separator_end);
}
return pems;
}
std::vector<ccf::crypto::Pem> split_x509_cert_bundle(
const std::string_view& pem);

inline void fill_json_schema(nlohmann::json& schema, const Pem*)
{
Expand Down
7 changes: 0 additions & 7 deletions include/ccf/ds/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,6 @@ namespace ccf::logger
logger->write(line);
}

#ifndef INSIDE_ENCLAVE
if (line.log_level == LoggerLevel::FATAL)
{
throw std::logic_error("Fatal: " + format_to_text(line));
}
#endif

return true;
}
};
Expand Down
41 changes: 41 additions & 0 deletions include/ccf/historical_queries_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,30 @@ namespace ccf::historical
std::optional<ccf::TxID> txid_from_header(
endpoints::CommandEndpointContext& args);

enum class HistoricalQueryErrorCode
{
InternalError,
TransactionPending,
TransactionInvalid,
TransactionIdMissing,
TransactionPartiallyReady,
};

using ErrorHandler = std::function<void(
HistoricalQueryErrorCode err,
std::string reason,
endpoints::EndpointContext& args)>;

using ReadOnlyErrorHandler = std::function<void(
HistoricalQueryErrorCode err,
std::string reason,
endpoints::ReadOnlyEndpointContext& args)>;

void default_error_handler(
HistoricalQueryErrorCode err,
std::string reason,
endpoints::CommandEndpointContext& args);

enum class HistoricalTxStatus
{
Error,
Expand All @@ -56,21 +80,38 @@ namespace ccf::historical
ccf::SeqNo seqno,
std::string& error_reason);

CCF_DEPRECATED("Replaced by _v4")
ccf::endpoints::EndpointFunction adapter_v3(
const HandleHistoricalQuery& f,
ccf::AbstractNodeContext& node_context,
const CheckHistoricalTxStatus& available,
const TxIDExtractor& extractor = txid_from_header);

CCF_DEPRECATED("Replaced by _v4")
ccf::endpoints::ReadOnlyEndpointFunction read_only_adapter_v3(
const HandleReadOnlyHistoricalQuery& f,
ccf::AbstractNodeContext& node_context,
const CheckHistoricalTxStatus& available,
const ReadOnlyTxIDExtractor& extractor = txid_from_header);

CCF_DEPRECATED("Replaced by _v4")
ccf::endpoints::EndpointFunction read_write_adapter_v3(
const HandleReadWriteHistoricalQuery& f,
ccf::AbstractNodeContext& node_context,
const CheckHistoricalTxStatus& available,
const TxIDExtractor& extractor = txid_from_header);

ccf::endpoints::ReadOnlyEndpointFunction read_only_adapter_v4(
const HandleReadOnlyHistoricalQuery& f,
ccf::AbstractNodeContext& node_context,
const CheckHistoricalTxStatus& available,
const ReadOnlyTxIDExtractor& extractor = txid_from_header,
const ReadOnlyErrorHandler& ehandler = default_error_handler);

ccf::endpoints::EndpointFunction read_write_adapter_v4(
const HandleReadWriteHistoricalQuery& f,
ccf::AbstractNodeContext& node_context,
const CheckHistoricalTxStatus& available,
const TxIDExtractor& extractor = txid_from_header,
const ErrorHandler& ehandler = default_error_handler);
}
6 changes: 3 additions & 3 deletions samples/apps/logging/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@ namespace loggingapp
make_read_only_endpoint(
"/log/private/historical",
HTTP_GET,
ccf::historical::read_only_adapter_v3(
ccf::historical::read_only_adapter_v4(
get_historical, context, is_tx_committed),
auth_policies)
.set_auto_schema<void, LoggingGetHistorical::Out>()
Expand Down Expand Up @@ -1335,7 +1335,7 @@ namespace loggingapp
make_read_only_endpoint(
"/log/private/historical_receipt",
HTTP_GET,
ccf::historical::read_only_adapter_v3(
ccf::historical::read_only_adapter_v4(
get_historical_with_receipt, context, is_tx_committed),
auth_policies)
.set_auto_schema<void, LoggingGetReceipt::Out>()
Expand Down Expand Up @@ -1391,7 +1391,7 @@ namespace loggingapp
make_read_only_endpoint(
"/log/public/historical_receipt",
HTTP_GET,
ccf::historical::read_only_adapter_v3(
ccf::historical::read_only_adapter_v4(
get_historical_with_receipt_and_claims, context, is_tx_committed),
auth_policies)
.set_auto_schema<void, LoggingGetReceipt::Out>()
Expand Down
2 changes: 1 addition & 1 deletion src/apps/js_generic/js_generic_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace ccf
consensus, view, seqno, error_reason);
};

ccf::historical::adapter_v3(
ccf::historical::read_write_adapter_v4(
[this, endpoint](
ccf::endpoints::EndpointContext& endpoint_ctx,
ccf::historical::StatePtr state) {
Expand Down
2 changes: 2 additions & 0 deletions src/clients/perf/perf_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace client
if (core_id > threads || core_id < 0)
{
LOG_FATAL_FMT("Invalid core id: {}", core_id);
abort();
return false;
}

Expand All @@ -43,6 +44,7 @@ namespace client
if (sched_setaffinity(0, sizeof(cpu_set_t), &set) < 0)
{
LOG_FATAL_FMT("Unable to set affinity");
abort();
return false;
}

Expand Down
52 changes: 52 additions & 0 deletions src/crypto/pem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#include "ccf/crypto/pem.h"

namespace ccf::crypto
{
void Pem::check_pem_format()
{
if (s.find("-----BEGIN") == std::string::npos)
{
throw std::runtime_error(
fmt::format("PEM constructed with non-PEM data: {}", s));
}
}

Pem::Pem(const std::string& s_) : s(s_)
{
check_pem_format();
}

Pem::Pem(const uint8_t* data, size_t size)
{
if (size == 0)
throw std::logic_error("Got PEM of size 0.");

// If it's already null-terminated, don't suffix again
const auto null_terminated = *(data + size - 1) == 0;
if (null_terminated)
size -= 1;

s.assign(reinterpret_cast<const char*>(data), size);

check_pem_format();
}

std::vector<ccf::crypto::Pem> split_x509_cert_bundle(
const std::string_view& pem)
{
std::string separator("-----END CERTIFICATE-----");
std::vector<ccf::crypto::Pem> pems;
auto separator_end = 0;
auto next_separator_start = pem.find(separator);
while (next_separator_start != std::string_view::npos)
{
pems.emplace_back(std::string(
pem.substr(separator_end, next_separator_start + separator.size())));
separator_end = next_separator_start + separator.size();
next_separator_start = pem.find(separator, separator_end);
}
return pems;
}
}
Loading

0 comments on commit 37a963c

Please sign in to comment.