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 <jdon...@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-unsubscr...@qpid.apache.org For additional commands, e-mail: users-h...@qpid.apache.org