SSL certificates and Boost asio

会有一股神秘感。 提交于 2019-11-30 05:18:29

Trusted certificates are often installed or updated via the OS, browsers, or individual packages. For instance, in the *nix world, the certificates are often available through the ca-certificates package, and the certificates are installed to locations that boost::asio::ssl::context::set_default_verify_paths() will find.

The certification verification is failing because the the client is attempting to verify the peer's certificates with hostname verification (rfc2818), and is checking for the literal "host.name" to be in the certificate, and the server's certificates do not list "host.name" as a name. Try changing:

socket.set_verify_callback(ssl::rfc2818_verification("host.name"));

to:

socket.set_verify_callback(ssl::rfc2818_verification(argv[1]));

To disable peer verification, provide boost::asio::ssl::verify_none to the boost::asio::ssl::stream::set_verify_mode():

socket.set_verify_mode(boost::asio::ssl::verify_none);

Boost.Asio provides other peer verify_modes.


When peer verification is failing, it can be helpful to provide a custom callback to boost::asio::ssl::stream::set_verify_callback that provides diagnostic information. As noted in the documentation, the handler signature must be:

bool verify_callback(
  bool preverified, // True if the certificate passed pre-verification.
  verify_context& ctx // The peer certificate and other context.
);

Here is a custom functor that prints the certificate subject name:

///@brief Helper class that prints the current certificate's subject
///       name and the verification results.
template <typename Verifier>
class verbose_verification
{
public:
  verbose_verification(Verifier verifier)
    : verifier_(verifier)
  {}

  bool operator()(
    bool preverified,
    boost::asio::ssl::verify_context& ctx
  )
  {
    char subject_name[256];
    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
    bool verified = verifier_(preverified, ctx);
    std::cout << "Verifying: " << subject_name << "\n"
                 "Verified: " << verified << std::endl;
    return verified;
  }
private:
  Verifier verifier_;
};

///@brief Auxiliary function to make verbose_verification objects.
template <typename Verifier>
verbose_verification<Verifier>
make_verbose_verification(Verifier verifier)
{
  return verbose_verification<Verifier>(verifier);
}

And its usage:

socket.set_verify_callback(make_verbose_verification(
  boost::asio::ssl::rfc2818_verification(argv[1])));

On my machine, when using it and set_default_verify_paths() is not invoked, I get the following output:

$ ./a.out www.google.co.uk /?gws_rd=ssl
Verifying: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Verified: 0
Exception: handshake: certificate verify failed

And when set_default_verify_paths() is invoked:

$ ./a.out www.google.co.uk /?gws_rd=ssl
Verifying: /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Verified: 1
Verifying: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Verified: 1
Verifying: /C=US/O=Google Inc/CN=Google Internet Authority G2
Verified: 1
Verifying: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
Verified: 1

And when rfc2818_verification("host.name") is used:

$ ./a.out www.google.co.uk /?gws_rd=ssl
Verifying: /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Verified: 1
Verifying: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Verified: 1
Verifying: /C=US/O=Google Inc/CN=Google Internet Authority G2
Verified: 1
Verifying: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
Verified: 0
Exception: handshake: certificate verify failed
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!