我希望有人可以帮助解决我在尝试针对服务器验证客户端上的证书时遇到的 OpenSSL(1.1.1k) 问题。证书内容以文本形式指定,而不是在客户端的 .PEM 文件中指定。一些示例代码在这里:
bool setCert(SSL_CTX* ctx, LPCSTR cert)
{
//cert is the text of the certificate e.g. -----BEGIN CERTIFICATE----- blah -----END CERTIFICATE-----
bool bOk = true;
if (!cert.empty()) // no cert on disk
{
BIO *bioCert = BIO_new_mem_buf((void*)cert, -1);
X509* pCert = PEM_read_bio_X509(bioCert, NULL, 0, NULL);
if (SSL_CTX_use_certificate(ctx, pCert) != 1)
{
//log errror, "Invalid certificate"
bOk = false;
}
BIO_free_all(bioCert);
X509_free(pCert);
}
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); // other options not used atm SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
return bOk;
}
此方法返回后,我根据上下文创建一个 SSL 对象,使用 SSL_new(ctx)。
然后我调用 SSL_Connect(ssl)
即使我传入无效的证书,也会发生握手并被接受。
我的假设是这样做是因为我没有像这样设置验证方法:
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
我的理解是我不能使用 SSL_VERIFY_PEER,除非客户端磁盘上有一个 cert/.PEM 文件来验证。
将证书内容保存在内存中时如何验证握手?
如果我更改代码以使用 PEM 文件,请调用 SSL_CTX_use_certificate_file 而不是 SSL_CTX_use_certificate,它可以工作。在那种情况下,我确实设置了 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
非常感谢这里的任何帮助。谢谢
答案 0 :(得分:0)
SSL_CTX_use_certificate
用于设置应该在本地使用的证书以对等方进行身份验证。它需要附带一个私钥,使用 SSL_CTX_use_PrivateKey
设置。但是针对对等点进行身份验证(即使用客户端证书)并不是您打算在客户端中执行的操作。
相反,您希望在验证服务器证书时设置一个证书以用作受信任的 CA。正确的函数应该是 X509_STORE_add_cert :
X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), pCert);