- Merged trunk into 1.1 branch

diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 195c2ce..bd676d2 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -1,4 +1,4 @@
-OPTION(USE_SHARED_POLARSSL_LIBRARY "Build PolarSSL as a shared library." OFF)
+option(USE_SHARED_POLARSSL_LIBRARY "Build PolarSSL as a shared library." OFF)
 
 set(src
      aes.c
@@ -46,11 +46,11 @@
 
 else(NOT USE_SHARED_POLARSSL_LIBRARY)
 
-ADD_LIBRARY(polarssl SHARED ${src})
-SET_TARGET_PROPERTIES(polarssl PROPERTIES VERSION 1.1.0 SOVERSION 1)
+add_library(polarssl SHARED ${src})
+set_target_properties(polarssl PROPERTIES VERSION 1.1.0 SOVERSION 1)
 
 endif(NOT USE_SHARED_POLARSSL_LIBRARY)
 
-INSTALL(TARGETS polarssl
+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/asn1parse.c b/library/asn1parse.c
index 09f67fa..2584774 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -242,7 +242,7 @@
                  sizeof( asn1_sequence ) );
 
             if( cur->next == NULL )
-                return( 1 );
+                return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
 
             cur = cur->next;
         }
diff --git a/library/bignum.c b/library/bignum.c
index 5920956..9dff991 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -89,12 +89,12 @@
     t_uint *p;
 
     if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
-        return( 1 );
+        return( POLARSSL_ERR_MPI_MALLOC_FAILED );
 
     if( X->n < nblimbs )
     {
         if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
-            return( 1 );
+            return( POLARSSL_ERR_MPI_MALLOC_FAILED );
 
         memset( p, 0, nblimbs * ciL );
 
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 6611c3d..5b610a2 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -38,11 +38,17 @@
 #include <stdio.h>
 #endif
 
-int ctr_drbg_init( ctr_drbg_context *ctx,
+/*
+ * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
+ * tests to succeed (which require known length fixed entropy)
+ */
+int ctr_drbg_init_entropy_len(
+                   ctr_drbg_context *ctx,
                    int (*f_entropy)(void *, unsigned char *, size_t),
                    void *p_entropy,
                    const unsigned char *custom,
-                   size_t len )
+                   size_t len,
+                   size_t entropy_len )
 {
     int ret;
     unsigned char key[CTR_DRBG_KEYSIZE];
@@ -53,7 +59,7 @@
     ctx->f_entropy = f_entropy;
     ctx->p_entropy = p_entropy;
 
-    ctx->entropy_len = CTR_DRBG_ENTROPY_LEN;
+    ctx->entropy_len = entropy_len;
     ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
 
     /*
@@ -67,6 +73,16 @@
     return( 0 );
 }
 
+int ctr_drbg_init( ctr_drbg_context *ctx,
+                   int (*f_entropy)(void *, unsigned char *, size_t),
+                   void *p_entropy,
+                   const unsigned char *custom,
+                   size_t len )
+{
+    return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
+                                       CTR_DRBG_ENTROPY_LEN ) );
+}
+
 void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
 {
     ctx->prediction_resistance = resistance;
@@ -228,7 +244,7 @@
     memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
 
     /*
-     * Gather POLARSSL_CTR_DRBG_ENTROPYLEN bytes of entropy to seed state
+     * Gather enropy_len bytes of entropy to seed state
      */
     if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
                              ctx->entropy_len ) )
