Verify certificate chain

I have 3 certificates:

Root cert
Intermediate cert (signed by Root)
Device cert (signed by Intermediate)

I’m trying to figure out if they form a valid chain:

what follows is pseudocode, but should be understandable.

/* Taken from mbedtls/programs/x509/cert_app.c */
static int my_verify( void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags )
{
    char buf[1024];
    ((void) data);

    log_error( "\nVerify requested for (Depth %d):\n", depth );
    mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
    log_error( "%s", buf );

    if ( ( *flags ) == 0 )
        log_error( "  This certificate has no flags\n" );
    else
    {
        mbedtls_x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
        log_error( "%s\n", buf );
    }

    return( 0 );
}

/* Start of chain  */
mbedtls_x509_crt_parse(devcrt, devcrt_char_array, length_of_devcrt_char_array);
/* Add the intermediate to the chain  */
mbedtls_x509_crt_parse(devcrt, intermediate_crt_char_array, length_of_intermediate_crt_char_array);
/* Add the root to the chain */
mbedtls_x509_crt_parse(devcrt, root_crt_char_array, length_of_root_crt_char_array);

/* Parse the root cert */
mbedtls_x509_crt_parse(rootcrt, root_crt_char_array, length_of_root_crt_char_array);

/* Verify the chain against the root */
mbedtls_x509_crt_verify(&devcert, &rootcert, NULL, NULL, &flags, my_verify, NULL)

Verify fails with error:

[my_verify:88] ERROR: Verify requested for (Depth 0):
[my_verify:90] ERROR:cert. version : 3
serial number : 01
issuer name : REDACTED , CN= Intermediate
subject name : REDACTED , CN=Device
issued on : 2019-01-28 09:14:48
expires on : 2040-01-01 09:14:48
signed using : ECDSA with SHA256
EC key size : 256 bits
basic constraints : CA=false
subject alt name : m:m:m

[my_verify:97] ERROR:  ! The certificate is not correctly signed by the trusted CA

What is strange that if I make a chain with only the intermediate cert, than i can verify that cert with the root cert and if I make a chain with only the dev cert, then I can verify the dev cert with the intermediate cert, so the certs look fine. But somehow making a chain of all 3 certs fails when I verify with the root cert.

Can someone explain what might be going on? Should I add the intermediate certificate to the trusted chain instead of only the root cert?

@mathieubordere Thank you for your question !

I have tried your pseudo code on locally, with a different certificate chain, and it worked for me.

Should I add the intermediate certificate to the trusted chain instead of only the root cert?

It is enough to have the root certificate in the trusted chain, if the intermediate is the issued by the root certificate, and it is the issuer of the device certificate.

I suggest you check you don’t have any missing configuration or any other over look.

Please add the full output of your application to understand what is wrong, and to see what the actual flags are.
Regards,
Mbed TLS Team member
Ron

In addition, I trust that when parsing the certificates you took into account the additional null character to the certificate lengths.

@roneld01 Thanks for your feedback, there was something wrong with the Intermediate certificate, after receiving an updated cert from our security engineer, the code works as expected. There was some flag missing that the Intermediate Cert was allowed to sign other certificates. Thanks for your time.