diff --git a/README.md b/README.md index 512031d..bd07020 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,14 @@ like Windows and macOS where the built-in TLS engines know how to verify hosts using the system's built-in certificate verification mechanism, this function will return `nothing`. On classic UNIX systems (excluding macOS), root certificates are typically stored in a file in `/etc`: the common places for the -current UNIX kernel will be searched and if one of these paths exists, it will +current UNIX system will be searched and if one of these paths exists, it will be returned; if none of these typical root certificate paths exist, then the path to the set of root certificates that are bundled with Julia is returned. The default value returned by `ca_roots()` may be overridden by setting the -`JULIA_SSL_CA_ROOTS_PATH` environment variable to a non-empty value, in which -case this function will always return that path (whether it exists or not). +`JULIA_SSL_CA_ROOTS_PATH`, `SSL_CERT_DIR`, or `SSL_CERT_FILE` environment +variables, in which case this function will always return the value of the first +of these variables that is set (whether the path exists or not). ### ca_roots_path @@ -53,8 +54,9 @@ used. The `ca_roots_path()` function should only be used when configuring libraries which _require_ a path to a file or directory for root certificates. The default value returned by `ca_roots_path()` may be overridden by setting the -`JULIA_SSL_CA_ROOTS_PATH` environment variable to a non-empty value, in which -case this function will always return that path (whether it exists or not). +`JULIA_SSL_CA_ROOTS_PATH`, `SSL_CERT_DIR`, or `SSL_CERT_FILE` environment +variables, in which case this function will always return the value of the first +of these variables that is set (whether the path exists or not). ### verify_host diff --git a/src/ca_roots.jl b/src/ca_roots.jl index 7dbfb3f..9f2e5b0 100644 --- a/src/ca_roots.jl +++ b/src/ca_roots.jl @@ -9,13 +9,14 @@ like Windows and macOS where the built-in TLS engines know how to verify hosts using the system's built-in certificate verification mechanism, this function will return `nothing`. On classic UNIX systems (excluding macOS), root certificates are typically stored in a file in `/etc`: the common places for the -current UNIX kernel will be searched and if one of these paths exists, it will +current UNIX system will be searched and if one of these paths exists, it will be returned; if none of these typical root certificate paths exist, then the path to the set of root certificates that are bundled with Julia is returned. The default value returned by `ca_roots()` may be overridden by setting the -`JULIA_SSL_CA_ROOTS_PATH` environment variable to a non-empty value, in which -case this function will always return that path (whether it exists or not). +`JULIA_SSL_CA_ROOTS_PATH`, `SSL_CERT_DIR`, or `SSL_CERT_FILE` environment +variables, in which case this function will always return the value of the first +of these variables that is set (whether the path exists or not). """ ca_roots()::Union{Nothing,String} = _ca_roots(true) @@ -37,8 +38,9 @@ used. The `ca_roots_path()` function should only be used when configuring libraries which _require_ a path to a file or directory for root certificates. The default value returned by `ca_roots_path()` may be overridden by setting the -`JULIA_SSL_CA_ROOTS_PATH` environment variable to a non-empty value, in which -case this function will always return that path (whether it exists or not). +`JULIA_SSL_CA_ROOTS_PATH`, `SSL_CERT_DIR`, or `SSL_CERT_FILE` environment +variables, in which case this function will always return the value of the first +of these variables that is set (whether the path exists or not). """ ca_roots_path()::String = _ca_roots(false) @@ -81,9 +83,19 @@ function system_ca_roots() return SYSTEM_CA_ROOTS[] end +const CA_ROOTS_VARS = [ + "JULIA_SSL_CA_ROOTS_PATH" + "SSL_CERT_DIR" + "SSL_CERT_FILE" +] + function _ca_roots(allow_nothing::Bool) - path = get(ENV, "JULIA_SSL_CA_ROOTS_PATH", nothing) - path !== nothing && !isempty(path) && return path - allow_nothing && (Sys.iswindows() || Sys.isapple()) && return nothing + for var in CA_ROOTS_VARS + path = get(ENV, var, nothing) + path !== nothing && !isempty(path) && return path + end + if Sys.iswindows() || Sys.isapple() + allow_nothing && return # use system certs + end return system_ca_roots() end diff --git a/test/runtests.jl b/test/runtests.jl index 4789311..3823cd5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,25 +4,31 @@ save_env() clear_env() @testset "ca_roots" begin - @test isfile(bundled_ca_roots()) - @test ca_roots_path() isa String - @test ispath(ca_roots_path()) - if Sys.iswindows() || Sys.isapple() - @test ca_roots_path() == bundled_ca_roots() - @test ca_roots() === nothing - else - @test ca_roots_path() != bundled_ca_roots() - @test ca_roots() == ca_roots_path() + @testset "system certs" begin + @test isfile(bundled_ca_roots()) + @test ca_roots_path() isa String + @test ispath(ca_roots_path()) + if Sys.iswindows() || Sys.isapple() + @test ca_roots_path() == bundled_ca_roots() + @test ca_roots() === nothing + else + @test ca_roots_path() != bundled_ca_roots() + @test ca_roots() == ca_roots_path() + end + end + @testset "env vars" begin + unset = ca_roots(), ca_roots_path() + value = "Why hello!" + for var in CA_ROOTS_VARS + ENV[var] = value + @test ca_roots() == value + @test ca_roots_path() == value + ENV[var] = "" + @test ca_roots() == unset[1] + @test ca_roots_path() == unset[2] + clear_env() + end end - unset = ca_roots(), ca_roots_path() - value = "Why hello!" - ENV["JULIA_SSL_CA_ROOTS_PATH"] = value - @test ca_roots() == value - @test ca_roots_path() == value - ENV["JULIA_SSL_CA_ROOTS_PATH"] = "" - @test ca_roots() == unset[1] - @test ca_roots_path() == unset[2] - clear_env() end @testset "verify_host" begin diff --git a/test/setup.jl b/test/setup.jl index ed2cac2..897abf7 100644 --- a/test/setup.jl +++ b/test/setup.jl @@ -1,7 +1,7 @@ using Test using Logging using NetworkOptions -using NetworkOptions: bundled_ca_roots +using NetworkOptions: CA_ROOTS_VARS, bundled_ca_roots const TEST_URLS = [ "" # not a valid host name @@ -47,9 +47,11 @@ host_variants(host::AbstractString) = Dict( ) const VARIABLES = [ + "JULIA_SSL_CA_ROOTS_PATH" + "SSL_CERT_DIR" + "SSL_CERT_FILE" "JULIA_NO_VERIFY_HOSTS" "JULIA_SSH_NO_VERIFY_HOSTS" - "JULIA_SSL_CA_ROOTS_PATH" "JULIA_SSL_NO_VERIFY_HOSTS" ]