mbedtls cannot parse valid x509 certificate

Solution 1:

Initially, the PEM format certificate string was parsed with the following code:

mbedtls_x509_crt certificate;
mbedtls_x509_crt_init(&certificate);
        
char certificate_string[] = "-----BEGIN CERTIFICATE--..."; // actually much longer
            
int result_code = mbedtls_x509_crt_parse(&certificate, (unsigned char*)certificate_string, strlen(certificate_string));

That resulted in a parsing error because for PEM format input, the final argument of the call to mbedtls_x509_crt certificate should be the length of the input including the null terminator. Changing the final argument to 1 + strlen(certificate_string) fixes the issue.


After successfully parsing, the issuer string was printed using:

printf("The issuer is: %s\n", certificate.issuer.val.p);

That produced some junk output that looked as if the initial part of the issuer string had been overwritten, but was actually due to the lack of a null terminator in the issuer string. The bytes of data after the issuer string included ASCII CR characters causing the terminal cursor position to move to the start of the line and print over the initial part of the output. (The CR characters can be seen by piping the output through | od -c for example, wherewith they are displayed as \r.)

Piping the output through | od -c produces:

0000000   T   h   e       i   s   s   u   e   r       i   s   :       A
0000020   m   a   z   o   n       W   e   b       S   e   r   v   i   c
0000040   e   s       O   =   A   m   a   z   o   n   .   c   o   m
0000060   I   n   c   .       L   =   S   e   a   t   t   l   e       S
0000100   T   =   W   a   s   h   i   n   g   t   o   n       C   =   U
0000120   S   0 036 027  \r   2   0   0   7   2   8   1   1   3   3   1
0000140   2   Z 027  \r   4   9   1   2   3   1   2   3   5   9   5   9
0000160   Z   0 036   1 034   0 032 006 003   U 004 003  \f 023   A   W
0000200   S       I   o   T       C   e   r   t   i   f   i   c   a   t
0000220   e   0 202 001   "   0  \r 006  \t   * 206   H 206 367  \r 001
0000240 001 001 005  \n
0000244

That shows unprintable bytes as 3-digit octal codes or as C backslash escape codes, depending on the byte value.

To print the issuer string without the junk, change the printf call to the following:

printf("The issuer is: %.*s\n", (int)certificate.issuer.val.len, certificate.issuer.val.p);