Index: lang/dotnet/Makefile =================================================================== --- lang/dotnet/Makefile +++ lang/dotnet/Makefile @@ -60,10 +60,16 @@ SDKVERSION=${SDKVERSION} SDKVERSIONSUFFIX=${SDKVERSIONSUFFIX} \ DOTNET_NETVERSION=net${DOTNETVERSION} -OPTIONS_DEFINE= NUPKG +OPTIONS_DEFINE= LIBRESSL NUPKG OPTIONS_DEFAULT= NUPKG OPTIONS_SUB= yes +LIBRESSL_DESC= Add experimental LibreSSL support (see pkg-descr) NUPKG_DESC= Install FreeBSD runtime NuGet packages + +LIBRESSL_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-libressl +LIBRESSL_VARS_OFF= BROKEN_SSL=libressl \ + BROKEN_SSL_REASON="Not supported upstream" + NUPKG_SUB_FILES= post-install-register-nuget NUPKG_VARS= PKGPOSTINSTALL+=${WRKDIR}/post-install-register-nuget Index: lang/dotnet/files/extra-patch-libressl =================================================================== --- /dev/null +++ lang/dotnet/files/extra-patch-libressl @@ -0,0 +1,167 @@ +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/openssl.c.orig 2024-03-27 20:02:53 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/openssl.c +@@ -21,7 +21,11 @@ + #include + + #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM ++# ifdef LIBRESSL_VERSION_NUMBER ++c_static_assert(CRYPTO_EX_INDEX_X509 == 12); ++# else + c_static_assert(CRYPTO_EX_INDEX_X509 == 3); ++# endif + #else + c_static_assert(CRYPTO_EX_INDEX_X509 == 10); + #endif +@@ -1206,7 +1210,7 @@ static void ExDataFree( + // In the OpenSSL 3 headers, `from_d` changed from (void*) to (void**). + static int ExDataDup( + CRYPTO_EX_DATA* to, +-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM ++#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM && !defined LIBRESSL_VERSION_NUMBER + const CRYPTO_EX_DATA* from, + #else + CRYPTO_EX_DATA* from, +@@ -1444,7 +1448,11 @@ static int32_t EnsureOpenSsl11Initialized(void) + atexit(HandleShutdown); + + // In OpenSSL 1.1.0+, CRYPTO_EX_INDEX_X509 is 3. ++#ifdef LIBRESSL_VERSION_NUMBER ++ g_x509_ocsp_index = CRYPTO_get_ex_new_index(12, 0, NULL, NULL, ExDataDup, ExDataFree); ++#else + g_x509_ocsp_index = CRYPTO_get_ex_new_index(3, 0, NULL, NULL, ExDataDup, ExDataFree); ++#endif + return 0; + } + +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_dsa.c.orig 2024-03-28 09:01:52 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_dsa.c +@@ -100,6 +100,7 @@ int32_t CryptoNative_DsaSign( + + ERR_clear_error(); + ++#ifndef LIBRESSL_VERSION_NUMBER + // DSA_OpenSSL() returns a shared pointer, no need to free/cache. + if (DSA_get_method(dsa) == DSA_OpenSSL()) + { +@@ -114,6 +115,7 @@ int32_t CryptoNative_DsaSign( + return 0; + } + } ++#endif + + unsigned int unsignedSigLen = 0; + int32_t success = DSA_sign(0, hash, hashLength, refsignature, &unsignedSigLen, dsa); +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_evp.c.orig 2024-03-27 20:33:36 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +@@ -69,7 +69,7 @@ int32_t CryptoNative_EvpDigestFinalEx(EVP_MD_CTX* ctx, + + int32_t CryptoNative_EvpDigestFinalXOF(EVP_MD_CTX* ctx, uint8_t* md, uint32_t len) + { +- #if HAVE_OPENSSL_SHA3 ++ #if HAVE_OPENSSL_SHA3 && !defined(LIBRESSL_VERSION_NUMBER) + if (API_EXISTS(EVP_DigestFinalXOF)) + { + ERR_clear_error(); +@@ -300,7 +300,7 @@ const EVP_MD* CryptoNative_EvpSha3_512(void) + const EVP_MD* CryptoNative_EvpShake128(void) + { + // No error queue impact. +-#if HAVE_OPENSSL_SHA3 ++#if HAVE_OPENSSL_SHA3 && !defined(LIBRESSL_VERSION_NUMBER) + if (API_EXISTS(EVP_shake128)) + { + return EVP_shake128(); +@@ -313,7 +313,7 @@ const EVP_MD* CryptoNative_EvpShake128(void) + const EVP_MD* CryptoNative_EvpShake256(void) + { + // No error queue impact. +-#if HAVE_OPENSSL_SHA3 ++#if HAVE_OPENSSL_SHA3 && !defined(LIBRESSL_VERSION_NUMBER) + if (API_EXISTS(EVP_shake256)) + { + return EVP_shake256(); +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c.orig 2024-03-27 20:49:40 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c +@@ -276,9 +276,18 @@ int32_t CryptoNative_EncodeSubjectPublicKeyInfo(EVP_PK + return i2d_PUBKEY(pkey, &buf); + } + ++#ifdef LIBRESSL_VERSION_NUMBER + static EVP_PKEY* LoadKeyFromEngine( + const char* engineName, + const char* keyName, ++ EVP_PKEY * (*load_func)(ENGINE *, const char *, UI_METHOD *, void *)) ++{ ++ return NULL; ++} ++#else ++static EVP_PKEY* LoadKeyFromEngine( ++ const char* engineName, ++ const char* keyName, + ENGINE_LOAD_KEY_PTR load_func) + { + ERR_clear_error(); +@@ -304,6 +313,7 @@ static EVP_PKEY* LoadKeyFromEngine( + + return ret; + } ++#endif + + EVP_PKEY* CryptoNative_LoadPrivateKeyFromEngine(const char* engineName, const char* keyName) + { +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c.orig 2024-03-28 07:25:55 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +@@ -111,7 +111,7 @@ static void DetectCiphersuiteConfiguration(void) + // + // The method uses OpenSSL 1.0.x API, except for the fallback function SSL_CTX_config, to + // make the portable version easier. +-#if defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0 ++#if (defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0) && !defined(LIBRESSL_VERSION_NUMBER) + + // Check to see if there's a registered default CipherString. If not, we will use our own. + SSL_CTX* ctx = SSL_CTX_new(TLS_method()); +@@ -718,7 +718,7 @@ void CryptoNative_SslSessionFree(SSL_SESSION* session) + + const char* CryptoNative_SslSessionGetHostname(SSL_SESSION* session) + { +-#if defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0 ++#if (defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0) && !defined(LIBRESSL_VERSION_NUMBER) + if (API_EXISTS(SSL_SESSION_get0_hostname)) + { + return SSL_SESSION_get0_hostname(session); +@@ -731,7 +731,7 @@ const char* CryptoNative_SslSessionGetHostname(SSL_SES + + int CryptoNative_SslSessionSetHostname(SSL_SESSION* session, const char* hostname) + { +-#if defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0 ++#if (defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0) && !defined(LIBRESSL_VERSION_NUMBER) + if (API_EXISTS(SSL_SESSION_set1_hostname)) + { + SSL_SESSION_set1_hostname(session, hostname); +@@ -1002,7 +1002,9 @@ void CryptoNative_SslSetClientCertCallback(SSL* ssl, i + { + // void shim functions don't lead to exceptions, so skip the unconditional error clearing. + ++#ifndef LIBRESSL_VERSION_NUMBER + SSL_set_cert_cb(ssl, set ? client_certificate_cb : NULL, NULL); ++#endif + } + + void CryptoNative_SslCtxSetKeylogCallback(SSL_CTX* ctx, SslCtxSetKeylogCallback cb) +--- src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_x509.c.orig 2024-03-28 07:59:11 UTC ++++ src/runtime/src/native/libs/System.Security.Cryptography.Native/pal_x509.c +@@ -57,12 +57,14 @@ c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_ + c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX == X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX); + c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_NAME_SYNTAX == X509_V_ERR_UNSUPPORTED_NAME_SYNTAX); + c_static_assert(PAL_X509_V_ERR_CRL_PATH_VALIDATION_ERROR == X509_V_ERR_CRL_PATH_VALIDATION_ERROR); ++#ifndef LIBRESSL_VERSION_NUMBER + c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_VERSION == X509_V_ERR_SUITE_B_INVALID_VERSION); + c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_ALGORITHM); + c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_CURVE == X509_V_ERR_SUITE_B_INVALID_CURVE); + c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM); + c_static_assert(PAL_X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED); + c_static_assert(PAL_X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 == X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256); ++#endif + c_static_assert(PAL_X509_V_ERR_HOSTNAME_MISMATCH == X509_V_ERR_HOSTNAME_MISMATCH); + c_static_assert(PAL_X509_V_ERR_EMAIL_MISMATCH == X509_V_ERR_EMAIL_MISMATCH); + c_static_assert(PAL_X509_V_ERR_IP_ADDRESS_MISMATCH == X509_V_ERR_IP_ADDRESS_MISMATCH); Index: lang/dotnet/pkg-descr =================================================================== --- lang/dotnet/pkg-descr +++ lang/dotnet/pkg-descr @@ -2,3 +2,9 @@ many different types of applications. It provides a standard set of base class libraries and APIs that are common to all .NET applications. .NET apps can be written in such languages as C#, F#, or Visual Basic. + +Using LibreSSL is not supported. Enabling the LIBRESSL port option will patch +the sources, so building with LibreSSL works, but this will just disable some +functionality and also interfere with runtime detection of OpenSSL APIs. .NET +projects built with this option set might fail to work correctly and are likely +to fail on machines using OpenSSL.