• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/x509.h"
4#include "mbedtls/x509_crt.h"
5#include "mbedtls/x509_crl.h"
6#include "mbedtls/x509_csr.h"
7#include "mbedtls/pem.h"
8#include "mbedtls/oid.h"
9#include "mbedtls/base64.h"
10#include "string.h"
11
12#if MBEDTLS_X509_MAX_INTERMEDIATE_CA > 19
13#error "The value of MBEDTLS_X509_MAX_INTERMEDIATE_C is larger \
14than the current threshold 19. To test larger values, please \
15adapt the script tests/data_files/dir-max/long.sh."
16#endif
17
18/* Test-only profile allowing all digests, PK algorithms, and curves. */
19const mbedtls_x509_crt_profile profile_all =
20{
21    0xFFFFFFFF, /* Any MD        */
22    0xFFFFFFFF, /* Any PK alg    */
23    0xFFFFFFFF, /* Any curve     */
24    1024,
25};
26
27/* Profile for backward compatibility. Allows SHA-1, unlike the default
28   profile. */
29const mbedtls_x509_crt_profile compat_profile =
30{
31    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
32    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
33    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
34    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
35    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
36    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
37    0xFFFFFFF, /* Any PK alg    */
38    0xFFFFFFF, /* Any curve     */
39    1024,
40};
41
42const mbedtls_x509_crt_profile profile_rsa3072 =
43{
44    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
45    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
46    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
47    MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_RSA ),
48    0,
49    3072,
50};
51
52const mbedtls_x509_crt_profile profile_sha512 =
53{
54    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
55    0xFFFFFFF, /* Any PK alg    */
56    0xFFFFFFF, /* Any curve     */
57    1024,
58};
59
60int verify_none( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
61{
62    ((void) data);
63    ((void) crt);
64    ((void) certificate_depth);
65    *flags |= MBEDTLS_X509_BADCERT_OTHER;
66
67    return 0;
68}
69
70int verify_all( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
71{
72    ((void) data);
73    ((void) crt);
74    ((void) certificate_depth);
75    *flags = 0;
76
77    return 0;
78}
79
80int verify_fatal( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
81{
82    int *levels = (int *) data;
83
84    ((void) crt);
85    ((void) certificate_depth);
86
87    /* Simulate a fatal error in the callback */
88    if( *levels & ( 1 << certificate_depth ) )
89    {
90        *flags |= ( 1 << certificate_depth );
91        return( -1 - certificate_depth );
92    }
93
94    return( 0 );
95}
96
97/* strsep() not available on Windows */
98char *mystrsep(char **stringp, const char *delim)
99{
100    const char *p;
101    char *ret = *stringp;
102
103    if( *stringp == NULL )
104        return( NULL );
105
106    for( ; ; (*stringp)++ )
107    {
108        if( **stringp == '\0' )
109        {
110            *stringp = NULL;
111            goto done;
112        }
113
114        for( p = delim; *p != '\0'; p++ )
115            if( **stringp == *p )
116            {
117                **stringp = '\0';
118                (*stringp)++;
119                goto done;
120            }
121    }
122
123done:
124    return( ret );
125}
126
127#if defined(MBEDTLS_X509_CRT_PARSE_C)
128typedef struct {
129    char buf[512];
130    char *p;
131} verify_print_context;
132
133void verify_print_init( verify_print_context *ctx )
134{
135    memset( ctx, 0, sizeof( verify_print_context ) );
136    ctx->p = ctx->buf;
137}
138
139int verify_print( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
140{
141    int ret;
142    verify_print_context *ctx = (verify_print_context *) data;
143    char *p = ctx->p;
144    size_t n = ctx->buf + sizeof( ctx->buf ) - ctx->p;
145    ((void) flags);
146
147    ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth );
148    MBEDTLS_X509_SAFE_SNPRINTF;
149
150    ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
151    MBEDTLS_X509_SAFE_SNPRINTF;
152
153    ret = mbedtls_snprintf( p, n, " - subject " );
154    MBEDTLS_X509_SAFE_SNPRINTF;
155
156    ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
157    MBEDTLS_X509_SAFE_SNPRINTF;
158
159    ret = mbedtls_snprintf( p, n, " - flags 0x%08x\n", *flags );
160    MBEDTLS_X509_SAFE_SNPRINTF;
161
162    ctx->p = p;
163
164    return( 0 );
165}
166#endif /* MBEDTLS_X509_CRT_PARSE_C */
167/* END_HEADER */
168
169/* BEGIN_DEPENDENCIES
170 * depends_on:MBEDTLS_BIGNUM_C
171 * END_DEPENDENCIES
172 */
173
174/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
175void x509_cert_info( char * crt_file, char * result_str )
176{
177    mbedtls_x509_crt   crt;
178    char buf[2000];
179    int res;
180
181    mbedtls_x509_crt_init( &crt );
182    memset( buf, 0, 2000 );
183
184    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
185    res = mbedtls_x509_crt_info( buf, 2000, "", &crt );
186
187    TEST_ASSERT( res != -1 );
188    TEST_ASSERT( res != -2 );
189
190    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
191
192exit:
193    mbedtls_x509_crt_free( &crt );
194}
195/* END_CASE */
196
197/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRL_PARSE_C */
198void mbedtls_x509_crl_info( char * crl_file, char * result_str )
199{
200    mbedtls_x509_crl   crl;
201    char buf[2000];
202    int res;
203
204    mbedtls_x509_crl_init( &crl );
205    memset( buf, 0, 2000 );
206
207    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 );
208    res = mbedtls_x509_crl_info( buf, 2000, "", &crl );
209
210    TEST_ASSERT( res != -1 );
211    TEST_ASSERT( res != -2 );
212
213    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
214
215exit:
216    mbedtls_x509_crl_free( &crl );
217}
218/* END_CASE */
219
220/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRL_PARSE_C */
221void mbedtls_x509_crl_parse( char * crl_file, int result )
222{
223    mbedtls_x509_crl   crl;
224    char buf[2000];
225
226    mbedtls_x509_crl_init( &crl );
227    memset( buf, 0, 2000 );
228
229    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == result );
230
231exit:
232    mbedtls_x509_crl_free( &crl );
233}
234/* END_CASE */
235
236/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CSR_PARSE_C */
237void mbedtls_x509_csr_info( char * csr_file, char * result_str )
238{
239    mbedtls_x509_csr   csr;
240    char buf[2000];
241    int res;
242
243    mbedtls_x509_csr_init( &csr );
244    memset( buf, 0, 2000 );
245
246    TEST_ASSERT( mbedtls_x509_csr_parse_file( &csr, csr_file ) == 0 );
247    res = mbedtls_x509_csr_info( buf, 2000, "", &csr );
248
249    TEST_ASSERT( res != -1 );
250    TEST_ASSERT( res != -2 );
251
252    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
253
254exit:
255    mbedtls_x509_csr_free( &csr );
256}
257/* END_CASE */
258
259/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
260void x509_verify_info( int flags, char * prefix, char * result_str )
261{
262    char buf[2000];
263    int res;
264
265    memset( buf, 0, sizeof( buf ) );
266
267    res = mbedtls_x509_crt_verify_info( buf, sizeof( buf ), prefix, flags );
268
269    TEST_ASSERT( res >= 0 );
270
271    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
272}
273/* END_CASE */
274
275/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_C */
276void x509_verify_restart( char *crt_file, char *ca_file,
277                          int result, int flags_result,
278                          int max_ops, int min_restart, int max_restart )
279{
280    int ret, cnt_restart;
281    mbedtls_x509_crt_restart_ctx rs_ctx;
282    mbedtls_x509_crt crt;
283    mbedtls_x509_crt ca;
284    uint32_t flags = 0;
285
286    /*
287     * See comments on ecp_test_vect_restart() for op count precision.
288     *
289     * For reference, with mbed TLS 2.6 and default settings:
290     * - ecdsa_verify() for P-256:  ~  6700
291     * - ecdsa_verify() for P-384:  ~ 18800
292     * - x509_verify() for server5 -> test-ca2:             ~ 18800
293     * - x509_verify() for server10 -> int-ca3 -> int-ca2:  ~ 25500
294     */
295
296    mbedtls_x509_crt_restart_init( &rs_ctx );
297    mbedtls_x509_crt_init( &crt );
298    mbedtls_x509_crt_init( &ca );
299
300    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
301    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
302
303    mbedtls_ecp_set_max_ops( max_ops );
304
305    cnt_restart = 0;
306    do {
307        ret = mbedtls_x509_crt_verify_restartable( &crt, &ca, NULL,
308                &mbedtls_x509_crt_profile_default, NULL, &flags,
309                NULL, NULL, &rs_ctx );
310    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
311
312    TEST_ASSERT( ret == result );
313    TEST_ASSERT( flags == (uint32_t) flags_result );
314
315    TEST_ASSERT( cnt_restart >= min_restart );
316    TEST_ASSERT( cnt_restart <= max_restart );
317
318    /* Do we leak memory when aborting? */
319    ret = mbedtls_x509_crt_verify_restartable( &crt, &ca, NULL,
320            &mbedtls_x509_crt_profile_default, NULL, &flags,
321            NULL, NULL, &rs_ctx );
322    TEST_ASSERT( ret == result || ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
323
324exit:
325    mbedtls_x509_crt_restart_free( &rs_ctx );
326    mbedtls_x509_crt_free( &crt );
327    mbedtls_x509_crt_free( &ca );
328}
329/* END_CASE */
330
331/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C */
332void x509_verify( char *crt_file, char *ca_file, char *crl_file,
333                  char *cn_name_str, int result, int flags_result,
334                  char *profile_str,
335                  char *verify_callback )
336{
337    mbedtls_x509_crt   crt;
338    mbedtls_x509_crt   ca;
339    mbedtls_x509_crl    crl;
340    uint32_t         flags = 0;
341    int         res;
342    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *) = NULL;
343    char *      cn_name = NULL;
344    const mbedtls_x509_crt_profile *profile;
345
346    mbedtls_x509_crt_init( &crt );
347    mbedtls_x509_crt_init( &ca );
348    mbedtls_x509_crl_init( &crl );
349
350    if( strcmp( cn_name_str, "NULL" ) != 0 )
351        cn_name = cn_name_str;
352
353    if( strcmp( profile_str, "" ) == 0 )
354        profile = &mbedtls_x509_crt_profile_default;
355    else if( strcmp( profile_str, "next" ) == 0 )
356        profile = &mbedtls_x509_crt_profile_next;
357    else if( strcmp( profile_str, "suite_b" ) == 0 )
358        profile = &mbedtls_x509_crt_profile_suiteb;
359    else if( strcmp( profile_str, "compat" ) == 0 )
360        profile = &compat_profile;
361    else if( strcmp( profile_str, "all" ) == 0 )
362        profile = &profile_all;
363    else
364        TEST_ASSERT( "Unknown algorithm profile" == 0 );
365
366    if( strcmp( verify_callback, "NULL" ) == 0 )
367        f_vrfy = NULL;
368    else if( strcmp( verify_callback, "verify_none" ) == 0 )
369        f_vrfy = verify_none;
370    else if( strcmp( verify_callback, "verify_all" ) == 0 )
371        f_vrfy = verify_all;
372    else
373        TEST_ASSERT( "No known verify callback selected" == 0 );
374
375    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
376    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
377    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 );
378
379    res = mbedtls_x509_crt_verify_with_profile( &crt, &ca, &crl, profile, cn_name, &flags, f_vrfy, NULL );
380
381    TEST_ASSERT( res == ( result ) );
382    TEST_ASSERT( flags == (uint32_t)( flags_result ) );
383
384exit:
385    mbedtls_x509_crt_free( &crt );
386    mbedtls_x509_crt_free( &ca );
387    mbedtls_x509_crl_free( &crl );
388}
389/* END_CASE */
390
391/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
392void x509_verify_callback( char *crt_file, char *ca_file, char *name,
393                           int exp_ret, char *exp_vrfy_out )
394{
395    int ret;
396    mbedtls_x509_crt crt;
397    mbedtls_x509_crt ca;
398    uint32_t flags = 0;
399    verify_print_context vrfy_ctx;
400
401    mbedtls_x509_crt_init( &crt );
402    mbedtls_x509_crt_init( &ca );
403    verify_print_init( &vrfy_ctx );
404
405    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
406    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
407
408    if( strcmp( name, "NULL" ) == 0 )
409        name = NULL;
410
411    ret = mbedtls_x509_crt_verify_with_profile( &crt, &ca, NULL,
412                                                &compat_profile,
413                                                name, &flags,
414                                                verify_print, &vrfy_ctx );
415
416    TEST_ASSERT( ret == exp_ret );
417    TEST_ASSERT( strcmp( vrfy_ctx.buf, exp_vrfy_out ) == 0 );
418
419exit:
420    mbedtls_x509_crt_free( &crt );
421    mbedtls_x509_crt_free( &ca );
422}
423/* END_CASE */
424
425/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
426void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str )
427{
428    mbedtls_x509_crt   crt;
429    char buf[2000];
430    int res = 0;
431
432    mbedtls_x509_crt_init( &crt );
433    memset( buf, 0, 2000 );
434
435    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
436    if( strcmp( entity, "subject" ) == 0 )
437        res =  mbedtls_x509_dn_gets( buf, 2000, &crt.subject );
438    else if( strcmp( entity, "issuer" ) == 0 )
439        res =  mbedtls_x509_dn_gets( buf, 2000, &crt.issuer );
440    else
441        TEST_ASSERT( "Unknown entity" == 0 );
442
443    TEST_ASSERT( res != -1 );
444    TEST_ASSERT( res != -2 );
445
446    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
447
448exit:
449    mbedtls_x509_crt_free( &crt );
450}
451/* END_CASE */
452
453/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
454void mbedtls_x509_time_is_past( char * crt_file, char * entity, int result )
455{
456    mbedtls_x509_crt   crt;
457
458    mbedtls_x509_crt_init( &crt );
459
460    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
461
462    if( strcmp( entity, "valid_from" ) == 0 )
463        TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_from ) == result );
464    else if( strcmp( entity, "valid_to" ) == 0 )
465        TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_to ) == result );
466    else
467        TEST_ASSERT( "Unknown entity" == 0 );
468
469exit:
470    mbedtls_x509_crt_free( &crt );
471}
472/* END_CASE */
473
474/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
475void mbedtls_x509_time_is_future( char * crt_file, char * entity, int result )
476{
477    mbedtls_x509_crt   crt;
478
479    mbedtls_x509_crt_init( &crt );
480
481    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
482
483    if( strcmp( entity, "valid_from" ) == 0 )
484        TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_from ) == result );
485    else if( strcmp( entity, "valid_to" ) == 0 )
486        TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_to ) == result );
487    else
488        TEST_ASSERT( "Unknown entity" == 0 );
489
490exit:
491    mbedtls_x509_crt_free( &crt );
492}
493/* END_CASE */
494
495/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */
496void x509parse_crt_file( char * crt_file, int result )
497{
498    mbedtls_x509_crt crt;
499
500    mbedtls_x509_crt_init( &crt );
501
502    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == result );
503
504exit:
505    mbedtls_x509_crt_free( &crt );
506}
507/* END_CASE */
508
509/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
510void x509parse_crt( data_t * buf, char * result_str, int result )
511{
512    mbedtls_x509_crt   crt;
513    unsigned char output[2000];
514    int res;
515
516    mbedtls_x509_crt_init( &crt );
517    memset( output, 0, 2000 );
518
519
520    TEST_ASSERT( mbedtls_x509_crt_parse( &crt, buf->x, buf->len ) == ( result ) );
521    if( ( result ) == 0 )
522    {
523        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
524
525        TEST_ASSERT( res != -1 );
526        TEST_ASSERT( res != -2 );
527
528        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
529    }
530
531exit:
532    mbedtls_x509_crt_free( &crt );
533}
534/* END_CASE */
535
536/* BEGIN_CASE depends_on:MBEDTLS_X509_CRL_PARSE_C */
537void x509parse_crl( data_t * buf, char * result_str, int result )
538{
539    mbedtls_x509_crl   crl;
540    unsigned char output[2000];
541    int res;
542
543    mbedtls_x509_crl_init( &crl );
544    memset( output, 0, 2000 );
545
546
547    TEST_ASSERT( mbedtls_x509_crl_parse( &crl, buf->x, buf->len ) == ( result ) );
548    if( ( result ) == 0 )
549    {
550        res = mbedtls_x509_crl_info( (char *) output, 2000, "", &crl );
551
552        TEST_ASSERT( res != -1 );
553        TEST_ASSERT( res != -2 );
554
555        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
556    }
557
558exit:
559    mbedtls_x509_crl_free( &crl );
560}
561/* END_CASE */
562
563/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_PARSE_C */
564void mbedtls_x509_csr_parse( data_t * csr_der, char * ref_out, int ref_ret )
565{
566    mbedtls_x509_csr csr;
567    char my_out[1000];
568    int my_ret;
569
570    mbedtls_x509_csr_init( &csr );
571    memset( my_out, 0, sizeof( my_out ) );
572
573    my_ret = mbedtls_x509_csr_parse_der( &csr, csr_der->x, csr_der->len );
574    TEST_ASSERT( my_ret == ref_ret );
575
576    if( ref_ret == 0 )
577    {
578        size_t my_out_len = mbedtls_x509_csr_info( my_out, sizeof( my_out ), "", &csr );
579        TEST_ASSERT( my_out_len == strlen( ref_out ) );
580        TEST_ASSERT( strcmp( my_out, ref_out ) == 0 );
581    }
582
583exit:
584    mbedtls_x509_csr_free( &csr );
585}
586/* END_CASE */
587
588/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
589void mbedtls_x509_crt_parse_path( char * crt_path, int ret, int nb_crt )
590{
591    mbedtls_x509_crt chain, *cur;
592    int i;
593
594    mbedtls_x509_crt_init( &chain );
595
596    TEST_ASSERT( mbedtls_x509_crt_parse_path( &chain, crt_path ) == ret );
597
598    /* Check how many certs we got */
599    for( i = 0, cur = &chain; cur != NULL; cur = cur->next )
600        if( cur->raw.p != NULL )
601            i++;
602
603    TEST_ASSERT( i == nb_crt );
604
605exit:
606    mbedtls_x509_crt_free( &chain );
607}
608/* END_CASE */
609
610/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
611void mbedtls_x509_crt_verify_max( char *ca_file, char *chain_dir, int nb_int,
612                                  int ret_chk, int flags_chk )
613{
614    char file_buf[128];
615    int ret;
616    uint32_t flags;
617    mbedtls_x509_crt trusted, chain;
618
619    /*
620     * We expect chain_dir to contain certificates 00.crt, 01.crt, etc.
621     * with NN.crt signed by NN-1.crt
622     */
623
624    mbedtls_x509_crt_init( &trusted );
625    mbedtls_x509_crt_init( &chain );
626
627    /* Load trusted root */
628    TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, ca_file ) == 0 );
629
630    /* Load a chain with nb_int intermediates (from 01 to nb_int),
631     * plus one "end-entity" cert (nb_int + 1) */
632    ret = mbedtls_snprintf( file_buf, sizeof file_buf, "%s/c%02d.pem", chain_dir,
633                                                            nb_int + 1 );
634    TEST_ASSERT( ret > 0 && (size_t) ret < sizeof file_buf );
635    TEST_ASSERT( mbedtls_x509_crt_parse_file( &chain, file_buf ) == 0 );
636
637    /* Try to verify that chain */
638    ret = mbedtls_x509_crt_verify( &chain, &trusted, NULL, NULL, &flags,
639                                   NULL, NULL );
640    TEST_ASSERT( ret == ret_chk );
641    TEST_ASSERT( flags == (uint32_t) flags_chk );
642
643exit:
644    mbedtls_x509_crt_free( &chain );
645    mbedtls_x509_crt_free( &trusted );
646}
647/* END_CASE */
648
649/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
650void mbedtls_x509_crt_verify_chain(  char *chain_paths, char *trusted_ca,
651                                     int flags_result, int result,
652                                     char *profile_name, int vrfy_fatal_lvls )
653{
654    char* act;
655    uint32_t flags;
656    int res;
657    mbedtls_x509_crt trusted, chain;
658    const mbedtls_x509_crt_profile *profile = NULL;
659
660    mbedtls_x509_crt_init( &chain );
661    mbedtls_x509_crt_init( &trusted );
662
663    while( ( act = mystrsep( &chain_paths, " " ) ) != NULL )
664        TEST_ASSERT( mbedtls_x509_crt_parse_file( &chain, act ) == 0 );
665    TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, trusted_ca ) == 0 );
666
667    if( strcmp( profile_name, "" ) == 0 )
668        profile = &mbedtls_x509_crt_profile_default;
669    else if( strcmp( profile_name, "next" ) == 0 )
670        profile = &mbedtls_x509_crt_profile_next;
671    else if( strcmp( profile_name, "suiteb" ) == 0 )
672        profile = &mbedtls_x509_crt_profile_suiteb;
673    else if( strcmp( profile_name, "rsa3072" ) == 0 )
674        profile = &profile_rsa3072;
675    else if( strcmp( profile_name, "sha512" ) == 0 )
676        profile = &profile_sha512;
677
678    res = mbedtls_x509_crt_verify_with_profile( &chain, &trusted, NULL, profile,
679            NULL, &flags, verify_fatal, &vrfy_fatal_lvls );
680
681    TEST_ASSERT( res == ( result ) );
682    TEST_ASSERT( flags == (uint32_t)( flags_result ) );
683
684exit:
685    mbedtls_x509_crt_free( &trusted );
686    mbedtls_x509_crt_free( &chain );
687}
688/* END_CASE */
689
690/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
691void x509_oid_desc( data_t * buf, char * ref_desc )
692{
693    mbedtls_x509_buf oid;
694    const char *desc = NULL;
695    int ret;
696
697
698    oid.tag = MBEDTLS_ASN1_OID;
699    oid.p   = buf->x;
700    oid.len   = buf->len;
701
702    ret = mbedtls_oid_get_extended_key_usage( &oid, &desc );
703
704    if( strcmp( ref_desc, "notfound" ) == 0 )
705    {
706        TEST_ASSERT( ret != 0 );
707        TEST_ASSERT( desc == NULL );
708    }
709    else
710    {
711        TEST_ASSERT( ret == 0 );
712        TEST_ASSERT( desc != NULL );
713        TEST_ASSERT( strcmp( desc, ref_desc ) == 0 );
714    }
715}
716/* END_CASE */
717
718/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
719void x509_oid_numstr( data_t * oid_buf, char * numstr, int blen, int ret )
720{
721    mbedtls_x509_buf oid;
722    char num_buf[100];
723
724    memset( num_buf, 0x2a, sizeof num_buf );
725
726    oid.tag = MBEDTLS_ASN1_OID;
727    oid.p   = oid_buf->x;
728    oid.len   = oid_buf->len;
729
730    TEST_ASSERT( (size_t) blen <= sizeof num_buf );
731
732    TEST_ASSERT( mbedtls_oid_get_numeric_string( num_buf, blen, &oid ) == ret );
733
734    if( ret >= 0 )
735    {
736        TEST_ASSERT( num_buf[ret] == 0 );
737        TEST_ASSERT( strcmp( num_buf, numstr ) == 0 );
738    }
739}
740/* END_CASE */
741
742/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CHECK_KEY_USAGE */
743void x509_check_key_usage( char * crt_file, int usage, int ret )
744{
745    mbedtls_x509_crt crt;
746
747    mbedtls_x509_crt_init( &crt );
748
749    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
750
751    TEST_ASSERT( mbedtls_x509_crt_check_key_usage( &crt, usage ) == ret );
752
753exit:
754    mbedtls_x509_crt_free( &crt );
755}
756/* END_CASE */
757
758/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
759void x509_check_extended_key_usage( char * crt_file, data_t * oid, int ret
760                                    )
761{
762    mbedtls_x509_crt crt;
763
764    mbedtls_x509_crt_init( &crt );
765
766
767    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
768
769    TEST_ASSERT( mbedtls_x509_crt_check_extended_key_usage( &crt, (const char *)oid->x, oid->len ) == ret );
770
771exit:
772    mbedtls_x509_crt_free( &crt );
773}
774/* END_CASE */
775
776/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
777void x509_get_time( int tag, char * time_str, int ret, int year, int mon,
778                    int day, int hour, int min, int sec )
779{
780    mbedtls_x509_time time;
781    unsigned char buf[21];
782    unsigned char* start = buf;
783    unsigned char* end = buf;
784
785    memset( &time, 0x00, sizeof( time ) );
786    *end = (unsigned char)tag; end++;
787    *end = strlen( time_str );
788    TEST_ASSERT( *end < 20 );
789    end++;
790    memcpy( end, time_str, (size_t)*(end - 1) );
791    end += *(end - 1);
792
793    TEST_ASSERT( mbedtls_x509_get_time( &start, end, &time ) == ret );
794    if( ret == 0 )
795    {
796        TEST_ASSERT( year == time.year );
797        TEST_ASSERT( mon  == time.mon  );
798        TEST_ASSERT( day  == time.day  );
799        TEST_ASSERT( hour == time.hour );
800        TEST_ASSERT( min  == time.min  );
801        TEST_ASSERT( sec  == time.sec  );
802    }
803}
804/* END_CASE */
805
806/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT */
807void x509_parse_rsassa_pss_params( data_t * params, int params_tag,
808                                   int ref_msg_md, int ref_mgf_md,
809                                   int ref_salt_len, int ref_ret )
810{
811    int my_ret;
812    mbedtls_x509_buf buf;
813    mbedtls_md_type_t my_msg_md, my_mgf_md;
814    int my_salt_len;
815
816    buf.p = params->x;
817    buf.len = params->len;
818    buf.tag = params_tag;
819
820    my_ret = mbedtls_x509_get_rsassa_pss_params( &buf, &my_msg_md, &my_mgf_md,
821                                                 &my_salt_len );
822
823    TEST_ASSERT( my_ret == ref_ret );
824
825    if( ref_ret == 0 )
826    {
827        TEST_ASSERT( my_msg_md == (mbedtls_md_type_t) ref_msg_md );
828        TEST_ASSERT( my_mgf_md == (mbedtls_md_type_t) ref_mgf_md );
829        TEST_ASSERT( my_salt_len == ref_salt_len );
830    }
831
832exit:
833    ;;
834}
835/* END_CASE */
836
837/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_SELF_TEST */
838void x509_selftest(  )
839{
840    TEST_ASSERT( mbedtls_x509_self_test( 1 ) == 0 );
841}
842/* END_CASE */
843