2014-02-23 3 views
2

iOS에서 Boost Asio를 사용하려고하는데 모든 것을 알아 냈지만 연결하려는 서버의 인증서를 확인하는 방법.iOS 용 SSL Asio 인증

Boost Asio로 iOS의 연결 서버 인증서를 어떻게 확인합니까?

답변

1

다른 답변으로 간단한 SSL 클라이언트를 볼 수 있습니다.

이 코드에서는 서버 인증서를 (추가로) 확인하는 데 사용할 수있는 verify_certificate을 빠르게 기록합니다. 내가 라이브러리가하는 Asio SSL 구현 아이폰 OS의 기초가되는 알고 있지만, 오히려 쓸모가있을 수 theserver 인증서 확인 (또는 고정)을 염두에 보관하지 않는

(!) 참고

참고. 인증서의 진위 여부 만 확인하면 이 표시됩니다. yesterday's security debacle의 빛에서 나는 무관 한 암호화 키를 properly patched하지 않는 서버가 유효한 인증서를 제시 할 수 있기 때문에이 많은 도움 생각하지만, 아직 사용하지 않는 -이 여전히 MITM 시나리오를 허용 이런 경우에이 문제를 지적

귀하의 질문은 어떻게 든 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; 
} 
에서이 situration

관련이있다