Как проверить сертификаты клиентов с помощью boost:: asio SSL?

Ниже приведен фрагмент кода для инициализации контекста SSL и подтверждения зарегистрированного обратного вызова. Если я подключу SSL-клиент с надлежащими сертификатами, он проверяет сертификат и работает как ожидалось.

Но если я подключу клиента без какого-либо сертификата, он позволяет подключиться (на самом деле он не должен разрешать подключение без сертификатов). Если клиент SSL не отправляет сертификат, он не вызывает проверку обратного вызова.

    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 функция обратного вызова

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

Как я могу изменить код, который не разрешает соединение без надлежащих файлов сертификатов? Спасибо заранее.!

Ответ 1

Наконец, получил решение. Один из моих товарищей по команде предложил использовать флаг boost::asio::ssl::verify_fail_if_no_peer_cert в связи с boost::asio::ssl::verify_peer, и он сработал.

обновленная строка кода:

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