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

Reply via email to