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

SSL certificate problem #445

Closed
hykzr opened this issue Sep 17, 2020 · 43 comments · Fixed by #717
Closed

SSL certificate problem #445

hykzr opened this issue Sep 17, 2020 · 43 comments · Fixed by #717

Comments

@hykzr
Copy link

hykzr commented Sep 17, 2020

SSL certificate problem: self signed certificate in certificate chain
SSL certificate problem: unable to get local issuer certificate

@COM8
Copy link
Member

COM8 commented Sep 18, 2020

Hi, thanks for reporting this.
Could you please provide a minimal sample for me to reproduce your problem.

@Vendicated
Copy link

Vendicated commented Sep 18, 2020

EDIT: This issue was fixed after deleting all CMake related folders and files and generating them again. Now it is working.
EDIT 2: Issue keeps reoccurring, I always have to repeat ^

Same issue for me. I am completely new to C++ so sorry if I may not be that competent!

Code:

#include <iostream>
#include <cpr/cpr.h>

int main(int argc, char **argv)
{
    auto res = cpr::Get(cpr::Url{"https://www.google.com"});

    std::cout << res.error.message << '\n';

    return 0;
}

Console Output: SSL certificate problem: unable to get local issuer certificate

CMakeLists.txt (I have no clue whether this is relevant so I am just going to include it! I just followed the readme in this repo)

cmake_minimum_required(VERSION 3.10)

project("stuff")

add_executable(app main.cpp)

include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/whoshuu/cpr.git GIT_TAG c8d33915dbd88ad6c92b258869b03aba06587ff9) # the commit hash for 1.5.0
FetchContent_MakeAvailable(cpr)

target_link_libraries(app PRIVATE cpr::cpr)

@COM8
Copy link
Member

COM8 commented Sep 19, 2020

@VenNeptury thanks!

What happens if you run:

$ ls -l /etc/ssl/certs/

@Vendicated
Copy link

@VenNeptury thanks!

What happens if you run:

$ ls -l /etc/ssl/certs/

It prints a lot of .pem files

❯ ls -l /etc/ssl/certs/
total 1364
lrwxrwxrwx 1 root root   64 Aug 23 18:23 ....
....

@hykzr
Copy link
Author

hykzr commented Sep 20, 2020

I find a way to solve it.
use cpr::VerifySsl(0) when making a request
cpr::Response r = cpr::Get(cpr::Url{ "https://github.com" },cpr::VerifySsl(0));

@COM8
Copy link
Member

COM8 commented Sep 21, 2020

@VenNeptury, ok.
And how about the following file:

/etc/pki/tls/certs/ca-bundle.crt

Does this one exist?

This is where libcurl expects the ca-bundle.

@xiao-huangren, thanks for your suggestion. But be aware, that with this you disable and more or less invalidate all the TLS authenticity.

@Vendicated
Copy link

Vendicated commented Sep 21, 2020

@VenNeptury, ok.
And how about the following file:

/etc/pki/tls/certs/ca-bundle.crt

Does this one exist?

This is where libcurl expects the ca-bundle.

@xiao-huangren, thanks for your suggestion. But be aware, that with this you disable and more or less invalidate all the TLS authenticity.

There is no such file, that file is at /etc/ssl/certs/ca-certificates.crt for my distro (I think that is the file at least? /etc/pki seems to be redhat exclusive). Should I symlink it to that location?

@COM8
Copy link
Member

COM8 commented Sep 21, 2020

Yes, you could try creating a symlink.
You can also try to see the output of the following command, in case you have libcurl-devel (Fedora) installed on your system.

$ curl-config --ca

This is where libcurl expects to find the ca-cert file.

@Vendicated
Copy link

Vendicated commented Sep 21, 2020

That command prints the proper location /etc/ssl/certs/ca-certificates.crt and this file exists. I also symlinked it to /etc/pki/tls/certs/ca-bundle.crt, but I am still getting the same error.

It is always fixed temporarily by deleting CMakeCache.txt and rebuilding everything for some reason

@slzatz
Copy link

slzatz commented Sep 21, 2020

I started using cpr yesterday for the first time so this could be my error but I have been unable to access https sites and found this issue, which seems related to my problem. So far every https site I try to access, I get a status code of 0, which I believe is a cancelled request. I can access those sites no problem with curl and I can get to those sites if I set cpr::VerifySsl(0) as suggested above. Running this on a current arch system and incorporated cpr into an existing project via FetchContent.

@COM8
Copy link
Member

COM8 commented Sep 22, 2020

@VenNeptury, interesting discovery. What distro are you using?

I might have to add additional CI runners for more distros to prevent those issues.

