chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.72k stars 1.19k forks source link

`use_certificate_chain()` fails with OpenSSL 3.2 on Windows #1414

Closed laudrup closed 5 months ago

laudrup commented 5 months ago

Adding a certificate to an asio::ssl::context fails on Windows with OpenSSL 3.2 with the error:

no start line (PEM routines) [asio.ssl:151584876]

Although the buffer being assigned does contain a valid start line. Interestingly, this only happens with OpenSSL 3.2 and only on Windows.

Digging a bit in the related code it seems like it fails here where ERR_GET_LIB() no longer returns ERR_LIB_PEM causing the code to continue and unconditionally set the error to PEM_R_NO_START_LINE as returned by OpenSSL. From the OpenSSL documentation it is not entirely clear to me if checking the error code combined with the library that returned the error is guaranteed to work on all versions, but it seems like a reasonable assumption.

This looks very much like it could be a regression in OpenSSL, maybe related to this commit but I haven't looked into that in detail.

Before digging more into the OpenSSL code and potentially filing a bug report there I would appreciate getting some input here first.

Here is a small example that shows the issue:

#include <iostream>
#include <string>

#include <boost/asio/ssl.hpp>

const std::string test_certificate =
  "-----BEGIN CERTIFICATE-----\n"
  "MIIDbzCCAlegAwIBAgIUaIFyQGvp8/q1J7Lun753bvRBjKQwDQYJKoZIhvcNAQEL\n"
  "BQAwRzELMAkGA1UEBhMCREsxEzARBgNVBAcMCkNvcGVuaGFnZW4xDzANBgNVBAoM\n"
  "BldpblRMUzESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIyMDYyNTIwMzg0OVoXDTQ5\n"
  "MTExMDIwMzg0OVowRzELMAkGA1UEBhMCREsxEzARBgNVBAcMCkNvcGVuaGFnZW4x\n"
  "DzANBgNVBAoMBldpblRMUzESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG\n"
  "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy6b79MKE2mdt1h7GtfFmol68HI/Q3tOsPHaJ\n"
  "cDv7PfflJofqlae1SPFAs4OspQ7IAjcwuictiyE9MbPo5vgiAEctZ2aP2PbF99AP\n"
  "XAtkeLLLF5zxqVTbQtmEt147aycALe7WddVNQqlAFQ7gd6VCo/1jZMRlwNHPT1Oi\n"
  "PkowAfVpDYCIwuL/0Rc6bRkh8p6J5Oi6S4sWcT7e6oo81NOKwyK6h2WJ8c01tFWp\n"
  "G26XySopaH3u2HT+3Elg0lIdaaAm4EhZMysYIsPli+o2OiM4Dm2qGwK/VxeZz83W\n"
  "aFS8jYPZQkB2fWOAk3Lm/hLLkSj5Z0qcin4543DOREO3b9J4ZQIDAQABo1MwUTAd\n"
  "BgNVHQ4EFgQU8TcsJp8OfaZJvBIfCOz5fqnhztwwHwYDVR0jBBgwFoAU8TcsJp8O\n"
  "faZJvBIfCOz5fqnhztwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
  "AQEAsUryE+jjeg/8xhwvthH+GJVjQSVvAbJjd1PQMLo3Yy578a1UN6aBOELwRe4W\n"
  "FgR3ASRKhrc/mnSju0eLSF69lSWStjJC+ZNlZRuwOS/Ik9A6BAe6sOARpKPV1rV2\n"
  "uWs8PxsWqPuTdICri91bEpmq1jntNTRgXmFW/hQR2ndy03h9hUHd0Xn70mlESayJ\n"
  "2s6qnAMp+OzlTtWO6eSYYajYQdmsmIpby5eGjPzPNhoIVPKtSUa6eN5GltlW74qu\n"
  "75w4XWlNO3J0AX4ZoWc7fztsWkgTX41Vv48lkxPLqLxQQTQsN6wdZ/c/sdSAXK0x\n"
  "GinlCF73ogVSHXdtNMGrQP1n8w==\n"
  "-----END CERTIFICATE-----\n";

using namespace boost;

int main(int argc, char* argv[]) {
  try {
    asio::ssl::context context{asio::ssl::context::tls_server};
    context.use_certificate_chain(asio::buffer(test_certificate));

  } catch (const std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

Thanks a lot.

laudrup commented 5 months ago

Turns out this was caused by somehow compiling with OpenSSL 3.2 headers while linking with an older version.

In my specific case this caused some of my GitHub actions tests to fail with the above error which wasn't immediately obvious as the Windows runners previously didn't shop with the OpenSSL headers/.lib files, but recently started including that causing issue if OpenSSL is also installed with eg. choco install openssl.

I though I was able to reproduce this but it turned out I had actually build the code above with OpenSSL 3.1 and then later upgraded to OpenSSL 3.2 so these libraries were used runtime.

A bit embarrassing that it took my so long to realize this but at least I hope this can help others who might experience something similar.