SSL with POCO

Admittedly, the topic of this post is very specific but I hope it will still be of some value for some people.The task for today is to setup SSL server and client with POCO framework classes. I will leave out the whole certificate managing issues and just assume that the right files are at hand.

The SSL related part of  the POCO libraries essentially wraps the OpenSSL library into a nice object-oriented interface. When you know OpenSSL, you can instantly relate to classes like Poco::Net::Context, or the …Handler classes (if you replace “handler” with “callback”).

“SSL” stands for Secure Socket Layer, so the first thing to discover is class Poco::Net::SecureServerSocket. As you would expect, this class is derived from Poco::Net::ServerSocket, extending it only with SSL related stuff. And sure enough, some constructors of Poco::Net::ServerSocket take a Poco::Net::ContextPtr as argument.

But why only some constructors? Since there is no setContext method, there must be some other mechanism in place by which SecureServerSockets get their SSL context.

Introducing Poco::Net::SSLManager. From the API docs:

SSLManager is a singleton for holding the default server/client Context and handling callbacks for certificate verification errors and private key passphrases.

Proper initialization of SSLManager is critical.

Aha! So all the constructors of SecureServerSocket that do not take Context pointers simply get it from the SSLManager singleton.

But how to initialize SSLManager?

1. The POCO Way:

If you developed your application with POCO from the ground up there probably exists a sub-class of Poco::Application, and all the configuration is handled by the built-in configuration classes.

With this in place, all you have to do is to add the proper ssl configuration elements:

openSSL.server.privateKeyFile = /path/to/key/file
openSSL.server.certificateFile = /path/to/certificate/file
openSSL.server.verificationMode = none
openSSL.server.verificationDepth = 9
openSSL.server.loadDefaultCAFile = false
openSSL.server.cypherList = ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
openSSL.server.privateKeyPassphraseHandler.name = KeyFileHandler
openSSL.server.privateKeyPassphraseHandler.options.password = securePassword
openSSL.server.invalidCertificateHandler = AcceptCertificateHandler

2. Manually:

Depending on which side you are – client or server – you have to call SSLManager::initializeClient or  SSLManager::initializeServer. Both methods take three arguments:

  1. PrivateKeyPassphraseHandler pointer
  2. InvalidCertificateHandler pointer
  3. Context pointer

This is where it becomes a little bit tricky: If you try to instantiate a Context with a privateKey file in order to provide it as argument to the initialize… method, a PrivateKeyPassphraseHandler might be needed. This handler is fetched from the SSLManager singleton – which you are just about to initialize!.

This circular dependency between Context and SSLManager can be overcome e.g. if you call SSLManager::initializeServer first only with a PrivateKeyPassphraseHandler, a InvalidCertificateHandler and null Context pointer. Then instantiate the Context and call SSLManager::initializeServer again.

Now that SSL Manager is initialized we can use Secure… prefixed classes as we would used their non-SSL counterparts. As with SecureServerSocket, other Secure… classes are derieved from corresponding non-secure base classes.

Conclusion: Once you got around the initialization of SSLManager singelton, using SSL POCO classes is very easy and straight forward. Check it out!

4 thoughts on “SSL with POCO

  1. Interesting post! I have tried to implement a HTTPS server following your description but I have an issue when I try to connect to the server using Firefox 14.

    My application responds correctly to the requests.
    But as soon as the keep alive timeout elapses the application stops responding and the browser gives an error: “The connection to the server was reset while the page was loading”.

    Are you experiencing anything similar?

    This is part of my source code:

    class SSLInit {
    public:
    static void init() {
    Poco::Path mycert( Poco::Util::ServerApplication::instance().config().getString(“application.dir”) );
    mycert.append(“mycert.pem”);
    Poco::SharedPtr pConsoleHandler = new KeyConsoleHandler(true);
    Poco::SharedPtr pCertHandler = new AcceptCertificateHandler(true);
    SSLManager::instance().initializeServer(pConsoleHandler, pCertHandler, NULL);
    Context::Ptr pContext = new Context(Context::SERVER_USE, mycert.toString(), mycert.toString(), “”, Context::VERIFY_RELAXED, 9, false, “ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH”);
    SSLManager::instance().initializeServer(pConsoleHandler, pCertHandler, pContext);
    }
    };

    class HTTPSRequestHandler: public HTTPRequestHandler {
    (…)
    void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
    {
    Poco::Timestamp now;
    std::string dt(Poco::DateTimeFormatter::format(now, “%W, %e %b %y %H:%M:%S %Z”));

    response.setChunkedTransferEncoding(true);
    response.setContentType(“text/html”);

    std::ostream& ostr = response.send();
    ostr << "HTTPSRequestHandler powered by POCO C++ Libraries”;
    ostr << "”;
    ostr << "”;
    ostr << "Hello HTTPS” << dt;
    ostr << "”;
    }
    };

    class HTTPSServer : public Poco::Util::ServerApplication
    {
    (…)
    int main(const std::vector& args)
    {
    SSLInit::init();
    SecureServerSocket scs(10444);

    int maxQueued = 100;
    int maxThreads = 16;
    HTTPServerParams* pParams = new HTTPServerParams;
    pParams->setMaxQueued(maxQueued);
    pParams->setMaxThreads(maxThreads);
    pParams->setKeepAlive(true);
    pParams->setKeepAliveTimeout(Poco::Timespan(5,0));

    HTTPServer scv(new HTTPSRequestHandlerFactory(), scs, pParams);
    scv.start();
    // wait for CTRL-C or kill
    waitForTerminationRequest();
    // Stop the HTTPServer
    scv.stop();

    return Application::EXIT_OK;
    }
    };

  2. Does the manual way of initialization with the circular dependency issue still seen in current version of Poco. I am using Poco 1.4.6.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s