Establishing TLS Connection with MQTT Broker using MQTT Client SL Package

ppix
2024-06-19
2024-06-20
  • ppix - 2024-06-19

    I’m currently working on establishing a TLS connection with an MQTT broker using the MQTT Client SL package in CODESYS. While I’ve successfully established communication with the broker without TLS, I'm encountering issues when trying to enable TLS.

    In the 'MQTT Explorer' application, I can easily upload the server certificate (.crt), client certificate (.crt), and client key (.key). However, in CODESYS, I can’t find a way to upload my client key (.key file).

    Here's a summary of my current setup:

    • Certificates: I have uploaded both the client and server certificates to the certificate store under the 'Trusted Certificates' folder in the security screen.
    • TLS Context Initialization: Despite setting the _sCommonName as the name of my client certificate, a new self-signed certificate is created and placed within the device’s certificates. I then need to manually move this certificate to the trusted certificates folder. This results in three certificates in my trusted certs folder: client cert, server cert, and the newly created cert.
        _ciDefaultCertInfo : MQTT.NBS.CERT_INFO := (psInfo := ADR(_sCommonName), udiSize := TO_UDINT(LEN(_sCommonName))); // CN of the certificate (common name)
        _sCipherList : MQTT.NBS.CIPHER_LIST := STRUCT(psList := ADR('HIGH'), udiSize := 4); // Cipher string see https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
        _tlsContext : MQTT.NBS.TLSContext := (  sUseCaseName := _sCommonName, // A certificate is stored in the certificate store with the use case name. You can choose any name. Here we use the common name.
                                            ePurpose := MQTT.NBS.PURPOSE.CLIENT_SIDE, // For client certificates set this to NBS.PURPOSE.CLIENT_SIDE
                                            sTLSVersion := '1.3', // The TLS version
                                            sCipherList := _sCipherList, // Set the cipher list
                                            sHostname := sHostname, // The hostname of the broker
                                            udiVerificationMode := 2, // 2 => Active Peer verification
                                            ciCertInfo := _ciDefaultCertInfo, // Set the cert info
                                            itfCertVerifer := 0); // 0 => No Verifier 
        mqttClient : MQTT.MQTTClient := (xUseTLS:=TRUE, itfTLSContext := _tlsContext, itfAsyncProperty := _asyncProperty);
    

    Additional Details:

    • In the client FB, I’ve set uiPort:= 8883, xUseTLS:= TRUE, and configured itfTLSContext as mentioned above.
    • The certificates are encrypted with SHA256RSA.
    • sHostname is the IP address of my broker.
    • I’ve attached a copy of the client FB, which shows straight lines where variables are assigned and boxes where they are not.
    • I am currently trying this on the only 2 compatible versions of COSDESYS with my controller (V3.5.15.20 and V3.5.18.40)

    My Question:
    How do I correctly set up this mTLS connection? What might I be missing? Any guidance or suggestions would be greatly appreciated, especially considering I’ve already successfully established a non-TLS connection with the same broker.

    Thank you in advance for your help!

     
  • ppix - 2024-06-20

    For anyone confused with the process visit this link (the bottom section about creating a .pfx file) https://content.helpme-codesys.com/en/LibDevSummary/certificate.html#import-of-client-certificates-with-private-key. I solved this problem by creating a .pfx file and importing it into the security store under 'Own Certificates'(must have SP18 or newer to import .pfx). I used a gitbash shell to enter the openssl command that created the .pfx file. Once you import the file, in your TLS context, set your 'sUseCaseName' to be the same as the name listed in the 'Information' column of your imported certificate. This did it for me

     

Log in to post a comment.