Skip to content

Commit 68ad9e8

Browse files
authored
Added an option native_ca to proj.ini and an environment variable PROJ_NATIVE_CA to be able to configure curl to use the operating system CA store. (OSGeo#4356)
Fixes OSGeo#4338
1 parent 3421b04 commit 68ad9e8

File tree

5 files changed

+51
-0
lines changed

5 files changed

+51
-0
lines changed

data/proj.ini

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ only_best_default = off
4242
; (added in PROJ 9.0)
4343
; ca_bundle_path = /path/to/cabundle.pem
4444

45+
; When this is set to on, the operating systems native CA store will be used for certificate verification
46+
; If you set this option to on and also set ca_bundle_path then during verification those certificates are
47+
; searched in addition to the native CA store.
48+
; (added in PROJ 9.6)
49+
; Valid values = on, off
50+
;native_ca = on
51+
52+
4553
; Transverse Mercator (and UTM) default algorithm: auto, evenden_snyder or poder_engsager
4654
; * evenden_snyder is the fastest, but less accurate far from central meridian
4755
; * poder_engsager is slower, but more accurate far from central meridian

docs/source/usage/environmentvars.rst

+8
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,11 @@ done by setting the variable with no content::
106106
Define a custom path to the CA Bundle file. This can be useful if `curl`
107107
and :envvar:`PROJ_NETWORK` are enabled. Alternatively, the
108108
:c:func:`proj_curl_set_ca_bundle_path` function can be used.
109+
110+
.. envvar:: PROJ_NATIVE_CA
111+
112+
.. versionadded:: 9.6.0
113+
114+
When this is set to ON, the operating systems native CA store will be used for certificate verification
115+
If you set this option to ON and also set PROJ_CURL_CA_BUNDLE then during verification those certificates are
116+
searched in addition to the native CA store.

src/filemanager.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,16 @@ void pj_load_ini(PJ_CONTEXT *ctx) {
19841984
ci_equal(proj_only_best_default, "TRUE");
19851985
}
19861986

1987+
const char *native_ca = getenv("PROJ_NATIVE_CA");
1988+
if (native_ca && native_ca[0] != '\0'){
1989+
ctx->native_ca = ci_equal(native_ca, "ON") ||
1990+
ci_equal(native_ca, "YES") ||
1991+
ci_equal(native_ca, "TRUE");
1992+
}
1993+
else {
1994+
native_ca = nullptr;
1995+
}
1996+
19871997
ctx->iniFileLoaded = true;
19881998
std::string content;
19891999
auto file = std::unique_ptr<NS_PROJ::File>(
@@ -2050,6 +2060,11 @@ void pj_load_ini(PJ_CONTEXT *ctx) {
20502060
ci_equal(value, "ON") || ci_equal(value, "YES") ||
20512061
ci_equal(value, "TRUE");
20522062
}
2063+
else if (native_ca == nullptr && key == "native_ca"){
2064+
ctx->native_ca =
2065+
ci_equal(value, "ON") || ci_equal(value, "YES") ||
2066+
ci_equal(value, "TRUE");
2067+
}
20532068
}
20542069

20552070
pos = content.find_first_not_of("\r\n", eol);

src/networkfilemanager.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,13 @@ static std::string pj_context_get_bundle_path(PJ_CONTEXT *ctx) {
15951595
return ctx->ca_bundle_path;
15961596
}
15971597

1598+
#if CURL_AT_LEAST_VERSION(7, 71, 0)
1599+
static bool pj_context_get_native_ca(PJ_CONTEXT *ctx) {
1600+
pj_load_ini(ctx);
1601+
return ctx->native_ca;
1602+
}
1603+
#endif
1604+
15981605
// ---------------------------------------------------------------------------
15991606

16001607
CurlFileHandle::CurlFileHandle(PJ_CONTEXT *ctx, const char *url, CURL *handle)
@@ -1622,7 +1629,19 @@ CurlFileHandle::CurlFileHandle(PJ_CONTEXT *ctx, const char *url, CURL *handle)
16221629
#if defined(SSL_OPTIONS)
16231630
// https://curl.se/libcurl/c/CURLOPT_SSL_OPTIONS.html
16241631
auto ssl_options = static_cast<long>(SSL_OPTIONS);
1632+
#if CURL_AT_LEAST_VERSION(7, 71, 0)
1633+
if (pj_context_get_native_ca(ctx)) {
1634+
ssl_options = ssl_options | CURLSSLOPT_NATIVE_CA;
1635+
}
1636+
#endif
16251637
CHECK_RET(ctx, curl_easy_setopt(handle, CURLOPT_SSL_OPTIONS, ssl_options));
1638+
#else
1639+
#if CURL_AT_LEAST_VERSION(7, 71, 0)
1640+
if (pj_context_get_native_ca(ctx)){
1641+
CHECK_RET(ctx, curl_easy_setopt(handle, CURLOPT_SSL_OPTIONS,
1642+
(long)CURLSSLOPT_NATIVE_CA));
1643+
}
1644+
#endif
16261645
#endif
16271646

16281647
const auto ca_bundle_path = pj_context_get_bundle_path(ctx);

src/proj_internal.h

+1
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ struct pj_ctx {
820820
std::string endpoint{};
821821
projNetworkCallbacksAndData networking{};
822822
std::string ca_bundle_path{};
823+
bool native_ca=false;
823824
projGridChunkCache gridChunkCache{};
824825
TMercAlgo defaultTmercAlgo =
825826
TMercAlgo::PODER_ENGSAGER; // can be overridden by content of proj.ini

0 commit comments

Comments
 (0)