Is there a way to quickly identify a data block is indeed a X.509 cert?

I have an embedded web server running on a 32-bit MPU. Right now a user can upload a new firmware image for the MPU firmware update. I would like to provide the ability to update/add root certificates. The part of code that handles the data storage doesn’t care what the data is. It simply stores them into an external SPI Flash chip. For the reading part, I’d like to identify if this block of data is a X.509 cert, DER or PEM before treating it as a firmware image. Does mbedTLS have an API that can do the job? I don’t have a file system mounted on the external SPI Flash memory, so there is no filename or directory structure etc…

Hi @acpie360
Do you mean mbedtls_x509_crt_parse()?
This function parses an input buffer as an X509 certificate. If the parsing succeeds, then it means it’s indeed an X509 data block.
Mbed TLS Team member

Ron, thanks. If mbedtls_x509_crt_parse() fails, do I still need to call mbedtls_x509_crt_free() ?

As you can see from the code, on every failure, a call to mbedtls_cx509_crt_free() is called, so you don’t have call it upon failure.

Ron, I wonder if you can suggest the best way of handling this - I am having trouble with mbedtls_x509_crt_parse() when my block of data is in PEM format. The problem on my side is that the PEM formatted data, when uploaded as-is, does not have the NULL terminator. This causes the parser to fail on this statement

    if( buflen != 0 && buf[buflen - 1] == '\0' &&
    strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
    buf_format = MBEDTLS_X509_FORMAT_PEM;

Would that be a problem if I remove the buf[buflen - 1] == ‘\0’ check inside the parser? Alternatively I can specify we only support DER format. What do you think? Thanks.

It is better not to remove this check, as it is expected in the code.

You can disable PEM altogether in your code, and this will reduce RAM usage and code size as well.
However, you can also add the nul terminator once you upload the PEM certificate, prior to parsing, can’t you?

Ron, thanks for the reply. I ended up calling mbedtls_x509_crt_parse() twice. If the first call fails, call the same function again with (size + 1) where buffer[size] has ‘\0’. If it fails too, then this block of data is not an X.509 cert. The execution goes to a different path.