2013-06-03 45 views
10

Dưới đây là đoạn mã để khởi tạo ngữ cảnh SSL và xác minh đăng ký gọi lại. Nếu tôi kết nối máy khách SSL với chứng chỉ thích hợp, nó sẽ xác minh chứng chỉ và hoạt động như mong đợi.cách xác minh chứng chỉ ứng dụng khách bằng cách sử dụng boost :: asio SSL?

Nhưng nếu tôi kết nối máy khách mà không có bất kỳ chứng chỉ nào thì nó cho phép kết nối (thực ra nó không cho phép kết nối không có chứng chỉ). Nếu máy khách SSL không gửi chứng chỉ thì nó không gọi xác minh gọi lại.

boost::asio::ssl::context_base::method SSL_version = 
      static_cast<boost::asio::ssl::context_base::method>(param_values[ID_PROTOCOL_VERSION].int32_value); 

    // load certificate files 
    boost::shared_ptr<boost::asio::ssl::context> context_ = boost::shared_ptr<boost::asio::ssl::context>(
      new boost::asio::ssl::context(SSL_version)); // parasoft-suppress BD-RES-LEAKS "The memory is allocated via boost::shared_ptr, hence it'll be deallocated automatically" 

    p_ctx = boost::static_pointer_cast<void>(context_); 

    context_->set_options(boost::asio::ssl::context::default_workarounds); 

    context_->use_certificate_chain_file(cert_chain_file); 
    context_->use_certificate_file(cert_file, boost::asio::ssl::context::pem); 
    context_->use_private_key_file(cert_file, boost::asio::ssl::context::pem); 

    context_->set_verify_mode(boost::asio::ssl::verify_peer); 
    context_->set_verify_callback(boost::bind(&verify_certificate_cb, _1, _2)); 

verify_certificate_cb hàm callback

bool verify_certificate_cb(bool preverified, boost::asio::ssl::verify_context& ctx) 
{ 
    std::cout << "Function : " << __func__ << " ----------------- Line : " << __LINE__ << std::endl; 
    int8_t subject_name[256]; 
    X509_STORE_CTX *cts = ctx.native_handle(); 
    int32_t length = 0; 
    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); 
    std::cout << "CTX ERROR : " << cts->error << std::endl; 

    int32_t depth = X509_STORE_CTX_get_error_depth(cts); 
    std::cout << "CTX DEPTH : " << depth << std::endl; 

    switch (cts->error) 
    { 
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 
     Debug(PRIORITY_ERROR, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT"); 
     break; 
    case X509_V_ERR_CERT_NOT_YET_VALID: 
    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 
     Debug(PRIORITY_ERROR, "Certificate not yet valid!!"); 
     break; 
    case X509_V_ERR_CERT_HAS_EXPIRED: 
    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 
     Debug(PRIORITY_ERROR, "Certificate expired.."); 
     break; 
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 
     Debug(PRIORITY_WARN, "Self signed certificate in chain!!!\n"); 
     preverified = true; 
     break; 
    default: 
     break; 
    } 
    const int32_t name_length = 256; 
    X509_NAME_oneline(X509_get_subject_name(cert), reinterpret_cast<char*>(subject_name), name_length); 
    Debug(PRIORITY_INFO, "Verifying %s", subject_name); 
    Debug(PRIORITY_INFO, "Verification status : %d", preverified); 

    std::cout << "Function : " << __func__ << " ----------------- Line : " << __LINE__ << std::endl; 
    return preverified; 
} 

Làm thế nào tôi có thể sửa đổi các mã mà không cho phép kết nối mà không cần file giấy chứng nhận phù hợp? Cảm ơn trước.!

+0

làm thế nào để làm verify_certificate_cb đồng bộ, mà không sử dụng set_verify_callback? –

Trả lời

18

Cuối cùng đã nhận được giải pháp. Một trong những đồng đội của tôi đã đề nghị sử dụng cờ boost::asio::ssl::verify_fail_if_no_peer_cert kết hợp với boost::asio::ssl::verify_peer và nó hoạt động.

cập nhật dòng mã:

context_->set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert); 
Các vấn đề liên quan