Merge more test improvements and tests

Conflicts:
	tests/suites/test_suite_cipher.blowfish.data
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af268e7..86439ad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,9 +85,6 @@
     COMMAND tests/scripts/test-ref-configs.pl
     )
 
-  # add programs/test/selftest even though the selftest functions are
-  # called from the testsuites since it runs them in verbose mode,
-  # avoiding spurious "uncovered" printf lines
   ADD_CUSTOM_TARGET(covtest
     COMMAND make test
     COMMAND programs/test/selftest
@@ -97,10 +94,13 @@
 
   ADD_CUSTOM_TARGET(lcov
     COMMAND rm -rf Coverage
-    COMMAND lcov --capture --directory library/CMakeFiles/polarssl.dir -o polarssl.info
+    COMMAND lcov --capture --initial --directory library/CMakeFiles/polarssl.dir -o files.info
+    COMMAND lcov --capture --directory library/CMakeFiles/polarssl.dir -o tests.info
+    COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
+    COMMAND lcov --remove all.info -o final.info '*.h'
     COMMAND gendesc tests/Descriptions.txt -o descriptions
-    COMMAND genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage polarssl.info
-    COMMAND rm -f polarssl.info descriptions
+    COMMAND genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
+    COMMAND rm -f files.info tests.info all.info final.info descriptions
     )
 
   ADD_CUSTOM_TARGET(memcheck
diff --git a/Makefile b/Makefile
index ec09f9c..0807e8d 100644
--- a/Makefile
+++ b/Makefile
@@ -60,19 +60,19 @@
 # CFLAGS='--coverage' make OFLAGS='-g3 -O0'
 covtest:
 	make check
-	# add programs/test/selftest even though the selftest functions are
-	# called from the testsuites since it runs them in verbose mode,
-	# avoiding spurious "uncovered" printf lines
 	programs/test/selftest
 	( cd tests && ./compat.sh )
 	( cd tests && ./ssl-opt.sh )
 
 lcov:
 	rm -rf Coverage
-	lcov --capture --directory library -o polarssl.info
+	lcov --capture --initial --directory library -o files.info
+	lcov --capture --directory library -o tests.info
+	lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
+	lcov --remove all.info -o final.info '*.h'
 	gendesc tests/Descriptions.txt -o descriptions
-	genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage polarssl.info
-	rm -f polarssl.info descriptions
+	genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
+	rm -f files.info tests.info all.info final.info descriptions
 
 apidoc:
 	mkdir -p apidoc
diff --git a/include/polarssl/x509_csr.h b/include/polarssl/x509_csr.h
index 4328598..bbe6bec 100644
--- a/include/polarssl/x509_csr.h
+++ b/include/polarssl/x509_csr.h
@@ -85,7 +85,19 @@
 
 #if defined(POLARSSL_X509_CSR_PARSE_C)
 /**
- * \brief          Load a Certificate Signing Request (CSR)
+ * \brief          Load a Certificate Signing Request (CSR) in DER format
+ *
+ * \param csr      CSR context to fill
+ * \param buf      buffer holding the CRL data
+ * \param buflen   size of the buffer
+ *
+ * \return         0 if successful, or a specific X509 error code
+ */
+int x509_csr_parse_der( x509_csr *csr,
+                        const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief          Load a Certificate Signing Request (CSR), DER or PEM format
  *
  * \param csr      CSR context to fill
  * \param buf      buffer holding the CRL data
@@ -116,8 +128,8 @@
  * \param prefix   A line prefix
  * \param csr      The X509 CSR to represent
  *
- * \return         The amount of data written to the buffer, or -1 in
- *                 case of an error.
+ * \return         The length of the string written (exluding the terminating
+ *                 null byte), or a negative value in case of an error.
  */
 int x509_csr_info( char *buf, size_t size, const char *prefix,
                    const x509_csr *csr );
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index f4d39fa..070963a 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -865,36 +865,6 @@
 #endif /* POLARSSL_CIPHER_MODE_CBC */
 }
 
-static int des_crypt_cfb128_wrap( void *ctx, operation_t operation,
-        size_t length, size_t *iv_off, unsigned char *iv,
-        const unsigned char *input, unsigned char *output )
-{
-    ((void) ctx);
-    ((void) operation);
-    ((void) length);
-    ((void) iv_off);
-    ((void) iv);
-    ((void) input);
-    ((void) output);
-
-    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-
-static int des_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
-        unsigned char *nonce_counter, unsigned char *stream_block,
-        const unsigned char *input, unsigned char *output )
-{
-    ((void) ctx);
-    ((void) length);
-    ((void) nc_off);
-    ((void) nonce_counter);
-    ((void) stream_block);
-    ((void) input);
-    ((void) output);
-
-    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-
 static int des_setkey_dec_wrap( void *ctx, const unsigned char *key,
                                 unsigned int key_length )
 {
@@ -969,8 +939,8 @@
     POLARSSL_CIPHER_ID_DES,
     des_crypt_ecb_wrap,
     des_crypt_cbc_wrap,
-    des_crypt_cfb128_wrap,
-    des_crypt_ctr_wrap,
+    NULL,
+    NULL,
     NULL,
     des_setkey_enc_wrap,
     des_setkey_dec_wrap,
@@ -1006,8 +976,8 @@
     POLARSSL_CIPHER_ID_DES,
     des3_crypt_ecb_wrap,
     des3_crypt_cbc_wrap,
-    des_crypt_cfb128_wrap,
-    des_crypt_ctr_wrap,
+    NULL,
+    NULL,
     NULL,
     des3_set2key_enc_wrap,
     des3_set2key_dec_wrap,
@@ -1043,8 +1013,8 @@
     POLARSSL_CIPHER_ID_DES,
     des3_crypt_ecb_wrap,
     des3_crypt_cbc_wrap,
-    des_crypt_cfb128_wrap,
-    des_crypt_ctr_wrap,
+    NULL,
+    NULL,
     NULL,
     des3_set3key_enc_wrap,
     des3_set3key_dec_wrap,
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 8f6a814..3f94d50 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -52,13 +52,13 @@
 #define polarssl_printf printf
 #endif
 
-static int pkcs5_parse_pbkdf2_params( asn1_buf *params,
+static int pkcs5_parse_pbkdf2_params( const asn1_buf *params,
                                       asn1_buf *salt, int *iterations,
                                       int *keylen, md_type_t *md_type )
 {
     int ret;
     asn1_buf prf_alg_oid;
-    unsigned char **p = &params->p;
+    unsigned char *p = params->p;
     const unsigned char *end = params->p + params->len;
 
     if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
@@ -73,28 +73,28 @@
      *  }
      *
      */
-    if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
+    if( ( ret = asn1_get_tag( &p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
         return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
 
-    salt->p = *p;
-    *p += salt->len;
+    salt->p = p;
+    p += salt->len;
 
-    if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 )
+    if( ( ret = asn1_get_int( &p, end, iterations ) ) != 0 )
         return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
 
-    if( *p == end )
+    if( p == end )
         return( 0 );
 
-    if( ( ret = asn1_get_int( p, end, keylen ) ) != 0 )
+    if( ( ret = asn1_get_int( &p, end, keylen ) ) != 0 )
     {
         if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
             return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
     }
 
-    if( *p == end )
+    if( p == end )
         return( 0 );
 
-    if( ( ret = asn1_get_alg_null( p, end, &prf_alg_oid ) ) != 0 )
+    if( ( ret = asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
         return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
 
     if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) )
@@ -102,7 +102,7 @@
 
     *md_type = POLARSSL_MD_SHA1;
 
-    if( *p != end )
+    if( p != end )
         return( POLARSSL_ERR_PKCS5_INVALID_FORMAT +
                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
 
@@ -175,6 +175,10 @@
     if( cipher_info == NULL )
         return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
 
+    /*
+     * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
+     * since it is optional and we don't know if it was set or not
+     */
     keylen = cipher_info->key_length / 8;
 
     if( enc_scheme_params.tag != ASN1_OCTET_STRING ||
@@ -200,19 +204,8 @@
     if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 )
         goto exit;
 
-    if( ( ret = cipher_set_iv( &cipher_ctx, iv, enc_scheme_params.len ) ) != 0 )
-        goto exit;
-
-    if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 )
-        goto exit;
-
-    if( ( ret = cipher_update( &cipher_ctx, data, datalen,
-                                output, &olen ) ) != 0 )
-    {
-        goto exit;
-    }
-
-    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
+    if( ( ret = cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
+                              data, datalen, output, &olen ) ) != 0 )
         ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH;
 
 exit:
@@ -295,6 +288,16 @@
 
 #if defined(POLARSSL_SELF_TEST)
 
+#if !defined(POLARSSL_SHA1_C)
+int pkcs5_self_test( int verbose )
+{
+    if( verbose != 0 )
+        polarssl_printf( "  PBKDF2 (SHA1): skipped\n\n" );
+
+    return( 0 );
+}
+#else
+
 #include <stdio.h>
 
 #define MAX_TESTS   6
@@ -398,6 +401,7 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SHA1_C */
 
 #endif /* POLARSSL_SELF_TEST */
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index dfa7e48..7a5f462 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -149,7 +149,8 @@
 
         x509_crt_init( session->peer_cert );
 
-        if( ( ret = x509_crt_parse( session->peer_cert, p, cert_len ) ) != 0 )
+        if( ( ret = x509_crt_parse_der( session->peer_cert,
+                                        p, cert_len ) ) != 0 )
         {
             x509_crt_free( session->peer_cert );
             polarssl_free( session->peer_cert );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1c5249c..ce6730d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -101,8 +101,8 @@
 
         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 )
+        if( ( ret = x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p,
+                                        src->peer_cert->raw.len ) ) != 0 )
         {
             polarssl_free( dst->peer_cert );
             dst->peer_cert = NULL;
diff --git a/library/x509.c b/library/x509.c
index 4c54b5b..17c7a7d 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1,5 +1,5 @@
 /*
- *  X.509 certificate and private key decoding
+ *  X.509 common functions for parsing and verification
  *
  *  Copyright (C) 2006-2014, Brainspark B.V.
  *
@@ -25,10 +25,9 @@
 /*
  *  The ITU-T X.509 standard defines a certificate format for PKI.
  *
- *  http://www.ietf.org/rfc/rfc3279.txt
- *  http://www.ietf.org/rfc/rfc3280.txt
- *
- *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  *
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
diff --git a/library/x509_create.c b/library/x509_create.c
index 96b153b..1019313 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -40,6 +40,59 @@
 #define strncasecmp _strnicmp
 #endif
 
+typedef struct {
+    const char *name;
+    size_t name_len;
+    const char*oid;
+} x509_attr_descriptor_t;
+
+#define ADD_STRLEN( s )     s, sizeof( s ) - 1
+
+static const x509_attr_descriptor_t x509_attrs[] =
+{
+    { ADD_STRLEN( "CN" ),                       OID_AT_CN },
+    { ADD_STRLEN( "commonName" ),               OID_AT_CN },
+    { ADD_STRLEN( "C" ),                        OID_AT_COUNTRY },
+    { ADD_STRLEN( "countryName" ),              OID_AT_COUNTRY },
+    { ADD_STRLEN( "O" ),                        OID_AT_ORGANIZATION },
+    { ADD_STRLEN( "organizationName" ),         OID_AT_ORGANIZATION },
+    { ADD_STRLEN( "L" ),                        OID_AT_LOCALITY },
+    { ADD_STRLEN( "locality" ),                 OID_AT_LOCALITY },
+    { ADD_STRLEN( "R" ),                        OID_PKCS9_EMAIL },
+    { ADD_STRLEN( "OU" ),                       OID_AT_ORG_UNIT },
+    { ADD_STRLEN( "organizationalUnitName" ),   OID_AT_ORG_UNIT },
+    { ADD_STRLEN( "ST" ),                       OID_AT_STATE },
+    { ADD_STRLEN( "stateOrProvinceName" ),      OID_AT_STATE },
+    { ADD_STRLEN( "emailAddress" ),             OID_PKCS9_EMAIL },
+    { ADD_STRLEN( "serialNumber" ),             OID_AT_SERIAL_NUMBER },
+    { ADD_STRLEN( "postalAddress" ),            OID_AT_POSTAL_ADDRESS },
+    { ADD_STRLEN( "postalCode" ),               OID_AT_POSTAL_CODE },
+    { ADD_STRLEN( "dnQualifier" ),              OID_AT_DN_QUALIFIER },
+    { ADD_STRLEN( "title" ),                    OID_AT_TITLE },
+    { ADD_STRLEN( "surName" ),                  OID_AT_SUR_NAME },
+    { ADD_STRLEN( "SN" ),                       OID_AT_SUR_NAME },
+    { ADD_STRLEN( "givenName" ),                OID_AT_GIVEN_NAME },
+    { ADD_STRLEN( "GN" ),                       OID_AT_GIVEN_NAME },
+    { ADD_STRLEN( "initials" ),                 OID_AT_INITIALS },
+    { ADD_STRLEN( "pseudonym" ),                OID_AT_PSEUDONYM },
+    { ADD_STRLEN( "generationQualifier" ),      OID_AT_GENERATION_QUALIFIER },
+    { ADD_STRLEN( "domainComponent" ),          OID_DOMAIN_COMPONENT },
+    { ADD_STRLEN( "DC" ),                       OID_DOMAIN_COMPONENT },
+    { NULL, 0, NULL }
+};
+
+static const char *x509_at_oid_from_name( const char *name, size_t name_len )
+{
+    const x509_attr_descriptor_t *cur;
+
+    for( cur = x509_attrs; cur->name != NULL; cur++ )
+        if( cur->name_len == name_len &&
+            strncasecmp( cur->name, name, name_len ) == 0 )
+            break;
+
+    return( cur->oid );
+}
+
 int x509_string_to_names( asn1_named_data **head, const char *name )
 {
     int ret = 0;
@@ -55,68 +108,7 @@
     {
         if( in_tag && *c == '=' )
         {
-            if( c - s == 2 && strncasecmp( s, "CN", 2 ) == 0 )
-                oid = OID_AT_CN;
-            else if( c - s == 10 && strncasecmp( s, "commonName", 10 ) == 0 )
-                oid = OID_AT_CN;
-            else if( c - s == 1 && strncasecmp( s, "C", 1 ) == 0 )
-                oid = OID_AT_COUNTRY;
-            else if( c - s == 11 && strncasecmp( s, "countryName", 11 ) == 0 )
-                oid = OID_AT_COUNTRY;
-            else if( c - s == 1 && strncasecmp( s, "O", 1 ) == 0 )
-                oid = OID_AT_ORGANIZATION;
-            else if( c - s == 16 &&
-                     strncasecmp( s, "organizationName", 16 ) == 0 )
-                oid = OID_AT_ORGANIZATION;
-            else if( c - s == 1 && strncasecmp( s, "L", 1 ) == 0 )
-                oid = OID_AT_LOCALITY;
-            else if( c - s == 8 && strncasecmp( s, "locality", 8 ) == 0 )
-                oid = OID_AT_LOCALITY;
-            else if( c - s == 1 && strncasecmp( s, "R", 1 ) == 0 )
-                oid = OID_PKCS9_EMAIL;
-            else if( c - s == 2 && strncasecmp( s, "OU", 2 ) == 0 )
-                oid = OID_AT_ORG_UNIT;
-            else if( c - s == 22 &&
-                     strncasecmp( s, "organizationalUnitName", 22 ) == 0 )
-                oid = OID_AT_ORG_UNIT;
-            else if( c - s == 2 && strncasecmp( s, "ST", 2 ) == 0 )
-                oid = OID_AT_STATE;
-            else if( c - s == 19 &&
-                     strncasecmp( s, "stateOrProvinceName", 19 ) == 0 )
-                oid = OID_AT_STATE;
-            else if( c - s == 12 && strncasecmp( s, "emailAddress", 12 ) == 0 )
-                oid = OID_PKCS9_EMAIL;
-            else if( c - s == 12 && strncasecmp( s, "serialNumber", 12 ) == 0 )
-                oid = OID_AT_SERIAL_NUMBER;
-            else if( c - s == 13 && strncasecmp( s, "postalAddress", 13 ) == 0 )
-                oid = OID_AT_POSTAL_ADDRESS;
-            else if( c - s == 10 && strncasecmp( s, "postalCode", 10 ) == 0 )
-                oid = OID_AT_POSTAL_CODE;
-            else if( c - s == 11 && strncasecmp( s, "dnQualifier", 11 ) == 0 )
-                oid = OID_AT_DN_QUALIFIER;
-            else if( c - s == 5 && strncasecmp( s, "title", 5 ) == 0 )
-                oid = OID_AT_TITLE;
-            else if( c - s == 7 && strncasecmp( s, "surName", 7 ) == 0 )
-                oid = OID_AT_SUR_NAME;
-            else if( c - s == 2 && strncasecmp( s, "SN", 2 ) == 0 )
-                oid = OID_AT_SUR_NAME;
-            else if( c - s == 9 && strncasecmp( s, "givenName", 9 ) == 0 )
-                oid = OID_AT_GIVEN_NAME;
-            else if( c - s == 2 && strncasecmp( s, "GN", 2 ) == 0 )
-                oid = OID_AT_GIVEN_NAME;
-            else if( c - s == 8 && strncasecmp( s, "initials", 8 ) == 0 )
-                oid = OID_AT_INITIALS;
-            else if( c - s == 9 && strncasecmp( s, "pseudonym", 9 ) == 0 )
-                oid = OID_AT_PSEUDONYM;
-            else if( c - s == 19 &&
-                     strncasecmp( s, "generationQualifier", 19 ) == 0 )
-                oid = OID_AT_GENERATION_QUALIFIER;
-            else if( c - s == 15 &&
-                     strncasecmp( s, "domainComponent", 15 ) == 0 )
-                oid = OID_DOMAIN_COMPONENT;
-            else if( c - s == 2 && strncasecmp( s, "DC", 2 ) == 0 )
-                oid = OID_DOMAIN_COMPONENT;
-            else
+            if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL )
             {
                 ret = POLARSSL_ERR_X509_UNKNOWN_OID;
                 goto exit;
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 7f8600d..7dd53c2 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -1,5 +1,5 @@
 /*
- *  X.509 certificate and private key decoding
+ *  X.509 Certidicate Revocation List (CRL) parsing
  *
  *  Copyright (C) 2006-2014, Brainspark B.V.
  *
@@ -25,10 +25,9 @@
 /*
  *  The ITU-T X.509 standard defines a certificate format for PKI.
  *
- *  http://www.ietf.org/rfc/rfc3279.txt
- *  http://www.ietf.org/rfc/rfc3280.txt
- *
- *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  *
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 50f92e6..c5f7f70 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1,5 +1,5 @@
 /*
- *  X.509 certificate and private key decoding
+ *  X.509 certificate parsing and verification
  *
  *  Copyright (C) 2006-2014, Brainspark B.V.
  *
@@ -25,10 +25,9 @@
 /*
  *  The ITU-T X.509 standard defines a certificate format for PKI.
  *
- *  http://www.ietf.org/rfc/rfc3279.txt
- *  http://www.ietf.org/rfc/rfc3280.txt
- *
- *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  *
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
diff --git a/library/x509_csr.c b/library/x509_csr.c
index f6d268b..0b4f771 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -25,10 +25,9 @@
 /*
  *  The ITU-T X.509 standard defines a certificate format for PKI.
  *
- *  http://www.ietf.org/rfc/rfc3279.txt
- *  http://www.ietf.org/rfc/rfc3280.txt
- *
- *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  *
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
@@ -91,18 +90,15 @@
 }
 
 /*
- * Parse a CSR
+ * Parse a CSR in DER format
  */
-int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
+int x509_csr_parse_der( x509_csr *csr,
+                        const unsigned char *buf, size_t buflen )
 {
     int ret;
     size_t len;
     unsigned char *p, *end;
     x509_buf sig_params;
-#if defined(POLARSSL_PEM_PARSE_C)
-    size_t use_len;
-    pem_context pem;
-#endif
 
     memset( &sig_params, 0, sizeof( x509_buf ) );
 
@@ -114,41 +110,15 @@
 
     x509_csr_init( csr );
 
-#if defined(POLARSSL_PEM_PARSE_C)
-    pem_init( &pem );
-    ret = pem_read_buffer( &pem,
-                           "-----BEGIN CERTIFICATE REQUEST-----",
-                           "-----END CERTIFICATE REQUEST-----",
-                           buf, NULL, 0, &use_len );
+    /*
+     * first copy the raw DER data
+     */
+    p = (unsigned char *) polarssl_malloc( len = buflen );
 
-    if( ret == 0 )
-    {
-        /*
-         * Was PEM encoded, steal PEM buffer
-         */
-        p = pem.buf;
-        pem.buf = NULL;
-        len = pem.buflen;
-        pem_free( &pem );
-    }
-    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
-    {
-        pem_free( &pem );
-        return( ret );
-    }
-    else
-#endif /* POLARSSL_PEM_PARSE_C */
-    {
-        /*
-         * nope, copy the raw DER data
-         */
-        p = (unsigned char *) polarssl_malloc( len = buflen );
+    if( p == NULL )
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
-        if( p == NULL )
-            return( POLARSSL_ERR_X509_MALLOC_FAILED );
-
-        memcpy( p, buf, buflen );
-    }
+    memcpy( p, buf, buflen );
 
     csr->raw.p = p;
     csr->raw.len = len;
@@ -285,6 +255,51 @@
     return( 0 );
 }
 
+/*
+ * Parse a CSR, allowing for PEM or raw DER encoding
+ */
+int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
+{
+    int ret;
+#if defined(POLARSSL_PEM_PARSE_C)
+    size_t use_len;
+    pem_context pem;
+#endif
+
+    /*
+     * Check for valid input
+     */
+    if( csr == NULL || buf == NULL )
+        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+
+#if defined(POLARSSL_PEM_PARSE_C)
+    pem_init( &pem );
+    ret = pem_read_buffer( &pem,
+                           "-----BEGIN CERTIFICATE REQUEST-----",
+                           "-----END CERTIFICATE REQUEST-----",
+                           buf, NULL, 0, &use_len );
+
+    if( ret == 0 )
+    {
+        /*
+         * Was PEM encoded, parse the result
+         */
+        if( ( ret = x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 )
+            return( ret );
+
+        pem_free( &pem );
+        return( 0 );
+    }
+    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+    {
+        pem_free( &pem );
+        return( ret );
+    }
+    else
+#endif /* POLARSSL_PEM_PARSE_C */
+    return( x509_csr_parse_der( csr, buf, buflen ) );
+}
+
 #if defined(POLARSSL_FS_IO)
 /*
  * Load a CSR into the structure
diff --git a/tests/compat.sh b/tests/compat.sh
index 06243bd..dc03ebd 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -965,7 +965,7 @@
 
 # Pick a "unique" port in the range 10000-19999.
 PORT="0000$$"
-PORT="1$(echo $PORT | tail -c 4)"
+PORT="1$(echo $PORT | tail -c 5)"
 
 # Also pick a unique name for intermediate files
 SRV_OUT="srv_out.$$"
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ddb7a0a..f43f1eb 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -316,7 +316,7 @@
 
 # Pick a "unique" port in the range 10000-19999.
 PORT="0000$$"
-PORT="1$(echo $PORT | tail -c 4)"
+PORT="1$(echo $PORT | tail -c 5)"
 
 # fix commands to use this port
 P_SRV="$P_SRV server_port=$PORT"
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 2be5dcc..d656519 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -102,11 +102,32 @@
 }
 
 /**
+ * Allocate and zeroize a buffer.
+ *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
+ * For convenience, dies if allocation fails.
+ */
+static unsigned char *zero_alloc( size_t len )
+{
+    void *p;
+    size_t actual_len = len != 0 ? len : 1;
+
+    assert( ( p = polarssl_malloc( actual_len ) ) != NULL );
+
+    memset( p, 0x00, actual_len );
+
+    return( p );
+}
+
+/**
  * Allocate and fill a buffer from hex data.
  *
  * The buffer is sized exactly as needed. This allows to detect buffer
  * overruns (including overreads) when running the test suite under valgrind.
  *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
  * For convenience, dies if allocation fails.
  */
 static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
@@ -115,6 +136,9 @@
 
     *olen = strlen(ibuf) / 2;
 
+    if( *olen == 0 )
+        return( zero_alloc( *olen ) );
+
     assert( ( obuf = polarssl_malloc( *olen ) ) != NULL );
 
     (void) unhexify( obuf, ibuf );
diff --git a/tests/suites/test_suite_cipher.blowfish.data b/tests/suites/test_suite_cipher.blowfish.data
index bd0f890..57cb049 100644
--- a/tests/suites/test_suite_cipher.blowfish.data
+++ b/tests/suites/test_suite_cipher.blowfish.data
@@ -601,4 +601,3 @@
 BLOWFISH ECB Decrypt test vector (SSLeay) #3, 192-bit key
 depends_on:POLARSSL_BLOWFISH_C
 test_vec_ecb:POLARSSL_CIPHER_BLOWFISH_ECB:POLARSSL_DECRYPT:"3849674c2602319e3849674c2602319e3849674c2602319e":"a25e7856cf2651eb":"51454b582ddf440a":0
-
diff --git a/tests/suites/test_suite_cipher.des.data b/tests/suites/test_suite_cipher.des.data
index bdc0e12..9a923bf 100644
--- a/tests/suites/test_suite_cipher.des.data
+++ b/tests/suites/test_suite_cipher.des.data
@@ -549,3 +549,43 @@
 DES3 Encrypt and decrypt 32 bytes in multiple parts 1
 depends_on:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_CIPHER_PADDING_PKCS7
 enc_dec_buf_multipart:POLARSSL_CIPHER_DES_EDE3_CBC:192:16:16:
+
+DES ECB Encrypt test vector (OpenSSL) #1
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_ENCRYPT:"0000000000000000":"0000000000000000":"8CA64DE9C1B123A7":0
+
+DES ECB Encrypt test vector (OpenSSL) #2
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_ENCRYPT:"FFFFFFFFFFFFFFFF":"FFFFFFFFFFFFFFFF":"7359B2163E4EDC58":0
+
+DES ECB Encrypt test vector (OpenSSL) #3
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_ENCRYPT:"FEDCBA9876543210":"0123456789ABCDEF":"ED39D950FA74BCC4":0
+
+DES ECB Decrypt test vector (OpenSSL) #1
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_DECRYPT:"0000000000000000":"8CA64DE9C1B123A7":"0000000000000000":0
+
+DES ECB Decrypt test vector (OpenSSL) #2
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_DECRYPT:"FFFFFFFFFFFFFFFF":"7359B2163E4EDC58":"FFFFFFFFFFFFFFFF":0
+
+DES ECB Decrypt test vector (OpenSSL) #3
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_ECB:POLARSSL_DECRYPT:"43297FAD38E373FE":"EA676B2CB7DB2B7A":"762514B829BF486A":0
+
+DES3-EDE ECB Encrypt test vector (OpenSSL) #1
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_EDE_ECB:POLARSSL_ENCRYPT:"0000000000000000FFFFFFFFFFFFFFFF":"0000000000000000":"9295B59BB384736E":0
+
+DES3-EDE ECB Encrypt test vector (OpenSSL) #2
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_EDE_ECB:POLARSSL_ENCRYPT:"FFFFFFFFFFFFFFFF3000000000000000":"FFFFFFFFFFFFFFFF":"199E9D6DF39AA816":0
+
+DES3-EDE ECB Decrypt test vector (OpenSSL) #1
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_EDE_ECB:POLARSSL_DECRYPT:"0000000000000000FFFFFFFFFFFFFFFF":"9295B59BB384736E":"0000000000000000":0
+
+DES3-EDE ECB Decrypt test vector (OpenSSL) #2
+depends_on:POLARSSL_DES_C
+test_vec_ecb:POLARSSL_CIPHER_DES_EDE_ECB:POLARSSL_DECRYPT:"FFFFFFFFFFFFFFFF3000000000000000":"199E9D6DF39AA816":"FFFFFFFFFFFFFFFF":0
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 03be2b8..09ae2e0 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -22,6 +22,76 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void cipher_null_args( )
+{
+    cipher_context_t ctx;
+    const cipher_info_t *info = cipher_info_from_type( *( cipher_list() ) );
+    unsigned char buf[1] = { 0 };
+    size_t olen;
+
+    memset( &ctx, 0, sizeof( cipher_context_t ) );
+
+    TEST_ASSERT( cipher_get_block_size( NULL ) == 0 );
+    TEST_ASSERT( cipher_get_block_size( &ctx ) == 0 );
+
+    TEST_ASSERT( cipher_get_cipher_mode( NULL ) == POLARSSL_MODE_NONE );
+    TEST_ASSERT( cipher_get_cipher_mode( &ctx ) == POLARSSL_MODE_NONE );
+
+    TEST_ASSERT( cipher_get_iv_size( NULL ) == 0 );
+    TEST_ASSERT( cipher_get_iv_size( &ctx ) == 0 );
+
+    TEST_ASSERT( cipher_info_from_string( NULL ) == NULL );
+
+    TEST_ASSERT( cipher_init_ctx( &ctx, NULL )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_init_ctx( NULL, info )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    TEST_ASSERT( cipher_setkey( NULL, buf, 0, POLARSSL_ENCRYPT )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_setkey( &ctx, buf, 0, POLARSSL_ENCRYPT )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    TEST_ASSERT( cipher_set_iv( NULL, buf, 0 )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_set_iv( &ctx, buf, 0 )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    TEST_ASSERT( cipher_reset( NULL ) == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_reset( &ctx ) == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( cipher_update_ad( NULL, buf, 0 )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_update_ad( &ctx, buf, 0 )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+#endif
+
+    TEST_ASSERT( cipher_update( NULL, buf, 0, buf, &olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_update( &ctx, buf, 0, buf, &olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    TEST_ASSERT( cipher_finish( NULL, buf, &olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_finish( &ctx, buf, &olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( cipher_write_tag( NULL, buf, olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_write_tag( &ctx, buf, olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    TEST_ASSERT( cipher_check_tag( NULL, buf, olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+    TEST_ASSERT( cipher_check_tag( &ctx, buf, olen )
+                 == POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void enc_dec_buf( int cipher_id, char *cipher_string, int key_len,
                   int length_val, int pad_mode )
 {
diff --git a/tests/suites/test_suite_cipher.padding.data b/tests/suites/test_suite_cipher.padding.data
index 702c88f..9b5f290 100644
--- a/tests/suites/test_suite_cipher.padding.data
+++ b/tests/suites/test_suite_cipher.padding.data
@@ -1,6 +1,9 @@
 Cipher list
 cipher_list:
 
+Cipher null/uninitialised arguments
+cipher_null_args:
+
 Set padding with AES-CBC
 depends_on:POLARSSL_AES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_CIPHER_PADDING_PKCS7
 set_padding:POLARSSL_CIPHER_AES_128_CBC:POLARSSL_PADDING_PKCS7:0
diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data
index bd25a53..85be7df 100644
--- a/tests/suites/test_suite_md.data
+++ b/tests/suites/test_suite_md.data
@@ -1,6 +1,9 @@
 MD process
 md_process:
 
+MD NULL/uninitialised arguments
+md_null_args:
+
 Information on MD2
 depends_on:POLARSSL_MD2_C
 md_info:POLARSSL_MD_MD2:"MD2":16
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 74c5a66..9f06443 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -37,6 +37,63 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void md_null_args( )
+{
+    md_context_t ctx;
+    const md_info_t *info = md_info_from_type( *( md_list() ) );
+    unsigned char buf[1] = { 0 };
+
+    memset( &ctx, 0, sizeof( md_context_t ) );
+
+    TEST_ASSERT( md_get_size( NULL ) == 0 );
+
+    TEST_ASSERT( md_get_type( NULL ) == POLARSSL_MD_NONE );
+
+    TEST_ASSERT( md_info_from_string( NULL ) == NULL );
+
+    TEST_ASSERT( md_init_ctx( &ctx, NULL ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_init_ctx( NULL, info ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_starts( NULL ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_starts( &ctx ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_update( NULL, buf, 1 ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_update( &ctx, buf, 1 ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_finish( NULL, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_finish( &ctx, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md( NULL, buf, 1, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_file( NULL, "", buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_hmac_starts( NULL, buf, 1 )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_hmac_starts( &ctx, buf, 1 )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_hmac_update( NULL, buf, 1 )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_hmac_update( &ctx, buf, 1 )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_hmac_finish( NULL, buf )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_hmac_finish( &ctx, buf )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_hmac_reset( NULL ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_hmac_reset( &ctx ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_hmac( NULL, buf, 1, buf, 1, buf )
+                 == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    TEST_ASSERT( md_process( NULL, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_process( &ctx, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void md_info( int md_type, char *md_name, int md_size )
 {
     const md_info_t *md_info;
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index fdbef02..5693a80 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -656,6 +656,22 @@
 depends_on:POLARSSL_GENPRIME
 mpi_is_prime:10:"49979687":0
 
+Test mpi_gen_prime (Too small)
+depends_on:POLARSSL_GENPRIME
+mpi_gen_prime:2:0:POLARSSL_ERR_MPI_BAD_INPUT_DATA
+
+Test mpi_gen_prime (OK, minimum size)
+depends_on:POLARSSL_GENPRIME
+mpi_gen_prime:3:0:0
+
+Test mpi_gen_prime (Larger)
+depends_on:POLARSSL_GENPRIME
+mpi_gen_prime:128:0:0
+
+Test mpi_gen_prime (Safe)
+depends_on:POLARSSL_GENPRIME
+mpi_gen_prime:128:1:0
+
 Test bit getting (Value bit 25)
 mpi_get_bit:10:"49979687":25:1
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 239f8a9..ec9752c 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -719,6 +719,36 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:POLARSSL_GENPRIME */
+void mpi_gen_prime( int bits, int safe, int ref_ret )
+{
+    mpi X;
+    int my_ret;
+
+    mpi_init( &X );
+
+    my_ret = mpi_gen_prime( &X, bits, safe, rnd_std_rand, NULL );
+    TEST_ASSERT( my_ret == ref_ret );
+
+    if( ref_ret == 0 )
+    {
+        size_t actual_bits = mpi_msb( &X );
+
+        TEST_ASSERT( actual_bits >= (size_t) bits );
+        TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
+
+        TEST_ASSERT( mpi_is_prime( &X, rnd_std_rand, NULL ) == 0 );
+        if( safe )
+        {
+            mpi_shift_r( &X, 1 ); /* X = ( X - 1 ) / 2 */
+            TEST_ASSERT( mpi_is_prime( &X, rnd_std_rand, NULL ) == 0 );
+        }
+    }
+
+    mpi_free( &X );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mpi_shift_l( int radix_X, char *input_X, int shift_X, int radix_A,
                   char *input_A)
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index 7ee0360..c22ad0b 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -17,3 +17,107 @@
 PBKDF2 RFC 6070 Test Vector #6 (SHA1)
 depends_on:POLARSSL_SHA1_C
 pbkdf2_hmac:POLARSSL_MD_SHA1:"7061737300776f7264":"7361006c74":4096:16:"56fa6aa75548099dcc37d7f03425e0c3"
+
+PBES2 Decrypt (OK)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
+
+PBES2 Decrypt (bad params tag)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_SEQUENCE:"":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad KDF AlgId: not a sequence)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"31":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad KDF AlgId: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"3001":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (KDF != PBKDF2)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"300B06092A864886F70D01050D":"":"":POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE:""
+
+PBES2 Decrypt (bad PBKDF2 params: not a sequence)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"300D06092A864886F70D01050C3100":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad PBKDF2 params: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"300D06092A864886F70D01050C3001":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (bad PBKDF2 params salt: not an octet string)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"300E06092A864886F70D01050C30010500":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad PBKDF2 params salt: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"300E06092A864886F70D01050C30010401":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (bad PBKDF2 params iter: not an int)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301906092A864886F70D01050C300C04082ED7F24A1D516DD70300":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad PBKDF2 params iter: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301906092A864886F70D01050C300C04082ED7F24A1D516DD70201":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (OK, PBKDF2 params explicit keylen)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301E06092A864886F70D01050C301104082ED7F24A1D516DD702020800020118301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
+
+PBES2 Decrypt (bad PBKDF2 params explicit keylen: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208000201":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (OK, PBKDF2 params explicit prf_alg)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0207301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
+
+PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg not a sequence)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208003100":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208003001":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg != HMAC-SHA1)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0208":"":"":POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE:""
+
+PBES2 Decrypt (bad, PBKDF2 params extra data)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"302806092A864886F70D01050C301B04082ED7F24A1D516DD702020800300A06082A864886F70D020700":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH:""
+
+PBES2 Decrypt (bad enc_scheme_alg: not a sequence)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD7020208003100":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG:""
+
+PBES2 Decrypt (bad enc_scheme_alg: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD7020208003001":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (bad enc_scheme_alg: unkown oid)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300A06082A864886F70D03FF":"":"":POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE:""
+
+PBES2 Decrypt (bad enc_scheme_alg params: not an octet string)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300C06082A864886F70D03070500":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT:""
+
+PBES2 Decrypt (bad enc_scheme_alg params: overlong)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300C06082A864886F70D03070401":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA:""
+
+PBES2 Decrypt (bad enc_scheme_alg params: len != iv_len)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301306082A864886F70D030704078A4FCC9DCC3949":"":"":POLARSSL_ERR_PKCS5_INVALID_FORMAT:""
+
+PBES2 Decrypt (bad password)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"F0617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
+
+PBES2 Decrypt (bad iter value)
+depends_on:POLARSSL_SHA1_C:POLARSSL_DES_C
+pkcs5_pbes2:ASN1_CONSTRUCTED | ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020801301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
diff --git a/tests/suites/test_suite_pkcs5.function b/tests/suites/test_suite_pkcs5.function
index adf7ffc..c745571 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -43,3 +43,35 @@
     TEST_ASSERT( strcmp( (char *) dst_str, result_key_string ) == 0 );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void pkcs5_pbes2( int params_tag, char *params_hex, char *pw_hex,
+                  char *data_hex, int ref_ret, char *ref_out_hex )
+{
+    int my_ret;
+    asn1_buf params;
+    unsigned char *my_out, *ref_out, *data, *pw;
+    size_t ref_out_len, data_len, pw_len;
+
+    params.tag = params_tag;
+    params.p = unhexify_alloc( params_hex, &params.len );
+
+    data = unhexify_alloc( data_hex, &data_len );
+    pw = unhexify_alloc( pw_hex, &pw_len );
+    ref_out = unhexify_alloc( ref_out_hex, &ref_out_len );
+    my_out = zero_alloc( ref_out_len );
+
+    my_ret = pkcs5_pbes2( &params, PKCS5_DECRYPT,
+                          pw, pw_len, data, data_len, my_out );
+    TEST_ASSERT( my_ret == ref_ret );
+
+    if( ref_ret == 0 )
+        TEST_ASSERT( memcmp( my_out, ref_out, ref_out_len ) == 0 );
+
+    polarssl_free( params.p );
+    polarssl_free( data );
+    polarssl_free( pw );
+    polarssl_free( ref_out );
+    polarssl_free( my_out );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index ba92716..54ef202 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1165,3 +1165,80 @@
 X509 RSASSA-PSS parameters ASN1 (trailerField not 1)
 x509_parse_rsassa_pss_params:"A303020102":ASN1_CONSTRUCTED | ASN1_SEQUENCE:POLARSSL_MD_SHA1:POLARSSL_MD_SHA1:20:POLARSSL_ERR_X509_INVALID_ALG
 
+X509 CSR ASN.1 (OK)
+x509_csr_parse:"308201183081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010349003046022100B49FD8C8F77ABFA871908DFBE684A08A793D0F490A43D86FCF2086E4F24BB0C2022100F829D5CCD3742369299E6294394717C4B723A0F68B44E831B6E6C3BCABF97243":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n":0
+
+X509 CSR ASN.1 (bad first tag)
+x509_csr_parse:"3100":"":POLARSSL_ERR_X509_INVALID_FORMAT
+
+X509 CSR ASN.1 (bad sequence: overlong)
+x509_csr_parse:"3001":"":POLARSSL_ERR_X509_INVALID_FORMAT
+
+X509 CSR ASN.1 (total length mistmatch)
+x509_csr_parse:"30010000":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH
+
+X509 CSR ASN.1 (bad CRI: not a sequence)
+x509_csr_parse:"30023100":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad CRI: overlong)
+x509_csr_parse:"30023001":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad CRI.Version: overlong)
+x509_csr_parse:"30053002020100":"":POLARSSL_ERR_X509_INVALID_VERSION + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad CRI.Version: not v1)
+x509_csr_parse:"30053003020101":"":POLARSSL_ERR_X509_UNKNOWN_VERSION
+
+X509 CSR ASN.1 (bad CRI.Name: not a sequence)
+x509_csr_parse:"300730050201003100":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad CRI.Name: overlong)
+x509_csr_parse:"30083005020100300100":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad CRI.Name payload: not a set)
+x509_csr_parse:"3009300702010030023000":"":POLARSSL_ERR_X509_INVALID_NAME + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad CRI.Name payload: overlong)
+x509_csr_parse:"300A30080201003002310100":"":POLARSSL_ERR_X509_INVALID_NAME + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad SubjectPublicKeyInfo: missing)
+x509_csr_parse:"30143012020100300D310B3009060355040613024E4C":"":POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad SubjectPublicKeyInfo: not a sequence)
+x509_csr_parse:"30163014020100300D310B3009060355040613024E4C3100":"":POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad SubjectPublicKeyInfo: overlong)
+x509_csr_parse:"30173014020100300D310B3009060355040613024E4C300100":"":POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad attributes: missing)
+x509_csr_parse:"3081973081940201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad attributes: bad tag)
+x509_csr_parse:"3081993081960201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF0500":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad attributes: overlong)
+x509_csr_parse:"30819A3081960201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA00100":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad sigAlg: missing)
+x509_csr_parse:"3081C23081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad sigAlg: not a sequence)
+x509_csr_parse:"3081C43081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E03100":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad sigAlg: overlong)
+x509_csr_parse:"3081C43081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E03001":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad sigAlg: unknown)
+x509_csr_parse:"3081CD3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04FF":"":POLARSSL_ERR_X509_UNKNOWN_SIG_ALG
+
+X509 CSR ASN.1 (bad sig: missing)
+x509_csr_parse:"3081CD3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D0401":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (bad sig: not a bit string)
+x509_csr_parse:"3081CF3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010400":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (bad sig: overlong)
+x509_csr_parse:"3081CF3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010301":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (extra data after signature)
+x509_csr_parse:"308201193081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010349003046022100B49FD8C8F77ABFA871908DFBE684A08A793D0F490A43D86FCF2086E4F24BB0C2022100F829D5CCD3742369299E6294394717C4B723A0F68B44E831B6E6C3BCABF9724300":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 5c4c29e..9fd3adc 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -267,6 +267,34 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:POLARSSL_X509_CSR_PARSE_C */
+void x509_csr_parse( char *csr_der_hex, char *ref_out, int ref_ret )
+{
+    x509_csr csr;
+    unsigned char *csr_der;
+    char my_out[1000];
+    size_t csr_der_len;
+    int my_ret;
+
+    x509_csr_init( &csr );
+    memset( my_out, 0, sizeof( my_out ) );
+    csr_der = unhexify_alloc( csr_der_hex, &csr_der_len );
+
+    my_ret = x509_csr_parse_der( &csr, csr_der, csr_der_len );
+    TEST_ASSERT( my_ret == ref_ret );
+
+    if( ref_ret == 0 )
+    {
+        size_t my_out_len = x509_csr_info( my_out, sizeof( my_out ), "", &csr );
+        TEST_ASSERT( my_out_len == strlen( ref_out ) );
+        TEST_ASSERT( strcmp( my_out, ref_out ) == 0 );
+    }
+
+    x509_csr_free( &csr );
+    polarssl_free( csr_der );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_CRT_PARSE_C */
 void x509_crt_parse_path( char *crt_path, int ret, int nb_crt )
 {