Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECDSA key support #1666

Open
rosy8 opened this issue Nov 13, 2024 · 11 comments
Open

ECDSA key support #1666

rosy8 opened this issue Nov 13, 2024 · 11 comments
Labels
is:question Issue is actually a question.

Comments

@rosy8
Copy link

rosy8 commented Nov 13, 2024

Hello,

We are testing the TLS handshake using an ECDSA key and have noticed that the handshake fails with the error: "[ERR]: SSL_accept failed (no shared cipher)."

I attempted to list the ciphers available for that session before the ssl_accept call and confirmed that the ciphers are indeed present on the server side. (STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl);)

Additionally, I tried to specifically set the private key to NC_SSH_KEY_ECDSA by specifically hardcoding it as shown below

int tls_set_server_cert_clb(const char *name, void *user_data, char **cert_path, char **cert_data,
char **privkey_path, char **privkey_data,
NC_SSH_KEY_TYPE *privkey_type)
{
.........................
*cert_path = strdup(cpath.c_str());
*privkey_path = strdup(pkey.c_str());
*privkey_type= NC_SSH_KEY_ECDSA;

}

Logs:
tls_set_server_cert_clb] privkey_type=>3
……

[ERR]: SSL_accept failed (no shared cipher).
[ERR]: SSL_accept failed - Free session->ti.tls)

However, the ssl_accept call still fails with the error "no cipher found." According to the packet capture (pcap), the client hello message lists all ciphers from the client side which inculdes the ECDSA ciphers.

I would appreciate any guidance on specific settings or configurations we might have missed.

FYI: The TLS handshale works while using the openssl client server command.

TLS Server:
openssl s_server -accept 1234 -cert /tmp/cert.pem -cipher 'ALL' -debug -key /tmp/key.key

TLS Client:
openssl s_client -host -port 1234 -CAfile /tmp/test/cacert.

Openssl version used:
openSSL 1.0.2k 26 Jan 2017

Thank you in advance.

Regards,
Haripriya

@Roytak
Copy link
Collaborator

Roytak commented Nov 13, 2024

Hello,
I am not sure what to suggest other than updating netopeer2 to the latest version. A TLS test that uses an EC key is now part of the libnetconf2 repository (CESNET/libnetconf2@acfb5cb) and it works. It's also possible that it works just because of a newer OpenSSL version being used and required.

If updating is not possible, then what you can try is to edit the libnetconf2 code in session_server_tls.c and add the specific TLS ciphersuites (the ones offered by the client) to the SSL/SSL_CTX structs there.

@Roytak Roytak added the is:question Issue is actually a question. label Nov 13, 2024
@rosy8
Copy link
Author

rosy8 commented Nov 13, 2024

Hi @Roytak ,

Thanks for your response. I should have added this issue as part of libnetconf.

We are using Tailf Confd as a netconf server.

Yeah, updating the OpenSSL version would not be possible at this stage.
However, I updated the libnetconf2 code as follows..

File : session_server_tls.c
Function : nc_accept_tls_session(...)

Added the following to the SSL_CTX
// Set the desired TLS cipher suites
const char *cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384";
if (SSL_CTX_set_cipher_list(tls_ctx, cipher_list) != 1) {
ERR(session, "Failed to set TLS cipher suites (%s).", ERR_reason_error_string(ERR_get_error()));
goto error;
}

==> Post doing this, also the ssl_accept fails with "no cipher" found.
[ERR]: ########################## CIPHERS:Start -[goto error tag] ###################################
[ERR]: SSL_accept failed (no shared cipher).
[ERR]: SSL_accept failed - Free session->ti.tls)

While dumping the supported ciphers, I observed that only "ECDHE-ECDSA-AES256-GCM-SHA384" was listed, as shown below:
[INFO]: CIPHERS: Initialized ciphers (ECDHE-ECDSA-AES256-GCM-SHA384).
However, without specifying this cipher suite, a comprehensive list of all supported ciphers was displayed.

void print_ciphers(struct nc_session *session, SSL *ssl, const char * str) {
const char *cipher;
STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl);
...
}

Summary: The ciphers are being loaded and initialized by the server as expected, but still the ssl_accept fails with "no cipher" found.

Any further guidance would be helpful.

Regards,
Haripriya

@rosy8
Copy link
Author

rosy8 commented Nov 13, 2024

Hello,

I tried to dump the key to check whether private key is being set properly or not and found that its being set properly also.

Function: :nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name)

EVP_PKEY *set_pkey = SSL_CTX_get0_privatekey(tls_ctx); 
if (set_pkey) {
    VRB(NULL, "Private key successfully set."); 

    // Check if the key is ECDSA
    if (EVP_PKEY_base_id(set_pkey) == EVP_PKEY_EC) {
        VRB(NULL, "The private key is of type ECDSA."); 

        // Dump the private key details in "EC PRIVATE KEY" format
        EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(set_pkey); 
        if (ec_key) {
            BIO *bio = BIO_new(BIO_s_mem());
            if (PEM_write_bio_ECPrivateKey(bio, ec_key, NULL, NULL, 0, NULL, NULL)) {
                char *key_data;
                long key_len = BIO_get_mem_data(bio, &key_data);
                VRB(NULL, "Private Key:\n%.*s", (int)key_len, key_data); 
            }
            BIO_free(bio);
            EC_KEY_free(ec_key);
        } else {
            ERR(NULL, "Failed to retrieve the EC key from the private key.");
        }
    } else {
        VRB(NULL, "The private key is not of type ECDSA.");
    }
} else {
    ERR(NULL, "Failed to retrieve the private key from the SSL context.");
}

