security/nss/lib/smime/cmscinfo.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * CMS contentInfo methods.
     7  */
     9 #include "cmslocal.h"
    11 #include "pk11func.h"
    12 #include "secitem.h"
    13 #include "secoid.h"
    14 #include "secerr.h"
    17 /*
    18  * NSS_CMSContentInfo_Create - create a content info
    19  *
    20  * version is set in the _Finalize procedures for each content type
    21  */
    22 SECStatus
    23 NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo)
    24 {
    25     if (cinfo->privateInfo) {
    26 	return SECSuccess;
    27     }
    28     cinfo->privateInfo = PORT_ZNew(NSSCMSContentInfoPrivate);
    29     return (cinfo->privateInfo) ? SECSuccess : SECFailure;
    30 }
    33 static void
    34 nss_cmsContentInfo_private_destroy(NSSCMSContentInfoPrivate *privateInfo)
    35 {
    36     if (privateInfo->digcx) {
    37 	/* must destroy digest objects */
    38 	NSS_CMSDigestContext_Cancel(privateInfo->digcx);
    39 	privateInfo->digcx = NULL;
    40     }
    41     if (privateInfo->ciphcx) {
    42 	NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
    43 	privateInfo->ciphcx = NULL;
    44     }
    45     PORT_Free(privateInfo);
    46 }
    48 /*
    49  * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
    50  */
    51 void
    52 NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
    53 {
    54     SECOidTag kind;
    56     kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    57     switch (kind) {
    58     case SEC_OID_PKCS7_ENVELOPED_DATA:
    59 	NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
    60 	break;
    61       case SEC_OID_PKCS7_SIGNED_DATA:
    62 	NSS_CMSSignedData_Destroy(cinfo->content.signedData);
    63 	break;
    64       case SEC_OID_PKCS7_ENCRYPTED_DATA:
    65 	NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
    66 	break;
    67       case SEC_OID_PKCS7_DIGESTED_DATA:
    68 	NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
    69 	break;
    70       default:
    71 	NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData);
    72 	/* XXX Anything else that needs to be "manually" freed/destroyed? */
    73 	break;
    74     }
    75     if (cinfo->privateInfo) {
    76 	nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
    77 	cinfo->privateInfo = NULL;
    78     }
    79     if (cinfo->bulkkey) {
    80 	PK11_FreeSymKey(cinfo->bulkkey);
    81     }
    82 }
    84 /*
    85  * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
    86  */
    87 NSSCMSContentInfo *
    88 NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
    89 {
    90     NSSCMSContentInfo * ccinfo  = NULL;
    91     SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    92     switch (tag) {
    93     case SEC_OID_PKCS7_SIGNED_DATA:
    94 	if (cinfo->content.signedData != NULL) {
    95 	    ccinfo = &(cinfo->content.signedData->contentInfo);
    96 	}
    97 	break;
    98     case SEC_OID_PKCS7_ENVELOPED_DATA:
    99 	if (cinfo->content.envelopedData != NULL) {
   100 	    ccinfo = &(cinfo->content.envelopedData->contentInfo);
   101 	}
   102 	break;
   103     case SEC_OID_PKCS7_DIGESTED_DATA:
   104 	if (cinfo->content.digestedData != NULL) {
   105 	    ccinfo = &(cinfo->content.digestedData->contentInfo);
   106 	}
   107 	break;
   108     case SEC_OID_PKCS7_ENCRYPTED_DATA:
   109 	if (cinfo->content.encryptedData != NULL) {
   110 	    ccinfo = &(cinfo->content.encryptedData->contentInfo);
   111 	}
   112 	break;
   113     case SEC_OID_PKCS7_DATA:
   114     default:
   115 	if (NSS_CMSType_IsWrapper(tag)) {
   116 	    if (cinfo->content.genericData != NULL) {
   117 	       ccinfo = &(cinfo->content.genericData->contentInfo);
   118 	    }
   119 	}
   120 	break;
   121     }
   122     if (ccinfo && !ccinfo->privateInfo) {
   123 	NSS_CMSContentInfo_Private_Init(ccinfo);
   124     }
   125     return ccinfo;
   126 }
   128 SECStatus
   129 NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream)
   130 {
   131    SECStatus rv;
   133    rv = NSS_CMSContentInfo_Private_Init(cinfo);
   134    if (rv != SECSuccess) {
   135 	/* default is streaming, failure to get ccinfo will not effect this */
   136 	return dontStream ? SECFailure :  SECSuccess ;
   137    }
   138    cinfo->privateInfo->dontStream = dontStream;
   139    return SECSuccess;
   140 }
   142 /*
   143  * NSS_CMSContentInfo_SetContent - set content type & content
   144  */
   145 SECStatus
   146 NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
   147 {
   148     SECStatus rv;
   150     cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
   151     if (cinfo->contentTypeTag == NULL)
   152 	return SECFailure;
   154     /* do not copy the oid, just create a reference */
   155     rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
   156     if (rv != SECSuccess)
   157 	return SECFailure;
   159     cinfo->content.pointer = ptr;
   161     if (NSS_CMSType_IsData(type) && ptr) {
   162 	cinfo->rawContent = ptr;
   163     } else {
   164 	/* as we always have some inner data,
   165 	 * we need to set it to something, just to fool the encoder enough to work on it
   166 	 * and get us into nss_cms_encoder_notify at that point */
   167 	cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
   168 	if (cinfo->rawContent == NULL) {
   169 	    PORT_SetError(SEC_ERROR_NO_MEMORY);
   170 	    return SECFailure;
   171 	}
   172     }
   174     return SECSuccess;
   175 }
   177 /*
   178  * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent
   179  */
   181 /*
   182  * data == NULL -> pass in data via NSS_CMSEncoder_Update
   183  * data != NULL -> take this data
   184  */
   185 SECStatus
   186 NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
   187 {
   188     if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
   189 	return SECFailure;
   190     if (detached) {
   191         cinfo->rawContent = NULL;
   192     }
   194     return SECSuccess;
   195 }
   197 SECStatus
   198 NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
   199 {
   200     return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
   201 }
   203 SECStatus
   204 NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
   205 {
   206     return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
   207 }
   209 SECStatus
   210 NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
   211 {
   212     return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
   213 }
   215 SECStatus
   216 NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
   217 {
   218     return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
   219 }
   222 /*
   223  * NSS_CMSContentInfo_GetContent - get pointer to inner content
   224  *
   225  * needs to be casted...
   226  */
   227 void *
   228 NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
   229 {
   230     SECOidTag tag = (cinfo && cinfo->contentTypeTag) 
   231 	                ? cinfo->contentTypeTag->offset 
   232 	                : SEC_OID_UNKNOWN;
   233     switch (tag) {
   234     case SEC_OID_PKCS7_DATA:
   235     case SEC_OID_PKCS7_SIGNED_DATA:
   236     case SEC_OID_PKCS7_ENVELOPED_DATA:
   237     case SEC_OID_PKCS7_DIGESTED_DATA:
   238     case SEC_OID_PKCS7_ENCRYPTED_DATA:
   239 	return cinfo->content.pointer;
   240     default:
   241 	return NSS_CMSType_IsWrapper(tag) ? cinfo->content.pointer : (NSS_CMSType_IsData(tag) ? cinfo->rawContent : NULL);
   242     }
   243 }
   245 /* 
   246  * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
   247  *
   248  * this is typically only called by NSS_CMSMessage_GetContent()
   249  */
   251 SECItem *
   252 NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
   253 {
   254     NSSCMSContentInfo *ccinfo;
   255     SECOidTag          tag;
   256     SECItem           *pItem = NULL;
   258     tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
   259     if (NSS_CMSType_IsData(tag)) {
   260 	pItem = cinfo->content.data; 
   261     } else if (NSS_CMSType_IsWrapper(tag)) {
   262 	ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
   263 	if (ccinfo != NULL) {
   264 	    pItem = NSS_CMSContentInfo_GetContent(ccinfo);
   265 	}
   266     } else {
   267 	PORT_Assert(0);
   268     }
   270     return pItem;
   271 }
   274 /*
   275  * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
   276  * for future reference) and return the inner content type.
   277  */
   278 SECOidTag
   279 NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
   280 {
   281     if (cinfo->contentTypeTag == NULL)
   282 	cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
   284     if (cinfo->contentTypeTag == NULL)
   285 	return SEC_OID_UNKNOWN;
   287     return cinfo->contentTypeTag->offset;
   288 }
   290 SECItem *
   291 NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
   292 {
   293     if (cinfo->contentTypeTag == NULL)
   294 	cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
   296     if (cinfo->contentTypeTag == NULL)
   297 	return NULL;
   299     return &(cinfo->contentTypeTag->oid);
   300 }
   302 /*
   303  * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
   304  * for future reference) and return the content encryption algorithm tag.
   305  */
   306 SECOidTag
   307 NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
   308 {
   309     if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
   310 	cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
   312     return cinfo->contentEncAlgTag;
   313 }
   315 /*
   316  * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
   317  */
   318 SECAlgorithmID *
   319 NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
   320 {
   321     return &(cinfo->contentEncAlg);
   322 }
   324 SECStatus
   325 NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
   326 				    SECOidTag bulkalgtag, SECItem *parameters, int keysize)
   327 {
   328     SECStatus rv;
   330     rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
   331     if (rv != SECSuccess)
   332 	return SECFailure;
   333     cinfo->keysize = keysize;
   334     return SECSuccess;
   335 }
   337 SECStatus
   338 NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
   339 				    SECAlgorithmID *algid, int keysize)
   340 {
   341     SECStatus rv;
   343     rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
   344     if (rv != SECSuccess)
   345 	return SECFailure;
   346     if (keysize >= 0)
   347 	cinfo->keysize = keysize;
   348     return SECSuccess;
   349 }
   351 void
   352 NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
   353 {
   354     cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
   355     cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
   356 }
   358 PK11SymKey *
   359 NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
   360 {
   361     if (cinfo->bulkkey == NULL)
   362 	return NULL;
   364     return PK11_ReferenceSymKey(cinfo->bulkkey);
   365 }
   367 int
   368 NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo)
   369 {
   370     return cinfo->keysize;
   371 }

mercurial