Fix undocumented feature of pem_read_buffer()

Used to work only for RSAPrivateKey content, now accepts ECPrivateKey too,
and may even work with similar enough structures when they appear.
diff --git a/include/polarssl/pem.h b/include/polarssl/pem.h
index 969faa2..782b235 100644
--- a/include/polarssl/pem.h
+++ b/include/polarssl/pem.h
@@ -84,6 +84,9 @@
  *                  POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
  *                  the length to skip)
  *
+ * \note            Checks password correctness by verifying if the decrypted
+ *                  text looks like a RSAPrivateKey or ECPrivateKey structure
+ *
  * \return          0 on success, ior a specific PEM error code
  */
 int pem_read_buffer( pem_context *ctx, const char *header, const char *footer,
diff --git a/library/pem.c b/library/pem.c
index c4c5cb4..3e3e96d 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -332,8 +332,22 @@
             pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
 #endif /* POLARSSL_AES_C */
 
-        if( buf[0] != 0x30 || buf[1] != 0x82 ||
-            buf[4] != 0x02 || buf[5] != 0x01 )
+        /*
+         * The result should look like RSAPrivateKey or ECPrivateKey
+         * We use the following heuristic:
+         *    len must be more than 6
+         *    byte 1 must be 0x30 (SEQUENCE tag)
+         *    then allow for one to 3 length bytes
+         *    then we must have 0x02 0x01 (INTEGER tag + length, for version)
+         *    version must be less than 4 (leaves some room)
+         */
+        if( ! ( len > 6 && buf[0] == 0x30 && (
+                   ( buf[1] <= 0x7f && /* 1 length byte */
+                     buf[2] == 0x02 && buf[3] == 0x01 && buf[4] < 4 ) ||
+                   ( buf[1] == 0x81 && /* 2 length bytes */
+                     buf[3] == 0x02 && buf[4] == 0x01 && buf[5] < 4 ) ||
+                   ( buf[1] == 0x82 && /* 2 length bytes */
+                     buf[4] == 0x02 && buf[5] == 0x01 && buf[6] < 4 ) ) ) )
         {
             polarssl_free( buf );
             return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );