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

Try migration to OpenSSL #53891

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open

Try migration to OpenSSL #53891

wants to merge 18 commits into from

Conversation

fxcoudert
Copy link
Contributor

This is a test of migrating the source build to OpenSSL.

@inkydragon inkydragon added build Build system, or building Julia or its dependencies external dependencies Involves LLVM, OpenBLAS, or other linked libraries labels Mar 29, 2024
@giordano giordano added this to the 1.12 milestone Mar 29, 2024
@fxcoudert
Copy link
Contributor Author

OK I'm learning about stdlib as I go along, feedback is very welcome. I think I've done what is needed to add OpenSSL_jl to stdlib. It allows me to build locally.

There is one thing I think I missed, but I don't know how to fix it:

julia> import MbedTLS_jll
┌ Info: Precompiling MbedTLS_jll [c8ffd9c3-330d-5841-b78e-0817d7145fa1] 
└ @ Base loading.jl:2879

julia> import Open<hit tab>
OpenBLAS_jll
OpenLibm_jll

I can't import OpenSSL_jll. I think it's built (because I had a bug in it at some point, and it was complaining which meant it tried to compile it, and now it doesn't complain anymore)… but I'm not sure.

@fxcoudert
Copy link
Contributor Author

OK, somehow the OpenSSL_jll sources are not getting copied to the right directory. I see this message (not an error, but worrying):

Stdlibs ─────   8.848309 seconds 27.013%
Total ───────  32.755706 seconds
find: /Users/fx/Desktop/julia/usr/share/julia/stdlib/v1.12/OpenSSL_jll/src: No such file or directory
 cd /Users/fx/Desktop/julia/base && if ! JULIA_BINDIR=/Users/fx/Desktop/julia/usr/bin WINEPATH="/Users/fx/Desktop/julia/usr/bin;$WINEPATH" JULIA_LOAD_PATH='@stdlib' JULIA_PROJECT= JULIA_DEPOT_PATH=':' JULIA_NUM_THREADS=1  /Users/fx/Desktop/julia/usr/bin/julia -O3 -C "apple-m1;clone_all"  --output-o /Users/fx/Desktop/julia/usr/lib/julia/sys-o.a.tmp  --startup-file=no --warn-overwrite=yes --sysimage /Users/fx/Desktop/julia/usr/lib/julia/sys.ji /Users/fx/Desktop/julia/contrib/generate_precompile.jl 1; then echo '*** This error is usually fixed by running `make clean`. If the error persists, try `make cleanall`. ***'; false; fi 

@ViralBShah
Copy link
Member

I think you need to add it to stdlib/Makefile too. That might fix that error.

@fxcoudert fxcoudert force-pushed the openssl branch 2 times, most recently from df3f08b to bbc918d Compare March 29, 2024 17:41
@fxcoudert
Copy link
Contributor Author

I think you need to add it to stdlib/Makefile too. That might fix that error.

Thanks, that works.

@giordano
Copy link
Contributor

Once we finish JuliaPackaging/Yggdrasil#8377 (and JuliaPackaging/Yggdrasil#8386) and the corresponding builds are updated here, we can remove mbedTLS_jll as stdlib from here, since it isn't used for anything else, I think.

@fxcoudert
Copy link
Contributor Author

Build works for me locally, but on CI it fails with:

ERROR: LoadError: ArgumentError: Package OpenSSL_jll [458c3c95-2e84-50aa-8efc-19380b2a3a95] is required but does not seem to be installed:
 - Run `Pkg.instantiate()` to install all recorded dependencies.

@giordano
Copy link
Contributor

I'm not sure, but maybe that's during documentation building?

@fxcoudert
Copy link
Contributor Author

fxcoudert commented Mar 29, 2024

Yes, it's during docs building, which I'm not doing locally (not sure what the make invocation for that is, if any). Somehow it's not finding the OpenSSL_jll, which it has just built:

Failed to precompile Documenter [e30172f5-a6a5-5a46-863b-614d45cd2de4] to "/cache/build/tester-amdci5-8/julialang/julia-master/doc/deps/compiled/v1.12/Documenter/jl_ZfVk9U".
ERROR: LoadError: ArgumentError: Package OpenSSL_jll [458c3c95-2e84-50aa-8efc-19380b2a3a95] is required but does not seem to be installed:
 - Run `Pkg.instantiate()` to install all recorded dependencies.
[ … stacktrace … ]
in expression starting at /cache/build/tester-amdci5-8/julialang/julia-master/doc/deps/packages/Git_jll/D8ZTt/src/wrappers/x86_64-linux-gnu.jl:6
in expression starting at /cache/build/tester-amdci5-8/julialang/julia-master/doc/deps/packages/Git_jll/D8ZTt/src/Git_jll.jl:2
in expression starting at stdin:4

@giordano
Copy link
Contributor

@IanButterworth @KristofferC do I understand correctly we need to update doc/Manifest.toml with the new stdlibs?

@IanButterworth
Copy link
Sponsor Member

@giordano yeah any manifests may need to be re-resolved

@fxcoudert
Copy link
Contributor Author

yeah any manifests may need to be re-resolved

May I ask how this is done? I couldn't figure it out from the doc.

@fxcoudert fxcoudert force-pushed the openssl branch 2 times, most recently from 7c1c2de to 44859e1 Compare March 31, 2024 10:16
@fxcoudert
Copy link
Contributor Author

Manually updated doc/Manifest.toml, will see how things go

@IanButterworth
Copy link
Sponsor Member

It usually requires Pkg to resolve it to be accurate

julia --project=doc -e "import Pkg; Pkg.resolve()"

I just pushed the result of that.

I also checked for other manifests in this repo that need updating and there doesn't appear to be any.

Surprisingly there's only one in Pkg https://github.com/IanButterworth/Pkg.jl/blob/205309092c861d58bf787628ccbff4f5a41a0840/test/test_packages/ShouldPreserveSemver/Manifest.toml#L90

@fxcoudert
Copy link
Contributor Author

fxcoudert commented Mar 31, 2024

Thanks @IanButterworth

That does not seem to pass CI (https://buildkite.com/julialang/julia-master/builds/35131#018e94a6-3c00-4b01-8b2a-8797e5b2ddf0), but… I can now run that command from my branch. I don't get the same output as you, here is the diff between your version and mine:

diff --git a/doc/Manifest.toml b/doc/Manifest.toml
index 3c8e5dbca3..12b2e3962e 100644
--- a/doc/Manifest.toml
+++ b/doc/Manifest.toml
@@ -10,9 +10,9 @@ uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9"
 version = "0.0.1"
 
 [[deps.AbstractTrees]]
-git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c"
+git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177"
 uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
-version = "0.4.4"
+version = "0.4.5"
 
 [[deps.ArgTools]]
 uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
@@ -66,21 +66,21 @@ version = "1.11.0"
 
 [[deps.Git]]
 deps = ["Git_jll"]
-git-tree-sha1 = "51764e6c2e84c37055e846c516e9015b4a291c7d"
+git-tree-sha1 = "04eff47b1354d702c3a85e8ab23d539bb7d5957e"
 uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2"
-version = "1.3.0"
+version = "1.3.1"
 
 [[deps.Git_jll]]
 deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"]
-git-tree-sha1 = "bb8f7cc77ec1152414b2af6db533d9471cfbb2d1"
+git-tree-sha1 = "12945451c5d0e2d0dca0724c3a8d6448b46bbdf9"
 uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb"
-version = "2.42.0+0"
+version = "2.44.0+1"
 
 [[deps.IOCapture]]
 deps = ["Logging", "Random"]
-git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6"
+git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c"
 uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
-version = "0.2.3"
+version = "0.2.4"
 
 [[deps.InteractiveUtils]]
 deps = ["Markdown"]
@@ -169,7 +169,6 @@ version = "1.2.0"
 
 [[deps.OpenSSL_jll]]
 deps = ["Artifacts", "Libdl"]
-git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f"
 uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
 version = "3.0.13+0"
 
@@ -180,9 +179,9 @@ version = "10.43.0+0"
 
 [[deps.Parsers]]
 deps = ["Dates", "PrecompileTools", "UUIDs"]
-git-tree-sha1 = "a935806434c9d4c506ba941871b327b96d41f2bf"
+git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821"
 uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
-version = "2.8.0"
+version = "2.8.1"
 
 [[deps.Pkg]]
 deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"]
@@ -195,15 +194,15 @@ weakdeps = ["REPL"]
 
 [[deps.PrecompileTools]]
 deps = ["Preferences"]
-git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f"
+git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
 uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
-version = "1.2.0"
+version = "1.2.1"
 
 [[deps.Preferences]]
 deps = ["TOML"]
-git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e"
+git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
 uuid = "21216c6a-2e73-6563-6e65-726566657250"
-version = "1.4.1"
+version = "1.4.3"
 
 [[deps.Printf]]
 deps = ["Unicode"]
@@ -258,9 +257,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
 version = "1.11.0"
 
 [[deps.TranscodingStreams]]
-git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f"
+git-tree-sha1 = "14389d51751169994b2e1317d5c72f7dc4f21045"
 uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
-version = "0.10.3"
+version = "0.10.6"
 weakdeps = ["Random", "Test"]
 
     [deps.TranscodingStreams.extensions]

Some versions and commit ids are different. But maybe more importantly, it does remove the git-tree-sha1 line for OpenSSL_jll, and that seems to make make html pass for me locally. Trying to push to see if CI likes it.

@fxcoudert
Copy link
Contributor Author

fxcoudert commented Mar 31, 2024

OK, that makes the build pass on FreeBSD and macOS (both Intel and ARM). It's also failing on Windows. It's failing on x86_64-linux and variants, but it is passing on aarch64-linux, powerpc64le-linux and i686-linux. The reason for failure is: could not load library "libcrypto.so.3"

My guess is that it's because in OpenSSL.v3.0.13.x86_64-linux-gnu (from https://github.com/JuliaBinaryWrappers/OpenSSL_jll.jl/releases/tag/OpenSSL-v3.0.13%2B0) the shared libraries are in lib64/ and not lib/. I've checked the example of LibGit2-v1.8.0+1, and there the libraries are always in lib/ and not lib64/.

So: should I got back to the OpenSSL package and make it put libraries in lib/? Or is there a way to tell Julia to be smarter about finding things in lib64/ on 64-bit linux?


On Windows, the naming convention is libcrypto-3-x64.dll for 64_bit and libcrypto-3.dll for 32-bit. Really?

I'll let testing finish here, but I think Windows can be handled with:

diff --git a/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl
index 26eb3d243e..bba9a0a299 100644
--- a/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl
+++ b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl
@@ -3,7 +3,7 @@
 ## dummy stub for https://github.com/JuliaBinaryWrappers/OpenSSL_jll.jl
 
 baremodule OpenSSL_jll
-using Base, Libdl
+using Base, Libdl, Base.BinaryPlatforms
 
 const PATH_list = String[]
 const LIBPATH_list = String[]
@@ -20,8 +20,13 @@ libssl_handle::Ptr{Cvoid} = C_NULL
 libssl_path::String = ""
 
 if Sys.iswindows()
-    const libcrypto = "libcrypto.dll"
-    const libssl = "libssl.dll"
+    if arch(HostPlatform()) == "x86_64"
+        const libcrypto = "libcrypto-3-x64.dll"
+        const libssl = "libssl-3-x64.dll"
+    else
+        const libcrypto = "libcrypto-3.dll"
+        const libssl = "libssl-3.dll"
+    end
 elseif Sys.isapple()
     const libcrypto = "@rpath/libcrypto.3.dylib"
     const libssl = "@rpath/libssl.3.dylib"

@fxcoudert
Copy link
Contributor Author

fxcoudert commented Mar 31, 2024

Status:

julia> import LibGit2

julia> repo = LibGit2.clone("https://github.com/JuliaLang/Example.jl", "/tmp/foobar")
TLS host verification: the identity of the server `github.com` could not be verified. Someone could be trying to man-in-the-middle your connection. It is also possible that the correct server is using an invalid certificate or that your system's certificate authority root store is misconfigured.
ERROR: GitError(Code:ERROR, Class:HTTP, user rejected certificate for github.com)
Stacktrace:
 [1] macro expansion
   @ ~/Desktop/julia/usr/share/julia/stdlib/v1.12/LibGit2/src/error.jl:115 [inlined]
 [2] clone(repo_url::String, repo_path::String, clone_opts::LibGit2.CloneOptions)
   @ LibGit2 ~/Desktop/julia/usr/share/julia/stdlib/v1.12/LibGit2/src/repository.jl:459
 [3] clone(repo_url::String, repo_path::String; branch::String, isbare::Bool, remote_cb::Ptr{Nothing}, credentials::Nothing, callbacks::Dict{Symbol, Tuple{Ptr{Nothing}, Any}})
   @ LibGit2 ~/Desktop/julia/usr/share/julia/stdlib/v1.12/LibGit2/src/LibGit2.jl:584
 [4] clone(repo_url::String, repo_path::String)
   @ LibGit2 ~/Desktop/julia/usr/share/julia/stdlib/v1.12/LibGit2/src/LibGit2.jl:557
 [5] top-level scope
   @ REPL[2]:1

I have to dig to understand why this used to work and doesn't anymore. It is working for me on a full source build, but not with binarybuilder. Go figure…

giordano

This comment was marked as resolved.

@giordano
Copy link
Contributor

On Windows, the naming convention is libcrypto-3-x64.dll for 64_bit and libcrypto-3.dll for 32-bit. Really?

Yes, we stumbled upon that already: JuliaPackaging/Yggdrasil#7576 (comment)

@giordano
Copy link
Contributor

giordano commented Mar 31, 2024

I have to dig to understand why this used to work and doesn't anymore. It is working for me on a full source build, but not with binarybuilder. Go figure…

It works locally for me with BinaryBuilder binaries:

julia> using LibGit2

julia> repo = LibGit2.clone("https://github.com/JuliaLang/Example.jl", mktempdir())
LibGit2.GitRepo("/tmp/jl_6yE8YE")

julia> versioninfo()
Julia Version 1.12.0-DEV.288
Commit 9aeeb2205ba* (2024-03-31 20:28 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: 8 × Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, haswell)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

but it's possible libgit2/openssl is picking up from my system whatever certificates it needs. Maybe we somehow need to inform openssl/libgit2 where the certificates are (MozillaCACerts_jll.cacert)?

@giordano
Copy link
Contributor

giordano commented Apr 5, 2024

@nanosoldier runtests(["OpenSSL", "NetCDF", "ADIOS2", "EHTNCDBase", "GillMatsuno", "GDAL", "WavePropBase", "Keldysh", "Seaborn", "KeldyshED", "Earth2014", "ZipArchives", "PlateMotionRequests", "PhysOcean", "NCTiles", "UnitfulRecipes", "Photosynthesis", "ScalingCollapse", "NetcdfIO", "ExtendableGrids", "ClimaCache", "NCDatasets", "SoilHydraulics", "ShallowWaters", "NWBStream", "StomataModels", "SurfaceFluxes", "MicroscopePSFs", "ChemometricsData", "ArviZExampleData", "NeutralLandscapes", "GEOTRACES", "Lale", "IntervalMDP", "CanopyRadiativeTransfer", "ClimateModels", "Ferrite", "CatBoost", "TIFFDatasets", "LeafOptics", "ClimateERA", "GeoDataFrames", "SpmImages", "GeoRegions", "ERA5Reanalysis", "ClimaUtilities", "ScikitLearn", "NASAPrecipitation", "ClimateTasks", "WorldOceanAtlasTools", "OptimizationSpeedMapping", "Qaintmodels", "OceanRobots", "QXTns", "SpatialBoundaries", "MITgcmTools", "MITgcm", "ArviZPythonPlots", "InferenceObjects", "SpeciesDistributionToolkit", "ClimateBase", "SimSpin", "YAXArrays", "GeoEstimation", "ArgoData", "ClimaCoreTempestRemap", "VMEC", "VisualRegressionTests", "sparseQFCA", "ParallelAnalysis", "OrthogonalSphericalShellGrids", "DIVAnd_HFRadar", "Mikrubi", "Omniscape", "StatGeochem", "FinEtoolsVibInFluids", "FinEtoolsVoxelMesher", "PowerSystemsMaps", "ITensorLattices", "Circuitscape", "Walrus", "AiidaDFTK", "SpeedyWeather", "MimiBRICK", "SMLMMetrics", "SMLMData", "ClimatePlots", "ClimateTools", "GeoIO", "SMLMFrameConnection", "GeophysicalModelGenerator", "LibTrixi", "AvailablePotentialEnergyFramework", "SurfaceReactions", "PlugFlowReactor", "NighttimeLights", "MRINavigator", "SMLMSim", "StableSpectralElements", "NeuroAnalysis"])

@giordano
Copy link
Contributor

giordano commented Apr 5, 2024

@quinnj what do you want to do about the legacy plugin? Should we ship in in a separate package? Is it ok (and feasible) to ship it in a separate package? Or maybe you want to stop supporting it?

@nanosoldier
Copy link
Collaborator

The package evaluation job you requested has completed - possible new issues were detected.
The full report is available.

@giordano
Copy link
Contributor

giordano commented Apr 5, 2024

With JuliaRegistries/General#104322 to address #53891 (comment) we're now down from 100 to 15 failing packages 🙂 As far as I can tell, main issues are OpenSSL.jl (see above), and PyCall not able to download stuff (see e.g. ScikitLearn.jl), which is very likely relevant to this PR. Edit: I can't reproduce locally the error with PyCall not able to download files

julia> using PyCall

julia> py"""
       import urllib.request
       with urllib.request.urlopen('http://python.org/') as response:
          html = response.read()
       """

julia> py"html"
"<!doctype html>\n<!--[if lt IE 7]>   <html class=\"no-js ie6 lt-ie7 lt-ie8 lt-ie9\">   <![endif]-->\n<!--[if IE 7]>      <html class=\"no-js ie7 lt-ie8 lt-ie9\">          <![endif]-->\n<!--[if IE 8]>      <html class=\"no-js ie8 lt-ie9\">                 <![endif]-->\n<!--[if gt IE 8]><!--><html class=\"no-js\" lang=\"en\" dir=\"ltr\">  <!--<![endif]-->\n\n<head>\n    <!-- Google tag (gtag.js) -->\n    <script async src=\"https://www.googletagmanager.com/gtag/js?id=G-TF35YF9CVH\"></script>\n    <script>\n      window.dataLayer = window.dataLayer || [];\n      function gtag(){dataLayer.push(arguments);}\n      gtag('js', new Date());\n      gtag('config', 'G-TF35YF9CVH');\n    </script>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n\n    <link rel=\"prefetch\" href=\"//ajax.googleapis.com/ajax/libs" ⋯ 49439 bytes ⋯ " <script src=\"//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js\"></script>\n    <script>window.jQuery || document.write('<script src=\"/static/js/libs/jquery-ui-1.12.1.min.js\"><\\/script>')</script>\n\n    <script src=\"/static/js/libs/masonry.pkgd.min.js\"></script>\n    <script src=\"/static/js/libs/html-includes.js\"></script>\n\n    <script type=\"text/javascript\" src=\"/static/js/main-min.f5487accf7ed.js\" charset=\"utf-8\"></script>\n    \n\n    <!--[if lte IE 7]>\n    <script type=\"text/javascript\" src=\"/static/js/plugins/IE8-min.8af6e26c7a3b.js\" charset=\"utf-8\"></script>\n    \n    \n    <![endif]-->\n\n    <!--[if lte IE 8]>\n    <script type=\"text/javascript\" src=\"/static/js/plugins/getComputedStyle-min.d41d8cd98f00.js\" charset=\"utf-8\"></script>\n    \n    \n    <![endif]-->\n\n    \n\n    \n    \n\n</body>\n</html>\n"

😕

We may still need to tweak something in the registry, because UnitfulRecipes.jl is failing, but it's due to installing a very old (and apparently incompatible) version of GR.jl (we get GR@0.52.0, which doesn't work for me on aarch64-darwin even on Julia v1.9, so that's very much unrelated to this PR). GR@v0.73 works fine for me on this PR, and I can't reproduce locally the installation issue, so it's a bit complicated to understand why we're getting an old GR.jl. (Edit: I think I tested something wrong, because I can reproduce test failure of UnitfulRecipes.jl, but the fact is that it's an old and unmaintained package, it's incompatible with newer versions of Plots.jl, I don't really think we can do much about it)

@quinnj
Copy link
Member

quinnj commented Apr 5, 2024

@quinnj what do you want to do about the legacy plugin? Should we ship in in a separate package? Is it ok (and feasible) to ship it in a separate package? Or maybe you want to stop supporting it?

Sorry, not quite following; what is your linked comment supposed to link to? I assume we're talking about the mariadb connector? Is there a piece there that isn't upgrading cleanly?

@giordano
Copy link
Contributor

giordano commented Apr 5, 2024

If you look at the linked log https://s3.amazonaws.com/julialang-reports/nanosoldier/pkgeval/by_hash/955b85b_vs_a69aa30/OpenSSL.primary.log, tests are failing when trying to call the legacy plugin

Encrypt: Error During Test at /home/pkgeval/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:462
  Got exception outside of a @test
  OpenSSL.OpenSSLError("005D06D96C7F0000:error:12800067:DSO support routines:(unknown function):could not load the shared library:crypto/dso/dso_dlfcn.c:118:filename(ossl-modules/legacy.so): ossl-modules/legacy.so: cannot open shared object file: No such file or directory\n005D06D96C7F0000:error:12800067:DSO support routines:(unknown function):could not load the shared library:crypto/dso/dso_lib.c:152:\n005D06D96C7F0000:error:07880025:common libcrypto routines:(unknown function):reason(524325):crypto/provider_core.c:912:name=legacy\n")
  Stacktrace:
    [1] load_provider(libctx::Ptr{Nothing}, provider_name::String)
      @ OpenSSL ~/.julia/packages/OpenSSL/6OIuN/src/OpenSSL.jl:587
    [2] load_legacy_provider()
      @ OpenSSL ~/.julia/packages/OpenSSL/6OIuN/src/OpenSSL.jl:602
    [3] top-level scope
      @ ~/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:463
    [4] macro expansion
      @ /opt/julia/share/julia/stdlib/v1.12/Test/src/Test.jl:164 [inlined]
    [5] macro expansion
      @ ~/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:208 [inlined]
    [6] include(fname::String)
      @ Main ./sysimg.jl:38
    [7] top-level scope
      @ none:6
    [8] eval
      @ ./boot.jl:432 [inlined]
    [9] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:245
   [10] _start()
      @ Base ./client.jl:533
Test Summary: | Error  Total  Time
Encrypt       |     1      1  2.8s

This is failing because we aren't currently installing the legacy module here

@PallHaraldsson
Copy link
Contributor

PallHaraldsson commented Apr 5, 2024

I looked up your "DSO support routines" error and maybe worth to try this simple:

nodejs/node#43132 (comment)

workaround, I ran export OPENSSL_CONF=/dev/null before starting node. This prevents the issue and the code begins to work, however this also bypasses the config for openssl.

https://askubuntu.com/a/1410124

I think this basically disables OpenSSL, or its security/old cipher or something, but it it may help PkgEval to show which package work; after some (insecure) download (so only do as a temp workaround until right config found, then re-PkgEval). I guess the /etc/ssl/openssl.cnf file needs changing, you look at it but it's for the older OpenSLL installed on the testing machine asking for something now in legacy, and you could just not use that thus not the legacy .so file. [This issue would also be bypassed if system OpenSSL is just used, since then it would match its config file?]

@quinnj
Copy link
Member

quinnj commented Apr 6, 2024

If you look at the linked log https://s3.amazonaws.com/julialang-reports/nanosoldier/pkgeval/by_hash/955b85b_vs_a69aa30/OpenSSL.primary.log, tests are failing when trying to call the legacy plugin

Encrypt: Error During Test at /home/pkgeval/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:462
  Got exception outside of a @test
  OpenSSL.OpenSSLError("005D06D96C7F0000:error:12800067:DSO support routines:(unknown function):could not load the shared library:crypto/dso/dso_dlfcn.c:118:filename(ossl-modules/legacy.so): ossl-modules/legacy.so: cannot open shared object file: No such file or directory\n005D06D96C7F0000:error:12800067:DSO support routines:(unknown function):could not load the shared library:crypto/dso/dso_lib.c:152:\n005D06D96C7F0000:error:07880025:common libcrypto routines:(unknown function):reason(524325):crypto/provider_core.c:912:name=legacy\n")
  Stacktrace:
    [1] load_provider(libctx::Ptr{Nothing}, provider_name::String)
      @ OpenSSL ~/.julia/packages/OpenSSL/6OIuN/src/OpenSSL.jl:587
    [2] load_legacy_provider()
      @ OpenSSL ~/.julia/packages/OpenSSL/6OIuN/src/OpenSSL.jl:602
    [3] top-level scope
      @ ~/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:463
    [4] macro expansion
      @ /opt/julia/share/julia/stdlib/v1.12/Test/src/Test.jl:164 [inlined]
    [5] macro expansion
      @ ~/.julia/packages/OpenSSL/6OIuN/test/runtests.jl:208 [inlined]
    [6] include(fname::String)
      @ Main ./sysimg.jl:38
    [7] top-level scope
      @ none:6
    [8] eval
      @ ./boot.jl:432 [inlined]
    [9] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:245
   [10] _start()
      @ Base ./client.jl:533
Test Summary: | Error  Total  Time
Encrypt       |     1      1  2.8s

This is failing because we aren't currently installing the legacy module here

I think @mkitti added that code when we did the 1 -> 3 upgrade. @mkitti, do you have an opinion on the legacy plugin? I don't personally know of any direct uses of it, so I'd be fine removing and doing a breaking release. We could at least make the tests probably versioned to run only if it's loaded?

@mkitti
Copy link
Contributor

mkitti commented Apr 6, 2024

I have no specific opinion on the matter other than making things just work. Honestly, I need review my own changes.

@fxcoudert
Copy link
Contributor Author

fxcoudert commented Apr 6, 2024

About the legacy modules. OpenSSL-v3.0.13+1 ships them under lib/ossl-modules/legacy.$(shext), which is as expected. However, the openssl doc states (https://www.openssl.org/docs/man3.0/man1/openssl-pkcs12.html):

If OpenSSL is not installed system-wide, it is necessary to also use, for example, -provider-path ./providers or to set the environment variable OPENSSL_MODULES to point to the directory where the providers can be found.

We don't want to modify the configuration file, so two options are available:

  1. define the environment variable OPENSSL_MODULES before we first load the openssl libraries
  2. remove the part of tests that expects legacy modules to work

The second option seems more reasonable, unless there is evidence they are actually used in actual code. Enabling loading of modules that upstream describes as “fallen out of use, have been deemed insecure by the cryptography community” does not appear to be good practice.

@quinnj
Copy link
Member

quinnj commented Apr 6, 2024

Option 2: JuliaWeb/OpenSSL.jl#34

giordano added a commit to JuliaCI/PkgEval.jl that referenced this pull request Apr 15, 2024
This is an old and unmaintained package (jw3126/UnitfulRecipes.jl#81), so even if we had to fix anything in that package, nothing could be done about it.  Note: this is currently failing tests in JuliaLang/julia#53891 (comment) because it's trying to install a very ancient version of `GR.jl`, I don't see any fix possible if the package is deprecated.
@giordano
Copy link
Contributor

giordano commented Apr 16, 2024

I'm having a look at the most recent failing tests. There are three packages which require a missing binary dependency:

  • OpenSSL should be addressed by Remove legacy plugin tests JuliaWeb/OpenSSL.jl#34
  • UnitfulRecipes is failing because it's trying to install an ancient version of GR.jl (GR@0.52.0) which for me doesn't even work on Julia v1.9, so that's really not specific to this PR. I opened Skip UnitfulRecipes JuliaCI/PkgEval.jl#263 to stop testing UnitfulRecipes, it's unmaintained
  • VisualRegressionTests is failing because by default Pkg installs a combination of packages which which again pulls in GR@0.52.0. If you do ]add add GR@0.73.0, VisualRegressionTests@v1.3.2 then you get a working combination and then tests will pass, but if you try to have also a more recent version of ColorVectorSpace then you start running into conflicts (and probably Pkg prefers downgrading GR over ColorVectorSpace):
    (jl_FlwejJ) pkg> add ColorVectorSpace@v0.10.0, GR@0.73.0, VisualRegressionTests@v1.3.2
       Resolving package versions...
    ERROR: Unsatisfiable requirements detected for package ImageMagick_jll [c73af94c]:
     ImageMagick_jll [c73af94c] log:
     ├─possible versions are: 6.9.10 - 7.1.1 or uninstalled
     ├─restricted by compatibility requirements with ImageMagick [6218d12a] to versions: 6.9.10 - 6.9.11
     │ └─ImageMagick [6218d12a] log:
     │   ├─possible versions are: 0.7.0 - 1.3.1 or uninstalled
     │   ├─restricted by compatibility requirements with FixedPointNumbers [53c48c17] to versions: [0.7.6 - 0.7.9, 1.1.1 - 1.3.1] or uninstalled, leaving only versions: [0.7.6 - 0.7.9, 1.1.1 - 1.3.1]
     │   │ └─FixedPointNumbers [53c48c17] log:
     │   │   ├─possible versions are: 0.5.0 - 0.8.4 or uninstalled
     │   │   └─restricted by compatibility requirements with ColorVectorSpace [c3611d14] to versions: 0.8.2 - 0.8.4
     │   │     └─ColorVectorSpace [c3611d14] log:
     │   │       ├─possible versions are: 0.6.0 - 0.10.0 or uninstalled
     │   │       ├─restricted to versions * by project [dd2e5e8e], leaving only versions: 0.6.0 - 0.10.0
     │   │       │ └─project [dd2e5e8e] log:
     │   │       │   ├─possible versions are: 0.0.0 or uninstalled
     │   │       │   └─project [dd2e5e8e] is fixed to version 0.0.0
     │   │       └─restricted to versions 0.10.0 by an explicit requirement, leaving only versions: 0.10.0
     │   └─restricted by compatibility requirements with ImageCore [a09fc81d] to versions: 1.3.0 - 1.3.1 or uninstalled, leaving only versions: 1.3.0 - 1.3.1
     │     └─ImageCore [a09fc81d] log:
     │       ├─possible versions are: 0.7.0 - 0.10.2 or uninstalled
     │       ├─restricted by compatibility requirements with ColorVectorSpace [c3611d14] to versions: [0.7.0 - 0.8.22, 0.10.0 - 0.10.2] or uninstalled
     │       │ └─ColorVectorSpace [c3611d14] log: see above
     │       ├─restricted by compatibility requirements with FixedPointNumbers [53c48c17] to versions: 0.8.12 - 0.10.2 or uninstalled, leaving only versions: [0.8.12 - 0.8.22, 0.10.0 - 0.10.2] or uninstalled
     │       │ └─FixedPointNumbers [53c48c17] log: see above
     │       ├─restricted by compatibility requirements with ImageMagick [6218d12a] to versions: 0.8.1 - 0.10.2, leaving only versions: [0.8.12 - 0.8.22, 0.10.0 - 0.10.2]
     │       │ └─ImageMagick [6218d12a] log: see above
     │       └─restricted by compatibility requirements with QuartzImageIO [dca85d43] to versions: 0.9.0 - 0.10.2, leaving only versions: 0.10.0 - 0.10.2
     │         └─QuartzImageIO [dca85d43] log:
     │           ├─possible versions are: 0.5.0 - 0.7.5 or uninstalled
     │           ├─restricted by compatibility requirements with VisualRegressionTests [34922c18] to versions: 0.7.0 - 0.7.5
     │           │ └─VisualRegressionTests [34922c18] log:
     │           │   ├─possible versions are: 0.2.0 - 1.3.2 or uninstalled
     │           │   └─restricted to versions 1.3.2 by an explicit requirement, leaving only versions: 1.3.2
     │           ├─restricted by compatibility requirements with ColorVectorSpace [c3611d14] to versions: 0.7.4 - 0.7.5 or uninstalled, leaving only versions: 0.7.4 - 0.7.5
     │           │ └─ColorVectorSpace [c3611d14] log: see above
     │           └─restricted by compatibility requirements with ImageCore [a09fc81d] to versions: 0.7.5 or uninstalled, leaving only versions: 0.7.5
     │             └─ImageCore [a09fc81d] log: see above
     └─restricted by compatibility requirements with Libtiff_jll [89763e89] to versions: 6.9.13 or uninstalled — no versions left
       └─Libtiff_jll [89763e89] log:
         ├─possible versions are: 4.0.10 - 4.6.0 or uninstalled
         └─restricted by compatibility requirements with GR_jll [d2c73de3] to versions: 4.5.1
           └─GR_jll [d2c73de3] log:
             ├─possible versions are: 0.51.2 - 0.73.3 or uninstalled
             └─restricted by compatibility requirements with GR [28b8d3ca] to versions: 0.73.0
               └─GR [28b8d3ca] log:
                 ├─possible versions are: 0.35.0 - 0.73.3 or uninstalled
                 ├─restricted to versions * by project [dd2e5e8e], leaving only versions: 0.35.0 - 0.73.3
                 │ └─project [dd2e5e8e] log: see above
                 └─restricted to versions 0.73.0 by an explicit requirement, leaving only versions: 0.73.0
    
    I need to figure out how we can nudge Pkg to install a better combination of packages out-of-the-box, maybe we should tell the registry GR@0.52.0 is unusable in newer versions of Julia. Edit: ah, the problem is ImageMagick_jll v6.9.12-0 is breaking for PNG and TIFF JuliaIO/ImageMagick.jl#206: we're stuck with ImageMagick_jll@6.9.11 for ImageMagick.jl.

maleadt pushed a commit to JuliaCI/PkgEval.jl that referenced this pull request Apr 16, 2024
This is an old and unmaintained package (jw3126/UnitfulRecipes.jl#81), so even if we had to fix anything in that package, nothing could be done about it.  Note: this is currently failing tests in JuliaLang/julia#53891 (comment) because it's trying to install a very ancient version of `GR.jl`, I don't see any fix possible if the package is deprecated.
@fxcoudert
Copy link
Contributor Author

Is there anything more I can do to help push this over the finish line?

@giordano
Copy link
Contributor

I was waiting for a new OpenSSL.jl version with the new update tests, to be able to make sure it's compatible with this branch. UnitfulRecipes.jl has been already excluded from future PkgEval tests (it's an unmaintained package), but I still need to adjust the General registry not to install super old versions of GR.jl.

The only other remaining thing I believe is figuring out why packages calling python via PyCall, #53891 (comment), problem which I couldn't reproduce locally on this branch with x86_64-linux nor aarch64-darwin.

@inkydragon
Copy link
Sponsor Member

inkydragon commented Apr 21, 2024

Cannot reproduce PyCall error on Windows too.

Test with:

  • OS: Windows (x86_64-w64-mingw32)
  • Version 1.12.0-DEV.302 (2024-04-03) pr/53891/955b85b549*
  • OpenSSL v1.4.3
  • PyCall v1.96.4

ScikitLearn.jl passed all tests.

@mkitti
Copy link
Contributor

mkitti commented Apr 21, 2024

I think you have the OpenSSL.jl version now: JuliaRegistries/General#105279

The Python error appears to be as follows:

base: Error During Test at /home/pkgeval/.julia/packages/ScikitLearn/sqLdT/test/runtests.jl:16
  Got exception outside of a @test
  PyError ($(Expr(:escape, :(ccall(#= /home/pkgeval/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'urllib.error.URLError'>
  URLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1007)'))
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/site-packages/sklearn/datasets/_california_housing.py", line 138, in fetch_california_housing
      archive_path = _fetch_remote(ARCHIVE, dirname=data_home)
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/site-packages/sklearn/datasets/_base.py", line 1324, in _fetch_remote
      urlretrieve(remote.url, file_path)
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 241, in urlretrieve
      with contextlib.closing(urlopen(url, data)) as fp:
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 216, in urlopen
      return opener.open(url, data, timeout)
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 519, in open
      response = self._open(req, data)
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 536, in _open
      result = self._call_chain(self.handle_open, protocol, protocol +
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 496, in _call_chain
      result = func(*args)
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 1391, in https_open
      return self.do_open(http.client.HTTPSConnection, req,
    File "/home/pkgeval/.julia/conda/3/x86_64/lib/python3.10/urllib/request.py", line 1351, in do_open
      raise URLError(err)

My current guess is that PyCall.jl is pulling in a version of Python compiled against OpenSSL 3.2.1.

Conda-forge does seem to have an openssl 3.0 branch in their feedstock:
https://github.com/conda-forge/openssl-feedstock/commits/3.0.x/

If I just request Python via conda/mamba, I get the following install:

$ mamba create -n python_openssl_test -c conda-forge python
...
  + ca-certificates       2024.2.2  hbcca054_0          conda-forge/linux-64     Cached
  + openssl                  3.2.1  hd590300_1          conda-forge/linux-64        3MB
  + python                  3.12.3  hab00c5b_0_cpython  conda-forge/linux-64       32MB
...

If I also specify that I want openssl 3.0, then I get the following packages:

$ mamba create -n python_openssl_test -c conda-forge python openssl=3.0
...
  + ca-certificates       2024.2.2  hbcca054_0          conda-forge/linux-64     Cached
  + openssl                 3.0.13  hd590300_0          conda-forge/linux-64        3MB
  + python                  3.11.0  he550d4f_1_cpython  conda-forge/linux-64       31MB
...

If we continue on the current course of building official Julia against OpenSSL 3.0 LTS (supported through September 7th, 2026), then we may need to be proactive about requesting a Python that also uses OpenSSL 3.0.

@mkitti
Copy link
Contributor

mkitti commented Apr 21, 2024

Here's a minimum demonstration of the Python issue via PythonCall:

using Pkg
Pkg.activate(; temp=true)
Pkg.add(["OpenSSL_jll", "PythonCall"])
using OpenSSL_jll, PythonCall, SHA

if !isempty(ARGS) && ARGS[1] == "--fix"
    using NetworkOptions
    ENV["SSL_CERT_FILE"] = NetworkOptions.ca_roots()
end

urllib_request = pyimport("urllib.request")
f = urllib_request.urlopen("https://ndownloader.figshare.com/files/5976036")
bytes = pyconvert(Vector, f.read())
f.close()
# should print aaa5c9a6afe2225cc2aed2723682ae403280c4a3695a2ddda4ffb5d8215ea681
println(bytes2hex(sha256(bytes)))

The problem is that the default trusted certificate store refers to /workspace/destdir/ssl.

julia> using OpenSSL_jll

julia> run(`$(OpenSSL_jll.openssl()) version -d`);
OPENSSLDIR: "/workspace/destdir/ssl"

According the OpenSSL docs this can be overriden via the environment variables SSL_CERT_FILE or SSL_CERT_DIR.

A Python-based fix is to configure a SSL context.

julia> begin
           using PythonCall, NetworkOptions
           ssl = pyimport("ssl")
           ctx = ssl.create_default_context()
           ctx.load_verify_locations(NetworkOptions.ca_roots())
           urllib_request = pyimport("urllib.request")
           f = urllib_request.urlopen("https://ndownloader.figshare.com/files/5976036", context=ctx)
           bytes = pyconvert(Vector, f.read())
           f.close()
           # should print aaa5c9a6afe2225cc2aed2723682ae403280c4a3695a2ddda4ffb5d8215ea681
           println(bytes2hex(sha256(bytes)))
       end
aaa5c9a6afe2225cc2aed2723682ae403280c4a3695a2ddda4ffb5d8215ea681

@mkitti
Copy link
Contributor

mkitti commented Apr 21, 2024

Here's Python reporting the default verify paths and environment variables.

julia> begin
           using OpenSSL_jll, PythonCall
           ssl = pyimport("ssl")
           ssl.get_default_verify_paths()
       end
Python: DefaultVerifyPaths(
    cafile=None, capath=None,
    openssl_cafile_env='SSL_CERT_FILE',
    openssl_cafile='/workspace/destdir/ssl/cert.pem',
    openssl_capath_env='SSL_CERT_DIR',
    openssl_capath='/workspace/destdir/ssl/certs'
)

julia> @ccall(OpenSSL_jll.libssl.X509_get_default_cert_dir()::Cstring) |> unsafe_string
"/workspace/destdir/ssl/certs"

julia> @ccall(OpenSSL_jll.libssl.X509_get_default_cert_file()::Cstring) |> unsafe_string
"/workspace/destdir/ssl/cert.pem"

julia> @ccall(OpenSSL_jll.libssl.X509_get_default_cert_file_env()::Cstring) |> unsafe_string
"SSL_CERT_FILE"

julia> @ccall(OpenSSL_jll.libssl.X509_get_default_cert_dir_env()::Cstring) |> unsafe_string
"SSL_CERT_DIR"

@stevengj , @cjdoris I wonder if you had any thoughts on how to have properly configure Python's OpenSSL library if Julia is supplying the the SSL library?

@giordano
Copy link
Contributor

Why with PyCall on this branch I get

julia> using OpenSSL_jll, PyCall

julia> py"""
       import ssl
       print(ssl.get_default_verify_paths())
       """
DefaultVerifyPaths(cafile='/Users/mose/.julia/conda/3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Users/mose/.julia/conda/3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Users/mose/.julia/conda/3/ssl/certs')

while with PythonCall

julia> begin
           using OpenSSL_jll, PythonCall
           ssl = pyimport("ssl")
           ssl.get_default_verify_paths()
       end
Python: DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/workspace/destdir/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/workspace/destdir/ssl/certs')

?

@mkitti
Copy link
Contributor

mkitti commented Apr 21, 2024

@giordano My guess is that PyCall is defaulting to relatively older install that might be loading an older OpenSSL? Meanwhile, PythonCall is setting up a brand new environment corresponding with your current Julia environment.

Run the following for your PyCall install.

import sys

print("Python version")
print(sys.version)
print("Version info.")
print(sys.version_info)

@mkitti
Copy link
Contributor

mkitti commented Apr 21, 2024

Here's mine for what it's worth.

julia> using OpenSSL_jll, PyCall

julia> py"""
       import ssl
       print(ssl.get_default_verify_paths())
       """
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/workspace/destdir/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/workspace/destdir/ssl/certs')

@giordano
Copy link
Contributor

giordano commented Apr 21, 2024

Ah, I guess it's because my PyCall is actually using OpenSSL 1.1, while PythonCall uses OpenSSL 3:

julia> using PyCall

julia> filter(contains(r"lib(ssl|crypto)\..*\.dylib"), readdir(dirname(PyCall.libpython)))
2-element Vector{String}:
 "libcrypto.1.1.dylib"
 "libssl.1.1.dylib"

julia> py"""
       import sys

       print("Python version")
       print(sys.version)
       print("Version info.")
       print(sys.version_info)
       """
Python version
3.9.5 | packaged by conda-forge | (default, Jun 19 2021, 00:27:15)
[Clang 11.1.0 ]
Version info.
sys.version_info(major=3, minor=9, micro=5, releaselevel='final', serial=0)

# new session

julia> using PythonCall

julia> filter(contains(r"lib(ssl|crypto)\..*\.dylib"), readdir(dirname(PythonCall.C.CTX.lib_path)))
2-element Vector{String}:
 "libcrypto.3.dylib"
 "libssl.3.dylib"

@PallHaraldsson
Copy link
Contributor

PallHaraldsson commented Apr 21, 2024

If we continue on the current course of building official Julia against OpenSSL 3.0 LTS (supported through September 7th, 2026), then we may need to be proactive about requesting a Python that also uses OpenSSL 3.0.

If I understand correctly, you link to OpenSSL, and Python (libpython or e.g. PythonCall?) does too, and it must be the same one, since you can only link to one .so version in the process? [You can call to R with RCall.jl etc. and getting all to use the same version might prove problematic.]

But does Julia have to link at all (by default)? I mean this is only for Downloads, and indirectly Pkg, to download (or also upload? does Julia per se support that?), but does it need to be in the same process? When you call Download.download it could open a separate Julia process (or some simpler one) that does the download and only it needs to link to OpenSLL, avoiding all possibility of conflict. It can even be async (not by default? though that might be great, at least eventually). [For Pkg there's precedent, it forks processes to precompile why not for the downloads also...]

Ah, I guess it's because my PyCall is actually using OpenSSL 1.1, while PythonCall uses OpenSSL 3

PyCall is not going away (at least in the near term, and because of packages like Pandas.jl), and you can use it with PythonCall, something to have in mind. Then you get either 1.1 with PyCall or both otherwise 3.0...

@mkitti
Copy link
Contributor

mkitti commented Apr 22, 2024

@PallHaraldsson Julia currently uses mbedTLS for SSL. This PR is an attempt to move away from mbedTLS to OpenSSL. The standard library packages LibSSH2_jll, LibGit2_jll, and LibCurl_jll all currently depend on mbedTLS_jll but if this PR goes through, then they will depend on OpenSSL_jll instead. Python also depends on OpenSSL.

The above discussion involves loading libpython into a Julia process. If the Julia process has already loaded libssl and libcrypto, then libpython will also attempt to use the same libssl and libcrypto. It's not compatible to have two different OpenSSL 3.x libraries loaded at the same time.

PyCall creates a single miniconda environment and tends to reuse that same conda environment for all Julia environments unless configured otherwise. In contrast, PythonCall tends to build a distinct conda environment for each Julia environment. One consequence of this is that PyCall installations tend to have older versions of Python installed using OpenSSL v1, which is no longer supported upstream. Fresh installs of PyCall will usually have been updated with Python built against OpenSSL v3.

Moving to an OpenSSL based standard library will make it much more likely that Julia will have dynamically loaded libssl and libcrypto. A new challenge for language interop will be ensuring that both Python and Julia can function with the same dynamically loaded OpenSSL libraries.

Overall, OpenSSL based Julia is probably a good idea for reasons I have elaborated on elsewhere. Namely mbedTLS seems to be mainly targeting embedded applications whereas OpenSSL seems to more aligned with where Julia is currently used.

@giordano
Copy link
Contributor

@StefanKarpinski since you deal a bit with network-related stuff, what do you think we should do with regards to the cert file:

  1. in the __init__ of OpenSSL_Jll we set the env var get!(ENV, "SSL_CERT_FILE", MozillaCACerts_jll.cacert) or something similar (with get! we change the value only if not already set, so that we don't override a value the user set possibly outside)
  2. we let developers of PyCall/PythonCall deal with this
  3. we set SSL_CERT_FILE only in PkgEval
  4. some other options I didn't think

@mkitti
Copy link
Contributor

mkitti commented Apr 22, 2024

The above question is applicable to OpenSSL.jl sitting upstream of HTTP.jl.

The constructor of OpenSSL.SSLContext defaults to MozillaCACerts_jll.cacert

function SSLContext(ssl_method::SSLMethod, verify_file::String=MozillaCACerts_jll.cacert)

https://github.com/JuliaWeb/OpenSSL.jl/blob/544711038ab32b04789f86f316f65bae3920e901/src/ssl.jl#L137

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Build system, or building Julia or its dependencies external dependencies Involves LLVM, OpenBLAS, or other linked libraries stdlib JLLs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants