Trying to use Device Certificates

I’m trying to use Device Certificates with the MQTT interface to Cumulocity. I have things working with a TLS secured connection using password authentication. But when I try to use Device Certificates, my client (the ESP32 SDK version 5.1.4) returns unauthorized. I also tried to use the same certificates and connect using MQTTX, which also returned “unauthorized”

This is the process I use. First I generate the root certificate that I’ll be putting in the “trusted certificates” section of my cumulocity instance;

openssl genrsa -out autodoser-private-key.pem 2048

Then the sign request;

openssl req -new -key autodoser-private-key.pem -out autodoser-cert-sign-request.pem -extensions v3_req -subj "/C=US/ST=Delaware/L=Wilmington/O=Solenis/CN=*.solenis.com"

Then I create and sign the public key;

openssl x509 -in autodoser-cert-sign-request.pem -out autodoser-cert.pem -req -signkey autodoser-private-key.pem -extensions v3_req -extfile intermediate-config.cnf -days 3650

intermediate-config.cnf.txt (115 Bytes)

I put the autodoser-cert.pem in the trusted certificates, enable it and then take the verification text from the page and put it into the file verification.txt

openssl dgst -sha256 -sign autodoser-private-key.pem verification_code.txt | openssl base64 -A

I take the code generated from this and put it into the verification to confirm ownership of the key. The trusted certificate entry acknowledges this.

DEVICE_ID represents the ID of the device I’m trying to generate cert/key pair for;

openssl genrsa -out DEVICE_ID-private-key.pem 2048
openssl req -new -key DEVICE_ID-private-key.pem -out DEVICE_ID-cert-sign-request.pem -extensions v3_req -subj "/C=US/ST=Delaware/L=Wilmington/O=device/CN=DEVICE_ID"
openssl x509 -req -CA autodoser-cert.pem -CAkey autodoser-private-key.pem -in DEVICE_ID-cert-sign-request.pem -out DEVICE_ID-cert.pem -days 730 -extensions v3_req -extfile "end-user-config.cnf" -CAcreateserial

end-user-config.cnf.txt (103 Bytes)

I then use the values from DEVICE_ID-cert.pem and DEVICE_ID-private-key.pem in the authentication structures of the mqtt client library. Can you see anything wrong with my key generation?

We use certificate authentication but not using intermediate certificates; it looks like you are using the right steps. Do you have the intermediate certificate trusted as well? That’s the first thing that jumps out at me.

Sounds like I may not understand the process. I loaded the root certificate to the trusted certificate store. Then I signed my device certificate using the root certificate. I was assuming that when I send the device certificate to the cloud, it will see that it’s signed by the root certificate and accept it. Am I missing a step? Do I need to load the device certificate to the trusted certificate store?

I assume you have per-device certificates? No, per-device certificates don’t need to be loaded. But having the whole certificate chain loaded is something we encountered.

But my per device certificate is signed by the root certificate. So I shouldn’t need any intermediate certificates, should I?

Until recently you needed to send the entire certificate chain, just having the root certificate as your trust anchor and sending the device certificate was not enough, this is documented here: Device certificates - Cumulocity IoT documentation. However, recently we have shipped an improvement where Cumulocity can infer the certificate chain, in that instance you need to upload the adjacent certificate to the device certificate as your trust anchor. Unfortunately this update was not properly documented, that is in hand and the documentation will be updated shortly. You do not mention which instance you are working on, but if it is eu-latest then you should be able to use the new certificate inference.
I hope this helps, Jane Porter

1 Like

Unfortunately, no. I’m signing my device certificate directly with the trusted root. One error I did notice is that I seem to have conflated intermediate certificate creation with root certificate creation and I was signing my root certificate with itself! lol. So I stopped doing that, I placed the following steps;

openssl req -new -key autodoser-private-key.pem -out autodoser-cert-sign-request.pem -extensions v3_req -subj "/C=US/ST=Delaware/L=Wilmington/O=Solenis/CN=*.iot-dev.solenis.com"
openssl x509 -in autodoser-cert-sign-request.pem -out autodoser-cert.pem -req -signkey autodoser-private-key.pem -extensions v3_req -extfile intermediate-config.cnf -days 3650

with

openssl req -config root-config.cnf -key autodoser-private-key.pem -new -x509 -days 7300 -sha256 -extensions v3_req -out autodoser-cert.pem -subj "/C=US/ST=Delaware/L=Wilmington/O=Solenis/CN=*.iot-dev.solenis.com"

unfortunately, I’m still getting “connection refused, not authorized”. So I’m still stuck

