title: SSL certificates and Boost asio
body: <p>Hello I'm trying to download content from webpage that uses https via C++. My very basic client program taken from the Boost asio examples compiles and runs fine, but when I test it eg with Google: www.google.co.uk/?gws_rd=ssl, it gives me the error "handshake: certificate verify failed". </p>
  
  <p>I think this is because ctx.set_default_verify_paths() doesn't contain a path with a certificate for Google (I'm on Windows). </p>
  
  <p>I'm <em>very</em> new to SSL, please can you help me with the following questions:</p>
  
  <p>1) When I installed openSSL, did it stick a list of trusted certifying authorities on my computer? If it did, what would cause Google's certificate not to be verified?</p>
  
  <p>2) Is there anyway of saying I don't care about verification, proceed to connect anyway, like when you add an exception manually in firefox? I'm not particularly interested in whether the connection is trusted as I am not transmitting anything that needs to be secure.</p>
  
  <p>Answers to either would be greatly appreciated!</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;istream&gt;
  #include &lt;ostream&gt;
  #include &lt;fstream&gt;
  #include &lt;string&gt;
  #include &lt;boost/asio.hpp&gt;
  #include &lt;boost/asio/ssl.hpp&gt;
  
  using boost::asio::ip::tcp;
  namespace ssl = boost::asio::ssl;
  typedef ssl::stream&lt;tcp::socket&gt; ssl_socket;
  
  int main(int argc, char* argv[])
  {
    try
    {
  if (argc != 3)
  {
    std::cout &lt;&lt; argc;
    std::cout &lt;&lt; "Usage: sync_client &lt;server&gt; &lt;path&gt;\n";
    std::cout &lt;&lt; "Example:\n";
    std::cout &lt;&lt; "  sync_client www.boost.org /LICENSE_1_0.txt\n";
    return 1;
  }
  
  boost::asio::io_service io_service;
  
  // Create a context that uses the default paths for
  // finding CA certificates.
  ssl::context ctx(ssl::context::sslv23);
  ctx.set_default_verify_paths();
  
  // Get a list of endpoints corresponding to the server name.
  tcp::resolver resolver(io_service);
  tcp::resolver::query query(argv[1], "https");
  tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
  
  // Try each endpoint until we successfully establish a connection.
  ssl_socket socket(io_service, ctx);
  boost::asio::connect(socket.lowest_layer(), endpoint_iterator);
  socket.lowest_layer().set_option(tcp::no_delay(true));
  
  // Perform SSL handshake and verify the remote host's
  // certificate.
  socket.set_verify_mode(ssl::verify_peer);
  socket.set_verify_callback(ssl::rfc2818_verification("host.name"));
  socket.handshake(ssl_socket::client);
  
  // Form the request. We specify the "Connection: close" header so that the
  // server will close the socket after transmitting the response. This will
  // allow us to treat all data up until the EOF as the content.
  boost::asio::streambuf request;
  std::ostream request_stream(&amp;request);
  request_stream &lt;&lt; "GET " &lt;&lt; argv[2] &lt;&lt; " HTTP/1.0\r\n";
  request_stream &lt;&lt; "Host: " &lt;&lt; argv[1] &lt;&lt; "\r\n";
  request_stream &lt;&lt; "Accept: */*\r\n";
  request_stream &lt;&lt; "Connection: close\r\n\r\n";
  
  // Send the request.
  boost::asio::write(socket, request);
  
  // Read the response status line. The response streambuf will automatically
  // grow to accommodate the entire line. The growth may be limited by passing
  // a maximum size to the streambuf constructor.
  boost::asio::streambuf response;
  boost::asio::read_until(socket, response, "\r\n");
  
  // Check that response is OK.
  std::istream response_stream(&amp;response);
  std::string http_version;
  response_stream &gt;&gt; http_version;
  unsigned int status_code;
  response_stream &gt;&gt; status_code;
  std::string status_message;
  std::getline(response_stream, status_message);
  
  if (!response_stream || http_version.substr(0, 5) != "HTTP/")
  {
    std::cout &lt;&lt; "Invalid response\n";
    return 1;
  }
  if (status_code != 200)
  {
      std::cout &lt;&lt; "Response returned with status code " &lt;&lt; status_code &lt;&lt; "\n";
      std::cout &lt;&lt; status_message &lt;&lt; "\n";
      // Read the response headers, which are terminated by a blank line.
      boost::asio::read_until(socket, response, "\r\n\r\n");
  
      // Process the response headers.
      std::string header;
      while (std::getline(response_stream, header) &amp;&amp; header != "\r")
          std::cout &lt;&lt; header &lt;&lt; "\n";
      std::cout &lt;&lt; "\n";
        return 1;
  }
  //code to read the data goes here, which works fine for http pages    
    }
    catch (std::exception&amp; e)
    {
      std::cout &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; "\n";
    }
    return 0;
  }
  </code></pre>