Merge improvements to SSL test scripts
diff --git a/include/polarssl/dhm.h b/include/polarssl/dhm.h
index 628cd62..c6c2d8f 100644
--- a/include/polarssl/dhm.h
+++ b/include/polarssl/dhm.h
@@ -43,6 +43,8 @@
 #define POLARSSL_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read/write of file failed. */
 
 /**
+ * RFC 2409 defines a number of standardized Diffie-Hellman groups
+ * that can be used.
  * RFC 3526 defines a number of standardized Diffie-Hellman groups
  * for IKE.
  * RFC 5114 defines a number of standardized Diffie-Hellman groups
@@ -51,11 +53,22 @@
  * Some are included here for convenience.
  *
  * Included are:
+ *  RFC 2409 6.2.  1024-bit MODP Group (Second Oakley Group)
  *  RFC 3526 3.    2048-bit MODP Group
  *  RFC 3526 4.    3072-bit MODP Group
  *  RFC 5114 2.1.  1024-bit MODP Group with 160-bit Prime Order Subgroup
  *  RFC 5114 2.2.  2048-bit MODP Group with 224-bit Prime Order Subgroup
  */
+#define POLARSSL_DHM_RFC2409_MODP_1024_P               \
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
+    "FFFFFFFFFFFFFFFF"
+
+#define POLARSSL_DHM_RFC2409_MODP_1024_G          "02"
+
 #define POLARSSL_DHM_RFC3526_MODP_2048_P               \
     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 4cbd162..2e202de 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -1,5 +1,6 @@
 option(USE_STATIC_POLARSSL_LIBRARY "Build PolarSSL static library." ON)
 option(USE_SHARED_POLARSSL_LIBRARY "Build PolarSSL shared library." OFF)
+option(LINK_WITH_PTHREAD "Explicitly link PolarSSL library to pthread." OFF)
 
 set(src
      aes.c
@@ -102,6 +103,9 @@
 		target_link_libraries(${polarssl_static_target} ${ZLIB_LIBRARIES})
 	endif(ZLIB_FOUND)
 
+	if(LINK_WITH_PTHREAD)
+        target_link_libraries(${polarssl_static_target} pthread)
+	endif()
 
 	install(TARGETS ${polarssl_static_target}
 			DESTINATION ${LIB_INSTALL_DIR}
@@ -118,6 +122,10 @@
 		target_link_libraries(polarssl ${ZLIB_LIBRARIES})
 	endif(ZLIB_FOUND)
 
+	if(LINK_WITH_PTHREAD)
+        target_link_libraries(polarssl pthread)
+	endif()
+
 	install(TARGETS polarssl
 			DESTINATION ${LIB_INSTALL_DIR}
 			PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/library/aes.c b/library/aes.c
index ca5c906..c03cbbe 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -565,10 +565,6 @@
                 RK[15] = RK[7] ^ RK[14];
             }
             break;
-
-        default:
-
-            break;
     }
 
     return( 0 );
@@ -586,14 +582,6 @@
     uint32_t *SK;
     int ret;
 
-    switch( keysize )
-    {
-        case 128: ctx->nr = 10; break;
-        case 192: ctx->nr = 12; break;
-        case 256: ctx->nr = 14; break;
-        default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH );
-    }
-
 #if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16)
     if( aes_padlock_ace == -1 )
         aes_padlock_ace = padlock_supports( PADLOCK_ACE );
@@ -604,10 +592,12 @@
 #endif
     ctx->rk = RK = ctx->buf;
 
-    ret = aes_setkey_enc( &cty, key, keysize );
-    if( ret != 0 )
+    /* Also checks keysize */
+    if( ( ret = aes_setkey_enc( &cty, key, keysize ) ) != 0 )
         return( ret );
 
+    ctx->nr = cty.nr;
+
 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
     if( aesni_supports( POLARSSL_AESNI_AES ) )
     {
diff --git a/library/camellia.c b/library/camellia.c
index 524e6ff..306be61 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -435,20 +435,14 @@
     uint32_t *SK;
     int ret;
 
-    switch( keysize )
-    {
-        case 128: ctx->nr = 3; idx = 0; break;
-        case 192:
-        case 256: ctx->nr = 4; idx = 1; break;
-        default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH );
-    }
-
-    RK = ctx->rk;
-
-    ret = camellia_setkey_enc(&cty, key, keysize);
-    if( ret != 0 )
+    /* Also checks keysize */
+    if( ( ret = camellia_setkey_enc(&cty, key, keysize) ) )
         return( ret );
 
