Skip to content

Commit

Permalink
OpenSSL3: remove use of deprecated functions (#5481)
Browse files Browse the repository at this point in the history
  • Loading branch information
jumaffre authored Aug 22, 2023
1 parent 054356b commit 8aa778c
Show file tree
Hide file tree
Showing 20 changed files with 451 additions and 111 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Updated Open Enclave to [0.19.2](https://github.com/openenclave/openenclave/releases/tag/v0.19.2).
- Updated Open Enclave to [0.19.3](https://github.com/openenclave/openenclave/releases/tag/v0.19.3).
- Expose COSESign1 `content` for `user_cose_sign1` authenticated endpoints in JavaScript/TypeScript apps (#5465).
- SGX builds now use OpenSSL 3.1.1 by default (#5481).
- Add HMAC support to JS API. Call with `ccf.crypto.sign({"name": "HMAC", "hash": "SHA-256"}, key, data)`.

## [4.0.5]
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
11 changes: 8 additions & 3 deletions cmake/open_enclave.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ if(REQUIRE_OPENENCLAVE)
# Find OpenEnclave package
find_package(OpenEnclave 0.19.3 CONFIG REQUIRED)

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()
# As well as pulling in openenclave:: targets, this sets variables which can
# be used for our edge cases (eg - for virtual libraries). These do not follow
# the standard naming patterns, for example use OE_INCLUDEDIR rather than
# OpenEnclave_INCLUDE_DIRS
if(COMPILE_TARGET STREQUAL "sgx")
set(OE_TARGET_LIBC openenclave::oelibc)
set(OE_TARGET_ENCLAVE_AND_STD
openenclave::oeenclave openenclave::oelibcxx openenclave::oelibc
openenclave::oecryptoopenssl
set(OE_TARGET_ENCLAVE_AND_STD openenclave::oeenclave openenclave::oelibcxx
openenclave::oelibc ${OE_OPENSSL_LIBRARY}
)

# These oe libraries must be linked in specific order
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

0 comments on commit 8aa778c

Please sign in to comment.