I'm trying to use the POCO libraries to write a program that makes an HTTPS request to a server. For testing purposes, I'm connecting to a server which has a self-signed certificate, and I want to allow the client to connect anyway. To allow that to happen, I've attempted to install an InvalidCertificateHandler
which is an instance of AcceptCertificateHandler
- which I thought would accept the certificate even though it's not signed. Here's the code I'm using:
try {
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pAcceptCertHandler =
new Poco::Net::AcceptCertificateHandler(true);
Poco::Net::Context::Ptr pContext =
new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "",
"","",Poco::Net::Context::VERIFY_RELAXED,
9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
SSLManager::instance().initializeClient(NULL, pAcceptCertHandler, pContext);
Poco::Net::HTTPSClientSession theSess(myHostName,myHostPort);
// Create the HTTP request object
Poco::Net::HTTPRequest request("POST",
"https://myservername.com/MockServlet/activateEnc","1.1");
// Send the request
std::cout << "Debug point A" << std::endl;
std::ostream& aStream = theSess.sendRequest(request);
std::cout << "Debug point B" << std::endl;
if (aStream.fail()) {
std::cout << "Fail to send HTTP request for activateEnc" << std::endl;
return WSERR_CONNECTION_ERR;
}
} catch (Poco::Exception& exc) {
std::cout << "Exception caught while attempting to connect." << std::endl;
std::cerr << exc.displayText() << std::endl;
return WSERR_CONNECTION_ERR;
}
When I run this code, I get the following output:
Debug point A
Exception caught while attempting to connect.
Certificate validation error: Unacceptable certificate from myservername.com: application verification failure
My expectation was that since I'm using the AcceptCertificateHandler, the certificate would be accepted even though it is not valid. What might I be doing wrong?
A couple notes:
- In the Context object constructor call, I'm passing empty strings for privateKeyFile, certificateFile, and caLocation arguments. The reason I did this is because I think that as a client I don't need a private key, client certificate, or certificate authority certificates. Maybe this is the problem?
- In the call to initializeClient, I'm passing NULL as the PrivateKeyPasshraseHandler - because I'm not using a private key for the client.
- I'm not calling Context::useCertificate() before using the Context object. The docs say you need to call either userCertificate() or usePrivateKey(), but I wasn't sure what to pass or if this was required for client, or only for a server. Maybe this is the problem?