453276ca4d
Add support in CMS for content types other than S/MIME
2283 lines
75 KiB
Diff
2283 lines
75 KiB
Diff
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;
|
|
}
|