+    ctx->nr = cty.nr;
+    idx = ( ctx->nr == 4 );
+
+    RK = ctx->rk;
     SK = cty.rk + 24 * 2 + 8 * idx * 2;
 
     *RK++ = *SK++;
diff --git a/library/debug.c b/library/debug.c
index f2dd776..b747ddc 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -131,7 +131,7 @@
     if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL )
         idx = snprintf( str, maxlen, "%s(%04d): ", file, line );
 
-    snprintf( str + idx, maxlen - idx, "dumping '%s' (%d bytes)\n",
+    snprintf( str + idx, maxlen - idx, "dumping '%s' (%u bytes)\n",
               text, (unsigned int) len );
 
     str[maxlen] = '\0';
diff --git a/library/des.c b/library/des.c
index 79c81bc..2f06af3 100644
--- a/library/des.c
+++ b/library/des.c
@@ -837,15 +837,12 @@
     int i, j, u, v;
     des_context ctx;
     des3_context ctx3;
-    unsigned char key[24];
     unsigned char buf[8];
 #if defined(POLARSSL_CIPHER_MODE_CBC)
     unsigned char prv[8];
     unsigned char iv[8];
 #endif
 
-    memset( key, 0, 24 );
-
     /*
      * ECB mode
      */
diff --git a/library/gcm.c b/library/gcm.c
index a892076..62fe185 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -195,7 +195,6 @@
                       unsigned char output[16] )
 {
     int i = 0;
-    unsigned char z[16];
     unsigned char lo, hi, rem;
     uint64_t zh, zl;
 
@@ -213,8 +212,6 @@
     }
 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
 
-    memset( z, 0x00, 16 );
-
     lo = x[15] & 0xf;
     hi = x[15] >> 4;
 
