- Changed the behaviour of x509parse_parse_crt for permissive parsing. Now returns the number of 'failed certificates' instead of having a switch to enable it.
 - As a consequence all error code that were positive were changed. A lot of MALLOC_FAILED and FILE_IO_ERROR error codes added for different modules.
 - Programs and tests were adapted accordingly

diff --git a/ChangeLog b/ChangeLog
index 82871cd..426613e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -38,7 +38,9 @@
    * Moved all examples programs to use the new entropy and CTR_DRBG
    * Added permissive certificate parsing to x509parse_crt() and
      x509parse_crtfile(). With permissive parsing the parsing does not stop on
-	 encountering a parse-error
+	 encountering a parse-error. Beware that the meaning of return values has
+	 changed!
+   * All error codes are now negative. Even on mermory failures and IO errors.
 
 Bugfix
    * Fixed faulty HMAC-MD2 implementation. Found by dibac. (Closes
diff --git a/include/polarssl/asn1.h b/include/polarssl/asn1.h
index fc86fc8..82145c3 100644
--- a/include/polarssl/asn1.h
+++ b/include/polarssl/asn1.h
@@ -52,6 +52,7 @@
 #define POLARSSL_ERR_ASN1_INVALID_LENGTH                   -0x0018  /**< Error when trying to determine the length or invalid length. */
 #define POLARSSL_ERR_ASN1_LENGTH_MISMATCH                  -0x001A  /**< Actual length differs from expected length. */
 #define POLARSSL_ERR_ASN1_INVALID_DATA                     -0x001C  /**< Data is invalid. (not used) */
+#define POLARSSL_ERR_ASN1_MALLOC_FAILED                    -0x001E  /**< Memory allocation failed */
 /* \} name */
 
 /**
diff --git a/include/polarssl/base64.h b/include/polarssl/base64.h
index 9071155..883215d 100644
--- a/include/polarssl/base64.h
+++ b/include/polarssl/base64.h
@@ -29,8 +29,8 @@
 
 #include <string.h>
 
-#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL               -0x0010  /**< Output buffer too small. */
-#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              -0x0012  /**< Invalid character in input. */
+#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A  /**< Output buffer too small. */
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              -0x002C  /**< Invalid character in input. */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index b4496b8..f830c08 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -33,10 +33,11 @@
 #define POLARSSL_ERR_MPI_FILE_IO_ERROR                     -0x0002  /**< An error occurred while reading from or writing to a file. */
 #define POLARSSL_ERR_MPI_BAD_INPUT_DATA                    -0x0004  /**< Bad input parameters to function. */
 #define POLARSSL_ERR_MPI_INVALID_CHARACTER                 -0x0006  /**< There is an invalid character in the digit string. */
-#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008  /**< The buffer is too small to write too. */
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008  /**< The buffer is too small to write to. */
 #define POLARSSL_ERR_MPI_NEGATIVE_VALUE                    -0x000A  /**< The input arguments are negative or result in illegal output. */
 #define POLARSSL_ERR_MPI_DIVISION_BY_ZERO                  -0x000C  /**< The input argument for division is zero, which is not allowed. */
 #define POLARSSL_ERR_MPI_NOT_ACCEPTABLE                    -0x000E  /**< The input arguments are not acceptable. */
+#define POLARSSL_ERR_MPI_MALLOC_FAILED                     -0x0010  /**< Memory allocation failed. */
 
 #define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
 
@@ -145,7 +146,7 @@
  * \param nblimbs  The target number of limbs
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_grow( mpi *X, size_t nblimbs );
 
@@ -156,7 +157,7 @@
  * \param Y        Source MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_copy( mpi *X, const mpi *Y );
 
@@ -175,7 +176,7 @@
  * \param z        Value to use
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_lset( mpi *X, t_sint z );
 
@@ -200,7 +201,7 @@
  * \param val      The value to set the bit to (0 or 1)
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
  */
 int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
@@ -289,7 +290,7 @@
  * \param buflen   Input buffer size
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
 
@@ -312,7 +313,7 @@
  * \param count    Amount to shift
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_shift_l( mpi *X, size_t count );
 
@@ -323,7 +324,7 @@
  * \param count    Amount to shift
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_shift_r( mpi *X, size_t count );
 
@@ -371,7 +372,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
 
@@ -395,7 +396,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
 
@@ -407,7 +408,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
 
@@ -419,7 +420,7 @@
  * \param b        The integer value to add
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_add_int( mpi *X, const mpi *A, t_sint b );
 
@@ -431,7 +432,7 @@
  * \param b        The integer value to subtract
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
 
@@ -443,7 +444,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
 
@@ -457,7 +458,7 @@
  * \param b        The integer value to multiply with
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
 
@@ -470,7 +471,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
  *
  * \note           Either Q or R can be NULL.
@@ -486,7 +487,7 @@
  * \param b        Integer to divide by
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
  *
  * \note           Either Q or R can be NULL.
@@ -501,7 +502,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
  *                 POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
  */
@@ -515,7 +516,7 @@
  * \param b        Integer to divide by
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
  *                 POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
  */
@@ -531,7 +532,7 @@
  * \param _RR      Speed-up MPI used for recalculations
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
  *
  * \note           _RR is used to avoid re-computing R*R mod N across
@@ -549,7 +550,7 @@
  * \param p_rng    RNG parameter
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_fill_random( mpi *X, size_t size,
                      int (*f_rng)(void *, unsigned char *, size_t),
@@ -563,7 +564,7 @@
  * \param B        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  */
 int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
 
@@ -575,7 +576,7 @@
  * \param N        Right-hand MPI
  *
  * \return         0 if successful,
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
                    POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
  */
@@ -589,7 +590,7 @@
  * \param p_rng    RNG parameter
  *
  * \return         0 if successful (probably prime),
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
  */
 int mpi_is_prime( mpi *X,
@@ -606,7 +607,7 @@
  * \param p_rng    RNG parameter
  *
  * \return         0 if successful (probably prime),
- *                 1 if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
  *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
  */
 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
diff --git a/include/polarssl/ctr_drbg.h b/include/polarssl/ctr_drbg.h
index 5b20d49..83861a9 100644
--- a/include/polarssl/ctr_drbg.h
+++ b/include/polarssl/ctr_drbg.h
@@ -34,6 +34,7 @@
 #define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
 #define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< Too many random requested in single call. */
 #define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< Input too large (Entropy + additional). */
+#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read/write error in file. */
 
 #define CTR_DRBG_BLOCKSIZE          16      /**< Block size used by the cipher                  */
 #define CTR_DRBG_KEYSIZE            32      /**< Key size used by the cipher                    */
diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h
index 0c1f13f..aeec8b2 100644
--- a/include/polarssl/entropy.h
+++ b/include/polarssl/entropy.h
@@ -31,8 +31,8 @@
 
 #include "sha4.h"
 
-#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED                 -0x003A  /**< Critical entropy source failure. */
-#define POLARSSL_ERR_ENTROPY_MAX_SOURCES                   -0x003C  /**< No more sources can be added. */
+#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED                 -0x003C  /**< Critical entropy source failure. */
+#define POLARSSL_ERR_ENTROPY_MAX_SOURCES                   -0x003E  /**< No more sources can be added. */
 
 #define ENTROPY_MAX_SOURCES     20      /**< Maximum number of sources supported */
 #define ENTROPY_MAX_GATHER      128     /**< Maximum amount requested from entropy sources */
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 69e7b04..f167a7b 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -48,27 +48,33 @@
  * Low-level module errors (0x007E-0x0002)
  *
  * Module   Nr  Codes assigned 
- * MPI       7  0x0002-0x000E
- * BASE64    2  0x0010-0x0012
- * ASN1      5  0x0014-0x001C
+ * MPI       7  0x0002-0x0010
+ * ASN1      6  0x0014-0x001E
  * AES       2  0x0020-0x0022
  * CAMELLIA  2  0x0024-0x0026
  * XTEA      1  0x0028-0x0028
+ * BASE64    2  0x002A-0x002C
  * PADLOCK   1  0x0030-0x0030
  * DES       1  0x0032-0x0032
  * NET      11  0x0040-0x0054
- * CTR_DBRG  3  0x0034-0x0038
- * ENTROPY   2  0x003A-0x003C
+ * CTR_DBRG  3  0x0034-0x003A
+ * ENTROPY   2  0x003C-0x003E
+ * MD2       1  0x0070-0x0070
+ * MD4       1  0x0072-0x0072
+ * MD5       1  0x0074-0x0074
+ * SHA1      1  0x0076-0x0076
+ * SHA2      1  0x0078-0x0078
+ * SHA4      1  0x007A-0x007A
  *
  * High-level module nr (3 bits - 0x1...-0x8...)
  * Name     ID  Nr of Errors
  * PEM      1   8
- * X509     2   20
+ * X509     2   21
  * DHM      3   6
  * RSA      4   9
  * MD       5   1
  * CIPER    6   1
- * SSL      7   27
+ * SSL      7   30
  *
  * Module dependent error code (5 bits 0x.08.-0x.F8.)
  */
diff --git a/include/polarssl/md2.h b/include/polarssl/md2.h
index 2726ca3..1f60470 100644
--- a/include/polarssl/md2.h
+++ b/include/polarssl/md2.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_MD2_FILE_IO_ERROR                 -0x0070  /**< Read/write error in file. */
+
 /**
  * \brief          MD2 context structure
  */
@@ -87,8 +89,7 @@
  * \param path     input file name
  * \param output   MD2 checksum result
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_MD2_FILE_IO_ERROR
  */
 int md2_file( const char *path, unsigned char output[16] );
 
diff --git a/include/polarssl/md4.h b/include/polarssl/md4.h
index 5a796ae..2bd35ea 100644
--- a/include/polarssl/md4.h
+++ b/include/polarssl/md4.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_MD4_FILE_IO_ERROR                 -0x0072  /**< Read/write error in file. */
+
 /**
  * \brief          MD4 context structure
  */
@@ -86,8 +88,7 @@
  * \param path     input file name
  * \param output   MD4 checksum result
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_MD4_FILE_IO_ERROR
  */
 int md4_file( const char *path, unsigned char output[16] );
 
diff --git a/include/polarssl/md5.h b/include/polarssl/md5.h
index cf0459d..936e9c9 100644
--- a/include/polarssl/md5.h
+++ b/include/polarssl/md5.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_MD5_FILE_IO_ERROR                 -0x0074  /**< Read/write error in file. */
+
 /**
  * \brief          MD5 context structure
  */
@@ -86,8 +88,7 @@
  * \param path     input file name
  * \param output   MD5 checksum result
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_MD5_FILE_IO_ERROR
  */
 int md5_file( const char *path, unsigned char output[16] );
 
diff --git a/include/polarssl/sha1.h b/include/polarssl/sha1.h
index 76b369a..0d5e67e 100644
--- a/include/polarssl/sha1.h
+++ b/include/polarssl/sha1.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_SHA1_FILE_IO_ERROR                -0x0076  /**< Read/write error in file. */
+
 /**
  * \brief          SHA-1 context structure
  */
@@ -86,8 +88,7 @@
  * \param path     input file name
  * \param output   SHA-1 checksum result
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_SHA1_FILE_IO_ERROR
  */
 int sha1_file( const char *path, unsigned char output[20] );
 
diff --git a/include/polarssl/sha2.h b/include/polarssl/sha2.h
index c963ca1..811b0fd 100644
--- a/include/polarssl/sha2.h
+++ b/include/polarssl/sha2.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_SHA2_FILE_IO_ERROR                -0x0078  /**< Read/write error in file. */
+
 /**
  * \brief          SHA-256 context structure
  */
@@ -91,8 +93,7 @@
  * \param output   SHA-224/256 checksum result
  * \param is224    0 = use SHA256, 1 = use SHA224
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_SHA2_FILE_IO_ERROR
  */
 int sha2_file( const char *path, unsigned char output[32], int is224 );
 
diff --git a/include/polarssl/sha4.h b/include/polarssl/sha4.h
index 06a85f1..dafebec 100644
--- a/include/polarssl/sha4.h
+++ b/include/polarssl/sha4.h
@@ -29,6 +29,8 @@
 
 #include <string.h>
 
+#define POLARSSL_ERR_SHA4_FILE_IO_ERROR                -0x007A  /**< Read/write error in file. */
+
 #if defined(_MSC_VER) || defined(__WATCOMC__)
   #define UL64(x) x##ui64
   #define long64 __int64
@@ -99,8 +101,7 @@
  * \param output   SHA-384/512 checksum result
  * \param is384    0 = use SHA512, 1 = use SHA384
  *
- * \return         0 if successful, 1 if fopen failed,
- *                 or 2 if fread failed
+ * \return         0 if successful, or POLARSSL_ERR_SHA4_FILE_IO_ERROR
  */
 int sha4_file( const char *path, unsigned char output[64], int is384 );
 
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 02d75c7..c897a1e 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -81,6 +81,7 @@
 #define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY         -0x7D80  /**< Processing of the CertificateVerify handshake message failed. */
 #define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC         -0x7E00  /**< Processing of the ChangeCipherSpec handshake message failed. */
 #define POLARSSL_ERR_SSL_BAD_HS_FINISHED                   -0x7E80  /**< Processing of the Finished handshake message failed. */
+#define POLARSSL_ERR_SSL_MALLOC_FAILED                     -0x7F00  /**< Memory allocation failed */
 
 /*
  * Various constants
@@ -373,7 +374,8 @@
  *
  * \param ssl      SSL context
  *
- * \return         0 if successful, or 1 if memory allocation failed
+ * \return         0 if successful, or POLARSSL_ERR_SSL_MALLOC_FAILED if
+ *                 memory allocation failed
  */
 int ssl_init( ssl_context *ssl );
 
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 11f1a31..cd0dc84 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -59,7 +59,9 @@
 #define POLARSSL_ERR_X509_KEY_INVALID_VERSION              -0x2880  /**< Unsupported RSA key version */
 #define POLARSSL_ERR_X509_KEY_INVALID_FORMAT               -0x2900  /**< Invalid RSA key tag or value. */
 #define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT              -0x2980  /**< Format not recognized as DER or PEM. */
-#define POLARSSL_ERR_X509_VALUE_TO_LENGTH                  -0x2A00  /**< Not used. */
+#define POLARSSL_ERR_X509_INVALID_INPUT                    -0x2A00  /**< Input invalid. */
+#define POLARSSL_ERR_X509_MALLOC_FAILED                    -0x2A80  /**< Allocation of memory failed. */
+#define POLARSSL_ERR_X509_FILE_IO_ERROR                    -0x2B00  /**< Read/write of file failed. */
 /* \} name */
 
 
@@ -227,10 +229,6 @@
 #define X509_FORMAT_DER                 1
 #define X509_FORMAT_PEM                 2
 
-#define X509_NON_PERMISSIVE             0
-#define X509_PERMISSIVE                 1
-
-
 /** 
  * \addtogroup x509_module
  * \{ */
@@ -420,34 +418,35 @@
 /** \ingroup x509_module */
 /**
  * \brief          Parse one or more certificates and add them
- *                 to the chained list. With permissive parsing enabled
- *                 all certificates that cannot be parsed are ignored.
- *                 If none complete correctly, the first error is returned.
+ *                 to the chained list. Parses permissively. If some
+ *                 certificates can be parsed, the result is the number
+ *                 of failed certificates it encountered. If none complete
+ *                 correctly, the first error is returned.
  *
  * \param chain    points to the start of the chain
  * \param buf      buffer holding the certificate data
  * \param buflen   size of the buffer
- * \param permissive    X509_PERMISSIVE or X509_NON_PERMISSIVE
  *
- * \return         0 if successful, or a specific X509 or PEM error code
+ * \return         0 if all certificates parsed successfully, a positive number
+ *                 if partly successful or a specific X509 or PEM error code
  */
-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 );
 
 /** \ingroup x509_module */
 /**
  * \brief          Load one or more certificates and add them
- *                 to the chained list. With permissive parsing enabled
- *                 all certificates that cannot be parsed are ignored.
- *                 If none complete correctly, the first error is returned.
+ *                 to the chained list. Parses permissively. If some
+ *                 certificates can be parsed, the result is the number
+ *                 of failed certificates it encountered. If none complete
+ *                 correctly, the first error is returned.
  *
  * \param chain    points to the start of the chain
  * \param path     filename to read the certificates from
- * \param permissive    X509_PERMISSIVE or X509_NON_PERMISSIVE
  *
- * \return         0 if successful, or a specific X509 or PEM error code
+ * \return         0 if all certificates parsed successfully, a positive number
+ *                 if partly successful or a specific X509 or PEM error code
  */
-int x509parse_crtfile( x509_cert *chain, const char *path, int permissive );
+int x509parse_crtfile( x509_cert *chain, const char *path );
 
 /** \ingroup x509_module */
 /**
@@ -552,8 +551,6 @@
 
 /** \} name Functions to read in DHM parameters, a certificate, CRL or private RSA key */
 
-
-
 /**
  * \brief          Store the certificate DN in printable form into buf;
  *                 no more than size characters will be written.
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 478304e..5b610a2 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -244,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 ) )
@@ -357,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 );
@@ -365,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 );
@@ -379,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 );
@@ -391,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/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_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 )
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 39d69ac..f5bbe85 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -241,12 +241,12 @@
 
 #if defined(POLARSSL_FS_IO)
     if( strlen( opt.ca_file ) )
-        ret = x509parse_crtfile( &cacert, opt.ca_file, X509_NON_PERMISSIVE );
+        ret = x509parse_crtfile( &cacert, opt.ca_file );
     else 
 #endif
 #if defined(POLARSSL_CERTS_C)
         ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
-                strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                strlen( test_ca_crt ) );
 #else
     {
         ret = 1;
@@ -271,12 +271,12 @@
 
 #if defined(POLARSSL_FS_IO)
     if( strlen( opt.crt_file ) )
-        ret = x509parse_crtfile( &clicert, opt.crt_file, X509_NON_PERMISSIVE );
+        ret = x509parse_crtfile( &clicert, opt.crt_file );
     else 
 #endif
 #if defined(POLARSSL_CERTS_C)
         ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
-                strlen( test_cli_crt ), X509_NON_PERMISSIVE );
+                strlen( test_cli_crt ) );
 #else
     {
         ret = 1;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index d24ae00..881a68e 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -250,7 +250,7 @@
      * server and CA certificates, as well as x509parse_keyfile().
      */
     ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
-                         strlen( test_srv_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_srv_crt ) );
     if( ret != 0 )
     {
         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
@@ -258,7 +258,7 @@
     }
 
     ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
-                         strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_ca_crt ) );
     if( ret != 0 )
     {
         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index eb223b0..2f442c9 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -493,12 +493,12 @@
 
 #if defined(POLARSSL_FS_IO)
     if( strlen( opt.ca_file ) )
-        ret = x509parse_crtfile( &cacert, opt.ca_file, X509_NON_PERMISSIVE );
+        ret = x509parse_crtfile( &cacert, opt.ca_file );
     else
 #endif
 #if defined(POLARSSL_CERTS_C)
         ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
-                strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                strlen( test_ca_crt ) );
 #else
     {
         ret = 1;
@@ -523,15 +523,15 @@
 
 #if defined(POLARSSL_FS_IO)
     if( strlen( opt.crt_file ) )
-        ret = x509parse_crtfile( &clicert, opt.crt_file, X509_NON_PERMISSIVE );
+        ret = x509parse_crtfile( &clicert, opt.crt_file );
     else 
 #endif
 #if defined(POLARSSL_CERTS_C)
         ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
-                strlen( test_cli_crt ), X509_NON_PERMISSIVE );
+                strlen( test_cli_crt ) );
 #else
     {
-        ret = 1;
+        ret = -1;
         printf("POLARSSL_CERTS_C not defined.");
     }
 #endif
@@ -551,7 +551,7 @@
                 strlen( test_cli_key ), NULL, 0 );
 #else
     {
-        ret = 1;
+        ret = -1;
         printf("POLARSSL_CERTS_C not defined.");
     }
 #endif
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index f43e8b4..5ee2f63 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -220,7 +220,7 @@
      * server and CA certificates, as well as x509parse_keyfile().
      */
     ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
-                         strlen( test_srv_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_srv_crt ) );
     if( ret != 0 )
     {
         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
@@ -228,7 +228,7 @@
     }
 
     ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
-                         strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                         strlen( test_ca_crt ) );
     if( ret != 0 )
     {
         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
diff --git a/programs/test/ssl_cert_test.c b/programs/test/ssl_cert_test.c
index 2e4e6c5..57ea32c 100644
--- a/programs/test/ssl_cert_test.c
+++ b/programs/test/ssl_cert_test.c
@@ -100,7 +100,7 @@
      * Alternatively, you may load the CA certificates from a .pem or
      * .crt file by calling x509parse_crtfile( &cacert, "myca.crt" ).
      */
-    ret = x509parse_crtfile( &cacert, "ssl/test-ca/test-ca.crt", X509_NON_PERMISSIVE );
+    ret = x509parse_crtfile( &cacert, "ssl/test-ca/test-ca.crt" );
     if( ret != 0 )
     {
         printf( " failed\n  !  x509parse_crtfile returned %d\n\n", ret );
@@ -148,7 +148,7 @@
         printf( "  . Loading the client certificate %s...", name );
         fflush( stdout );
 
-        ret = x509parse_crtfile( &clicert, name, X509_NON_PERMISSIVE );
+        ret = x509parse_crtfile( &clicert, name );
         if( ret != 0 )
         {
             printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
diff --git a/programs/test/ssl_test.c b/programs/test/ssl_test.c
index 3337540..59fab01 100644
--- a/programs/test/ssl_test.c
+++ b/programs/test/ssl_test.c
@@ -214,7 +214,7 @@
         goto exit;
 #else
         ret =  x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
-                              strlen( test_srv_crt ), X509_NON_PERMISSIVE );
+                              strlen( test_srv_crt ) );
         if( ret != 0 )
         {
             printf( "  !  x509parse_crt returned %d\n\n", ret );
@@ -222,7 +222,7 @@
         }
 
         ret =  x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
-                              strlen( test_ca_crt ), X509_NON_PERMISSIVE );
+                              strlen( test_ca_crt ) );
         if( ret != 0 )
         {
             printf( "  !  x509parse_crt returned %d\n\n", ret );
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index a041a47..08d1b9a 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -200,17 +200,25 @@
         printf( "\n  . Loading the certificate(s) ..." );
         fflush( stdout );
 
-        ret = x509parse_crtfile( &crt, opt.filename, opt.permissive );
+        ret = x509parse_crtfile( &crt, opt.filename );
 
-        if( ret != 0 )
+        if( ret < 0 )
         {
             printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
             x509_free( &crt );
             goto exit;
         }
 
+        if( opt.permissive == 0 && ret > 0 )
+        {
+            printf( " failed\n  !  x509parse_crt failed to parse %d certificates\n\n", ret );
+            x509_free( &crt );
+            goto exit;
+        }
+
         printf( " ok\n" );
 
+    
         /*
          * 1.2 Print the certificate(s)
          */
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index e07200f..ef5e45f 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -9,7 +9,8 @@
 my $error_format_file = $data_dir.'/error.fmt';
 
 my @low_level_modules = ( "AES", "ASN1", "CAMELLIA", "BIGNUM", "BASE64", "XTEA",
-                          "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY" );
+                          "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY",
+                          "MD2", "MD4", "MD5", "SHA1", "SHA2", "SHA4" );
 my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "MD", "CIPHER", "SSL" );
 
 my $line_separator = $/;
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 7349517..155bfc5 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -2,8 +2,9 @@
 #include <polarssl/ctr_drbg.h>
 
 int test_offset;
