我正在尝试使用以下代码设置双向TLS双向身份验证,但是由于客户端拒绝连接,因此客户端似乎未发送自己的证书。
SSL_METHOD *meth = SSLv23_client_method();
m_ctx = SSL_CTX_new(meth);
if (m_ctx == NULL)
{
m_sLastError = GetSSLErrors().c_str();
}
else
{
long options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
SSL_CTX_set_options(m_ctx, options);
if (SSL_CTX_set_cipher_list(m_ctx, "DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:!3DES:!RC4:!CAMELLIA") != 1)
{
m_sLastError = GetSSLErrors().c_str();
cout << "SSL_CTX_set_cipher_list failed, error";
}
try
{
//Populate certificate file paths from VMRegistry
string vmproCertsPath = "/var/tmp";
string m_serverCertFile;
string m_rootCACertFile;
string m_serverCertKeyFile;
m_serverCertFile.Format("%s/%s", vmproCertsPath.c_str(), "client.pem");
m_rootCACertFile.Format("%s/%s", vmproCertsPath.c_str(), "ca.pem");
m_serverCertKeyFile.Format("%s/%s", vmproCertsPath.c_str(), "key.pem");
int ret = 0;
// Read server certificate, intermediate certificates and store in SSL context
// Here server certificate is a mandatory certificate for SSL handshake
// Intermediate certificates are for additional security.
ret = SSL_CTX_use_certificate_chain_file(m_ctx, "/cert.pem");
if (ret != 1)
{
string sErr(GetSSLErrors().c_str());
cout << "SSL_CTX_use_certificate_file error" << sErr;
return false;
}
cout << "SSL_CTX_use_certificate_file success ret" << ret;
// Read private key from certificate file
// We store server certificate & corresponding private key
// in same file, which of of PEM format.
ret = SSL_CTX_use_PrivateKey_file(m_ctx, "/key.pem", SSL_FILETYPE_PEM);
if (ret != 1)
{
string sErr(GetSSLErrors().c_str());
cout << "SSL_CTX_use_PrivateKey_file error" << sErr;
return false;
}
cout << "SSL_CTX_use_PrivateKey_file success ret" << ret;
// Validate if certificate & private key match.
ret = SSL_CTX_check_private_key(m_ctx);
if (ret != 1)
{
string sErr(GetSSLErrors().c_str());
cout << "Private key does not match the certificate public key";
return false;
}
cout << "SSL_CTX_check_private_key success ret" << ret;
// Read CA certificate
// Even if we are unable to read CA certificate SSL context should get populated
// Lets not return flase on failure
ret = SSL_CTX_load_verify_locations(m_ctx, "/ca.pem", NULL);
if (ret != 1)
{
string sErr(GetSSLErrors().c_str());
cout << sErr;
}
cout << "SSL_CTX_load_verify_locations success ret" << ret;
//Won't handle incomplete read/write due to renegotiation
//SSL_CTX_set_mode(m_ctx, SSL_MODE_AUTO_RETRY);
//Specify that we need to verify the server certificate
SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify_depth(m_ctx, 1);
}
catch (...)
{
cout << "Exception occured";
}
}
还观察到,当服务器拒绝连接时,我没有收到任何错误,并且套接字仍处于连接状态。 任何想法与上面的代码有什么不对。