From 03a85bca4c1e2ce4e74e0c9ecd6a5bb64e5cc29f Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Wed, 19 Jun 2013 12:06:00 +0200
Subject: [PATCH] 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)
---
include/polarssl/error.h | 2 +-
include/polarssl/pem.h | 11 ++++++++---
library/error.c | 6 ++++--
library/pem.c | 22 ++++++++++++----------
library/x509parse.c | 12 ++++++------
5 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 9c1707105..8fc221e88 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -68,7 +68,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 1505401c7..e95dc10a0 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
@@ -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 @@ void pem_init( pem_context *ctx );
* \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 452f45881..3829cff21 100644
--- a/library/error.c
+++ b/library/error.c
@@ -182,8 +182,8 @@ void error_strerror( int ret, char *buf, size_t buflen )
#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) )
@@ -198,6 +198,8 @@ void error_strerror( int ret, char *buf, size_t buflen )
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 33e74ab78..41f36ab83 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
@@ -183,7 +183,7 @@ int pem_read_buffer( pem_context *ctx, char *header, char *footer, const unsigne
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 @@ int pem_read_buffer( pem_context *ctx, char *header, char *footer, const unsigne
#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( (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( (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 @@ int pem_read_buffer( pem_context *ctx, char *header, char *footer, const unsigne
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 82853f7f4..7fd167291 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -1349,7 +1349,7 @@ int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
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 );
@@ -1489,7 +1489,7 @@ int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
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 );
@@ -1852,7 +1852,7 @@ int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
"-----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-----",
@@ -1867,7 +1867,7 @@ int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
*/
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 );
@@ -2112,7 +2112,7 @@ int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t key
*/
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 );
@@ -2204,7 +2204,7 @@ int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen
*/
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 );