This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

The function modem_key_mgmt_cmp() fails to identify valid certificate

Hi,

I'm running of the fw-nrfconnect-nrf master branch (commit: 96e75dba598320c2707dede3ffef44bf326a89e3) because there are some improvements since the release of SDK v1.2.0 that are of use to me. I'm testing the http_application_update sample in the nrf9160-dk v0.9.0 and modem firmware v1.2.0.

Recently, I have been trying to make use of one of the latest additions: the function modem_key_mgmt_cmp() in the Modem Key Management library. However, on my tests this function is failing to identify valid certificates already commissioned to the modem and always returns 1 (meaning that there is a mismatch between the length of the certificates read from the modem and the ones my app is trying to compare). In fact, this function seems to fail at:

/* Compare the size first, it's cheap */
at_params_size_get(&cmng, AT_CMNG_CONTENT_INDEX, &size);
if (size != len) {
	LOG_DBG("Credential length %d bytes (expected %d)", size, len);
	at_params_list_free(&cmng);
	return 1;
}

This is what I get on the debug console:

D: Credential length 0 bytes (expected 2171)

As the returned length of the certificates in the modem is always 0, I suspect that at_params_size_get() is not returning the correct length for some reason, even though I've checked that the certificates are present in the modem.

The following code snippet can be used to reproduce this behavior:

int cert_provision(const char* cert, const u32_t cert_len, enum modem_key_mgnt_cred_type cred_type)
{
	int err;
	bool exists;
	u8_t unused;

        /* Check if the certificate/key already exists in the modem */
	err = modem_key_mgmt_exists(TLS_SEC_TAG, cred_type, &exists, &unused);
	if (err) {
		printk("Failed to check for certificates err %d\n", err);
		return err;
	}

	if (exists) {         
          /* Check if the certificate/key under the same tag matches the certificate to be provisioned */
          err = modem_key_mgmt_cmp(TLS_SEC_TAG, cred_type, cert, cert_len); 
          if (err) {
            printk("Certificate/key mismatch. Deleting existing certificate/key..., err %d\n", err);
            
            /* Delete the existing certificate/key in case of mismatch */
            err = modem_key_mgmt_delete(TLS_SEC_TAG, cred_type);
            if (err) {
                  printk("Failed to delete existing certificate/key, err %d\n", err);
            }
          } else {
            
            /* The certificate/key already exists in the modem and matches the certificate to be provisioned */
            printk("Valid Certificate/key found.\n");
            return 0;        
          }      
	}     
             
        /* Provision certificate/key to modem */
        printk("Provisioning certificate...\n");

        /*  Provision certificate to the modem */
        err = modem_key_mgmt_write(TLS_SEC_TAG, cred_type, cert, cert_len);
        if (err) {
                printk("Failed to provision certificate/key, err %d\n", err);
                return err;
        }

	return 0;
}

To use the snippet, call:

static const char CA_CERT[] = {
#include "../cert/ca.crt"
}; 
BUILD_ASSERT_MSG(sizeof(CA_CERT) < KB(4), "CA Certificate too large");
static const u32_t CA_CERT_LEN = sizeof(CA_CERT) - 1;

cert_provision(CA_CERT, CA_CERT_LEN, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);

Thanks,

Best Regards,

