Skip to content

Commit d2ab6ed

Browse files
Add wc_PKCS7_DecodeEncryptedKeyPackage()
1 parent 703bd6d commit d2ab6ed

8 files changed

Lines changed: 359 additions & 16 deletions

File tree

certs/renewcerts.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,8 @@ run_renewcerts(){
792792
cd ./test || { echo "Failed to switch to dir ./test"; exit 1; }
793793
echo "test" | openssl cms -encrypt -binary -keyid -out ktri-keyid-cms.msg -outform der -recip ../client-cert.pem -nocerts
794794
check_result $? "generate ktri-keyid-cms.msg"
795+
echo "testencrypt" | openssl cms -EncryptedData_encrypt -binary -keyid -aes-128-cbc -secretkey 0123456789ABCDEF0011223344556677 -out encrypteddata.msg -outform der -recip ../client-cert.pem -nocerts
796+
check_result $? "generate encrypteddata.msg"
795797
cd ../ || exit 1
796798
echo "End of section"
797799
echo "---------------------------------------------------------------------"

certs/test/encrypteddata.msg

82 Bytes
Binary file not shown.

certs/test/include.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ EXTRA_DIST += \
6969
certs/test/server-localhost.pem \
7070
certs/test/ossl-trusted-cert.pem \
7171
certs/test/ktri-keyid-cms.msg \
72+
certs/test/encrypteddata.msg \
7273
certs/test/smime-test.p7s \
7374
certs/test/smime-test-canon.p7s \
7475
certs/test/smime-test-multipart.p7s \

doc/dox_comments/header_files/pkcs7.h

Lines changed: 113 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,7 @@ int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
312312
\return 0 Returned on successfully extracting the information
313313
from the message
314314
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid
315-
\return ASN_PARSE_E Returned if there is an error parsing from the
316-
given pkiMsg
315+
\return ASN_PARSE_E Returned if there is an error parsing the given pkiMsg
317316
\return PKCS7_OID_E Returned if the given pkiMsg is not a signed data type
318317
\return ASN_VERSION_E Returned if the PKCS7 signer info is not version 1
319318
\return MEMORY_E Returned if there is an error allocating memory
@@ -390,8 +389,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
390389
\return 0 Returned on successfully extracting the information
391390
from the message
392391
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid
393-
\return ASN_PARSE_E Returned if there is an error parsing from the
394-
given pkiMsg
392+
\return ASN_PARSE_E Returned if there is an error parsing the given pkiMsg
395393
\return PKCS7_OID_E Returned if the given pkiMsg is not a signed data type
396394
\return ASN_VERSION_E Returned if the PKCS7 signer info is not version 1
397395
\return MEMORY_E Returned if there is an error allocating memory
@@ -522,7 +520,7 @@ int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
522520
... etc.
523521
524522
ret = wc_PKCS7_EncodeEnvelopedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
525-
if ( ret != 0 ) {
523+
if ( ret < 0 ) {
526524
// error encoding into output buffer
527525
}
528526
\endcode
@@ -543,8 +541,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
543541
\return On successfully extracting the information from the message,
544542
returns the bytes written to output
545543
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid
546-
\return ASN_PARSE_E Returned if there is an error parsing from the
547-
given pkiMsg
544+
\return ASN_PARSE_E Returned if there is an error parsing the given pkiMsg
548545
\return PKCS7_OID_E Returned if the given pkiMsg is not an enveloped
549546
data type
550547
\return ASN_VERSION_E Returned if the PKCS7 signer info is not version 0
@@ -599,15 +596,118 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
599596
pkcs7.privateKeySz = keySz;
600597
601598
decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, received,
602-
sizeof(received),decoded, sizeof(decoded));
603-
if ( decodedSz != 0 ) {
604-
// error decoding message
599+
sizeof(received),decoded, sizeof(decoded));
600+
if ( decodedSz < 0 ) {
601+
// error decoding message
605602
}
606603
\endcode
607604
608605
\sa wc_PKCS7_InitWithCert
609606
\sa wc_PKCS7_EncodeEnvelopedData
610607
*/
611-
int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
612-
word32 pkiMsgSz, byte* output,
613-
word32 outputSz);
608+
int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
609+
word32 pkiMsgSz, byte* output, word32 outputSz);
610+
611+
/*!
612+
\ingroup PKCS7
613+
614+
\brief This function unwraps and decrypts a PKCS7 encrypted data content
615+
type, decoding the message into output. It uses the encryption key of the
616+
PKCS7 object passed in via pkcs7->encryptionKey and
617+
pkcs7->encryptionKeySz to decrypt the message.
618+
619+
\return On successfully extracting the information from the message,
620+
returns the bytes written to output
621+
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid
622+
\return ASN_PARSE_E Returned if there is an error parsing the given pkiMsg
623+
\return PKCS7_OID_E Returned if the given pkiMsg is not an encrypted
624+
data type
625+
\return ASN_VERSION_E Returned if the PKCS7 signer info is not version 0
626+
\return MEMORY_E Returned if there is an error allocating memory
627+
\return BUFFER_E Returned if the encrypted content size is invalid
628+
629+
\param pkcs7 pointer to the PKCS7 structure containing the encryption key with
630+
which to decode the encrypted data package
631+
\param pkiMsg pointer to the buffer containing the encrypted data package
632+
\param pkiMsgSz size of the encrypted data package
633+
\param output pointer to the buffer in which to store the decoded message
634+
\param outputSz size available in the output buffer
635+
636+
_Example_
637+
\code
638+
PKCS7 pkcs7;
639+
byte received[] = { }; // initialize with received encrypted data message
640+
byte decoded[FOURK_BUF];
641+
int decodedSz;
642+
643+
// initialize pkcs7 with certificate
644+
// update key
645+
pkcs7.encryptionKey = key;
646+
pkcs7.encryptionKeySz = keySz;
647+
648+
decodedSz = wc_PKCS7_DecodeEncryptedData(&pkcs7, received,
649+
sizeof(received), decoded, sizeof(decoded));
650+
if ( decodedSz < 0 ) {
651+
// error decoding message
652+
}
653+
\endcode
654+
655+
\sa wc_PKCS7_InitWithCert
656+
*/
657+
int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg,
658+
word32 pkiMsgSz, byte* output, word32 outputSz);
659+
660+
/*!
661+
\ingroup PKCS7
662+
663+
\brief This function unwraps and decrypts a PKCS7 encrypted key package
664+
content type, decoding the message into output. If the wrapped content
665+
type is EncryptedData, the encryption key must be set in the pkcs7 input
666+
structure (via pkcs7->encryptionKey and pkcs7->encryptionKeySz). If the
667+
wrapped content type is EnvelopedData, the private key must be set in the
668+
pkcs7 input structure (via pkcs7->privateKey and pkcs7->privateKeySz).
669+
A wrapped content type of AuthEnvelopedData is not currently supported.
670+
671+
This function will automatically call either wc_PKCS7_DecodeEnvelopedData()
672+
or wc_PKCS7_DecodeEncryptedData() depending on the wrapped content type.
673+
This function could also return any error code from either of those
674+
functions in addition to the error codes listed here.
675+
676+
\return On successfully extracting the information from the message,
677+
returns the bytes written to output
678+
\return ASN_PARSE_E Returned if there is an error parsing the given pkiMsg
679+
or if the wrapped content type is EncryptedData and support for
680+
EncryptedData is not compiled in (e.g. NO_PKCS7_ENCRYPTED_DATA is set)
681+
\return PKCS7_OID_E Returned if the given pkiMsg is not an encrypted
682+
key package data type
683+
684+
\param pkcs7 pointer to the PKCS7 structure containing the private key or
685+
encryption key with which to decode the encrypted key package
686+
\param pkiMsg pointer to the buffer containing the encrypted key package message
687+
\param pkiMsgSz size of the encrypted key package message
688+
\param output pointer to the buffer in which to store the decoded output
689+
\param outputSz size available in the output buffer
690+
691+
_Example_
692+
\code
693+
PKCS7 pkcs7;
694+
byte received[] = { }; // initialize with received encrypted data message
695+
byte decoded[FOURK_BUF];
696+
int decodedSz;
697+
698+
// initialize pkcs7 with certificate
699+
// update key for expected EnvelopedData (example)
700+
pkcs7.privateKey = key;
701+
pkcs7.privateKeySz = keySz;
702+
703+
decodedSz = wc_PKCS7_DecodeEncryptedKeyPackage(&pkcs7, received,
704+
sizeof(received), decoded, sizeof(decoded));
705+
if ( decodedSz < 0 ) {
706+
// error decoding message
707+
}
708+
\endcode
709+
710+
\sa wc_PKCS7_InitWithCert
711+
*/
712+
int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7,
713+
byte * pkiMsg, word32 pkiMsgSz, byte * output, word32 outputSz);

