Overview
Features
Download
Documentation
Community
Add-Ons & Services

POCO NetSSL Class Context

Please post support and help requests here.

POCO NetSSL Class Context

Postby nvpacific » 08 Feb 2011, 01:31

In the POCO documentation for the Context class, they mention 2 overloaded constructors. The first takes a directory path for 'caLocation' and 'false' for 'loadDefaultCAs' and the second constructor takes a blank string for path and 'true' for 'loadDefaultCAs'.

What we would like to do is to pass 'false' for 'loadDefaultCAs' and then use our certificate that is statically complied into our program and read as a string buffer internally.

So in this case, we pass in a blank string for path in the Context constructor since we do not have the certificate as a hard disk file. Also we pass 'false' for 'loadDefaultCAs'. After that we call 'useCertificate(..)' to pass in our x509Certificate pointer.

What ends up happening is that the 'InvalidCertificateHandler(..)' get called. If I choose to ignore the error then everything works out OK when VerifyPeerCertificate is called. If I do not implement this handler, I fail.

My question is: Is there a way to pass in the Certificate as a buffer pointer without incurring an invalid certificate error? What should we pass in the Context constructor for this case? We are NOT using default CAs and also we not loading the certificate from a disk file. Instead we have it compiled into our code and we want to pass a pointer to a buffer containing this certificate. Lastly, we do not want to receive an 'onInvalidCertificate' call.
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby guenter » 08 Feb 2011, 22:57

The invocation of InvalidCertificateHandler has nothing to do with the in-memory certificate you pass to the context, which is used to encrypt the connection and to authenticate the client against the server, if the server requires it. The invocation is caused by a failure to validate the certificate that was presented by the server. This can have different reasons:
  • the server uses a self-signed certificate. Unless you add your own certificate to the list of OpenSSL root certificates used to verify the certificate chain, validation of a self-signed certificate will always fail.
  • the server uses a valid certificate, but the root CA certificate is not present in OpenSSL's default certificate (if loadDefaultCAs is true) or in your own root certificate list (if loadDefaultCAs is false) or you don't provide a root certificate list
guenter
 
Posts: 1119
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: POCO NetSSL Class Context

Postby nvpacific » 09 Feb 2011, 00:32

Günter

Thanks very much.

Our certificate is generated dynamically as it part of our code. So, for example, I can generate a pointer to a X509Certificate object.

So my questions are

1. How do I generate my own root certificate list and then add this certificate to that list?

2. How do I pass this root certificate list to POCO so it knows?

Thanks
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby nvpacific » 09 Feb 2011, 00:48

Actually, this is what I do: (The _cert509 is a pointer to a X509Certificate object thats dynamically created)

_ptrCert = new SSL_RejectCertificateHandler(false);
_ptrContext = new Net::Context(Net::Context::CLIENT_USE, "", Poco::Net::Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
if(!_ptrContext || !_ptrCert)
return false;

_ptrContext->useCertificate(*_cert509);
Poco::Net::SSLManager::instance().initializeClient(0, _ptrCert, _ptrContext);

So I am passing our CA root Certficate (which is actually, Entrust.netSecureServerCertificationAuthority.pem) using "useCertificate".

But I still get the call to invalidCertificateHandler(...) which says, 'certificate not trusted'.
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby nvpacific » 09 Feb 2011, 00:57

Just one additional comment.

My 'InvalidCertificateHandler' get called twice.

The first time it says ..."unable to get local issuer certificate"

The second time it says..."certificate not trusted"
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby guenter » 09 Feb 2011, 14:35

You should add the root certificate with addChainCertificate(). If this is the certificate you use to sign the dynamically created certificate, and you've got that from a CA, then you'll also need to add the CA's certificate with addChainCertificate(), so that the entire chain from the dynamically created certificate to the root certificate is complete. Also, please note that the certificate errors come from the server certificate, so you need to make sure that you have a complete server certificate chain as well.
guenter
 
Posts: 1119
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: POCO NetSSL Class Context

Postby nvpacific » 09 Feb 2011, 23:38

I tried this but did not succeed. Maybe I am making some mistake. I call useCertificate with the root Entrust CA certificate. Then I call addCertificateChain with 3 other certificates that are part of the chain.

However what puzzles me is the difference between these 2 cases:

Case A: If you hardcode the file path and the file contains just the Entrust certificate it works fine WITHOUT calling the invalid cert handler.

Case B : If I pass the very same certificate as a buffer pointer to useCertificate, then invalid cert handler gets called.

It seems to me that both cases are equivalent. The only difference being the manner in which the certificate is passed.
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby nvpacific » 21 Feb 2011, 19:23

Problem completely solved!

Do NOT use POCO code ! USE OPENSSL Directly.

1. Load the certificate to a buffer.

2. Create a new context object: _ptrContext = new Net::Context( Net::Context::CLIENT_USE, "" );

3. Next get the openSSL context object and call openSSL function to add to the cert store:

SSL_CTX* pOpenSSLContext = _ptrContext->sslContext();
X509_STORE* pCertStore = SSL_CTX_get_cert_store( pOpenSSLContext );
X509_STORE_add_cert( pCertStore, (X509*) _RootCert->certificate() );

This completely solves the problem. No need for addChainCertificate(..) and all that other stuff !!!
nvpacific
 
Posts: 10
Joined: 27 Jan 2011, 05:02

Re: POCO NetSSL Class Context

Postby delphi13 » 14 Jun 2012, 01:26

As a followup, I couldn't get the Poco calls to work for loading a public root certificate from memory either.

If I use the Context constructor to specify the caLocation file, all works great (loading a single certificate).

However if I call Net::Context::useCertificate
Poco::Crypto::X509Certificate X509Cert(SSCert);
ptrContext->useCertificate(X509Cert);
future HTTPSClientSession::sendRequest calls error with "certificate verify failed"

Many thanks to nvpacific for his work around post.
I also used the direct OpenSSL calls and it works fine.
Here's some slightly expanded code:

const unsigned char HTTPSCertificate[]=
"-----BEGIN CERTIFICATE-----\n\
...
-----END CERTIFICATE-----";

//create BioCert from read only memory
BIO *BioCert=BIO_new_mem_buf(const_cast<unsigned char*>(HTTPSCertificate),-1);
X509 *X509Cert=PEM_read_bio_X509(BioCert,NULL,NULL,NULL);

SSL_CTX* pOpenSSLContext=ptrContext->sslContext();
X509_STORE* pCertStore=SSL_CTX_get_cert_store(pOpenSSLContext);
X509_STORE_add_cert(pCertStore,X509Cert);

X509_free(X509Cert);
BIO_free(BioCert);

Perhaps I just don't know enough about SSL, but I can't understand why it works from the file just fine.

Hope this helps someone else.
delphi13
 
Posts: 6
Joined: 12 Jul 2010, 04:12


Return to Support

Who is online

Users browsing this forum: No registered users and 3 guests

cron