TC

  • Hi!

    Sorry for the delayed reply, I've been taking a look at this with a developer. I am unfortunately not able to reproduce your error, so I'll need some debug information from you.

    If you add CONFIG_AT_CMD_LOG_LEVEL__DBG=y to your project, you should get you a message like "Sending AT%CMNG=<>". I need you to flash an NCS sample that allows you to send AT commands directly to the modem and then and send that specific AT command and see what the output is. 

    Best regards,

    Heidi

  • Hi Heidi, thanks for getting back to me. I've added AT CMD Level debug to my http_application_update example and got the following output:

    *** Booting Zephyr OS build v2.1.99-ncs1-1145-g13dc96f83bab  ***
    HTTPS application update sample started v1
    Initializing bsdlib
    Initialized bsdlib
    D: Setting notification handler to 0x0003952d
    D: Common AT socket created
    D: Common AT socket processing thread created
    D: Sending command AT+CMEE?
    DD: Awaiting response for AT+CMEE?
    : AT socket thread started
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: at_cmd_rx 15 bytes, +CMEE: 0
    OK
    
    D: Bytes sent: 8
    D: Sending command AT+CMEE=1
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT+CMEE=1
    D: at_cmd_rx 5 bytes, OK
    
    D: Bytes sent: 9
    D: Sending command AT%CMNG=1,24514698,0
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT%CMNG=1,24514698,0
    D: at_cmd_rx 91 bytes, %CMNG: 24514698,0,"0000000000000000000000000000000000000000000000000000000000000000"
    OK
    
    D: Bytes sent: 20
    D: Sending command AT+CMEE=0
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT+CMEE=0
    D: at_cmd_rx 5 bytes, OK
    
    D: Bytes sent: 9
    D: Sending: AT%CMNG=2,24514698,0
    D: Sending command AT+CMEE?
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT+CMEE?
    D: at_cmd_rx 15 bytes, +CMEE: 0
    OK
    
    D: Bytes sent: 8
    D: Sending command AT+CMEE=1
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT+CMEE=1
    D: at_cmd_rx 5 bytes, OK
    
    D: Bytes sent: 9
    D: Sending command AT%CMNG=2,24514698,0
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT%CMNG=2,24514698,0
    D: at_cmd_rx 2265 bytes, %CMNG: 24514698,0,"0000000000000000000000000000000000000000000000000000000000000000","-----BEGIN CERTIFICATE-----
    MIIGFzCCA/+gAwIBAgIUN6ec2FP/QL5ASPNvIjpjSvsNZv4wDQYJKoZIhvcNAQEL
    BQAwgZoxCzAJBgNVBAYTAlBUMQ4wDAYDVQQIDAVQb3J0bzEaMBgGA1UEBwwRVmls
    YSBOb3ZhIGRlIEdhaWExFjAUBgNVBAoMDVVyYmFuIENvbnRyb2wxGTAXBgNVBAMM
    EHVyYmFuLWNvbnRyb2wucHQxLDAqBgkqhkiG9w0BCQEWHXRpYWdvLmNvc3RhQHVy
    YmFuLWNvbnRyb2wuY29tMB4XDTIwMDUwODA4MzE1OFoXDTQ4MDUyMTA4MzE1OFow
    gZoxCzAJBgNVBAYTAlBUMQ4wDAYDVQQIDAVQb3J0bzEaMBgGA1UEBwwRVmlsYSBO
    b3ZhIGRlIEdhaWExFjAUBgNVBAoMDVVyYmFuIENvbnRyb2wxGTAXBgNVBAMMEHVy
    YmFuLWNvbnRyb2wucHQxLDAqBgkqhkiG9w0BCQEWHXRpYWdvLmNvc3RhQHVyYmFu
    LWNvbnRyb2wuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzmAR
    0MNN2Ik+uMVYXOKgHqqcI3nChl9VE0k+9TJFTxfSiL1Cl16mi7hSWx3YjjGvRLA0
    FRsm1MHpDie9GF0yUdl2rmmLlx+msNu0i07qZpgWVd5L5O/OaEDMUtCe2RQ9BeHU
    5oueW2oYuwocDtoDg+2J0CUiB2MiudH9IRIcotFzLcxnLa4yIfEKQtbbQofC0c3U
    X33HiQDZkMlhanIo6dn4ITsrxbHG0hj2xQJ6KWlYlzI8QTGxxipzf4dYSC0JeYFO
    uwZrubNiHZ+FB7XCCSU2+vCIcRQ/XPgFm7/YnQuXXQv1Tk67pwnC5imh5XhscpKe
    UkFuejyWNGsTVptRUxkd0jx0NJcmSoGQrsiTOGHkteNomvJF6SbQd4JgxWB/pMsH
    tYi1XmYJfIo00dbzUftGDhjbcVKHxMg1p18OzbiDzsJsO+Qq2c5BgzrDjf0EIwHb
    MIBkrO78SjWxfdPWFq7a72LPCxaQ4/Q+yFDddnOEBfWy7nxRqlGhEfwNaF0ORB3m
    ULG0WDpXuySyqsCEj1VUH5v/qTxuVYeVf389g3VT3FjHCAMEUR92rmk+MX6G6xFE
    IBg5CTazbFjpzpIJevRFITTnipyeES6kLC0aBcKFNgc2cDbuSKAfkC/JxSopwJRq
    ZzTnp8NC5Wp5BHUnWtvlwLx+rf5zEF9DNl+tHykCAwEAAaNTMFEwHQYDVR0OBBYE
    FEu1g2lXCONMLcDGZwcjNf64QtGqMB8GA1UdIwQYMBaAFEu1g2lXCONMLcDGZwcj
    Nf64QtGqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAG0xHXli
    l4d9lud8Ub0BbHy26o02Ye7Q8RNG1g8USwynHKbaw+Y4ceG/KRpQQJLBaNSTQyuD
    8/9hTulJt7iS1aBdckiJWZzkhTu0H13QmDIwmphTkhZLaf2ffQvHp0M1kLiiTvxk
    s7WDOEgw2bPhzUeul2Opvy8I2gGVBL5h5qp2Gm4WRDDMUK6YnJ0yINRmO307GdK9
    688svP2WZG9S7OLX+40BJmi4FLdXI4mUyDzLJIx2yFTHLBxdc+rldUeK1WFB+g17
    g4t3MvbBM1Nfa/CONRtJlxVommn0t+KDbXmGnBOWgL5kmjSjkOyyDfLS191wRagv
    5T8LFZFYSKCnZWg/ZTaIlja70vtYLW0vzDKs2COeqnrrc9eAQhFmD3Idw0FrM9zR
    Vsz6bKdcG3oMTs6goFEmPJVLgXsNHLtCKMfpgYL8TcoK/sOclQEIIzn0iMbhTSE6
    fyPtr56BiYrFSHP3ONTf6G3lauWAUg/+6QZOinUK0dFgumEfUJoriwKZoeD37M25
    ZdgpnMvsPOlmJfSpBEKsVw8vkdbj7jpAvM1VCS2XPzctU+tuz49yh9ldXHwJiWCo
    AA9uRd6aAbzFmH/JIHYBaFgSyV1ft8tEFPthX7mS+nltNdthVb7lXVySzcULXR4J
    XDMjezxXeiOjLp2lVe8yUTMEVxX0OmmYAKVJ
    -----END CERTIFICATE-----
    "
    OK
    
    D: Bytes sent: 20
    D: Sending command AT+CMEE=0
    D: Allocating memory slab for AT socket
    D: Allocation done
    D: Awaiting response for AT+CMEE=0
    D: at_cmd_rx 5 bytes, OK
    
    D: Bytes sent: 9
    D: Credential length 0 bytes (expected 2171)
    Certificate/key mismatch. Deleting existing certificate/key..., err 1
    
    (...)

    Please let me know if you also want me to send the command manually to the modem.

    Thanks,

    TC

  • Hi, thank you.

    It looks like this might be a bug at the AT Command parser level: either it's filling the incorrect size, or it's not able to parse the response from the modem. The developers will have a look either tomorrow or the beginning of next week, and I'll let you know as soon as we find the root cause of this. 

    Best regards,

    Heidi

  • Hi Tiago, AT commands are put on the heap when parsed, and  if no memory is available the `at_cmd_parser` won't report and error :/

    Try to increase the heap and see if the problem is solved.

Related