Njål Arne Gjermundshaug Njål Arne Gjermundshaug - 2 months ago 29
C++ Question

Poco + OpenSSL + CA PEM : "Unacceptable certificate" error for 1 out of 2 identical sites

I am trying to do a SSL handshake with

www1.filemail.com
. I am using cURL's
cacert.pem
, but I am getting this error:

Unacceptable certificate from 188.138.81.30: application verification failure


Making the handshake against any other HTTPS website works - including
www2.filemail.com
.
www1
and
www2
should be identically configured - and they both work fine in all browsers. They also test fine here (identical certificates and intermediary certificates are sent out for both sites):



Why am I getting this problem with
www1
using OpenSSL and the
cacert.pem
file?

There has to be a difference in the certificate setup of www1 and www2. I have tested with a myriad of tools (openssl, ssllabs etc.) to try to pinpoint the difference - but I always get the exact same results for both sites (except when running my code)

What am I missing here? What's the difference between the sites?

(It should be noted that we are using a relatively cheap wildcard certificate provided by RapidSSL - so I'm guessing it has something to do with intermediate or cross-root certificates - but everything seems to be in order when testing with the tools mentioned above.)




Code:

Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pCert = new Poco::Net::ConsoleCertificateHandler(false);
Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "C:\\cacert.pem", Poco::Net::Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(0, pCert, pContext);

URI uri("https://www1.filemail.com");
Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()));
ss.completeHandshake();

Answer

G√ľnter Obiltschnig helped me out via POCO@Github and got it working by replacing

Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()));

with

Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()), uri.getHost());

(including the host name in the constructor of SecureStreamSocket - it is used for certificate verification)

From the POCO documentation:

SecureStreamSocket(
    const SocketAddress & address,
    const std::string & hostName
);

//Creates a secure stream socket using the default client SSL context and connects it to the socket specified by address.
//The given host name is used for certificate verification <=======

I still do not know the exact difference in config between www1 and www2 are, would love if someone could enlighten me on this.