Exemplo n.º 1
0
static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
{
    char buf[1024];
    ((void) data);

    polarssl_printf( "\nVerify requested for (Depth %d):\n", depth );
    x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
    polarssl_printf( "%s", buf );

    if( ( (*flags) & BADCERT_EXPIRED ) != 0 )
        polarssl_printf( "  ! server certificate has expired\n" );

    if( ( (*flags) & BADCERT_REVOKED ) != 0 )
        polarssl_printf( "  ! server certificate has been revoked\n" );

    if( ( (*flags) & BADCERT_CN_MISMATCH ) != 0 )
        polarssl_printf( "  ! CN mismatch\n" );

    if( ( (*flags) & BADCERT_NOT_TRUSTED ) != 0 )
        polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );

    if( ( (*flags) & BADCRL_NOT_TRUSTED ) != 0 )
        polarssl_printf( "  ! CRL not trusted\n" );

    if( ( (*flags) & BADCRL_EXPIRED ) != 0 )
        polarssl_printf( "  ! CRL expired\n" );

    if( ( (*flags) & BADCERT_OTHER ) != 0 )
        polarssl_printf( "  ! other (unknown) flag\n" );

    if ( ( *flags ) == 0 )
        polarssl_printf( "  This certificate has no flags\n" );

    return( 0 );
}
Exemplo n.º 2
0
/*
 * Checkup routine
 */
int md2_self_test( int verbose )
{
    int i;
    unsigned char md2sum[16];

    for( i = 0; i < 7; i++ )
    {
        if( verbose != 0 )
            polarssl_printf( "  MD2 test #%d: ", i + 1 );

        md2( (unsigned char *) md2_test_str[i],
             strlen( md2_test_str[i] ), md2sum );

        if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
        {
            if( verbose != 0 )
                polarssl_printf( "failed\n" );

            return( 1 );
        }

        if( verbose != 0 )
            polarssl_printf( "passed\n" );
    }

    if( verbose != 0 )
        polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 3
0
/*
 * Checkup routine
 */
int arc4_self_test( int verbose )
{
    int i;
    unsigned char ibuf[8];
    unsigned char obuf[8];
    arc4_context ctx;

    for( i = 0; i < 3; i++ )
    {
        if( verbose != 0 )
            polarssl_printf( "  ARC4 test #%d: ", i + 1 );

        memcpy( ibuf, arc4_test_pt[i], 8 );

        arc4_setup( &ctx, arc4_test_key[i], 8 );
        arc4_crypt( &ctx, 8, ibuf, obuf );

        if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
        {
            if( verbose != 0 )
                polarssl_printf( "failed\n" );

            return( 1 );
        }

        if( verbose != 0 )
            polarssl_printf( "passed\n" );
    }

    if( verbose != 0 )
        polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 4
0
int main( int argc, char *argv[] )
{
    int ret, i;

    if( argc == 1 )
    {
        polarssl_printf( "print mode:  sha1sum <file> <file> ...\n" );
        polarssl_printf( "check mode:  sha1sum -c <checksum file>\n" );

#if defined(_WIN32)
        polarssl_printf( "\n  Press Enter to exit this program.\n" );
        fflush( stdout ); getchar();
#endif

        return( 1 );
    }

    if( argc == 3 && strcmp( "-c", argv[1] ) == 0 )
        return( sha1_check( argv[2] ) );

    ret = 0;
    for( i = 1; i < argc; i++ )
        ret |= sha1_print( argv[i] );

    return( ret );
}
Exemplo n.º 5
0
static void dump_buf( const char *title, unsigned char *buf, size_t len )
{
    size_t i;

    polarssl_printf( "%s", title );
    for( i = 0; i < len; i++ )
        polarssl_printf("%c%c", "0123456789ABCDEF" [buf[i] / 16],
                       "0123456789ABCDEF" [buf[i] % 16] );
    polarssl_printf( "\n" );
}
Exemplo n.º 6
0
static int sha1_print( char *filename )
{
    int i;
    unsigned char sum[20];

    if( sha1_wrapper( filename, sum ) != 0 )
        return( 1 );

    for( i = 0; i < 20; i++ )
        polarssl_printf( "%02x", sum[i] );

    polarssl_printf( "  %s\n", filename );
    return( 0 );
}
Exemplo n.º 7
0
/*
 * Checkup routine for HMAC_DRBG with SHA-1
 */
SSL_ROM_TEXT_SECTION
int hmac_drbg_self_test( int verbose )
{
    hmac_drbg_context ctx;
    unsigned char buf[OUTPUT_LEN];
    const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 );

    /*
     * PR = True
     */
    if( verbose != 0 )
        polarssl_printf( "  HMAC_DRBG (PR = True) : " );

    test_offset = 0;
    CHK( hmac_drbg_init( &ctx, md_info,
                         hmac_drbg_self_test_entropy, entropy_pr,
                         NULL, 0 ) );
    hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON );
    CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
    CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
    CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
    hmac_drbg_free( &ctx );

    if( verbose != 0 )
        polarssl_printf( "passed\n" );

    /*
     * PR = False
     */
    if( verbose != 0 )
        polarssl_printf( "  HMAC_DRBG (PR = False) : " );

    test_offset = 0;
    CHK( hmac_drbg_init( &ctx, md_info,
                         hmac_drbg_self_test_entropy, entropy_nopr,
                         NULL, 0 ) );
    CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) );
    CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
    CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
    CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
    hmac_drbg_free( &ctx );

    if( verbose != 0 )
        polarssl_printf( "passed\n" );

    if( verbose != 0 )
        polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 8
