0

I am using the asio C++ library. When creating a SSL server socket, I have the below working code based on the sample, for specifying the server certificates.

http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/ssl/server.cpp

  context_.set_options(
    boost::asio::ssl::context::default_workarounds
    | boost::asio::ssl::context::no_sslv2
    | boost::asio::ssl::context::single_dh_use);
   context_.set_password_callback(boost::bind(&server::get_password, this));
   context_.use_certificate_chain_file("server.pem");
   context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem);
   context_.use_tmp_dh_file("dh512.pem");

Is it possible to use the API somehow with a single certificate here, as opposed to loading 3 files as above?

tech74
  • 1,609
  • 1
  • 20
  • 39

2 Answers2

2

No, because an SSL socket has to have a certificate and a private key. You cannot just have a certificate, because you have to decrypt a replies from the client using the private key.

There might be possibilities to omit the DH usage on your server. And another one is that you can have both the private key and the certificate in the same file, if it is a question on how many file opening queries to the OS to do. However, I cannot image the situation where it can matter for the server.

As a reply to the comment, regarding how to use one file for both private key and certificate. There is no straight forward way to do it, because Boost Asio is not a crypto library, but a network framework. To do that you need to employ something like OpenSSL or similar libraries and something like PKCS#12 archive format, where you have several object in one file. Use the former to parse the latter. Forward raw data out of those objects to use_private_key and use_certificate_chain through const_buffer with the format set probably to ASN.1. And voila! Zillion times less maintainable, harder comprehensible, unnecessary, but works. Another trivially hacky approach is to put both data in PEM bundles (one file with the private key and the certificate PEM-encoded), than manually find PEM armor (-----BEGIN..., -----END), extract the object data and pass this to use_private_key, use_certificate_chain correspondingly specifying PEM as format.

Community
  • 1
  • 1
Yuki
  • 3,857
  • 5
  • 25
  • 43
1

It turns out you just need to put the private key in the same file as the certificate and pass the same file to both

context_.use_certificate_chain_file("server.pem");
context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem);

The third file is not necessary in my case.

   context_.use_tmp_dh_file("dh512.pem");
tech74
  • 1,609
  • 1
  • 20
  • 39