diff --git a/allow-content-types-beyond-smime.patch b/allow-content-types-beyond-smime.patch new file mode 100644 index 0000000..ca350fc --- /dev/null +++ b/allow-content-types-beyond-smime.patch @@ -0,0 +1,2282 @@ +Index: ./mozilla/security/nss/lib/smime/cms.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cms.h,v +retrieving revision 1.23 +retrieving revision 1.25 +diff -u -p -r1.23 -r1.25 +--- ./mozilla/security/nss/lib/smime/cms.h 25 Apr 2010 23:37:38 -0000 1.23 ++++ ./mozilla/security/nss/lib/smime/cms.h 31 Jan 2011 23:56:29 -0000 1.25 +@@ -37,7 +37,7 @@ + /* + * Interfaces of the CMS implementation. + * +- * $Id: cms.h,v 1.23 2010/04/25 23:37:38 nelson%bolyard.com Exp $ ++ * $Id: cms.h,v 1.25 2011/01/31 23:56:29 rrelyea%redhat.com Exp $ + */ + + #ifndef _CMS_H_ +@@ -303,6 +303,14 @@ extern SECStatus + NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd); + + /* ++ * turn off streaming for this content type. ++ * This could fail with SEC_ERROR_NO_MEMORY in memory constrained conditions. ++ */ ++extern SECStatus ++NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream); ++ ++ ++/* + * NSS_CMSContentInfo_GetContent - get pointer to inner content + * + * needs to be casted... +@@ -1128,6 +1136,51 @@ NSS_CMSDEREncode(NSSCMSMessage *cmsg, SE + PLArenaPool *arena); + + ++/************************************************************************ ++ * ++ ************************************************************************/ ++ ++/* ++ * define new S/MIME content type entries ++ * ++ * S/MIME uses the builtin PKCS7 oid types for encoding and decoding the ++ * various S/MIME content. Some applications have their own content type ++ * which is different from the standard content type defined by S/MIME. ++ * ++ * This function allows you to register new content types. There are basically ++ * Two different types of content, Wrappping content, and Data. ++ * ++ * For data types, All the functions below can be zero or NULL excext ++ * type and is isData, which should be your oid tag and PR_FALSE respectively ++ * ++ * For wrapping types, everything must be provided, or you will get encoder ++ * failures. ++ * ++ * If NSS doesn't already define the OID that you need, you can register ++ * your own with SECOID_AddEntry. ++ * ++ * Once you have defined your new content type, you can pass your new content ++ * type to NSS_CMSContentInfo_SetContent(). ++ * ++ * If you are using a wrapping type you can pass your own data structure in ++ * the ptr field, but it must contain and embedded NSSCMSGenericWrappingData ++ * structure as the first element. The size you pass to ++ * NSS_CMSType_RegisterContentType is the total size of your self defined ++ * data structure. NSS_CMSContentInfo_GetContent will return that data ++ * structure from the content info. Your ASN1Template will be evaluated ++ * against that data structure. ++ */ ++SECStatus NSS_CMSType_RegisterContentType(SECOidTag type, ++ SEC_ASN1Template *template, size_t size, ++ NSSCMSGenericWrapperDataDestroy destroy, ++ NSSCMSGenericWrapperDataCallback decode_before, ++ NSSCMSGenericWrapperDataCallback decode_after, ++ NSSCMSGenericWrapperDataCallback decode_end, ++ NSSCMSGenericWrapperDataCallback encode_start, ++ NSSCMSGenericWrapperDataCallback encode_before, ++ NSSCMSGenericWrapperDataCallback encode_after, ++ PRBool isData); ++ + /************************************************************************/ + SEC_END_PROTOS + +Index: ./mozilla/security/nss/lib/smime/cmsasn1.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsasn1.c,v +retrieving revision 1.7 +retrieving revision 1.9 +diff -u -p -r1.7 -r1.9 +--- ./mozilla/security/nss/lib/smime/cmsasn1.c 6 Jun 2010 22:36:35 -0000 1.7 ++++ ./mozilla/security/nss/lib/smime/cmsasn1.c 31 Jan 2011 23:56:30 -0000 1.9 +@@ -37,7 +37,7 @@ + /* + * CMS ASN.1 templates + * +- * $Id: cmsasn1.c,v 1.7 2010/06/06 22:36:35 nelson%bolyard.com Exp $ ++ * $Id: cmsasn1.c,v 1.9 2011/01/31 23:56:30 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -479,6 +479,20 @@ const SEC_ASN1Template NSS_PointerToCMSE + { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate } + }; + ++const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = { ++ { SEC_ASN1_INLINE, ++ offsetof(NSSCMSGenericWrapperData,contentInfo), ++ NSSCMSEncapsulatedContentInfoTemplate }, ++}; ++ ++SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate); ++ ++const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = { ++ { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate } ++}; ++ ++SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate); ++ + /* ----------------------------------------------------------------------------- + * FORTEZZA KEA + */ +@@ -547,15 +561,17 @@ nss_cms_choose_content_template(void *sr + { + const SEC_ASN1Template *theTemplate; + NSSCMSContentInfo *cinfo; ++ SECOidTag type; + + PORT_Assert (src_or_dest != NULL); + if (src_or_dest == NULL) + return NULL; + + cinfo = (NSSCMSContentInfo *)src_or_dest; +- switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { ++ type = NSS_CMSContentInfo_GetContentTypeTag(cinfo); ++ switch (type) { + default: +- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); ++ theTemplate = NSS_CMSType_GetTemplate(type); + break; + case SEC_OID_PKCS7_DATA: + theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); +Index: ./mozilla/security/nss/lib/smime/cmscinfo.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmscinfo.c,v +retrieving revision 1.7 +retrieving revision 1.9 +diff -u -p -r1.7 -r1.9 +--- ./mozilla/security/nss/lib/smime/cmscinfo.c 25 Apr 2004 15:03:16 -0000 1.7 ++++ ./mozilla/security/nss/lib/smime/cmscinfo.c 31 Jan 2011 23:56:30 -0000 1.9 +@@ -37,7 +37,7 @@ + /* + * CMS contentInfo methods. + * +- * $Id: cmscinfo.c,v 1.7 2004/04/25 15:03:16 gerv%gerv.net Exp $ ++ * $Id: cmscinfo.c,v 1.9 2011/01/31 23:56:30 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -47,11 +47,37 @@ + #include "secoid.h" + #include "secerr.h" + ++ + /* + * NSS_CMSContentInfo_Create - create a content info + * + * version is set in the _Finalize procedures for each content type + */ ++SECStatus ++NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo) ++{ ++ if (cinfo->private) { ++ return SECSuccess; ++ } ++ cinfo->private = PORT_ZNew(NSSCMSContentInfoPrivate); ++ return (cinfo->private) ? SECSuccess: SECFailure; ++} ++ ++ ++static void ++nss_cmsContentInfo_private_destroy(NSSCMSContentInfoPrivate *private) ++{ ++ if (private->digcx) { ++ /* must destroy digest objects */ ++ NSS_CMSDigestContext_Cancel(private->digcx); ++ private->digcx = NULL; ++ } ++ if (private->ciphcx) { ++ NSS_CMSCipherContext_Destroy(private->ciphcx); ++ private->ciphcx = NULL; ++ } ++ PORT_Free(private); ++} + + /* + * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces. +@@ -76,23 +102,17 @@ NSS_CMSContentInfo_Destroy(NSSCMSContent + NSS_CMSDigestedData_Destroy(cinfo->content.digestedData); + break; + default: ++ NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData); + /* XXX Anything else that needs to be "manually" freed/destroyed? */ + break; + } +- if (cinfo->digcx) { +- /* must destroy digest objects */ +- NSS_CMSDigestContext_Cancel(cinfo->digcx); +- cinfo->digcx = NULL; ++ if (cinfo->private) { ++ nss_cmsContentInfo_private_destroy(cinfo->private); ++ cinfo->private = NULL; + } +- if (cinfo->bulkkey) ++ if (cinfo->bulkkey) { + PK11_FreeSymKey(cinfo->bulkkey); +- +- if (cinfo->ciphcx) { +- NSS_CMSCipherContext_Destroy(cinfo->ciphcx); +- cinfo->ciphcx = NULL; + } +- +- /* we live in a pool, so no need to worry about storage */ + } + + /* +@@ -101,31 +121,56 @@ NSS_CMSContentInfo_Destroy(NSSCMSContent + NSSCMSContentInfo * + NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo) + { +- void * ptr = NULL; + NSSCMSContentInfo * ccinfo = NULL; + SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); + switch (tag) { + case SEC_OID_PKCS7_SIGNED_DATA: +- ptr = (void *)cinfo->content.signedData; +- ccinfo = &(cinfo->content.signedData->contentInfo); ++ if (cinfo->content.signedData != NULL) { ++ ccinfo = &(cinfo->content.signedData->contentInfo); ++ } + break; + case SEC_OID_PKCS7_ENVELOPED_DATA: +- ptr = (void *)cinfo->content.envelopedData; +- ccinfo = &(cinfo->content.envelopedData->contentInfo); ++ if (cinfo->content.envelopedData != NULL) { ++ ccinfo = &(cinfo->content.envelopedData->contentInfo); ++ } + break; + case SEC_OID_PKCS7_DIGESTED_DATA: +- ptr = (void *)cinfo->content.digestedData; +- ccinfo = &(cinfo->content.digestedData->contentInfo); ++ if (cinfo->content.digestedData != NULL) { ++ ccinfo = &(cinfo->content.digestedData->contentInfo); ++ } + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: +- ptr = (void *)cinfo->content.encryptedData; +- ccinfo = &(cinfo->content.encryptedData->contentInfo); ++ if (cinfo->content.encryptedData != NULL) { ++ ccinfo = &(cinfo->content.encryptedData->contentInfo); ++ } + break; + case SEC_OID_PKCS7_DATA: + default: ++ if (NSS_CMSType_IsWrapper(tag)) { ++ if (cinfo->content.genericData != NULL) { ++ ccinfo = &(cinfo->content.genericData->contentInfo); ++ } ++ } + break; + } +- return (ptr ? ccinfo : NULL); ++ if (ccinfo && !ccinfo->private) { ++ NSS_CMSContentInfo_Private_Init(ccinfo); ++ } ++ return ccinfo; ++} ++ ++SECStatus ++NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream) ++{ ++ SECStatus rv; ++ ++ rv = NSS_CMSContentInfo_Private_Init(cinfo); ++ if (rv != SECSuccess) { ++ /* default is streaming, failure to get ccinfo will not effect this */ ++ return dontStream ? SECFailure : SECSuccess ; ++ } ++ cinfo->private->dontStream = dontStream; ++ return SECSuccess; + } + + /* +@@ -147,7 +192,9 @@ NSS_CMSContentInfo_SetContent(NSSCMSMess + + cinfo->content.pointer = ptr; + +- if (type != SEC_OID_PKCS7_DATA) { ++ if (NSS_CMSType_IsData(type) && ptr) { ++ cinfo->rawContent = ptr; ++ } else { + /* as we always have some inner data, + * we need to set it to something, just to fool the encoder enough to work on it + * and get us into nss_cms_encoder_notify at that point */ +@@ -174,9 +221,10 @@ NSS_CMSContentInfo_SetContent_Data(NSSCM + { + if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) + return SECFailure; +- cinfo->rawContent = (detached) ? +- NULL : (data) ? +- data : SECITEM_AllocItem(cmsg->poolp, NULL, 1); ++ if (detached) { ++ cinfo->rawContent = NULL; ++ } ++ + return SECSuccess; + } + +@@ -204,6 +252,7 @@ NSS_CMSContentInfo_SetContent_EncryptedD + return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd); + } + ++ + /* + * NSS_CMSContentInfo_GetContent - get pointer to inner content + * +@@ -223,7 +272,7 @@ NSS_CMSContentInfo_GetContent(NSSCMSCont + case SEC_OID_PKCS7_ENCRYPTED_DATA: + return cinfo->content.pointer; + default: +- return NULL; ++ return NSS_CMSType_IsWrapper(tag) ? cinfo->content.pointer : (NSS_CMSType_IsData(tag) ? cinfo->rawContent : NULL); + } + } + +@@ -232,6 +281,7 @@ NSS_CMSContentInfo_GetContent(NSSCMSCont + * + * this is typically only called by NSS_CMSMessage_GetContent() + */ ++ + SECItem * + NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo) + { +@@ -240,26 +290,21 @@ NSS_CMSContentInfo_GetInnerContent(NSSCM + SECItem *pItem = NULL; + + tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); +- switch (tag) { +- case SEC_OID_PKCS7_DATA: +- /* end of recursion - every message has to have a data cinfo */ ++ if (NSS_CMSType_IsData(tag)) { + pItem = cinfo->content.data; +- break; +- case SEC_OID_PKCS7_DIGESTED_DATA: +- case SEC_OID_PKCS7_ENCRYPTED_DATA: +- case SEC_OID_PKCS7_ENVELOPED_DATA: +- case SEC_OID_PKCS7_SIGNED_DATA: ++ } else if (NSS_CMSType_IsWrapper(tag)) { + ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo); +- if (ccinfo != NULL) ++ if (ccinfo != NULL) { + pItem = NSS_CMSContentInfo_GetContent(ccinfo); +- break; +- default: ++ } ++ } else { + PORT_Assert(0); +- break; + } ++ + return pItem; + } + ++ + /* + * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result + * for future reference) and return the inner content type. +Index: ./mozilla/security/nss/lib/smime/cmsdecode.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsdecode.c,v +retrieving revision 1.9.66.1 +retrieving revision 1.11 +diff -u -p -r1.9.66.1 -r1.11 +--- ./mozilla/security/nss/lib/smime/cmsdecode.c 23 Dec 2010 18:03:41 -0000 1.9.66.1 ++++ ./mozilla/security/nss/lib/smime/cmsdecode.c 28 Jan 2011 23:03:59 -0000 1.11 +@@ -37,7 +37,7 @@ + /* + * CMS decoding. + * +- * $Id: cmsdecode.c,v 1.9.66.1 2010/12/23 18:03:41 kaie%kuix.de Exp $ ++ * $Id: cmsdecode.c,v 1.11 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -120,8 +120,7 @@ nss_cms_decoder_notify(void *arg, PRBool + #endif + + /* so what are we working on right now? */ +- switch (p7dcx->type) { +- case SEC_OID_UNKNOWN: ++ if (p7dcx->type == SEC_OID_UNKNOWN) { + /* + * right now, we are still decoding the OUTER (root) cinfo + * As soon as we know the inner content type, set up the info, +@@ -136,8 +135,7 @@ nss_cms_decoder_notify(void *arg, PRBool + /* is this ready already ? need to alloc? */ + /* XXX yes we need to alloc -- continue here */ + } +- break; +- case SEC_OID_PKCS7_DATA: ++ } else if (NSS_CMSType_IsData(p7dcx->type)) { + /* this can only happen if the outermost cinfo has DATA in it */ + /* otherwise, we handle this type implicitely in the inner decoders */ + +@@ -150,86 +148,71 @@ nss_cms_decoder_notify(void *arg, PRBool + nss_cms_decoder_update_filter, + p7dcx, + (PRBool)(p7dcx->cb != NULL)); +- break; +- } +- +- if (after && dest == &(rootcinfo->content.data)) { ++ } else if (after && dest == &(rootcinfo->content.data)) { + /* remove the filter */ + SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); + } +- break; +- +- case SEC_OID_PKCS7_SIGNED_DATA: +- case SEC_OID_PKCS7_ENVELOPED_DATA: +- case SEC_OID_PKCS7_DIGESTED_DATA: +- case SEC_OID_PKCS7_ENCRYPTED_DATA: +- +- if (before && dest == &(rootcinfo->content)) +- break; /* we're not there yet */ ++ } else if (NSS_CMSType_IsWrapper(p7dcx->type)) { ++ if (!before || dest != &(rootcinfo->content)) { + +- if (p7dcx->content.pointer == NULL) +- p7dcx->content = rootcinfo->content; ++ if (p7dcx->content.pointer == NULL) ++ p7dcx->content = rootcinfo->content; + +- /* get this data type's inner contentInfo */ +- cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, ++ /* get this data type's inner contentInfo */ ++ cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, + p7dcx->type); + +- if (before && dest == &(cinfo->contentType)) { +- /* at this point, set up the &%$&$ back pointer */ +- /* we cannot do it later, because the content itself is optional! */ +- /* please give me C++ */ +- switch (p7dcx->type) { +- case SEC_OID_PKCS7_SIGNED_DATA: +- p7dcx->content.signedData->cmsg = p7dcx->cmsg; +- break; +- case SEC_OID_PKCS7_DIGESTED_DATA: +- p7dcx->content.digestedData->cmsg = p7dcx->cmsg; +- break; +- case SEC_OID_PKCS7_ENVELOPED_DATA: +- p7dcx->content.envelopedData->cmsg = p7dcx->cmsg; +- break; +- case SEC_OID_PKCS7_ENCRYPTED_DATA: +- p7dcx->content.encryptedData->cmsg = p7dcx->cmsg; +- break; +- default: +- PORT_Assert(0); +- break; ++ if (before && dest == &(cinfo->contentType)) { ++ /* at this point, set up the &%$&$ back pointer */ ++ /* we cannot do it later, because the content itself ++ * is optional! */ ++ switch (p7dcx->type) { ++ case SEC_OID_PKCS7_SIGNED_DATA: ++ p7dcx->content.signedData->cmsg = p7dcx->cmsg; ++ break; ++ case SEC_OID_PKCS7_DIGESTED_DATA: ++ p7dcx->content.digestedData->cmsg = p7dcx->cmsg; ++ break; ++ case SEC_OID_PKCS7_ENVELOPED_DATA: ++ p7dcx->content.envelopedData->cmsg = p7dcx->cmsg; ++ break; ++ case SEC_OID_PKCS7_ENCRYPTED_DATA: ++ p7dcx->content.encryptedData->cmsg = p7dcx->cmsg; ++ break; ++ default: ++ p7dcx->content.genericData->cmsg = p7dcx->cmsg; ++ break; ++ } + } +- } + +- if (before && dest == &(cinfo->rawContent)) { +- /* we want the ASN.1 decoder to deliver the decoded bytes to us +- ** from now on +- */ +- SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, ++ if (before && dest == &(cinfo->rawContent)) { ++ /* we want the ASN.1 decoder to deliver the decoded bytes to us ++ ** from now on ++ */ ++ SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, + nss_cms_decoder_update_filter, + p7dcx, (PRBool)(p7dcx->cb != NULL)); + + +- /* we're right in front of the data */ +- if (nss_cms_before_data(p7dcx) != SECSuccess) { +- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); +- /* stop all processing */ +- p7dcx->error = PORT_GetError(); ++ /* we're right in front of the data */ ++ if (nss_cms_before_data(p7dcx) != SECSuccess) { ++ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); ++ /* stop all processing */ ++ p7dcx->error = PORT_GetError(); ++ } + } +- } +- if (after && dest == &(cinfo->rawContent)) { +- /* we're right after of the data */ +- if (nss_cms_after_data(p7dcx) != SECSuccess) +- p7dcx->error = PORT_GetError(); ++ if (after && dest == &(cinfo->rawContent)) { ++ /* we're right after of the data */ ++ if (nss_cms_after_data(p7dcx) != SECSuccess) ++ p7dcx->error = PORT_GetError(); + +- /* we don't need to see the contents anymore */ +- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); ++ /* we don't need to see the contents anymore */ ++ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); ++ } + } +- break; +- +-#if 0 /* NIH */ +- case SEC_OID_PKCS7_AUTHENTICATED_DATA: +-#endif +- default: ++ } else { + /* unsupported or unknown message type - fail gracefully */ + p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE; +- break; + } + } + +@@ -269,7 +252,8 @@ nss_cms_before_data(NSSCMSDecoderContext + p7dcx->content.encryptedData); + break; + default: +- return SECFailure; ++ rv = NSS_CMSGenericWrapperData_Decode_BeforeData(p7dcx->type, ++ p7dcx->content.genericData); + } + if (rv != SECSuccess) + return SECFailure; +@@ -280,7 +264,7 @@ nss_cms_before_data(NSSCMSDecoderContext + cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type); + childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); + +- if (childtype == SEC_OID_PKCS7_DATA) { ++ if (NSS_CMSType_IsData(childtype)) { + cinfo->content.pointer = (void *) nss_cms_create_decoder_data(poolp); + if (cinfo->content.pointer == NULL) + /* set memory error */ +@@ -395,7 +379,8 @@ nss_cms_after_data(NSSCMSDecoderContext + /* do nothing */ + break; + default: +- rv = SECFailure; ++ rv = NSS_CMSGenericWrapperData_Decode_AfterData(p7dcx->type, ++ p7dcx->content.genericData); + break; + } + done: +@@ -430,7 +415,8 @@ nss_cms_after_end(NSSCMSDecoderContext * + case SEC_OID_PKCS7_DATA: + break; + default: +- rv = SECFailure; /* we should not have got that far... */ ++ rv = NSS_CMSGenericWrapperData_Decode_AfterEnd(p7dcx->type, ++ p7dcx->content.genericData); + break; + } + return rv; +@@ -469,7 +455,7 @@ nss_cms_decoder_work_data(NSSCMSDecoderC + goto loser; + } + +- if (cinfo->ciphcx != NULL) { ++ if (cinfo->private && cinfo->private->ciphcx != NULL) { + /* + * we are decrypting. + * +@@ -483,7 +469,7 @@ nss_cms_decoder_work_data(NSSCMSDecoderC + unsigned int buflen; /* length available for decrypted data */ + + /* find out about the length of decrypted data */ +- buflen = NSS_CMSCipherContext_DecryptLength(cinfo->ciphcx, len, final); ++ buflen = NSS_CMSCipherContext_DecryptLength(cinfo->private->ciphcx, len, final); + + /* + * it might happen that we did not provide enough data for a full +@@ -514,7 +500,7 @@ nss_cms_decoder_work_data(NSSCMSDecoderC + * any output (see above), but we still need to call NSS_CMSCipherContext_Decrypt to + * keep track of incoming data + */ +- rv = NSS_CMSCipherContext_Decrypt(cinfo->ciphcx, buf, &outlen, buflen, ++ rv = NSS_CMSCipherContext_Decrypt(cinfo->private->ciphcx, buf, &outlen, buflen, + data, len, final); + if (rv != SECSuccess) { + p7dcx->error = PORT_GetError(); +@@ -534,8 +520,8 @@ nss_cms_decoder_work_data(NSSCMSDecoderC + /* + * Update the running digests with plaintext bytes (if we need to). + */ +- if (cinfo->digcx) +- NSS_CMSDigestContext_Update(cinfo->digcx, data, len); ++ if (cinfo->private && cinfo->private->digcx) ++ NSS_CMSDigestContext_Update(cinfo->private->digcx, data, len); + + /* at this point, we have the plain decoded & decrypted data + ** which is either more encoded DER (which we need to hand to the child +Index: ./mozilla/security/nss/lib/smime/cmsdigdata.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsdigdata.c,v +retrieving revision 1.5 +retrieving revision 1.6 +diff -u -p -r1.5 -r1.6 +--- ./mozilla/security/nss/lib/smime/cmsdigdata.c 25 Apr 2004 15:03:16 -0000 1.5 ++++ ./mozilla/security/nss/lib/smime/cmsdigdata.c 28 Jan 2011 23:03:59 -0000 1.6 +@@ -37,7 +37,7 @@ + /* + * CMS digestedData methods. + * +- * $Id: cmsdigdata.c,v 1.5 2004/04/25 15:03:16 gerv%gerv.net Exp $ ++ * $Id: cmsdigdata.c,v 1.6 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -117,7 +117,8 @@ NSS_CMSDigestedData_Encode_BeforeStart(N + SECItem *dummy; + + version = NSS_CMS_DIGESTED_DATA_VERSION_DATA; +- if (NSS_CMSContentInfo_GetContentTypeTag(&(digd->contentInfo)) != SEC_OID_PKCS7_DATA) ++ if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag( ++ &(digd->contentInfo)))) + version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP; + + dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version); +@@ -134,11 +135,16 @@ NSS_CMSDigestedData_Encode_BeforeStart(N + SECStatus + NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd) + { ++ SECStatus rv =NSS_CMSContentInfo_Private_Init(&digd->contentInfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } ++ + /* set up the digests */ + if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) { + /* if digest is already there, do nothing */ +- digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); +- if (digd->contentInfo.digcx == NULL) ++ digd->contentInfo.private->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); ++ if (digd->contentInfo.private->digcx == NULL) + return SECFailure; + } + return SECSuccess; +@@ -156,12 +162,12 @@ NSS_CMSDigestedData_Encode_AfterData(NSS + { + SECStatus rv = SECSuccess; + /* did we have digest calculation going on? */ +- if (digd->contentInfo.digcx) { +- rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx, ++ if (digd->contentInfo.private && digd->contentInfo.private->digcx) { ++ rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.private->digcx, + digd->cmsg->poolp, + &(digd->digest)); + /* error has been set by NSS_CMSDigestContext_FinishSingle */ +- digd->contentInfo.digcx = NULL; ++ digd->contentInfo.private->digcx = NULL; + } + + return rv; +@@ -177,12 +183,19 @@ NSS_CMSDigestedData_Encode_AfterData(NSS + SECStatus + NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd) + { ++ SECStatus rv; ++ + /* is there a digest algorithm yet? */ + if (digd->digestAlg.algorithm.len == 0) + return SECFailure; + +- digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); +- if (digd->contentInfo.digcx == NULL) ++ rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } ++ ++ digd->contentInfo.private->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); ++ if (digd->contentInfo.private->digcx == NULL) + return SECFailure; + + return SECSuccess; +@@ -200,12 +213,12 @@ NSS_CMSDigestedData_Decode_AfterData(NSS + { + SECStatus rv = SECSuccess; + /* did we have digest calculation going on? */ +- if (digd->contentInfo.digcx) { +- rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx, ++ if (digd->contentInfo.private && digd->contentInfo.private->digcx) { ++ rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.private->digcx, + digd->cmsg->poolp, + &(digd->cdigest)); + /* error has been set by NSS_CMSDigestContext_FinishSingle */ +- digd->contentInfo.digcx = NULL; ++ digd->contentInfo.private->digcx = NULL; + } + + return rv; +Index: ./mozilla/security/nss/lib/smime/cmsencdata.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsencdata.c,v +retrieving revision 1.11 +retrieving revision 1.12 +diff -u -p -r1.11 -r1.12 +--- ./mozilla/security/nss/lib/smime/cmsencdata.c 3 Feb 2008 06:08:49 -0000 1.11 ++++ ./mozilla/security/nss/lib/smime/cmsencdata.c 28 Jan 2011 23:03:59 -0000 1.12 +@@ -37,7 +37,7 @@ + /* + * CMS encryptedData methods. + * +- * $Id: cmsencdata.c,v 1.11 2008/02/03 06:08:49 nelson%bolyard.com Exp $ ++ * $Id: cmsencdata.c,v 1.12 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -181,6 +181,7 @@ NSS_CMSEncryptedData_Encode_BeforeData(N + NSSCMSContentInfo *cinfo; + PK11SymKey *bulkkey; + SECAlgorithmID *algid; ++ SECStatus rv; + + cinfo = &(encd->contentInfo); + +@@ -192,12 +193,16 @@ NSS_CMSEncryptedData_Encode_BeforeData(N + if (algid == NULL) + return SECFailure; + ++ rv = NSS_CMSContentInfo_Private_Init(cinfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } + /* this may modify algid (with IVs generated in a token). + * it is therefore essential that algid is a pointer to the "real" contentEncAlg, + * not just to a copy */ +- cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid); ++ cinfo->private->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid); + PK11_FreeSymKey(bulkkey); +- if (cinfo->ciphcx == NULL) ++ if (cinfo->private->ciphcx == NULL) + return SECFailure; + + return SECSuccess; +@@ -209,9 +214,9 @@ NSS_CMSEncryptedData_Encode_BeforeData(N + SECStatus + NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd) + { +- if (encd->contentInfo.ciphcx) { +- NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx); +- encd->contentInfo.ciphcx = NULL; ++ if (encd->contentInfo.private && encd->contentInfo.private->ciphcx) { ++ NSS_CMSCipherContext_Destroy(encd->contentInfo.private->ciphcx); ++ encd->contentInfo.private->ciphcx = NULL; + } + + /* nothing to do after data */ +@@ -244,8 +249,14 @@ NSS_CMSEncryptedData_Decode_BeforeData(N + + NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); + +- cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); +- if (cinfo->ciphcx == NULL) ++ rv = NSS_CMSContentInfo_Private_Init(cinfo); ++ if (rv != SECSuccess) { ++ goto loser; ++ } ++ rv = SECFailure; ++ ++ cinfo->private->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); ++ if (cinfo->private->ciphcx == NULL) + goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ + + +@@ -264,9 +275,9 @@ loser: + SECStatus + NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd) + { +- if (encd->contentInfo.ciphcx) { +- NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx); +- encd->contentInfo.ciphcx = NULL; ++ if (encd->contentInfo.private && encd->contentInfo.private->ciphcx) { ++ NSS_CMSCipherContext_Destroy(encd->contentInfo.private->ciphcx); ++ encd->contentInfo.private->ciphcx = NULL; + } + + return SECSuccess; +Index: ./mozilla/security/nss/lib/smime/cmsencode.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsencode.c,v +retrieving revision 1.6.66.1 +retrieving revision 1.10 +diff -u -p -r1.6.66.1 -r1.10 +--- ./mozilla/security/nss/lib/smime/cmsencode.c 23 Dec 2010 18:03:41 -0000 1.6.66.1 ++++ ./mozilla/security/nss/lib/smime/cmsencode.c 1 Feb 2011 23:24:56 -0000 1.10 +@@ -37,7 +37,7 @@ + /* + * CMS encoding. + * +- * $Id: cmsencode.c,v 1.6.66.1 2010/12/23 18:03:41 kaie%kuix.de Exp $ ++ * $Id: cmsencode.c,v 1.10 2011/02/01 23:24:56 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -92,8 +92,23 @@ nss_cms_encoder_out(void *arg, const cha + + #ifdef CMSDEBUG + int i; ++ const char *data_name = "unknown"; + +- fprintf(stderr, "kind = %d, depth = %d, len = %d\n", data_kind, depth, len); ++ switch (data_kind) { ++ case SEC_ASN1_Identifier: ++ data_name = "identifier"; ++ break; ++ case SEC_ASN1_Length: ++ data_name = "length"; ++ break; ++ case SEC_ASN1_Contents: ++ data_name = "contents"; ++ break; ++ case SEC_ASN1_EndOfContents: ++ data_name = "end-of-contents"; ++ break; ++ } ++ fprintf(stderr, "kind = %s, depth = %d, len = %d\n", data_name, depth, len); + for (i=0; i < len; i++) { + fprintf(stderr, " %02x%s", (unsigned int)buf[i] & 0xff, ((i % 16) == 15) ? "\n" : ""); + } +@@ -159,34 +174,17 @@ nss_cms_encoder_notify(void *arg, PRBool + * Watch for the content field, at which point we want to instruct + * the ASN.1 encoder to start taking bytes from the buffer. + */ +- switch (p7ecx->type) { +- default: +- case SEC_OID_UNKNOWN: +- /* we're still in the root message */ +- if (after && dest == &(rootcinfo->contentType)) { +- /* got the content type OID now - so find out the type tag */ +- p7ecx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo); +- /* set up a pointer to our current content */ +- p7ecx->content = rootcinfo->content; +- } +- break; +- +- case SEC_OID_PKCS7_DATA: +- if (before && dest == &(rootcinfo->rawContent)) { ++ if (NSS_CMSType_IsData(p7ecx->type)) { ++ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); ++ if (before && dest == &(cinfo->rawContent)) { + /* just set up encoder to grab from user - no encryption or digesting */ +- if ((item = rootcinfo->content.data) != NULL) ++ if ((item = cinfo->content.data) != NULL) + (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE); + else + SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); + SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ + } +- break; +- +- case SEC_OID_PKCS7_SIGNED_DATA: +- case SEC_OID_PKCS7_ENVELOPED_DATA: +- case SEC_OID_PKCS7_DIGESTED_DATA: +- case SEC_OID_PKCS7_ENCRYPTED_DATA: +- ++ } else if (NSS_CMSType_IsWrapper(p7ecx->type)) { + /* when we know what the content is, we encode happily until we reach the inner content */ + cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); + childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); +@@ -199,19 +197,32 @@ nss_cms_encoder_notify(void *arg, PRBool + p7ecx->error = PORT_GetError(); + } + if (before && dest == &(cinfo->rawContent)) { +- if (childtype == SEC_OID_PKCS7_DATA && (item = cinfo->content.data) != NULL) +- /* we have data - feed it in */ +- (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE); +- else +- /* else try to get it from user */ ++ if (p7ecx->childp7ecx == NULL) { ++ if ((NSS_CMSType_IsData(childtype) && (item = cinfo->content.data) != NULL)) { ++ /* we are the innermost non-data and we have data - feed it in */ ++ (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE); ++ } else { ++ /* else we'll have to get data from user */ ++ SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); ++ } ++ } else { ++ /* if we have a nested encoder, wait for its data */ + SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); ++ } + } + if (after && dest == &(cinfo->rawContent)) { + if (nss_cms_after_data(p7ecx) != SECSuccess) + p7ecx->error = PORT_GetError(); + SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ + } +- break; ++ } else { ++ /* we're still in the root message */ ++ if (after && dest == &(rootcinfo->contentType)) { ++ /* got the content type OID now - so find out the type tag */ ++ p7ecx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo); ++ /* set up a pointer to our current content */ ++ p7ecx->content = rootcinfo->content; ++ } + } + } + +@@ -247,7 +258,11 @@ nss_cms_before_data(NSSCMSEncoderContext + rv = NSS_CMSEncryptedData_Encode_BeforeData(p7ecx->content.encryptedData); + break; + default: +- rv = SECFailure; ++ if (NSS_CMSType_IsWrapper(p7ecx->type)) { ++ rv = NSS_CMSGenericWrapperData_Encode_BeforeData(p7ecx->type, p7ecx->content.genericData); ++ } else { ++ rv = SECFailure; ++ } + } + if (rv != SECSuccess) + return SECFailure; +@@ -258,14 +273,7 @@ nss_cms_before_data(NSSCMSEncoderContext + cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); + childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); + +- switch (childtype) { +- case SEC_OID_PKCS7_SIGNED_DATA: +- case SEC_OID_PKCS7_ENVELOPED_DATA: +- case SEC_OID_PKCS7_ENCRYPTED_DATA: +- case SEC_OID_PKCS7_DIGESTED_DATA: +-#if 0 +- case SEC_OID_PKCS7_DATA: /* XXX here also??? maybe yes! */ +-#endif ++ if (NSS_CMSType_IsWrapper(childtype)) { + /* in these cases, we need to set up a child encoder! */ + /* create new encoder context */ + childp7ecx = PORT_ZAlloc(sizeof(NSSCMSEncoderContext)); +@@ -284,6 +292,8 @@ nss_cms_before_data(NSSCMSEncoderContext + childp7ecx->output.destpoolp = NULL; + childp7ecx->output.dest = NULL; + childp7ecx->cmsg = p7ecx->cmsg; ++ childp7ecx->ecxupdated = PR_FALSE; ++ childp7ecx->childp7ecx = NULL; + + template = NSS_CMSUtil_GetTemplateByTypeTag(childtype); + if (template == NULL) +@@ -303,11 +313,8 @@ nss_cms_before_data(NSSCMSEncoderContext + case SEC_OID_PKCS7_ENCRYPTED_DATA: + rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData); + break; +- case SEC_OID_PKCS7_DATA: +- rv = SECSuccess; +- break; + default: +- PORT_Assert(0); ++ rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(childp7ecx->type, cinfo->content.genericData); + break; + } + if (rv != SECSuccess) +@@ -321,17 +328,17 @@ nss_cms_before_data(NSSCMSEncoderContext + if (childp7ecx->ecx == NULL) + goto loser; + +- childp7ecx->ecxupdated = PR_FALSE; +- + /* + * Indicate that we are streaming. We will be streaming until we + * get past the contents bytes. + */ +- SEC_ASN1EncoderSetStreaming(childp7ecx->ecx); ++ if (!cinfo->private || !cinfo->private->dontStream) ++ SEC_ASN1EncoderSetStreaming(childp7ecx->ecx); + + /* + * The notify function will watch for the contents field. + */ ++ p7ecx->childp7ecx = childp7ecx; + SEC_ASN1EncoderSetNotifyProc(childp7ecx->ecx, nss_cms_encoder_notify, childp7ecx); + + /* please note that we are NOT calling SEC_ASN1EncoderUpdate here to kick off the */ +@@ -339,22 +346,11 @@ nss_cms_before_data(NSSCMSEncoderContext + /* otherwise we'd be encoding data from a call of the notify function of the */ + /* parent encoder (which would not work) */ + +- /* this will kick off the encoding process & encode everything up to the content bytes, +- * at which point the notify function sets streaming mode (and possibly creates +- * another child encoder). */ +- if (SEC_ASN1EncoderUpdate(childp7ecx->ecx, NULL, 0) != SECSuccess) +- goto loser; +- +- p7ecx->childp7ecx = childp7ecx; +- break; +- +- case SEC_OID_PKCS7_DATA: ++ } else if (NSS_CMSType_IsData(childtype)) { + p7ecx->childp7ecx = NULL; +- break; +- default: ++ } else { + /* we do not know this type */ + p7ecx->error = SEC_ERROR_BAD_DER; +- break; + } + + return SECSuccess; +@@ -364,6 +360,7 @@ loser: + if (childp7ecx->ecx) + SEC_ASN1EncoderFinish(childp7ecx->ecx); + PORT_Free(childp7ecx); ++ p7ecx->childp7ecx = NULL; + } + return SECFailure; + } +@@ -387,11 +384,12 @@ nss_cms_after_data(NSSCMSEncoderContext + case SEC_OID_PKCS7_ENCRYPTED_DATA: + rv = NSS_CMSEncryptedData_Encode_AfterData(p7ecx->content.encryptedData); + break; +- case SEC_OID_PKCS7_DATA: +- /* do nothing */ +- break; + default: +- rv = SECFailure; ++ if (NSS_CMSType_IsWrapper(p7ecx->type)) { ++ rv = NSS_CMSGenericWrapperData_Encode_AfterData(p7ecx->type, p7ecx->content.genericData); ++ } else { ++ rv = SECFailure; ++ } + break; + } + return rv; +@@ -432,23 +430,23 @@ nss_cms_encoder_work_data(NSSCMSEncoderC + } + + /* Update the running digest. */ +- if (len && cinfo->digcx != NULL) +- NSS_CMSDigestContext_Update(cinfo->digcx, data, len); ++ if (len && cinfo->private && cinfo->private->digcx != NULL) ++ NSS_CMSDigestContext_Update(cinfo->private->digcx, data, len); + + /* Encrypt this chunk. */ +- if (cinfo->ciphcx != NULL) { ++ if (cinfo->private && cinfo->private->ciphcx != NULL) { + unsigned int inlen; /* length of data being encrypted */ + unsigned int outlen; /* length of encrypted data */ + unsigned int buflen; /* length available for encrypted data */ + + inlen = len; +- buflen = NSS_CMSCipherContext_EncryptLength(cinfo->ciphcx, inlen, final); ++ buflen = NSS_CMSCipherContext_EncryptLength(cinfo->private->ciphcx, inlen, final); + if (buflen == 0) { + /* + * No output is expected, but the input data may be buffered + * so we still have to call Encrypt. + */ +- rv = NSS_CMSCipherContext_Encrypt(cinfo->ciphcx, NULL, NULL, 0, ++ rv = NSS_CMSCipherContext_Encrypt(cinfo->private->ciphcx, NULL, NULL, 0, + data, inlen, final); + if (final) { + len = 0; +@@ -465,7 +463,7 @@ nss_cms_encoder_work_data(NSSCMSEncoderC + if (buf == NULL) { + rv = SECFailure; + } else { +- rv = NSS_CMSCipherContext_Encrypt(cinfo->ciphcx, buf, &outlen, buflen, ++ rv = NSS_CMSCipherContext_Encrypt(cinfo->private->ciphcx, buf, &outlen, buflen, + data, inlen, final); + data = buf; + len = outlen; +@@ -481,12 +479,12 @@ nss_cms_encoder_work_data(NSSCMSEncoderC + * (which will encode it, then hand it back to the user or the parent encoder) + * We don't encode the data if we're innermost and we're told not to include the data + */ +- if (p7ecx->ecx != NULL && len && (!innermost || cinfo->rawContent != NULL)) ++ if (p7ecx->ecx != NULL && len && (!innermost || cinfo->rawContent != cinfo->content.pointer)) + rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len); + + done: + +- if (cinfo->ciphcx != NULL) { ++ if (cinfo->private && cinfo->private->ciphcx != NULL) { + if (dest != NULL) { + dest->data = buf; + dest->len = len; +@@ -532,6 +530,7 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg + NSSCMSEncoderContext *p7ecx; + SECStatus rv; + NSSCMSContentInfo *cinfo; ++ SECOidTag tag; + + NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg, + detached_digestalgs, detached_digests); +@@ -551,7 +550,8 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg + + cinfo = NSS_CMSMessage_GetContentInfo(cmsg); + +- switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { ++ tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); ++ switch (tag) { + case SEC_OID_PKCS7_SIGNED_DATA: + rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData); + break; +@@ -565,7 +565,12 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg + rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData); + break; + default: +- rv = SECFailure; ++ if (NSS_CMSType_IsWrapper(tag)) { ++ rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(tag, ++ p7ecx->content.genericData); ++ } else { ++ rv = SECFailure; ++ } + break; + } + if (rv != SECSuccess) { +@@ -587,7 +592,8 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg + * Indicate that we are streaming. We will be streaming until we + * get past the contents bytes. + */ +- SEC_ASN1EncoderSetStreaming(p7ecx->ecx); ++ if (!cinfo->private || !cinfo->private->dontStream) ++ SEC_ASN1EncoderSetStreaming(p7ecx->ecx); + + /* + * The notify function will watch for the contents field. +@@ -597,6 +603,7 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg + /* this will kick off the encoding process & encode everything up to the content bytes, + * at which point the notify function sets streaming mode (and possibly creates + * a child encoder). */ ++ p7ecx->ecxupdated = PR_TRUE; + if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) { + PORT_Free (p7ecx); + return NULL; +@@ -627,6 +634,13 @@ NSS_CMSEncoder_Update(NSSCMSEncoderConte + + /* hand data to the innermost decoder */ + if (p7ecx->childp7ecx) { ++ /* tell the child to start encoding, up to its first data byte, if it ++ * hasn't started yet */ ++ if (!p7ecx->childp7ecx->ecxupdated) { ++ p7ecx->childp7ecx->ecxupdated = PR_TRUE; ++ if (SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0) != SECSuccess) ++ return SECFailure; ++ } + /* recursion here */ + rv = NSS_CMSEncoder_Update(p7ecx->childp7ecx, data, len); + } else { +@@ -640,7 +654,7 @@ NSS_CMSEncoder_Update(NSSCMSEncoderConte + } + + childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); +- if (childtype != SEC_OID_PKCS7_DATA) ++ if (!NSS_CMSType_IsData(childtype)) + return SECFailure; + /* and we must not have preset data */ + if (cinfo->content.data != NULL) +@@ -721,6 +735,16 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderConte + * while we are already in NSS_CMSEncoder_Finish, but that's allright. + */ + if (p7ecx->childp7ecx) { ++ /* tell the child to start encoding, up to its first data byte, if it ++ * hasn't yet */ ++ if (!p7ecx->childp7ecx->ecxupdated) { ++ p7ecx->childp7ecx->ecxupdated = PR_TRUE; ++ rv = SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0); ++ if (rv != SECSuccess) { ++ NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */ ++ goto loser; ++ } ++ } + rv = NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */ + if (rv != SECSuccess) + goto loser; +@@ -737,7 +761,6 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderConte + + p7ecx->childp7ecx = NULL; + +- /* find out about our inner content type - must be data */ + cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); + if (!cinfo) { + /* The original programmer didn't expect this to happen */ +@@ -745,14 +768,10 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderConte + rv = SECFailure; + goto loser; + } +- childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); +- if (childtype == SEC_OID_PKCS7_DATA && cinfo->content.data == NULL) { +- SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx); +- /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */ +- rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); +- } +- ++ SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx); + SEC_ASN1EncoderClearStreaming(p7ecx->ecx); ++ /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */ ++ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); + + if (p7ecx->error) + rv = SECFailure; +Index: ./mozilla/security/nss/lib/smime/cmsenvdata.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsenvdata.c,v +retrieving revision 1.11 +retrieving revision 1.12 +diff -u -p -r1.11 -r1.12 +--- ./mozilla/security/nss/lib/smime/cmsenvdata.c 3 Oct 2005 22:01:57 -0000 1.11 ++++ ./mozilla/security/nss/lib/smime/cmsenvdata.c 28 Jan 2011 23:03:59 -0000 1.12 +@@ -37,7 +37,7 @@ + /* + * CMS envelopedData methods. + * +- * $Id: cmsenvdata.c,v 1.11 2005/10/03 22:01:57 relyea%netscape.com Exp $ ++ * $Id: cmsenvdata.c,v 1.12 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -270,6 +270,7 @@ NSS_CMSEnvelopedData_Encode_BeforeData(N + NSSCMSContentInfo *cinfo; + PK11SymKey *bulkkey; + SECAlgorithmID *algid; ++ SECStatus rv; + + cinfo = &(envd->contentInfo); + +@@ -281,12 +282,16 @@ NSS_CMSEnvelopedData_Encode_BeforeData(N + if (algid == NULL) + return SECFailure; + ++ rv = NSS_CMSContentInfo_Private_Init(cinfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } + /* this may modify algid (with IVs generated in a token). + * it is essential that algid is a pointer to the contentEncAlg data, not a + * pointer to a copy! */ +- cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid); ++ cinfo->private->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid); + PK11_FreeSymKey(bulkkey); +- if (cinfo->ciphcx == NULL) ++ if (cinfo->private->ciphcx == NULL) + return SECFailure; + + return SECSuccess; +@@ -298,9 +303,9 @@ NSS_CMSEnvelopedData_Encode_BeforeData(N + SECStatus + NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd) + { +- if (envd->contentInfo.ciphcx) { +- NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx); +- envd->contentInfo.ciphcx = NULL; ++ if (envd->contentInfo.private && envd->contentInfo.private->ciphcx) { ++ NSS_CMSCipherContext_Destroy(envd->contentInfo.private->ciphcx); ++ envd->contentInfo.private->ciphcx = NULL; + } + + /* nothing else to do after data */ +@@ -380,8 +385,13 @@ NSS_CMSEnvelopedData_Decode_BeforeData(N + + bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo); + +- cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); +- if (cinfo->ciphcx == NULL) ++ rv = NSS_CMSContentInfo_Private_Init(cinfo); ++ if (rv != SECSuccess) { ++ goto loser; ++ } ++ rv = SECFailure; ++ cinfo->private->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); ++ if (cinfo->private->ciphcx == NULL) + goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ + + +@@ -401,9 +411,9 @@ loser: + SECStatus + NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd) + { +- if (envd && envd->contentInfo.ciphcx) { +- NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx); +- envd->contentInfo.ciphcx = NULL; ++ if (envd && envd->contentInfo.private && envd->contentInfo.private->ciphcx) { ++ NSS_CMSCipherContext_Destroy(envd->contentInfo.private->ciphcx); ++ envd->contentInfo.private->ciphcx = NULL; + } + + return SECSuccess; +Index: ./mozilla/security/nss/lib/smime/cmslocal.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmslocal.h,v +retrieving revision 1.5 +retrieving revision 1.6 +diff -u -p -r1.5 -r1.6 +--- ./mozilla/security/nss/lib/smime/cmslocal.h 27 Jun 2005 22:21:18 -0000 1.5 ++++ ./mozilla/security/nss/lib/smime/cmslocal.h 28 Jan 2011 23:03:59 -0000 1.6 +@@ -42,7 +42,7 @@ + * you. If that has a problem, then just move out what you need, changing + * its name as appropriate! + * +- * $Id: cmslocal.h,v 1.5 2005/06/27 22:21:18 julien.pierre.bugs%sun.com Exp $ ++ * $Id: cmslocal.h,v 1.6 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #ifndef _CMSLOCAL_H_ +@@ -54,9 +54,25 @@ + + extern const SEC_ASN1Template NSSCMSContentInfoTemplate[]; + ++struct NSSCMSContentInfoPrivateStr { ++ NSSCMSCipherContext *ciphcx; ++ NSSCMSDigestContext *digcx; ++ PRBool dontStream; ++}; ++ + /************************************************************************/ + SEC_BEGIN_PROTOS + ++/* ++ * private content Info stuff ++ */ ++ ++/* initialize the private content info field. If this returns ++ * SECSuccess, the cinfo->private field is safe to dereference. ++ */ ++SECStatus NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo); ++ ++ + /*********************************************************************** + * cmscipher.c - en/decryption routines + ***********************************************************************/ +@@ -340,7 +356,34 @@ NSS_CMSAttributeArray_SetAttr(PLArenaPoo + extern SECStatus + NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert); + ++ + /************************************************************************/ ++ ++/* ++ * local functions to handle user defined S/MIME content types ++ */ ++ ++ ++PRBool NSS_CMSType_IsWrapper(SECOidTag type); ++PRBool NSS_CMSType_IsData(SECOidTag type); ++size_t NSS_CMSType_GetContentSize(SECOidTag type); ++const SEC_ASN1Template * NSS_CMSType_GetTemplate(SECOidTag type); ++ ++void NSS_CMSGenericWrapperData_Destroy(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++SECStatus NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd); ++ + SEC_END_PROTOS + + #endif /* _CMSLOCAL_H_ */ +Index: ./mozilla/security/nss/lib/smime/cmsmessage.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsmessage.c,v +retrieving revision 1.6 +retrieving revision 1.7 +diff -u -p -r1.6 -r1.7 +--- ./mozilla/security/nss/lib/smime/cmsmessage.c 25 Apr 2004 15:03:16 -0000 1.6 ++++ ./mozilla/security/nss/lib/smime/cmsmessage.c 28 Jan 2011 23:03:59 -0000 1.7 +@@ -37,7 +37,7 @@ + /* + * CMS message methods. + * +- * $Id: cmsmessage.c,v 1.6 2004/04/25 15:03:16 gerv%gerv.net Exp $ ++ * $Id: cmsmessage.c,v 1.7 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -81,6 +81,7 @@ NSS_CMSMessage_Create(PLArenaPool *poolp + PORT_FreeArena(poolp, PR_FALSE); + return NULL; + } ++ NSS_CMSContentInfo_Private_Init(&(cmsg->contentInfo)); + + cmsg->poolp = poolp; + cmsg->poolp_is_ours = poolp_is_ours; +@@ -234,11 +235,12 @@ NSS_CMSMessage_ContainsCertsOrCrls(NSSCM + + /* descend into CMS message */ + for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { +- if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) ++ if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(cinfo))) + continue; /* next level */ + + if (NSS_CMSSignedData_ContainsCertsOrCrls(cinfo->content.signedData)) + return PR_TRUE; ++ /* callback here for generic wrappers? */ + } + return PR_FALSE; + } +@@ -259,6 +261,7 @@ NSS_CMSMessage_IsEncrypted(NSSCMSMessage + case SEC_OID_PKCS7_ENCRYPTED_DATA: + return PR_TRUE; + default: ++ /* callback here for generic wrappers? */ + break; + } + } +@@ -289,6 +292,7 @@ NSS_CMSMessage_IsSigned(NSSCMSMessage *c + return PR_TRUE; + break; + default: ++ /* callback here for generic wrappers? */ + break; + } + } +Index: ./mozilla/security/nss/lib/smime/cmssigdata.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmssigdata.c,v +retrieving revision 1.29 +retrieving revision 1.30 +diff -u -p -r1.29 -r1.30 +--- ./mozilla/security/nss/lib/smime/cmssigdata.c 27 Jun 2005 22:21:18 -0000 1.29 ++++ ./mozilla/security/nss/lib/smime/cmssigdata.c 28 Jan 2011 23:03:59 -0000 1.30 +@@ -37,7 +37,7 @@ + /* + * CMS signedData methods. + * +- * $Id: cmssigdata.c,v 1.29 2005/06/27 22:21:18 julien.pierre.bugs%sun.com Exp $ ++ * $Id: cmssigdata.c,v 1.30 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -217,17 +217,22 @@ loser: + SECStatus + NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd) + { ++ SECStatus rv; + if (!sigd) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } ++ rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } + /* set up the digests */ + if (sigd->digests && sigd->digests[0]) { +- sigd->contentInfo.digcx = NULL; /* don't attempt to make new ones. */ ++ sigd->contentInfo.private->digcx = NULL; /* don't attempt to make new ones. */ + } else if (sigd->digestAlgorithms != NULL) { +- sigd->contentInfo.digcx = ++ sigd->contentInfo.private->digcx = + NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); +- if (sigd->contentInfo.digcx == NULL) ++ if (sigd->contentInfo.private->digcx == NULL) + return SECFailure; + } + return SECSuccess; +@@ -267,11 +272,11 @@ NSS_CMSSignedData_Encode_AfterData(NSSCM + cinfo = &(sigd->contentInfo); + + /* did we have digest calculation going on? */ +- if (cinfo->digcx) { +- rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, ++ if (cinfo->private && cinfo->private->digcx) { ++ rv = NSS_CMSDigestContext_FinishMultiple(cinfo->private->digcx, poolp, + &(sigd->digests)); + /* error has been set by NSS_CMSDigestContext_FinishMultiple */ +- cinfo->digcx = NULL; ++ cinfo->private->digcx = NULL; + if (rv != SECSuccess) + goto loser; + } +@@ -392,15 +397,20 @@ loser: + SECStatus + NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd) + { ++ SECStatus rv; + if (!sigd) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } ++ rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } + /* set up the digests */ + if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) { + /* if digests are already there, do nothing */ +- sigd->contentInfo.digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); +- if (sigd->contentInfo.digcx == NULL) ++ sigd->contentInfo.private->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); ++ if (sigd->contentInfo.private->digcx == NULL) + return SECFailure; + } + return SECSuccess; +@@ -421,11 +431,11 @@ NSS_CMSSignedData_Decode_AfterData(NSSCM + } + + /* did we have digest calculation going on? */ +- if (sigd->contentInfo.digcx) { +- rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx, ++ if (sigd->contentInfo.private && sigd->contentInfo.private->digcx) { ++ rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.private->digcx, + sigd->cmsg->poolp, &(sigd->digests)); + /* error set by NSS_CMSDigestContext_FinishMultiple */ +- sigd->contentInfo.digcx = NULL; ++ sigd->contentInfo.private->digcx = NULL; + } + return rv; + } +Index: ./mozilla/security/nss/lib/smime/cmssiginfo.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmssiginfo.c,v +retrieving revision 1.32.2.1 +retrieving revision 1.33 +diff -u -p -r1.32.2.1 -r1.33 +--- ./mozilla/security/nss/lib/smime/cmssiginfo.c 28 Aug 2010 19:51:44 -0000 1.32.2.1 ++++ ./mozilla/security/nss/lib/smime/cmssiginfo.c 28 Aug 2010 18:09:09 -0000 1.33 +@@ -38,7 +38,7 @@ + /* + * CMS signerInfo methods. + * +- * $Id: cmssiginfo.c,v 1.32.2.1 2010/08/28 19:51:44 nelson%bolyard.com Exp $ ++ * $Id: cmssiginfo.c,v 1.33 2010/08/28 18:09:09 nelson%bolyard.com Exp $ + */ + + #include "cmslocal.h" +Index: ./mozilla/security/nss/lib/smime/cmst.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmst.h,v +retrieving revision 1.10 +retrieving revision 1.12 +diff -u -p -r1.10 -r1.12 +--- ./mozilla/security/nss/lib/smime/cmst.h 27 Jun 2005 22:21:19 -0000 1.10 ++++ ./mozilla/security/nss/lib/smime/cmst.h 31 Jan 2011 23:56:30 -0000 1.12 +@@ -37,7 +37,7 @@ + /* + * Header for CMS types. + * +- * $Id: cmst.h,v 1.10 2005/06/27 22:21:19 julien.pierre.bugs%sun.com Exp $ ++ * $Id: cmst.h,v 1.12 2011/01/31 23:56:30 rrelyea%redhat.com Exp $ + */ + + #ifndef _CMST_H_ +@@ -98,6 +98,8 @@ typedef struct NSSCMSRecipientInfoStr NS + typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData; + typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData; + ++typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData; ++ + typedef struct NSSCMSSMIMEKEAParametersStr NSSCMSSMIMEKEAParameters; + + typedef struct NSSCMSAttributeStr NSSCMSAttribute; +@@ -108,6 +110,21 @@ typedef struct NSSCMSEncoderContextStr N + typedef struct NSSCMSCipherContextStr NSSCMSCipherContext; + typedef struct NSSCMSDigestContextStr NSSCMSDigestContext; + ++typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate; ++ ++typedef SECStatus (*NSSCMSGenericWrapperDataCallback) ++ (NSSCMSGenericWrapperData *); ++typedef void (*NSSCMSGenericWrapperDataDestroy) ++ (NSSCMSGenericWrapperData *); ++ ++extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[]; ++extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[]; ++ ++SEC_ASN1_CHOOSER_DECLARE(NSS_PointerToCMSGenericWrapperDataTemplate) ++SEC_ASN1_CHOOSER_DECLARE(NSSCMSGenericWrapperDataTemplate) ++ ++ ++ + /* + * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart. + * If specified, this is where the content bytes (only) will be "sent" +@@ -142,6 +159,7 @@ union NSSCMSContentUnion { + NSSCMSEncryptedData * encryptedData; + NSSCMSEnvelopedData * envelopedData; + NSSCMSSignedData * signedData; ++ NSSCMSGenericWrapperData * genericData; + /* or anonymous pointer to something */ + void * pointer; + }; +@@ -164,8 +182,8 @@ struct NSSCMSContentInfoStr { + * (only used by creation code) */ + SECOidTag contentEncAlgTag; /* oid tag of encryption algorithm + * (only used by creation code) */ +- NSSCMSCipherContext *ciphcx; /* context for en/decryption going on */ +- NSSCMSDigestContext *digcx; /* context for digesting going on */ ++ NSSCMSContentInfoPrivate *private; /* place for NSS private info */ ++ void *reserved; /* keep binary compatibility */ + }; + + /* ============================================================================= +@@ -186,6 +204,18 @@ struct NSSCMSMessageStr { + void * decrypt_key_cb_arg; + }; + ++/* ============================================================================ ++ * GENERIC WRAPPER ++ * ++ * used for user defined types. ++ */ ++struct NSSCMSGenericWrapperDataStr { ++ NSSCMSContentInfo contentInfo; ++ /* ---- local; not part of encoding ------ */ ++ NSSCMSMessage * cmsg; ++ /* wrapperspecific data starts here */ ++}; ++ + /* ============================================================================= + * SIGNEDDATA + */ +Index: ./mozilla/security/nss/lib/smime/cmsudf.c +=================================================================== +RCS file: ./mozilla/security/nss/lib/smime/cmsudf.c +diff -N ./mozilla/security/nss/lib/smime/cmsudf.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ ./mozilla/security/nss/lib/smime/cmsudf.c 31 Jan 2011 23:56:30 -0000 1.2 +@@ -0,0 +1,480 @@ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is the Netscape security libraries. ++ * ++ * The Initial Developer of the Original Code is ++ * Netscape Communications Corporation. ++ * Portions created by the Initial Developer are Copyright (C) 1994-2000 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++/* ++ * CMS User Define Types ++ * ++ * $Id: cmsudf.c,v 1.2 2011/01/31 23:56:30 rrelyea%redhat.com Exp $ ++ */ ++ ++#include "cmslocal.h" ++ ++#include "prinit.h" ++#include "pk11func.h" ++#include "secitem.h" ++#include "secoid.h" ++#include "secerr.h" ++#include "nss.h" ++ ++typedef struct nsscmstypeInfoStr nsscmstypeInfo; ++struct nsscmstypeInfoStr { ++ SECOidTag type; ++ SEC_ASN1Template *template; ++ size_t size; ++ PRBool isData; ++ NSSCMSGenericWrapperDataDestroy destroy; ++ NSSCMSGenericWrapperDataCallback decode_before; ++ NSSCMSGenericWrapperDataCallback decode_after; ++ NSSCMSGenericWrapperDataCallback decode_end; ++ NSSCMSGenericWrapperDataCallback encode_start; ++ NSSCMSGenericWrapperDataCallback encode_before; ++ NSSCMSGenericWrapperDataCallback encode_after; ++}; ++ ++/* make sure the global tables are only initialized once */ ++static PRCallOnceType nsscmstypeOnce; ++static PRCallOnceType nsscmstypeClearOnce; ++/* lock for adding a new entry */ ++static PRLock *nsscmstypeAddLock; ++/* lock for the hash table */ ++static PRLock *nsscmstypeHashLock; ++/* the hash table itself */ ++static PLHashTable *nsscmstypeHash; ++/* arena to hold all the hash table data */ ++static PRArenaPool *nsscmstypeArena; ++ ++/* ++ * clean up our global tables ++ */ ++SECStatus ++nss_cmstype_shutdown(void *appData, void *reserved) ++{ ++ if (nsscmstypeHashLock) { ++ PR_Lock(nsscmstypeHashLock); ++ } ++ if (nsscmstypeHash) { ++ PL_HashTableDestroy(nsscmstypeHash); ++ nsscmstypeHash = NULL; ++ } ++ if (nsscmstypeArena) { ++ PORT_FreeArena(nsscmstypeArena, PR_FALSE); ++ nsscmstypeArena = NULL; ++ } ++ if (nsscmstypeAddLock) { ++ PR_DestroyLock(nsscmstypeAddLock); ++ } ++ if (nsscmstypeHashLock) { ++ PRLock *oldLock = nsscmstypeHashLock; ++ nsscmstypeHashLock = NULL; ++ PR_Unlock(oldLock); ++ PR_DestroyLock(oldLock); ++ } ++ ++ /* don't clear out the PR_ONCE data if we failed our inital call */ ++ if (appData == NULL) { ++ nsscmstypeOnce = nsscmstypeClearOnce; ++ } ++ return SECSuccess; ++} ++ ++static PLHashNumber ++nss_cmstype_hash_key(const void *key) ++{ ++ return (PLHashNumber) key; ++} ++ ++static PRIntn ++nss_cmstype_compare_keys(const void *v1, const void *v2) ++{ ++ PLHashNumber value1 = (PLHashNumber) v1; ++ PLHashNumber value2 = (PLHashNumber) v2; ++ ++ return (value1 == value2); ++} ++ ++/* ++ * initialize our hash tables, called once on the first attemat to register ++ * a new SMIME type. ++ */ ++static PRStatus ++nss_cmstype_init(void) ++{ ++ SECStatus rv; ++ ++ nsscmstypeHashLock = PR_NewLock(); ++ if (nsscmstypeHashLock == NULL) { ++ return PR_FAILURE; ++ } ++ nsscmstypeAddLock = PR_NewLock(); ++ if (nsscmstypeHashLock == NULL) { ++ goto fail; ++ } ++ nsscmstypeHash = PL_NewHashTable(64, nss_cmstype_hash_key, ++ nss_cmstype_compare_keys, PL_CompareValues, NULL, NULL); ++ if (nsscmstypeHash == NULL) { ++ goto fail; ++ } ++ nsscmstypeArena = PORT_NewArena(2048); ++ if (nsscmstypeArena == NULL) { ++ goto fail; ++ } ++ rv = NSS_RegisterShutdown(nss_cmstype_shutdown, NULL); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ return PR_SUCCESS; ++ ++fail: ++ nss_cmstype_shutdown(&nsscmstypeOnce, NULL); ++ return PR_FAILURE; ++} ++ ++ ++/* ++ * look up and registered SIME type ++ */ ++static const nsscmstypeInfo * ++nss_cmstype_lookup(SECOidTag type) ++{ ++ nsscmstypeInfo *typeInfo = NULL;; ++ if (!nsscmstypeHash) { ++ return NULL; ++ } ++ PR_Lock(nsscmstypeHashLock); ++ if (nsscmstypeHash) { ++ typeInfo = PL_HashTableLookupConst(nsscmstypeHash, (void *)type); ++ } ++ PR_Unlock(nsscmstypeHashLock); ++ return typeInfo; ++} ++ ++/* ++ * add a new type to the SMIME type table ++ */ ++static SECStatus ++nss_cmstype_add(SECOidTag type, nsscmstypeInfo *typeinfo) ++{ ++ PLHashEntry *entry; ++ ++ if (!nsscmstypeHash) { ++ /* assert? this shouldn't happen */ ++ return SECFailure; ++ } ++ PR_Lock(nsscmstypeHashLock); ++ /* this is really paranoia. If we really are racing nsscmstypeHash, we'll ++ * also be racing nsscmstypeHashLock... */ ++ if (!nsscmstypeHash) { ++ PR_Unlock(nsscmstypeHashLock); ++ return SECFailure; ++ } ++ entry = PL_HashTableAdd(nsscmstypeHash, (void *)type, typeinfo); ++ PR_Unlock(nsscmstypeHashLock); ++ return entry ? SECSuccess : SECFailure; ++} ++ ++ ++/* helper functions to manage new content types ++ */ ++ ++PRBool ++NSS_CMSType_IsWrapper(SECOidTag type) ++{ ++ const nsscmstypeInfo *typeInfo = NULL; ++ ++ switch (type) { ++ case SEC_OID_PKCS7_SIGNED_DATA: ++ case SEC_OID_PKCS7_ENVELOPED_DATA: ++ case SEC_OID_PKCS7_DIGESTED_DATA: ++ case SEC_OID_PKCS7_ENCRYPTED_DATA: ++ return PR_TRUE; ++ default: ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo && !typeInfo->isData) { ++ return PR_TRUE; ++ } ++ } ++ return PR_FALSE; ++} ++ ++PRBool ++NSS_CMSType_IsData(SECOidTag type) ++{ ++ const nsscmstypeInfo *typeInfo = NULL; ++ ++ switch (type) { ++ case SEC_OID_PKCS7_DATA: ++ return PR_TRUE; ++ default: ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo && typeInfo->isData) { ++ return PR_TRUE; ++ } ++ } ++ return PR_FALSE; ++} ++ ++const SEC_ASN1Template * ++NSS_CMSType_GetTemplate(SECOidTag type) ++{ ++ const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type); ++ ++ if (typeInfo && typeInfo->template) { ++ return typeInfo->template; ++ } ++ return SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); ++} ++ ++size_t ++NSS_CMSType_GetContentSize(SECOidTag type) ++{ ++ const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type); ++ ++ if (typeInfo) { ++ return typeInfo->size; ++ } ++ return sizeof(SECItem *); ++ ++} ++ ++void ++NSS_CMSGenericWrapperData_Destroy(SECOidTag type, NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type); ++ ++ if (typeInfo && typeInfo->destroy) { ++ (*typeInfo->destroy)(gd); ++ } ++ ++} ++ ++ ++SECStatus ++NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->decode_before) { ++ return (*typeInfo->decode_before)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++ ++} ++ ++SECStatus ++NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->decode_after) { ++ return (*typeInfo->decode_after)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++} ++ ++SECStatus ++NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->decode_end) { ++ return (*typeInfo->decode_end)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++} ++ ++SECStatus ++NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->encode_start) { ++ return (*typeInfo->encode_start)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++} ++ ++SECStatus ++NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->encode_before) { ++ return (*typeInfo->encode_before)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++} ++ ++SECStatus ++NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type, ++ NSSCMSGenericWrapperData *gd) ++{ ++ const nsscmstypeInfo *typeInfo; ++ ++ /* short cut common case */ ++ if (type == SEC_OID_PKCS7_DATA) { ++ return SECSuccess; ++ } ++ ++ typeInfo = nss_cmstype_lookup(type); ++ if (typeInfo) { ++ if (typeInfo->encode_after) { ++ return (*typeInfo->encode_after)(gd); ++ } ++ /* decoder ops optional for data tags */ ++ if (typeInfo->isData) { ++ return SECSuccess; ++ } ++ } ++ /* expected a function, but none existed */ ++ return SECFailure; ++} ++ ++ ++SECStatus ++NSS_CMSType_RegisterContentType(SECOidTag type, ++ SEC_ASN1Template *template, size_t size, ++ NSSCMSGenericWrapperDataDestroy destroy, ++ NSSCMSGenericWrapperDataCallback decode_before, ++ NSSCMSGenericWrapperDataCallback decode_after, ++ NSSCMSGenericWrapperDataCallback decode_end, ++ NSSCMSGenericWrapperDataCallback encode_start, ++ NSSCMSGenericWrapperDataCallback encode_before, ++ NSSCMSGenericWrapperDataCallback encode_after, ++ PRBool isData) ++{ ++ PRStatus rc; ++ SECStatus rv; ++ nsscmstypeInfo *typeInfo; ++ const nsscmstypeInfo *exists; ++ ++ rc = PR_CallOnce( &nsscmstypeOnce, nss_cmstype_init); ++ if (rc == PR_FAILURE) { ++ return SECFailure; ++ } ++ PR_Lock(nsscmstypeAddLock); ++ exists = nss_cmstype_lookup(type); ++ if (exists) { ++ PR_Unlock(nsscmstypeAddLock); ++ /* already added */ ++ return SECSuccess; ++ } ++ typeInfo = PORT_ArenaNew(nsscmstypeArena, nsscmstypeInfo); ++ typeInfo->type =type; ++ typeInfo->size = size; ++ typeInfo->isData = isData; ++ typeInfo->template = template; ++ typeInfo->destroy = destroy; ++ typeInfo->decode_before = decode_before; ++ typeInfo->decode_after = decode_after; ++ typeInfo->decode_end = decode_end; ++ typeInfo->encode_start = encode_start; ++ typeInfo->encode_before = encode_before; ++ typeInfo->encode_after = encode_after; ++ rv = nss_cmstype_add(type, typeInfo); ++ PR_Unlock(nsscmstypeAddLock); ++ return rv; ++} ++ +Index: ./mozilla/security/nss/lib/smime/cmsutil.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/cmsutil.c,v +retrieving revision 1.15 +retrieving revision 1.16 +diff -u -p -r1.15 -r1.16 +--- ./mozilla/security/nss/lib/smime/cmsutil.c 10 Mar 2008 00:01:27 -0000 1.15 ++++ ./mozilla/security/nss/lib/smime/cmsutil.c 28 Jan 2011 23:03:59 -0000 1.16 +@@ -38,7 +38,7 @@ + /* + * CMS miscellaneous utility functions. + * +- * $Id: cmsutil.c,v 1.15 2008/03/10 00:01:27 wtc%google.com Exp $ ++ * $Id: cmsutil.c,v 1.16 2011/01/28 23:03:59 rrelyea%redhat.com Exp $ + */ + + #include "cmslocal.h" +@@ -243,8 +243,7 @@ NSS_CMSUtil_GetTemplateByTypeTag(SECOidT + template = NSSCMSDigestedDataTemplate; + break; + default: +- case SEC_OID_PKCS7_DATA: +- template = NULL; ++ template = NSS_CMSType_GetTemplate(type); + break; + } + return template; +@@ -269,8 +268,7 @@ NSS_CMSUtil_GetSizeByTypeTag(SECOidTag t + size = sizeof(NSSCMSDigestedData); + break; + default: +- case SEC_OID_PKCS7_DATA: +- size = 0; ++ size = NSS_CMSType_GetContentSize(type); + break; + } + return size; +@@ -300,6 +298,9 @@ NSS_CMSContent_GetContentInfo(void *msg, + break; + default: + cinfo = NULL; ++ if (NSS_CMSType_IsWrapper(type)) { ++ cinfo = &(c.genericData->contentInfo); ++ } + } + return cinfo; + } +Index: ./mozilla/security/nss/lib/smime/manifest.mn +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/manifest.mn,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -u -p -r1.9 -r1.11 +--- ./mozilla/security/nss/lib/smime/manifest.mn 15 Aug 2007 15:30:03 -0000 1.9 ++++ ./mozilla/security/nss/lib/smime/manifest.mn 28 Jan 2011 23:03:59 -0000 1.11 +@@ -69,14 +69,13 @@ CSRCS = \ + cmsreclist.c \ + cmssigdata.c \ + cmssiginfo.c \ ++ cmsudf.c \ + cmsutil.c \ + smimemessage.c \ + smimeutil.c \ + smimever.c \ + $(NULL) + +-REQUIRES = dbm +- + LIBRARY_NAME = smime + LIBRARY_VERSION = 3 + +Index: ./mozilla/security/nss/lib/smime/smime.def +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/smime.def,v +retrieving revision 1.35 +retrieving revision 1.37 +diff -u -p -r1.35 -r1.37 +--- ./mozilla/security/nss/lib/smime/smime.def 30 Sep 2008 04:24:55 -0000 1.35 ++++ ./mozilla/security/nss/lib/smime/smime.def 31 Jan 2011 23:56:30 -0000 1.37 +@@ -273,3 +273,23 @@ SEC_PKCS12AddCertOrChainAndKey; + ;+ local: + ;+ *; + ;+}; ++;+NSS_3.12.10 { # NSS 3.12.10 release ++;+ global: ++NSS_CMSType_RegisterContentType; ++NSS_CMSContentInfo_SetDontStream; ++NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs; ++;+# ++;+# Data objects ++;+# ++;+# Don't export these DATA symbols on Windows because they don't work right. ++;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them. ++;+# ++;+# See nssutil for other examples. ++;+# ++;;NSSCMSGenericWrapperDataTemplate DATA ; ++;;NSS_PointerToCMSGenericWrapperDataTemplate DATA ; ++NSS_Get_NSSCMSGenericWrapperDataTemplate; ++NSS_Get_NSS_PointerToCMSGenericWrapperDataTemplate; ++;+ local: ++;+ *; ++;+}; +Index: ./mozilla/security/nss/lib/smime/smime.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/smime.h,v +retrieving revision 1.8 +retrieving revision 1.9 +diff -u -p -r1.8 -r1.9 +--- ./mozilla/security/nss/lib/smime/smime.h 25 Apr 2004 15:03:16 -0000 1.8 ++++ ./mozilla/security/nss/lib/smime/smime.h 11 Oct 2010 19:30:10 -0000 1.9 +@@ -38,7 +38,7 @@ + * Header file for routines specific to S/MIME. Keep things that are pure + * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc. + * +- * $Id: smime.h,v 1.8 2004/04/25 15:03:16 gerv%gerv.net Exp $ ++ * $Id: smime.h,v 1.9 2010/10/11 19:30:10 wtc%google.com Exp $ + */ + + #ifndef _SECMIME_H_ +@@ -83,7 +83,7 @@ extern SECStatus NSS_SMIMEUtil_EnableCip + * Initialize the local recording of the S/MIME policy. + * This function is called to allow/disallow a particular cipher. + * +- * XXX This is for a the current module, I think, so local, static storage ++ * XXX This is for the current module, I think, so local, static storage + * XXX is okay. Is that correct, or could multiple uses of the same + * XXX library expect to operate under different policies? + * +Index: ./mozilla/security/nss/lib/cryptohi/seckey.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/cryptohi/seckey.c,v +retrieving revision 1.54 +retrieving revision 1.54.2.1 +diff -u -p -r1.54 -r1.54.2.1 +--- ./mozilla/security/nss/lib/cryptohi/seckey.c 23 Jun 2010 02:13:56 -0000 1.54 ++++ ./mozilla/security/nss/lib/cryptohi/seckey.c 28 Jan 2011 23:07:46 -0000 1.54.2.1 +@@ -1000,6 +1000,15 @@ seckey_GetKeyType (SECOidTag tag) { + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: + keyType = ecKey; + break; ++ /* accommodate applications that hand us a signature type when they ++ * should be handing us a cipher type */ ++ case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: ++ case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: ++ keyType = rsaKey; ++ break; + default: + keyType = nullKey; + } diff --git a/nss.spec b/nss.spec index 049cd9e..0ed8a30 100644 --- a/nss.spec +++ b/nss.spec @@ -6,7 +6,7 @@ Summary: Network Security Services Name: nss Version: 3.12.9 -Release: 3%{?dist} +Release: 4%{?dist} License: MPLv1.1 or GPLv2+ or LGPLv2+ URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries @@ -43,6 +43,7 @@ Patch3: renegotiate-transitional.patch Patch6: nss-enable-pem.patch Patch7: nsspem-642433.patch Patch11: honor-user-trust-preferences.patch +Patch12: allow-content-types-beyond-smime.patch %description Network Security Services (NSS) is a set of libraries designed to @@ -115,6 +116,7 @@ low level services. %patch6 -p0 -b .libpem %patch7 -p0 -b .642433 %patch11 -p1 -b .643134 +%patch12 -p1 -b .contenttypes %build @@ -490,6 +492,9 @@ rm -rf $RPM_BUILD_ROOT/%{_includedir}/nss3/nsslowhash.h %{_libdir}/libnssckfw.a %changelog +* Tue Feb 01 2011 Elio Maldonado - 3.12.9-4 +- Fix infinite recursion when encoding NSS enveloped/digested data (#499444) + * Mon Jan 31 2011 Elio Maldonado - 3.12.9-3 - Update the cacert trust patch per upstream review requests (#633043)