The instructions I have for creating my device credentials are somewhat old and I can’t find them on the cumulocity website anymore. You have a new page on creating credentials that ups it to a 4 Kib key and the method requires a password on the key and forces a serial numbering convention that will not work with our manufacturing. I might be able to live with the password, but if you can help me to figure out how to get rid of the automatic serial number assignment that allows me to write in my own, that would be very helpful.

HI Can you please send the link to the documentation you are using, can you also confirm which Cumulocity instance you are using.
Thanks, Jane.

The instructions I’m currently using no longer exist, but I put the steps in my original post. The current documentation is;
https://cumulocity.com/guides/device-integration/mqtt/#device-certificates

But I don’t know how to modify it to suite my needs.

How can I confirm the cumulocity instance? Can I give you the tenant ID? It’s a company specific instance.

Thanks,

I have 2 trusted certificates loaded and verified up in my system. The only thing that I seem to be missing is how to generate a device key/certificate pair that will be acknowledged by the system.

Using my 2 Kib key (the version of esp32 sdk I’m using, doesn’t seem to like 4 Kib keys), the following is the description of the root certificate that I’ve loaded to the trusted certificate page and verified ownership;

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            68:03:ae:30:c4:4e:8a:4f:3a:e9:81:46:16:1c:6c:7d:96:78:74:3a
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Delaware, L = Wilmington, O = Solenis, CN = *.iot-dev.solenis.com
        Validity
            Not Before: Sep 16 17:57:50 2024 GMT
            Not After : Sep 11 17:57:50 2044 GMT
        Subject: C = US, ST = Delaware, L = Wilmington, O = Solenis, CN = *.iot-dev.solenis.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:90:d9:3c:98:58:d0:6e:e1:35:cc:94:07:ca:09:
                    72:fc:bf:1a:7f:61:01:08:8d:5c:a5:25:e9:df:41:
                    c8:cc:bc:a9:dd:b0:72:8d:d6:54:df:f3:c0:8a:85:
                    c9:6f:96:59:f4:4a:33:5d:2d:18:d4:65:e6:f8:cc:
                    13:f5:a9:74:fd:ca:28:02:b0:0e:bb:f3:f6:23:ff:
                    a9:fd:32:c7:75:ac:52:73:a5:66:be:64:e9:61:02:
                    8d:6c:22:0f:e9:23:27:f1:88:53:13:34:0e:0a:63:
                    45:e5:4e:79:45:03:5d:9a:ed:6c:f0:73:e2:bd:d5:
                    69:65:1f:06:69:86:ce:9c:40:94:71:0f:7c:8b:40:
                    23:d7:9b:88:11:02:15:06:89:57:7d:69:91:f7:94:
                    a9:d2:4b:0e:c5:d8:a0:6e:95:ec:10:d6:02:b4:b5:
                    86:3b:ca:06:f9:8d:db:0c:c0:56:35:59:ba:5a:dc:
                    89:3c:af:2e:9f:45:fa:fe:18:d5:03:a9:be:a6:49:
                    74:77:8c:63:70:67:bc:43:38:bf:2c:26:e3:1f:c7:
                    48:36:3a:b6:29:9a:15:8a:9a:d2:2b:70:d3:87:e0:
                    6d:ad:3e:c7:ca:dc:e5:a1:36:f4:5e:59:85:6f:17:
                    4b:cb:ac:0f:66:fb:62:0f:8d:da:99:ba:23:16:a2:
                    eb:5d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:TRUE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment, Certificate Sign
            X509v3 Subject Key Identifier:
                D0:96:CE:48:E6:B1:F0:DF:A4:DE:CB:E7:FA:0C:DB:62:A4:2B:0C:CF
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        53:04:0d:bd:d4:44:41:9a:08:0c:9f:c0:8f:00:8f:1e:c2:92:
        7c:f0:63:86:84:27:e7:80:2a:0d:5c:53:64:96:9c:6b:a2:13:
        8c:1a:e1:d8:74:ec:fa:ee:df:0d:31:c0:b2:6f:4f:3c:80:a7:
        bf:06:e3:27:3a:15:94:c6:bf:a8:2a:a4:34:a5:ac:f7:ca:7b:
        7b:b5:91:53:e7:7f:d9:7b:88:d9:43:35:3b:d9:f4:21:ae:eb:
        ab:55:be:ea:0a:b4:f8:a1:02:64:2b:7a:60:f7:d9:b0:f2:80:
        fc:a0:86:61:61:45:ef:ee:5c:85:a5:d8:7c:21:8f:f4:26:39:
        f9:73:fe:fe:28:82:41:c2:9b:1a:8a:1e:24:6a:cd:6d:3e:0e:
        7c:12:e5:03:d0:2f:0b:c8:5a:36:f9:2f:fb:52:1e:c6:30:3e:
        c5:59:0e:bf:0b:d3:f2:49:96:cc:eb:25:41:ec:3c:1e:3e:45:
        40:90:b2:09:e7:dd:db:59:98:3e:74:bc:72:98:93:1c:aa:d2:
        39:e5:6a:15:88:f3:63:44:cc:aa:5d:d8:bc:e4:70:56:35:68:
        51:0f:6b:88:6c:61:53:a7:ed:1f:5b:c0:20:98:28:a5:22:2e:
        29:f6:2b:45:a9:ab:05:d8:c3:84:13:3a:60:81:07:d4:e0:75:
        d4:1f:74:7a

The following is the description of the device certificate I’m using with my device;

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            53:ab:d4:f3:fc:ee:77:f6:77:7d:df:ca:58:df:fd:7a:eb:7e:f3:cc
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Delaware, L = Wilmington, O = Solenis, CN = *.iot-dev.solenis.com
        Validity
            Not Before: Sep 16 18:02:23 2024 GMT
            Not After : Sep 16 18:02:23 2026 GMT
        Subject: C = US, ST = Delaware, L = Wilmington, O = device, CN = S2422700003
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:86:e2:69:d3:9a:36:4a:ae:b0:20:2c:a2:64:22:
                    5c:5e:0e:fd:7b:96:b9:17:f0:11:b0:07:b5:18:a8:
                    d2:84:cb:cb:df:1d:5c:19:58:86:ed:7b:30:6a:3d:
                    67:87:8e:83:b6:f6:3c:21:4b:27:9d:93:ef:85:52:
                    d0:a1:aa:04:cd:59:5a:f9:d1:90:95:3a:7e:2c:8d:
                    50:44:ba:60:49:98:f3:91:30:6f:c5:d6:90:a4:20:
                    38:40:fc:7a:dc:ed:98:05:24:17:3e:82:85:e7:00:
                    4a:c1:26:51:15:b9:79:c4:11:22:71:a7:d5:a8:65:
                    1b:c1:22:78:01:8a:c6:f2:59:24:27:e1:08:33:82:
                    18:f9:76:98:8a:10:a5:6b:56:ce:a8:50:d6:48:0d:
                    6f:f1:68:ec:42:31:cf:20:92:3a:7e:7b:0e:0c:d2:
                    0a:ad:e9:53:b6:e5:7f:04:0b:3a:3e:9d:85:29:a2:
                    d4:57:93:ca:6b:73:40:e7:30:d2:14:e8:fa:a0:25:
                    86:c0:c7:d6:ec:3f:fb:c9:53:e7:ee:a2:68:cc:b3:
                    27:45:99:79:63:97:f3:fa:07:c9:1e:ec:df:a9:7a:
                    2b:6b:de:f0:b5:94:eb:96:18:49:06:b8:83:81:d6:
                    60:29:0e:32:d7:92:79:2d:0a:3e:45:e8:46:fc:76:
                    2f:b3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Key Identifier:
                93:2E:D6:32:35:45:53:06:FF:79:91:A0:96:77:4E:F5:22:E2:69:D1
            X509v3 Authority Key Identifier:
                D0:96:CE:48:E6:B1:F0:DF:A4:DE:CB:E7:FA:0C:DB:62:A4:2B:0C:CF
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        6f:40:ca:ed:38:3e:47:35:c1:4d:fb:0c:c8:93:e9:6c:3e:4a:
        09:b4:87:84:58:ad:a5:a4:ad:68:de:a4:34:ff:ab:29:64:48:
        c0:83:15:22:3a:e6:a7:cb:81:4a:e9:1d:c7:11:8a:9d:57:4b:
        f9:41:53:db:70:76:8f:9c:80:e1:c6:b7:26:86:5e:ad:1c:1c:
        5b:45:94:93:6e:4f:6c:90:62:b1:a3:26:6d:b7:69:f8:09:12:
        27:7b:bb:1c:7c:44:7a:cf:e7:a6:ab:b1:a6:ef:17:fc:33:0e:
        ee:23:4d:aa:9e:c6:58:a5:24:82:47:3b:60:53:5c:0b:7c:8e:
        1e:39:9a:22:3f:d6:ef:7d:01:fd:82:87:fe:a0:b8:82:ca:83:
        02:07:26:f0:15:6d:1e:a5:bc:2e:bd:67:f4:1e:d2:da:b5:fd:
        ea:38:e0:74:b7:ae:d5:d8:ce:ad:61:02:e5:a0:33:4a:1f:f2:
        a2:b4:6a:38:77:66:a2:f4:e8:6a:75:8a:0a:b8:71:64:1f:23:
        63:bd:94:d4:0f:b7:6b:ac:e7:fd:15:3e:d5:29:97:46:24:30:
        2a:9b:fb:f7:90:3a:3a:8c:27:34:1d:e7:82:6a:9d:15:9b:8c:
        b4:c4:cb:bd:2f:e5:a7:e2:96:91:1a:76:5d:d9:3c:cb:c6:d9:
        12:16:1a:c3

