Implement parameter validation in pk, pkparse and pkwrite

Add checks for null pointers under MBEDTLS_CHECK_PARAMS.

In functions that perform operations with a context, only check if the
context pointer is non-null under MBEDTLS_CHECK_PARAMS. In the default
configuration, unconditionally dereference the context pointer.

In functions that query a context, support NULL as a
pointer-to-context argument, and return the same value as for a
context which has been initialized but not set up.
This commit is contained in:
Gilles Peskine 2018-12-19 00:51:38 +01:00
parent a310b41ebe
commit e97dc60b42
3 changed files with 106 additions and 17 deletions

View file

@ -61,6 +61,12 @@
#define mbedtls_free free
#endif
/* Parameter validation macros based on platform_util.h */
#define PK_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
#define PK_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_FS_IO)
/*
* Load all data from a file into a given buffer.
@ -74,6 +80,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
FILE *f;
long size;
PK_VALIDATE_RET( path != NULL );
PK_VALIDATE_RET( buf != NULL );
PK_VALIDATE_RET( n != NULL );
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
@ -124,6 +134,8 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
size_t n;
unsigned char *buf;
PK_VALIDATE_RET( ctx != NULL );
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret );
@ -148,6 +160,8 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
size_t n;
unsigned char *buf;
PK_VALIDATE_RET( ctx != NULL );
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret );
@ -605,6 +619,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
const mbedtls_pk_info_t *pk_info;
PK_VALIDATE_RET( p != NULL );
PK_VALIDATE_RET( *p != NULL );
PK_VALIDATE_RET( end != NULL );
PK_VALIDATE_RET( pk != NULL );
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
@ -1145,12 +1164,17 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
{
int ret;
const mbedtls_pk_info_t *pk_info;
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
mbedtls_pem_context pem;
#endif
mbedtls_pem_init( &pem );
PK_VALIDATE_RET( pk != NULL );
PK_VALIDATE_RET( key != NULL || keylen == 0 );
PK_VALIDATE_RET( pwd != NULL || pwdlen == 0 );
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
#if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
@ -1360,7 +1384,12 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
mbedtls_pem_context pem;
#endif
PK_VALIDATE_RET( ctx != NULL );
PK_VALIDATE_RET( key != NULL || keylen == 0 );
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
#if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */