pocoproject / poco

The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
https://pocoproject.org
Other
8.49k stars 2.18k forks source link

Problem with POCO HTTPS request on Android app #4698

Open AnDevi opened 2 months ago

AnDevi commented 2 months ago

I'm trying to use POCO https requests on Android app. I'm using poco 1.10.1 (I built poco with BoringSSL instead of OpenSSL) and my setup for SSL looks like this:

Poco::Net::initializeSSL();
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert = new Poco::Net::ConsoleCertificateHandler(false);
SSLContext = new Context(Context::TLSV1_2_CLIENT_USE, "", Context:: VERIFY_STRICT, 9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(0, ptrCert, SSLContext);

after https request I'm still getting error error:SSL Exception: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED, code: 0, what: SSL Exception

Anyone has idea what else should be configured to make it work ?

micheleselea commented 2 months ago

try using new Context(Context::CLIENT_USE, "", Context:: VERIFY_NONE

AnDevi commented 2 months ago

That works, but I think it's not the solution, I don't want to skip security. ;(

micheleselea commented 2 months ago

You are not skipping security: if you look Context:: VERIFY_NONE Same as VERIFY_RELAXED. Context::VERIFY_RELAXED /// Client: The server certificate is verified, if one is provided. /// If the verification process fails, the TLS/SSL handshake is /// immediately terminated with an alert message containing the /// reason for the verification failure.

The verification is failing because you cannot verify the certificate the server sent to you to check if it's a valid certificate. You can handle it using Poco::Net::InvalidCertificateHandler on Poco::Net::SSLManager::instance().initializeClient

the other thing you can do is to create a client context that has the "caLocation" set with a PEM file containing all valid certificate authority. For example you can, for example, this https://curl.se/docs/caextract.html

AnDevi commented 2 months ago

For VERIFY_NONE I can see:

Client: If not using an anonymous cipher (by default disabled), the server will send a certificate which will be checked, but the result of the check will be ignored. so using it still seems to me like something dangerous.

What do you mean by that You can handle it using Poco::Net::InvalidCertificateHandler ?

You mean handling it this way:

class MyCertificateHandler : public Poco::Net::InvalidCertificateHandler {
public:
    MyCertificateHandler(bool handleErrorsOnServerSide) : Poco::Net::InvalidCertificateHandler(handleErrorsOnServerSide) {}

    void onInvalidCertificate(const void* pSender, Poco::Net::VerificationErrorArgs& errorCert) override {
        EELogError("Invalid certificate encountered!");
        errorCert.setIgnoreError(true);
    }
};

Handling it by errorCert.setIgnoreError(true); but it also seems tricky and unsafe.

Or you meant something else ?

micheleselea commented 2 months ago

Context::VERIFY_STRICT and VERIFY_RELAXED and VERIFY_ONCE for client use it's the same, so use what I suggested with one of that, for example VERIFY_RELAXED