- Fixed possible heap overflow in pkcs1_decrypt on data larger than output

buffer after padding. For instance the premaster decryption in
   ssl_parse_client_key_exchange() in ssl_serv.c (Thanks to Christophe
   Devine)
This commit is contained in:
Paul Bakker 2009-01-12 21:48:39 +00:00
parent c32c6b56ca
commit 060c56871c
3 changed files with 15 additions and 5 deletions

View File

@ -31,6 +31,7 @@
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440 #define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450 #define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460 #define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
/* /*
* PKCS#1 constants * PKCS#1 constants
@ -216,16 +217,19 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
* \param input buffer holding the encrypted data * \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext * \param output buffer that will hold the plaintext
* \param olen will contain the plaintext length * \param olen will contain the plaintext length
* \param output_max_len maximum length of the output buffer
* *
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
* *
* \note The output buffer must be as large as the size * \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used). * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/ */
int rsa_pkcs1_decrypt( rsa_context *ctx, int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen, int mode, int *olen,
unsigned char *input, unsigned char *input,
unsigned char *output ); unsigned char *output,
int output_max_len);
/** /**
* \brief Do a private RSA to sign a message digest * \brief Do a private RSA to sign a message digest

View File

@ -328,7 +328,8 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
int rsa_pkcs1_decrypt( rsa_context *ctx, int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen, int mode, int *olen,
unsigned char *input, unsigned char *input,
unsigned char *output ) unsigned char *output,
int output_max_len)
{ {
int ret, ilen; int ret, ilen;
unsigned char *p; unsigned char *p;
@ -369,6 +370,9 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
return( POLARSSL_ERR_RSA_INVALID_PADDING ); return( POLARSSL_ERR_RSA_INVALID_PADDING );
} }
if (ilen - (int)(p - buf) > output_max_len)
return( POLARSSL_ERR_RSA_OUTPUT_TO_LARGE );
*olen = ilen - (int)(p - buf); *olen = ilen - (int)(p - buf);
memcpy( output, p, *olen ); memcpy( output, p, *olen );
@ -677,7 +681,8 @@ int rsa_self_test( int verbose )
printf( "passed\n PKCS#1 decryption : " ); printf( "passed\n PKCS#1 decryption : " );
if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len, if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
rsa_ciphertext, rsa_decrypted ) != 0 ) rsa_ciphertext, rsa_decrypted,
sizeof(rsa_decrypted) ) != 0 )
{ {
if( verbose != 0 ) if( verbose != 0 )
printf( "failed\n" ); printf( "failed\n" );

View File

@ -726,7 +726,8 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
} }
ret = rsa_pkcs1_decrypt( ssl->rsa_key, RSA_PRIVATE, &ssl->pmslen, ret = rsa_pkcs1_decrypt( ssl->rsa_key, RSA_PRIVATE, &ssl->pmslen,
ssl->in_msg + i, ssl->premaster ); ssl->in_msg + i, ssl->premaster,
sizeof(ssl->premaster) );
if( ret != 0 || ssl->pmslen != 48 || if( ret != 0 || ssl->pmslen != 48 ||
ssl->premaster[0] != ssl->max_major_ver || ssl->premaster[0] != ssl->max_major_ver ||