Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/4.x] Cherry pick: OpenSSL3: remove use of deprecated functions (#5481) #5637

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

[4.0.8]: https://github.com/microsoft/CCF/releases/tag/ccf-4.0.8

- SGX builds now use OpenSSL 3.1.1 by default (#5481).
- Converted SNP attestation UVM endorsements from integer to arbitrary string.

- Add `/node/ready/app` and `/node/ready/gov` endpoints for the use of load balancers wanting to check if a node is ready to accept application or governance transactions. See [Operator RPC API](https://microsoft.github.io/CCF/main/operations/operator_rpc_api.html) for details.
- Updated `llhttp` from `6.0.9` to `9.0.1`.
- Updated `fmt` library from `9.1.0` to `10.1.1`.
Expand Down
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,6 @@ set(CCF_ENDPOINTS_SOURCES
${CCF_DIR}/src/node/receipt.cpp
)

find_library(CRYPTO_LIBRARY crypto)
find_library(TLS_LIBRARY ssl)

include(${CCF_DIR}/cmake/crypto.cmake)
include(${CCF_DIR}/cmake/quickjs.cmake)
include(${CCF_DIR}/cmake/sss.cmake)
Expand Down
4 changes: 4 additions & 0 deletions cmake/crypto.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ elseif(COMPILE_TARGET STREQUAL "snp")
)
endif()

find_library(CRYPTO_LIBRARY crypto)
find_library(TLS_LIBRARY ssl)

add_library(ccfcrypto.host STATIC ${CCFCRYPTO_SRC})
add_san(ccfcrypto.host)
target_compile_options(ccfcrypto.host PUBLIC ${COMPILE_LIBCXX})
target_link_options(ccfcrypto.host PUBLIC ${LINK_LIBCXX})

target_link_libraries(ccfcrypto.host PUBLIC qcbor.host)
target_link_libraries(ccfcrypto.host PUBLIC t_cose.host)
target_link_libraries(ccfcrypto.host PUBLIC crypto)
Expand Down
7 changes: 7 additions & 0 deletions cmake/open_enclave.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ find_package(OpenEnclave 0.19.3 CONFIG REQUIRED)
# standard naming patterns, for example use OE_INCLUDEDIR rather than
# OpenEnclave_INCLUDE_DIRS

option(USE_OPENSSL_3 "Use OpenSSL 3.x for Open Enclave builds" ON)
if(USE_OPENSSL_3)
set(OE_OPENSSL_LIBRARY openenclave::oecryptoopenssl_3)
else()
set(OE_OPENSSL_LIBRARY openenclave::oecryptoopenssl)
endif()

if(COMPILE_TARGET STREQUAL "sgx")
set(OE_TARGET_LIBC openenclave::oelibc)
set(OE_TARGET_ENCLAVE_AND_STD
Expand Down
2 changes: 1 addition & 1 deletion cmake/t_cose.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if(COMPILE_TARGET STREQUAL "sgx")

target_link_libraries(t_cose.enclave PUBLIC qcbor.enclave)
# This is needed to get the OpenSSL includes from Open Enclave
target_link_libraries(t_cose.enclave PRIVATE openenclave::oecryptoopenssl)
target_link_libraries(t_cose.enclave PRIVATE ${OE_OPENSSL_LIBRARY})

install(
TARGETS t_cose.enclave
Expand Down
30 changes: 7 additions & 23 deletions src/clients/tls_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,12 @@ namespace client
init();
}

virtual ~TlsClient() {}
virtual ~TlsClient()
{
SSL* ssl;
BIO_get_ssl(bio, &ssl);
SSL_shutdown(ssl);
}

auto get_ciphersuite_name()
{
Expand Down Expand Up @@ -207,28 +212,7 @@ namespace client
std::vector<uint8_t> read_all()
{
constexpr auto read_size = 4096;
std::vector<uint8_t> buf(read_size);
auto ret = 0;
do
{
ret = BIO_read(bio, buf.data(), buf.size());
} while (ret < 0 && BIO_should_retry(bio));

if (ret > 0)
{
buf.resize(ret);
}
else if (ret == 0)
{
connected = false;
throw std::logic_error("Underlying transport closed");
}
else
{
throw std::logic_error(error_string(ERR_get_error()));
}

return buf;
return read(read_size);
}

void set_tcp_nodelay(bool on)
Expand Down
1 change: 1 addition & 0 deletions src/crypto/key_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "openssl/symmetric_key.h"

#include <cstdint>
#include <openssl/rand.h>
#include <stdexcept>
#include <vector>

Expand Down
4 changes: 4 additions & 0 deletions src/crypto/openssl/cose_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ namespace crypto

EVP_PKEY* pk = X509_get_pubkey(cert);

#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
if (EVP_PKEY_get_base_id(pk) == EVP_PKEY_EC)
#else
if (EVP_PKEY_get0_EC_KEY(pk))
#endif
{
public_key = std::make_shared<PublicKey_OpenSSL>(pk);
}
Expand Down
47 changes: 39 additions & 8 deletions src/crypto/openssl/key_pair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>
#include <stdexcept>
#include <string>

#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
# include <openssl/core_names.h>
#endif

namespace crypto
{
using namespace OpenSSL;
Expand Down Expand Up @@ -67,16 +72,36 @@ namespace crypto

KeyPair_OpenSSL::KeyPair_OpenSSL(const JsonWebKeyECPrivate& jwk)
{
auto ec_key = PublicKey_OpenSSL::ec_key_public_from_jwk(jwk);

key = EVP_PKEY_new();
Unique_BIGNUM d;
auto d_raw = raw_from_b64url(jwk.d);
OpenSSL::CHECKNULL(BN_bin2bn(d_raw.data(), d_raw.size(), d));

#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
auto nid = get_openssl_group_id(jwk_curve_to_curve_id(jwk.crv));
// Note: d_raw is big endian while OSSL_PARAM_construct_BN expects native
// endianness
std::vector<uint8_t> d_raw_native(d_raw.size());
CHECKPOSITIVE(BN_bn2nativepad(d, d_raw_native.data(), d_raw_native.size()));

auto pub_buf = PublicKey_OpenSSL::ec_point_public_from_jwk(jwk);

OSSL_PARAM params[4];
params[0] = OSSL_PARAM_construct_utf8_string(
OSSL_PKEY_PARAM_GROUP_NAME, (char*)OSSL_EC_curve_nid2name(nid), 0);
params[1] = OSSL_PARAM_construct_octet_string(
OSSL_PKEY_PARAM_PUB_KEY, pub_buf.data(), pub_buf.size());
params[2] = OSSL_PARAM_construct_BN(
OSSL_PKEY_PARAM_PRIV_KEY, d_raw_native.data(), d_raw_native.size());
params[3] = OSSL_PARAM_construct_end();

Unique_EVP_PKEY_CTX pctx("EC");
CHECK1(EVP_PKEY_fromdata_init(pctx));
CHECK1(EVP_PKEY_fromdata(pctx, &key, EVP_PKEY_KEYPAIR, params));
#else
auto ec_key = PublicKey_OpenSSL::ec_key_public_from_jwk(jwk);
CHECK1(EC_KEY_set_private_key(ec_key, d));

key = EVP_PKEY_new();
CHECK1(EVP_PKEY_set1_EC_KEY(key, ec_key));
#endif
}

Pem KeyPair_OpenSSL::private_key_pem() const
Expand Down Expand Up @@ -458,10 +483,16 @@ namespace crypto
// As per https://www.openssl.org/docs/man1.0.2/man3/BN_num_bytes.html, size
// should not be calculated with BN_num_bytes(d)!
size_t size = EVP_PKEY_bits(key) / 8;
Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(key));
const BIGNUM* d = EC_KEY_get0_private_key(eckey);

std::vector<uint8_t> bytes(size);
Unique_BIGNUM d;
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
BIGNUM* bn_d = NULL;
CHECK1(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_PRIV_KEY, &bn_d));
d.reset(bn_d);
#else
Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(key));
d = EC_KEY_get0_private_key(eckey);
#endif
auto rc = BN_bn2binpad(d, bytes.data(), size);
if (rc != size)
{
Expand Down
25 changes: 25 additions & 0 deletions src/crypto/openssl/openssl_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@
#include "ccf/crypto/pem.h"

#define FMT_HEADER_ONLY

#include <chrono>
#include <ds/x509_time_fmt.h>
#include <fmt/format.h>
#include <memory>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
# include <openssl/evp.h>
#endif

namespace crypto
{
namespace OpenSSL
Expand Down Expand Up @@ -193,6 +200,12 @@ namespace crypto
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
Expand All @@ -205,6 +218,14 @@ namespace crypto
Unique_SSL_OBJECT(
EVP_PKEY_CTX_new_id(key_type, 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_EVP_MD_CTX
Expand Down Expand Up @@ -309,6 +330,8 @@ namespace crypto
struct Unique_BIGNUM : public Unique_SSL_OBJECT<BIGNUM, BN_new, BN_free>
{
using Unique_SSL_OBJECT::Unique_SSL_OBJECT;

Unique_BIGNUM(const BIGNUM* n) : Unique_BIGNUM(BN_dup(n), BN_free) {}
};

struct Unique_X509_TIME
Expand Down Expand Up @@ -357,6 +380,7 @@ namespace crypto
{}
};

#if !(defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3)
struct Unique_EC_KEY : public Unique_SSL_OBJECT<EC_KEY, nullptr, nullptr>
{
Unique_EC_KEY(int nid) :
Expand All @@ -372,6 +396,7 @@ namespace crypto
{
using Unique_SSL_OBJECT::Unique_SSL_OBJECT;
};
#endif

struct Unique_EVP_ENCODE_CTX : public Unique_SSL_OBJECT<
EVP_ENCODE_CTX,
Expand Down
Loading
Loading