@@ -341,7 +357,7 @@
     unsigned char buf[ CTR_DRBG_MAX_INPUT ];
 
     if( ( f = fopen( path, "wb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
 
     if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
         return( ret );
@@ -349,7 +365,7 @@
     if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
     {
         fclose( f );
-        return( 1 );
+        return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
     }
 
     fclose( f );
@@ -363,7 +379,7 @@
     unsigned char buf[ CTR_DRBG_MAX_INPUT ];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
 
     fseek( f, 0, SEEK_END );
     n = (size_t) ftell( f );
@@ -375,7 +391,7 @@
     if( fread( buf, 1, n, f ) != n )
     {
         fclose( f );
-        return( 1 );
+        return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
     }
 
     ctr_drbg_update( ctx, buf, n );
diff --git a/library/entropy.c b/library/entropy.c
index 0ece345..bc0e141 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -39,21 +39,26 @@
     sha4_starts( &ctx->accumulator, 0 );
 
 #if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
-    entropy_add_source( ctx, platform_entropy_poll, NULL );
+    entropy_add_source( ctx, platform_entropy_poll, NULL,
+                        ENTROPY_MIN_PLATFORM );
 #endif
 #if defined(POLARSSL_TIMING_C)
-    entropy_add_source( ctx, hardclock_poll, NULL );
+    entropy_add_source( ctx, hardclock_poll, NULL, ENTROPY_MIN_HARDCLOCK );
 #endif
 }
 
 int entropy_add_source( entropy_context *ctx,
-                        f_source_ptr f_source, void *p_source )
+                        f_source_ptr f_source, void *p_source,
+                        size_t threshold )
 {
-    if( ctx->source_count >= ENTROPY_MAX_SOURCES )
+    int index = ctx->source_count;
+
+    if( index >= ENTROPY_MAX_SOURCES )
         return( POLARSSL_ERR_ENTROPY_MAX_SOURCES );
 
-    ctx->f_source[ctx->source_count] = f_source;
-    ctx->p_source[ctx->source_count] = p_source;
+    ctx->source[index].f_source = f_source;
+    ctx->source[index].p_source = p_source;
+    ctx->source[index].threshold = threshold;
 
     ctx->source_count++;
 
@@ -85,8 +90,6 @@
     sha4_update( &ctx->accumulator, header, 2 );
     sha4_update( &ctx->accumulator, p, use_len );
     
-    ctx->size += use_len;
-
     return( 0 );
 }
 
@@ -111,7 +114,7 @@
     for( i = 0; i < ctx->source_count; i++ )
     {
         olen = 0;
-        if ( ( ret = ctx->f_source[i]( ctx->p_source[i],
+        if ( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
                         buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 )
         {
             return( ret );
@@ -121,7 +124,10 @@
          * Add if we actually gathered something
          */
         if( olen > 0 )
+        {
             entropy_update( ctx, (unsigned char) i, buf, olen );
+            ctx->source[i].size += olen;
+        }
     }
 
     return( 0 );
@@ -129,7 +135,7 @@
 
 int entropy_func( void *data, unsigned char *output, size_t len )
 {
-    int ret, count = 0;
+    int ret, count = 0, i, reached;
     entropy_context *ctx = (entropy_context *) data;
     unsigned char buf[ENTROPY_BLOCK_SIZE];
 
@@ -146,8 +152,14 @@
 
         if( ( ret = entropy_gather( ctx ) ) != 0 )
             return( ret );
+
+        reached = 0;
+
+        for( i = 0; i < ctx->source_count; i++ )
+            if( ctx->source[i].size >= ctx->source[i].threshold )
+                reached++;
     }
-    while( ctx->size < ENTROPY_MIN_POOL );
+    while( reached != ctx->source_count );
 
     memset( buf, 0, ENTROPY_BLOCK_SIZE );
 
@@ -159,11 +171,14 @@
     sha4( buf, ENTROPY_BLOCK_SIZE, buf, 0 );
 
     /*
-     * Reset accumulator
+     * Reset accumulator and counters and recycle existing entropy
      */
     memset( &ctx->accumulator, 0, sizeof( sha4_context ) );
     sha4_starts( &ctx->accumulator, 0 );
-    ctx->size = 0;
+    sha4_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE );
+
+    for( i = 0; i < ctx->source_count; i++ )
+        ctx->source[i].size = 0;
 
     memcpy( output, buf, len );
 
diff --git a/library/error.c b/library/error.c
index 33fad85..05e84e7 100644
--- a/library/error.c
+++ b/library/error.c
@@ -67,6 +67,18 @@
 #include "polarssl/md.h"
 #endif
 
+#if defined(POLARSSL_MD2_C)
+#include "polarssl/md2.h"
+#endif
+
+#if defined(POLARSSL_MD4_C)
+#include "polarssl/md4.h"
+#endif
+
+#if defined(POLARSSL_MD5_C)
+#include "polarssl/md5.h"
+#endif
+
 #if defined(POLARSSL_NET_C)
 #include "polarssl/net.h"
 #endif
@@ -83,6 +95,18 @@
 #include "polarssl/rsa.h"
 #endif
 
+#if defined(POLARSSL_SHA1_C)
+#include "polarssl/sha1.h"
+#endif
+
+#if defined(POLARSSL_SHA2_C)
+#include "polarssl/sha2.h"
+#endif
+
+#if defined(POLARSSL_SHA4_C)
+#include "polarssl/sha4.h"
+#endif
+
 #if defined(POLARSSL_SSL_TLS_C)
 #include "polarssl/ssl.h"
 #endif
@@ -258,6 +282,8 @@
             snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
         if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_FINISHED) )
             snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
+        if( use_ret == -(POLARSSL_ERR_SSL_MALLOC_FAILED) )
+            snprintf( buf, buflen, "SSL - Memory allocation failed" );
 #endif /* POLARSSL_SSL_TLS_C */
 
 #if defined(POLARSSL_X509_PARSE_C)
@@ -299,8 +325,12 @@
             snprintf( buf, buflen, "X509 - Invalid RSA key tag or value" );
         if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT) )
             snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
-        if( use_ret == -(POLARSSL_ERR_X509_VALUE_TO_LENGTH) )
-            snprintf( buf, buflen, "X509 - Not used" );
+        if( use_ret == -(POLARSSL_ERR_X509_INVALID_INPUT) )
+            snprintf( buf, buflen, "X509 - Input invalid" );
+        if( use_ret == -(POLARSSL_ERR_X509_MALLOC_FAILED) )
+            snprintf( buf, buflen, "X509 - Allocation of memory failed" );
+        if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) )
+            snprintf( buf, buflen, "X509 - Read/write of file failed" );
 #endif /* POLARSSL_X509_PARSE_C */
 
         if( strlen( buf ) == 0 )
@@ -348,6 +378,8 @@
         snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
     if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_DATA) )
         snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
+    if( use_ret == -(POLARSSL_ERR_ASN1_MALLOC_FAILED) )
+        snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
 #endif /* POLARSSL_ASN1_PARSE_C */
 
 #if defined(POLARSSL_BASE64_C)
@@ -365,13 +397,15 @@
     if( use_ret == -(POLARSSL_ERR_MPI_INVALID_CHARACTER) )
         snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
     if( use_ret == -(POLARSSL_ERR_MPI_BUFFER_TOO_SMALL) )
-        snprintf( buf, buflen, "BIGNUM - The output buffer is too small to write too" );
+        snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
     if( use_ret == -(POLARSSL_ERR_MPI_NEGATIVE_VALUE) )
         snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
     if( use_ret == -(POLARSSL_ERR_MPI_DIVISION_BY_ZERO) )
         snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
     if( use_ret == -(POLARSSL_ERR_MPI_NOT_ACCEPTABLE) )
         snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
+    if( use_ret == -(POLARSSL_ERR_MPI_MALLOC_FAILED) )
+        snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
 #endif /* POLARSSL_BIGNUM_C */
 
 #if defined(POLARSSL_CAMELLIA_C)
@@ -388,6 +422,8 @@
         snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
     if( use_ret == -(POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG) )
         snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
+    if( use_ret == -(POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
 #endif /* POLARSSL_CTR_DRBG_C */
 
 #if defined(POLARSSL_DES_C)
@@ -402,6 +438,21 @@
         snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
 #endif /* POLARSSL_ENTROPY_C */
 
+#if defined(POLARSSL_MD2_C)
+    if( use_ret == -(POLARSSL_ERR_MD2_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "MD2 - Read/write error in file" );
+#endif /* POLARSSL_MD2_C */
+
+#if defined(POLARSSL_MD4_C)
+    if( use_ret == -(POLARSSL_ERR_MD4_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "MD4 - Read/write error in file" );
+#endif /* POLARSSL_MD4_C */
+
+#if defined(POLARSSL_MD5_C)
+    if( use_ret == -(POLARSSL_ERR_MD5_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "MD5 - Read/write error in file" );
+#endif /* POLARSSL_MD5_C */
+
 #if defined(POLARSSL_NET_C)
     if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) )
         snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
@@ -432,6 +483,21 @@
         snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
 #endif /* POLARSSL_PADLOCK_C */
 
+#if defined(POLARSSL_SHA1_C)
+    if( use_ret == -(POLARSSL_ERR_SHA1_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "SHA1 - Read/write error in file" );
+#endif /* POLARSSL_SHA1_C */
+
+#if defined(POLARSSL_SHA2_C)
+    if( use_ret == -(POLARSSL_ERR_SHA2_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "SHA2 - Read/write error in file" );
+#endif /* POLARSSL_SHA2_C */
+
+#if defined(POLARSSL_SHA4_C)
+    if( use_ret == -(POLARSSL_ERR_SHA4_FILE_IO_ERROR) )
+        snprintf( buf, buflen, "SHA4 - Read/write error in file" );
+#endif /* POLARSSL_SHA4_C */
+
 #if defined(POLARSSL_XTEA_C)
     if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) )
         snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
diff --git a/library/md2.c b/library/md2.c
index ff1b5aa..954aa07 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -189,7 +189,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
 
     md2_starts( &ctx );
 
@@ -203,7 +203,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/md4.c b/library/md4.c
index a1c8244..ad52e5e 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -285,7 +285,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
 
     md4_starts( &ctx );
 
@@ -299,7 +299,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/md5.c b/library/md5.c
index 1c5b397..7a449b2 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -304,7 +304,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
 
     md5_starts( &ctx );
 
@@ -318,7 +318,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/sha1.c b/library/sha1.c
index 56028fe..72ca063 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -339,7 +339,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
 
     sha1_starts( &ctx );
 
@@ -353,7 +353,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/sha2.c b/library/sha2.c
index 9cc88e8..4b5e696 100644
--- a/library/sha2.c
+++ b/library/sha2.c
@@ -341,7 +341,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_SHA2_FILE_IO_ERROR );
 
     sha2_starts( &ctx, is224 );
 
@@ -355,7 +355,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_SHA2_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/sha4.c b/library/sha4.c
index ee6cf90..cf54d11 100644
--- a/library/sha4.c
+++ b/library/sha4.c
@@ -339,7 +339,7 @@
     unsigned char buf[1024];
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
 
     sha4_starts( &ctx, is384 );
 
@@ -353,7 +353,7 @@
     if( ferror( f ) != 0 )
     {
         fclose( f );
-        return( 2 );
+        return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
     }
 
     fclose( f );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a7900e4..08aaf80 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -395,7 +395,7 @@
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
     }
 
-    if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
+    if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 512 )
     {
         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 26e7dfa..545317a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1376,7 +1376,7 @@
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed",
                        sizeof( x509_cert ) ) );
