pem_read_buffer() already update use_len after header and footer are read
After header and footer are read, pem_read_buffer() is able to determine
the length of input data used. This allows calling functions to skip
this PEM bit if an error occurs during its parsing.
(cherry picked from commit 9255e8300e550b548b54603c77585921f442e391)
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 728b29e..cb8840c 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -75,7 +75,7 @@
*
* High-level module nr (3 bits - 0x1...-0x8...)
* Name ID Nr of Errors
- * PEM 1 8
+ * PEM 1 9
* X509 2 21
* DHM 3 6
* RSA 4 9
diff --git a/include/polarssl/pem.h b/include/polarssl/pem.h
index 1505401..e95dc10 100644
--- a/include/polarssl/pem.h
+++ b/include/polarssl/pem.h
@@ -3,7 +3,7 @@
*
* \brief Privacy Enhanced Mail (PEM) decoding
*
- * Copyright (C) 2006-2010, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -35,7 +35,7 @@
* PEM data.
* \{
*/
-#define POLARSSL_ERR_PEM_NO_HEADER_PRESENT -0x1080 /**< No PEM header found. */
+#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */
#define POLARSSL_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */
#define POLARSSL_ERR_PEM_MALLOC_FAILED -0x1180 /**< Failed to allocate memory. */
#define POLARSSL_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */
@@ -43,6 +43,7 @@
#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */
#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */
#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */
+#define POLARSSL_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */
/* \} name */
/**
@@ -77,7 +78,11 @@
* \param data source data to look in
* \param pwd password for decryption (can be NULL)
* \param pwdlen length of password
- * \param use_len destination for total length used
+ * \param use_len destination for total length used (set after header is
+ * correctly read, so unless you get
+ * POLARSSL_ERR_PEM_BAD_INPUT_DATA or
+ * POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
+ * the length to skip)
*
* \return 0 on success, ior a specific PEM error code
*/
diff --git a/library/error.c b/library/error.c
index 32d9cf1..fe2be91 100644
--- a/library/error.c
+++ b/library/error.c
@@ -213,8 +213,8 @@
#endif /* POLARSSL_MD_C */
#if defined(POLARSSL_PEM_C)
- if( use_ret == -(POLARSSL_ERR_PEM_NO_HEADER_PRESENT) )
- snprintf( buf, buflen, "PEM - No PEM header found" );
+ if( use_ret == -(POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
+ snprintf( buf, buflen, "PEM - No PEM header or footer found" );
if( use_ret == -(POLARSSL_ERR_PEM_INVALID_DATA) )
snprintf( buf, buflen, "PEM - PEM string is not as expected" );
if( use_ret == -(POLARSSL_ERR_PEM_MALLOC_FAILED) )
@@ -229,6 +229,8 @@
snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
if( use_ret == -(POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
+ if( use_ret == -(POLARSSL_ERR_PEM_BAD_INPUT_DATA) )
+ snprintf( buf, buflen, "PEM - Bad input parameters to function" );
#endif /* POLARSSL_PEM_C */
#if defined(POLARSSL_RSA_C)
diff --git a/library/pem.c b/library/pem.c
index 7070681..813c4ec 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -1,7 +1,7 @@
/*
* Privacy Enhanced Mail (PEM) decoding
*
- * Copyright (C) 2006-2010, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -183,7 +183,7 @@
int ret, enc;
size_t len;
unsigned char *buf;
- unsigned char *s1, *s2;
+ const unsigned char *s1, *s2, *end;
#if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
unsigned char pem_iv[16];
cipher_type_t enc_alg = POLARSSL_CIPHER_NONE;
@@ -193,22 +193,28 @@
#endif /* POLARSSL_MD5_C && (POLARSSL_AES_C || POLARSSL_DES_C) */
if( ctx == NULL )
- return( POLARSSL_ERR_PEM_INVALID_DATA );
+ return( POLARSSL_ERR_PEM_BAD_INPUT_DATA );
s1 = (unsigned char *) strstr( (const char *) data, header );
if( s1 == NULL )
- return( POLARSSL_ERR_PEM_NO_HEADER_PRESENT );
+ return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
s2 = (unsigned char *) strstr( (const char *) data, footer );
if( s2 == NULL || s2 <= s1 )
- return( POLARSSL_ERR_PEM_INVALID_DATA );
+ return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
s1 += strlen( header );
if( *s1 == '\r' ) s1++;
if( *s1 == '\n' ) s1++;
- else return( POLARSSL_ERR_PEM_INVALID_DATA );
+ else return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
+
+ end = s2;
+ end += strlen( footer );
+ if( *end == '\r' ) end++;
+ if( *end == '\n' ) end++;
+ *use_len = end - data;
enc = 0;
@@ -330,10 +336,6 @@
ctx->buf = buf;
ctx->buflen = len;
- s2 += strlen( footer );
- if( *s2 == '\r' ) s2++;
- if( *s2 == '\n' ) s2++;
- *use_len = s2 - data;
return( 0 );
}
diff --git a/library/x509parse.c b/library/x509parse.c
index 686d9d1..47bcdeb 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -1430,7 +1430,7 @@
buflen -= use_len;
buf += use_len;
}
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
pem_free( &pem );
@@ -1570,7 +1570,7 @@
len = pem.buflen;
pem_free( &pem );
}
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
pem_free( &pem );
return( ret );
@@ -2025,7 +2025,7 @@
"-----END RSA PRIVATE KEY-----",
key, pwd, pwdlen, &len );
- if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ if( ret == POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
ret = pem_read_buffer( &pem,
"-----BEGIN PRIVATE KEY-----",
@@ -2040,7 +2040,7 @@
*/
keylen = pem.buflen;
}
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
pem_free( &pem );
return( ret );
@@ -2265,7 +2265,7 @@
*/
keylen = pem.buflen;
}
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
pem_free( &pem );
return( ret );
@@ -2357,7 +2357,7 @@
*/
dhminlen = pem.buflen;
}
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
pem_free( &pem );
return( ret );