设置 SSL_CTX_set_cipher_list() 失败并出现 "No cipher match" 错误
Setting SSL_CTX_set_cipher_list() fails with "No cipher match" error
我正在尝试使用 SSL_CTX_set_cipher_list() 限制我的 gsoap ssl 服务器中的密码列表。但是方法 returns 与 0 无关,无论我提供什么列表。没有设置列表一切正常。
我基本上做的和 gsoap 文档中的一样https://www.genivia.com/doc/guide/html/group__group__ssl.html#ga3492465cdd8aa71fe746199d3842cac7
auto err = BIO_new_fp(stderr, BIO_NOCLOSE);
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
CalculatorSoapBindingService service;
service.soap->send_timeout = service.soap->recv_timeout = 5;
if (useSSL) {
soap_ssl_init(); // init SSL (just need to do this once in an application)
if (soap_ssl_server_context(
service.soap,
SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_TLSv1 | SOAP_SSL_NO_DEFAULT_CA_PATH,
"server.pem", // server keyfile (cert+key)
"password", // password to read the private key in the keyfile
nullptr, // no cert to authenticate clients
nullptr, // no capath to trusted certificates
nullptr, // DH/RSA: use 2048 bit RSA (default with NULL)
nullptr, // no random data to seed randomness
"testServer" // no SSL session cache
))
{
service.soap_stream_fault(std::cerr);
exit(EXIT_FAILURE);
}
const char allowedCiphers[] = "ALL:!aNULL";
auto rc = SSL_CTX_set_cipher_list(service.soap->ctx, allowedCiphers);
if (rc != 1) {
ERR_print_errors(err);
exit(EXIT_FAILURE);
}
}
根据 documentation return 代码 0 表示完全失败。
错误信息是:140347788101304:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl_lib.c:1385:
当我 运行 "openssl ciphers" 时,我得到了完整的密码列表。
有什么想法我想念的吗?上下文没有正确初始化?
这是一个 SSL 初始化问题。使用 SSL_library_init()
而不是 soap_ssl_init()
解决了问题。
这是我最终的工作解决方案:
CalculatorSoapBindingService service;
service.soap->send_timeout = service.soap->recv_timeout = 5; // 5 sec socket idle timeout
if (useSSL) {
SSL_library_init();
BIO_new_fp(stderr, BIO_NOCLOSE);
SSL_load_error_strings();
if (soap_ssl_server_context(
service.soap,
SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_TLSv1 | SOAP_SSL_NO_DEFAULT_CA_PATH,
"server.pem", // server keyfile (cert+key)
"haslerrail", // password to read the private key in the keyfile
nullptr, // no cert to authenticate clients
nullptr, // no capath to trusted certificates
nullptr, // DH/RSA: use 2048 bit RSA (default with NULL)
nullptr, // no random data to seed randomness
"testServer" // no SSL session cache
))
{
service.soap_stream_fault(std::cerr);
exit(EXIT_FAILURE);
}
const char allowedCiphers[] = "ECDH:!aNULL:!eNULL:!ADH:!SHA:@STRENGTH";
auto nid = NID_X9_62_prime256v1;
auto key = EC_KEY_new_by_curve_name(nid);
if (key == nullptr) {
std::cout << "Failed to create curve" << OBJ_nid2sn(nid) << std::endl;;
exit(EXIT_FAILURE);;
}
SSL_CTX_set_tmp_ecdh(service.soap->ctx, key);
EC_KEY_free(key);
auto rc = SSL_CTX_set_cipher_list(service.soap->ctx, allowedCiphers);
if (rc != 1) {
std::cout << "no cipher list found " << rc << std::endl;
ERR_print_errors(err);
exit(EXIT_FAILURE);
}
}
我正在尝试使用 SSL_CTX_set_cipher_list() 限制我的 gsoap ssl 服务器中的密码列表。但是方法 returns 与 0 无关,无论我提供什么列表。没有设置列表一切正常。
我基本上做的和 gsoap 文档中的一样https://www.genivia.com/doc/guide/html/group__group__ssl.html#ga3492465cdd8aa71fe746199d3842cac7
auto err = BIO_new_fp(stderr, BIO_NOCLOSE);
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
CalculatorSoapBindingService service;
service.soap->send_timeout = service.soap->recv_timeout = 5;
if (useSSL) {
soap_ssl_init(); // init SSL (just need to do this once in an application)
if (soap_ssl_server_context(
service.soap,
SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_TLSv1 | SOAP_SSL_NO_DEFAULT_CA_PATH,
"server.pem", // server keyfile (cert+key)
"password", // password to read the private key in the keyfile
nullptr, // no cert to authenticate clients
nullptr, // no capath to trusted certificates
nullptr, // DH/RSA: use 2048 bit RSA (default with NULL)
nullptr, // no random data to seed randomness
"testServer" // no SSL session cache
))
{
service.soap_stream_fault(std::cerr);
exit(EXIT_FAILURE);
}
const char allowedCiphers[] = "ALL:!aNULL";
auto rc = SSL_CTX_set_cipher_list(service.soap->ctx, allowedCiphers);
if (rc != 1) {
ERR_print_errors(err);
exit(EXIT_FAILURE);
}
}
根据 documentation return 代码 0 表示完全失败。 错误信息是:140347788101304:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl_lib.c:1385: 当我 运行 "openssl ciphers" 时,我得到了完整的密码列表。 有什么想法我想念的吗?上下文没有正确初始化?
这是一个 SSL 初始化问题。使用 SSL_library_init()
而不是 soap_ssl_init()
解决了问题。
这是我最终的工作解决方案:
CalculatorSoapBindingService service;
service.soap->send_timeout = service.soap->recv_timeout = 5; // 5 sec socket idle timeout
if (useSSL) {
SSL_library_init();
BIO_new_fp(stderr, BIO_NOCLOSE);
SSL_load_error_strings();
if (soap_ssl_server_context(
service.soap,
SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_TLSv1 | SOAP_SSL_NO_DEFAULT_CA_PATH,
"server.pem", // server keyfile (cert+key)
"haslerrail", // password to read the private key in the keyfile
nullptr, // no cert to authenticate clients
nullptr, // no capath to trusted certificates
nullptr, // DH/RSA: use 2048 bit RSA (default with NULL)
nullptr, // no random data to seed randomness
"testServer" // no SSL session cache
))
{
service.soap_stream_fault(std::cerr);
exit(EXIT_FAILURE);
}
const char allowedCiphers[] = "ECDH:!aNULL:!eNULL:!ADH:!SHA:@STRENGTH";
auto nid = NID_X9_62_prime256v1;
auto key = EC_KEY_new_by_curve_name(nid);
if (key == nullptr) {
std::cout << "Failed to create curve" << OBJ_nid2sn(nid) << std::endl;;
exit(EXIT_FAILURE);;
}
SSL_CTX_set_tmp_ecdh(service.soap->ctx, key);
EC_KEY_free(key);
auto rc = SSL_CTX_set_cipher_list(service.soap->ctx, allowedCiphers);
if (rc != 1) {
std::cout << "no cipher list found " << rc << std::endl;
ERR_print_errors(err);
exit(EXIT_FAILURE);
}
}