diff --git a/library/net.c b/library/net.c
index be30fbd..0866149 100644
--- a/library/net.c
+++ b/library/net.c
@@ -146,7 +146,7 @@
 
     if( wsa_init_done == 0 )
     {
-        if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
+        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
             return( POLARSSL_ERR_NET_SOCKET_FAILED );
 
         wsa_init_done = 1;
diff --git a/library/pem.c b/library/pem.c
index 2775ef9..3dd3b79 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -370,11 +370,8 @@
 
 void pem_free( pem_context *ctx )
 {
-    if( ctx->buf )
-        polarssl_free( ctx->buf );
-
-    if( ctx->info )
-        polarssl_free( ctx->info );
+    polarssl_free( ctx->buf );
+    polarssl_free( ctx->info );
 
     memset( ctx, 0, sizeof( pem_context ) );
 }
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 9e49b9a..836b685 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -321,8 +321,7 @@
         ssl_session_free( &prv->session );
 
 #if defined(POLARSSL_X509_CRT_PARSE_C)
-        if( prv->peer_cert.p != NULL )
-            polarssl_free( prv->peer_cert.p );
+        polarssl_free( prv->peer_cert.p );
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
         polarssl_free( prv );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 5152895..53b3179 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -691,7 +691,7 @@
 static int ssl_parse_alpn_ext( ssl_context *ssl,
                                unsigned char *buf, size_t len )
 {
-    size_t list_len, cur_len;
+    size_t list_len, cur_len, ours_len;
     const unsigned char *theirs, *start, *end;
     const char **ours;
 
@@ -722,6 +722,7 @@
     end = buf + len;
     for( ours = ssl->alpn_list; *ours != NULL; ours++ )
     {
+        ours_len = strlen( *ours );
         for( theirs = start; theirs != end; theirs += cur_len )
         {
             /* If the list is well formed, we should get equality first */
@@ -734,7 +735,7 @@
             if( cur_len == 0 )
                 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 
-            if( cur_len == strlen( *ours ) &&
+            if( cur_len == ours_len &&
                 memcmp( theirs, *ours, cur_len ) == 0 )
             {
                 ssl->alpn_chosen = *ours;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8c29e21..2cd0cce 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -97,7 +97,7 @@
         x509_crt_init( dst->peer_cert );
 
         if( ( ret = x509_crt_parse( dst->peer_cert, src->peer_cert->raw.p,
-                                    src->peer_cert->raw.len ) != 0 ) )
+                                    src->peer_cert->raw.len ) ) != 0 )
         {
             polarssl_free( dst->peer_cert );
             dst->peer_cert = NULL;
@@ -1070,8 +1070,7 @@
 
         if( ssl->out_msglen != olen )
         {
-            SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
-                                ssl->out_msglen, olen ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
     }
@@ -1146,8 +1145,7 @@
 
         if( olen != enc_msglen )
         {
-            SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
-                                enc_msglen, olen ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
 
@@ -1225,8 +1223,7 @@
 
         if( enc_msglen != olen )
         {
-            SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
-                                enc_msglen, olen ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
 
@@ -1308,7 +1305,7 @@
 
         if( ssl->in_msglen != olen )
         {
-            SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
     }
@@ -1372,8 +1369,7 @@
 
         if( olen != dec_msglen )
         {
-            SSL_DEBUG_MSG( 1, ( "total decrypted length incorrect %d %d",
-                                dec_msglen, olen ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
     }
@@ -1448,7 +1444,7 @@
 
         if( dec_msglen != olen )
         {
-            SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
 
diff --git a/library/timing.c b/library/timing.c
index 4b29d7e..fe741b9 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -337,6 +337,25 @@
 #endif
 
 /*
+ * Busy-waits for the given number of milliseconds.
+ * Used for testing hardclock.
+ */
+static void busy_msleep( unsigned long msec )
+{
+    struct hr_time hires;
+    unsigned long i = 0; /* for busy-waiting */
+    volatile unsigned long j; /* to prevent optimisation */
+
+    (void) get_timer( &hires, 1 );
+
+    while( get_timer( &hires, 0 ) < msec )
+        i++;
+
+    j = i;
+    (void) j;
+}
+
+/*
  * Checkup routine
  *
  * Warning: this is work in progress, some tests may not be reliable enough
@@ -350,7 +369,7 @@
     struct hr_time hires;
 
     if( verbose != 0)
-        polarssl_printf( "  TIMING tests warning: will take some time!\n" );
+        polarssl_printf( "  TIMING tests note: will take some time!\n" );
 
     if( verbose != 0 )
         polarssl_printf( "  TIMING test #1 (m_sleep   / get_timer): " );
@@ -401,7 +420,7 @@
         polarssl_printf( "passed\n" );
 
     if( verbose != 0 )
-        polarssl_printf( "  TIMING test #3 (hardclock / m_sleep  ): " );
+        polarssl_printf( "  TIMING test #3 (hardclock / get_timer): " );
 
     /*
      * Allow one failure for possible counter wrapping.
@@ -420,15 +439,17 @@
     }
 
     /* Get a reference ratio cycles/ms */
+    millisecs = 1;
     cycles = hardclock();
-    m_sleep( 1 );
+    busy_msleep( millisecs );
     cycles = hardclock() - cycles;
-    ratio = cycles / 1;
+    ratio = cycles / millisecs;
 
+    /* Check that the ratio is mostly constant */
     for( millisecs = 2; millisecs <= 4; millisecs++ )
     {
         cycles = hardclock();
-        m_sleep( millisecs );
+        busy_msleep( millisecs );
         cycles = hardclock() - cycles;
 
         /* Allow variation up to 20% */
@@ -443,9 +464,6 @@
     if( verbose != 0 )
         polarssl_printf( "passed\n" );
 
-    if( verbose != 0 )
-        polarssl_printf( "\n" );
-
 #if defined(POLARSSL_NET_C)
     if( verbose != 0 )
         polarssl_printf( "  TIMING test #4 (net_usleep/ get_timer): " );
@@ -471,6 +489,9 @@
         polarssl_printf( "passed\n" );
 #endif /* POLARSSL_NET_C */
 
+    if( verbose != 0 )
+        polarssl_printf( "\n" );
+
     return( 0 );
 }
 
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 7946068..54e76db 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1550,12 +1550,12 @@
 static int x509_wildcard_verify( const char *cn, x509_buf *name )
 {
     size_t i;
-    size_t cn_idx = 0;
+    size_t cn_idx = 0, cn_len = strlen( cn );
 
     if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
         return( 0 );
 
-    for( i = 0; i < strlen( cn ); ++i )
+    for( i = 0; i < cn_len; ++i )
     {
         if( cn[i] == '.' )
         {
@@ -1567,7 +1567,7 @@
     if( cn_idx == 0 )
         return( 0 );
 
-    if( strlen( cn ) - cn_idx == name->len - 1 &&
+    if( cn_len - cn_idx == name->len - 1 &&
         x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
     {
         return( 1 );
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 07e2b12..63e4463 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -205,10 +205,7 @@
 #endif
 #endif
 
-/*
- * Not reliable enough yet
- */
-#if 0 && defined(POLARSSL_TIMING_C)
+#if defined(POLARSSL_TIMING_C)
     if( ( ret = timing_self_test( v ) ) != 0 )
         return( ret );
 #endif
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 72618e6..e558da2 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -65,6 +65,7 @@
 #define DFL_MODE                MODE_NONE
 #define DFL_FILENAME            "cert.crt"
 #define DFL_CA_FILE             ""
+#define DFL_CRL_FILE            ""
 #define DFL_CA_PATH             ""
 #define DFL_SERVER_NAME         "localhost"
 #define DFL_SERVER_PORT         4433
@@ -79,6 +80,7 @@
     int mode;                   /* the mode to run the application in   */
     const char *filename;       /* filename of the certificate file     */
     const char *ca_file;        /* the file with the CA certificate(s)  */
+    const char *crl_file;       /* the file with the CRL to use         */
     const char *ca_path;        /* the path with the CA certificate(s) reside */
     const char *server_name;    /* hostname of the server (client only) */
     int server_port;            /* port on which the ssl service runs   */
@@ -134,6 +136,8 @@
 #define USAGE_IO \
     "    ca_file=%%s          The single file containing the top-level CA(s) you fully trust\n" \
     "                        default: \"\" (none)\n" \
+    "    crl_file=%%s         The single CRL file you want to use\n" \
+    "                        default: \"\" (none)\n" \
     "    ca_path=%%s          The path containing the top-level CA(s) you fully trust\n" \
     "                        default: \"\" (none) (overrides ca_file)\n"
 
@@ -158,6 +162,7 @@
     ssl_context ssl;
     x509_crt cacert;
     x509_crt clicert;
+    x509_crl cacrl;
     pk_context pkey;
     int i, j;
     int flags, verify = 0;
@@ -170,6 +175,7 @@
     server_fd = 0;
     x509_crt_init( &cacert );
     x509_crt_init( &clicert );
+    x509_crl_init( &cacrl );
     pk_init( &pkey );
 
     if( argc == 0 )
@@ -182,6 +188,7 @@
     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;
@@ -214,6 +221,8 @@
             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 )
@@ -265,6 +274,18 @@
 
     printf( " ok (%d skipped)\n", ret );
 
+    if( strlen( opt.crl_file ) )
+    {
+        ret = x509_crl_parse_file( &cacrl, opt.crl_file );
+        verify = 1;
+    }
+
+    if( ret < 0 )
+    {
+        printf( " failed\n  !  x509_crl_parse returned -0x%x\n\n", -ret );
+        goto exit;
+    }
+
     if( opt.mode == MODE_FILE )
     {
         x509_crt crt;
@@ -322,7 +343,7 @@
         {
             printf( "  . Verifying X.509 certificate..." );
 
-            if( ( ret = x509_crt_verify( &crt, &cacert, NULL, NULL, &flags,
+            if( ( ret = x509_crt_verify( &crt, &cacert, &cacrl, NULL, &flags,
                                          my_verify, NULL ) ) != 0 )
             {
                 printf( " failed\n" );
@@ -452,6 +473,7 @@
         net_close( server_fd );
     x509_crt_free( &cacert );
     x509_crt_free( &clicert );
+    x509_crl_free( &cacrl );
     pk_free( &pkey );
     entropy_free( &entropy );
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d75752c..cbccebd 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -97,7 +97,7 @@
     file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data_files" target)
 
     if (NOT EXISTS ${link})
-        if (UNIX)
+        if (CMAKE_HOST_UNIX)
             set(command ln -s ${target} ${link})
         else()
             set(command cmd.exe /c mklink ${link} ${target})