Key Exchange issue

I'm communicating with my customers website through a certificate and key provided by an OAUTH process.  I'm posting data to the website successfully by adding those certs to my TLS Credentials
   err = tls_credential_add( TLS_SEC_TAG,
                             strlen(certPtr) + 1);
   if ( err ) LOG_ERR( "Error adding GET_CLOUD_CERT" );
   param_read( PARAM_REPO_CLOUD_KEY, keyPtr, CLOUD_KEY_LEN );
   err = tls_credential_add( TLS_SEC_TAG,
                             strlen(keyPtr) + 1);
   if ( err ) LOG_ERR( "Error adding GET_CLOUD_KEY" );
   err = tls_credential_add( TLS_SEC_TAG,
                             strlen(oauth_root_ca) + 1);
I'm posting this to their site
Another process that I need to implement is to renew the keys when they are close to expiration.  To do this I need to send a GET request to using the same cert and key pair.
This is failing on my device.  It does work if I use curl;
curl -vv --key key.pem --cert cert.pem 
So I'm thinking that authentication with the cert/key is working but the key exchange is not.  I've tried enabling every exchange option that I can find;

# TLS configuration




But nothing works.  Some things seem to be out of my range because I'm using MBEDTLS_BUILTIN.  Some options seem to call for NRF_SECURITY or L2_OPENTHREAD.  I'm concerned that trying to move to any of that will cause problems with my existing setup.  I was hoping that you might be able to think of some things I can try.
  • Hi,

    For us to help you with this in the best possible way, please list the following information:

    • SDK Version
    • Development Kit Version
    • Which sample do you use?
    • Do you use custom hardware or code?

    Sigurd Hellesvik

  • It's SDK 2.5.2 on custom hardware.  But we are using the Laird Pinnacle 100 module that has a 52840 paired with the Sierra Wireless modem.  But we are using the Zephyr builtin mbedTLS library.

    The cloud provider dug into this some and has the following comments;


    For some reason Azure don't send a certificate request when using a App Service hosted in docker in Azure. Our other endpoints is hosted using Azure function and the Microsoft Identity Provider intercept the call and do a rewrite of the header. That's why it works for and not


    The are two way of do a mTLS init connection.

    1) The server ask for a certificate from the client (that's what Zephyr supports out of the box)

    2) The client send the cert inside the handshake (that's what curl does).


    It seems to be related to an Azure issue;

    Hopefully that sheds more light

  • Randall said:

    The are two way of do a mTLS init connection.

    1) The server ask for a certificate from the client (that's what Zephyr supports out of the box)

    2) The client send the cert inside the handshake (that's what curl does).

    Both can be true here, so I do not quite grasp the difference.
    The server first asks for a cert, and then the client sends it as part of the handshake?

    Do you mean by 2) that the server never requests the cert? That would be wierd as the spec says:

       The server MUST send a Certificate message whenever the agreed-upon
       key exchange method uses certificates for authentication (this
       includes all key exchange methods defined in this document
       except PSK).

    Disclaimer: I must admit that I have not looked very much at the TLS spec before so I might vert well be mistaken here

    But I still would like to know a bit more about the two different methods mentioned here.


    nvm I found this other section on certificate requests saying MAY. And that is what you are referring to:

    A server which is authenticating with a certificate MAY optionally
       request a certificate from the client.  
  • As you see from the edit on the message below, I agree that it looks possible yes.

    So I asked our crypto team if they know how to configure mbedtls for this, if possible

  • Looking at mbedtls code, it only gives the certificate if it is requested.

    However, having a another look at the spec:

    The client MUST send a Certificate message if and only if the server
       has requested client authentication via a CertificateRequest message

    So only sending cert if requested seems to align with the spec after all.

    This was a bit back and forth. Let me know if anything was unclear and what you think about this