pkcs7: add support for signed data

OpenSSL provides APIs to generate only the signted data
format PKCS7 i.e. without content type OID. This patch
adds support to parse the data correctly even if formatted
only as signed data

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
This commit is contained in:
Nayna Jain 2020-12-14 22:44:49 +00:00 committed by Nick Child
parent c9deb184b0
commit 673a226698
5 changed files with 57 additions and 14 deletions

View file

@ -96,6 +96,20 @@ typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;
*/ */
typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence; typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence;
/**
* PKCS7 types
*/
typedef enum {
MBEDTLS_PKCS7_NONE=0,
MBEDTLS_PKCS7_DATA,
MBEDTLS_PKCS7_SIGNED_DATA,
MBEDTLS_PKCS7_ENVELOPED_DATA,
MBEDTLS_PKCS7_SIGNED_AND_ENVELOPED_DATA,
MBEDTLS_PKCS7_DIGESTED_DATA,
MBEDTLS_PKCS7_ENCRYPTED_DATA,
}
mbedtls_pkcs7_type;
/** /**
* Structure holding PKCS7 signer info * Structure holding PKCS7 signer info
*/ */
@ -168,7 +182,7 @@ void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 );
* \p buf. In particular, \p buf may be destroyed or reused * \p buf. In particular, \p buf may be destroyed or reused
* after this call returns. * after this call returns.
* *
* \return \c 0, if successful. * \return The \c mbedtls_pkcs7_type of \p buf, if successful.
* \return A negative error code on failure. * \return A negative error code on failure.
*/ */
int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf, int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,

View file

@ -103,6 +103,7 @@ static int pkcs7_get_content_info_type( unsigned char **p, unsigned char *end,
{ {
size_t len = 0; size_t len = 0;
int ret; int ret;
unsigned char *start = *p;
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE ); | MBEDTLS_ASN1_SEQUENCE );
@ -110,8 +111,10 @@ static int pkcs7_get_content_info_type( unsigned char **p, unsigned char *end,
return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret ); return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OID ); ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OID );
if( ret != 0 ) if( ret != 0 ) {
*p = start;
return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret ); return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
}
pkcs7->tag = MBEDTLS_ASN1_OID; pkcs7->tag = MBEDTLS_ASN1_OID;
pkcs7->len = len; pkcs7->len = len;
@ -428,6 +431,7 @@ int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
unsigned char *end; unsigned char *end;
size_t len = 0; size_t len = 0;
int ret; int ret;
int isoidset = 0;
if( !pkcs7 ) if( !pkcs7 )
return( MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA );
@ -444,7 +448,10 @@ int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
ret = pkcs7_get_content_info_type( &start, end, &pkcs7->content_type_oid ); ret = pkcs7_get_content_info_type( &start, end, &pkcs7->content_type_oid );
if( ret != 0 ) if( ret != 0 )
goto out; {
len = buflen;
goto try_data;
}
if( ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid ) if( ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid ) || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid )
@ -463,17 +470,31 @@ int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
goto out; goto out;
} }
isoidset = 1;
start = start + pkcs7->content_type_oid.len; start = start + pkcs7->content_type_oid.len;
ret = pkcs7_get_next_content_len( &start, end, &len ); ret = pkcs7_get_next_content_len( &start, end, &len );
if( ret != 0 ) if( ret != 0 )
goto out; goto out;
try_data:
ret = pkcs7_get_signed_data( start, len, &pkcs7->signed_data ); ret = pkcs7_get_signed_data( start, len, &pkcs7->signed_data );
if ( ret != 0 )
goto out;
if ( !isoidset )
{
pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS7_SIGNED_DATA );
pkcs7->content_type_oid.p = (unsigned char *)MBEDTLS_OID_PKCS7_SIGNED_DATA;
}
ret = MBEDTLS_PKCS7_SIGNED_DATA;
out: out:
if ( ret != 0 ) if ( ret < 0 )
mbedtls_pkcs7_free( pkcs7 ); mbedtls_pkcs7_free( pkcs7 );
return( ret ); return( ret );
} }

