mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-02-27 15:40:02 +00:00
Rather than only parsing/verifying one SignerInfo in the SignerInfos field of the PKCS7 stucture, allow the ability to parse and verify more than one signature. Verification will return success if any of the signatures produce a match. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Nick Child <nick.child@ibm.com>
486 lines
12 KiB
Plaintext
486 lines
12 KiB
Plaintext
/* BEGIN_HEADER */
|
|
#include "mbedtls/bignum.h"
|
|
#include "mbedtls/pkcs7.h"
|
|
#include "mbedtls/x509.h"
|
|
#include "mbedtls/x509_crt.h"
|
|
#include "mbedtls/x509_crl.h"
|
|
#include "mbedtls/oid.h"
|
|
#include "sys/types.h"
|
|
#include "sys/stat.h"
|
|
/* END_HEADER */
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
* depends_on:MBEDTLS_PKCS7_C
|
|
* END_DEPENDENCIES
|
|
*/
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_RSA_C */
|
|
void pkcs7_parse( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
|
|
void pkcs7_parse_without_cert( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_RSA_C */
|
|
void pkcs7_parse_multiple_certs( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_ERR_PKCS7_INVALID_CERT );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_RSA_C */
|
|
void pkcs7_parse_corrupted_cert( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_ERR_PKCS7_INVALID_CERT );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_RSA_C */
|
|
void pkcs7_parse_corrupted_signer_info( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res < 0 );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
|
|
void pkcs7_parse_version( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_ERR_PKCS7_INVALID_VERSION );
|
|
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
|
|
void pkcs7_parse_content_oid( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen);
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res != 0 );
|
|
TEST_ASSERT( res == MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE );
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */
|
|
void pkcs7_verify( char *pkcs7_file, char *crt, char *filetobesigned )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
unsigned char *data = NULL;
|
|
struct stat st;
|
|
size_t datalen;
|
|
int res;
|
|
FILE *file;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
mbedtls_x509_crt x509;
|
|
|
|
USE_PSA_INIT();
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
mbedtls_x509_crt_init( &x509 );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509, crt );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
mbedtls_free( pkcs7_buf );
|
|
|
|
res = stat( filetobesigned, &st );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
file = fopen( filetobesigned, "rb" );
|
|
TEST_ASSERT( file != NULL );
|
|
|
|
datalen = st.st_size;
|
|
data = mbedtls_calloc( datalen, 1 );
|
|
buflen = fread( ( void * )data , sizeof( unsigned char ), datalen, file );
|
|
TEST_ASSERT( buflen == datalen);
|
|
|
|
fclose(file);
|
|
|
|
res = mbedtls_pkcs7_signed_data_verify( &pkcs7, &x509, data, datalen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
exit:
|
|
mbedtls_x509_crt_free( &x509 );
|
|
mbedtls_free( data );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
USE_PSA_DONE();
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_SHA256_C */
|
|
void pkcs7_verify_hash( char *pkcs7_file, char *crt, char *filetobesigned )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
unsigned char *data = NULL;
|
|
unsigned char hash[32];
|
|
struct stat st;
|
|
size_t datalen;
|
|
int res;
|
|
FILE *file;
|
|
const mbedtls_md_info_t *md_info;
|
|
mbedtls_md_type_t md_alg;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
mbedtls_x509_crt x509;
|
|
|
|
USE_PSA_INIT();
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
mbedtls_x509_crt_init( &x509 );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509, crt );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
res = stat( filetobesigned, &st );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
file = fopen( filetobesigned, "rb" );
|
|
TEST_ASSERT( file != NULL );
|
|
|
|
datalen = st.st_size;
|
|
data = mbedtls_calloc( datalen, 1 );
|
|
TEST_ASSERT( data != NULL);
|
|
|
|
buflen = fread( (void *)data , sizeof( unsigned char ), datalen, file );
|
|
TEST_ASSERT( buflen == datalen);
|
|
fclose( file );
|
|
|
|
res = mbedtls_oid_get_md_alg( &(pkcs7.signed_data.digest_alg_identifiers), &md_alg );
|
|
TEST_ASSERT( res == 0 );
|
|
TEST_ASSERT( md_alg == MBEDTLS_MD_SHA256 );
|
|
|
|
md_info = mbedtls_md_info_from_type( md_alg );
|
|
|
|
res = mbedtls_md( md_info, data, datalen, hash );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_signed_hash_verify( &pkcs7, &x509, hash, sizeof(hash) );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
exit:
|
|
mbedtls_x509_crt_free( &x509 );
|
|
mbedtls_free( data );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
mbedtls_free( pkcs7_buf );
|
|
USE_PSA_DONE();
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */
|
|
void pkcs7_verify_badcert( char *pkcs7_file, char *crt, char *filetobesigned )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
unsigned char *data = NULL;
|
|
struct stat st;
|
|
size_t datalen;
|
|
int res;
|
|
FILE *file;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
mbedtls_x509_crt x509;
|
|
|
|
USE_PSA_INIT();
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
mbedtls_x509_crt_init( &x509 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509, crt );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = stat( filetobesigned, &st );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
file = fopen( filetobesigned, "rb" );
|
|
TEST_ASSERT( file != NULL );
|
|
|
|
datalen = st.st_size;
|
|
data = mbedtls_calloc( datalen, 1 );
|
|
buflen = fread( ( void * )data , sizeof( unsigned char ), datalen, file );
|
|
TEST_ASSERT( buflen == datalen);
|
|
|
|
fclose(file);
|
|
|
|
res = mbedtls_pkcs7_signed_data_verify( &pkcs7, &x509, data, datalen );
|
|
TEST_ASSERT( res != 0 );
|
|
|
|
exit:
|
|
mbedtls_x509_crt_free( &x509 );
|
|
mbedtls_free( data );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
mbedtls_free( pkcs7_buf );
|
|
USE_PSA_DONE();
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */
|
|
void pkcs7_verify_tampered_data( char *pkcs7_file, char *crt, char *filetobesigned )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
unsigned char *data = NULL;
|
|
struct stat st;
|
|
size_t datalen;
|
|
int res;
|
|
FILE *file;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
mbedtls_x509_crt x509;
|
|
|
|
USE_PSA_INIT();
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
mbedtls_x509_crt_init( &x509 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509, crt );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = stat( filetobesigned, &st );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
file = fopen( filetobesigned, "rb" );
|
|
TEST_ASSERT( file != NULL );
|
|
|
|
datalen = st.st_size;
|
|
data = mbedtls_calloc( datalen, 1 );
|
|
buflen = fread( ( void * )data , sizeof( unsigned char ), datalen, file );
|
|
TEST_ASSERT( buflen == datalen);
|
|
|
|
fclose(file);
|
|
|
|
res = mbedtls_pkcs7_signed_data_verify( &pkcs7, &x509, data, datalen );
|
|
TEST_ASSERT( res != 0 );
|
|
|
|
exit:
|
|
mbedtls_x509_crt_free( &x509 );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
mbedtls_free( data );
|
|
mbedtls_free( pkcs7_buf );
|
|
USE_PSA_DONE();
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */
|
|
void pkcs7_verify_multiple_signers( char *pkcs7_file, char *crt1, char *crt2, char *filetobesigned )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
unsigned char *data = NULL;
|
|
struct stat st;
|
|
size_t datalen;
|
|
int res;
|
|
FILE *file;
|
|
|
|
mbedtls_pkcs7 pkcs7;
|
|
mbedtls_x509_crt x509_1;
|
|
mbedtls_x509_crt x509_2;
|
|
|
|
USE_PSA_INIT();
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
mbedtls_x509_crt_init( &x509_1 );
|
|
mbedtls_x509_crt_init( &x509_2 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
|
|
|
|
TEST_ASSERT( pkcs7.signed_data.no_of_signers == 2 );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509_1, crt1 );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_x509_crt_parse_file( &x509_2, crt2 );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = stat( filetobesigned, &st );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
file = fopen( filetobesigned, "r" );
|
|
TEST_ASSERT( file != NULL );
|
|
|
|
datalen = st.st_size;
|
|
data = ( unsigned char* ) calloc( datalen, sizeof(unsigned char) );
|
|
buflen = fread( ( void * )data , sizeof( unsigned char ), datalen, file );
|
|
TEST_ASSERT( buflen == datalen );
|
|
|
|
fclose( file );
|
|
|
|
res = mbedtls_pkcs7_signed_data_verify( &pkcs7, &x509_1, data, datalen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_signed_data_verify( &pkcs7, &x509_2, data, datalen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
exit:
|
|
mbedtls_x509_crt_free( &x509_1 );
|
|
mbedtls_x509_crt_free( &x509_2 );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
mbedtls_free( data );
|
|
mbedtls_free( pkcs7_buf );
|
|
USE_PSA_DONE();
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
|
|
void pkcs7_parse_failure( char *pkcs7_file )
|
|
{
|
|
unsigned char *pkcs7_buf = NULL;
|
|
size_t buflen;
|
|
int res;
|
|
mbedtls_pkcs7 pkcs7;
|
|
|
|
mbedtls_pkcs7_init( &pkcs7 );
|
|
|
|
res = mbedtls_pk_load_file( pkcs7_file, &pkcs7_buf, &buflen );
|
|
TEST_ASSERT( res == 0 );
|
|
|
|
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
|
|
TEST_ASSERT( res != 0 );
|
|
exit:
|
|
mbedtls_free( pkcs7_buf );
|
|
mbedtls_pkcs7_free( &pkcs7 );
|
|
}
|
|
/* END_CASE */
|