-int entropy_func( void *p, unsigned char *buf, size_t len )
+int entropy_func( void *data, unsigned char *buf, size_t len )
 {
+    unsigned char *p = (unsigned char *) data;
     memcpy( buf, p + test_offset, len );
     test_offset += 32;
     return( 0 );
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index 950c7ea..02381ca 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -35,7 +35,7 @@
 
     ssl_set_dbg(&ssl, string_debug, &buffer);
 
-    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file}, X509_NON_PERMISSIVE ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file} ) == 0 );
     debug_print_crt( &ssl, 0, {file}, {line}, {prefix}, &crt);
 
     TEST_ASSERT( strcmp( buffer.buf, {result_str} ) == 0 );
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index deac249..18e1c41 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -38,7 +38,7 @@
     memset( &crt, 0, sizeof( x509_cert ) );
     memset( buf, 0, 2000 );
 
-    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file}, X509_NON_PERMISSIVE ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file} ) == 0 );
     res = x509parse_cert_info( buf, 2000, "", &crt );
 
     TEST_ASSERT( res != -1 );
@@ -81,8 +81,8 @@
     memset( &ca, 0, sizeof( x509_cert ) );
     memset( &crl, 0, sizeof( x509_crl ) );
 
-    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file}, X509_NON_PERMISSIVE ) == 0 );
-    TEST_ASSERT( x509parse_crtfile( &ca, {ca_file}, X509_NON_PERMISSIVE ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file} ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &ca, {ca_file} ) == 0 );
     TEST_ASSERT( x509parse_crlfile( &crl, {crl_file} ) == 0 );
 
     res = x509parse_verify( &crt, &ca, &crl, {cn_name}, &flags, {verify_callback}, NULL );
@@ -102,7 +102,7 @@
     memset( &crt, 0, sizeof( x509_cert ) );
     memset( buf, 0, 2000 );
 
-    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file}, X509_NON_PERMISSIVE ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file} ) == 0 );
     res =  x509parse_dn_gets( buf, 2000, &crt.{entity} );
 
     TEST_ASSERT( res != -1 );
@@ -119,7 +119,7 @@
 
     memset( &crt, 0, sizeof( x509_cert ) );
 
-    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file}, X509_NON_PERMISSIVE ) == 0 );
+    TEST_ASSERT( x509parse_crtfile( &crt, {crt_file} ) == 0 );
     TEST_ASSERT( x509parse_time_expired( &crt.{entity} ) == {result} );
 }
 END_CASE
@@ -176,7 +176,7 @@
 
     data_len = unhexify( buf, {crt_data} );
 
-    TEST_ASSERT( x509parse_crt( &crt, buf, data_len, X509_NON_PERMISSIVE ) == ( {result} ) );
+    TEST_ASSERT( x509parse_crt( &crt, buf, data_len ) == ( {result} ) );
     if( ( {result} ) == 0 )
     {
         res = x509parse_cert_info( (char *) output, 2000, "", &crt );