0
int main( void )
{
    polarssl_printf( "POLARSSL_CTR_DRBG_C and/or POLARSSL_ENTROPY_C and/or "
            "POLARSSL_NET_C and/or POLARSSL_SSL_CLI_C and/or UNIX "
            "not defined.\n");
    return( 0 );
}
Exemplo n.º 9
0
int main( void )
{
    polarssl_printf("POLARSSL_RSA_C and/or POLARSSL_X509_CRT_PARSE_C "
           "POLARSSL_FS_IO and/or POLARSSL_X509_CRL_PARSE_C "
           "not defined.\n");
    return( 0 );
}
Exemplo n.º 10
0
int main( void )
{
    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_PK_PARSE_C and/or "
           "POLARSSL_FS_IO and/or POLARSSL_ENTROPY_C and/or "
           "POLARSSL_CTR_DRBG_C not defined.\n");
    return( 0 );
}
Exemplo n.º 11
0
/* Dummy checkup routine */
int hmac_drbg_self_test( int verbose )
{

    if( verbose != 0 )
        polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 12
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf( "POLARSSL_PK_WRITE_C and/or POLARSSL_FS_IO not defined.\n" );
    return( 0 );
}
Exemplo n.º 13
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_TIMING_C not defined.\n");
    return( 0 );
}
Exemplo n.º 14
0
int main( void )
{
    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C "
                    "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
                    "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
                    "POLARSSL_CTR_DRBG_C and/or POLARSSL_X509_CRT_PARSE_C "
                    "not defined.\n");
    return( 0 );
}
Exemplo n.º 15
0
/* Dummy checkup routine */
SSL_ROM_TEXT_SECTION
int hmac_drbg_self_test( int verbose )
{

    if( verbose != 0 )
        polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 16
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_RSA_C and/or "
           "POLARSSL_X509_CRL_PARSE_C and/or POLARSSL_FS_IO not defined.\n");
    return( 0 );
}
Exemplo n.º 17
0
/*
 * Checkup routine
 */
int ctr_drbg_self_test( int verbose )
{
    ctr_drbg_context ctx;
    unsigned char buf[16];

    /*
     * Based on a NIST CTR_DRBG test vector (PR = True)
     */
    if( verbose != 0 )
        polarssl_printf( "  CTR_DRBG (PR = TRUE) : " );

    test_offset = 0;
    CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy,
                                entropy_source_pr, nonce_pers_pr, 16, 32 ) );
    ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
    CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) );
    CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) );
    CHK( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) );

    if( verbose != 0 )
        polarssl_printf( "passed\n" );

    /*
     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
     */
    if( verbose != 0 )
        polarssl_printf( "  CTR_DRBG (PR = FALSE): " );

    test_offset = 0;
    CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy,
                            entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
    CHK( ctr_drbg_random( &ctx, buf, 16 ) );
    CHK( ctr_drbg_reseed( &ctx, NULL, 0 ) );
    CHK( ctr_drbg_random( &ctx, buf, 16 ) );
    CHK( memcmp( buf, result_nopr, 16 ) );

    if( verbose != 0 )
        polarssl_printf( "passed\n" );

    if( verbose != 0 )
            polarssl_printf( "\n" );

    return( 0 );
}
Exemplo n.º 18
0
/*
 * Enabled if debug_level > 1 in code below
 */
