Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37429564
en ru br
Репозитории ALT
S:3.93.0-alt1
5.1: 3.12.9.0-alt1.M50P.1
4.1: 3.12.1-alt0.20080628.M41.2
4.0: 3.11.4-alt1
www.altlinux.org/Changes

Группа :: Система/Библиотеки
Пакет: nss

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: allow-content-types-beyond-smime.patch
Скачать


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;
     }
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin