Search code examples
c++sslclientpoco

Unable to verify server certificate through Poco


I'm trying to implement certificate verification in my client. I'm always getting SSL Exception: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed after 893ms and I'm sure it is valid, tried getting google.com this way and failed. I am using RejectCertificateHandler because the documentation states:

A RejectCertificateHandler is invoked whenever an error occurs verifying the certificate. It always rejects the certificate.

A AcceptCertificateHandler is invoked whenever an error occurs verifying the certificate. It always accepts the certificate. Should be using for testing purposes only.

What am I doing wrong? Here's my code:

Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pAcceptCertHandler = new Poco::Net::RejectCertificateHandler(true);

Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(NULL, pAcceptCertHandler, pContext);

Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), pContext);
std::string path(uri.getPathAndQuery());

Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
initializeHttpGetRequest(request);
session.sendRequest(request);
session.setKeepAlive(true);

Poco::Timespan timespan(0, 0, 10, 0, 0);
session.setKeepAliveTimeout(timespan);

Poco::Net::HTTPResponse res;
std::istream & is = session.receiveResponse(res);

responseCode = res.getStatus();

Solution

  • After further research I've found out, that the built in OpenSSL with Mac OS doesn't have any CA certificate bundled (it doesn't use those inside the system Keychain). So whatever host you try to verify, fails even if the certificate is valid.

    I've exported those CA certificates into a single .pem file and bundled it with my application.

    Now when I create a context I use this method:

    NSString *rootCA = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"rootCA.pem"];
    Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", [rootCA UTF8String], verificationMode, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");