View file

@ -1223,6 +1223,11 @@ pkcs7_signerInfo_serial_invalid_size.der: pkcs7_data_cert_signed_sha256.der
echo -en '\x15' | dd of=$@ seek=973 bs=1 conv=notrunc echo -en '\x15' | dd of=$@ seek=973 bs=1 conv=notrunc
all_final += pkcs7_signerInfo_serial_invalid_size.der all_final += pkcs7_signerInfo_serial_invalid_size.der
# pkcs7 signature file just with signed data
pkcs7_data_cert_signeddata_sha256.der: pkcs7_data_cert_signed_sha256.der
dd if=pkcs7_data_cert_signed_sha256.der of=$@ skip=19 bs=1
all_final += pkcs7_data_cert_signeddata_sha256.der
################################################################ ################################################################
#### Diffie-Hellman parameters #### Diffie-Hellman parameters
################################################################ ################################################################

View file

@ -51,3 +51,6 @@ pkcs7_parse_failure:"data_files/pkcs7_signerInfo_issuer_invalid_size.der"
PKCS7 Signed Data Parse Failure Corrupt signerInfo.serial #15.2 PKCS7 Signed Data Parse Failure Corrupt signerInfo.serial #15.2
pkcs7_parse_failure:"data_files/pkcs7_signerInfo_serial_invalid_size.der" pkcs7_parse_failure:"data_files/pkcs7_signerInfo_serial_invalid_size.der"
PKCS7 Only Signed Data Parse Pass #15
pkcs7_parse:"data_files/pkcs7_data_cert_signeddata_sha256.der"

View file

@ -29,7 +29,7 @@ void pkcs7_parse( char *pkcs7_file )
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
exit: exit:
mbedtls_free( pkcs7_buf ); mbedtls_free( pkcs7_buf );
@ -52,7 +52,7 @@ void pkcs7_parse_without_cert( char *pkcs7_file )
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
exit: exit:
mbedtls_free( pkcs7_buf ); mbedtls_free( pkcs7_buf );
@ -210,10 +210,10 @@ void pkcs7_verify( char *pkcs7_file, char *crt, char *filetobesigned )
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
mbedtls_free( pkcs7_buf ); mbedtls_free( pkcs7_buf );
res = stat(filetobesigned, &st); res = stat( filetobesigned, &st );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
file = fopen( filetobesigned, "rb" ); file = fopen( filetobesigned, "rb" );
@ -263,9 +263,9 @@ void pkcs7_verify_hash( char *pkcs7_file, char *crt, char *filetobesigned )
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
res = stat(filetobesigned, &st); res = stat( filetobesigned, &st );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
file = fopen( filetobesigned, "rb" ); file = fopen( filetobesigned, "rb" );
@ -319,12 +319,12 @@ void pkcs7_verify_badcert( char *pkcs7_file, char *crt, char *filetobesigned )
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
res = mbedtls_x509_crt_parse_file( &x509, crt ); res = mbedtls_x509_crt_parse_file( &x509, crt );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = stat(filetobesigned, &st); res = stat( filetobesigned, &st );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
file = fopen( filetobesigned, "rb" ); file = fopen( filetobesigned, "rb" );
@ -369,12 +369,12 @@ void pkcs7_verify_tampered_data( char *pkcs7_file, char *crt, char *filetobesign
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen ); res = mbedtls_pkcs7_parse_der( &pkcs7, pkcs7_buf, buflen );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == MBEDTLS_PKCS7_SIGNED_DATA );
res = mbedtls_x509_crt_parse_file( &x509, crt ); res = mbedtls_x509_crt_parse_file( &x509, crt );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
res = stat(filetobesigned, &st); res = stat( filetobesigned, &st );
TEST_ASSERT( res == 0 ); TEST_ASSERT( res == 0 );
file = fopen( filetobesigned, "rb" ); file = fopen( filetobesigned, "rb" );