Below is the code snippet for SSL context initialization and verify callback registered. If I connect SSL client with proper certificates it verifies the certificate and works as expected.
But if I connect client without any certificate then it allows connection(actually it should not allow connection without certificates). If SSL client do not send certificate then it do not call verify callback.
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 function
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;
}
How can I modify the code that do not allow connection without proper certificate files? Thanks in advance.!
Chrome: Verifying that Your Client Certificate Is InstalledIn Chrome, go to Settings. On the Settings page, below Default browser, click Show advanced settings. Under HTTPS/SSL, click Manage certificates. In the Certificates window, on the Personal tab, you should see your Client Certificate.
Create a client certificate request. After receiving the certificate, export it to a password-protected PKCS12 file and send the password and the file to the user. Make sure the file is securely sent.
On the taskbar, click Start, and then click Control Panel. In Control Panel, click Programs and Features, and then click Turn Windows Features on or off. Expand Internet Information Services, then select Client Certificate Mapping Authentication, and then click OK.
Finally got the solution. One of my teammate has suggested to use flag boost::asio::ssl::verify_fail_if_no_peer_cert
in association with boost::asio::ssl::verify_peer
and it worked.
updated line of code :
context_->set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With