• 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 "mbedtls/error.h"
11#include "string.h"
12
13#include "mbedtls/legacy_or_psa.h"
14
15#if MBEDTLS_X509_MAX_INTERMEDIATE_CA > 19
16#error "The value of MBEDTLS_X509_MAX_INTERMEDIATE_C is larger \
17than the current threshold 19. To test larger values, please \
18adapt the script tests/data_files/dir-max/long.sh."
19#endif
20
21/* Test-only profile allowing all digests, PK algorithms, and curves. */
22const mbedtls_x509_crt_profile profile_all =
23{
24    0xFFFFFFFF, /* Any MD        */
25    0xFFFFFFFF, /* Any PK alg    */
26    0xFFFFFFFF, /* Any curve     */
27    1024,
28};
29
30/* Profile for backward compatibility. Allows SHA-1, unlike the default
31   profile. */
32const mbedtls_x509_crt_profile compat_profile =
33{
34    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
35    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
36    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
37    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
38    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
39    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
40    0xFFFFFFFF, /* Any PK alg    */
41    0xFFFFFFFF, /* Any curve     */
42    1024,
43};
44
45const mbedtls_x509_crt_profile profile_rsa3072 =
46{
47    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
48    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
49    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
50    MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_RSA ),
51    0,
52    3072,
53};
54
55const mbedtls_x509_crt_profile profile_sha512 =
56{
57    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
58    0xFFFFFFFF, /* Any PK alg    */
59    0xFFFFFFFF, /* Any curve     */
60    1024,
61};
62
63int verify_none( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
64{
65    ((void) data);
66    ((void) crt);
67    ((void) certificate_depth);
68    *flags |= MBEDTLS_X509_BADCERT_OTHER;
69
70    return 0;
71}
72
73int verify_all( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
74{
75    ((void) data);
76    ((void) crt);
77    ((void) certificate_depth);
78    *flags = 0;
79
80    return 0;
81}
82
83#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
84int ca_callback_fail( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates )
85{
86    ((void) data);
87    ((void) child);
88    ((void) candidates);
89
90    return -1;
91}
92#if defined(MBEDTLS_X509_CRT_PARSE_C)
93int ca_callback( void *data, mbedtls_x509_crt const *child,
94                 mbedtls_x509_crt **candidates )
95{
96    int ret = 0;
97    mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data;
98    mbedtls_x509_crt *first;
99
100    /* This is a test-only implementation of the CA callback
101     * which always returns the entire list of trusted certificates.
102     * Production implementations managing a large number of CAs
103     * should use an efficient presentation and lookup for the
104     * set of trusted certificates (such as a hashtable) and only
105     * return those trusted certificates which satisfy basic
106     * parental checks, such as the matching of child `Issuer`
107     * and parent `Subject` field. */
108    ((void) child);
109
110    first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
111    if( first == NULL )
112    {
113        ret = -1;
114        goto exit;
115    }
116    mbedtls_x509_crt_init( first );
117
118    if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
119    {
120        ret = -1;
121        goto exit;
122    }
123
124    while( ca->next != NULL )
125    {
126        ca = ca->next;
127        if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
128        {
129            ret = -1;
130            goto exit;
131        }
132    }
133
134exit:
135
136    if( ret != 0 )
137    {
138        mbedtls_x509_crt_free( first );
139        mbedtls_free( first );
140        first = NULL;
141    }
142
143    *candidates = first;
144    return( ret );
145}
146#endif /* MBEDTLS_X509_CRT_PARSE_C */
147#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
148
149int verify_fatal( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
150{
151    int *levels = (int *) data;
152
153    ((void) crt);
154    ((void) certificate_depth);
155
156    /* Simulate a fatal error in the callback */
157    if( *levels & ( 1 << certificate_depth ) )
158    {
159        *flags |= ( 1 << certificate_depth );
160        return( -1 - certificate_depth );
161    }
162
163    return( 0 );
164}
165
166/* strsep() not available on Windows */
167char *mystrsep(char **stringp, const char *delim)
168{
169    const char *p;
170    char *ret = *stringp;
171
172    if( *stringp == NULL )
173        return( NULL );
174
175    for( ; ; (*stringp)++ )
176    {
177        if( **stringp == '\0' )
178        {
179            *stringp = NULL;
180            goto done;
181        }
182
183        for( p = delim; *p != '\0'; p++ )
184            if( **stringp == *p )
185            {
186                **stringp = '\0';
187                (*stringp)++;
188                goto done;
189            }
190    }
191
192done:
193    return( ret );
194}
195
196#if defined(MBEDTLS_X509_CRT_PARSE_C)
197typedef struct {
198    char buf[512];
199    char *p;
200} verify_print_context;
201
202void verify_print_init( verify_print_context *ctx )
203{
204    memset( ctx, 0, sizeof( verify_print_context ) );
205    ctx->p = ctx->buf;
206}
207
208int verify_print( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
209{
210    int ret;
211    verify_print_context *ctx = (verify_print_context *) data;
212    char *p = ctx->p;
213    size_t n = ctx->buf + sizeof( ctx->buf ) - ctx->p;
214    ((void) flags);
215
216    ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth );
217    MBEDTLS_X509_SAFE_SNPRINTF;
218
219    ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
220    MBEDTLS_X509_SAFE_SNPRINTF;
221
222    ret = mbedtls_snprintf( p, n, " - subject " );
223    MBEDTLS_X509_SAFE_SNPRINTF;
224
225    ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
226    MBEDTLS_X509_SAFE_SNPRINTF;
227
228    ret = mbedtls_snprintf( p, n, " - flags 0x%08x\n", *flags );
229    MBEDTLS_X509_SAFE_SNPRINTF;
230
231    ctx->p = p;
232
233    return( 0 );
234}
235
236int verify_parse_san( mbedtls_x509_subject_alternative_name *san,
237                      char **buf, size_t *size )
238{
239    int ret;
240    size_t i;
241    char *p = *buf;
242    size_t n = *size;
243
244    ret = mbedtls_snprintf( p, n, "type : %d", san->type );
245    MBEDTLS_X509_SAFE_SNPRINTF;
246
247    switch( san->type )
248    {
249        case( MBEDTLS_X509_SAN_OTHER_NAME ):
250            ret = mbedtls_snprintf( p, n, "\notherName :");
251            MBEDTLS_X509_SAFE_SNPRINTF;
252
253            if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
254                     &san->san.other_name.value.hardware_module_name.oid ) != 0 )
255            {
256                ret = mbedtls_snprintf( p, n, " hardware module name :" );
257                MBEDTLS_X509_SAFE_SNPRINTF;
258                ret = mbedtls_snprintf( p, n, " hardware type : " );
259                MBEDTLS_X509_SAFE_SNPRINTF;
260
261                ret = mbedtls_oid_get_numeric_string( p, n,
262                           &san->san.other_name.value.hardware_module_name.oid );
263                MBEDTLS_X509_SAFE_SNPRINTF;
264
265                ret = mbedtls_snprintf( p, n, ", hardware serial number : " );
266                MBEDTLS_X509_SAFE_SNPRINTF;
267
268                for( i = 0; i < san->san.other_name.value.hardware_module_name.val.len; i++ )
269                {
270                    ret = mbedtls_snprintf( p, n, "%02X", san->san.other_name.value.hardware_module_name.val.p[i] );
271                    MBEDTLS_X509_SAFE_SNPRINTF;
272                }
273            }
274        break;/* MBEDTLS_OID_ON_HW_MODULE_NAME */
275        case(  MBEDTLS_X509_SAN_DNS_NAME ):
276            ret = mbedtls_snprintf( p, n, "\ndNSName : " );
277            MBEDTLS_X509_SAFE_SNPRINTF;
278            if( san->san.unstructured_name.len >= n )
279            {
280                *p = '\0';
281                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
282            }
283            n -= san->san.unstructured_name.len;
284            for( i = 0; i < san->san.unstructured_name.len; i++ )
285                *p++ = san->san.unstructured_name.p[i];
286        break;/* MBEDTLS_X509_SAN_DNS_NAME */
287
288        default:
289        /*
290         * Should not happen.
291         */
292        return( -1 );
293    }
294    ret = mbedtls_snprintf( p, n, "\n" );
295    MBEDTLS_X509_SAFE_SNPRINTF;
296
297    *size = n;
298    *buf = p;
299
300    return( 0 );
301}
302
303int parse_crt_ext_cb( void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid,
304                      int critical, const unsigned char *cp, const unsigned char *end )
305{
306    ( void ) crt;
307    ( void ) critical;
308    mbedtls_x509_buf *new_oid = (mbedtls_x509_buf *)p_ctx;
309    if( oid->tag == MBEDTLS_ASN1_OID &&
310        MBEDTLS_OID_CMP( MBEDTLS_OID_CERTIFICATE_POLICIES, oid ) == 0 )
311    {
312        /* Handle unknown certificate policy */
313        int ret, parse_ret = 0;
314        size_t len;
315        unsigned char **p = (unsigned char **)&cp;
316
317        /* Get main sequence tag */
318        ret = mbedtls_asn1_get_tag( p, end, &len,
319                                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
320        if( ret != 0 )
321            return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
322
323        if( *p + len != end )
324            return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
325                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
326
327        /*
328         * Cannot be an empty sequence.
329         */
330        if( len == 0 )
331            return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
332                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
333
334        while( *p < end )
335        {
336            const unsigned char *policy_end;
337
338            /*
339             * Get the policy sequence
340             */
341            if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
342                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
343                return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
344
345            policy_end = *p + len;
346
347            if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
348                                              MBEDTLS_ASN1_OID ) ) != 0 )
349                return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
350
351            /*
352             * Recognize exclusively the policy with OID 1
353             */
354            if( len != 1 || *p[0] != 1 )
355                parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
356
357            *p += len;
358
359           /*
360            * If there is an optional qualifier, then *p < policy_end
361            * Check the Qualifier len to verify it doesn't exceed policy_end.
362            */
363            if( *p < policy_end )
364            {
365                if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
366                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
367                    return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
368                /*
369                 * Skip the optional policy qualifiers.
370                 */
371                *p += len;
372            }
373
374            if( *p != policy_end )
375                return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
376                        MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
377        }
378
379        if( *p != end )
380            return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
381                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
382
383        return( parse_ret );
384    }
385    else if( new_oid != NULL && new_oid->tag == oid->tag && new_oid->len == oid->len &&
386             memcmp( new_oid->p, oid->p, oid->len ) == 0 )
387        return( 0 );
388    else
389        return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
390                                   MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
391}
392#endif /* MBEDTLS_X509_CRT_PARSE_C */
393/* END_HEADER */
394
395/* BEGIN_DEPENDENCIES
396 * depends_on:MBEDTLS_BIGNUM_C
397 * END_DEPENDENCIES
398 */
399
400/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
401void x509_accessor_ext_types( int ext_type, int has_ext_type )
402{
403    mbedtls_x509_crt crt;
404    int expected_result = ext_type & has_ext_type;
405
406    mbedtls_x509_crt_init( &crt );
407
408    crt.ext_types = ext_type;
409
410    TEST_ASSERT( mbedtls_x509_crt_has_ext_type( &crt, has_ext_type ) == expected_result );
411
412    mbedtls_x509_crt_free( &crt );
413}
414/* END_CASE */
415
416/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
417void x509_parse_san( char * crt_file, char * result_str )
418{
419    int ret;
420    mbedtls_x509_crt   crt;
421    mbedtls_x509_subject_alternative_name san;
422    mbedtls_x509_sequence *cur = NULL;
423    char buf[2000];
424    char *p = buf;
425    size_t n = sizeof( buf );
426
427    mbedtls_x509_crt_init( &crt );
428    memset( buf, 0, 2000 );
429
430    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
431
432    if( crt.ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
433    {
434        cur = &crt.subject_alt_names;
435        while( cur != NULL )
436        {
437            ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
438            TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
439            /*
440             * If san type not supported, ignore.
441             */
442            if( ret == 0)
443                TEST_ASSERT( verify_parse_san( &san, &p, &n ) == 0 );
444            cur = cur->next;
445        }
446    }
447
448    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
449
450exit:
451
452    mbedtls_x509_crt_free( &crt );
453}
454/* END_CASE */
455
456/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:!MBEDTLS_X509_REMOVE_INFO:MBEDTLS_X509_CRT_PARSE_C */
457void x509_cert_info( char * crt_file, char * result_str )
458{
459    mbedtls_x509_crt   crt;
460    char buf[2000];
461    int res;
462
463    mbedtls_x509_crt_init( &crt );
464    memset( buf, 0, 2000 );
465
466    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
467    res = mbedtls_x509_crt_info( buf, 2000, "", &crt );
468
469    TEST_ASSERT( res != -1 );
470    TEST_ASSERT( res != -2 );
471
472    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
473
474exit:
475    mbedtls_x509_crt_free( &crt );
476}
477/* END_CASE */
478
479/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRL_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
480void mbedtls_x509_crl_info( char * crl_file, char * result_str )
481{
482    mbedtls_x509_crl   crl;
483    char buf[2000];
484    int res;
485
486    mbedtls_x509_crl_init( &crl );
487    memset( buf, 0, 2000 );
488
489    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 );
490    res = mbedtls_x509_crl_info( buf, 2000, "", &crl );
491
492    TEST_ASSERT( res != -1 );
493    TEST_ASSERT( res != -2 );
494
495    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
496
497exit:
498    mbedtls_x509_crl_free( &crl );
499}
500/* END_CASE */
501
502/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRL_PARSE_C */
503void mbedtls_x509_crl_parse( char * crl_file, int result )
504{
505    mbedtls_x509_crl   crl;
506    char buf[2000];
507
508    mbedtls_x509_crl_init( &crl );
509    memset( buf, 0, 2000 );
510
511    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == result );
512
513exit:
514    mbedtls_x509_crl_free( &crl );
515}
516/* END_CASE */
517
518/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CSR_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
519void mbedtls_x509_csr_info( char * csr_file, char * result_str )
520{
521    mbedtls_x509_csr   csr;
522    char buf[2000];
523    int res;
524
525    mbedtls_x509_csr_init( &csr );
526    memset( buf, 0, 2000 );
527
528    TEST_ASSERT( mbedtls_x509_csr_parse_file( &csr, csr_file ) == 0 );
529    res = mbedtls_x509_csr_info( buf, 2000, "", &csr );
530
531    TEST_ASSERT( res != -1 );
532    TEST_ASSERT( res != -2 );
533
534    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
535
536exit:
537    mbedtls_x509_csr_free( &csr );
538}
539/* END_CASE */
540
541/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
542void x509_verify_info( int flags, char * prefix, char * result_str )
543{
544    char buf[2000];
545    int res;
546
547    memset( buf, 0, sizeof( buf ) );
548
549    res = mbedtls_x509_crt_verify_info( buf, sizeof( buf ), prefix, flags );
550
551    TEST_ASSERT( res >= 0 );
552
553    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
554}
555/* END_CASE */
556
557/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_C */
558void x509_verify_restart( char *crt_file, char *ca_file,
559                          int result, int flags_result,
560                          int max_ops, int min_restart, int max_restart )
561{
562    int ret, cnt_restart;
563    mbedtls_x509_crt_restart_ctx rs_ctx;
564    mbedtls_x509_crt crt;
565    mbedtls_x509_crt ca;
566    uint32_t flags = 0;
567
568    /*
569     * See comments on ecp_test_vect_restart() for op count precision.
570     *
571     * For reference, with mbed TLS 2.6 and default settings:
572     * - ecdsa_verify() for P-256:  ~  6700
573     * - ecdsa_verify() for P-384:  ~ 18800
574     * - x509_verify() for server5 -> test-ca2:             ~ 18800
575     * - x509_verify() for server10 -> int-ca3 -> int-ca2:  ~ 25500
576     */
577
578    mbedtls_x509_crt_restart_init( &rs_ctx );
579    mbedtls_x509_crt_init( &crt );
580    mbedtls_x509_crt_init( &ca );
581
582    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
583    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
584
585    mbedtls_ecp_set_max_ops( max_ops );
586
587    cnt_restart = 0;
588    do {
589        ret = mbedtls_x509_crt_verify_restartable( &crt, &ca, NULL,
590                &mbedtls_x509_crt_profile_default, NULL, &flags,
591                NULL, NULL, &rs_ctx );
592    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
593
594    TEST_ASSERT( ret == result );
595    TEST_ASSERT( flags == (uint32_t) flags_result );
596
597    TEST_ASSERT( cnt_restart >= min_restart );
598    TEST_ASSERT( cnt_restart <= max_restart );
599
600    /* Do we leak memory when aborting? */
601    ret = mbedtls_x509_crt_verify_restartable( &crt, &ca, NULL,
602            &mbedtls_x509_crt_profile_default, NULL, &flags,
603            NULL, NULL, &rs_ctx );
604    TEST_ASSERT( ret == result || ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
605
606exit:
607    mbedtls_x509_crt_restart_free( &rs_ctx );
608    mbedtls_x509_crt_free( &crt );
609    mbedtls_x509_crt_free( &ca );
610}
611/* END_CASE */
612
613/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C */
614void x509_verify( char *crt_file, char *ca_file, char *crl_file,
615                  char *cn_name_str, int result, int flags_result,
616                  char *profile_str,
617                  char *verify_callback )
618{
619    mbedtls_x509_crt   crt;
620    mbedtls_x509_crt   ca;
621    mbedtls_x509_crl    crl;
622    uint32_t         flags = 0;
623    int         res;
624    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *) = NULL;
625    char *      cn_name = NULL;
626    const mbedtls_x509_crt_profile *profile;
627
628    mbedtls_x509_crt_init( &crt );
629    mbedtls_x509_crt_init( &ca );
630    mbedtls_x509_crl_init( &crl );
631
632    USE_PSA_INIT( );
633
634    if( strcmp( cn_name_str, "NULL" ) != 0 )
635        cn_name = cn_name_str;
636
637    if( strcmp( profile_str, "" ) == 0 )
638        profile = &mbedtls_x509_crt_profile_default;
639    else if( strcmp( profile_str, "next" ) == 0 )
640        profile = &mbedtls_x509_crt_profile_next;
641    else if( strcmp( profile_str, "suite_b" ) == 0 )
642        profile = &mbedtls_x509_crt_profile_suiteb;
643    else if( strcmp( profile_str, "compat" ) == 0 )
644        profile = &compat_profile;
645    else if( strcmp( profile_str, "all" ) == 0 )
646        profile = &profile_all;
647    else
648        TEST_ASSERT( "Unknown algorithm profile" == 0 );
649
650    if( strcmp( verify_callback, "NULL" ) == 0 )
651        f_vrfy = NULL;
652    else if( strcmp( verify_callback, "verify_none" ) == 0 )
653        f_vrfy = verify_none;
654    else if( strcmp( verify_callback, "verify_all" ) == 0 )
655        f_vrfy = verify_all;
656    else
657        TEST_ASSERT( "No known verify callback selected" == 0 );
658
659    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
660    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
661    TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 );
662
663    res = mbedtls_x509_crt_verify_with_profile( &crt, &ca, &crl, profile, cn_name, &flags, f_vrfy, NULL );
664
665    TEST_ASSERT( res == ( result ) );
666    TEST_ASSERT( flags == (uint32_t)( flags_result ) );
667
668#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
669    /* CRLs aren't supported with CA callbacks, so skip the CA callback
670     * version of the test if CRLs are in use. */
671    if( crl_file == NULL || strcmp( crl_file, "" ) == 0 )
672    {
673        flags = 0;
674
675        res = mbedtls_x509_crt_verify_with_ca_cb( &crt, ca_callback, &ca, profile, cn_name, &flags, f_vrfy, NULL );
676
677        TEST_ASSERT( res == ( result ) );
678        TEST_ASSERT( flags == (uint32_t)( flags_result ) );
679    }
680#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
681exit:
682    mbedtls_x509_crt_free( &crt );
683    mbedtls_x509_crt_free( &ca );
684    mbedtls_x509_crl_free( &crl );
685    USE_PSA_DONE( );
686}
687/* END_CASE */
688
689/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C:MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
690void x509_verify_ca_cb_failure( char *crt_file, char *ca_file, char *name,
691                                int exp_ret )
692{
693    int ret;
694    mbedtls_x509_crt crt;
695    mbedtls_x509_crt ca;
696    uint32_t flags = 0;
697
698    mbedtls_x509_crt_init( &crt );
699    mbedtls_x509_crt_init( &ca );
700
701    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
702    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
703
704    if( strcmp( name, "NULL" ) == 0 )
705        name = NULL;
706
707    ret = mbedtls_x509_crt_verify_with_ca_cb( &crt, ca_callback_fail, &ca,
708                                              &compat_profile, name, &flags,
709                                              NULL, NULL );
710
711    TEST_ASSERT( ret == exp_ret );
712    TEST_ASSERT( flags == (uint32_t)( -1 ) );
713exit:
714    mbedtls_x509_crt_free( &crt );
715    mbedtls_x509_crt_free( &ca );
716}
717/* END_CASE */
718
719/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
720void x509_verify_callback( char *crt_file, char *ca_file, char *name,
721                           int exp_ret, char *exp_vrfy_out )
722{
723    int ret;
724    mbedtls_x509_crt crt;
725    mbedtls_x509_crt ca;
726    uint32_t flags = 0;
727    verify_print_context vrfy_ctx;
728
729    mbedtls_x509_crt_init( &crt );
730    mbedtls_x509_crt_init( &ca );
731    verify_print_init( &vrfy_ctx );
732
733    USE_PSA_INIT( );
734
735    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
736    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
737
738    if( strcmp( name, "NULL" ) == 0 )
739        name = NULL;
740
741    ret = mbedtls_x509_crt_verify_with_profile( &crt, &ca, NULL,
742                                                &compat_profile,
743                                                name, &flags,
744                                                verify_print, &vrfy_ctx );
745
746    TEST_ASSERT( ret == exp_ret );
747    TEST_ASSERT( strcmp( vrfy_ctx.buf, exp_vrfy_out ) == 0 );
748
749exit:
750    mbedtls_x509_crt_free( &crt );
751    mbedtls_x509_crt_free( &ca );
752    USE_PSA_DONE( );
753}
754/* END_CASE */
755
756/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
757void mbedtls_x509_dn_gets_subject_replace( char * crt_file, char * new_subject_ou, char * result_str, int ret )
758{
759    mbedtls_x509_crt   crt;
760    char buf[2000];
761    int res = 0;
762
763    mbedtls_x509_crt_init( &crt );
764    memset( buf, 0, 2000 );
765
766    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
767    crt.subject.next->val.p = (unsigned char *) new_subject_ou;
768    crt.subject.next->val.len = strlen( new_subject_ou );
769
770    res =  mbedtls_x509_dn_gets( buf, 2000, &crt.subject );
771
772    if ( ret != 0 )
773    {
774        TEST_ASSERT( res == ret );
775    }
776    else
777    {
778        TEST_ASSERT( res != -1 );
779        TEST_ASSERT( res != -2 );
780        TEST_ASSERT( strcmp( buf, result_str ) == 0 );
781    }
782exit:
783    mbedtls_x509_crt_free( &crt );
784}
785/* END_CASE */
786
787/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
788void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str )
789{
790    mbedtls_x509_crt   crt;
791    char buf[2000];
792    int res = 0;
793
794    mbedtls_x509_crt_init( &crt );
795    memset( buf, 0, 2000 );
796
797    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
798    if( strcmp( entity, "subject" ) == 0 )
799        res =  mbedtls_x509_dn_gets( buf, 2000, &crt.subject );
800    else if( strcmp( entity, "issuer" ) == 0 )
801        res =  mbedtls_x509_dn_gets( buf, 2000, &crt.issuer );
802    else
803        TEST_ASSERT( "Unknown entity" == 0 );
804
805    TEST_ASSERT( res != -1 );
806    TEST_ASSERT( res != -2 );
807
808    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
809
810exit:
811    mbedtls_x509_crt_free( &crt );
812}
813/* END_CASE */
814
815/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
816void mbedtls_x509_get_name( char * rdn_sequence, int exp_ret )
817{
818    unsigned char *name;
819    unsigned char *p;
820    size_t name_len;
821    mbedtls_x509_name head;
822    int ret;
823
824    memset( &head, 0, sizeof( head ) );
825
826    name = mbedtls_test_unhexify_alloc( rdn_sequence, &name_len );
827    p = name;
828
829    ret = mbedtls_x509_get_name( &p, ( name + name_len ), &head );
830    if( ret == 0 )
831        mbedtls_asn1_free_named_data_list_shallow( head.next );
832
833    TEST_EQUAL( ret, exp_ret );
834
835    mbedtls_free( name );
836}
837/* END_CASE */
838
839/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
840void mbedtls_x509_dn_get_next( char * name_str, int next_merged, char * expected_oids, int exp_count, char * exp_dn_gets )
841{
842    int ret = 0, i;
843    size_t len = 0, out_size;
844    mbedtls_asn1_named_data *names = NULL;
845    mbedtls_x509_name parsed, *parsed_cur;
846    // Size of buf is maximum required for test cases
847    unsigned char buf[80], *out = NULL, *c;
848    const char *short_name;
849
850    memset( &parsed, 0, sizeof( parsed ) );
851    memset( buf, 0, sizeof( buf ) );
852    c = buf + sizeof( buf );
853    // Additional size required for trailing space
854    out_size = strlen( expected_oids ) + 2;
855    ASSERT_ALLOC( out, out_size );
856
857    TEST_EQUAL( mbedtls_x509_string_to_names( &names, name_str ), 0 );
858
859    ret = mbedtls_x509_write_names( &c, buf, names );
860    TEST_LE_S( 0, ret );
861
862    TEST_EQUAL( mbedtls_asn1_get_tag( &c, buf + sizeof( buf ), &len,
863                       MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ), 0 );
864    TEST_EQUAL( mbedtls_x509_get_name( &c, buf + sizeof( buf ), &parsed ), 0 );
865
866    // Iterate over names and set next_merged nodes
867    parsed_cur = &parsed;
868    for( ; next_merged != 0 && parsed_cur != NULL; next_merged = next_merged >> 1 )
869    {
870        parsed_cur->next_merged = next_merged & 0x01;
871        parsed_cur = parsed_cur->next;
872    }
873
874    // Iterate over RDN nodes and print OID of first element to buffer
875    parsed_cur = &parsed;
876    len = 0;
877    for( i = 0; parsed_cur != NULL; i++ )
878    {
879        TEST_EQUAL( mbedtls_oid_get_attr_short_name( &parsed_cur->oid,
880                                                      &short_name ), 0 );
881        len += mbedtls_snprintf( (char*) out + len, out_size - len, "%s ", short_name );
882        parsed_cur = mbedtls_x509_dn_get_next( parsed_cur );
883    }
884    out[len-1] = 0;
885
886    TEST_EQUAL( exp_count, i );
887    TEST_EQUAL( strcmp( (char *) out, expected_oids ), 0 );
888    mbedtls_free( out );
889    out = NULL;
890
891    out_size = strlen( exp_dn_gets ) + 1;
892    ASSERT_ALLOC( out, out_size );
893
894    TEST_LE_S( 0, mbedtls_x509_dn_gets( (char *) out, out_size, &parsed ) );
895    TEST_EQUAL( strcmp( (char *) out, exp_dn_gets ), 0 );
896exit:
897    mbedtls_free( out );
898    mbedtls_asn1_free_named_data_list( &names );
899    mbedtls_asn1_free_named_data_list_shallow( parsed.next );
900}
901/* END_CASE */
902
903/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
904void mbedtls_x509_time_is_past( char * crt_file, char * entity, int result )
905{
906    mbedtls_x509_crt   crt;
907
908    mbedtls_x509_crt_init( &crt );
909
910    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
911
912    if( strcmp( entity, "valid_from" ) == 0 )
913        TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_from ) == result );
914    else if( strcmp( entity, "valid_to" ) == 0 )
915        TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_to ) == result );
916    else
917        TEST_ASSERT( "Unknown entity" == 0 );
918
919exit:
920    mbedtls_x509_crt_free( &crt );
921}
922/* END_CASE */
923
924/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
925void mbedtls_x509_time_is_future( char * crt_file, char * entity, int result )
926{
927    mbedtls_x509_crt   crt;
928
929    mbedtls_x509_crt_init( &crt );
930
931    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
932
933    if( strcmp( entity, "valid_from" ) == 0 )
934        TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_from ) == result );
935    else if( strcmp( entity, "valid_to" ) == 0 )
936        TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_to ) == result );
937    else
938        TEST_ASSERT( "Unknown entity" == 0 );
939
940exit:
941    mbedtls_x509_crt_free( &crt );
942}
943/* END_CASE */
944
945/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */
946void x509parse_crt_file( char * crt_file, int result )
947{
948    mbedtls_x509_crt crt;
949
950    mbedtls_x509_crt_init( &crt );
951
952    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == result );
953
954exit:
955    mbedtls_x509_crt_free( &crt );
956}
957/* END_CASE */
958
959/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
960void x509parse_crt( data_t * buf, char * result_str, int result )
961{
962    mbedtls_x509_crt   crt;
963#if !defined(MBEDTLS_X509_REMOVE_INFO)
964    unsigned char output[2000] = { 0 };
965    int res;
966#else
967    ((void) result_str);
968#endif
969
970    mbedtls_x509_crt_init( &crt );
971
972    TEST_ASSERT( mbedtls_x509_crt_parse_der( &crt, buf->x, buf->len ) == ( result ) );
973#if !defined(MBEDTLS_X509_REMOVE_INFO)
974    if( ( result ) == 0 )
975    {
976        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
977        TEST_ASSERT( res != -1 );
978        TEST_ASSERT( res != -2 );
979
980        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
981    }
982    memset( output, 0, 2000 );
983#endif
984
985    mbedtls_x509_crt_free( &crt );
986    mbedtls_x509_crt_init( &crt );
987
988    TEST_ASSERT( mbedtls_x509_crt_parse_der_nocopy( &crt, buf->x, buf->len ) == ( result ) );
989#if !defined(MBEDTLS_X509_REMOVE_INFO)
990    if( ( result ) == 0 )
991    {
992        memset( output, 0, 2000 );
993
994        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
995
996        TEST_ASSERT( res != -1 );
997        TEST_ASSERT( res != -2 );
998
999        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1000    }
1001    memset( output, 0, 2000 );
1002#endif /* !MBEDTLS_X509_REMOVE_INFO */
1003
1004    mbedtls_x509_crt_free( &crt );
1005    mbedtls_x509_crt_init( &crt );
1006
1007    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, NULL, NULL ) == ( result ) );
1008#if !defined(MBEDTLS_X509_REMOVE_INFO)
1009    if( ( result ) == 0 )
1010    {
1011        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
1012
1013        TEST_ASSERT( res != -1 );
1014        TEST_ASSERT( res != -2 );
1015
1016        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1017    }
1018    memset( output, 0, 2000 );
1019#endif /* !MBEDTLS_X509_REMOVE_INFO */
1020
1021    mbedtls_x509_crt_free( &crt );
1022    mbedtls_x509_crt_init( &crt );
1023
1024    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, NULL, NULL ) == ( result ) );
1025#if !defined(MBEDTLS_X509_REMOVE_INFO)
1026    if( ( result ) == 0 )
1027    {
1028        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
1029
1030        TEST_ASSERT( res != -1 );
1031        TEST_ASSERT( res != -2 );
1032
1033        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1034    }
1035#endif /* !MBEDTLS_X509_REMOVE_INFO */
1036
1037exit:
1038    mbedtls_x509_crt_free( &crt );
1039}
1040/* END_CASE */
1041
1042/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
1043void x509parse_crt_cb( data_t * buf, char * result_str, int result )
1044{
1045    mbedtls_x509_crt   crt;
1046    mbedtls_x509_buf   oid;
1047
1048#if !defined(MBEDTLS_X509_REMOVE_INFO)
1049    unsigned char output[2000] = { 0 };
1050    int res;
1051#else
1052    ((void) result_str);
1053#endif
1054
1055    oid.tag = MBEDTLS_ASN1_OID;
1056    oid.len = MBEDTLS_OID_SIZE(MBEDTLS_OID_PKIX "\x01\x1F");
1057    oid.p = (unsigned char *)MBEDTLS_OID_PKIX "\x01\x1F";
1058
1059    mbedtls_x509_crt_init( &crt );
1060
1061    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, parse_crt_ext_cb, &oid ) == ( result ) );
1062#if !defined(MBEDTLS_X509_REMOVE_INFO)
1063    if( ( result ) == 0 )
1064    {
1065        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
1066
1067        TEST_ASSERT( res != -1 );
1068        TEST_ASSERT( res != -2 );
1069
1070        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1071    }
1072    memset( output, 0, 2000 );
1073#endif /* !MBEDTLS_X509_REMOVE_INFO */
1074
1075    mbedtls_x509_crt_free( &crt );
1076    mbedtls_x509_crt_init( &crt );
1077
1078    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, parse_crt_ext_cb, &oid ) == ( result ) );
1079#if !defined(MBEDTLS_X509_REMOVE_INFO)
1080    if( ( result ) == 0 )
1081    {
1082        res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
1083
1084        TEST_ASSERT( res != -1 );
1085        TEST_ASSERT( res != -2 );
1086
1087        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1088    }
1089#endif /* !MBEDTLS_X509_REMOVE_INFO */
1090
1091exit:
1092    mbedtls_x509_crt_free( &crt );
1093}
1094/* END_CASE */
1095
1096/* BEGIN_CASE depends_on:MBEDTLS_X509_CRL_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
1097void x509parse_crl( data_t * buf, char * result_str, int result )
1098{
1099    mbedtls_x509_crl   crl;
1100    unsigned char output[2000];
1101    int res;
1102
1103    mbedtls_x509_crl_init( &crl );
1104    memset( output, 0, 2000 );
1105
1106
1107    TEST_ASSERT( mbedtls_x509_crl_parse( &crl, buf->x, buf->len ) == ( result ) );
1108    if( ( result ) == 0 )
1109    {
1110        res = mbedtls_x509_crl_info( (char *) output, 2000, "", &crl );
1111
1112        TEST_ASSERT( res != -1 );
1113        TEST_ASSERT( res != -2 );
1114
1115        TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
1116    }
1117
1118exit:
1119    mbedtls_x509_crl_free( &crl );
1120}
1121/* END_CASE */
1122
1123/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
1124void mbedtls_x509_csr_parse( data_t * csr_der, char * ref_out, int ref_ret )
1125{
1126    mbedtls_x509_csr csr;
1127    char my_out[1000];
1128    int my_ret;
1129
1130    mbedtls_x509_csr_init( &csr );
1131    memset( my_out, 0, sizeof( my_out ) );
1132
1133    my_ret = mbedtls_x509_csr_parse_der( &csr, csr_der->x, csr_der->len );
1134    TEST_ASSERT( my_ret == ref_ret );
1135
1136    if( ref_ret == 0 )
1137    {
1138        size_t my_out_len = mbedtls_x509_csr_info( my_out, sizeof( my_out ), "", &csr );
1139        TEST_ASSERT( my_out_len == strlen( ref_out ) );
1140        TEST_ASSERT( strcmp( my_out, ref_out ) == 0 );
1141    }
1142
1143exit:
1144    mbedtls_x509_csr_free( &csr );
1145}
1146/* END_CASE */
1147
1148/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
1149void mbedtls_x509_crt_parse_path( char * crt_path, int ret, int nb_crt )
1150{
1151    mbedtls_x509_crt chain, *cur;
1152    int i;
1153
1154    mbedtls_x509_crt_init( &chain );
1155
1156    TEST_ASSERT( mbedtls_x509_crt_parse_path( &chain, crt_path ) == ret );
1157
1158    /* Check how many certs we got */
1159    for( i = 0, cur = &chain; cur != NULL; cur = cur->next )
1160        if( cur->raw.p != NULL )
1161            i++;
1162
1163    TEST_ASSERT( i == nb_crt );
1164
1165exit:
1166    mbedtls_x509_crt_free( &chain );
1167}
1168/* END_CASE */
1169
1170/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
1171void mbedtls_x509_crt_verify_max( char *ca_file, char *chain_dir, int nb_int,
1172                                  int ret_chk, int flags_chk )
1173{
1174    char file_buf[128];
1175    int ret;
1176    uint32_t flags;
1177    mbedtls_x509_crt trusted, chain;
1178
1179    /*
1180     * We expect chain_dir to contain certificates 00.crt, 01.crt, etc.
1181     * with NN.crt signed by NN-1.crt
1182     */
1183
1184    mbedtls_x509_crt_init( &trusted );
1185    mbedtls_x509_crt_init( &chain );
1186
1187    USE_PSA_INIT( );
1188
1189    /* Load trusted root */
1190    TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, ca_file ) == 0 );
1191
1192    /* Load a chain with nb_int intermediates (from 01 to nb_int),
1193     * plus one "end-entity" cert (nb_int + 1) */
1194    ret = mbedtls_snprintf( file_buf, sizeof file_buf, "%s/c%02d.pem", chain_dir,
1195                                                            nb_int + 1 );
1196    TEST_ASSERT( ret > 0 && (size_t) ret < sizeof file_buf );
1197    TEST_ASSERT( mbedtls_x509_crt_parse_file( &chain, file_buf ) == 0 );
1198
1199    /* Try to verify that chain */
1200    ret = mbedtls_x509_crt_verify( &chain, &trusted, NULL, NULL, &flags,
1201                                   NULL, NULL );
1202    TEST_ASSERT( ret == ret_chk );
1203    TEST_ASSERT( flags == (uint32_t) flags_chk );
1204
1205exit:
1206    mbedtls_x509_crt_free( &chain );
1207    mbedtls_x509_crt_free( &trusted );
1208    USE_PSA_DONE( );
1209}
1210/* END_CASE */
1211
1212/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
1213void mbedtls_x509_crt_verify_chain(  char *chain_paths, char *trusted_ca,
1214                                     int flags_result, int result,
1215                                     char *profile_name, int vrfy_fatal_lvls )
1216{
1217    char* act;
1218    uint32_t flags;
1219    int res;
1220    mbedtls_x509_crt trusted, chain;
1221    const mbedtls_x509_crt_profile *profile = NULL;
1222
1223    mbedtls_x509_crt_init( &chain );
1224    mbedtls_x509_crt_init( &trusted );
1225
1226    USE_PSA_INIT( );
1227
1228    while( ( act = mystrsep( &chain_paths, " " ) ) != NULL )
1229        TEST_ASSERT( mbedtls_x509_crt_parse_file( &chain, act ) == 0 );
1230    TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, trusted_ca ) == 0 );
1231
1232    if( strcmp( profile_name, "" ) == 0 )
1233        profile = &mbedtls_x509_crt_profile_default;
1234    else if( strcmp( profile_name, "next" ) == 0 )
1235        profile = &mbedtls_x509_crt_profile_next;
1236    else if( strcmp( profile_name, "suiteb" ) == 0 )
1237        profile = &mbedtls_x509_crt_profile_suiteb;
1238    else if( strcmp( profile_name, "rsa3072" ) == 0 )
1239        profile = &profile_rsa3072;
1240    else if( strcmp( profile_name, "sha512" ) == 0 )
1241        profile = &profile_sha512;
1242
1243    res = mbedtls_x509_crt_verify_with_profile( &chain, &trusted, NULL, profile,
1244            NULL, &flags, verify_fatal, &vrfy_fatal_lvls );
1245
1246    TEST_ASSERT( res == ( result ) );
1247    TEST_ASSERT( flags == (uint32_t)( flags_result ) );
1248
1249exit:
1250    mbedtls_x509_crt_free( &trusted );
1251    mbedtls_x509_crt_free( &chain );
1252    USE_PSA_DONE( );
1253}
1254/* END_CASE */
1255
1256/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C:!MBEDTLS_X509_REMOVE_INFO */
1257void x509_oid_desc( data_t * buf, char * ref_desc )
1258{
1259    mbedtls_x509_buf oid;
1260    const char *desc = NULL;
1261    int ret;
1262
1263
1264    oid.tag = MBEDTLS_ASN1_OID;
1265    oid.p   = buf->x;
1266    oid.len   = buf->len;
1267
1268    ret = mbedtls_oid_get_extended_key_usage( &oid, &desc );
1269
1270    if( strcmp( ref_desc, "notfound" ) == 0 )
1271    {
1272        TEST_ASSERT( ret != 0 );
1273        TEST_ASSERT( desc == NULL );
1274    }
1275    else
1276    {
1277        TEST_ASSERT( ret == 0 );
1278        TEST_ASSERT( desc != NULL );
1279        TEST_ASSERT( strcmp( desc, ref_desc ) == 0 );
1280    }
1281}
1282/* END_CASE */
1283
1284/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
1285void x509_oid_numstr( data_t * oid_buf, char * numstr, int blen, int ret )
1286{
1287    mbedtls_x509_buf oid;
1288    char num_buf[100];
1289
1290    memset( num_buf, 0x2a, sizeof num_buf );
1291
1292    oid.tag = MBEDTLS_ASN1_OID;
1293    oid.p   = oid_buf->x;
1294    oid.len   = oid_buf->len;
1295
1296    TEST_ASSERT( (size_t) blen <= sizeof num_buf );
1297
1298    TEST_ASSERT( mbedtls_oid_get_numeric_string( num_buf, blen, &oid ) == ret );
1299
1300    if( ret >= 0 )
1301    {
1302        TEST_ASSERT( num_buf[ret] == 0 );
1303        TEST_ASSERT( strcmp( num_buf, numstr ) == 0 );
1304    }
1305}
1306/* END_CASE */
1307
1308/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
1309void x509_check_key_usage( char * crt_file, int usage, int ret )
1310{
1311    mbedtls_x509_crt crt;
1312
1313    mbedtls_x509_crt_init( &crt );
1314
1315    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
1316
1317    TEST_ASSERT( mbedtls_x509_crt_check_key_usage( &crt, usage ) == ret );
1318
1319exit:
1320    mbedtls_x509_crt_free( &crt );
1321}
1322/* END_CASE */
1323
1324/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
1325void x509_check_extended_key_usage( char * crt_file, data_t * oid, int ret
1326                                    )
1327{
1328    mbedtls_x509_crt crt;
1329
1330    mbedtls_x509_crt_init( &crt );
1331
1332
1333    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
1334
1335    TEST_ASSERT( mbedtls_x509_crt_check_extended_key_usage( &crt, (const char *)oid->x, oid->len ) == ret );
1336
1337exit:
1338    mbedtls_x509_crt_free( &crt );
1339}
1340/* END_CASE */
1341
1342/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
1343void x509_get_time( int tag, char * time_str, int ret, int year, int mon,
1344                    int day, int hour, int min, int sec )
1345{
1346    mbedtls_x509_time time;
1347    unsigned char buf[21];
1348    unsigned char* start = buf;
1349    unsigned char* end = buf;
1350
1351    memset( &time, 0x00, sizeof( time ) );
1352    *end = (unsigned char)tag; end++;
1353    *end = strlen( time_str );
1354    TEST_ASSERT( *end < 20 );
1355    end++;
1356    memcpy( end, time_str, (size_t)*(end - 1) );
1357    end += *(end - 1);
1358
1359    TEST_ASSERT( mbedtls_x509_get_time( &start, end, &time ) == ret );
1360    if( ret == 0 )
1361    {
1362        TEST_ASSERT( year == time.year );
1363        TEST_ASSERT( mon  == time.mon  );
1364        TEST_ASSERT( day  == time.day  );
1365        TEST_ASSERT( hour == time.hour );
1366        TEST_ASSERT( min  == time.min  );
1367        TEST_ASSERT( sec  == time.sec  );
1368    }
1369}
1370/* END_CASE */
1371
1372/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT */
1373void x509_parse_rsassa_pss_params( data_t * params, int params_tag,
1374                                   int ref_msg_md, int ref_mgf_md,
1375                                   int ref_salt_len, int ref_ret )
1376{
1377    int my_ret;
1378    mbedtls_x509_buf buf;
1379    mbedtls_md_type_t my_msg_md, my_mgf_md;
1380    int my_salt_len;
1381
1382    buf.p = params->x;
1383    buf.len = params->len;
1384    buf.tag = params_tag;
1385
1386    my_ret = mbedtls_x509_get_rsassa_pss_params( &buf, &my_msg_md, &my_mgf_md,
1387                                                 &my_salt_len );
1388
1389    TEST_ASSERT( my_ret == ref_ret );
1390
1391    if( ref_ret == 0 )
1392    {
1393        TEST_ASSERT( my_msg_md == (mbedtls_md_type_t) ref_msg_md );
1394        TEST_ASSERT( my_mgf_md == (mbedtls_md_type_t) ref_mgf_md );
1395        TEST_ASSERT( my_salt_len == ref_salt_len );
1396    }
1397
1398exit:
1399    ;;
1400}
1401/* END_CASE */
1402