eclipse-threadx / netxduo

Eclipse ThreadX - NetXDuo is an advanced, industrial-grade TCP/IP network stack designed specifically for deeply embedded real-time and IoT applications
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/netx-duo/index.md
MIT License
230 stars 131 forks source link

Question : verify TLS private key locally #102

Closed EdouardMALOT closed 2 years ago

EdouardMALOT commented 2 years ago

Hi,

For an application I receive remotely the TLS certificate/keys below :

I use _nx_secure_x509_certificate_verify() to verify consistency of this certificates/keys. Many tests are done but private_key doesn't seem to be checked. (If I set a wrong private key I got success).

Which function can I use to challenge a certificate/private_key locally with netxduo ?

Thank you for this great stack

tstapko commented 2 years ago

First off, _nx_secure_x509_certificate_verify() is an undocumented "private" API*. Using such an API directly might not work the way you expect and may change across versions.

(*C doesn't have a public/private notion other than file-static functions which doesn't work for the standardized organization of the NetX code - the leading underscore usually indicates that it is a private API. The functions that are documented/public have an "error handler" wrapper routine ("nxe_" prefix).)

For your specific problem, there unfortunately isn't really isn't a public API that will do what you want directly. The _nx_secure_x509_certificate_verify() API is really designed to only check a certificate against a full chain of certificates - that is, it's only verifying the signature of one certificate was created using the public key of a known-good issuer (this is done by "decrypting" the signature in the X.509 cert using the issuer's public key - details are a bit more complex but basically the idea). Private keys are not even considered in the API - you're probably seeing a successful result because the "issuer_certificate" parameter represents a valid issuer for the "certificate" parameter.

If you're interested in validating private keys against certificates you're going to need to do one of two things:

  1. Encrypt something using the public key and decrypt using the private key you want to validate: for example, encrypt a string with RSA using the cert's public key, decrypt using the private key under test, then compare the output to the original string, OR
  2. You could do a signature validation by running the encryption in reverse (encrypt using the private key).

Option 1 is conceptually much easier because it's a basic asymmetric encryption operation. The second option is signature generation/validation and with RSA is easy (the algorithm works both ways) but with ECC would require you to utilize ECDSA or a similar signature scheme. If you're comfortable with the NetX Crypto library, it should be fairly straightforward to implement a simple encrypt/decrypt for local validation, but you will need to be careful not to introduce any security vulnerabilities. If the process is being used for any sensitive data, please be sure to have a security expert review your code.

EdouardMALOT commented 2 years ago

Thanks.

Do you plan to add a public API to manage it in the near future?

TiejunMS commented 2 years ago

@DoudFPV , could you share your scenario of why it is needed to validate key pairs on device?

EdouardMALOT commented 2 years ago

@TiejunMS yes of course. The device needs to send data to an MQTT broker in mutual TLS authentication. On each project, the TLS certificates of the MQTT broker are different, so the user has to provide the certificate to the device via a REST API.

Important: the MQTT broker is not always running when configuring the REST API, so it is not possible to connect to the broker to check that everything is working.

Sometimes users mix ca.der / client.der / client_key.der from different projects...., so it will save a lot of time if we can give feedback during configuration on the API. _nx_secure_x509_certificate_verify() does most of the work (even though it's a private API) but doesn't verify the private key.

I think a public API to check the TLS chain (for mutual authentication) would be very useful and could be called during TLS init.

TiejunMS commented 2 years ago

@DoudFPV , thanks for sharing your use case. That is a common mistake we want user application to avoid. Do you think if following workaround could help you?

After a certificate is initialized by nx_secure_x509_certificate_initialize, call nx_secure_x509_extension_find with extension_id set to NX_SECURE_TLS_X509_TYPE_AUTHORITY_KEY_ID. This extension must exist in CA certificate while not in device certificate.

EdouardMALOT commented 2 years ago

@TiejunMS thanks. But if I understand well, this command :

TiejunMS commented 2 years ago

@DoudFPV , you are right. This workaround only makes sure the ca certificate is not mixed with client certificate. Typically, ca certificate is used by device to validate the certificate sent from server. While client certificate is used by server to validate device. I merely see a use case that client certificate is signed by ca certificate used on device. Let me give you an example.

  1. On server side, the certificate chain is CA1 -> server cert.
  2. On device side, the certificate chain is CA2 -> device cert. In application, you will need to set CA1, device cert to device. But the device cert is not signed by CA1 and you can not verify the certificate chain either.

Correct me if CA1 and CA2 are the same one in your use case.

EdouardMALOT commented 2 years ago

@TiejunMS thanks for your answer.

In our case the installer only setup the MQTT client on the device. Each device can connect with multiples MQTT broker, and each MQTT broker have is own CA.

During the setup, the installer need to send (via API rest) the configuration of each broker to the device. So if the device need to be connected to two broker, we want to be sure he gives the right CA + client cert + Key for each broker.

TiejunMS commented 2 years ago

CA certificate is used to verify MQTT broker. When you are not able to connect to MQTT broker at the time CA certificate is uploaded, how do you plan to verify it is a correct one?

EdouardMALOT commented 2 years ago

It is mutual authentification. On client side we have CA + client_cert + client_key. We want to check :

TiejunMS commented 2 years ago

Closing. Feel free to reopen if you have further questions.