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 );
}
ca
and chain
are not initialized, you should call mbedtls_x509_crt_init
for themparse_from_file
should probably be mbedtls_x509_crt_parse_file
.mbedtls_x509_crt_verify_info
can be called if the return value indicates an errormbedtls_x509_crt_verify
provides the possibility for a custom callback: this verification callback is called for each certificate in the chain and can be used to output additional informationThe 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