diff --git a/.gitmodules b/.gitmodules index 4d5dd20c..e231b39f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,6 @@ [submodule "godot-cpp"] path = godot-cpp url = https://github.com/godotengine/godot-cpp - branch = 3.x [submodule "thirdparty/git2/libgit2"] path = thirdparty/git2/libgit2 url = https://github.com/libgit2/libgit2 @@ -9,6 +8,6 @@ [submodule "thirdparty/ssh2/libssh2"] path = thirdparty/ssh2/libssh2 url = https://github.com/libssh2/libssh2 -[submodule "thirdparty/openssl"] - path = thirdparty/openssl - url = https://github.com/openssl/openssl +[submodule "thirdparty/mbedtls"] + path = thirdparty/mbedtls + url = https://github.com/Mbed-TLS/mbedtls.git diff --git a/SConstruct b/SConstruct index ad759fe0..4e4a6b5e 100644 --- a/SConstruct +++ b/SConstruct @@ -29,22 +29,19 @@ env.PrependENVPath("PATH", os.getenv("PATH")) # Prepend PATH, done upstream in if env["platform"] == "windows" and env.get("is_msvc", False): env.AppendUnique(LINKFLAGS=["/LTCG"]) -# OpenSSL Builder -env.Tool("openssl", toolpath=["tools"]) - -# SSH2 Builder env.Tool("cmake", toolpath=["tools"]) +env.Tool("mbedtls", toolpath=["tools"]) env.Tool("ssh2", toolpath=["tools"]) env.Tool("git2", toolpath=["tools"]) opts.Update(env) -ssl = env.OpenSSL() -ssh2 = env.BuildSSH2(ssl) -ssl += ssh2 -git2 = env.BuildGIT2(ssl) +mbedtls = env.BuildMbedTLS() +ssh2 = env.BuildSSH2(mbedtls) +mbedtls += ssh2 +git2 = env.BuildGIT2(mbedtls) -Export("ssl") +Export("mbedtls") Export("env") SConscript("godot-git-plugin/SCsub") diff --git a/godot-git-plugin/SCsub b/godot-git-plugin/SCsub index 05ec9944..f924ca66 100644 --- a/godot-git-plugin/SCsub +++ b/godot-git-plugin/SCsub @@ -4,7 +4,7 @@ import os env = {} Import("env") -Import("ssl") +Import("mbedtls") env["target_path"] = "../" + env["target_path"] @@ -29,7 +29,7 @@ env.Append(CPPPATH=[".", "src/"]) env.Append(CPPPATH=["#thirdparty/git2/libgit2/include/"]) lib_sources = Glob("src/*.cpp") -env.Depends(lib_sources, ssl) +env.Depends(lib_sources, mbedtls) library = env.SharedLibrary( target=env["target_path"] + "{}{}{}".format(env["target_name"], env["suffix"], env["SHLIBSUFFIX"]), diff --git a/thirdparty/git2/libgit2 b/thirdparty/git2/libgit2 index 3e2baa6d..338e6fb6 160000 --- a/thirdparty/git2/libgit2 +++ b/thirdparty/git2/libgit2 @@ -1 +1 @@ -Subproject commit 3e2baa6d0bfb42f9016e24cba1733a6ae26a8ae6 +Subproject commit 338e6fb681369ff0537719095e22ce9dc602dbf0 diff --git a/thirdparty/mbedtls b/thirdparty/mbedtls new file mode 160000 index 00000000..22098d41 --- /dev/null +++ b/thirdparty/mbedtls @@ -0,0 +1 @@ +Subproject commit 22098d41c6620ce07cf8a0134d37302355e1e5ef diff --git a/thirdparty/openssl b/thirdparty/openssl deleted file mode 160000 index 2cf4e90e..00000000 --- a/thirdparty/openssl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2cf4e90eaaf7402bf038b158dbdacd0a15561fb7 diff --git a/thirdparty/ssh2/libssh2 b/thirdparty/ssh2/libssh2 index 1c3f1b7d..a312b433 160000 --- a/thirdparty/ssh2/libssh2 +++ b/thirdparty/ssh2/libssh2 @@ -1 +1 @@ -Subproject commit 1c3f1b7da588f2652260285529ec3c1f1125eb4e +Subproject commit a312b43325e3383c865a87bb1d26cb52e3292641 diff --git a/tools/git2.py b/tools/git2.py index 92f1a982..f1dc6532 100644 --- a/tools/git2.py +++ b/tools/git2.py @@ -4,23 +4,23 @@ def build_library(env, deps): config = { "CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release", - "OPENSSL_USE_STATIC_LIBS": 1, - "OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"], - "OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"], - "OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"], - "OPENSSL_ROOT_DIR": env["SSL_INSTALL"], + "CMAKE_C_STANDARD": "99", + "USE_SHARED_MBEDTLS_LIBRARY": 0, + "USE_STATIC_MBEDTLS_LIBRARY": 1, + "MBEDTLS_LIBRARY": env["MBEDTLS_LIBRARY"], + "MBEDCRYPTO_LIBRARY": env["MBEDTLS_CRYPTO_LIBRARY"], + "MBEDX509_LIBRARY": env["MBEDTLS_X509_LIBRARY"], + "MBEDTLS_INCLUDE_DIR": env["MBEDTLS_INCLUDE"], "BUILD_TESTS": 0, "BUILD_CLI": 0, "BUILD_EXAMPLES": 0, "BUILD_FUZZERS": 0, - "USE_SSH": 1, - "USE_HTTPS": 1, - "USE_SHA1": 1, + "USE_SSH": "libssh2", "USE_BUNDLED_ZLIB": 1, "USE_HTTP_PARSER": "builtin", "REGEX_BACKEND": "builtin", - "USE_HTTPS": "OpenSSL", - "USE_SHA1": "OpenSSL", + "USE_HTTPS": "mbedTLS", + "USE_SHA1": "mbedTLS", "BUILD_SHARED_LIBS": 0, "LINK_WITH_STATIC_LIBRARIES": 1, "LIBSSH2_INCLUDE_DIR": env.Dir("#thirdparty/ssh2/libssh2/include").abspath, @@ -33,8 +33,6 @@ def build_library(env, deps): if env["platform"] != "windows": config["CMAKE_C_FLAGS"] = "-fPIC" - else: - config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"] is_msvc = env.get("is_msvc", False) lib_ext = ".lib" if is_msvc else ".a" diff --git a/tools/mbedtls.py b/tools/mbedtls.py new file mode 100644 index 00000000..1891f0f0 --- /dev/null +++ b/tools/mbedtls.py @@ -0,0 +1,69 @@ +def build_library(env): + mbedtls_bin = env.Dir("bin/thirdparty/mbedtls/{}/{}/install".format(env["platform"], env["arch"])) + is_msvc = env.get("is_msvc", False) + c_flags = "-DMBEDTLS_SSL_DTLS_SRTP" + if env["platform"] == "linux": + # This is needed on some arch when building with the godot buildroot toolchain + c_flags += " -fPIC" + elif env["platform"] == "windows" and not is_msvc: + c_flags += " -D__USE_MINGW_ANSI_STDIO=0" # See https://github.com/Mbed-TLS/mbedtls/issues/10161 + + mbedtls_config = { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release", + "ENABLE_TESTING": 0, + "ENABLE_PROGRAMS": 0, + "CMAKE_INSTALL_PREFIX": env.Dir(mbedtls_bin).abspath, + "CMAKE_INSTALL_LIBDIR": "lib", + "CMAKE_C_FLAGS": c_flags, + "MBEDTLS_FATAL_WARNINGS": 0, + } + lib_ext = ".lib" if is_msvc else ".a" + lib_prefix = "" if is_msvc else "lib" + mbedtls_libs = [ + "/install/lib/{}mbedtls{}".format(lib_prefix, lib_ext), + "/install/lib/{}mbedx509{}".format(lib_prefix, lib_ext), + "/install/lib/{}mbedcrypto{}".format(lib_prefix, lib_ext), + ] + + mbedtls_cmake_config = [ + "/install/lib/cmake/MbedTLS/MbedTLSConfig.cmake", + "/install/lib/cmake/MbedTLS/MbedTLSConfigVersion.cmake", + "/install/lib/cmake/MbedTLS/MbedTLSTargets.cmake", + ] + + # Build libdatachannel + mbedtls = env.CMakeBuild( + env.Dir("bin/thirdparty/mbedtls/"), + env.Dir("thirdparty/mbedtls"), + cmake_options=mbedtls_config, + cmake_outputs=mbedtls_libs + mbedtls_cmake_config, + install=True, + ) + + # Configure env. + if env["platform"] == "windows": + env.PrependUnique(LIBS=["bcrypt", "ws2_32", "iphlpapi"]) + if env["platform"] == "linux": + env.PrependUnique(LIBS=["pthread"]) + env.Prepend(LIBS=list(filter(lambda f: str(f).endswith(lib_ext), mbedtls))) + env.Append(CPPPATH=[env.Dir("thirdparty/mbedtls/include")]) + + return mbedtls + + +def exists(env): + return "CMake" in env + + +def generate(env): + mbedtls_install_dir = "bin/thirdparty/mbedtls/{}/{}/install".format(env["platform"], env["arch"]) + lib_ext = ".lib" if env.get("is_msvc", False) else ".a" + mbedtls = env.File(mbedtls_install_dir + "/lib/libmbedtls" + lib_ext) + crypto = env.File(mbedtls_install_dir + "/lib/libmbedcrypto" + lib_ext) + x509 = env.File(mbedtls_install_dir + "/lib/libmbedx509" + lib_ext) + includes = env.Dir("thirdparty/mbedtls/include") + env.AddMethod(build_library, "BuildMbedTLS") + env["MBEDTLS_LIBRARY"] = mbedtls.abspath + env["MBEDTLS_CRYPTO_LIBRARY"] = crypto.abspath + env["MBEDTLS_X509_LIBRARY"] = x509.abspath + env["MBEDTLS_INCLUDE"] = includes.abspath diff --git a/tools/openssl.py b/tools/openssl.py deleted file mode 100644 index 99a2426e..00000000 --- a/tools/openssl.py +++ /dev/null @@ -1,288 +0,0 @@ -import os, sys -import SCons.Util -import SCons.Builder -import SCons.Action -from SCons.Defaults import Mkdir -from SCons.Variables import PathVariable, BoolVariable - - -def ssl_platform_target(env): - targets = {} - platform = env["platform"] - if platform == "linux": - targets = { - "x86_32": "linux-x86", - "x86_64": "linux-x86_64", - "arm64": "linux-aarch64", - "arm32": "linux-armv4", - "rv64": "linux64-riscv64", - } - elif platform == "android": - targets = { - "arm64": "android-arm64", - "arm32": "android-arm", - "x86_32": "android-x86", - "x86_64": "android-x86_64", - } - elif platform == "macos": - targets = { - "x86_64": "darwin64-x86_64", - "arm64": "darwin64-arm64", - } - elif platform == "ios": - if env["ios_simulator"]: - targets = { - "x86_64": "iossimulator-xcrun", - "arm64": "iossimulator-xcrun", - } - else: - targets = { - "arm64": "ios64-xcrun", - "arm32": "ios-xcrun", - } - elif platform == "windows": - if env.get("is_msvc", False): - targets = { - "x86_32": "VC-WIN32", - "x86_64": "VC-WIN64A", - } - else: - targets = { - "x86_32": "mingw", - "x86_64": "mingw64", - } - - arch = env["arch"] - target = targets.get(arch, "") - if target == "": - raise ValueError("Architecture '%s' not supported for platform: '%s'" % (arch, platform)) - return target - - -def ssl_platform_options(env): - ssl_config_options = [ - "no-ssl2", - "no-ssl3", - "no-weak-ssl-ciphers", - "no-legacy", - "no-shared", - "no-tests", - ] - if env["platform"] == "windows": - ssl_config_options.append("enable-capieng") - return ssl_config_options - - -def ssl_platform_flags(env): - args = [] - if env["platform"] == "android": - if env.get("android_api_level", ""): - api = int(env["android_api_level"]) - args.append("-D__ANDROID_API__=%s" % api) - elif env["platform"] == "macos": - if env["macos_deployment_target"] != "default": - args.append("-mmacosx-version-min=%s" % env["macos_deployment_target"]) - # OSXCross toolchain setup. - if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ: - for k in ["CC", "CXX", "AR", "AS", "RANLIB"]: - args.append("%s=%s" % (k, env[k])) - elif env["platform"] == "windows": - is_win_host = sys.platform in ["win32", "msys", "cygwin"] - if not (is_win_host or env.get("is_msvc", False)): - mingw_prefixes = { - "x86_32": "--cross-compile-prefix=i686-w64-mingw32-", - "x86_64": "--cross-compile-prefix=x86_64-w64-mingw32-", - } - args.append(mingw_prefixes[env["arch"]]) - return args - - -def ssl_configure_args(env): - if env.get("openssl_configure_options", ""): - opts = SCons.Util.CLVar(env["openssl_configure_options"]) - else: - opts = ssl_platform_options(env) - - if env.get("openssl_configure_target", ""): - target = [env["openssl_configure_target"]] - else: - target = [ssl_platform_target(env)] - - if env.get("openssl_configure_flags", ""): - flags = SCons.Util.CLVar(env["openssl_configure_flags"]) - else: - flags = ssl_platform_flags(env) - - return opts + target + flags - - -def ssl_emitter(target, source, env): - return env["SSL_LIBS"], [env.File(env["SSL_SOURCE"] + "/Configure"), env.File(env["SSL_SOURCE"] + "/VERSION.dat")] - - -def build_openssl(env, jobs=None): - if env["SSL_EXTERNAL"]: - # Setup the env to use the provided libraries, and return them without building. - env.Prepend(CPPPATH=[env["SSL_INCLUDE"]]) - env.Prepend(LIBPATH=[env["SSL_BUILD"]]) - if env["platform"] == "windows": - env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"]) - env.Prepend(LIBS=env["SSL_LIBS"]) - return [env["SSL_CRYPTO_LIBRARY"], env["SSL_LIBRARY"]] - - if jobs is None: - jobs = int(env.GetOption("num_jobs")) - - # Since the OpenSSL build system does not support macOS universal binaries, we first need to build the two libraries - # separately, then we join them together using lipo. - if env["platform"] == "macos" and env["arch"] == "universal": - build_envs = { - "x86_64": env.Clone(), - "arm64": env.Clone(), - } - arch_ssl = [] - for arch in build_envs: - benv = build_envs[arch] - benv["arch"] = arch - generate(benv) - benv["SSLBUILDJOBS"] = max([1, int(jobs / len(build_envs))]) - ssl = benv.OpenSSLBuilder() - arch_ssl.extend(ssl) - benv.NoCache(ssl) # Needs refactoring to properly cache generated headers. - - # x86_64 and arm64 includes are equivalent. - env["SSL_INCLUDE"] = build_envs["arm64"]["SSL_INCLUDE"] - - # Join libraries using lipo. - lipo_action = "lipo $SOURCES -create -output $TARGET" - ssl_libs = list(map(lambda arch: build_envs[arch]["SSL_LIBRARY"], build_envs)) - ssl_crypto_libs = list(map(lambda arch: build_envs[arch]["SSL_CRYPTO_LIBRARY"], build_envs)) - ssl = env.Command(env["SSL_LIBRARY"], ssl_libs, lipo_action) - ssl += env.Command(env["SSL_CRYPTO_LIBRARY"], ssl_crypto_libs, lipo_action) - env.Depends(ssl, arch_ssl) - else: - benv = env.Clone() - benv["SSLBUILDJOBS"] = jobs - ssl = benv.OpenSSLBuilder() - benv.NoCache(ssl) # Needs refactoring to properly cache generated headers. - - # Setup the environment to use the freshly built openssl. - env.Prepend(CPPPATH=[env["SSL_INCLUDE"]]) - env.Prepend(LIBPATH=[env["SSL_BUILD"]]) - if env["platform"] == "windows": - env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"]) - env.Prepend(LIBS=env["SSL_LIBS"]) - - return ssl - - -def ssl_generator(target, source, env, for_signature): - # Strip the -j option for signature to avoid rebuilding when num_jobs changes. - build = env["SSLBUILDCOM"].replace("-j$SSLBUILDJOBS", "") if for_signature else env["SSLBUILDCOM"] - return [ - Mkdir("$SSL_BUILD"), - Mkdir("$SSL_INSTALL"), - SCons.Action.Action("$SSLCONFIGCOM", "$SSLCONFIGCOMSTR"), - SCons.Action.Action(build, "$SSLBUILDCOMSTR"), - ] - - -def options(opts): - opts.Add(PathVariable("openssl_source", "Path to the openssl sources.", "thirdparty/openssl")) - opts.Add("openssl_build", "Destination path of the openssl build.", "bin/thirdparty/openssl") - opts.Add( - "openssl_configure_options", - "OpenSSL configure options override. Will use a reasonable default if not specified.", - "", - ) - opts.Add( - "openssl_configure_target", "OpenSSL configure target override, will be autodetected if not specified.", "" - ) - opts.Add( - "openssl_configure_flags", - "OpenSSL configure compiler flags override. Will be autodetected if not specified.", - "", - ) - opts.Add( - "openssl_external_crypto", - 'An external libcrypto static library (e.g. "/usr/lib/x86_64-linux-gnu/libcrypto.a"). If not provided, OpenSSL will be built from source.', - "", - ) - opts.Add( - "openssl_external_ssl", - 'An external libssl static library (e.g. "/usr/lib/x86_64-linux-gnu/libssl.a"). If not provided, OpenSSL will be built from source.', - "", - ) - opts.Add( - "openssl_external_include", - 'An external OpenSSL "include" folder (e.g. "/usr/include/openssl").', - "", - ) - - -def exists(env): - return True - - -def generate(env): - env.AddMethod(build_openssl, "OpenSSL") - - # Check if the user specified infos about external OpenSSL files. - external_opts = ["openssl_external_crypto", "openssl_external_ssl", "openssl_external_include"] - is_set = lambda k: env.get(k, "") != "" - if any(map(is_set, external_opts)): - # Need provide the whole (crypto, ssl, include) triple to proceed. - if not all(map(is_set, external_opts)): - print('Error: The options "%s" must all be set to use a external library.' % '", "'.join(external_opts)) - sys.exit(255) - - env["SSL_CRYPTO_LIBRARY"] = env.File("${openssl_external_crypto}") - env["SSL_LIBRARY"] = env.File("${openssl_external_ssl}") - env["SSL_BUILD"] = env.Dir("${SSL_LIBRARY.dir}").abspath - env["SSL_INSTALL"] = env.Dir("${SSL_LIBRARY.dir}").abspath - env["SSL_INCLUDE"] = env.Dir("${openssl_external_include}").abspath - env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]] - env["SSL_EXTERNAL"] = True - return - - # We will need to build our own OpenSSL library. - env["SSL_EXTERNAL"] = False - - # Android needs the NDK in ENV, and proper PATH setup. - if env["platform"] == "android" and env["ENV"].get("ANDROID_NDK_ROOT", "") == "": - cc_path = os.path.dirname(env["CC"]) - if cc_path and cc_path not in env["ENV"]: - env.PrependENVPath("PATH", cc_path) - if "ANDROID_NDK_ROOT" not in env["ENV"]: - env["ENV"]["ANDROID_NDK_ROOT"] = env.get("ANDROID_NDK_ROOT", os.environ.get("ANDROID_NDK_ROOT", "")) - - env["SSL_SOURCE"] = env.Dir(env["openssl_source"]).abspath - env["SSL_BUILD"] = env.Dir(env["openssl_build"] + "/{}/{}".format(env["platform"], env["arch"])).abspath - env["SSL_INSTALL"] = env.Dir(env["SSL_BUILD"] + "/dest").abspath - env["SSL_INCLUDE"] = env.Dir(env["SSL_INSTALL"] + "/include").abspath - lib_ext = ".lib" if env.get("is_msvc", False) else ".a" - env["SSL_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libssl" + lib_ext) - env["SSL_CRYPTO_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libcrypto" + lib_ext) - env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]] - - # Configure action - env["PERL"] = env.get("PERL", "perl") - env["_ssl_configure_args"] = ssl_configure_args - env["SSLPLATFORMCONFIG"] = "${_ssl_configure_args(__env__)}" - env["SSLCONFFLAGS"] = SCons.Util.CLVar("") - # fmt: off - env["SSLCONFIGCOM"] = 'cd ${TARGET.dir} && $PERL -- ${SOURCE.abspath} --prefix="${SSL_INSTALL}" --openssldir="${SSL_INSTALL}" $SSLPLATFORMCONFIG $SSLCONFFLAGS' - # fmt: on - - # Build action - env["SSLBUILDJOBS"] = "${__env__.GetOption('num_jobs')}" - # fmt: off - env["SSLBUILDCOM"] = "make -j$SSLBUILDJOBS -C ${TARGET.dir} && make -j$SSLBUILDJOBS -C ${TARGET.dir} install_sw install_ssldirs" - # fmt: on - - # Windows MSVC needs to build using NMake - if env["platform"] == "windows" and env.get("is_msvc", False): - env["SSLBUILDCOM"] = "cd ${TARGET.dir} && nmake install_sw install_ssldirs" - - env["BUILDERS"]["OpenSSLBuilder"] = SCons.Builder.Builder(generator=ssl_generator, emitter=ssl_emitter) - env.AddMethod(build_openssl, "OpenSSL") diff --git a/tools/ssh2.py b/tools/ssh2.py index 581ad463..a5e7f318 100644 --- a/tools/ssh2.py +++ b/tools/ssh2.py @@ -4,23 +4,20 @@ def build_library(env, deps): config = { "CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release", - "OPENSSL_USE_STATIC_LIBS": 1, - "OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"], - "OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"].abspath, - "OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"].abspath, - "OPENSSL_ROOT_DIR": env["SSL_INSTALL"], + "MbedTLS_LIBRARY": env["MBEDTLS_LIBRARY"], + "MBEDCRYPTO_LIBRARY": env["MBEDTLS_CRYPTO_LIBRARY"], + "MBEDX509_LIBRARY": env["MBEDTLS_X509_LIBRARY"], + "MBEDTLS_INCLUDE_DIR": env["MBEDTLS_INCLUDE"], "BUILD_EXAMPLES": 0, "BUILD_TESTING": 0, "BUILD_SHARED_LIBS": 0, "CMAKE_DISABLE_FIND_PACKAGE_ZLIB": 1, "CMAKE_DISABLE_FIND_PACKAGE_OPENSSL": 1, - "CRYPTO_BACKEND": "OpenSSL", + "CRYPTO_BACKEND": "mbedTLS", } if env["platform"] != "windows": config["CMAKE_C_FLAGS"] = "-fPIC" - else: - config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"] is_msvc = env.get("is_msvc", False) lib_ext = ".lib" if is_msvc else ".a"