mbedtls/tests/suites/test_suite_x509write.function
Paul Elliott 102bac7a46 Add tests for buffer corruption after PEM write
Zero remaining bytes in buffer after writing PEM data and add checks to
ensure that this is the case.

Signed-off-by: Paul Elliott <paul.elliott@arm.com>
2020-12-07 16:49:30 +00:00

267 lines
9.2 KiB
Plaintext

/* BEGIN_HEADER */
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_csr.h"
#include "mbedtls/pem.h"
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
#if defined(MBEDTLS_RSA_C)
int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len )
{
return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, NULL, NULL, mode, olen,
input, output, output_max_len ) );
}
int mbedtls_rsa_sign_func( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig )
{
return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, mode,
md_alg, hashlen, hash, sig ) );
}
size_t mbedtls_rsa_key_len_func( void *ctx )
{
return( ((const mbedtls_rsa_context *) ctx)->len );
}
#endif /* MBEDTLS_RSA_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO:MBEDTLS_PK_PARSE_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C */
void x509_csr_check( char * key_file, char * cert_req_check_file, int md_type,
int key_usage, int set_key_usage, int cert_type,
int set_cert_type )
{
mbedtls_pk_context key;
mbedtls_x509write_csr req;
unsigned char buf[4096];
unsigned char check_buf[4000];
int ret;
size_t olen = 0, pem_len = 0, buf_index;
int der_len = -1;
FILE *f;
const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
rnd_pseudo_info rnd_info;
memset( &rnd_info, 0x2a, sizeof( rnd_pseudo_info ) );
mbedtls_pk_init( &key );
TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL ) == 0 );
mbedtls_x509write_csr_init( &req );
mbedtls_x509write_csr_set_md_alg( &req, md_type );
mbedtls_x509write_csr_set_key( &req, &key );
TEST_ASSERT( mbedtls_x509write_csr_set_subject_name( &req, subject_name ) == 0 );
if( set_key_usage != 0 )
TEST_ASSERT( mbedtls_x509write_csr_set_key_usage( &req, key_usage ) == 0 );
if( set_cert_type != 0 )
TEST_ASSERT( mbedtls_x509write_csr_set_ns_cert_type( &req, cert_type ) == 0 );
ret = mbedtls_x509write_csr_pem( &req, buf, sizeof( buf ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( ret == 0 );
pem_len = strlen( (char *) buf );
for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
{
TEST_ASSERT( buf[buf_index] == 0 );
}
f = fopen( cert_req_check_file, "r" );
TEST_ASSERT( f != NULL );
olen = fread( check_buf, 1, sizeof( check_buf ), f );
fclose( f );
TEST_ASSERT( olen >= pem_len - 1 );
TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
der_len = mbedtls_x509write_csr_der( &req, buf, sizeof( buf ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( der_len >= 0 );
if( der_len == 0 )
goto exit;
ret = mbedtls_x509write_csr_der( &req, buf, (size_t)( der_len - 1 ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
exit:
mbedtls_x509write_csr_free( &req );
mbedtls_pk_free( &key );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_SHA1_C */
void x509_crt_check( char *subject_key_file, char *subject_pwd,
char *subject_name, char *issuer_key_file,
char *issuer_pwd, char *issuer_name,
char *serial_str, char *not_before, char *not_after,
int md_type, int key_usage, int set_key_usage,
int cert_type, int set_cert_type, int auth_ident,
int ver, char *cert_check_file, int rsa_alt )
{
mbedtls_pk_context subject_key, issuer_key, issuer_key_alt;
mbedtls_pk_context *key = &issuer_key;
mbedtls_x509write_cert crt;
unsigned char buf[4096];
unsigned char check_buf[5000];
mbedtls_mpi serial;
int ret;
size_t olen = 0, pem_len = 0, buf_index;
int der_len = -1;
FILE *f;
rnd_pseudo_info rnd_info;
memset( &rnd_info, 0x2a, sizeof( rnd_pseudo_info ) );
mbedtls_mpi_init( &serial );
mbedtls_pk_init( &subject_key );
mbedtls_pk_init( &issuer_key );
mbedtls_pk_init( &issuer_key_alt );
mbedtls_x509write_crt_init( &crt );
TEST_ASSERT( mbedtls_pk_parse_keyfile( &subject_key, subject_key_file,
subject_pwd ) == 0 );
TEST_ASSERT( mbedtls_pk_parse_keyfile( &issuer_key, issuer_key_file,
issuer_pwd ) == 0 );
#if defined(MBEDTLS_RSA_C)
/* For RSA PK contexts, create a copy as an alternative RSA context. */
if( rsa_alt == 1 && mbedtls_pk_get_type( &issuer_key ) == MBEDTLS_PK_RSA )
{
TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &issuer_key_alt,
mbedtls_pk_rsa( issuer_key ),
mbedtls_rsa_decrypt_func,
mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func ) == 0 );
key = &issuer_key_alt;
}
#else
(void) rsa_alt;
#endif
TEST_ASSERT( mbedtls_mpi_read_string( &serial, 10, serial_str ) == 0 );
if( ver != -1 )
mbedtls_x509write_crt_set_version( &crt, ver );
TEST_ASSERT( mbedtls_x509write_crt_set_serial( &crt, &serial ) == 0 );
TEST_ASSERT( mbedtls_x509write_crt_set_validity( &crt, not_before,
not_after ) == 0 );
mbedtls_x509write_crt_set_md_alg( &crt, md_type );
TEST_ASSERT( mbedtls_x509write_crt_set_issuer_name( &crt, issuer_name ) == 0 );
TEST_ASSERT( mbedtls_x509write_crt_set_subject_name( &crt, subject_name ) == 0 );
mbedtls_x509write_crt_set_subject_key( &crt, &subject_key );
mbedtls_x509write_crt_set_issuer_key( &crt, key );
if( crt.version >= MBEDTLS_X509_CRT_VERSION_3 )
{
TEST_ASSERT( mbedtls_x509write_crt_set_basic_constraints( &crt, 0, 0 ) == 0 );
TEST_ASSERT( mbedtls_x509write_crt_set_subject_key_identifier( &crt ) == 0 );
if( auth_ident )
TEST_ASSERT( mbedtls_x509write_crt_set_authority_key_identifier( &crt ) == 0 );
if( set_key_usage != 0 )
TEST_ASSERT( mbedtls_x509write_crt_set_key_usage( &crt, key_usage ) == 0 );
if( set_cert_type != 0 )
TEST_ASSERT( mbedtls_x509write_crt_set_ns_cert_type( &crt, cert_type ) == 0 );
}
ret = mbedtls_x509write_crt_pem( &crt, buf, sizeof( buf ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( ret == 0 );
pem_len = strlen( (char *) buf );
for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
{
TEST_ASSERT( buf[buf_index] == 0 );
}
f = fopen( cert_check_file, "r" );
TEST_ASSERT( f != NULL );
olen = fread( check_buf, 1, sizeof( check_buf ), f );
fclose( f );
TEST_ASSERT( olen < sizeof( check_buf ) );
TEST_ASSERT( olen >= pem_len - 1 );
TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
der_len = mbedtls_x509write_crt_der( &crt, buf, sizeof( buf ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( der_len >= 0 );
if( der_len == 0 )
goto exit;
ret = mbedtls_x509write_crt_der( &crt, buf, (size_t)( der_len - 1 ),
rnd_pseudo_rand, &rnd_info );
TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
exit:
mbedtls_x509write_crt_free( &crt );
mbedtls_pk_free( &issuer_key_alt );
mbedtls_pk_free( &subject_key );
mbedtls_pk_free( &issuer_key );
mbedtls_mpi_free( &serial );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
void mbedtls_x509_string_to_names( char *name, char *parsed_name, int result )
{
int ret;
size_t len = 0;
mbedtls_asn1_named_data *names = NULL;
mbedtls_x509_name parsed, *parsed_cur, *parsed_prv;
unsigned char buf[1024], out[1024], *c;
memset( &parsed, 0, sizeof( parsed ) );
memset( out, 0, sizeof( out ) );
memset( buf, 0, sizeof( buf ) );
c = buf + sizeof( buf );
ret = mbedtls_x509_string_to_names( &names, name );
TEST_ASSERT( ret == result );
if( ret != 0 )
goto exit;
ret = mbedtls_x509_write_names( &c, buf, names );
TEST_ASSERT( ret > 0 );
TEST_ASSERT( mbedtls_asn1_get_tag( &c, buf + sizeof( buf ), &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) == 0 );
TEST_ASSERT( mbedtls_x509_get_name( &c, buf + sizeof( buf ), &parsed ) == 0 );
ret = mbedtls_x509_dn_gets( (char *) out, sizeof( out ), &parsed );
TEST_ASSERT( ret > 0 );
TEST_ASSERT( strcmp( (char *) out, parsed_name ) == 0 );
exit:
mbedtls_asn1_free_named_data_list( &names );
parsed_cur = parsed.next;
while( parsed_cur != 0 )
{
parsed_prv = parsed_cur;
parsed_cur = parsed_cur->next;
mbedtls_free( parsed_prv );
}
}
/* END_CASE */