LWM2M Client With X.509 Certificate

Hello,

I am trying to run nRF sample of cellular LWM2M client on nRF9151 development kit that communicates with a custom Leshan server over the LTE-M. Security modes of no security and PSK seem to be working without any issues in the provided samples. However, there is no sample of running cellular LWM2M with X.509 certificate. 

In the SDK v2.7.0 sample "Cellular: LwM2M Client" I have tried substituting lwm2m_security_set_psk with lwm2m_security_set_certificate without any luck. I have tried loading the certificate both with Cellular Monitor application and with lwm2m_security_set_certificate method. I also tried to follow the steps of "Lightweight M2M (LWM2M)" in Zephyr Project documentation.

Currently, the errors that I get are:

<err> lwm2m_security: No security credentials provisioned
<err> net_lwm2m_rd_client: Cannot init LWM2M engine (-2)
<err> net_lwm2m_rd_client: sm_do_network_error, retries 0
<err> net_lwm2m_rd_client: sm_do_network_error, retries 0

As I understand the certificates are not being loaded to modem properly or they are not being selected for usage.

Therefore, could you please provide a sample or instructions of how to use LWM2M with X.509?

Parents
  • Hi,

    When X.509 certificates are used, it is necessary to set up security object for X.509 certificate mode. There are several lwm2m_security_object_ids that need to be set. You can have a look at LwM2M security modes.

    Best regards,
    Dejan

  • I have seen the reference you provided, but it is not clear on how to implement it in the SDK v2.7.0 sample "Cellular: LwM2M Client". Is lwm2m_security_set_certificate still needed when lwm2m_security_object_ids are being set? Could you please provide exact instructions on how to set up X.509 security object in the scope of the "Cellular: LwM2M Client" sample.

    Thanks!

  • Hi,

    I have asked internally for more specific information with regard to your question. We will look into this. I will get back to you probably during next week.

    Best regards,
    Dejan

  • Hi,

    The easiest way to run LwM2M client in X.509 mode is to write certificates to the modem before application starts.
    1. create own root CA certificate

    ## Generate private CA certificate
     
    You only need to generate these once.
    On a commercial operations, you don't do this, but instead rely on real CA authority.
     
    openssl ecparam -genkey -name prime256v1 -out ca.key
    openssl req -x509 -new -SHA256 -nodes -key ca.key -days 3650 -subj '/O=My Company/CN=My root CA/' -out ca.crt
    
     

    2. generate certificate and private key for your client device
    ## Generate certificate and private key for the client
     
    openssl ecparam -genkey -name prime256v1 -out client.key
    openssl req -x509 -new -SHA256 -nodes -key client.key -CA ca.crt -CAkey ca.key -subj '/CN=urn:imei:<your_15_digit_imei_goes_here>/' -out client.crt

    3. flash the device with AT client sample and write certificates to the modem using nRF Cellular Monitor -> Certification Manager.
    4. build LwM2M application without default PSK key so that it uses whatever has been already provisioned
    west build -b nrf9151dk/nrf9151/ns -- -DCONFIG_APP_LWM2M_PSK="\"\""

    Best regards,
    Dejan

Reply
  • Hi,

    The easiest way to run LwM2M client in X.509 mode is to write certificates to the modem before application starts.
    1. create own root CA certificate

    ## Generate private CA certificate
     
    You only need to generate these once.
    On a commercial operations, you don't do this, but instead rely on real CA authority.
     
    openssl ecparam -genkey -name prime256v1 -out ca.key
    openssl req -x509 -new -SHA256 -nodes -key ca.key -days 3650 -subj '/O=My Company/CN=My root CA/' -out ca.crt
    
     

    2. generate certificate and private key for your client device
    ## Generate certificate and private key for the client
     
    openssl ecparam -genkey -name prime256v1 -out client.key
    openssl req -x509 -new -SHA256 -nodes -key client.key -CA ca.crt -CAkey ca.key -subj '/CN=urn:imei:<your_15_digit_imei_goes_here>/' -out client.crt

    3. flash the device with AT client sample and write certificates to the modem using nRF Cellular Monitor -> Certification Manager.
    4. build LwM2M application without default PSK key so that it uses whatever has been already provisioned
    west build -b nrf9151dk/nrf9151/ns -- -DCONFIG_APP_LWM2M_PSK="\"\""

    Best regards,
    Dejan

Children
  • Let me clarify few more things.

    When writing certificates and CA certificates to modem, please note that CA certificate that you write should be the one that is used by the target server. Not your own CA that you used to generate the client certificate.

    So then it depends on the server configuration whether it trust your own CA.
    And when you program the CA that server uses, then modem trusts the server.

    If we use Leshan as an example, you can fetch the server certificate with OpenSSL command line and use that as a CA chain that is programmed to the modem

    openssl s_client -dtls -showcerts -connect leshan.eclipseprojects.io:5684
    

    Then what comes to lwm2m_security_set_certificate(), it has a same effect as those separate writes in  LwM2M security modes. If you use that it causes certificates to be provisioned to the modem every time the client boots, which might not be wanted behaviour.

    But anyhow, here is an example how to use it. Modify the lwm2m_setup() to look like this:

    static int lwm2m_setup(void)
    {
    	/* Save power by not updating timestamp on device object */
    	lwm2m_update_device_service_period(0);
    
    	/* Manufacturer dependent */
    	/* use IMEI as serial number */
    	lwm2m_app_init_device(imei_buf);
    	lwm2m_init_security(&client, endpoint_name, NULL);
    
    	/* Security Mode */
    	static const char certificate[] =
    		"-----BEGIN CERTIFICATE-----\n"
    		"...clip..."
    		"-----END CERTIFICATE-----";
    
    	static const char key[] =
    		"-----BEGIN EC PRIVATE KEY-----\n"
    		"...clip..."
    		"-----END EC PRIVATE KEY-----";
    
    	static const char root_ca[] =
    		"-----BEGIN CERTIFICATE-----\n"
    		"...clip..."
    		"-----END CERTIFICATE-----";
    
    	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0), "coaps://leshan.eclipseprojects.io:5684");
    	lwm2m_security_set_certificate(0, certificate, sizeof(certificate), key, sizeof(key),
    				       root_ca, sizeof(root_ca));
    

Related