Skip to content

Commit

Permalink
Added an option native_ca to proj.ini and an environment variable PRO…
Browse files Browse the repository at this point in the history
…J_NATIVE_CA to be able to configure curl to use the operating system CA store. (#4356)

Fixes #4338
  • Loading branch information
Robrecht-VS authored Dec 24, 2024
1 parent 3421b04 commit 68ad9e8
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
8 changes: 8 additions & 0 deletions data/proj.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ only_best_default = off
; (added in PROJ 9.0)
; ca_bundle_path = /path/to/cabundle.pem

; When this is set to on, the operating systems native CA store will be used for certificate verification
; If you set this option to on and also set ca_bundle_path then during verification those certificates are
; searched in addition to the native CA store.
; (added in PROJ 9.6)
; Valid values = on, off
;native_ca = on


; Transverse Mercator (and UTM) default algorithm: auto, evenden_snyder or poder_engsager
; * evenden_snyder is the fastest, but less accurate far from central meridian
; * poder_engsager is slower, but more accurate far from central meridian
Expand Down
8 changes: 8 additions & 0 deletions docs/source/usage/environmentvars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,11 @@ done by setting the variable with no content::
Define a custom path to the CA Bundle file. This can be useful if `curl`
and :envvar:`PROJ_NETWORK` are enabled. Alternatively, the
:c:func:`proj_curl_set_ca_bundle_path` function can be used.

.. envvar:: PROJ_NATIVE_CA

.. versionadded:: 9.6.0

When this is set to ON, the operating systems native CA store will be used for certificate verification
If you set this option to ON and also set PROJ_CURL_CA_BUNDLE then during verification those certificates are
searched in addition to the native CA store.
15 changes: 15 additions & 0 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,16 @@ void pj_load_ini(PJ_CONTEXT *ctx) {
ci_equal(proj_only_best_default, "TRUE");
}

const char *native_ca = getenv("PROJ_NATIVE_CA");
if (native_ca && native_ca[0] != '\0'){
ctx->native_ca = ci_equal(native_ca, "ON") ||
ci_equal(native_ca, "YES") ||
ci_equal(native_ca, "TRUE");
}
else {
native_ca = nullptr;
}

ctx->iniFileLoaded = true;
std::string content;
auto file = std::unique_ptr<NS_PROJ::File>(
Expand Down Expand Up @@ -2050,6 +2060,11 @@ void pj_load_ini(PJ_CONTEXT *ctx) {
ci_equal(value, "ON") || ci_equal(value, "YES") ||
ci_equal(value, "TRUE");
}
else if (native_ca == nullptr && key == "native_ca"){
ctx->native_ca =
ci_equal(value, "ON") || ci_equal(value, "YES") ||
ci_equal(value, "TRUE");
}
}

pos = content.find_first_not_of("\r\n", eol);
Expand Down
19 changes: 19 additions & 0 deletions src/networkfilemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,13 @@ static std::string pj_context_get_bundle_path(PJ_CONTEXT *ctx) {
return ctx->ca_bundle_path;
}

#if CURL_AT_LEAST_VERSION(7, 71, 0)
static bool pj_context_get_native_ca(PJ_CONTEXT *ctx) {
pj_load_ini(ctx);
return ctx->native_ca;
}
#endif

// ---------------------------------------------------------------------------

CurlFileHandle::CurlFileHandle(PJ_CONTEXT *ctx, const char *url, CURL *handle)
Expand Down Expand Up @@ -1622,7 +1629,19 @@ CurlFileHandle::CurlFileHandle(PJ_CONTEXT *ctx, const char *url, CURL *handle)
#if defined(SSL_OPTIONS)
// https://curl.se/libcurl/c/CURLOPT_SSL_OPTIONS.html
auto ssl_options = static_cast<long>(SSL_OPTIONS);
#if CURL_AT_LEAST_VERSION(7, 71, 0)
if (pj_context_get_native_ca(ctx)) {
ssl_options = ssl_options | CURLSSLOPT_NATIVE_CA;
}
#endif
CHECK_RET(ctx, curl_easy_setopt(handle, CURLOPT_SSL_OPTIONS, ssl_options));
#else
#if CURL_AT_LEAST_VERSION(7, 71, 0)
if (pj_context_get_native_ca(ctx)){
CHECK_RET(ctx, curl_easy_setopt(handle, CURLOPT_SSL_OPTIONS,
(long)CURLSSLOPT_NATIVE_CA));
}
#endif
#endif

const auto ca_bundle_path = pj_context_get_bundle_path(ctx);
Expand Down
1 change: 1 addition & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,7 @@ struct pj_ctx {
std::string endpoint{};
projNetworkCallbacksAndData networking{};
std::string ca_bundle_path{};
bool native_ca=false;
projGridChunkCache gridChunkCache{};
TMercAlgo defaultTmercAlgo =
TMercAlgo::PODER_ENGSAGER; // can be overridden by content of proj.ini
Expand Down

0 comments on commit 68ad9e8

Please sign in to comment.