add CMS EnvelopedData KEKRecipientInfo support

This commit is contained in:
Chris Conlon 2018-09-12 13:23:35 -06:00 committed by David Garske
parent ec07fe492e
commit dbb5bb7570
7 changed files with 1105 additions and 382 deletions

1
.gitignore vendored
View File

@ -115,6 +115,7 @@ pkcs7signedData_ECDSA_SHA384.der
pkcs7signedData_ECDSA_SHA512.der
pkcs7envelopedDataDES3.der
pkcs7envelopedDataAES128CBC.der
pkcs7envelopedDataAES128CBC_KEKRI.der
pkcs7envelopedDataAES192CBC.der
pkcs7envelopedDataAES256CBC.der
diff

View File

@ -56,6 +56,7 @@ CLEANFILES+= cert.der \
pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF_ukm.der \
pkcs7envelopedDataDES3.der \
pkcs7envelopedDataAES128CBC.der \
pkcs7envelopedDataAES128CBC_KEKRI.der \
pkcs7envelopedDataAES192CBC.der \
pkcs7envelopedDataAES256CBC.der \
pkcs7signedData_RSA_SHA.der \

View File

@ -4863,10 +4863,12 @@ int GetTimeString(byte* date, int format, char* buf, int len)
#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
/* set current time string, either UTC or GeneralizedTime */
int GetAsnTimeString(byte* buf, word32 len)
/* Set current time string, either UTC or GeneralizedTime.
* (void*) tm should be a pointer to time_t, output is placed in buf.
*
* Return time string length placed in buf on success, negative on error */
int GetAsnTimeString(void* currTime, byte* buf, word32 len)
{
time_t currTime;
struct tm* ts = NULL;
struct tm* tmpTime = NULL;
#if defined(NEED_TMP_TIME)
@ -4884,8 +4886,7 @@ int GetAsnTimeString(byte* buf, word32 len)
if (buf == NULL || len == 0)
return BAD_FUNC_ARG;
currTime = XTIME(0);
ts = (struct tm *)XGMTIME(&currTime, tmpTime);
ts = (struct tm *)XGMTIME(currTime, tmpTime);
if (ts == NULL){
WOLFSSL_MSG("failed to get time data.");
return ASN_TIME_E;

File diff suppressed because it is too large Load Diff

View File

@ -18942,6 +18942,18 @@ typedef struct {
word32 privateKeySz;
byte* optionalUkm;
word32 optionalUkmSz;
/* KEKRI specific */
byte* secretKey; /* key, only for kekri RecipientInfo types */
word32 secretKeySz; /* size of secretKey, bytes */
byte* secretKeyId; /* key identifier */
word32 secretKeyIdSz; /* size of key identifier, bytes */
void* timePtr; /* time_t pointer */
byte* otherAttrOID; /* OPTIONAL, other attribute OID */
word32 otherAttrOIDSz; /* size of otherAttrOID, bytes */
byte* otherAttr; /* OPTIONAL, other attribute, ASN.1 encoded */
word32 otherAttrSz; /* size of otherAttr, bytes */
const char* outFileName;
} pkcs7EnvelopedVector;
@ -18973,27 +18985,44 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
};
#endif /* NO_AES */
#if !defined(NO_AES) && !defined(NO_SHA) && defined(WOLFSSL_AES_128)
/* encryption key for kekri recipient types */
byte secretKey[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
};
/* encryption key identifier */
byte secretKeyId[] = {
0x02,0x02,0x03,0x04
};
#endif
const pkcs7EnvelopedVector testVectors[] =
{
/* key transport key encryption technique */
#ifndef NO_RSA
#ifndef NO_DES3
{data, (word32)sizeof(data), DATA, DES3b, 0, 0, rsaCert, rsaCertSz,
rsaPrivKey, rsaPrivKeySz, NULL, 0, "pkcs7envelopedDataDES3.der"},
rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0,
NULL, 0, "pkcs7envelopedDataDES3.der"},
#endif
#ifndef NO_AES
#ifdef WOLFSSL_AES_128
{data, (word32)sizeof(data), DATA, AES128CBCb, 0, 0, rsaCert, rsaCertSz,
rsaPrivKey, rsaPrivKeySz, NULL, 0, "pkcs7envelopedDataAES128CBC.der"},
rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0,
NULL, 0, "pkcs7envelopedDataAES128CBC.der"},
#endif
#ifdef WOLFSSL_AES_192
{data, (word32)sizeof(data), DATA, AES192CBCb, 0, 0, rsaCert, rsaCertSz,
rsaPrivKey, rsaPrivKeySz, NULL, 0, "pkcs7envelopedDataAES192CBC.der"},
rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0,
NULL, 0, "pkcs7envelopedDataAES192CBC.der"},
#endif
#ifdef WOLFSSL_AES_256
{data, (word32)sizeof(data), DATA, AES256CBCb, 0, 0, rsaCert, rsaCertSz,
rsaPrivKey, rsaPrivKeySz, NULL, 0, "pkcs7envelopedDataAES256CBC.der"},
rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0,
NULL, 0, "pkcs7envelopedDataAES256CBC.der"},
#endif
#endif /* NO_AES */
#endif
@ -19004,31 +19033,42 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
#if !defined(NO_SHA) && defined(WOLFSSL_AES_128)
{data, (word32)sizeof(data), DATA, AES128CBCb, AES128_WRAP,
dhSinglePass_stdDH_sha1kdf_scheme, eccCert, eccCertSz, eccPrivKey,
eccPrivKeySz, NULL, 0,
eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0,
"pkcs7envelopedDataAES128CBC_ECDH_SHA1KDF.der"},
#endif
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_256)
{data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP,
dhSinglePass_stdDH_sha256kdf_scheme, eccCert, eccCertSz, eccPrivKey,
eccPrivKeySz, NULL, 0,
eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0,
"pkcs7envelopedDataAES256CBC_ECDH_SHA256KDF.der"},
#endif /* NO_SHA256 && WOLFSSL_AES_256 */
#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_AES_256)
{data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP,
dhSinglePass_stdDH_sha512kdf_scheme, eccCert, eccCertSz, eccPrivKey,
eccPrivKeySz, NULL, 0,
eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0,
"pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF.der"},
/* with optional user keying material (ukm) */
{data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP,
dhSinglePass_stdDH_sha512kdf_scheme, eccCert, eccCertSz, eccPrivKey,
eccPrivKeySz, optionalUkm, sizeof(optionalUkm),
eccPrivKeySz, optionalUkm, sizeof(optionalUkm), NULL, 0,
NULL, 0, NULL, NULL, 0, NULL, 0,
"pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF_ukm.der"},
#endif /* WOLFSSL_SHA512 && WOLFSSL_AES_256 */
#endif /* NO_AES */
#endif
/* kekri (KEKRecipientInfo) recipient types */
#ifndef NO_AES
#if !defined(NO_SHA) && defined(WOLFSSL_AES_128)
{data, (word32)sizeof(data), DATA, AES128CBCb, AES128_WRAP, 0,
NULL, 0, NULL, 0, NULL, 0, secretKey, sizeof(secretKey),
secretKeyId, sizeof(secretKeyId), NULL, NULL, 0, NULL, 0,
"pkcs7envelopedDataAES128CBC_KEKRI.der"},
#endif
#endif
};
testSz = sizeof(testVectors) / sizeof(pkcs7EnvelopedVector);
@ -19044,23 +19084,61 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
if (pkcs7 == NULL)
return -9214;
ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert,
(word32)testVectors[i].certSz);
if (ret != 0) {
wc_PKCS7_Free(pkcs7);
return -9215;
}
if (testVectors[i].secretKey != NULL) {
/* KEKRI recipient type */
pkcs7->content = (byte*)testVectors[i].content;
pkcs7->contentSz = testVectors[i].contentSz;
pkcs7->contentOID = testVectors[i].contentOID;
pkcs7->encryptOID = testVectors[i].encryptOID;
pkcs7->keyWrapOID = testVectors[i].keyWrapOID;
pkcs7->keyAgreeOID = testVectors[i].keyAgreeOID;
pkcs7->privateKey = testVectors[i].privateKey;
pkcs7->privateKeySz = testVectors[i].privateKeySz;
pkcs7->ukm = testVectors[i].optionalUkm;
pkcs7->ukmSz = testVectors[i].optionalUkmSz;
ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId);
if (ret != 0) {
return -9215;
}
pkcs7->content = (byte*)testVectors[i].content;
pkcs7->contentSz = testVectors[i].contentSz;
pkcs7->contentOID = testVectors[i].contentOID;
pkcs7->encryptOID = testVectors[i].encryptOID;
pkcs7->ukm = testVectors[i].optionalUkm;
pkcs7->ukmSz = testVectors[i].optionalUkmSz;
ret = wc_PKCS7_AddRecipient_KEKRI(pkcs7, testVectors[i].keyWrapOID,
testVectors[i].secretKey, testVectors[i].secretKeySz,
testVectors[i].secretKeyId, testVectors[i].secretKeyIdSz,
testVectors[i].timePtr, testVectors[i].otherAttrOID,
testVectors[i].otherAttrOIDSz, testVectors[i].otherAttr,
testVectors[i].otherAttrSz);
if (ret < 0) {
wc_PKCS7_Free(pkcs7);
return -9216;
}
/* set key, for decryption */
ret = wc_PKCS7_SetKey(pkcs7, testVectors[i].secretKey,
testVectors[i].secretKeySz);
if (ret != 0) {
wc_PKCS7_Free(pkcs7);
return -9217;
}
} else {
/* KTRI or KARI recipient types */
ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert,
(word32)testVectors[i].certSz);
if (ret != 0) {
wc_PKCS7_Free(pkcs7);
return -9218;
}
pkcs7->keyWrapOID = testVectors[i].keyWrapOID;
pkcs7->keyAgreeOID = testVectors[i].keyAgreeOID;
pkcs7->privateKey = testVectors[i].privateKey;
pkcs7->privateKeySz = testVectors[i].privateKeySz;
pkcs7->content = (byte*)testVectors[i].content;
pkcs7->contentSz = testVectors[i].contentSz;
pkcs7->contentOID = testVectors[i].contentOID;
pkcs7->encryptOID = testVectors[i].encryptOID;
pkcs7->ukm = testVectors[i].optionalUkm;
pkcs7->ukmSz = testVectors[i].optionalUkmSz;
}
/* encode envelopedData */
envelopedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, enveloped,
@ -19068,36 +19146,39 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
if (envelopedSz <= 0) {
printf("DEBUG: i = %d, envelopedSz = %d\n", i, envelopedSz);
wc_PKCS7_Free(pkcs7);
return -9216;
return -9219;
}
/* decode envelopedData */
printf("CHRIS: Trying to decode: %s\n", testVectors[i].outFileName);
decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, enveloped, envelopedSz,
decoded, sizeof(decoded));
if (decodedSz <= 0) {
wc_PKCS7_Free(pkcs7);
return -9217;
return -9220;
}
/* test decode result */
if (XMEMCMP(decoded, data, sizeof(data)) != 0){
wc_PKCS7_Free(pkcs7);
return -9218;
return -9221;
}
(void)decoded;
(void)decodedSz;
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
/* output pkcs7 envelopedData for external testing */
pkcs7File = fopen(testVectors[i].outFileName, "wb");
if (!pkcs7File) {
wc_PKCS7_Free(pkcs7);
return -9219;
return -9222;
}
ret = (int)fwrite(enveloped, 1, envelopedSz, pkcs7File);
fclose(pkcs7File);
if (ret != envelopedSz) {
wc_PKCS7_Free(pkcs7);
return -9220;
return -9223;
}
#endif /* PKCS7_OUTPUT_TEST_BUNDLES */
@ -19110,6 +19191,8 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
(void)eccCertSz;
(void)eccPrivKey;
(void)eccPrivKeySz;
(void)secretKey;
(void)secretKeyId;
#endif
#ifdef NO_RSA
(void)rsaCert;
@ -19117,7 +19200,6 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
(void)rsaPrivKey;
(void)rsaPrivKeySz;
#endif
return 0;
}

