You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@qpid.apache.org by Jeff Donner <jd...@morphodetection.com> on 2016/08/09 03:39:51 UTC

Getting a client onto the qpidd broker via Proton C++, mutually authenticated with SSL. Or SASL.

Hi -

  What is some C++ code to get a client /onto the broker/ via SSL, with Proton, and mutually authenticated? Assuming that I have all the needed .pem or certutil .db files? I prefer peer-to-peer (certificate exchange) rather than an internal root CA, though I can do that too if need be.

There's an example in this mailing list thread:

http://qpid.2158936.n2.nabble.com/EXTERNAL-authentication-and-peer-certificates-td6270012.html#a6293640,

but that particular qpid-perf client probably isn't applicable to Proton (it's not in the source) and I'm not convinced that Proton accepts the QPID_* env. vars. (Does Proton accept those, btw? Or is they only for the older C++ client? I don't find them in the Proton source.) I tried the same setup with the  examples/cpp/client.cpp example with the same env vars set and had no luck:

> ssl-play$ ./client -a amqps://0.0.0.0:5671/example
> amqp:connection:framing-error: SSL Failure: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate

I gather that examples/cpp/ssl_client_cert.cpp is the most relevant example (in 0.12.1,2 -- though I can go to 0.13, or 0.14 if that's easier), but it deals in .pem files, how would you make it use certutil .db files, so as to handle clients with multiple, different certs?


Here's the SSL-configuration part of examples/cpp/ssl_client_cert.cpp:

  void on_start(proton::event &e) {
    // "EXTERNAL", where authentication is implicit in the context (e.g.,
    // for protocols already using IPsec or TLS)
    //
    // Configure listener.  Details vary by platform.
    ssl_certificate server_cert = platform_certificate("tserver", "tserverpw");
    std::string client_CA = platform_CA("tclient");
    // Specify an SSL domain with CA's for client certificate verification.
    ssl_server_options srv_ssl(server_cert, client_CA);
    connection_options server_opts;
    server_opts.ssl_server_options(srv_ssl).handler(&s_handler);
    server_opts.allowed_mechs("EXTERNAL");
    e.container().server_connection_options(server_opts);

    // Configure client.
    ssl_certificate client_cert = platform_certificate("tclient", "tclientpw");
    std::string server_CA = platform_CA("tserver");
    ssl_client_options ssl_cli(client_cert, server_CA);
    connection_options client_opts;
    client_opts.ssl_client_options(ssl_cli).allowed_mechs("EXTERNAL");
    // Validate the server certificate against this name:
    client_opts.peer_hostname("test_server");
    e.container().client_connection_options(client_opts);

    s_handler.inbound_listener = e.container().listen(url);
    e.container().open_sender(url);
  }


// Support utils:
// Just the certificate.pem
std::string platform_CA(const std::string &base_name) {
    return g_cert_directory + base_name + "-certificate.pem";
}

// The certificate and the private key
ssl_certificate platform_certificate(const std::string &base_name,
                                     const std::string &passwd) {
    return ssl_certificate(g_cert_directory + base_name + "-certificate.pem",
                           g_cert_directory + base_name + "-private-key.pem",
                           passwd);
}

Any help greatly appreciated.

Thanks,
Jeff


Re: Getting a client onto the qpidd broker via Proton C++, mutually authenticated with SSL. Or SASL.

Posted by Cliff Jansen <cl...@gmail.com>.
Hi Jeff,

Further to Jakub's excellent reply...

If both sides are authenticating each other, each side must provide an
appropriate certificate (with private key), and use a separate
database/collection of root certificates (usually without private key
info) to verify the peer's certificate.

That "collection" could be a single CA, a possibility you can live
with but don't prefer.  Alternatively it could be the whole set of
public self-signed X509 certificates (without private key) that you
choose to trust.

For Proton on Posix systems, which use OpenSSL, that collection could
be all the individual PEM files concatenated together into a single
file (for a smaller set), or it could be a directory created (or
indexed) with the OpenSSL "rehash" command from the individual PEM
files (for a larger set).

For Proton on Windows, which use SChannel, the self-signed certificate
collection could be grouped in a specific system certificate store or
all imported into a single PKCS12 format file.

Cliff

On Tue, Aug 9, 2016 at 2:42 PM, Jakub Scholz <ja...@scholz.cz> wrote:
> Hi Jeff,
>
> The QPID_* variables and the certutil databases work only with the Qpid
> Messaging C++ API (
> http://qpid.apache.org/components/messaging-api/index.html) or with the
> Qpid C++ broker. They are not supported by Proton's C++ API - you really
> have to use PEM files directly. However, the trusted peer / trusted CA
> concept which is discussed in the old discussion you linked is part of the
> broker setup. So as long as your broker is still the C++ broker / qpidd,
> you can easily use Proton with trusted peer certificates.
>
> Here is some example code which has Proton C++ client connecting to Qpid
> C++ broker with SSL client authentication:
> https://github.com/Eurex-Clearing-Messaging-Interfaces/C-Code-Examples
>
> Regards
> Jakub
>
>
> On Tue, Aug 9, 2016 at 5:39 AM, Jeff Donner <jd...@morphodetection.com>
> wrote:
>
>> Hi -
>>
>>   What is some C++ code to get a client /onto the broker/ via SSL, with
>> Proton, and mutually authenticated? Assuming that I have all the needed
>> .pem or certutil .db files? I prefer peer-to-peer (certificate exchange)
>> rather than an internal root CA, though I can do that too if need be.
>>
>> There's an example in this mailing list thread:
>>
>> http://qpid.2158936.n2.nabble.com/EXTERNAL-authentication-
>> and-peer-certificates-td6270012.html#a6293640,
>>
>> but that particular qpid-perf client probably isn't applicable to Proton
>> (it's not in the source) and I'm not convinced that Proton accepts the
>> QPID_* env. vars. (Does Proton accept those, btw? Or is they only for the
>> older C++ client? I don't find them in the Proton source.) I tried the same
>> setup with the  examples/cpp/client.cpp example with the same env vars set
>> and had no luck:
>>
>> > ssl-play$ ./client -a amqps://0.0.0.0:5671/example
>> > amqp:connection:framing-error: SSL Failure: error:14094412:SSL
>> routines:ssl3_read_bytes:sslv3 alert bad certificate
>>
>> I gather that examples/cpp/ssl_client_cert.cpp is the most relevant
>> example (in 0.12.1,2 -- though I can go to 0.13, or 0.14 if that's easier),
>> but it deals in .pem files, how would you make it use certutil .db files,
>> so as to handle clients with multiple, different certs?
>>
>>
>> Here's the SSL-configuration part of examples/cpp/ssl_client_cert.cpp:
>>
>>   void on_start(proton::event &e) {
>>     // "EXTERNAL", where authentication is implicit in the context (e.g.,
>>     // for protocols already using IPsec or TLS)
>>     //
>>     // Configure listener.  Details vary by platform.
>>     ssl_certificate server_cert = platform_certificate("tserver",
>> "tserverpw");
>>     std::string client_CA = platform_CA("tclient");
>>     // Specify an SSL domain with CA's for client certificate verification.
>>     ssl_server_options srv_ssl(server_cert, client_CA);
>>     connection_options server_opts;
>>     server_opts.ssl_server_options(srv_ssl).handler(&s_handler);
>>     server_opts.allowed_mechs("EXTERNAL");
>>     e.container().server_connection_options(server_opts);
>>
>>     // Configure client.
>>     ssl_certificate client_cert = platform_certificate("tclient",
>> "tclientpw");
>>     std::string server_CA = platform_CA("tserver");
>>     ssl_client_options ssl_cli(client_cert, server_CA);
>>     connection_options client_opts;
>>     client_opts.ssl_client_options(ssl_cli).allowed_mechs("EXTERNAL");
>>     // Validate the server certificate against this name:
>>     client_opts.peer_hostname("test_server");
>>     e.container().client_connection_options(client_opts);
>>
>>     s_handler.inbound_listener = e.container().listen(url);
>>     e.container().open_sender(url);
>>   }
>>
>>
>> // Support utils:
>> // Just the certificate.pem
>> std::string platform_CA(const std::string &base_name) {
>>     return g_cert_directory + base_name + "-certificate.pem";
>> }
>>
>> // The certificate and the private key
>> ssl_certificate platform_certificate(const std::string &base_name,
>>                                      const std::string &passwd) {
>>     return ssl_certificate(g_cert_directory + base_name +
>> "-certificate.pem",
>>                            g_cert_directory + base_name +
>> "-private-key.pem",
>>                            passwd);
>> }
>>
>> Any help greatly appreciated.
>>
>> Thanks,
>> Jeff
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
For additional commands, e-mail: users-help@qpid.apache.org


Re: Getting a client onto the qpidd broker via Proton C++, mutually authenticated with SSL. Or SASL.

Posted by Jakub Scholz <ja...@scholz.cz>.
Hi Jeff,

The QPID_* variables and the certutil databases work only with the Qpid
Messaging C++ API (
http://qpid.apache.org/components/messaging-api/index.html) or with the
Qpid C++ broker. They are not supported by Proton's C++ API - you really
have to use PEM files directly. However, the trusted peer / trusted CA
concept which is discussed in the old discussion you linked is part of the
broker setup. So as long as your broker is still the C++ broker / qpidd,
you can easily use Proton with trusted peer certificates.

Here is some example code which has Proton C++ client connecting to Qpid
C++ broker with SSL client authentication:
https://github.com/Eurex-Clearing-Messaging-Interfaces/C-Code-Examples

Regards
Jakub


On Tue, Aug 9, 2016 at 5:39 AM, Jeff Donner <jd...@morphodetection.com>
wrote:

> Hi -
>
>   What is some C++ code to get a client /onto the broker/ via SSL, with
> Proton, and mutually authenticated? Assuming that I have all the needed
> .pem or certutil .db files? I prefer peer-to-peer (certificate exchange)
> rather than an internal root CA, though I can do that too if need be.
>
> There's an example in this mailing list thread:
>
> http://qpid.2158936.n2.nabble.com/EXTERNAL-authentication-
> and-peer-certificates-td6270012.html#a6293640,
>
> but that particular qpid-perf client probably isn't applicable to Proton
> (it's not in the source) and I'm not convinced that Proton accepts the
> QPID_* env. vars. (Does Proton accept those, btw? Or is they only for the
> older C++ client? I don't find them in the Proton source.) I tried the same
> setup with the  examples/cpp/client.cpp example with the same env vars set
> and had no luck:
>
> > ssl-play$ ./client -a amqps://0.0.0.0:5671/example
> > amqp:connection:framing-error: SSL Failure: error:14094412:SSL
> routines:ssl3_read_bytes:sslv3 alert bad certificate
>
> I gather that examples/cpp/ssl_client_cert.cpp is the most relevant
> example (in 0.12.1,2 -- though I can go to 0.13, or 0.14 if that's easier),
> but it deals in .pem files, how would you make it use certutil .db files,
> so as to handle clients with multiple, different certs?
>
>
> Here's the SSL-configuration part of examples/cpp/ssl_client_cert.cpp:
>
>   void on_start(proton::event &e) {
>     // "EXTERNAL", where authentication is implicit in the context (e.g.,
>     // for protocols already using IPsec or TLS)
>     //
>     // Configure listener.  Details vary by platform.
>     ssl_certificate server_cert = platform_certificate("tserver",
> "tserverpw");
>     std::string client_CA = platform_CA("tclient");
>     // Specify an SSL domain with CA's for client certificate verification.
>     ssl_server_options srv_ssl(server_cert, client_CA);
>     connection_options server_opts;
>     server_opts.ssl_server_options(srv_ssl).handler(&s_handler);
>     server_opts.allowed_mechs("EXTERNAL");
>     e.container().server_connection_options(server_opts);
>
>     // Configure client.
>     ssl_certificate client_cert = platform_certificate("tclient",
> "tclientpw");
>     std::string server_CA = platform_CA("tserver");
>     ssl_client_options ssl_cli(client_cert, server_CA);
>     connection_options client_opts;
>     client_opts.ssl_client_options(ssl_cli).allowed_mechs("EXTERNAL");
>     // Validate the server certificate against this name:
>     client_opts.peer_hostname("test_server");
>     e.container().client_connection_options(client_opts);
>
>     s_handler.inbound_listener = e.container().listen(url);
>     e.container().open_sender(url);
>   }
>
>
> // Support utils:
> // Just the certificate.pem
> std::string platform_CA(const std::string &base_name) {
>     return g_cert_directory + base_name + "-certificate.pem";
> }
>
> // The certificate and the private key
> ssl_certificate platform_certificate(const std::string &base_name,
>                                      const std::string &passwd) {
>     return ssl_certificate(g_cert_directory + base_name +
> "-certificate.pem",
>                            g_cert_directory + base_name +
> "-private-key.pem",
>                            passwd);
> }
>
> Any help greatly appreciated.
>
> Thanks,
> Jeff
>
>