static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
{
    char buf[1024];
    ((void) data);

    polarssl_printf( "\nVerify requested for (Depth %d):\n", depth );
    x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
    polarssl_printf( "%s", buf );

    if ( ( *flags ) == 0 )
        polarssl_printf( "  This certificate has no flags\n" );
    else
    {
        x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
        polarssl_printf( "%s\n", buf );
    }

    return( 0 );
}
Exemplo n.º 19
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_ENTROPY_C and/or "
           "POLARSSL_FS_IO and/or POLARSSL_CTR_DRBG_C and/or "
           "POLARSSL_GENPRIME not defined.\n");
    return( 0 );
}
Exemplo n.º 20
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_ENTROPY_C and/or "
           "POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_CLI_C and/or "
           "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
           "POLARSSL_X509_CRT_PARSE_C and/or POLARSSL_FS_IO and/or "
           "POLARSSL_CTR_DRBG_C not defined.\n");
    return( 0 );
}
Exemplo n.º 21
0
int main( void )
{
    int i;
    unsigned char digest[16];
    char str[] = "Hello, world!";

    polarssl_printf( "\n  MD5('%s') = ", str );

    md5( (unsigned char *) str, 13, digest );

    for( i = 0; i < 16; i++ )
        polarssl_printf( "%02x", digest[i] );

    polarssl_printf( "\n\n" );

#if defined(_WIN32)
    polarssl_printf( "  Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( 0 );
}
Exemplo n.º 22
0
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C "
           "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
           "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
           "POLARSSL_CTR_DRBG_C and/or POLARSSL_X509_CRT_PARSE_C and/or "
           "POLARSSL_THREADING_C and/or POLARSSL_THREADING_PTHREAD "
           "not defined.\n");
    return( 0 );
}
Exemplo n.º 23
0
int main( int argc, char *argv[] )
{
    long int val;
    char *end = argv[1];

    if( argc != 2 )
    {
        polarssl_printf( USAGE );
        return( 0 );
    }

    val = strtol( argv[1], &end, 10 );
    if( *end != '\0' )
    {
        val = strtol( argv[1], &end, 16 );
        if( *end != '\0' )
        {
            polarssl_printf( USAGE );
            return( 0 );
        }
    }
    if( val > 0 )
        val = -val;

    if( val != 0 )
    {
        char error_buf[200];
        polarssl_strerror( val, error_buf, 200 );
        polarssl_printf("Last error was: -0x%04x - %s\n\n", (int) -val, error_buf );
    }

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( val );
}
Exemplo n.º 24
0
static void dump_pubkey( const char *title, ecdsa_context *key )
{
    unsigned char buf[300];
    size_t len;

    if( ecp_point_write_binary( &key->grp, &key->Q,
                POLARSSL_ECP_PF_UNCOMPRESSED, &len, buf, sizeof buf ) != 0 )
    {
        polarssl_printf("internal error\n");
        return;
    }

    dump_buf( title, buf, len );
}
Exemplo n.º 25
0
static int thread_create( int client_fd )
{
    int ret, i;

    /*
     * Find in-active or finished thread slot
     */
    for( i = 0; i < MAX_NUM_THREADS; i++ )
    {
        if( threads[i].active == 0 )
            break;

        if( threads[i].data.thread_complete == 1 )
        {
            polarssl_printf( "  [ main ]  Cleaning up thread %d\n", i );
            pthread_join(threads[i].thread, NULL );
            memset( &threads[i], 0, sizeof(pthread_info_t) );
            break;
        }
    }

    if( i == MAX_NUM_THREADS )
        return( -1 );

    /*
     * Fill thread-info for thread
     */
    memcpy( &threads[i].data, &base_info, sizeof(base_info) );
    threads[i].active = 1;
    threads[i].data.client_fd = client_fd;

    if( ( ret = pthread_create( &threads[i].thread, NULL, handle_ssl_connection,                                &threads[i].data ) ) != 0 )
    {
        return( ret );
    }

    return( 0 );
}
Exemplo n.º 26
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    pk_context pk;
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    unsigned char hash[20];
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    char filename[512];
    const char *pers = "pk_sign";
    size_t olen = 0;

    entropy_init( &entropy );
    pk_init( &pk );

    if( argc != 3 )
    {
        polarssl_printf( "usage: pk_sign <key_file> <filename>\n" );

#if defined(_WIN32)
        polarssl_printf( "\n" );
#endif

        goto exit;
    }

    polarssl_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ctr_drbg_init returned -0x%04x\n", -ret );
        goto exit;
    }

    polarssl_printf( "\n  . Reading private key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not open '%s'\n", argv[1] );
        goto exit;
    }

    /*
     * Compute the SHA-1 hash of the input file,
     * then calculate the signature of the hash.
     */
    polarssl_printf( "\n  . Generating the SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[2], hash ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = pk_sign( &pk, POLARSSL_MD_SHA1, hash, 0, buf, &olen,
                         ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! pk_sign returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>-sig.txt
     */
    snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not create %s\n\n", filename );
        goto exit;
    }

    if( fwrite( buf, 1, olen, f ) != olen )
    {
        polarssl_printf( "failed\n  ! fwrite failed\n\n" );
        goto exit;
    }

    fclose( f );

    polarssl_printf( "\n  . Done (created \"%s\")\n\n", filename );

exit:
    pk_free( &pk );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(POLARSSL_ERROR_C)
    polarssl_strerror( ret, (char *) buf, sizeof(buf) );
    polarssl_printf( "  !  Last error was: %s\n", buf );
