Openwrt based router mosquitto bridge fails to connect using TLS - lib(20) us unable to get local issuer certificate

Hi

I am working with a new device to simplify the deployment of Losant.
It is an openwrt modem/router with some hardware I/O

I can successfully connect it in bridge mode to losant but unsecure. I am trying to establish a TLS connection. However I get the following error.

1570665206: Connecting bridge Losant (broker.losant.com:8883)
1570665206: Bridge 5c80629330bca9000848e855 sending CONNECT
1570665207: OpenSSL Error: error:14090086:lib(20):func(144):reason(134)
1570665207: Socket error on client local.5c80629330bca9000848e855, disconnecting.

error lib(20) us unable to get local issuer certificate

I am new to openwrt and normally am doing everything through python or mosquitto bridge on full linux.
So looking for some advice :wink:

Connecting via openssl provides some more details

r oot@Teltonika-RUT955:/etc# openssl s_client -connect broker.losant.com:8883 -CAfile /lib/uci/upload/cbid.mosquitto.mqtt.bridge_cafile -CApath /etc
CONNECTED(00000003)
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify error:num=20:unable to get local issuer certificate

Certificate chain
0 s:/C=US/ST=Ohio/L=Cincinnati/O=Losant IoT, Inc./CN=.losant.com
i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
1 s:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA

Server certificate
-----BEGIN CERTIFICATE-----
MIIGnjCCBYagAwIBAgIQB1hRcQwEBmL0kIZXyjqaYzANBgkqhkiG9w0BAQsFADBN

-----END CERTIFICATE-----
subject=/C=US/ST=Ohio/L=Cincinnati/O=Losant IoT, Inc./CN=
.losant.com
issuer=/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA

No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:0x07+0x08:0x08+0x08:0x09+0x08:0x0A+0x08:0x0B+0x08:0x04+0x08:0x05+0x08:0x06+0x08:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1:DSA+SHA224:DSA+SHA1:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1:DSA+SHA224:DSA+SHA1:DSA+SHA256:DSA+SHA384:DSA+SHA512
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits

SSL handshake has read 3610 bytes and written 396 bytes

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 9A29C7AEA16B507D493C951AA970FCEFFB6FCBCE49EAC7D6D40667415242BF80
Session-ID-ctx:
Master-Key: E9EEEC80D016DB26954163565235EB0197A70F5DE1247E135E1BDFCA9000929E3BC7EE87539CA702C13C09E2B974F205
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 41 93 82 43 e7 b1 6f 61-f6 64 d7 d2 5f de 0b 02 A…C…oa.d…
0010 - 63 bf 75 0f 65 ff 4e dd-bc aa b5 02 85 d8 1b 92 c.u.e.N…
0020 - ed 6a ac 0b 31 0f 27 72-08 65 24 76 48 4c 93 a0 .j…1.'r.e$vHL…
0030 - e5 e2 38 1a e5 3c 3b 4f-68 3b e4 86 7e 5c 55 bf …8…<;Oh;…~\U.
0040 - 7d 76 ab e1 9b 83 2a 41-e9 cf 20 75 08 5f d8 08 }v…*A… u.

0050 - 38 fd 83 36 ed d7 32 38-32 0d 6f 7a 27 34 a6 04 8…6…282.oz’4…
0060 - 57 9b 94 8f b3 24 ca 12-3e bd 18 f9 e7 48 d1 0d W…$…>…H…
0070 - 22 31 1a 7a d1 67 99 98-3f 80 e8 a9 4f d6 ba 9d "1.z.g…?..O…
0080 - d5 9c 44 2a f9 60 2c 9d-34 b2 e2 86 5a 73 83 2f …D*.`,.4…Zs./
0090 - 16 51 b4 51 c9 e9 a4 0c-23 f5 38 d6 5d b7 e9 f9 .Q.Q…#.8.]…
00a0 - 22 19 9b 8e 97 cf fa c0-4a b1 0b e1 f7 b4 31 7d "…J…1}

    Start Time: 1570665869
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
closed

Ok got a little further at least with openssl

I found that install ca-certificates package (opkg install ca-certificates) openssl command connects with out the error lib(20) us unable to get local issuer certificate error

root@Teltonika-RUT955:/etc/ssl/certs# openssl s_client -connect broker.losant.com:8883 -CAfile /lib/uci/upload/cbid.mosquitto.mqtt.bridge_cafile
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = US, ST = Ohio, L = Cincinnati, O = "Losant IoT, Inc.", CN = *.losant.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=Ohio/L=Cincinnati/O=Losant IoT, Inc./CN=*.losant.com
   i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
 1 s:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA

However mosquitto broker is still unable to connect and has the same error.
It would seem the broker is unable to locate other required certificates in the certificate chain.

Will keep digging and reporting - hopefully this well help someone else too.

Ok found the solution.

The modem as a cacert bundle which can be editined through the web interface (or via commandline).

By adding all of the digicert certificates to this bundle and the specifying the bridge_cafile points to the bundle the mosquitto bridge can connect successfully using TLS.

It would seem there are not enough of the full chain of certificates present, by default. After installing them pointing capath in mosquitto.conf was insufficient. Documentation for mosquitto.conf would suggest that would work.

So point bridge_cafile to the bundle solves the issue

bridge_cafile /etc/cacert.pem

Hope this helps anyone else venturing here :wink:

T

1 Like

Lastly I had to modify the UCI services for mosquitto as it the incarnation provided by default expects

bridge_keyfile
bridge_certfile

Which we don’t have for a losant connection. So in /etc/init.d/mosquitto added conditions on each of these.

                # Use TLS/SSL for bridge connection
                if [ "$use_remote_tls" == "1" ]; then
                        echo "bridge_cafile $bridge_ca_file" >> $CONFIG
                        if [ ! -z "$bridge_cert_file"]; then
                          echo "bridge_certfile $bridge_cert_file" >> $CONFIG
                        fi
                        if [ ! -z "$bridge_key_file"]; then
                          echo "bridge_keyfile $bridge_key_file" >> $CONFIG
                        fi
                        echo "bridge_tls_version $bridge_tls_version" >> $CONFIG
                        if [ "$bridge_insecure" = "1" ]
                        then
                                echo "bridge_insecure true" >> $CONFIG
                        fi
                fi
1 Like

Hi @Tim_Hoffman,

So glad you found a solution, and thank you so much for sharing it! I know this will help someone in the future :smile:

Thanks,
Julia

1 Like