@Vendicated
Copy link

Exactly the same as described by slzatz, Arch Linux

@COM8
Copy link
Member

COM8 commented Sep 22, 2020

Aha, ok.
On fedora it worked for me with only creating a symlink to /etc/pki/tls/certs/ca-bundle.crt.

I'd say the problem here is, libcurl is not finding the ca bundle during compilation, because there a re only a few predefined directories for it.
Reference: https://stackoverflow.com/questions/48433182/define-ca-info-at-compile-time-for-libcurl

Since we are using libcurl with CMAKE and not their own build system, this could be interesting.

@phasmide
Copy link

Had the same error. Solved the issue on fedora 32 replacing:

include(FetchContent)
FetchContent_Declare(cpr
    GIT_REPOSITORY https://github.com/whoshuu/cpr.git
    GIT_TAG        v1.5.1
    GIT_SHALLOW    TRUE
)
FetchContent_MakeAvailable(cpr)

by

include(FetchContent)
FetchContent_Declare(cpr
    GIT_REPOSITORY https://github.com/whoshuu/cpr.git
    GIT_TAG        v1.5.1
    GIT_SHALLOW    TRUE
)
FetchContent_GetProperties(cpr)
if(NOT cpr_POPULATED)
  FetchContent_Populate(cpr)
  set(USE_SYSTEM_CURL ON CACHE BOOL "" FORCE)
  add_subdirectory(${cpr_SOURCE_DIR} ${cpr_BINARY_DIR})
endif()

@COM8
Copy link
Member

COM8 commented Sep 23, 2020

@phasmide, the same behaviour can be archived by setting USE_SYSTEM_CURL to ON during configuration (-DUSE_SYSTEM_CURL=ON).

With this you are requiring curl (libcurl) to be installed on your targets PC and this solution is less portable, since we depend on a well configured curl (libcurl) instance on the targets PC.

I (we) will have to figure out how to set the ca-bundle path during configuration of curl using CMAKE (ping @KingKili ).

@phasmide
Copy link

@phasmide, the same behaviour can be archived by setting USE_SYSTEM_CURL to ON during configuration (-DUSE_SYSTEM_CURL=ON).

Way simpler indeed.

With this you are requiring curl (libcurl) to be installed on your targets PC and this solution is less portable, since we depend on a well configured curl (libcurl) instance on the targets PC.

I understand that: my wording was ill-chosen:

Solved Circumvented the issue on fedora 32 replacing:

;)

I (we) will have to figure out how to set the ca-bundle path during configuration of curl using CMAKE (ping @KingKili ).

Can't this be always set to /etc/ssl/certs on Linux platforms?

Thank you for your response.

@COM8
Copy link
Member

COM8 commented Sep 23, 2020

Yes, but I currently do not know how :D

@dFohlen
Copy link

dFohlen commented Sep 25, 2020

Is there any news on this? It's a pretty critical problem.

@COM8
Copy link
Member

COM8 commented Sep 25, 2020

Currently not. I'm currently trying to understand how the curl CMake project works so I can fix this.

@COM8
Copy link
Member

COM8 commented Sep 27, 2020

A workaround for all of those with this issue (arch users?):

Example:

# Configure
$ cmake .. -DCURL_CA_BUNDLE="/home/user_name/Downloads/cacert.pem"
# Build
$ cmake --build .

The reason for this issue is the auto ca cret discovery fails on some systems.

@COM8
Copy link
Member

COM8 commented Oct 1, 2020

Can anybody confirm that installing ca-certificates fixes this issue?

For me on Manjaro, this fixed it.

Arch:

$ pacman -S ca-certificates

Once installed you have to perform a clean rebuild to force curl to search again for certificates.

$ cd cpr/build
$ rm -rf *
$ cmake ..
$ cmake --build .

@slzatz
Copy link

slzatz commented Oct 2, 2020

On plain vanilla arch. Since I had previously installed cpr through cmake FetchContent I deleted all the cpr and curl directories in _deps/ and rebuilt everything but unfortunately that did not work at least for connecting to the Compiler Explorer api. When I added back VerifySsl(0) I was able to connect again. (I already had the ca-certs installed.) I did this using current cpr trunk.

@COM8
Copy link
Member

COM8 commented Oct 5, 2020

Ok. Thanks for testing. I guess I cant get around setting up a pure Arch VM :)

@GiuseppeCesarano
Copy link
Contributor

Can anybody confirm that installing ca-certificates fixes this issue?

In my pure Arch installing ca-certificates fixes the issue.

@adventurist
Copy link

adventurist commented Mar 1, 2021

