From c4eb5642b15830ae67790b35f609aabfeedf7c89 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 17 Jan 2014 14:07:40 -0800 Subject: [PATCH] 1. Sign the PKCS#7 with a supplied private key, not the single cert's public key. 2. Rename PKCS7 Envelope Data function as `PKCS7_EncodeEnvelopedData()`. 3. Encode signed data to check input parameters. --- ctaocrypt/src/pkcs7.c | 27 +++++++++------ ctaocrypt/test/test.c | 74 +++++++++++++++++++++++++++------------- cyassl/ctaocrypt/pkcs7.h | 16 ++++----- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index 6a92aaa13..48b5adf5f 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -326,6 +326,13 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) word32 innerOidSz = sizeof(innerOid); word32 outerOidSz = sizeof(outerOid); + if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || + pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 || + pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 || + pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 || + output == NULL || outputSz == 0) + return BAD_FUNC_ARG; + XMEMSET(&esd, 0, sizeof(esd)); InitSha(&esd.sha); @@ -399,7 +406,7 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* Calculate the final hash and encrypt it. */ { - RsaKey pubKey; + RsaKey privKey; int result; word32 scratch = 0; @@ -414,19 +421,19 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) } ShaFinal(&esd.sha, esd.contentAttribsDigest); - InitRsaKey(&pubKey, NULL); - result = RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &pubKey, - pkcs7->publicKeySz); + InitRsaKey(&privKey, NULL); + result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey, + pkcs7->privateKeySz); if (result < 0) { XFREE(flatSignedAttribs, 0, NULL); return PUBLIC_KEY_E; } - result = RsaPublicEncrypt(esd.contentAttribsDigest, + result = RsaSSL_Sign(esd.contentAttribsDigest, sizeof(esd.contentAttribsDigest), esd.encContentDigest, - sizeof(esd.encContentDigest), &pubKey, + sizeof(esd.encContentDigest), &privKey, pkcs7->rng); - FreeRsaKey(&pubKey); + FreeRsaKey(&privKey); if (result < 0) { XFREE(flatSignedAttribs, 0, NULL); return result; @@ -649,7 +656,7 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, /* build PKCS#7 envelopedData content type, return enveloped size */ -int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz) +int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) { int i, idx = 0; int totalSz = 0, padSz = 0, desOutSz = 0; @@ -888,7 +895,7 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, if (pkcs7 == NULL || pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL || - pkcs7->privKeySize == 0) + pkcs7->privateKeySz == 0) return BAD_FUNC_ARG; if (pkiMsg == NULL || pkiMsgSz == 0 || @@ -906,7 +913,7 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, /* load private key */ InitRsaKey(&privKey, 0); ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey, - pkcs7->privKeySize); + pkcs7->privateKeySz); if (ret != 0) { CYASSL_MSG("Failed to decode RSA private key"); return ret; diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 010b62e12..80fb90e06 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -4085,11 +4085,11 @@ int pkcs7enveloped_test(void) pkcs7.contentOID = DATA; pkcs7.encryptOID = cipher; pkcs7.privateKey = privKey; - pkcs7.privKeySize = (word32)privKeySz; + pkcs7.privateKeySz = (word32)privKeySz; /* encode envelopedData */ - envelopedSz = PKCS7_EncodeEnvelopeData(&pkcs7, enveloped, - sizeof(enveloped)); + envelopedSz = PKCS7_EncodeEnvelopedData(&pkcs7, enveloped, + sizeof(enveloped)); if (envelopedSz <= 0) return -203; @@ -4125,17 +4125,15 @@ int pkcs7signed_test(void) { int ret = 0; - byte* cert; - byte out[2048]; + FILE* file; + byte* certDer; + byte* keyDer; + byte* out; char data[] = "Hello World"; - word32 dataSz, outSz; + word32 dataSz, outSz, certDerSz, keyDerSz; PKCS7 msg; RNG rng; - word32 certSz; - FILE* file; - FILE* pkcs7File; - byte transIdOid[] = { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07 }; @@ -4166,20 +4164,40 @@ int pkcs7signed_test(void) }; dataSz = (word32) strlen(data); - outSz = sizeof(out); + outSz = FOURK_BUF; - cert = (byte*)malloc(FOURK_BUF); - if (cert == NULL) + certDer = (byte*)malloc(FOURK_BUF); + keyDer = (byte*)malloc(FOURK_BUF); + out = (byte*)malloc(FOURK_BUF); + + if (certDer == NULL) return -207; + if (keyDer == NULL) + return -208; + if (out == NULL) + return -209; /* read in DER cert of recipient, into cert of size certSz */ file = fopen(clientCert, "rb"); - - if (!file) + if (!file) { + free(certDer); + free(keyDer); + free(out); err_sys("can't open ./certs/client-cert.der, " "Please run from CyaSSL home dir", -44); + } + certDerSz = (word32)fread(certDer, 1, FOURK_BUF, file); + fclose(file); - certSz = (word32)fread(cert, 1, FOURK_BUF, file); + file = fopen(clientKey, "rb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + err_sys("can't open ./certs/client-key.der, " + "Please run from CyaSSL home dir", -45); + } + keyDerSz = (word32)fread(keyDer, 1, FOURK_BUF, file); fclose(file); ret = InitRng(&rng); @@ -4187,7 +4205,9 @@ int pkcs7signed_test(void) senderNonce[1] = 0x20; RNG_GenerateBlock(&rng, &senderNonce[2], 32); - PKCS7_InitWithCert(&msg, cert, certSz); + PKCS7_InitWithCert(&msg, certDer, certDerSz); + msg.privateKey = keyDer; + msg.privateKeySz = keyDerSz; msg.content = (byte*)data; msg.contentSz = dataSz; msg.hashOID = SHAh; @@ -4213,17 +4233,25 @@ int pkcs7signed_test(void) } ret = PKCS7_EncodeSignedData(&msg, out, outSz); if (ret < 0) { - return -208; + return -210; } else outSz = ret; /* write PKCS#7 to output file for more testing */ - pkcs7File = fopen("./pkcs7signedData.der", "wb"); - if (!pkcs7File) - return -209; - ret = (int)fwrite(out, outSz, 1, pkcs7File); - fclose(pkcs7File); + file = fopen("./pkcs7signedData.der", "wb"); + if (!file) { + free(certDer); + free(keyDer); + free(out); + return -211; + } + ret = (int)fwrite(out, outSz, 1, file); + fclose(file); + + free(certDer); + free(keyDer); + free(out); if (ret > 0) return 0; diff --git a/cyassl/ctaocrypt/pkcs7.h b/cyassl/ctaocrypt/pkcs7.h index 8dad31748..f060dc11d 100644 --- a/cyassl/ctaocrypt/pkcs7.h +++ b/cyassl/ctaocrypt/pkcs7.h @@ -75,14 +75,14 @@ typedef struct PKCS7 { byte* singleCert; /* recipient cert, DER, not owner */ word32 singleCertSz; /* size of recipient cert buffer, bytes */ - byte* issuer; - word32 issuerSz; - byte* privateKey; /* recipient private key, DER, not owner */ - word32 privKeySize; /* size of private key buffer, bytes */ - byte issuerSn[MAX_SN_SZ]; - word32 issuerSnSz; + byte* issuer; /* issuer name of singleCert */ + word32 issuerSz; /* length of issuer name */ + byte issuerSn[MAX_SN_SZ]; /* singleCert's serial number */ + word32 issuerSnSz; /* length of serial number */ byte publicKey[512]; word32 publicKeySz; + byte* privateKey; /* private key, DER, not owner */ + word32 privateKeySz; /* size of private key buffer, bytes */ PKCS7Attrib* signedAttribs; word32 signedAttribsSz; @@ -102,8 +102,8 @@ CYASSL_API int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz); CYASSL_API int PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz); CYASSL_API int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz); -CYASSL_API int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, - byte* output, word32 outputSz); +CYASSL_API int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, + byte* output, word32 outputSz); CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, byte* output, word32 outputSz);