我正在尝试在 iOS 上使用 Boost Asio,并且已经弄清楚了所有问题,但是如何检查我正在连接的服务器的证书。
如何使用 Boost Asio 在 iOS 中检查连接服务器的证书?
最佳答案
在我的另一个回答中,您可以看到一个简单的 SSL 客户端。
在此代码中,您会很快注意到 verify_certificate
,您可以使用它来(另外)验证服务器证书。
Sidenote
Note that I don't know which libraries are underlying the Asio SSL implementation iOS, but keep in mind verifying (or even pinning) theserver certificate could be rather useless. It would only verify the authenticity of the certificate presented. In the light of yesterday's security debacle I don't think this helps much, because unless properly patched the server could have presented a valid certificate, but still use unrelated encryption keys - this still allows a MiTM scenario
Just noting this in case your question is somehow related to this situration
来自 A: HTTPS POST request with boost asio
#define DEMO_USING_SSL
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <iostream>
#include <iomanip>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
class client
{
public:
client(boost::asio::io_service& io_service,
boost::asio::ssl::context& context,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service
#ifdef DEMO_USING_SSL
, context)
{
socket_.set_verify_mode(boost::asio::ssl::verify_peer);
socket_.set_verify_callback(
boost::bind(&client::verify_certificate, this, _1, _2));
#else
)
{
(void) context;
#endif
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
bool verify_certificate(bool preverified,
boost::asio::ssl::verify_context& ctx)
{
// The verify callback can be used to check whether the certificate that is
// being presented is valid for the peer. For example, RFC 2818 describes
// the steps involved in doing this for HTTPS. Consult the OpenSSL
// documentation for more details. Note that the callback is called once
// for each certificate in the certificate chain, starting from the root
// certificate authority.
// In this example we will simply print the certificate's subject name.
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);
std::cout << "Verifying " << subject_name << "\n";
return preverified;
}
void handle_connect(const boost::system::error_code& error)
{
#ifdef DEMO_USING_SSL
if (!error)
{
socket_.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&client::handle_handshake, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Connect failed: " << error.message() << "\n";
}
#else
handle_handshake(error);
#endif
}
void handle_handshake(const boost::system::error_code& error)
{
if (!error)
{
std::cout << "Enter message: ";
static char const raw[] = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n";
static_assert(sizeof(raw)<=sizeof(request_), "too large");
size_t request_length = strlen(raw);
std::copy(raw, raw+request_length, request_);
{
// used this for debugging:
std::ostream hexos(std::cout.rdbuf());
for(auto it = raw; it != raw+request_length; ++it)
hexos << std::hex << std::setw(2) << std::setfill('0') << std::showbase << ((short unsigned) *it) << " ";
std::cout << "\n";
}
boost::asio::async_write(socket_,
boost::asio::buffer(request_, request_length),
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Handshake failed: " << error.message() << "\n";
}
}
void handle_write(const boost::system::error_code& error,
size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "starting read loop\n";
boost::asio::async_read_until(socket_,
//boost::asio::buffer(reply_, sizeof(reply_)),
reply_, '\n',
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}
void handle_read(const boost::system::error_code& error, size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "Reply: " << &reply_ << "\n";
}
else
{
std::cout << "Read failed: " << error.message() << "\n";
}
}
private:
#ifdef DEMO_USING_SSL
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
#else
boost::asio::ip::tcp::socket socket_;
#endif
char request_[1024];
boost::asio::streambuf reply_;
};
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cerr << "Usage: client <host> <port>\n";
return 1;
}
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.set_default_verify_paths();
client c(io_service, ctx, iterator);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
关于ios - 在 iOS 上提升 Asio SSL 认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21968931/