-        return( 1 );
+        return( POLARSSL_ERR_SSL_MALLOC_FAILED );
     }
 
     memset( ssl->peer_cert, 0, sizeof( x509_cert ) );
@@ -1401,8 +1401,7 @@
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
         }
 
-        ret = x509parse_crt( ssl->peer_cert, ssl->in_msg + i, n,
-                             X509_NON_PERMISSIVE );
+        ret = x509parse_crt( ssl->peer_cert, ssl->in_msg + i, n );
         if( ret != 0 )
         {
             SSL_DEBUG_RET( 1, " x509parse_crt", ret );
@@ -1707,7 +1706,7 @@
     if( ssl->in_ctr == NULL )
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
-        return( 1 );
+        return( POLARSSL_ERR_SSL_MALLOC_FAILED );
     }
 
     ssl->out_ctr = (unsigned char *) malloc( len );
@@ -1718,7 +1717,7 @@
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
         free( ssl-> in_ctr );
-        return( 1 );
+        return( POLARSSL_ERR_SSL_MALLOC_FAILED );
     }
 
     memset( ssl-> in_ctr, 0, SSL_BUFFER_LEN );
diff --git a/library/x509parse.c b/library/x509parse.c
index d7da8c4..f561754 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -284,7 +284,7 @@
                     sizeof( x509_name ) );
 
             if( use->next == NULL )
-                return( 1 );
+                return( POLARSSL_ERR_X509_MALLOC_FAILED );
             
             memset( use->next, 0, sizeof( x509_name ) );
 
@@ -303,7 +303,7 @@
          sizeof( x509_name ) );
 
     if( cur->next == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
     return( x509_get_name( p, end2, cur->next ) );
 }
