Mbedtls_x509_crt_verify 2700 on embedded platform

I am trying validate one root CA and one Intermediate CA signed by root CA.

On linux PC, it is working fine, But on arm based embedded platform mbedtls_x509_crt_verify function is -0x2700 . What could be possibly went wrong. Using valgrind profiled the memory utilization - found to be 12 kb on heap 16kb on stack.

I configured my RTOS to have even more like 32k for each and still getting this error. What else would went wrong, any help would be appreciated.

On Linux platform: parsing & verification success
On embedded platform: Parsing trusted cert & verify cert are successful, but verification failed with error return -0x2700 and flag 512.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "mbedtls/x509_crt.h"

int main()
{
int ret;     uint32_t flags;
uint8_t BufDEVICECert[] = DEVICE_RSA_CERT; //preprocessor
uint8_t BufCaCert[] = ROOT_CA_RSA_CERT; //preprocessor

mbedtls_x509_crt CtxDEVICECert;
mbedtls_x509_crt CtxCaCert;

mbedtls_x509_crt_init( &CtxDEVICECert );
mbedtls_x509_crt_init( &CtxCaCert );

printf( "Parsing DEVICE.Cert " );
if( ret = mbedtls_x509_crt_parse( &CtxDEVICECert, BufDEVICECert,
                                  sizeof(BufDEVICECert) ) )
    printf( "ret-code: 0x%04x \r\n", -ret );
printf( "Parsing Ca.Cert " );
if( ret = mbedtls_x509_crt_parse( &CtxCaCert, BufCaCert,
                                  sizeof(BufCaCert) ) )
    printf( "ret-code: 0x%04x \r\n", -ret );
printf( "Verify DEVICE.Cert " );
ret = mbedtls_x509_crt_verify( &CtxDEVICECert, &CtxCaCert, NULL,
                               NULL, &flags, NULL, NULL );
printf( "ret-code: 0x%04x \r\n", -ret );
return ret;
}

Thanks,
Gopi Krishnan

Hi @gopi219
The flag 512 is 0x200 which is MBEDTLS_X509_BADCERT_FUTURE.
This probably means that the system time in your device is not set correct.
Regards,
Mbed TLS Support
Ron

Thank you, It is working with time disabled from config.h.

Now, I am writing my custom function to obtain timestamp in uint32_t UnixGMT, May I have any resource how to integrate that with mbedtls library so that mbedtls_x509_crt_verify will use my-custom-build-fn to get current time for validation.

Hi @gopi219

In this article you should find explanation how to set your own implementation of mbedtls_time() .

However, in x509 verification, you will also need support for gmtime_r. Is this available in your system? If not, you should follw instructions in here for how to define mbedtls_platform_gmtime_r().

Regards

I have such a function. uint32_t u32GetEpoch() manages to return platform time in GMT format. However, bit confused in defining MBEDTLS_PLATFORM_GMTIME_R_ALT macro.

Shall I simple add #define MBEDTLS_PLATFORM_GMTIME_R_ALT u32GetEpoch but config.h or platform.h

    struct tm *gmtime_r(const time_t *timep, struct tm *result);

Our OS & it library don’t have these data types. How could we port platform_time

Hi @gopi219

Shall I simple add #define MBEDTLS_PLATFORM_GMTIME_R_ALT u32GetEpoch but config.h or platform.h

No, as mentioned here, you will need to implement a thread safe function mbedtls_platform_gmtime_r() which will wrap u32GetEpoch.
Note that this function should be thread safe across all the system, as gmtime_r behaves.
if u32GetEpoch is already thread-safe, then you only need to call this function, with the relevant parameters.

Regards

I have Configured them

config.h

#define MBEDTLS_HAVE_TIME
#define MBEDTLS_HAVE_TIME_DATE
#include “time_ALT.h”
#define MBEDTLS_PLATFORM_TIME_MACRO time_ALT
#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t

And implemented

time_t time_ALT( time_t *t )
{
   time_t lt = (time_t)u32ComputeTime();    // platform fn that compute current time based on uptime and last synced unix-gmt with peer
   if( NULL != t)
   {
      *t = lt;
   }
#if DEBUG_ENABLE
   printf("<timer:%d>", lt);
#endif
   return lt;
}

The application I used with Certificate v1 is perfectly working fine. However, after chainging the PKI with Certificate v3, it is stopped working.

To make the verification success, I need to comment all time/date related functions above, so that date/time validty check is skipped.

While calling the below function, I tried pringing debug time_ALT. It could able to print correct time. However the verify funtion fails with -2700 and flag 1. as below

mbedtls_x509_crt_verify
<timer:1579788907>
<timer:1579788908>
<timer:1579790514>
<timer:1579790516>
<timer:1579790518>
VerifyFlag: [1:-2700]failed! i32X509StoreVerify: -2700
<6>Waiting for certificateÿ

And my mbedtls_platform_gmtime_r function as follows in platform_util.c

#if defined(MBEDTLS_HAVE_TIME_DATE) && defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)

/* Include platform implementation of header(time_ALT.h) */
#include “time_ALT.h”

struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
{
struct tm *tmm_buf = gmtime(tt);

tm_buf->tm_year = tmm_buf->tm_year + 1900;
tm_buf->tm_mon = tmm_buf->tm_mon + 1;

return tm_buf;
}

Any help to rectify this would be appreciated.

Thanks,

Hi @gopi219
The error and flag means that the certificate verification failed because it expired.

Why have you added 1900 to the year amd 1 to the month? Note that mbedtls_platform_gmtime_r should behave like gmtime_r which is, in short, threadsafe gmtime, so you shouldn’t add these values.

As you can see in the implementation of x509_get_current_time(), these values are added the the structure returned by your function, so your certificate has expired, probably because its expiration date was before 2020 + 1900 = 2920, I assume:)
Regards

Thanks, I’ll try and let you know.

Thank you,

Adding more detail to help anybody else is facing similar problem:

struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
{
struct tm *tmm_buf = gmtime(tt);

tm_buf->tm_year = tmm_buf->tm_year + 1900;
tm_buf->tm_mon = tmm_buf->tm_mon + 1;
tm_buf->tm_mday = tmm_buf->tm_mday;
return tm_buf;
}

Hi @gopi219
Thanks for sharing your solution.
Do I understand that you were missing the tm_mday part? Hasn’t the addition of 1900 to the year caused problems in the certificate verification, due to x509_get_current_time()?
Regards

struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
                                      struct tm *tm_buf )
{
   struct tm *tmm_buf = gmtime(tt);
   tm_buf->tm_year = tmm_buf->tm_year;
   tm_buf->tm_mon  = tmm_buf->tm_mon;
   tm_buf->tm_mday = tmm_buf->tm_mday;
   tm_buf->tm_hour = tmm_buf->tm_hour;
   tm_buf->tm_min  = tmm_buf->tm_min;
   tm_buf->tm_sec  = tmm_buf->tm_sec;

   return tm_buf;
}
1 Like