Logs:

CIPHERS: Loading the server certificate from path (/tmp/certs/device/cert-0-0.pem).
CIPHERS: Loading the private key (/tmp/certs/private/key-x-x.pem).
Private key successfully set.
The private key is of type ECDSA.
Private Key:
-----BEGIN EC PRIVATE KEY-----
......................
-----END EC PRIVATE KEY-----

So the private key is also being loaded properly, and its the same as present in the server side.
However, still the ssl_accept fails with the "no cipher found" error.

Regards,
Haripriya,

@michalvasko
Copy link
Member

I am sorry but we cannot help you any more, we do not provide support for deprecated netopeer2 and/or OpenSSL versions. We made sure it works in the current versions and if you cannot use those, you are on your own.

@rosy8
Copy link
Author

rosy8 commented Nov 14, 2024

I am sorry but we cannot help you any more, we do not provide support for deprecated netopeer2 and/or OpenSSL versions. We made sure it works in the current versions and if you cannot use those, you are on your own.

Hi Michal,

Thank you for your response.

I understand that support for deprecated versions of Netopeer2 and OpenSSL is no longer provided. However, we are using ConfD, not Netopeer2.

I am seeking your guidance regarding libnetconf2. The issue I am encountering appears to be related to libnetconf2. But yes, internally, it uses OpenSSL APIs.

Interestingly, the TLS handshake works seamlessly with standard OpenSSL client/server commands, which adds to my confusion. If the current OpenSSL version did not support ECDSA, I believe it should not have worked with the standard OpenSSL client/server commands.

Could you please advise if there might be a specific API or configuration that we might have missed that could resolve this issue? Any insights or suggestions you could provide would be immensely helpful.

Or should I post this query in the libnetconf2 page?

Thank you for your understanding and support.

Reagrds,
Haripriya Patel

@michalvasko
Copy link
Member

Okay, we are the maintainers of libnetconf2 as well so it does not matter where you create the issue or in which project is the problem. What I am saying is that we have no specific advice to give you because we have no more information than you do so we could only do what you are doing, try various fixes until it finally works. And we do not have a reason to spend time doing this because it works fine in our current versions so while it may help you specifically, there is no benefit to us or the community. So I am again sorry, but this is not included in the free support we provide.

@rosy8
Copy link
Author

rosy8 commented Nov 14, 2024

Okay, we are the maintainers of libnetconf2 as well so it does not matter where you create the issue or in which project is the problem. What I am saying is that we have no specific advice to give you because we have no more information than you do so we could only do what you are doing, try various fixes until it finally works. And we do not have a reason to spend time doing this because it works fine in our current versions so while it may help you specifically, there is no benefit to us or the community. So I am again sorry, but this is not included in the free support we provide

Hi Michal,

Thanks again for your reply and for clarifying the situation.

I understand that you have no additional information beyond what I have and that the issue does not occur in the current versions, which limits the support you can provide.

Given the circumstances, I will continue to explore potential fixes on my end.

However, when you mention the "current OpenSSL version," could you please specify the minimum version that would be acceptable for your support and compatibility?

This information would be very helpful for us to ensure we are aligned with the versions that are known to work well with libnetconf2.

Thank you once again for your assistance.

Regards,
Haripriya

@michalvasko
Copy link
Member

Any supported version is fine. Using any unsupported version is a major security risk.

@rosy8
Copy link
Author

rosy8 commented Nov 14, 2024

Any supported version is fine. Using any unsupported version is a major security risk.

Thank you, Michal.

Regrads,
Haripriya

@Roytak
Copy link
Collaborator

Roytak commented Nov 15, 2024

Hi,

While dumping the supported ciphers, I observed that only "ECDHE-ECDSA-AES256-GCM-SHA384" was listed, as shown below:

This seems to be TLS1.2 only cipher, can you make sure that both the client and the server offer TLS1.2? If yes, then the last suggestion I have is to analyze the pcap from the successful handshake with OpenSSL's s_client and s_server and actually set all the ciphersuites (or possibly even TLS/SSL versions) offered by both the client and the server, not just one (and not just on the server). If that does not work, then I can not help you.

@rosy8
Copy link
Author

rosy8 commented Nov 18, 2024

Hi,

While dumping the supported ciphers, I observed that only "ECDHE-ECDSA-AES256-GCM-SHA384" was listed, as shown below:

This seems to be TLS1.2 only cipher, can you make sure that both the client and the server offer TLS1.2? If yes, then the last suggestion I have is to analyze the pcap from the successful handshake with OpenSSL's s_client and s_server and actually set all the ciphersuites (or possibly even TLS/SSL versions) offered by both the client and the server, not just one (and not just on the server). If that does not work, then I can not help you.

Hi @Roytak ,

Thank you for your suggestion.
Actually, I had already tried adding a few specific ciphers supported by both the client and server and still encountered the same error. However, I will try adding all the common ciphers and will give it another try.

Regards,
Haripriya

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
is:question Issue is actually a question.
Projects
None yet
Development

No branches or pull requests

3 participants