cx509mbedtls

mbedtls DER formatted certificate chain verification


I am trying to verify a certificate chain using mbedTLS version 2.16.2. The certificate chain in DER format as individual files. The PKI is simple as three levels (1) Root_CA (2) Intermediate_CA (3) Device_CERT

I could able to verify the certificates using openssl verify --- command ; but with below program, the certificate verification fails with Error: -0x2700; flag: 8

Am I verifying the cert chain (DER formatted files) the correct way?

void verify_cert_chain_driver( void )
{
   int32_t r = -1; uint32_t flags = 0;

   mbedtls_x509_crt ca, chain;

   do{

      r = parse_from_file( &ca, "x509-root-ca.der" );
      if( EXIT_SUCCESS != r )    break;
      
      r = parse_from_file( &chain, "x509-intermediate-ca.der" );
      if( EXIT_SUCCESS != r )    break;

      r = parse_from_file( &chain, "x509-dev-cert.der" );
      if( EXIT_SUCCESS != r )    break;

      r = mbedtls_x509_crt_verify( &chain, &ca, NULL, NULL, &flags, NULL, NULL );
      if( EXIT_SUCCESS != r )    break;

      printf( "Verify OK\r\n" );
   }while(0);

   if( 0 != r )  printf( "Error: 0x%04x; flag: %u\r\n", r, flags );
}

Solution

  • The sample code for cert_app.c provides a nice verification callback called my_verify as well as a snippet to extract better error information via mbedtls_x509_crt_verify_info.

    If you then apply the above points, your code would look something like this:

    #include <stdio.h>
    #include <stdint.h>
    #include "mbedtls/platform.h"
    #include "mbedtls/entropy.h"
    #include "mbedtls/ssl.h"
    
    //taken from https://github.com/Mbed-TLS/mbedtls/blob/development/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);
    
        mbedtls_printf("\nVerify requested for (Depth %d):\n", depth);
        mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
        mbedtls_printf("%s", buf);
    
        if ((*flags) == 0)
            mbedtls_printf("  This certificate has no flags\n");
        else {
            mbedtls_x509_crt_verify_info(buf, sizeof(buf), "  ! ", *flags);
            mbedtls_printf("%s\n", buf);
        }
    
        return (0);
    }
    
    
    void verify_cert_chain_driver(void) {
        int32_t r;
        uint32_t flags = 0;
    
        mbedtls_x509_crt ca, chain;
    
        mbedtls_x509_crt_init(&ca);
        mbedtls_x509_crt_init(&chain);
        do {
    
            r = mbedtls_x509_crt_parse_file(&ca, "x509-root-ca.der");
            if (EXIT_SUCCESS != r) break;
    
            r = mbedtls_x509_crt_parse_file(&chain, "x509-dev-cert.der");
            if (EXIT_SUCCESS != r) break;
    
            r = mbedtls_x509_crt_parse_file(&chain, "x509-intermediate-ca.der");
            if (EXIT_SUCCESS != r) break;
    
            //see https://github.com/Mbed-TLS/mbedtls/blob/development/programs/x509/cert_app.c
            if ((r = mbedtls_x509_crt_verify(&chain, &ca, NULL, NULL, &flags,
                                             my_verify, NULL)) != 0) {
                char vrfy_buf[512];
                mbedtls_printf(" failed\n");
                mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
                mbedtls_printf("%s\n", vrfy_buf);
            } else
                mbedtls_printf(" Verify OK\n");
    
        } while (0);
    
        if (0 != r) mbedtls_printf("Error: 0x%04x; flag: %u\n", r, flags);
    }
    
    int main(void) {
        verify_cert_chain_driver();
        return 0;
    }
    

    An error message from mbedtls_x509_crt_verify_info could e.g. look like this:

     failed
      ! The certificate is not correctly signed by the trusted CA
    

    A successful test would output something like this:

    
    Verify requested for (Depth 2):
    cert. version     : 3
    serial number     : 08:3B:E0:56:90:42:46:B1:A1:75:6A:C9:59:91:C7:4A
    issuer name       : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
    subject name      : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
    issued  on        : 2006-11-10 00:00:00
    expires on        : 2031-11-10 00:00:00
    signed using      : RSA with SHA1
    RSA key size      : 2048 bits
    basic constraints : CA=true
    key usage         : Digital Signature, Key Cert Sign, CRL Sign
      This certificate has no flags
    
    Verify requested for (Depth 1):
    cert. version     : 3
    serial number     : 02:79:AC:45:8B:C1:B2:45:AB:F9:80:53:CD:2C:9B:B1
    issuer name       : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
    subject name      : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=Encryption Everywhere DV TLS CA - G1
    issued  on        : 2017-11-27 12:46:10
    expires on        : 2027-11-27 12:46:10
    signed using      : RSA with SHA-256
    RSA key size      : 2048 bits
    basic constraints : CA=true, max_pathlen=0
    key usage         : Digital Signature, Key Cert Sign, CRL Sign
    ext key usage     : TLS Web Server Authentication, TLS Web Client Authentication
    certificate policies : ???, ???
      This certificate has no flags
    
    Verify requested for (Depth 0):
    cert. version     : 3
    serial number     : 0C:B1:71:BD:2C:AD:62:1A:68:9C:7A:2D:9C:F4:35:03
    issuer name       : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=Encryption Everywhere DV TLS CA - G1
    subject name      : CN=software7.com
    issued  on        : 2022-01-04 00:00:00
    expires on        : 2023-01-04 23:59:59
    signed using      : RSA with SHA-256
    RSA key size      : 2048 bits
    basic constraints : CA=false
    subject alt name  :
        dNSName : software7.com
        dNSName : www.software7.com
    key usage         : Digital Signature, Key Encipherment
    ext key usage     : TLS Web Server Authentication, TLS Web Client Authentication
    certificate policies : ???
      This certificate has no flags
     Verify OK