diff --git a/CMakeLists.txt b/CMakeLists.txt index 99c48245..2dc829d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ option(PIPY_LTO "enable LTO" OFF) option(PIPY_USE_NTLS, "Use externally compiled TongSuo Crypto library instead of OpenSSL. Used with PIPY_OPENSSL" OFF) option(PIPY_USE_SYSTEM_ZLIB "Use system installed zlib" OFF) option(PIPY_USE_SYSTEM_OPENSSL "Use system installed OpenSSL" OFF) +option(PIPY_USE_OPENSSL1, "Use openssl v1 when compiling pipy" OFF) set(BUILD_SHARED_LIBS OFF) set(BUILD_TESTING OFF) @@ -131,6 +132,10 @@ else() endif(PIPY_USE_SYSTEM_ZLIB) endif() +if(PIPY_USE_OPENSSL1) + add_definitions(-DPIPY_USE_OPENSSL1) +endif() + if(PIPY_USE_SYSTEM_OPENSSL) find_package(OpenSSL REQUIRED) if(OPENSSL_FOUND) @@ -148,6 +153,16 @@ elseif(PIPY_OPENSSL) set(OPENSSL_LIB_DIR ${PIPY_OPENSSL}/lib) else() + if (DEFINED PIPY_USE_OPENSSL1) + message(FATAL_ERROR + "Error: OpenSSL v1 detected (PIPY_USE_OPENSSL1 is set).\n" + "To compile with OpenSSL v1, you must set one of the following options:\n" + " - PIPY_OPENSSL: Provide a custom OpenSSL installation path.\n" + " - PIPY_USE_SYSTEM_OPENSSL: Use the system-installed OpenSSL library.\n" + "Please configure CMake with the correct option and try again." + ) + endif() + set(OPENSSL_SRC_DIR ${CMAKE_SOURCE_DIR}/deps/openssl-3.2.0) set(OPENSSL_LIB_DIR ${OPENSSL_SRC_DIR}/build) set(OPENSSL_INC_DIR ${OPENSSL_SRC_DIR}/include ${OPENSSL_LIB_DIR}/include) diff --git a/src/api/crypto.cpp b/src/api/crypto.cpp index ac1830e0..fc7c3a24 100644 --- a/src/api/crypto.cpp +++ b/src/api/crypto.cpp @@ -168,8 +168,16 @@ PublicKey::PublicKey(pjs::Str *data) { } PublicKey::PublicKey(PrivateKey *pkey) { +#ifdef PIPY_USE_OPENSSL1 + m_pkey = pkey->pkey(); + if (!m_pkey) + throw_error(); + EVP_PKEY_up_ref(m_pkey); +#else m_pkey = EVP_PKEY_dup(pkey->pkey()); - if (!m_pkey) throw_error(); + if (!m_pkey) + throw_error(); +#endif } PublicKey::~PublicKey() { @@ -423,7 +431,15 @@ Certificate::Certificate(const Options &options) { throw std::runtime_error("missing public key"); } - // Digest algorithm + // Digest algorithm +#ifdef PIPY_USE_OPENSSL1 + const EVP_MD *md = nullptr; + if (EVP_PKEY_type(EVP_PKEY_id(options.private_key->pkey())) == EVP_PKEY_RSA || + EVP_PKEY_type(EVP_PKEY_id(options.private_key->pkey())) == EVP_PKEY_EC) { + // Default to SHA256 for RSA and EC keys + md = EVP_sha256(); + } +#else char digest_name[80]; if (EVP_PKEY_get_default_digest_name(options.private_key->pkey(), digest_name, sizeof(digest_name)) == 2) { if (!std::strcmp(digest_name, "UNDEF")) { @@ -431,6 +447,7 @@ Certificate::Certificate(const Options &options) { } } auto md = digest_name[0] ? Hash::algorithm(digest_name) : nullptr; +#endif // Sign if (!X509_sign(x509, options.private_key->pkey(), md)) throw_error(); diff --git a/src/filters/tls.cpp b/src/filters/tls.cpp index d3823bf9..7e2ee112 100644 --- a/src/filters/tls.cpp +++ b/src/filters/tls.cpp @@ -353,9 +353,16 @@ auto TLSSession::hostname() -> pjs::Str* { auto TLSSession::peer() -> crypto::Certificate* { if (!m_peer) { +#ifndef PIPY_USE_OPENSSL1 if (auto x = SSL_get0_peer_certificate(m_ssl)) { m_peer = crypto::Certificate::make(x); } +#else + if (auto x = SSL_get_peer_certificate(m_ssl)) { + m_peer = crypto::Certificate::make(x); + X509_free(x); + } +#endif } return m_peer; }