#endif

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
Exemplo n.º 27
0
int main( int argc, char *argv[] )
{
    int ret = 0;
    unsigned char buf[100000];
    x509_crl crl;
    int i;
    char *p, *q;

    /*
     * Set to sane values
     */
    x509_crl_init( &crl );

    if( argc == 0 )
    {
usage:
        polarssl_printf( USAGE );
        goto exit;
    }

    opt.filename            = DFL_FILENAME;

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else
            goto usage;
    }

    /*
     * 1.1. Load the CRL
     */
    polarssl_printf( "\n  . Loading the CRL ..." );
    fflush( stdout );

    ret = x509_crl_parse_file( &crl, opt.filename );

    if( ret != 0 )
    {
        polarssl_printf( " failed\n  !  x509_crl_parse_file returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    polarssl_printf( " ok\n" );

    /*
     * 1.2 Print the CRL
     */
    polarssl_printf( "  . CRL information    ...\n" );
    ret = x509_crl_info( (char *) buf, sizeof( buf ) - 1, "      ", &crl );
    if( ret == -1 )
    {
        polarssl_printf( " failed\n  !  x509_crl_info returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    polarssl_printf( "%s\n", buf );

exit:
    x509_crl_free( &crl );

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
Exemplo n.º 28
0
int main( int argc, const char *argv[] )
{
    /* Client and server declarations. */
    int ret;
    int len;
#if SOCKET_COMMUNICATION
    int listen_fd = -1;
    int client_fd = -1;
    int server_fd = -1;
#endif
    unsigned char buf[1024];
    /* Handshake step counter */
    size_t step = 1;
    int flags;

    ssl_context s_ssl, c_ssl;
    x509_crt srvcert;
    pk_context pkey;
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_context cache;
#endif

    if( argc == 3)
    {
        packet_in_num = atoi(argv[1]);
        packet_in_file = argv[2];
    }
    else if( argc != 1)
    {
        usage(argv[0]);
        exit(1);
    }

    /* Server init */
    memset( &s_ssl, 0, sizeof( ssl_context ) );
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_init( &cache );
#endif
    x509_crt_init( &srvcert );
    pk_init( &pkey );

    /* Client init */
    memset( &c_ssl, 0, sizeof( ssl_context ) );
    /*x509_crt_init( &cacert );*/

#if defined(POLARSSL_DEBUG_C)
    debug_set_threshold( DEBUG_LEVEL );
#endif

    /*
     * Server:
     * Load the certificates and private RSA key
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Loading the server cert. and key..." );
        fflush( stdout );
    }

    /*
     * This demonstration program uses embedded test certificates.
     * Instead, you may want to use x509_crt_parse_file() to read the
     * server and CA certificates, as well as pk_parse_keyfile().
     */
    ret = x509_crt_parse( &srvcert, (const unsigned char *) test_srv_crt,
                          strlen( test_srv_crt ) );
    if( ret != 0 )
    {
        printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret );
        goto exit;
    }

    ret = x509_crt_parse( &srvcert, (const unsigned char *) test_ca_list,
                          strlen( test_ca_list ) );
    if( ret != 0 )
    {
        polarssl_printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret );
        goto exit;
    }

    ret =  pk_parse_key( &pkey, (const unsigned char *) test_srv_key,
                         strlen( test_srv_key ), NULL, 0 );
    if( ret != 0 )
    {
        printf( " failed\n  !  pk_parse_key returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * Setup stuff
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Server: Setting up the SSL data...." );
        fflush( stdout );
    }

    if( ( ret = ssl_init( &s_ssl ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
        goto exit;
    }

    ssl_set_endpoint( &s_ssl, SSL_IS_SERVER );
    ssl_set_authmode( &s_ssl, SSL_VERIFY_NONE );

    /* SSLv3 is deprecated, set minimum to TLS 1.0 */
    ssl_set_min_version( &s_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 );
    /* RC4 is deprecated, disable it */
    ssl_set_arc4_support( &s_ssl, SSL_ARC4_DISABLED );

    ssl_set_rng( &s_ssl, ctr_drbg_deterministic, NULL );
    ssl_set_dbg( &s_ssl, my_debug, stdout );

#if defined(POLARSSL_SSL_CACHE_C)
    ssl_set_session_cache( &s_ssl, ssl_cache_get, &cache,
                           ssl_cache_set, &cache );
#endif

    ssl_set_ca_chain( &s_ssl, srvcert.next, NULL, NULL );
    if( ( ret = ssl_set_own_cert( &s_ssl, &srvcert, &pkey ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    ssl_session_reset( &s_ssl );

#if SOCKET_COMMUNICATION
    /*
     * Server:
     * Setup the listening TCP socket
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Bind on https://localhost:%d/ ...", SERVER_PORT );
        fflush( stdout );
    }

    if( ( ret = net_bind( &listen_fd, NULL, SERVER_PORT ) ) != 0 )
    {
        printf( " failed\n  ! net_bind returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Client:
     * Start the connection
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Connecting to tcp/%s/%d...", SERVER_NAME, SERVER_PORT );
        fflush( stdout );
    }

    if( ( ret = net_connect( &server_fd, SERVER_NAME,
                             SERVER_PORT ) ) != 0 )
    {
        printf( " failed\n  ! net_connect returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * Start listening for client connections
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Waiting for a remote connection ..." );
        fflush( stdout );
    }

    /*
     * Server:
     * Accept client connection (socket is set non-blocking in
     * library/net.c)
     */
    if( ( ret = net_accept( listen_fd, &client_fd,
                            NULL ) ) != 0 )
    {
        printf( " failed\n  ! net_accept returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    ssl_set_bio( &s_ssl, recv_custom, &client_fd, send_custom, &client_fd );
#else
    ssl_set_bio( &s_ssl, func_server_recv_buf, NULL, func_server_send_buf, NULL );
#endif

    /*
     * Client:
     * Setup stuff
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Client: Setting up the SSL/TLS structure..." );
        fflush( stdout );
    }

    if( ( ret = ssl_init( &c_ssl ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        polarssl_printf( " ok\n" );
    }

    ssl_set_endpoint( &c_ssl, SSL_IS_CLIENT );
    /* OPTIONAL is not optimal for security,
     * but makes interop easier in this simplified example */
    ssl_set_authmode( &c_ssl, SSL_VERIFY_OPTIONAL );
    /* NONE permits man-in-the-middle attacks. */
    /*ssl_set_authmode( &c_ssl, VERIFY_NONE );*/
    /*ssl_set_authmode( &c_ssl, SSL_VERIFY_REQUIRED );*/
    ssl_set_ca_chain( &c_ssl, &srvcert, NULL, "PolarSSL Server 1" );

    /* SSLv3 is deprecated, set minimum to TLS 1.0 */
    ssl_set_min_version( &c_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 );
    /* RC4 is deprecated, disable it */
    ssl_set_arc4_support( &c_ssl, SSL_ARC4_DISABLED );

    ssl_set_rng( &c_ssl, ctr_drbg_deterministic, NULL );
    ssl_set_dbg( &c_ssl, my_debug, stdout );

    if( ( ret = ssl_set_hostname( &c_ssl, "mbed TLS Server 1" ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_hostname returned %d\n\n", ret );
        goto exit;
    }

#if SOCKET_COMMUNICATION
    ssl_set_bio( &c_ssl, recv_custom, &server_fd, send_custom, &server_fd );
#else
    ssl_set_bio( &c_ssl, func_client_recv_buf, NULL, func_client_send_buf,  NULL );
#endif

    if( packet_in_num == 0 )
    {
        printf( "  . Performing the SSL/TLS handshake...\n" );
        fflush( stdout );
    }

    /*
     * The following number of steps are hardcoded to ensure
     * that the client and server complete the handshake without
     * waiting infinitely for the other side to send data.
     *
     *                     1  2  3  4  5  6  7  8  9
     */
    int client_steps[] = { 2, 1, 1, 1, 4, 2, 1, 1, 3 };
    int server_steps[] = { 3, 1, 1, 3, 2, 1, 2, 1, 2 };

    do {
        /*
         * Client:
         * Handshake step
         */
        int i;
        int no_steps;

        if( c_ssl.state == SSL_HANDSHAKE_OVER ) {
            no_steps = 0;
        } else {
            no_steps = client_steps[step - 1];
        }

        for (i = 0; i < no_steps; i++) {
            if(  ( ret = ssl_handshake_step( &c_ssl ) ) != 0 )
            {
                if(  ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
                {
                    printf( " failed\n  ! ssl_handshake returned -0x%x\n\n", -ret );
                    goto exit;
                }
            }
        }

        if( packet_in_num == 0 )
        {
            printf( "--- client handshake step %zd ok\n", step );
        }

        /*
         * Server:
         * Handshake step
         */
        if( s_ssl.state == SSL_HANDSHAKE_OVER ) {
            printf("over\n");
            no_steps = 0;
        } else {
            no_steps = server_steps[step - 1];
        }

        for (i = 0; i < no_steps; i++) {
            if(  ( ret = ssl_handshake_step( &s_ssl ) ) != 0 )
            {
                if(  ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
                {
                    printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
                    goto exit;
                }
            }
        }

        if( packet_in_num == 0 )
        {
            printf( "--- server handshake step %zd ok\n", step );
        }

        step++;
    } while( ((c_ssl.state != SSL_HANDSHAKE_OVER)
              || (s_ssl.state != SSL_HANDSHAKE_OVER))
             && (step <= MAX_HANDSHAKE_STEPS) );

    if( packet_in_num == 0 )
    {
        printf( "c_ssl.state: %d\n", c_ssl.state != SSL_HANDSHAKE_OVER );
        printf( "s_ssl.state: %d\n", s_ssl.state != SSL_HANDSHAKE_OVER );
    }

    /*
     * Client:
     * Verify the server certificate
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Verifying peer X.509 certificate..." );
    }

    /* In real life, we probably want to bail out when ret != 0 */
    if( ( flags = ssl_get_verify_result( &c_ssl ) ) != 0 )
    {
        char vrfy_buf[512];

        printf( " failed\n" );

        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );

        printf( "%s\n", vrfy_buf );
    }
    else if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Client:
     * Write the GET request
     */
    if( packet_in_num == 0 )
    {
        printf( "  > Write to server:" );
        fflush( stdout );
    }

    len = sprintf( (char *) buf, GET_REQUEST );

    while( ( ret = ssl_write( &c_ssl, buf, len ) ) <= 0 )
    {
        if( ret !=POLARSSL_ERR_NET_WANT_READ && ret !=POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_write returned %d\n\n", ret );
            goto exit;
        }
    }

    len = ret;
    if( packet_in_num == 0 )
    {
        printf( " %d bytes written\n\n%s", len, (char *) buf );
    }

    /*
     * Server:
     * Read the HTTP Request
     */
    if( packet_in_num == 0 )
    {
        printf( "  < Read from client:" );
        fflush( stdout );
    }

    do
    {
        len = sizeof( buf ) - 1;
        memset( buf, 0, sizeof( buf ) );
        ret = ssl_read( &s_ssl, buf, len );

        if( ret ==POLARSSL_ERR_NET_WANT_READ || ret ==POLARSSL_ERR_NET_WANT_WRITE )
            continue;

        if( ret <= 0 )
        {
            switch( ret )
            {
            case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
                printf( " connection was closed gracefully\n" );
                break;

            case POLARSSL_ERR_NET_CONN_RESET:
                printf( " connection was reset by peer\n" );
                break;

            default:
                printf( " ssl_read returned -0x%x\n", -ret );
                break;
            }

            break;
        }

        len = ret;
        if( packet_in_num == 0 )
        {
            printf( " %d bytes read\n\n%s", len, (char *) buf );
        }

        if( ret > 0 )
            break;
    }
    while( 1 );

    /*
     * Server:
     * Write the 200 Response
     */
    if( packet_in_num == 0 )
    {
        printf( "  > Write to client:" );
        fflush( stdout );
    }

    len = sprintf( (char *) buf, HTTP_RESPONSE,
                   ssl_get_ciphersuite( &s_ssl ) );

    while( ( ret = ssl_write( &s_ssl, buf, len ) ) <= 0 )
    {
        if( ret == POLARSSL_ERR_NET_CONN_RESET )
        {
            printf( " failed\n  ! peer closed the connection\n\n" );
            goto exit;
        }

        if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_write returned %d\n\n", ret );
            goto exit;
        }
    }

    len = ret;
    if( packet_in_num == 0 )
    {
        printf( " %d bytes written\n\n%s\n", len, (char *) buf );
    }

    /*
     * Client:
     * Read the HTTP response
     */
    if( packet_in_num == 0 )
    {
        printf( "  < Read from server:" );
        fflush( stdout );
    }

    do
    {
        len = sizeof( buf ) - 1;
        memset( buf, 0, sizeof( buf ) );
        ret = ssl_read( &c_ssl, buf, len );

        if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
            continue;

        if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
        {
            ret = 0;
            break;
        }

        if( ret < 0 )
        {
            printf( "failed\n  ! ssl_read returned %d\n\n", ret );
            break;
        }

        if( ret == 0 )
        {
            printf( "\n\nEOF\n\n" );
            break;
        }

        len = ret;
        if( packet_in_num == 0 )
        {
            printf( " %d bytes read\n\n%s", len, (char *) buf );
        }

        /*
         * Server:
         * Client read response. Close connection.
         */
        if ( packet_in_num == 0 )
        {
            printf( "  . Closing the connection..." );
            fflush( stdout );
        }

        while( ( ret = ssl_close_notify( &s_ssl ) ) < 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ &&
                    ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_close_notify returned %d\n\n", ret );
                goto exit;
            }
        }

        if( packet_in_num == 0 )
        {
            printf( " ok\n" );
        }
    }
    while( 1 );

    /*
     * Client:
     * Close connection.
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Closing the connection..." );
        fflush( stdout );
    }

    ssl_close_notify( &c_ssl );

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * We do not have multiple clients and therefore do not goto reset.
     */
    /*ret = 0;*/
    /*goto reset;*/

exit:

#ifdef POLARSSL_ERROR_C
    if( ret != 0 )
    {
        char error_buf[100];
        polarssl_strerror( ret, error_buf, 100 );
        printf("Last error was: %d - %s\n\n", ret, error_buf );
    }
#endif

#if SOCKET_COMMUNICATION
    if ( client_fd != 1 )
        net_close( client_fd );
    if( server_fd != -1 )
        net_close( server_fd );
    if ( listen_fd != 1 )
        net_close( listen_fd );
#endif

    x509_crt_free( &srvcert );
    pk_free( &pkey );
    ssl_free( &s_ssl );
    ssl_free( &c_ssl );
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_free( &cache );
#endif

#if defined(_WIN32)
    printf( "  Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
Exemplo n.º 29
0
int main( int argc, char *argv[] )
{
    int ret = 0, server_fd;
    unsigned char buf[1024];
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    ssl_context ssl;
    x509_crt cacert;
    x509_crt clicert;
    x509_crl cacrl;
    pk_context pkey;
    int i, j;
    int flags, verify = 0;
    char *p, *q;
    const char *pers = "cert_app";

    /*
     * Set to sane values
     */
    server_fd = 0;
    x509_crt_init( &cacert );
    x509_crt_init( &clicert );
#if defined(POLARSSL_X509_CRL_PARSE_C)
    x509_crl_init( &cacrl );
#else
    /* Zeroize structure as CRL parsing is not supported and we have to pass
       it to the verify function */
    memset( &cacrl, 0, sizeof(x509_crl) );
#endif
    pk_init( &pkey );

    if( argc == 0 )
    {
    usage:
        polarssl_printf( USAGE );
        ret = 2;
        goto exit;
    }

    opt.mode                = DFL_MODE;
    opt.filename            = DFL_FILENAME;
    opt.ca_file             = DFL_CA_FILE;
    opt.crl_file            = DFL_CRL_FILE;
    opt.ca_path             = DFL_CA_PATH;
    opt.server_name         = DFL_SERVER_NAME;
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
    opt.permissive          = DFL_PERMISSIVE;

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        for( j = 0; p + j < q; j++ )
        {
            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
                argv[i][j] |= 0x20;
        }

        if( strcmp( p, "mode" ) == 0 )
        {
            if( strcmp( q, "file" ) == 0 )
                opt.mode = MODE_FILE;
            else if( strcmp( q, "ssl" ) == 0 )
                opt.mode = MODE_SSL;
            else
                goto usage;
        }
        else if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else if( strcmp( p, "ca_file" ) == 0 )
            opt.ca_file = q;
        else if( strcmp( p, "crl_file" ) == 0 )
            opt.crl_file = q;
        else if( strcmp( p, "ca_path" ) == 0 )
            opt.ca_path = q;
        else if( strcmp( p, "server_name" ) == 0 )
            opt.server_name = q;
        else if( strcmp( p, "server_port" ) == 0 )
        {
            opt.server_port = atoi( q );
            if( opt.server_port < 1 || opt.server_port > 65535 )
                goto usage;
        }
        else if( strcmp( p, "debug_level" ) == 0 )
        {
            opt.debug_level = atoi( q );
            if( opt.debug_level < 0 || opt.debug_level > 65535 )
                goto usage;
        }
        else if( strcmp( p, "permissive" ) == 0 )
        {
            opt.permissive = atoi( q );
            if( opt.permissive < 0 || opt.permissive > 1 )
                goto usage;
        }
        else
            goto usage;
    }

    /*
     * 1.1. Load the trusted CA
     */
    polarssl_printf( "  . Loading the CA root certificate ..." );
    fflush( stdout );

    if( strlen( opt.ca_path ) )
    {
        ret = x509_crt_parse_path( &cacert, opt.ca_path );
        verify = 1;
    }
    else if( strlen( opt.ca_file ) )
    {
        ret = x509_crt_parse_file( &cacert, opt.ca_file );
        verify = 1;
    }

    if( ret < 0 )
    {
        polarssl_printf( " failed\n  !  x509_crt_parse returned -0x%x\n\n", -ret );
        goto exit;
    }

    polarssl_printf( " ok (%d skipped)\n", ret );

#if defined(POLARSSL_X509_CRL_PARSE_C)
    if( strlen( opt.crl_file ) )
    {
        if( ( ret = x509_crl_parse_file( &cacrl, opt.crl_file ) ) != 0 )
        {
            polarssl_printf( " failed\n  !  x509_crl_parse returned -0x%x\n\n", -ret );
            goto exit;
        }

        verify = 1;
    }
#endif

    if( opt.mode == MODE_FILE )
    {
        x509_crt crt;
        x509_crt *cur = &crt;
        x509_crt_init( &crt );

        /*
         * 1.1. Load the certificate(s)
         */
        polarssl_printf( "\n  . Loading the certificate(s) ..." );
        fflush( stdout );

        ret = x509_crt_parse_file( &crt, opt.filename );

        if( ret < 0 )
        {
            polarssl_printf( " failed\n  !  x509_crt_parse_file returned %d\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        if( opt.permissive == 0 && ret > 0 )
        {
            polarssl_printf( " failed\n  !  x509_crt_parse failed to parse %d certificates\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        polarssl_printf( " ok\n" );

        /*
         * 1.2 Print the certificate(s)
         */
        while( cur != NULL )
        {
            polarssl_printf( "  . Peer certificate information    ...\n" );
            ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                                 cur );
            if( ret == -1 )
            {
                polarssl_printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
                x509_crt_free( &crt );
                goto exit;
            }

            polarssl_printf( "%s\n", buf );

            cur = cur->next;
        }

        /*
         * 1.3 Verify the certificate
         */
        if( verify )
        {
            polarssl_printf( "  . Verifying X.509 certificate..." );

            if( ( ret = x509_crt_verify( &crt, &cacert, &cacrl, NULL, &flags,
                                         my_verify, NULL ) ) != 0 )
            {
                polarssl_printf( " failed\n" );

                if( ( ret & BADCERT_EXPIRED ) != 0 )
                    polarssl_printf( "  ! server certificate has expired\n" );

                if( ( ret & BADCERT_REVOKED ) != 0 )
                    polarssl_printf( "  ! server certificate has been revoked\n" );

                if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
                    polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", opt.server_name );

                if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
                    polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );

                polarssl_printf( "\n" );
            }
            else
                polarssl_printf( " ok\n" );
        }

        x509_crt_free( &crt );
    }
    else if( opt.mode == MODE_SSL )
    {
        /*
         * 1. Initialize the RNG and the session data
         */
        polarssl_printf( "\n  . Seeding the random number generator..." );
        fflush( stdout );

        entropy_init( &entropy );
        if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                                   (const unsigned char *) pers,
                                   strlen( pers ) ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ctr_drbg_init returned %d\n", ret );
            goto exit;
        }

        polarssl_printf( " ok\n" );

        /*
         * 2. Start the connection
         */
        polarssl_printf( "  . SSL connection to tcp/%s/%-4d...", opt.server_name,
                                                        opt.server_port );
        fflush( stdout );

        if( ( ret = net_connect( &server_fd, opt.server_name,
                                             opt.server_port ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! net_connect returned %d\n\n", ret );
            goto exit;
        }

        /*
         * 3. Setup stuff
         */
        if( ( ret = ssl_init( &ssl ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
            goto exit;
        }

        ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
        if( verify )
        {
            ssl_set_authmode( &ssl, SSL_VERIFY_REQUIRED );
            ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
            ssl_set_verify( &ssl, my_verify, NULL );
        }
        else
            ssl_set_authmode( &ssl, SSL_VERIFY_NONE );

        ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
        ssl_set_dbg( &ssl, my_debug, stdout );
        ssl_set_bio( &ssl, net_recv, &server_fd,
                net_send, &server_fd );

        if( ( ret = ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret );
            goto exit;
        }

#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
        if( ( ret = ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_set_hostname returned %d\n\n", ret );
            goto exit;
        }
#endif

        /*
         * 4. Handshake
         */
        while( ( ret = ssl_handshake( &ssl ) ) != 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                polarssl_printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
                ssl_free( &ssl );
                goto exit;
            }
        }

        polarssl_printf( " ok\n" );

        /*
         * 5. Print the certificate
         */
        polarssl_printf( "  . Peer certificate information    ...\n" );
        ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                             ssl.session->peer_cert );
        if( ret == -1 )
        {
            polarssl_printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
            ssl_free( &ssl );
            goto exit;
        }

        polarssl_printf( "%s\n", buf );

        ssl_close_notify( &ssl );
        ssl_free( &ssl );
    }
    else
        goto usage;

exit:

    if( server_fd )
        net_close( server_fd );
    x509_crt_free( &cacert );
    x509_crt_free( &clicert );
#if defined(POLARSSL_X509_CRL_PARSE_C)
    x509_crl_free( &cacrl );
#endif
    pk_free( &pkey );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    if( ret < 0 )
        ret = 1;

    return( ret );
}
Exemplo n.º 30
0
Arquivo: x509.c Projeto: ftes/opensgx
/*
 * Checkup routine
 */
int x509_self_test( int verbose )
{
#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
    int ret;
    int flags;
    x509_crt cacert;
    x509_crt clicert;

    if( verbose != 0 )
        polarssl_printf( "  X.509 certificate load: " );

    x509_crt_init( &clicert );

    ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
                          strlen( test_cli_crt ) );
    if( ret != 0 )
    {
        if( verbose != 0 )
            polarssl_printf( "failed\n" );

        return( ret );
    }

    x509_crt_init( &cacert );

    ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
                          strlen( test_ca_crt ) );
    if( ret != 0 )
    {
        if( verbose != 0 )
            polarssl_printf( "failed\n" );

        return( ret );
    }

    if( verbose != 0 )
        polarssl_printf( "passed\n  X.509 signature verify: ");

    ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
    if( ret != 0 )
    {
        if( verbose != 0 )
            polarssl_printf( "failed\n" );

        polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );

        return( ret );
    }

    if( verbose != 0 )
        polarssl_printf( "passed\n\n");

    x509_crt_free( &cacert  );
    x509_crt_free( &clicert );

    return( 0 );
#else
    ((void) verbose);
    return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
#endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
}