The authority key identifier is D0:96:CE:48:E6:B1:F0:DF:A4:DE:CB:E7:FA:0C:DB:62:A4:2B:0C:CF
Which to me indicates that it is indeed signed by the root in the trusted certificate store. So I’m very confused as to why is isn’t working.

I discovered this snippet in the cumulocity documentation;

Does it only support 1 at a time? username/password authentication is working, does this mean that the IT team has disabled 2-way certificate authentication?

I rediscovered the source from where my original device credential creation came from;

I hope you haven’t given up on me with this. I’ve confirmed with IT that we have 2-Way SSL enabled.

It might be helpful to use thin-edge.io to check if your tenant can support 2-way SSL as thin-edge.io supports certificate based authentication out of the box, so if thin-edge.io works, then it will help you focus on what is wrong in the setup.

You can checkout the thin-edge.io docs for general information about the open source project, or just jump straight into the tedge-demo-container project that we’ve created to spin up a thin-edge.io container and connect it to your tenant in less than 60 seconds (assuming you have docker and docker compose installed).

And if you don’t want to use thin-edge.io to help debug, then below are some general pointers about using certificate based authentication with Cumulocity IoT:

  • Check that the trusted certificate has “auto registration” enabled
  • Check that the device’s public certificate has the full chain (with the device’s certificate at the start of the file, and then work up the certificate chain include the public certificate which is uploaded to the trusted certificates in Cumulocity IoT)…For example, if you have uploaded the intermediate cert to Cumulocity IoT Trusted Certificates, then you need to have: <device_cert>\n<intermediate_cert>. Or if you have uploaded the root certificate, then you need to also append the root certificate as well.
  • If you’ve registered a device credentials using the username/password (e.g. the “classic” device registration process), then you can’t use the same user for 2-way SSL. You will have to use a new external identity (of type c8y_Serial) for the device.
1 Like

OK, well none of the specific items worked, so I tried things with the thin-edge.io. I got it to work but I noticed that it didn’t have anything to setup a root certificate in the trusted certificate store and sign device certificates with, but rather self-signed the device certificate with CA:true and used that. When I did that with my device, certificates started working.

I was hoping to only have to load 1 trusted certificate to the store and as long as all my device certificates were signed by that root, it would work but that appears not to be the case even though the cumulocity documentation indicates that it should be.

So, I guess I’ll consider this closed and just have a process for putting every device certificate into the store. No what I was hoping for, but I guess it’s what I need to do.

Just to be clear, thin-edge.io also certificates which are signed by a root or intermediate certificate, however you do currently have to do the signing yourself (or using some PKI etc.).

But getting everything to work is not trivial, but the rough steps are as follows:

  1. Create a root certificate
  2. Create an intermediate cert (signed by the root cert)
  3. Upload the intermediate cert to Cumulocity IoT Trusted Certificates
  4. Create a device certificate (signed by the intermediate cert, and the device cert MUST be a leaf certificate, e.g. basicConstraints=CA:FALSE)
  5. Append the public intermediate certificate to the device’s public certificate (to create a certificate chain)
  6. Use the device certificate to connect to Cumulocity IoT using MQTT on port 8883

If you’re after the openssl commands used for most of the steps then you can have a look at a utility that the thin-edge.io team created to help with this (though it might be slightly difficult to read as it is also generating other certificates to enable mtls for components in the local network) - See our tool here: tedge-bootstrap

I don’t know. It seems like most of the cumulocity documentation and the advice I’ve been getting regarding device certificate has been wrong so I’m just going to stick with making the device certificate the root and loading them all into the trusted certificate store for now. I may go back and experiment with intermediate certificates later if I have the time. But I’m considering the topic closed for now.