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

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

mercurial