Skip to content

Commit c347f75

Browse files
authored
Merge pull request #9029 from holtrop/extract-kari-rid
Add wc_PKCS7_GetEnvelopedDataKariRid()
2 parents a06268f + 804c4f2 commit c347f75

File tree

8 files changed

+222
-1
lines changed

8 files changed

+222
-1
lines changed

certs/renewcerts.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,11 @@ run_renewcerts(){
523523
openssl x509 -in client-ecc-cert.pem -text > tmp.pem
524524
check_result $? "Step 3"
525525
mv tmp.pem client-ecc-cert.pem
526+
527+
# Extract the Subject Key Identifier from the generated certificate
528+
# for unit test use.
529+
openssl x509 -in client-ecc-cert.pem -noout -text | grep -A1 'Subject Key Identifier' | tail -n +2 | sed -e 's/[ :]//g' > test/client-ecc-cert-ski.hex
530+
check_result $? "Step 4"
526531
echo "End of section"
527532
echo "---------------------------------------------------------------------"
528533
############################################################
@@ -792,6 +797,9 @@ run_renewcerts(){
792797
cd ./test || { echo "Failed to switch to dir ./test"; exit 1; }
793798
echo "test" | openssl cms -encrypt -binary -keyid -out ktri-keyid-cms.msg -outform der -recip ../client-cert.pem -nocerts
794799
check_result $? "generate ktri-keyid-cms.msg"
800+
# Generate an EnvelopedData with KARI recipient for testing.
801+
echo "testkari" | openssl cms -encrypt -binary -keyid -out kari-keyid-cms.msg -outform der -recip ../client-ecc-cert.pem -nocerts
802+
check_result $? "generate kari-keyid-cms.msg"
795803
echo "testencrypt" | openssl cms -EncryptedData_encrypt -binary -keyid -aes-128-cbc -secretkey 0123456789ABCDEF0011223344556677 -out encrypteddata.msg -outform der -recip ../client-cert.pem -nocerts
796804
check_result $? "generate encrypteddata.msg"
797805
cd ../ || exit 1

certs/test/client-ecc-cert-ski.hex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
EBD44B596B95613F5157B6044D894188445CABF2

certs/test/include.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ EXTRA_DIST += \
3636
certs/test/cert-over-max-altnames.cfg \
3737
certs/test/cert-over-max-altnames.pem \
3838
certs/test/cert-over-max-nc.cfg \
39-
certs/test/cert-over-max-nc.pem
39+
certs/test/cert-over-max-nc.pem \
40+
certs/test/client-ecc-cert-ski.hex
4041

4142
# The certs/server-cert with the last byte (signature byte) changed
4243
EXTRA_DIST += \
@@ -69,6 +70,7 @@ EXTRA_DIST += \
6970
certs/test/server-localhost.pem \
7071
certs/test/ossl-trusted-cert.pem \
7172
certs/test/ktri-keyid-cms.msg \
73+
certs/test/kari-keyid-cms.msg \
7274
certs/test/encrypteddata.msg \
7375
certs/test/smime-test.p7s \
7476
certs/test/smime-test-canon.p7s \

certs/test/kari-keyid-cms.msg

275 Bytes
Binary file not shown.

doc/dox_comments/header_files/pkcs7.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,31 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
643643
int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
644644
word32 pkiMsgSz, byte* output, word32 outputSz);
645645

646+
/*!
647+
\ingroup PKCS7
648+
649+
\brief This function extracts the KeyAgreeRecipientIdentifier object from
650+
an EnvelopedData package containing a KeyAgreeRecipientInfo RecipientInfo
651+
object. Only the first KeyAgreeRecipientIdentifer found in the first
652+
RecipientInfo is copied. This function does not support multiple
653+
RecipientInfo objects or multiple RecipientEncryptedKey objects within an
654+
KeyAgreeRecipientInfo.
655+
656+
\return Returns 0 on success.
657+
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid.
658+
\return ASN_PARSE_E Returned if there is an error parsing the input message.
659+
\return PKCS7_OID_E Returned if the input message is not an enveloped
660+
data type.
661+
\return BUFFER_E Returned if there is not enough room in the output buffer.
662+
663+
\param[in] in Input buffer containing the EnvelopedData ContentInfo message.
664+
\param[in] inSz Size of the input buffer.
665+
\param[out] out Output buffer.
666+
\param[in,out] outSz Output buffer size on input, Size written on output.
667+
*/
668+
int wc_PKCS7_GetEnvelopedDataKariRid(const byte * in, word32 inSz,
669+
byte * out, word32 * outSz);
670+
646671
/*!
647672
\ingroup PKCS7
648673

tests/api.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18304,6 +18304,78 @@ static int test_wc_PKCS7_SetAESKeyWrapUnwrapCb(void)
1830418304
return EXPECT_RESULT();
1830518305
}
1830618306

18307+
/*
18308+
* Testing wc_PKCS7_GetEnvelopedDataKariRid().
18309+
*/
18310+
static int test_wc_PKCS7_GetEnvelopedDataKariRid(void)
18311+
{
18312+
EXPECT_DECLS;
18313+
#if defined(HAVE_PKCS7)
18314+
#if defined(HAVE_ECC) && (!defined(NO_AES) || (!defined(NO_SHA) || \
18315+
!defined(NO_SHA256) || defined(WOLFSSL_SHA512)))
18316+
/* The kari-keyid-cms.msg generated by openssl has a 68 byte RID structure.
18317+
* Reserve a bit more than that in case it might grow. */
18318+
byte rid[256];
18319+
byte cms[1024];
18320+
XFILE cmsFile = XBADFILE;
18321+
int ret;
18322+
word32 ridSz = sizeof(rid);
18323+
XFILE skiHexFile = XBADFILE;
18324+
byte skiHex[256];
18325+
word32 cmsSz = 0;
18326+
word32 skiHexSz = 0;
18327+
size_t i = 0;
18328+
const word32 ridKeyIdentifierOffset = 4;
18329+
18330+
ExpectTrue((cmsFile = XFOPEN("./certs/test/kari-keyid-cms.msg", "rb"))
18331+
!= XBADFILE);
18332+
ExpectTrue((cmsSz = (word32)XFREAD(cms, 1, sizeof(cms), cmsFile)) > 0);
18333+
if (cmsFile != XBADFILE)
18334+
XFCLOSE(cmsFile);
18335+
18336+
ExpectTrue((skiHexFile = XFOPEN("./certs/test/client-ecc-cert-ski.hex",
18337+
"rb")) != XBADFILE);
18338+
ExpectTrue((skiHexSz = (word32)XFREAD(skiHex, 1, sizeof(skiHex),
18339+
skiHexFile)) > 0);
18340+
if (skiHexFile != XBADFILE)
18341+
XFCLOSE(skiHexFile);
18342+
18343+
if (EXPECT_SUCCESS()) {
18344+
ret = wc_PKCS7_GetEnvelopedDataKariRid(cms, cmsSz, rid, &ridSz);
18345+
}
18346+
ExpectIntEQ(ret, 0);
18347+
ExpectIntLT(ridSz, sizeof(rid));
18348+
ExpectIntGT(ridSz, ridKeyIdentifierOffset);
18349+
/* The Subject Key Identifier hex file should have 2 hex characters for each
18350+
* byte of the key identifier in the returned recipient ID (rid), plus a
18351+
* terminating new line character. */
18352+
ExpectIntGE(skiHexSz, ((ridSz - ridKeyIdentifierOffset) * 2) + 1);
18353+
if (EXPECT_SUCCESS()) {
18354+
for (i = 0; i < (ridSz - ridKeyIdentifierOffset); i++)
18355+
{
18356+
size_t j;
18357+
byte ridKeyIdByte = rid[ridKeyIdentifierOffset + i];
18358+
byte skiByte = 0;
18359+
for (j = 0; j <= 1; j++)
18360+
{
18361+
byte hexChar = skiHex[i * 2 + j];
18362+
skiByte = skiByte << 4;
18363+
if ('0' <= hexChar && hexChar <= '9')
18364+
skiByte |= (hexChar - '0');
18365+
else if ('A' <= hexChar && hexChar <= 'F')
18366+
skiByte |= (hexChar - 'A' + 10);
18367+
else
18368+
ExpectTrue(0);
18369+
}
18370+
ExpectIntEQ(ridKeyIdByte, skiByte);
18371+
}
18372+
}
18373+
#endif
18374+
#endif /* HAVE_PKCS7 */
18375+
return EXPECT_RESULT();
18376+
} /* END test_wc_PKCS7_GetEnvelopedDataKariRid() */
18377+
18378+
1830718379
/*
1830818380
* Testing wc_PKCS7_EncodeEncryptedData()
1830918381
*/
@@ -68404,6 +68476,7 @@ TEST_CASE testCases[] = {
6840468476
TEST_DECL(test_wc_PKCS7_DecodeEnvelopedData_stream),
6840568477
TEST_DECL(test_wc_PKCS7_EncodeDecodeEnvelopedData),
6840668478
TEST_DECL(test_wc_PKCS7_SetAESKeyWrapUnwrapCb),
68479+
TEST_DECL(test_wc_PKCS7_GetEnvelopedDataKariRid),
6840768480
TEST_DECL(test_wc_PKCS7_EncodeEncryptedData),
6840868481
TEST_DECL(test_wc_PKCS7_DecodeEncryptedKeyPackage),
6840968482
TEST_DECL(test_wc_PKCS7_DecodeSymmetricKeyPackage),

wolfcrypt/src/pkcs7.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12957,6 +12957,116 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1295712957
}
1295812958

