diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9c61d401..f55a2e41 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev7 +FROM ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev8 diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index d9f472a1..83b10a47 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -13,7 +13,7 @@ jobs: checks: name: Format and License Checks runs-on: ubuntu-20.04 - container: ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev7 + container: ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev8 steps: - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Checkout repository @@ -37,7 +37,7 @@ jobs: unit_tests_enabled: OFF runs-on: ${{ matrix.platform.nodes }} container: - image: ghcr.io/microsoft/ccf/app/dev/${{ matrix.platform.image }}:ccf-6.0.0-dev7 + image: ghcr.io/microsoft/ccf/app/dev/${{ matrix.platform.image }}:ccf-6.0.0-dev8 options: ${{ matrix.platform.options }} env: # Helps to distinguish between CI and local builds. diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5ac24df7..a3fffb38 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -17,7 +17,7 @@ jobs: name: Analyze runs-on: ubuntu-latest - container: ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev7 + container: ghcr.io/microsoft/ccf/app/dev/virtual:ccf-6.0.0-dev8 permissions: actions: read diff --git a/.pipelines/pullrequest.yml b/.pipelines/pullrequest.yml index daef99d5..83d7dded 100644 --- a/.pipelines/pullrequest.yml +++ b/.pipelines/pullrequest.yml @@ -8,7 +8,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time - name: CCF_VERSION displayName: Target CCF version to build for type: string - default: 6.0.0-dev7 + default: 6.0.0-dev8 variables: SCITT_CI: 1 # used in scitt builds and tests diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 304ec160..a53b6939 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -39,10 +39,10 @@ It is expected that you have Ubuntu 20.04. Follow the steps below to setup your 2. Install dependencies: ```sh - wget https://github.com/microsoft/CCF/archive/refs/tags/ccf-6.0.0-dev7.tar.gz - tar xvzf ccf-6.0.0-dev7.tar.gz - cd CCF-ccf-6.0.0-dev7/getting_started/setup_vm/ - ./run.sh app-dev.yml -e ccf_ver=6.0.0-dev7 -e platform= -e clang_version=15 + wget https://github.com/microsoft/CCF/archive/refs/tags/ccf-6.0.0-dev8.tar.gz + tar xvzf ccf-6.0.0-dev8.tar.gz + cd CCF-ccf-6.0.0-dev8/getting_started/setup_vm/ + ./run.sh app-dev.yml -e ccf_ver=6.0.0-dev8 -e platform= -e clang_version=15 ``` ## Compiling diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index aac2e811..84ae9b52 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -19,7 +19,7 @@ project(scitt set(COMPILE_TARGET "snp" CACHE STRING "Target compilation platform, either 'virtual', or 'snp'") option(BUILD_TESTS "Whether to build tests" ON) option(ENABLE_CLANG_TIDY "Run clang-tidy on the codebase" OFF) -# Added as option to enable Azure Linux build in 6.0.0-dev7, will eventually be removed +# Added as option to enable Azure Linux build in 6.0.0-dev, will eventually be removed # once the transition to libstdc++ is complete set(USE_LIBCXX ON CACHE BOOL "Use libc++ instead of libstdc++") @@ -141,7 +141,7 @@ if (BUILD_TESTS) unit_tests SYSTEM PRIVATE ${CCF_DIR}/include ${CCF_DIR}/include/3rdparty - ${CCF_DIR}/include/ccf/_private # openssl_wrappers depends on ds/x509_time_fmt.h + ${CCF_DIR}/include/ccf/_private # public_key.h and verifier.h depend on crypto/openssl/openssl_wrappers.h ) if (ENABLE_CLANG_TIDY) diff --git a/app/src/cbor.h b/app/src/cbor.h index cd5c1b0c..076cf832 100644 --- a/app/src/cbor.h +++ b/app/src/cbor.h @@ -5,7 +5,6 @@ #include "tracing.h" -#include #include #include #include diff --git a/app/src/cose.h b/app/src/cose.h index bf28c670..fe2311b3 100644 --- a/app/src/cose.h +++ b/app/src/cose.h @@ -4,7 +4,6 @@ #pragma once #include "cbor.h" -#include "openssl_wrappers.h" #include "public_key.h" #include "tracing.h" #include "util.h" diff --git a/app/src/did/resolver.h b/app/src/did/resolver.h index 447aeebf..b2c709b8 100644 --- a/app/src/did/resolver.h +++ b/app/src/did/resolver.h @@ -101,13 +101,16 @@ namespace scitt::did void register_resolver(std::unique_ptr resolver) { - CCF_ASSERT( - resolver->get_method_prefix().starts_with(DID_PREFIX), - "Method resolver prefix must start with `did:`"); - CCF_ASSERT( - resolver->get_method_prefix().ends_with(':'), - "Method resolver prefix must end with a colon"); - + if (!resolver->get_method_prefix().starts_with(DID_PREFIX)) + { + throw std::invalid_argument( + "Method resolver prefix must start with `did:`"); + } + if (!resolver->get_method_prefix().ends_with(':')) + { + throw std::invalid_argument( + "Method resolver prefix must end with a colon"); + } resolvers.push_back(std::move(resolver)); } }; diff --git a/app/src/http_error.h b/app/src/http_error.h index 6a0a58f2..6a568be0 100644 --- a/app/src/http_error.h +++ b/app/src/http_error.h @@ -10,11 +10,11 @@ namespace scitt struct HTTPError : public std::runtime_error { using Headers = std::unordered_map; - http_status status_code; + ccf::http_status status_code; std::string code; Headers headers; HTTPError( - http_status status_code, + ccf::http_status status_code, std::string code, std::string msg, Headers headers = {}) : diff --git a/app/src/openssl_wrappers.h b/app/src/openssl_wrappers.h deleted file mode 100644 index a05f5b41..00000000 --- a/app/src/openssl_wrappers.h +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once - -#define FMT_HEADER_ONLY -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Note: This file was extended from: -// https://github.com/microsoft/CCF/blob/main/src/crypto/openssl/openssl_wrappers.h - -#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 -# include -#endif - -namespace scitt -{ - namespace OpenSSL - { - /* - * Generic OpenSSL error handling - */ - - /// Returns the error string from an error code - inline std::string error_string(unsigned long ec) - { - // ERR_error_string doesn't really expect the code could actually be zero - // and uses the `static char buf[256]` which is NOT cleaned nor checked - // if it has changed. So we use ERR_error_string_n directly. - if (ec) - { - std::string err(256, '\0'); - ERR_error_string_n(ec, err.data(), err.size()); - // Remove any trailing NULs before returning - err.resize(std::strlen(err.c_str())); - return err; - } - else - { - return "unknown error"; - } - } - - /// Throws if rc is not 1 and has error - inline void CHECK1(int rc) - { - unsigned long ec = ERR_get_error(); - if (rc != 1 && ec != 0) - { - throw std::runtime_error( - fmt::format("OpenSSL error: {}", error_string(ec))); - } - } - - /// Throws if rc is 0 and has error - inline void CHECK0(int rc) - { - unsigned long ec = ERR_get_error(); - if (rc == 0 && ec != 0) - { - throw std::runtime_error( - fmt::format("OpenSSL error: {}", error_string(ec))); - } - } - - /// Throws if ptr is null - inline void CHECKNULL(void* ptr) - { - if (ptr == NULL) - { - throw std::runtime_error("OpenSSL error: missing object"); - } - } - - // Throws if values are not equal - inline void CHECKEQUAL(int expect, int actual) - { - if (expect != actual) - { - unsigned long ec = ERR_get_error(); - throw std::runtime_error( - fmt::format("OpenSSL error: {}", error_string(ec))); - } - } - - // Throws if value is not positive - inline void CHECKPOSITIVE(int val) - { - if (val <= 0) - { - throw std::runtime_error("OpenSSL error: expected positive value"); - } - } - - /* - * Unique pointer wrappers for SSL objects, with SSL' specific constructors - * and destructors. Some objects need special functionality, others are just - * wrappers around the same template interface Unique_SSL_OBJECT. - */ - - /// Generic template interface for different types of objects below - /// If there are no c-tors in the derived class that matches this one, - /// pass `nullptr` to the CTOR/DTOR parameters and make sure to implement - /// and delete the appropriate c-tors in the derived class. - template - class Unique_SSL_OBJECT - { - protected: - /// Pointer owning storage - std::unique_ptr p; - - public: - /// C-tor with new pointer via T's c-tor - Unique_SSL_OBJECT() : p(CTOR(), DTOR) - { - CHECKNULL(p.get()); - } - /// C-tor with pointer created in base class - Unique_SSL_OBJECT(T* ptr, void (*dtor)(T*), bool check_null = true) : - p(ptr, dtor) - { - if (check_null) - { - CHECKNULL(p.get()); - } - } - /// Type cast to underlying pointer - operator T*() - { - return p.get(); - } - /// Type cast to underlying pointer - operator T*() const - { - return p.get(); - } - /// Reset pointer, free old if any - void reset(T* other) - { - p.reset(other); - } - /// Release pointer, so it's freed elsewhere (CAUTION!) - T* release() - { - return p.release(); - } - }; - - struct Unique_BIO : public Unique_SSL_OBJECT - { - Unique_BIO() : - Unique_SSL_OBJECT(BIO_new(BIO_s_mem()), [](auto x) { BIO_free(x); }) - {} - Unique_BIO(const void* buf, int len) : - Unique_SSL_OBJECT( - BIO_new_mem_buf(buf, len), [](auto x) { BIO_free(x); }) - {} - Unique_BIO(std::span d) : - Unique_SSL_OBJECT( - BIO_new_mem_buf(d.data(), d.size()), [](auto x) { BIO_free(x); }) - {} - Unique_BIO(const ccf::crypto::Pem& pem) : - Unique_SSL_OBJECT( - BIO_new_mem_buf(pem.data(), -1), [](auto x) { BIO_free(x); }) - {} - Unique_BIO(SSL_CTX* ctx) : - Unique_SSL_OBJECT( - BIO_new_ssl_connect(ctx), [](auto x) { BIO_free_all(x); }) - {} - }; - - struct Unique_SSL_CTX : public Unique_SSL_OBJECT - { - Unique_SSL_CTX(const SSL_METHOD* m) : - Unique_SSL_OBJECT(SSL_CTX_new(m), SSL_CTX_free) - {} - }; - - struct Unique_SSL : public Unique_SSL_OBJECT - { - Unique_SSL(SSL_CTX* ctx) : Unique_SSL_OBJECT(SSL_new(ctx), SSL_free) {} - }; - - struct Unique_PKEY - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - Unique_PKEY(BIO* mem) : - Unique_SSL_OBJECT( - PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL), EVP_PKEY_free) - {} - -#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 - Unique_PKEY(EVP_PKEY* pkey) : - Unique_SSL_OBJECT(EVP_PKEY_dup(pkey), EVP_PKEY_free) - {} -#endif - }; - - struct Unique_EVP_PKEY_CTX - : public Unique_SSL_OBJECT - { - Unique_EVP_PKEY_CTX(EVP_PKEY* key) : - Unique_SSL_OBJECT(EVP_PKEY_CTX_new(key, NULL), EVP_PKEY_CTX_free) - {} - Unique_EVP_PKEY_CTX() : - Unique_SSL_OBJECT( - EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free) - {} - -#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 - Unique_EVP_PKEY_CTX(const std::string& name) : - Unique_SSL_OBJECT( - EVP_PKEY_CTX_new_from_name(NULL, name.c_str(), NULL), - EVP_PKEY_CTX_free) - {} -#endif - }; - - struct Unique_X509_REQ - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - Unique_X509_REQ(BIO* mem) : - Unique_SSL_OBJECT( - PEM_read_bio_X509_REQ(mem, NULL, NULL, NULL), X509_REQ_free) - {} - }; - - struct Unique_X509_CRL - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - Unique_X509_CRL(BIO* mem) : - Unique_SSL_OBJECT( - PEM_read_bio_X509_CRL(mem, NULL, NULL, NULL), X509_CRL_free) - {} - }; - - struct Unique_X509 : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - // p == nullptr is OK (e.g. wrong format) - Unique_X509(BIO* mem, bool pem, bool check_null = false) : - Unique_SSL_OBJECT( - pem ? PEM_read_bio_X509(mem, NULL, NULL, NULL) : - d2i_X509_bio(mem, NULL), - X509_free, - check_null) - {} - Unique_X509(X509* cert, bool check_null) : - Unique_SSL_OBJECT(cert, X509_free, check_null) - {} - }; - - struct Unique_X509_STORE - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_X509_STORE_CTX : public Unique_SSL_OBJECT< - X509_STORE_CTX, - X509_STORE_CTX_new, - X509_STORE_CTX_free> - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_EVP_CIPHER_CTX : public Unique_SSL_OBJECT< - EVP_CIPHER_CTX, - EVP_CIPHER_CTX_new, - EVP_CIPHER_CTX_free> - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_STACK_OF_X509 - : public Unique_SSL_OBJECT - { - Unique_STACK_OF_X509() : - Unique_SSL_OBJECT( - sk_X509_new_null(), [](auto x) { sk_X509_pop_free(x, X509_free); }) - {} - }; - - struct Unique_STACK_OF_X509_EXTENSIONS - : public Unique_SSL_OBJECT - { - Unique_STACK_OF_X509_EXTENSIONS() : - Unique_SSL_OBJECT(sk_X509_EXTENSION_new_null(), [](auto x) { - sk_X509_EXTENSION_pop_free(x, X509_EXTENSION_free); - }) - {} - Unique_STACK_OF_X509_EXTENSIONS(STACK_OF(X509_EXTENSION) * exts) : - Unique_SSL_OBJECT( - exts, - [](auto x) { sk_X509_EXTENSION_pop_free(x, X509_EXTENSION_free); }, - /*check_null=*/false) - {} - }; - - struct Unique_ECDSA_SIG - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - - Unique_ECDSA_SIG(ECDSA_SIG* sig, bool check_null) : - Unique_SSL_OBJECT(sig, ECDSA_SIG_free, check_null) - {} - }; - - struct Unique_BIGNUM : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - - Unique_BIGNUM(const BIGNUM* n) : Unique_BIGNUM(BN_dup(n), BN_free) {} - }; - - struct Unique_X509_TIME - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - Unique_X509_TIME(const std::string& s) : - Unique_SSL_OBJECT(ASN1_TIME_new(), ASN1_TIME_free, /*check_null=*/false) - { - auto t = ::ds::to_x509_time_string(s); - CHECK1(ASN1_TIME_set_string(*this, t.c_str())); - CHECK1(ASN1_TIME_normalize(*this)); - } - Unique_X509_TIME(ASN1_TIME* t) : - Unique_SSL_OBJECT(t, ASN1_TIME_free, /*check_null=*/false) - {} - Unique_X509_TIME(const std::chrono::system_clock::time_point& t) : - Unique_X509_TIME(::ds::to_x509_time_string(t)) - {} - }; - - struct Unique_BN_CTX - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_EC_GROUP - : public Unique_SSL_OBJECT - { - Unique_EC_GROUP(int nid) : - Unique_SSL_OBJECT( - EC_GROUP_new_by_curve_name(nid), EC_GROUP_free, /*check_null=*/true) - {} - }; - - struct Unique_EC_POINT - : public Unique_SSL_OBJECT - { - Unique_EC_POINT(EC_GROUP* group) : - Unique_SSL_OBJECT( - EC_POINT_new(group), EC_POINT_free, /*check_null=*/true) - {} - Unique_EC_POINT(EC_POINT* point) : - Unique_SSL_OBJECT(point, EC_POINT_free, /*check_null=*/true) - {} - }; - -#if !(defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) - struct Unique_EC_KEY : public Unique_SSL_OBJECT - { - Unique_EC_KEY(int nid) : - Unique_SSL_OBJECT( - EC_KEY_new_by_curve_name(nid), EC_KEY_free, /*check_null=*/true) - {} - Unique_EC_KEY(EC_KEY* key) : - Unique_SSL_OBJECT(key, EC_KEY_free, /*check_null=*/true) - {} - }; - - struct Unique_RSA : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; -#endif - - struct Unique_EVP_ENCODE_CTX : public Unique_SSL_OBJECT< - EVP_ENCODE_CTX, - EVP_ENCODE_CTX_new, - EVP_ENCODE_CTX_free> - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_EVP_MD_CTX - : public Unique_SSL_OBJECT - { - using Unique_SSL_OBJECT::Unique_SSL_OBJECT; - }; - - struct Unique_EVP_PKEY - : public Unique_SSL_OBJECT - { - Unique_EVP_PKEY() = default; - Unique_EVP_PKEY(EVP_PKEY* key) : Unique_SSL_OBJECT(key, EVP_PKEY_free) {} - }; - } -} diff --git a/app/src/operations_endpoints.h b/app/src/operations_endpoints.h index e8cb455b..ff5f84c4 100644 --- a/app/src/operations_endpoints.h +++ b/app/src/operations_endpoints.h @@ -153,9 +153,10 @@ namespace scitt else if (auto it = operations_.find(operation_id.seqno); it != operations_.end()) { - CCF_ASSERT( - operation_id.view == it->second.view, - "Operation ID has inconsistent view"); + if (operation_id.view != it->second.view) + { + throw std::invalid_argument("Operation ID has inconsistent view"); + } return { .operation_id = operation_id, .status = it->second.status, @@ -241,15 +242,17 @@ namespace scitt else if (auto it = operations_.find(operation_id.seqno); it != operations_.end()) { - CCF_ASSERT( - operation_id.view == it->second.view, - "Operation ID has inconsistent view"); + if (operation_id.view != it->second.view) + { + throw std::invalid_argument("Operation ID has inconsistent view"); + } if (it->second.status == OperationStatus::Running) { - CCF_ASSERT_FMT( - it->second.context_digest.has_value(), - "No context digest for operation {}", - tx_str); + if (!it->second.context_digest.has_value()) + { + throw std::invalid_argument( + fmt::format("No context digest for operation {}", tx_str)); + } return it->second.context_digest.value(); } else @@ -289,9 +292,10 @@ namespace scitt } auto it = operations_.find(operation_id.seqno); - CCF_ASSERT( - (it == operations_.end()) || (operation_id.view == it->second.view), - "Operation ID has inconsistent view"); + if (!(it == operations_.end()) || (operation_id.view == it->second.view)) + { + throw std::invalid_argument("Operation ID has inconsistent view"); + } auto current_status = it != operations_.end() ? std::optional(it->second.status) : @@ -401,7 +405,10 @@ namespace scitt operation_id.to_str()); } } - CCF_ASSERT(valid, "Invalid operation transition"); + if (!valid) + { + throw std::logic_error("Invalid operation transition"); + } return valid; } diff --git a/app/src/public_key.h b/app/src/public_key.h index 0d9c71d5..e9a3c5f8 100644 --- a/app/src/public_key.h +++ b/app/src/public_key.h @@ -3,8 +3,7 @@ #pragma once -#include "openssl_wrappers.h" - +#include #include #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 @@ -21,7 +20,8 @@ namespace scitt PublicKey() = default; PublicKey( - const OpenSSL::Unique_X509& cert, std::optional cose_alg) : + const ccf::crypto::OpenSSL::Unique_X509& cert, + std::optional cose_alg) : key(X509_get_pubkey(cert)), cose_alg(cose_alg) {} @@ -40,9 +40,9 @@ namespace scitt OSSL_PKEY_PARAM_RSA_E, e_raw.data(), e_raw.size()); params[2] = OSSL_PARAM_construct_end(); - OpenSSL::Unique_EVP_PKEY_CTX pctx("RSA"); - OpenSSL::CHECK1(EVP_PKEY_fromdata_init(pctx)); - OpenSSL::CHECK1( + ccf::crypto::OpenSSL::Unique_EVP_PKEY_CTX pctx("RSA"); + ccf::crypto::OpenSSL::CHECK1(EVP_PKEY_fromdata_init(pctx)); + ccf::crypto::OpenSSL::CHECK1( EVP_PKEY_fromdata(pctx, (EVP_PKEY**)&key, EVP_PKEY_PUBLIC_KEY, params)); } @@ -57,14 +57,15 @@ namespace scitt OSSL_PKEY_PARAM_PUB_KEY, buf.data(), buf.size()); params[2] = OSSL_PARAM_construct_end(); - OpenSSL::Unique_EVP_PKEY_CTX pctx("EC"); - OpenSSL::CHECK1(EVP_PKEY_fromdata_init(pctx)); - OpenSSL::CHECK1( + ccf::crypto::OpenSSL::Unique_EVP_PKEY_CTX pctx("EC"); + ccf::crypto::OpenSSL::CHECK1(EVP_PKEY_fromdata_init(pctx)); + ccf::crypto::OpenSSL::CHECK1( EVP_PKEY_fromdata(pctx, (EVP_PKEY**)&key, EVP_PKEY_PUBLIC_KEY, params)); } #else PublicKey( - const OpenSSL::Unique_RSA& rsa_key, std::optional cose_alg) : + const ccf::crypto::OpenSSL::Unique_RSA& rsa_key, + std::optional cose_alg) : cose_alg(cose_alg) { if (!EVP_PKEY_set1_RSA(key, rsa_key)) @@ -74,7 +75,8 @@ namespace scitt } PublicKey( - const OpenSSL::Unique_EC_KEY& ec_key, std::optional cose_alg) : + const ccf::crypto::OpenSSL::Unique_EC_KEY& ec_key, + std::optional cose_alg) : cose_alg(cose_alg) { if (!EVP_PKEY_set1_EC_KEY(key, ec_key)) @@ -104,7 +106,7 @@ namespace scitt } private: - OpenSSL::Unique_EVP_PKEY key; + ccf::crypto::OpenSSL::Unique_EVP_PKEY key; std::optional cose_alg; }; } diff --git a/app/src/receipt.h b/app/src/receipt.h index 91e0427c..45e5258b 100644 --- a/app/src/receipt.h +++ b/app/src/receipt.h @@ -89,8 +89,9 @@ namespace scitt */ static size_t get_certificate_ecdsa_curve_size(std::span der) { - OpenSSL::Unique_X509 cert(OpenSSL::Unique_BIO(der), false, true); - OpenSSL::Unique_PKEY pk(X509_get_pubkey(cert), EVP_PKEY_free); + ccf::crypto::OpenSSL::Unique_X509 cert( + ccf::crypto::OpenSSL::Unique_BIO(der.data(), der.size()), false, true); + ccf::crypto::OpenSSL::Unique_PKEY pk(X509_get_pubkey(cert), EVP_PKEY_free); size_t bits = EVP_PKEY_bits(pk); return (bits + 7) / 8; @@ -116,8 +117,8 @@ namespace scitt } const uint8_t* p = signature.data(); - OpenSSL::Unique_ECDSA_SIG sig( - d2i_ECDSA_SIG(NULL, &p, signature.size()), true); + ccf::crypto::OpenSSL::Unique_ECDSA_SIG sig( + d2i_ECDSA_SIG(NULL, &p, signature.size())); const BIGNUM* r = ECDSA_SIG_get0_r(sig); const BIGNUM* s = ECDSA_SIG_get0_s(sig); diff --git a/app/src/tracing.h b/app/src/tracing.h index 813f1ee0..e5eba4ae 100644 --- a/app/src/tracing.h +++ b/app/src/tracing.h @@ -8,6 +8,7 @@ #include "util.h" #include +#include #include #include #include diff --git a/app/src/util.h b/app/src/util.h index 8afca462..dbc7d30f 100644 --- a/app/src/util.h +++ b/app/src/util.h @@ -14,23 +14,6 @@ namespace scitt { const static ccf::crypto::EntropyPtr ENTROPY = ccf::crypto::get_entropy(); - static std::vector split_x509_cert_bundle( - const std::string_view& pem) - { - std::string separator("-----END CERTIFICATE-----"); - std::vector 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; - } - template bool contains(const std::vector& v, const U& e) { diff --git a/app/src/verifier.h b/app/src/verifier.h index a77d15fe..6e78814b 100644 --- a/app/src/verifier.h +++ b/app/src/verifier.h @@ -6,14 +6,15 @@ #include "cose.h" #include "did/resolver.h" #include "didx509cpp/didx509cpp.h" -#include "openssl_wrappers.h" #include "profiles.h" #include "public_key.h" #include "signature_algorithms.h" #include "tracing.h" +#include #include #include +#include #include #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 @@ -108,7 +109,8 @@ namespace scitt::verifier // only x5t is. This logic will need to authenticate x5chain[0] // against x5t before it can proceed to verify the signature. // Verify the signature as early as possible - OpenSSL::Unique_X509 leaf = parse_certificate(phdr.x5chain.value()[0]); + ccf::crypto::OpenSSL::Unique_X509 leaf = + parse_certificate(phdr.x5chain.value()[0]); PublicKey key(leaf, std::nullopt); try { @@ -458,7 +460,7 @@ namespace scitt::verifier * If successful, returns the leaf certificate. Otherwise throws a * VerificationError. */ - static OpenSSL::Unique_X509 verify_chain( + static ccf::crypto::OpenSSL::Unique_X509 verify_chain( std::span trusted, std::span> chain) { @@ -468,24 +470,26 @@ namespace scitt::verifier "Certificate chain must contain at least one certificate"); } - OpenSSL::Unique_X509 leaf = parse_certificate(chain[0]); + ccf::crypto::OpenSSL::Unique_X509 leaf = parse_certificate(chain[0]); - OpenSSL::Unique_X509_STORE store; + ccf::crypto::OpenSSL::Unique_X509_STORE store; for (const auto& pem : trusted) { - OpenSSL::CHECK1(X509_STORE_add_cert(store, parse_certificate(pem))); + ccf::crypto::OpenSSL::CHECK1( + X509_STORE_add_cert(store, parse_certificate(pem))); } - OpenSSL::Unique_STACK_OF_X509 chain_stack; + ccf::crypto::OpenSSL::Unique_STACK_OF_X509 chain_stack; for (const auto& der : chain.subspan(1)) { - OpenSSL::Unique_X509 cert = parse_certificate(der); - OpenSSL::CHECK1(sk_X509_push(chain_stack, cert)); - OpenSSL::CHECK1(X509_up_ref(cert)); + ccf::crypto::OpenSSL::Unique_X509 cert = parse_certificate(der); + ccf::crypto::OpenSSL::CHECK1(sk_X509_push(chain_stack, cert)); + ccf::crypto::OpenSSL::CHECK1(X509_up_ref(cert)); } - OpenSSL::Unique_X509_STORE_CTX store_ctx; - OpenSSL::CHECK1(X509_STORE_CTX_init(store_ctx, store, leaf, chain_stack)); + ccf::crypto::OpenSSL::Unique_X509_STORE_CTX store_ctx; + ccf::crypto::OpenSSL::CHECK1( + X509_STORE_CTX_init(store_ctx, store, leaf, chain_stack)); if (X509_verify_cert(store_ctx) != 1) { @@ -503,30 +507,34 @@ namespace scitt::verifier private: /** Parse a PEM certificate */ - static OpenSSL::Unique_X509 parse_certificate(const ccf::crypto::Pem& pem) + static ccf::crypto::OpenSSL::Unique_X509 parse_certificate( + const ccf::crypto::Pem& pem) { - OpenSSL::Unique_BIO bio(pem); - OpenSSL::Unique_X509 cert(bio, true); + ccf::crypto::OpenSSL::Unique_BIO bio(pem); + ccf::crypto::OpenSSL::Unique_X509 cert(bio, true); if (!cert) { unsigned long ec = ERR_get_error(); SCITT_INFO( - "Could not parse PEM certificate: {}", OpenSSL::error_string(ec)); + "Could not parse PEM certificate: {}", + ccf::crypto::OpenSSL::error_string(ec)); throw VerificationError("Could not parse certificate"); } return cert; } /** Parse a DER certificate */ - static OpenSSL::Unique_X509 parse_certificate(std::span der) + static ccf::crypto::OpenSSL::Unique_X509 parse_certificate( + std::span der) { - OpenSSL::Unique_BIO bio(der); - OpenSSL::Unique_X509 cert(bio, false); + ccf::crypto::OpenSSL::Unique_BIO bio(der.data(), der.size()); + ccf::crypto::OpenSSL::Unique_X509 cert(bio, false); if (!cert) { unsigned long ec = ERR_get_error(); SCITT_INFO( - "Could not parse DER certificate: {}", OpenSSL::error_string(ec)); + "Could not parse DER certificate: {}", + ccf::crypto::OpenSSL::error_string(ec)); throw VerificationError("Could not parse certificate"); } return cert; @@ -548,7 +556,7 @@ namespace scitt::verifier throw std::runtime_error( "Failed to load x509 Root CA certificates from KV"); } - return split_x509_cert_bundle(*ca_certs); + return ccf::crypto::split_x509_cert_bundle(*ca_certs); } /** @@ -580,8 +588,8 @@ namespace scitt::verifier { auto n = ccf::crypto::raw_from_b64url(jwk.n.value()); auto e = ccf::crypto::raw_from_b64url(jwk.e.value()); - OpenSSL::Unique_BIGNUM n_bn; - OpenSSL::Unique_BIGNUM e_bn; + ccf::crypto::OpenSSL::Unique_BIGNUM n_bn; + ccf::crypto::OpenSSL::Unique_BIGNUM e_bn; if (BN_bin2bn(n.data(), n.size(), n_bn) == nullptr) { throw VerificationError("JWK n could not be parsed"); @@ -595,14 +603,14 @@ namespace scitt::verifier std::pair, std::vector> r( BN_num_bytes(n_bn), BN_num_bytes(e_bn)); - OpenSSL::CHECKPOSITIVE( + ccf::crypto::OpenSSL::CHECKPOSITIVE( BN_bn2nativepad(n_bn, r.first.data(), r.first.size())); - OpenSSL::CHECKPOSITIVE( + ccf::crypto::OpenSSL::CHECKPOSITIVE( BN_bn2nativepad(e_bn, r.second.data(), r.second.size())); return PublicKey(r.first, r.second, cose_alg); #else - OpenSSL::Unique_RSA rsa; + ccf::crypto::OpenSSL::Unique_RSA rsa; if (!RSA_set0_key(rsa, n_bn, e_bn, nullptr)) { throw std::runtime_error("RSA key could not be set"); @@ -628,8 +636,8 @@ namespace scitt::verifier auto crv = jwk.crv.value(); auto x = ccf::crypto::raw_from_b64url(jwk.x.value()); auto y = ccf::crypto::raw_from_b64url(jwk.y.value()); - OpenSSL::Unique_BIGNUM x_bn; - OpenSSL::Unique_BIGNUM y_bn; + ccf::crypto::OpenSSL::Unique_BIGNUM x_bn; + ccf::crypto::OpenSSL::Unique_BIGNUM y_bn; if (BN_bin2bn(x.data(), x.size(), x_bn) == nullptr) { throw VerificationError("JWK x could not be parsed"); @@ -657,15 +665,15 @@ namespace scitt::verifier } #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 - OpenSSL::Unique_BN_CTX bn_ctx; - OpenSSL::Unique_EC_GROUP group(nid); - OpenSSL::Unique_EC_POINT p(group); - OpenSSL::CHECK1( + ccf::crypto::OpenSSL::Unique_BN_CTX bn_ctx; + ccf::crypto::OpenSSL::Unique_EC_GROUP group(nid); + ccf::crypto::OpenSSL::Unique_EC_POINT p(group); + ccf::crypto::OpenSSL::CHECK1( EC_POINT_set_affine_coordinates(group, p, x_bn, y_bn, bn_ctx)); size_t buf_size = EC_POINT_point2oct( group, p, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, bn_ctx); std::vector buf(buf_size); - OpenSSL::CHECKPOSITIVE(EC_POINT_point2oct( + ccf::crypto::OpenSSL::CHECKPOSITIVE(EC_POINT_point2oct( group, p, POINT_CONVERSION_UNCOMPRESSED, @@ -675,7 +683,7 @@ namespace scitt::verifier return PublicKey(buf, nid, cose_alg); #else - auto ec_key = OpenSSL::Unique_EC_KEY(nid); + auto ec_key = ccf::crypto::OpenSSL::Unique_EC_KEY(nid); if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x_bn, y_bn)) { throw std::runtime_error("EC key could not be set"); diff --git a/app/unit-tests/verifier_test.cpp b/app/unit-tests/verifier_test.cpp index 9d82f06a..fa6f2115 100644 --- a/app/unit-tests/verifier_test.cpp +++ b/app/unit-tests/verifier_test.cpp @@ -64,7 +64,7 @@ namespace { chain_certs.push_back(ccf::crypto::cert_pem_to_der(c.get().first)); } - Verifier::verify_chain(store_certs, chain_certs); + scitt::verifier::Verifier::verify_chain(store_certs, chain_certs); } } @@ -167,7 +167,7 @@ TEST(Verifier, GarbageCert) const std::vector garbage = {0xde, 0xad, 0xbe, 0xef}; EXPECT_THROW( - Verifier::verify_chain( + scitt::verifier::Verifier::verify_chain( {{root.first}}, {{ garbage, @@ -176,7 +176,7 @@ TEST(Verifier, GarbageCert) VerificationError); EXPECT_THROW( - Verifier::verify_chain( + scitt::verifier::Verifier::verify_chain( {{root.first}}, {{ ccf::crypto::cert_pem_to_der(leaf.first), diff --git a/build.sh b/build.sh index b84db4ce..2d9ec8e8 100755 --- a/build.sh +++ b/build.sh @@ -19,7 +19,7 @@ if [ "$PLATFORM" != "virtual" ] && [ "$PLATFORM" != "snp" ]; then fi if [ "$BUILD_CCF_FROM_SOURCE" = "ON" ]; then - CCF_SOURCE_VERSION="6.0.0-dev7" + CCF_SOURCE_VERSION="6.0.0-dev8" echo "Cloning CCF sources" rm -rf ccf-source git clone --single-branch -b "ccf-${CCF_SOURCE_VERSION}" https://github.com/microsoft/CCF ccf-source diff --git a/docker/snp.Dockerfile b/docker/snp.Dockerfile index eb5a80de..adf9b5a1 100644 --- a/docker/snp.Dockerfile +++ b/docker/snp.Dockerfile @@ -1,4 +1,4 @@ -ARG CCF_VERSION=6.0.0-dev7 +ARG CCF_VERSION=6.0.0-dev8 FROM ghcr.io/microsoft/ccf/app/dev/snp:ccf-${CCF_VERSION} as builder ARG CCF_VERSION ARG SCITT_VERSION_OVERRIDE diff --git a/docker/virtual.Dockerfile b/docker/virtual.Dockerfile index 49b0e2fb..a7771ab8 100644 --- a/docker/virtual.Dockerfile +++ b/docker/virtual.Dockerfile @@ -1,4 +1,4 @@ -ARG CCF_VERSION=6.0.0-dev7 +ARG CCF_VERSION=6.0.0-dev8 FROM ghcr.io/microsoft/ccf/app/dev/virtual:ccf-${CCF_VERSION} as builder ARG CCF_VERSION ARG SCITT_VERSION_OVERRIDE diff --git a/pyscitt/setup.py b/pyscitt/setup.py index 23828b41..f2b7a373 100644 --- a/pyscitt/setup.py +++ b/pyscitt/setup.py @@ -25,7 +25,7 @@ }, python_requires=">=3.8", install_requires=[ - "ccf==6.0.0-dev7", + "ccf==6.0.0-dev8", "cryptography==43.*", # needs to match ccf "httpx", "cbor2==5.4.*", diff --git a/test/requirements.txt b/test/requirements.txt index 7725c1d7..8e9abd10 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -3,5 +3,5 @@ httpx pytest loguru aiotools -ccf==6.0.0-dev7 +ccf==6.0.0-dev8 cryptography==43.*