tests/api.c

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17486,7 +17486,7 @@ static int test_wc_PKCS7_DecodeEnvelopedData_stream(void)
1748617486
} /* END test_wc_PKCS7_DecodeEnvelopedData_stream() */
1748717487

1748817488
/*
17489-
* Testing wc_PKCS7_EncodeEnvelopedData()
17489+
* Testing wc_PKCS7_EncodeEnvelopedData(), wc_PKCS7_DecodeEnvelopedData()
1749017490
*/
1749117491
static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void)
1749217492
{
@@ -18177,6 +18177,178 @@ static int test_wc_PKCS7_EncodeEncryptedData(void)
1817718177
return EXPECT_RESULT();
1817818178
} /* END test_wc_PKCS7_EncodeEncryptedData() */
1817918179

18180+
18181+
#if defined(HAVE_PKCS7) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_DES3) && !defined(NO_RSA) && !defined(NO_SHA)
18182+
static void build_test_EncryptedKeyPackage(byte * out, word32 * out_size, byte * in_data, word32 in_size, size_t in_content_type, size_t test_vector)
18183+
{
18184+
/* EncryptedKeyPackage ContentType TLV DER */
18185+
static const byte ekp_oid_tlv[] = {0x06U, 10U,
18186+
0X60U, 0X86U, 0X48U, 0X01U, 0X65U, 0X02U, 0X01U, 0X02U, 0X4EU, 0X02U};
18187+
if (in_content_type == ENCRYPTED_DATA) {
18188+
/* EncryptedData subtype */
18189+
size_t ekp_content_der_size = 2U + in_size;
18190+
size_t ekp_content_info_size = sizeof(ekp_oid_tlv) + ekp_content_der_size;
18191+
/* EncryptedKeyPackage ContentType */
18192+
out[0] = 0x30U;
18193+
out[1] = ekp_content_info_size & 0x7FU;
18194+
/* EncryptedKeyPackage ContentInfo */
18195+
XMEMCPY(&out[2], ekp_oid_tlv, sizeof(ekp_oid_tlv));
18196+
/* EncryptedKeyPackage content [0] */
18197+
out[14] = 0xA0U;
18198+
out[15] = in_size & 0x7FU;
18199+
XMEMCPY(&out[16], in_data, in_size);
18200+
*out_size = 16U + in_size;
18201+
switch (test_vector)
18202+
{
18203+
case 1: out[0] = 0x20U; break;
18204+
case 2: out[2] = 0x01U; break;
18205+
case 3: out[7] = 0x42U; break;
18206+
case 4: out[14] = 0xA2U; break;
18207+
}
18208+
}
18209+
else if (in_content_type == ENVELOPED_DATA) {
18210+
/* EnvelopedData subtype */
18211+
size_t ekp_choice_der_size = 4U + in_size;
18212+
size_t ekp_content_der_size = 4U + ekp_choice_der_size;
18213+
size_t ekp_content_info_size = sizeof(ekp_oid_tlv) + ekp_content_der_size;
18214+
/* EncryptedKeyPackage ContentType */
18215+
out[0] = 0x30U;
18216+
out[1] = 0x82U;
18217+
out[2] = ekp_content_info_size >> 8U;
18218+
out[3] = ekp_content_info_size & 0xFFU;
18219+
/* EncryptedKeyPackage ContentInfo */
18220+
XMEMCPY(&out[4], ekp_oid_tlv, sizeof(ekp_oid_tlv));
18221+
/* EncryptedKeyPackage content [0] */
18222+
out[16] = 0xA0U;
18223+
out[17] = 0x82U;
18224+
out[18] = ekp_choice_der_size >> 8U;
18225+
out[19] = ekp_choice_der_size & 0xFFU;
18226+
/* EncryptedKeyPackage CHOICE [0] EnvelopedData */
18227+
out[20] = 0xA0U;
18228+
out[21] = 0x82U;
18229+
out[22] = in_size >> 8U;
18230+
out[23] = in_size & 0xFFU;
18231+
XMEMCPY(&out[24], in_data, in_size);
18232+
*out_size = 24U + in_size;
18233+
switch (test_vector)
18234+
{
18235+
case 1: out[0] = 0x20U; break;
18236+
case 2: out[4] = 0x01U; break;
18237+
case 3: out[9] = 0x42U; break;
18238+
case 4: out[16] = 0xA2U; break;
18239+
}
18240+
}
18241+
}
18242+
#endif /* HAVE_PKCS7 && USE_CERT_BUFFERS_2048 && !NO_DES3 && !NO_RSA && !NO_SHA */
18243+
18244+
/*
18245+
* Test wc_PKCS7_DecodeEncryptedKeyPackage().
18246+
*/
18247+
static int test_wc_PKCS7_DecodeEncryptedKeyPackage(void)
18248+
{
18249+
EXPECT_DECLS;
18250+
#if defined(HAVE_PKCS7) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_DES3) && !defined(NO_RSA) && !defined(NO_SHA)
18251+
static const struct {
18252+
const char * msg_file_name;
18253+
word32 msg_content_type;
18254+
} test_messages[] = {
18255+
{"./certs/test/ktri-keyid-cms.msg", ENVELOPED_DATA},
18256+
{"./certs/test/encrypteddata.msg", ENCRYPTED_DATA},
18257+
};
18258+
static const int test_vectors[] = {
18259+
0,
18260+
WC_NO_ERR_TRACE(ASN_PARSE_E),
18261+
WC_NO_ERR_TRACE(ASN_PARSE_E),
18262+
WC_NO_ERR_TRACE(PKCS7_OID_E),
18263+
WC_NO_ERR_TRACE(ASN_PARSE_E),
18264+
};
18265+
static const byte key[] = {
18266+
0x01U, 0x23U, 0x45U, 0x67U, 0x89U, 0xABU, 0xCDU, 0xEFU,
18267+
0x00U, 0x11U, 0x22U, 0x33U, 0x44U, 0x55U, 0x66U, 0x77U,
18268+
};
18269+
size_t test_msg = 0U;
18270+
size_t test_vector = 0U;
18271+
18272+
for (test_msg = 0U; test_msg < (sizeof(test_messages)/sizeof(test_messages[0])); test_msg++)
18273+
{
18274+
for (test_vector = 0U; test_vector < (sizeof(test_vectors)/sizeof(test_vectors[0])); test_vector++)
18275+
{
18276+
byte * ekp_cms_der = NULL;
18277+
word32 ekp_cms_der_size = 0U;
18278+
byte * inner_cms_der = NULL;
18279+
word32 inner_cms_der_size = (word32)FOURK_BUF;
18280+
XFILE inner_cms_file = XBADFILE;
18281+
PKCS7 * pkcs7 = NULL;
18282+
byte out[15] = {0};
18283+
int result = 0;
18284+
18285+
ExpectNotNull(ekp_cms_der = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
18286+
/* Check for possible previous test failure. */
18287+
if (ekp_cms_der == NULL) {
18288+
break;
18289+
}
18290+
18291+
ExpectNotNull(inner_cms_der = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
18292+
ExpectTrue((inner_cms_file = XFOPEN(test_messages[test_msg].msg_file_name, "rb")) != XBADFILE);
18293+
ExpectTrue((inner_cms_der_size = (word32)XFREAD(inner_cms_der, 1, inner_cms_der_size, inner_cms_file)) > 0);
18294+
if (inner_cms_file != XBADFILE) {
18295+
XFCLOSE(inner_cms_file);
18296+
}
18297+
if (test_messages[test_msg].msg_content_type == ENVELOPED_DATA) {
18298+
/* Verify that the build_test_EncryptedKeyPackage can format as expected. */
18299+
ExpectIntGT(inner_cms_der_size, 127);
18300+
}
18301+
if (test_messages[test_msg].msg_content_type == ENCRYPTED_DATA) {
18302+
/* Verify that the build_test_EncryptedKeyPackage can format as expected. */
18303+
ExpectIntLT(inner_cms_der_size, 124);
18304+
}
18305+
build_test_EncryptedKeyPackage(ekp_cms_der, &ekp_cms_der_size, inner_cms_der, inner_cms_der_size, test_messages[test_msg].msg_content_type, test_vector);
18306+
XFREE(inner_cms_der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
18307+
18308+
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
18309+
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte *)client_cert_der_2048, sizeof_client_cert_der_2048), 0);
18310+
if (pkcs7 != NULL) {
18311+
if (test_messages[test_msg].msg_content_type == ENVELOPED_DATA) {
18312+
/* To test EnvelopedData, set private key. */
18313+
pkcs7->privateKey = (byte *)client_key_der_2048;
18314+
pkcs7->privateKeySz = sizeof_client_key_der_2048;
18315+
}
18316+
if (test_messages[test_msg].msg_content_type == ENCRYPTED_DATA) {
18317+
/* To test EncryptedData, set symmetric encryption key. */
18318+
pkcs7->encryptionKey = (byte *)key;
18319+
pkcs7->encryptionKeySz = sizeof(key);
18320+
}
18321+
}
18322+
result = wc_PKCS7_DecodeEncryptedKeyPackage(pkcs7, ekp_cms_der, ekp_cms_der_size, out, sizeof(out));
18323+
if (result == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
18324+
result = wc_PKCS7_DecodeEncryptedKeyPackage(pkcs7, ekp_cms_der, ekp_cms_der_size, out, sizeof(out));
18325+
}
18326+
if (test_vectors[test_vector] == 0U) {
18327+
if (test_messages[test_msg].msg_content_type == ENVELOPED_DATA) {
18328+
ExpectIntGT(result, 0);
18329+
ExpectIntEQ(XMEMCMP(out, "test", 4), 0);
18330+
}
18331+
if (test_messages[test_msg].msg_content_type == ENCRYPTED_DATA) {
18332+
#ifndef NO_PKCS7_ENCRYPTED_DATA
18333+
ExpectIntGT(result, 0);
18334+
ExpectIntEQ(XMEMCMP(out, "testencrypt", 11), 0);
18335+
#else
18336+
ExpectIntEQ(result, WC_NO_ERR_TRACE(ASN_PARSE_E));
18337+
#endif
18338+
}
18339+
}
18340+
else {
18341+
ExpectIntEQ(result, test_vectors[test_vector]);
18342+
}
18343+
XFREE(ekp_cms_der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
18344+
wc_PKCS7_Free(pkcs7);
18345+
}
18346+
}
18347+
#endif /* HAVE_PKCS7 && USE_CERT_BUFFERS_2048 && !NO_DES3 && !NO_RSA && !NO_SHA */
18348+
return EXPECT_RESULT();
18349+
} /* END test_wc_PKCS7_DecodeEncryptedKeyPackage() */
18350+
18351+
1818018352
/*
1818118353
* Testing wc_PKCS7_Degenerate()
1818218354
*/
@@ -67601,6 +67773,7 @@ TEST_CASE testCases[] = {
6760167773
TEST_DECL(test_wc_PKCS7_DecodeEnvelopedData_stream),
6760267774
TEST_DECL(test_wc_PKCS7_EncodeDecodeEnvelopedData),
6760367775
TEST_DECL(test_wc_PKCS7_EncodeEncryptedData),
67776+
TEST_DECL(test_wc_PKCS7_DecodeEncryptedKeyPackage),
6760467777
TEST_DECL(test_wc_PKCS7_Degenerate),
6760567778
TEST_DECL(test_wc_PKCS7_BER),
6760667779
TEST_DECL(test_wc_PKCS7_signed_enveloped),

0 commit comments

Comments
 (0)