Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to limit the cypher list in my gsoap ssl server using SSL_CTX_set_cipher_list(). But the method returns with 0, no matter what list I provide. Without setting the list everything works fine.

I'm basically doing the same as in gsoap documentation 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);

According to documentation return code 0 means complete failure. The error message is: 140347788101304:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl_lib.c:1385: When I run "openssl ciphers" I get the full list of ciphers. Any ideas what I'm missing? Is the context not correctly initialized?

Call ERR_print_errors to get the reason why it failed. You may have to load the error strings first depending on your version. See SSL_load_error_strings. Have you loaded all algorithms first with OpenSSL_add_ssl_algorithms? – indiv May 28, 2019 at 22:47 I don't really have any more suggestions because I don't know this soap API, but I do see that you're initializing OpenSSL yourself and then you call soap_ssl_init, which does it again, perhaps with different options. The docs say you may want to call soap_ssl_noinit instead. Other than that, since you said that openssl ciphers returns the full list, then you can look at the source code and see what they do. I suspect it's more of an initialization problem though. – indiv May 29, 2019 at 17:06 It was indeed an initialization problem as @indiv suggested. I'm now calling SSL_library_init() instead of soap_ssl_init() and it works. Thanks a lot. – maersk Jun 6, 2019 at 6:11 Great news! If you feel so inclined, I suggest you write an answer to this question with fixed code and mark it "answered". Sounds like your investigation and solution could help others someday. – indiv Jun 6, 2019 at 20:25

It was an SSL initialisation problem. Using SSL_library_init() instead of soap_ssl_init() solved the problem. This is my final working solution:

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);
                You should have commented, telling what you had to change. Just showing some code (and let the reader find out the differences) is a poor answer IMHO.
– U. Windl
                Mar 8, 2022 at 11:24
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.