View File

@ -992,7 +992,7 @@ typedef struct tm wolfssl_tm;
WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len);
#endif
#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
WOLFSSL_LOCAL int GetAsnTimeString(byte* buf, word32 len);
WOLFSSL_LOCAL int GetAsnTimeString(void* currTime, byte* buf, word32 len);
#endif
WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format,
wolfssl_tm* certTime, int* idx);

View File

@ -48,7 +48,7 @@
/* Max number of certificates that PKCS7 structure can parse */
#ifndef MAX_PKCS7_CERTS
#define MAX_PKCS7_CERTS 4
#define MAX_PKCS7_CERTS 4
#endif
/* PKCS#7 content types, ref RFC 2315 (Section 14) */
@ -86,6 +86,15 @@ enum Pkcs7_SignerIdentifier_Types {
SID_SUBJECT_KEY_IDENTIFIER = 1
};
/* CMS/PKCS#7 RecipientInfo types, RFC 5652, Section 6.2 */
enum Pkcs7_RecipientInfo_Types {
PKCS7_KTRI = 0,
PKCS7_KARI = 1,
PKCS7_KEKRI = 2,
PKCS7_PWRI = 3,
PKCS7_ORI = 4
};
typedef struct PKCS7Attrib {
const byte* oid;
word32 oidSz;
@ -103,6 +112,7 @@ typedef struct PKCS7DecodedAttrib {
} PKCS7DecodedAttrib;
typedef struct Pkcs7Cert Pkcs7Cert;
typedef struct Pkcs7EncodedRecip Pkcs7EncodedRecip;
/* Public Structure Warning:
* Existing members must not be changed to maintain backwards compatibility!
@ -164,6 +174,9 @@ typedef struct PKCS7 {
SID_ISSUER_AND_SERIAL_NUMBER */
byte issuerSubjKeyId[KEYID_SIZE]; /* SubjectKeyIdentifier of singleCert */
Pkcs7Cert* certList; /* certificates list for SignedData set */
Pkcs7EncodedRecip* recipList; /* recipients list */
byte* cek; /* content encryption key, random, dynamic */
word32 cekSz; /* size of cek, bytes */
/* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */
} PKCS7;
@ -177,8 +190,19 @@ WOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7);
WOLFSSL_API int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid,
word32 oidSz, byte* out, word32* outSz);
WOLFSSL_API int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type);
WOLFSSL_API int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType,
word32 sz);
WOLFSSL_API int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz);
WOLFSSL_API int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
word32 blockSz);
/* CMS/PKCS#7 Data */
WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
word32 outputSz);
/* CMS/PKCS#7 SignedData */
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
@ -190,19 +214,28 @@ WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
word32 pkiMsgFootSz);
/* CMS/PKCS#7 EnvelopedData */
WOLFSSL_API int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert,
word32 certSz);
WOLFSSL_API int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert,
word32 certSz, int keyWrapOID,
int keyAgreeOID, byte* ukm,
word32 ukmSz);
WOLFSSL_API int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID,
byte* kek, word32 kekSz,
byte* keyID, word32 keyIdSz,
void* timePtr, byte* otherOID,
word32 otherOIDSz, byte* other,
word32 otherSz);
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz);
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
word32 pkiMsgSz, byte* output,
word32 outputSz);
WOLFSSL_API int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type);
WOLFSSL_API int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType,
word32 sz);
WOLFSSL_API int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz);
WOLFSSL_API int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
word32 blockSz);
/* CMS/PKCS#7 EncryptedData */
#ifndef NO_PKCS7_ENCRYPTED_DATA
WOLFSSL_API int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7,
byte* output, word32 outputSz);
@ -211,6 +244,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg,
word32 outputSz);
#endif /* NO_PKCS7_ENCRYPTED_DATA */
/* CMS/PKCS#7 CompressedData */
#ifdef HAVE_LIBZ
WOLFSSL_API int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output,
word32 outputSz);