I've also fallen victim to this issue on an Ubuntu 20.04.2 system.

I have tried:

  • the system's update-ca-certificates command
  • symlinking /etc/ssl/certs/ca-certificates.crt to /etc/pki/tls/certs/ca-bundle.crt

I am temporarily settling on disabling verification. Will try to debug it some more.

Note: I don't have this issue on Manjaro

@christk1
Copy link
Contributor

christk1 commented Mar 3, 2021

I've also fallen victim to this issue on an Ubuntu 20.04.2 system.

I have tried:

* the system's `update-ca-certificates` command

* symlinking `/etc/ssl/certs/ca-certificates.crt` to `/etc/pki/tls/certs/ca-bundle.crt`

I am temporarily settling on disabling verification. Will try to debug it some more.

Note: I don't have this issue on Manjaro

I had the same problem, then I installed the latest commit (04f06b8) and it worked :)

@COM8 COM8 added this to the CPR 1.7.0 milestone Mar 19, 2021
@aliaksei135
Copy link

aliaksei135 commented Mar 28, 2021

I have had this issue on Ubuntu 20.04 running in WSL. Building cpr v1.6.0 with CMake FetchContent. I've also added this snippet in my build script, in case my project gets built on Windows:

    if(WIN32)
       set(WINSSL ON)
       set(OPENSSL OFF)
    else()
       set(WINSSL OFF)
       set(OPENSSL ON)
    endif()

Then refreshing my certs:

$ sudo apt-get remove ca-certificates
$ sudo apt-get install ca-certificates 
$ sudo update-ca-certificates

fixed it.

@COM8
Copy link
Member

COM8 commented Mar 28, 2021

With 1.6.0, CPR should auto detect the best SSL backend for your OS if you do not specify anything.

WINSSL and OPENSSL are internal variables. If you want to keep using your snippet try something like this:

if(WIN32)
    set(CPR_FORCE_WINSSL_BACKEND ON)
else()
    set(CPR_FORCE_OPENSSL_BACKEND ON)
endif()

@alpha-alpha-alpha
Copy link

I'm still having this issue on MSYS2.

@COM8
Copy link
Member

COM8 commented Jun 1, 2021

@AquaVirus could you please give me a little bit more context.

  • What version of cpr are you using?
  • Where did you get it from (git/vcpkg/conan/...)?
  • Please provide a full log or even better a small demo project so I can reproduce this

@alpha-alpha-alpha
Copy link

My bad, it's working on MSYS2. The issue was that I was using outdated DLLs.

@Alababdiy
Copy link

VerifySsl

it's worked ..

is that secure ?

@COM8
Copy link
Member

COM8 commented Aug 4, 2021

VerifySsl

it's worked ..

is that secure ?

Like always, it depends.
If you know what you are doing and you trust (knowing there won't be a man in the middle attack) the server/you validate the cert manually, you are accessing, sure why not.

If you just disable it to fix the missing cert file. NO!
There you should look into obtaining your own cert bundle and setting it in curl, like described here: #445 (comment)
Or fix your cert paths :)

@Alababdiy
Copy link

Alababdiy commented Aug 4, 2021

VerifySsl

it's worked ..
is that secure ?

Like always, it depends.
If you know what you are doing and you trust (knowing there won't be a man in the middle attack) the server/you validate the cert manually, you are accessing, sure why not.

If you just disable it to fix the missing cert file. NO!
There you should look into obtaining your own cert bundle and setting it in curl, like described here: #445 (comment)
Or fix your cert paths :)

it's not working .. Let me show you what i do :-

my project home tree like this
.
├── blocks.h
├── build
│   ├── bin
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── _deps
│   ├── lib
│   ├── Makefile
│   ├── package
│   ├── uploads
│   └── webhook.ratina
├── CMakeLists.txt
├── config.json
├── evaluator.h
├── functions.h
├── logs_pm2.sh
├── main.cc
├── messenger.h
├── models
│   └── model.json
├── package
│   ├── cacert.pem
│   └── cpr
├───── CMakeLists.txt
├───── CONTRIBUTING.md
├───── LICENSE
├───── README.md
├───── build
├───── cmake
├───── cpr
├───── cpr-config.cmake
├───── include
└───── test

|
├── README.md
└── update.sh

how i include cpr :-
project_home/CMakeLists.txt:-

....
add_subdirectory("package/cpr")
target_link_libraries(${CPR_LIBRARIES})
include_directories(${CPR_INCLUDE_DIRS})
...

Go to cpr and build with cacert file