@@ -1018,12 +1018,12 @@
      * Check for valid input
      */
     if( crt == NULL || buf == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_INVALID_INPUT );
 
     p = (unsigned char *) malloc( len = buflen );
 
     if( p == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
     memcpy( p, buf, buflen );
 
@@ -1259,10 +1259,9 @@
 /*
  * Parse one or more PEM certificates from a buffer and add them to the chained list
  */
-int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen,
-                   int permissive )
+int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
 {
-    int ret, success = 0, first_error = 0;
+    int ret, success = 0, first_error = 0, total_failed = 0;
     x509_cert *crt, *prev = NULL;
     int buf_format = X509_FORMAT_DER;
 
@@ -1272,7 +1271,7 @@
      * Check for valid input
      */
     if( crt == NULL || buf == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_INVALID_INPUT );
 
     while( crt->version != 0 && crt->next != NULL )
     {
@@ -1288,7 +1287,7 @@
         crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
 
         if( crt->next == NULL )
-            return( 1 );
+            return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
         prev = crt;
         crt = crt->next;
@@ -1349,9 +1348,9 @@
             if( ret != 0 )
             {
                 /*
-                 * quit parsing on a memory error or if in non-permissive parsing mode
+                 * quit parsing on a memory error
                  */
-                if( ret == 1 || permissive != 1 )
+                if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
                 {
                     if( prev )
                         prev->next = NULL;
@@ -1364,6 +1363,8 @@
 
                 if( first_error == 0 )
                     first_error = ret;
+                
+                total_failed++;
 
                 memset( crt, 0, sizeof( x509_cert ) );
                 continue;
@@ -1377,7 +1378,7 @@
             crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
 
             if( crt->next == NULL )
-                return( 1 );
+                return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
             prev = crt;
             crt = crt->next;
@@ -1396,7 +1397,7 @@
     }
 
     if( success )
-        return( 0 );
+        return( total_failed );
     else if( first_error )
         return( first_error );
     else
@@ -1423,7 +1424,7 @@
      * Check for valid input
      */
     if( crl == NULL || buf == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_INVALID_INPUT );
 
     while( crl->version != 0 && crl->next != NULL )
         crl = crl->next;
@@ -1438,7 +1439,7 @@
         if( crl->next == NULL )
         {
             x509_crl_free( crl );
-            return( 1 );
+            return( POLARSSL_ERR_X509_MALLOC_FAILED );
         }
 
         crl = crl->next;
@@ -1481,7 +1482,7 @@
         p = (unsigned char *) malloc( len = buflen );
 
         if( p == NULL )
-            return( 1 );
+            return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
         memcpy( p, buf, buflen );
 
@@ -1491,7 +1492,7 @@
     p = (unsigned char *) malloc( len = buflen );
 
     if( p == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
     memcpy( p, buf, buflen );
 
@@ -1680,7 +1681,7 @@
         if( crl->next == NULL )
         {
             x509_crl_free( crl );
-            return( 1 );
+            return( POLARSSL_ERR_X509_MALLOC_FAILED );
         }
 
         crl = crl->next;
@@ -1701,20 +1702,20 @@
     FILE *f;
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
 
     fseek( f, 0, SEEK_END );
     *n = (size_t) ftell( f );
     fseek( f, 0, SEEK_SET );
 
     if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
-        return( 1 );
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
         free( *buf );
-        return( 1 );
+        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
     }
 
     fclose( f );
@@ -1727,16 +1728,16 @@
 /*
  * Load one or more certificates and add them to the chained list
  */
-int x509parse_crtfile( x509_cert *chain, const char *path, int permissive )
+int x509parse_crtfile( x509_cert *chain, const char *path )
 {
     int ret;
     size_t n;
     unsigned char *buf;
 
-    if ( load_file( path, &buf, &n ) )
-        return( 1 );
+    if ( (ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
 
-    ret = x509parse_crt( chain, buf, n, permissive );
+    ret = x509parse_crt( chain, buf, n );
 
     memset( buf, 0, n + 1 );
     free( buf );
@@ -1753,8 +1754,8 @@
     size_t n;
     unsigned char *buf;
 
-    if ( load_file( path, &buf, &n ) )
-        return( 1 );
+    if ( (ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
 
     ret = x509parse_crl( chain, buf, n );
 
@@ -1773,8 +1774,8 @@
     size_t n;
     unsigned char *buf;
 
-    if ( load_file( path, &buf, &n ) )
-        return( 1 );
+    if ( (ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
 
     if( pwd == NULL )
         ret = x509parse_key( rsa, buf, n, NULL, 0 );
@@ -1797,8 +1798,8 @@
     size_t n;
     unsigned char *buf;
 
-    if ( load_file( path, &buf, &n ) )
-        return( 1 );
+    if ( (ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
 
     ret = x509parse_public_key( rsa, buf, n );
 
@@ -2250,8 +2251,8 @@
     size_t n;
     unsigned char *buf;
 
-    if ( load_file( path, &buf, &n ) )
-        return( 1 );
+    if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
 
     ret = x509parse_dhm( dhm, buf, n );
 
@@ -3155,7 +3156,7 @@
     memset( &clicert, 0, sizeof( x509_cert ) );
 
     ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
-                         strlen( test_cli_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_cli_crt ) );
     if( ret != 0 )
     {
         if( verbose != 0 )
@@ -3167,7 +3168,7 @@
     memset( &cacert, 0, sizeof( x509_cert ) );
 
     ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
-                         strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_ca_crt ) );
     if( ret != 0 )
     {
         if( verbose != 0 )