diff --git a/.gitignore b/.gitignore index ebfc8c475..c9629d289 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,8 @@ key.der key.pem certreq.der certreq.pem +pkcs7test.der +pkcs7test.pem diff sslSniffer/sslSnifferTest/tracefile.txt *.gz diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 1874e36c8..af42451d3 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -2278,6 +2278,12 @@ CYASSL_LOCAL word32 SetSet(word32 len, byte* output) return SetLength(len, output + 1) + 1; } +CYASSL_LOCAL word32 SetTagged(byte tag, word32 len, byte* output) +{ + output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | tag; + return SetLength(len, output + 1) + 1; +} + #if defined(HAVE_ECC) && defined(CYASSL_CERT_GEN) diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index c23e2b39a..960389309 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -30,6 +30,14 @@ #include #include #include +#include + +#ifndef min + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } +#endif CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output) { @@ -109,11 +117,31 @@ CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output) int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) { - XMEMSET(pkcs7, 0, sizeof(PKCS7)); - pkcs7->singleCert = cert; - pkcs7->singleCertSz = certSz; + int ret = 0; - return 0; + XMEMSET(pkcs7, 0, sizeof(PKCS7)); + if (cert != NULL && certSz > 0) { + DecodedCert dCert; + + pkcs7->singleCert = cert; + pkcs7->singleCertSz = certSz; + InitDecodedCert(&dCert, cert, certSz, 0); + + ret = ParseCert(&dCert, CA_TYPE, NO_VERIFY, 0); + if (ret < 0) { + FreeDecodedCert(&dCert); + return ret; + } + XMEMCPY(pkcs7->publicKey, dCert.publicKey, dCert.pubKeySize); + pkcs7->publicKeySz = dCert.pubKeySize; + pkcs7->issuer = dCert.issuerRaw; + pkcs7->issuerSz = dCert.issuerRawLen; + XMEMCPY(pkcs7->issuerSn, dCert.serial, dCert.serialSz); + pkcs7->issuerSnSz = dCert.serialSz; + FreeDecodedCert(&dCert); + } + + return ret; } @@ -126,18 +154,19 @@ int PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz) byte octetStr[MAX_OCTET_STR_SZ]; word32 seqSz; word32 octetStrSz; + word32 oidSz = (word32)sizeof(oid); int idx = 0; octetStrSz = SetOctetString(pkcs7->contentSz, octetStr); - seqSz = SetSequence(pkcs7->contentSz + octetStrSz + sizeof(oid), seq); + seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq); - if (outputSz < pkcs7->contentSz + octetStrSz + sizeof(oid) + seqSz) + if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz) return BUFFER_E; XMEMCPY(output, seq, seqSz); idx += seqSz; - XMEMCPY(output + idx, oid, sizeof(oid)); - idx += sizeof(oid); + XMEMCPY(output + idx, oid, oidSz); + idx += oidSz; XMEMCPY(output + idx, octetStr, octetStrSz); idx += octetStrSz; XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); @@ -147,12 +176,325 @@ int PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz) } +typedef struct EncodedAttrib { + byte valueSeq[MAX_SEQ_SZ]; + const byte* oid; + byte valueSet[MAX_SET_SZ]; + const byte* value; + word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz; +} EncodedAttrib; + + +typedef struct ESD { + Sha sha; + byte contentDigest[SHA_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */ + byte contentAttribsDigest[SHA_DIGEST_SIZE]; /* content + attribs */ + byte encContentDigest[512]; + + byte outerSeq[MAX_SEQ_SZ]; + byte outerContent[MAX_EXP_SZ]; + byte innerSeq[MAX_SEQ_SZ]; + byte version[MAX_VERSION_SZ]; + byte digAlgoIdSet[MAX_SET_SZ]; + byte singleDigAlgoId[MAX_ALGO_SZ]; + + byte contentInfoSeq[MAX_SEQ_SZ]; + byte innerContSeq[MAX_EXP_SZ]; + byte innerOctets[MAX_OCTET_STR_SZ]; + + byte certsSet[MAX_SET_SZ]; + + byte signerInfoSet[MAX_SET_SZ]; + byte signerInfoSeq[MAX_SEQ_SZ]; + byte signerVersion[MAX_VERSION_SZ]; + byte issuerSnSeq[MAX_SEQ_SZ]; + byte issuerName[MAX_SEQ_SZ]; + byte issuerSn[MAX_SN_SZ]; + byte signerDigAlgoId[MAX_ALGO_SZ]; + byte digEncAlgoId[MAX_ALGO_SZ]; + byte signedAttribSet[MAX_SET_SZ]; + EncodedAttrib signedAttribs[6]; + byte signerDigest[MAX_OCTET_STR_SZ]; + word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz; + word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz, + singleDigAlgoIdSz, certsSetSz; + word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz, + issuerSnSeqSz, issuerNameSz, issuerSnSz, + signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz; + word32 encContentDigestSz, signedAttribsSz, signedAttribsCount, + signedAttribSetSz; +} ESD; + + +static int EncodeAttributes(EncodedAttrib* ea, int eaSz, + PKCS7Attrib* attribs, int attribsSz) +{ + int i; + int maxSz = min(eaSz, attribsSz); + int allAttribsSz = 0; + + for (i = 0; i < maxSz; i++) + { + int attribSz = 0; + + ea[i].value = attribs[i].value; + ea[i].valueSz = attribs[i].valueSz; + attribSz += ea[i].valueSz; + ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet); + attribSz += ea[i].valueSetSz; + ea[i].oid = attribs[i].oid; + ea[i].oidSz = attribs[i].oidSz; + attribSz += ea[i].oidSz; + ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq); + attribSz += ea[i].valueSeqSz; + ea[i].totalSz = attribSz; + + allAttribsSz += attribSz; + } + return allAttribsSz; +} + + +static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz) +{ + int i, idx; + + idx = 0; + for (i = 0; i < eaSz; i++) { + XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz); + idx += ea[i].valueSeqSz; + XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz); + idx += ea[i].oidSz; + XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz); + idx += ea[i].valueSetSz; + XMEMCPY(output + idx, ea[i].value, ea[i].valueSz); + idx += ea[i].valueSz; + } + return 0; +} + + int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { - (void)pkcs7; - (void)output; - (void)outputSz; - return 0; + static const byte outerOid[] = + { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x07, 0x02 }; + static const byte innerOid[] = + { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x07, 0x01 }; + + ESD esd; + word32 signerInfoSz = 0; + word32 totalSz = 0; + int idx = 0; + byte* flatSignedAttribs = NULL; + word32 flatSignedAttribsSz = 0; + + XMEMSET(&esd, 0, sizeof(esd)); + InitSha(&esd.sha); + + if (pkcs7->contentSz != 0) + { + ShaUpdate(&esd.sha, pkcs7->content, pkcs7->contentSz); + esd.contentDigest[0] = ASN_OCTET_STRING; + esd.contentDigest[1] = SHA_DIGEST_SIZE; + ShaFinal(&esd.sha, &esd.contentDigest[2]); + } + + esd.innerOctetsSz = SetOctetString(pkcs7->contentSz, esd.innerOctets); + esd.innerContSeqSz = SetTagged(0, esd.innerOctetsSz + pkcs7->contentSz, + esd.innerContSeq); + esd.contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd.innerOctetsSz + + sizeof(innerOid) + esd.innerContSeqSz, + esd.contentInfoSeq); + + esd.issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, + esd.issuerSn); + signerInfoSz += esd.issuerSnSz; + esd.issuerNameSz = SetSequence(pkcs7->issuerSz, esd.issuerName); + signerInfoSz += esd.issuerNameSz + pkcs7->issuerSz; + esd.issuerSnSeqSz = SetSequence(signerInfoSz, esd.issuerSnSeq); + signerInfoSz += esd.issuerSnSeqSz; + esd.signerVersionSz = SetMyVersion(1, esd.signerVersion, 0); + signerInfoSz += esd.signerVersionSz; + esd.signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.signerDigAlgoId, + hashType, 0); + signerInfoSz += esd.signerDigAlgoIdSz; + esd.digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd.digEncAlgoId, + keyType, 0); + signerInfoSz += esd.digEncAlgoIdSz; + + if (pkcs7->signedAttribsSz != 0) { + byte contentTypeOid[] = + { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, + 0x09, 0x03 }; + byte contentType[] = + { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x07, 0x01 }; + byte messageDigestOid[] = + { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x04 }; + + PKCS7Attrib cannedAttribs[2] = + { + { contentTypeOid, sizeof(contentTypeOid), + contentType, sizeof(contentType) }, + { messageDigestOid, sizeof(messageDigestOid), + esd.contentDigest, sizeof(esd.contentDigest) } + }; + word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); + + esd.signedAttribsCount += cannedAttribsCount; + esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[0], 2, + cannedAttribs, cannedAttribsCount); + + esd.signedAttribsCount += pkcs7->signedAttribsSz; + esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[2], 4, + pkcs7->signedAttribs, pkcs7->signedAttribsSz); + + flatSignedAttribs = (byte*)XMALLOC(esd.signedAttribsSz, 0, NULL); + flatSignedAttribsSz = esd.signedAttribsSz; + if (flatSignedAttribs == NULL) + return MEMORY_E; + FlattenAttributes(flatSignedAttribs, + esd.signedAttribs, esd.signedAttribsCount); + esd.signedAttribSetSz = SetTagged(0, esd.signedAttribsSz, + esd.signedAttribSet); + } + /* Calculate the final hash and encrypt it. */ + { + RsaKey pubKey; + int result; + word32 scratch = 0; + + if (pkcs7->signedAttribsSz != 0) { + byte attribSet[MAX_SET_SZ]; + word32 attribSetSz; + + attribSetSz = SetSet(flatSignedAttribsSz, attribSet); + + ShaUpdate(&esd.sha, attribSet, attribSetSz); + ShaUpdate(&esd.sha, flatSignedAttribs, flatSignedAttribsSz); + } + ShaFinal(&esd.sha, esd.contentAttribsDigest); + + InitRsaKey(&pubKey, NULL); + result = RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &pubKey, + pkcs7->publicKeySz); + if (result < 0) { + XFREE(flatSignedAttribs, 0, NULL); + return PUBLIC_KEY_E; + } + result = RsaPublicEncrypt(esd.contentAttribsDigest, + sizeof(esd.contentAttribsDigest), + esd.encContentDigest, + sizeof(esd.encContentDigest), &pubKey, + pkcs7->rng); + FreeRsaKey(&pubKey); + if (result < 0) { + XFREE(flatSignedAttribs, 0, NULL); + return result; + } + esd.encContentDigestSz = (word32)result; + } + signerInfoSz += flatSignedAttribsSz + esd.signedAttribSetSz; + + esd.signerDigestSz = SetOctetString(esd.encContentDigestSz, + esd.signerDigest); + signerInfoSz += esd.signerDigestSz + esd.encContentDigestSz; + + esd.signerInfoSeqSz = SetSequence(signerInfoSz, esd.signerInfoSeq); + signerInfoSz += esd.signerInfoSeqSz; + esd.signerInfoSetSz = SetSet(signerInfoSz, esd.signerInfoSet); + signerInfoSz += esd.signerInfoSetSz; + + esd.certsSetSz = SetTagged(0, pkcs7->singleCertSz, esd.certsSet); + + esd.singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.singleDigAlgoId, + hashType, 0); + esd.digAlgoIdSetSz = SetSet(esd.singleDigAlgoIdSz, esd.digAlgoIdSet); + + + esd.versionSz = SetMyVersion(1, esd.version, 0); + + totalSz = esd.versionSz + esd.singleDigAlgoIdSz + esd.digAlgoIdSetSz + + esd.contentInfoSeqSz + esd.certsSetSz + pkcs7->singleCertSz + + esd.innerOctetsSz + esd.innerContSeqSz + + sizeof(innerOid) + pkcs7->contentSz + + signerInfoSz; + esd.innerSeqSz = SetSequence(totalSz, esd.innerSeq); + totalSz += esd.innerSeqSz; + esd.outerContentSz = SetTagged(0, totalSz, esd.outerContent); + totalSz += esd.outerContentSz + sizeof(outerOid); + esd.outerSeqSz = SetSequence(totalSz, esd.outerSeq); + totalSz += esd.outerSeqSz; + + if (outputSz < totalSz) + return BUFFER_E; + + idx = 0; + XMEMCPY(output + idx, esd.outerSeq, esd.outerSeqSz); + idx += esd.outerSeqSz; + XMEMCPY(output + idx, outerOid, sizeof(outerOid)); + idx += sizeof(outerOid); + XMEMCPY(output + idx, esd.outerContent, esd.outerContentSz); + idx += esd.outerContentSz; + XMEMCPY(output + idx, esd.innerSeq, esd.innerSeqSz); + idx += esd.innerSeqSz; + XMEMCPY(output + idx, esd.version, esd.versionSz); + idx += esd.versionSz; + XMEMCPY(output + idx, esd.digAlgoIdSet, esd.digAlgoIdSetSz); + idx += esd.digAlgoIdSetSz; + XMEMCPY(output + idx, esd.singleDigAlgoId, esd.singleDigAlgoIdSz); + idx += esd.singleDigAlgoIdSz; + XMEMCPY(output + idx, esd.contentInfoSeq, esd.contentInfoSeqSz); + idx += esd.contentInfoSeqSz; + XMEMCPY(output + idx, innerOid, sizeof(innerOid)); + idx += sizeof(innerOid); + XMEMCPY(output + idx, esd.innerContSeq, esd.innerContSeqSz); + idx += esd.innerContSeqSz; + XMEMCPY(output + idx, esd.innerOctets, esd.innerOctetsSz); + idx += esd.innerOctetsSz; + XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); + idx += pkcs7->contentSz; + XMEMCPY(output + idx, esd.certsSet, esd.certsSetSz); + idx += esd.certsSetSz; + XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz); + idx += pkcs7->singleCertSz; + XMEMCPY(output + idx, esd.signerInfoSet, esd.signerInfoSetSz); + idx += esd.signerInfoSetSz; + XMEMCPY(output + idx, esd.signerInfoSeq, esd.signerInfoSeqSz); + idx += esd.signerInfoSeqSz; + XMEMCPY(output + idx, esd.signerVersion, esd.signerVersionSz); + idx += esd.signerVersionSz; + XMEMCPY(output + idx, esd.issuerSnSeq, esd.issuerSnSeqSz); + idx += esd.issuerSnSeqSz; + XMEMCPY(output + idx, esd.issuerName, esd.issuerNameSz); + idx += esd.issuerNameSz; + XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz); + idx += pkcs7->issuerSz; + XMEMCPY(output + idx, esd.issuerSn, esd.issuerSnSz); + idx += esd.issuerSnSz; + XMEMCPY(output + idx, esd.signerDigAlgoId, esd.signerDigAlgoIdSz); + idx += esd.signerDigAlgoIdSz; + + /* SignerInfo:Attributes */ + if (pkcs7->signedAttribsSz != 0) { + XMEMCPY(output + idx, esd.signedAttribSet, esd.signedAttribSetSz); + idx += esd.signedAttribSetSz; + XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz); + idx += flatSignedAttribsSz; + XFREE(flatSignedAttribs, 0, NULL); + } + + XMEMCPY(output + idx, esd.digEncAlgoId, esd.digEncAlgoIdSz); + idx += esd.digEncAlgoIdSz; + XMEMCPY(output + idx, esd.signerDigest, esd.signerDigestSz); + idx += esd.signerDigestSz; + XMEMCPY(output + idx, esd.encContentDigest, esd.encContentDigestSz); + idx += esd.encContentDigestSz; + + return idx; } diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 3d0f52ae3..16588da4b 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -61,6 +61,9 @@ #ifdef HAVE_LIBZ #include #endif +#ifdef HAVE_PKCS7 + #include +#endif #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ @@ -174,6 +177,9 @@ int pbkdf2_test(void); #ifdef HAVE_LIBZ int compress_test(void); #endif +#ifdef HAVE_PKCS7 + int pkcs7_test(void); +#endif @@ -458,6 +464,13 @@ void ctaocrypt_test(void* args) printf( "COMPRESS test passed!\n"); #endif +#ifdef HAVE_PKCS7 + if ( (ret = pkcs7_test()) != 0) + err_sys("PKCS7 test failed!\n", ret); + else + printf( "PKCS7 test passed!\n"); +#endif + ((func_args*)args)->return_code = ret; } @@ -4009,4 +4022,118 @@ int compress_test(void) #endif /* HAVE_LIBZ */ +#ifdef HAVE_PKCS7 + +int pkcs7_test(void) +{ + int ret = 0; + byte* cert; + byte out[2048]; + char data[] = "Hello World"; + word32 dataSz, outSz; + PKCS7 msg; + RNG rng; + + word32 certSz; + FILE* file; + FILE* pkcs7File; + + byte transIdOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x07 }; + byte messageTypeOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x02 }; + byte senderNonceOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x05 }; + byte pkiStatusOid[] = + { 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, + 0x09, 0x03 }; + byte transId[(SHA_DIGEST_SIZE + 1) * 2 + 1]; + byte messageType[] = { 0x13, 2, '1', '9' }; + byte senderNonce[34]; + byte pkiStatus[] = { 0x13, 1, '0' }; + + PKCS7Attrib attribs[] = + { + { transIdOid, sizeof(transIdOid), + transId, sizeof(transId) - 1 }, /* take off the null */ + { messageTypeOid, sizeof(messageTypeOid), + messageType, sizeof(messageType) }, + { senderNonceOid, sizeof(senderNonceOid), + senderNonce, sizeof(senderNonce) }, + { pkiStatusOid, sizeof(pkiStatusOid), + pkiStatus, sizeof(pkiStatus) } + }; + + dataSz = (word32) strlen(data); + outSz = sizeof(out); + + cert = (byte*)malloc(FOURK_BUF); + if (cert == NULL) + return -40; + + /* read in DER cert of recipient, into cert of size certSz */ + file = fopen(clientCert, "rb"); + + if (!file) + err_sys("can't open ./certs/client-cert.der, " + "Please run from CyaSSL home dir", -40); + + certSz = (word32)fread(cert, 1, FOURK_BUF, file); + fclose(file); + + ret = InitRng(&rng); + senderNonce[0] = 0x04; + senderNonce[1] = 0x20; + RNG_GenerateBlock(&rng, &senderNonce[2], 32); + + PKCS7_InitWithCert(&msg, cert, certSz); + msg.content = (byte*)data; + msg.contentSz = dataSz; + msg.hashOID = SHAh; + msg.encryptOID = RSAk; + msg.signedAttribs = attribs; + msg.signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib); + msg.rng = &rng; + { + Sha sha; + byte digest[SHA_DIGEST_SIZE]; + int i,j; + + transId[0] = 0x13; + transId[1] = SHA_DIGEST_SIZE * 2; + + InitSha(&sha); + ShaUpdate(&sha, msg.publicKey, msg.publicKeySz); + ShaFinal(&sha, digest); + + for (i = 0, j = 2; i < SHA_DIGEST_SIZE; i++, j += 2) { + snprintf((char*)&transId[j], 3, "%02x", digest[i]); + } + } + ret = PKCS7_EncodeSignedData(&msg, out, outSz); + if (ret < 0) { + printf("Pkcs7_encrypt failed\n"); + return -42; + } + else + outSz = ret; + + /* write PKCS#7 to output file for more testing */ + pkcs7File = fopen("./pkcs7test.der", "wb"); + if (!pkcs7File) + return -43; + ret = (int)fwrite(out, outSz, 1, pkcs7File); + fclose(pkcs7File); + + if (ret > 0) + return 0; + + return ret; +} + +#endif /* HAVE_PKCS7 */ + #endif /* NO_CRYPT_TEST */ diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 121af0aef..1373c46e4 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -127,6 +127,7 @@ enum Misc_ASN { MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */ MAX_SET_SZ = 5, /* enum(set | con) + length(4) */ MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */ + MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */ MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */ MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/ MAX_ENCODED_DIG_SZ = 73, /* sha512 + enum(bit or octet) + legnth(4) */ @@ -448,6 +449,7 @@ CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, CYASSL_LOCAL word32 SetLength(word32 length, byte* output); CYASSL_LOCAL word32 SetSequence(word32 len, byte* output); CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output); +CYASSL_LOCAL word32 SetTagged(byte tag, word32 len, byte* output); CYASSL_LOCAL word32 SetSet(word32 len, byte* output); CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header); diff --git a/cyassl/ctaocrypt/pkcs7.h b/cyassl/ctaocrypt/pkcs7.h index 496c7321f..4cd984b12 100644 --- a/cyassl/ctaocrypt/pkcs7.h +++ b/cyassl/ctaocrypt/pkcs7.h @@ -67,6 +67,8 @@ typedef struct PKCS7 { word32 contentSz; int contentOID; + RNG* rng; + int hashOID; int encryptOID; @@ -74,9 +76,13 @@ typedef struct PKCS7 { word32 singleCertSz; byte* issuer; word32 issuerSz; + byte issuerSn[MAX_SN_SZ]; + word32 issuerSnSz; + byte publicKey[512]; + word32 publicKeySz; - PKCS7Attrib** signedAttribs; - word32 signedAttribsSz; /* Number of attribs in list */ + PKCS7Attrib* signedAttribs; + word32 signedAttribsSz; } PKCS7;