cd package/cpr/build
rm -rf * 
cmake .. -DCURL_CA_BUNDLE="/root/webhook.ratina/package/cacert.pem"
cmake --build .

Go to my project and rebuild : -

cd project_home/build
cmake ..
make 

@COM8
Copy link
Member

COM8 commented Aug 9, 2021

Any reason you are not using FetchContent to include cpr?
https://github.com/whoshuu/cpr#cmake

@nonetrix
Copy link

A workaround for all of those with this issue (arch users?):

Example:

# Configure
$ cmake .. -DCURL_CA_BUNDLE="/home/user_name/Downloads/cacert.pem"
# Build
$ cmake --build .

The reason for this issue is the auto ca cret discovery fails on some systems.

Same here on Arch this fixed it for me, but not really an ideal fix, but werks so who cares ¯_(ツ)_/¯

@cieslarmichal
Copy link

Hello, I had same problem with ubuntu 21.04.

solution:
sudo apt-get remove ca-certificates
sudo apt-get install ca-certificates
sudo update-ca-certificates

@Dimon4eg
Copy link
Contributor

the same error on android:
SSL certificate problem: unable to get local issuer certificate

@Leon0402
Copy link
Contributor

Leon0402 commented Jan 9, 2022

I ran into this issue on Arch as well. I already had ca-certificates installed. I then played around a little bit with different urls, because I suspected this to be a server problem (my server is self signed). Now all of the sudden everything works and I can't reproduce the error anymore.
I don't really trust it to be fixed, but I'll see.

@fangzhou-xie
Copy link

I am using Fedora 35 with FetchContent and had the same issue. I used the following setup in CMakeLists.txt and seemed to solve the problem:

find_package(CURL 7.29 REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
set(YOURPROJECT_LIB_DEPS ${YOURPROJECT_LIB_DEPS} ${CURL_LIBRARIES})

find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
set(YOURPROJECT_LIB_DEPS ${YOURPROJECT_LIB_DEPS} ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})

Reference: here in #191 .

@Leon0402
Copy link
Contributor

Leon0402 commented Mar 24, 2022

I found out how to reproduce the issues and why this fails.

How to reproduce?

On the first configure it will always work. If you then configure again (without deleting the build folder) it will fail. If you delete the CMakeCache.txt and reconfigure it will work again.

So the issue is clearly something which involves cache variables

What is the issue?

In https://github.com/libcpr/cpr/blob/master/CMakeLists.txt#L208 we always set CURL_CA_BUNDLE to auto. This will be done on every call as the usage of INTERNAL will lead to the behavior that this is always overwritten no matter if it already has a value or not.

In https://github.com/curl/curl/blob/90dd1fc66401d5bb7814f4edeb16a06c925b1f1e/CMakeLists.txt#L862 this will trigger autodetect as expected and then the correct path is detected and written into the same variable CURL_CA_BUNDLE here: https://github.com/curl/curl/blob/90dd1fc66401d5bb7814f4edeb16a06c925b1f1e/CMakeLists.txt#L900

One line later though curl will set CURL_CA_BUNDLE_SET to True and therefore saves that curl already found the ca bundle.

On the next configure CPR will set CURL_CA_BUNDLE back to auto. But this time curl will not research the ca bundle, because it already did that the last time. So the CA_Bundle will be auto or to be more concrete unset, because curl will actually always unset it if it's set to auto.

How to fix it?

The easiest fix can be done in CPR here https://github.com/libcpr/cpr/blob/master/CMakeLists.txt#L208, just guard this

if(CURL_CA_BUNDLE STREQUAL "")
    set(CURL_CA_BUNDLE "auto" CACHE INTERNAL"")
endif()

So once ca bundle is found, cpr will not set it again. Works like a charm

Arguably this whole behavior could be seen as a flaw in curl. Mainly: Why do they use this variable for configuring auto mode instead of a separate variable.

So my recommendation would be: Temporarily fix this in CPR and release a new version, because this a huge issue. But at the same way also get in contact with curl maintainers as this really should be fixed on their side.

@COM8
Copy link
Member

COM8 commented Mar 24, 2022

Nice catch @Leon0402 and I also can confirm this behaviour!
Would you like to create a PR for this?
cpr 1.8.0 is feature complete and I'm currently testing it and finishing up the docs for the next release. I'm planing to release it this week if nothing comes up.

Also I would suggest something like:

if(NOT CURL_CA_BUNDLE_SET)
    set(CURL_CA_BUNDLE "auto" CACHE INTERNAL"")
endif()

Makes it a bit more reliable for your case.

@COM8
Copy link
Member

COM8 commented Mar 24, 2022

This allows people to set the bundle by hand if they want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.