1295912959

12960+
int wc_PKCS7_GetEnvelopedDataKariRid(const byte * in, word32 inSz,
12961+
byte * out, word32 * outSz)
12962+
{
12963+
int ret = 0;
12964+
word32 idx = 0;
12965+
int length = 0;
12966+
word32 contentType = 0;
12967+
word32 ridIdx = 0;
12968+
byte ridTag = 0;
12969+
12970+
if (in == NULL || inSz == 0 || out == NULL || outSz == NULL) {
12971+
ret = BAD_FUNC_ARG;
12972+
}
12973+
/* Consume ContentInfo SEQUENCE header. */
12974+
else if (GetSequence(in, &idx, &length, inSz) < 0) {
12975+
ret = ASN_PARSE_E;
12976+
}
12977+
/* Validate the EnvelopedData OBJECT IDENTIFIER. */
12978+
else if (wc_GetContentType(in, &idx, &contentType, inSz) < 0) {
12979+
ret = ASN_PARSE_E;
12980+
}
12981+
else if (contentType != ENVELOPED_DATA) {
12982+
WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
12983+
ret = PKCS7_OID_E;
12984+
}
12985+
/* Consume EXPLICIT content [0] header. */
12986+
else if (GetASNHeader(in, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
12987+
&length, inSz) < 0) {
12988+
ret = ASN_PARSE_E;
12989+
}
12990+
/* Consume EnvelopedData SEQUENCE header. */
12991+
else if (GetSequence(in, &idx, &length, inSz) < 0) {
12992+
ret = ASN_PARSE_E;
12993+
}
12994+
/* Consume version. */
12995+
else if (GetMyVersion(in, &idx, &length, inSz) < 0) {
12996+
ret = ASN_PARSE_E;
12997+
}
12998+
/* Consume originatorInfo if present. */
12999+
else if (GetASNHeader(in, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
13000+
&length, inSz) >= 0) {
13001+
idx += (word32)length;
13002+
}
13003+
/* Consume recipientInfos SET OF header. */
13004+
if (ret == 0 && GetSet(in, &idx, &length, inSz) < 0) {
13005+
ret = ASN_PARSE_E;
13006+
}
13007+
/* Consume kari [1] header. */
13008+
if (ret == 0 && GetASNHeader(in, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
13009+
&idx, &length, inSz) < 0) {
13010+
ret = ASN_PARSE_E;
13011+
}
13012+
/* Consume KARI version. */
13013+
if (ret == 0 && GetMyVersion(in, &idx, &length, inSz) < 0) {
13014+
ret = ASN_PARSE_E;
13015+
}
13016+
/* Consume KARI originator [0] header. */
13017+
if (ret == 0 && GetASNHeader(in, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED,
13018+
&idx, &length, inSz) < 0) {
13019+
ret = ASN_PARSE_E;
13020+
}
13021+
/* Skip originator [0] content. */
13022+
if (ret == 0)
13023+
idx += (word32)length;
13024+
/* Consume KARI ukm [1] if present. */
13025+
if (ret == 0 && GetASNHeader(in, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
13026+
&idx, &length, inSz) >= 0) {
13027+
idx += (word32) length;
13028+
}
13029+
/* Consume KARI keyEncryptionAlgorithm. */
13030+
if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0) {
13031+
ret = ASN_PARSE_E;
13032+
}
13033+
/* Skip keyEncryptionAlgorithm content. */
13034+
if (ret == 0)
13035+
idx += (word32)length;
13036+
/* Consume RecipientEncryptedKeys SEQUENCE OF header. */
13037+
if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0) {
13038+
ret = ASN_PARSE_E;
13039+
}
13040+
/* Consume RecipientEncryptedKey SEQUENCE header. */
13041+
if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0) {
13042+
ret = ASN_PARSE_E;
13043+
}
13044+
if (ret == 0)
13045+
ridIdx = idx;
13046+
/* Consume KeyAgreeRecipientIdentifier tag. */
13047+
if (ret == 0 && GetASNTag(in, &idx, &ridTag, inSz) < 0) {
13048+
ret = ASN_PARSE_E;
13049+
}
13050+
/* Consume KeyAgreeRecipientIdentifier length. */
13051+
if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0) {
13052+
ret = ASN_PARSE_E;
13053+
}
13054+
if (ret == 0) {
13055+
word32 ridSz = (idx + (word32)length) - ridIdx;
13056+
if (ridSz > *outSz) {
13057+
/* Not enough room in output buffer. */
13058+
ret = BUFFER_E;
13059+
}
13060+
else {
13061+
/* Copy KeyAgreeRecipientIdentifier to output buffer. */
13062+
XMEMCPY(out, &in[ridIdx], ridSz);
13063+
*outSz = ridSz;
13064+
}
13065+
}
13066+
return ret;
13067+
}
13068+
13069+
1296013070
/* build PKCS#7 authEnvelopedData content type, return enveloped size */
1296113071
int wc_PKCS7_EncodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* output,
1296213072
word32 outputSz)

wolfssl/wolfcrypt/pkcs7.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,8 @@ WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7,
516516
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* pkiMsg,
517517
word32 pkiMsgSz, byte* output,
518518
word32 outputSz);
519+
WOLFSSL_API int wc_PKCS7_GetEnvelopedDataKariRid(const byte * in, word32 inSz,
520+
byte * out, word32 * outSz);
519521

520522
/* CMS/PKCS#7 AuthEnvelopedData */
521523
WOLFSSL_API int wc_PKCS7_EncodeAuthEnvelopedData(wc_PKCS7* pkcs7,

0 commit comments

Comments
 (0)