2013-06-03 12 views
10

Im Folgenden finden Sie den Codeausschnitt für die Initialisierung des SSL-Kontexts und die Überprüfung des registrierten Rückrufs. Wenn ich den SSL-Client mit den richtigen Zertifikaten verbinde, verifiziert er das Zertifikat und funktioniert wie erwartet.Wie überprüft man Client-Zertifikate mit boost :: asio SSL?

Aber wenn ich Client ohne Zertifikat verbinden dann ermöglicht es Verbindung (eigentlich sollte es keine Verbindung ohne Zertifikate zulassen). Wenn der SSL-Client kein Zertifikat sendet, ruft er den Bestätigungsrückruf nicht auf.

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 Callback-Funktion

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; 
} 

Wie kann ich den Code ändern, die eine Verbindung nicht ohne entsprechende Zertifikat Dateien erlauben es? Vielen Dank im Voraus.!

+0

wie die verify_certificate_cb synchron zu tun, ohne set_verify_callback zu verwenden? –

Antwort

18

Endlich die Lösung. Einer meiner Teamkollegen hat vorgeschlagen, das Flag boost::asio::ssl::verify_fail_if_no_peer_cert in Verbindung mit boost::asio::ssl::verify_peer zu verwenden, und es hat funktioniert.

aktualisiert Codezeile:

context_->set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);