security/nss/lib/smime/cmscinfo.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/smime/cmscinfo.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,371 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/*
     1.9 + * CMS contentInfo methods.
    1.10 + */
    1.11 +
    1.12 +#include "cmslocal.h"
    1.13 +
    1.14 +#include "pk11func.h"
    1.15 +#include "secitem.h"
    1.16 +#include "secoid.h"
    1.17 +#include "secerr.h"
    1.18 +
    1.19 +
    1.20 +/*
    1.21 + * NSS_CMSContentInfo_Create - create a content info
    1.22 + *
    1.23 + * version is set in the _Finalize procedures for each content type
    1.24 + */
    1.25 +SECStatus
    1.26 +NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo)
    1.27 +{
    1.28 +    if (cinfo->privateInfo) {
    1.29 +	return SECSuccess;
    1.30 +    }
    1.31 +    cinfo->privateInfo = PORT_ZNew(NSSCMSContentInfoPrivate);
    1.32 +    return (cinfo->privateInfo) ? SECSuccess : SECFailure;
    1.33 +}
    1.34 +
    1.35 +
    1.36 +static void
    1.37 +nss_cmsContentInfo_private_destroy(NSSCMSContentInfoPrivate *privateInfo)
    1.38 +{
    1.39 +    if (privateInfo->digcx) {
    1.40 +	/* must destroy digest objects */
    1.41 +	NSS_CMSDigestContext_Cancel(privateInfo->digcx);
    1.42 +	privateInfo->digcx = NULL;
    1.43 +    }
    1.44 +    if (privateInfo->ciphcx) {
    1.45 +	NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
    1.46 +	privateInfo->ciphcx = NULL;
    1.47 +    }
    1.48 +    PORT_Free(privateInfo);
    1.49 +}
    1.50 +
    1.51 +/*
    1.52 + * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
    1.53 + */
    1.54 +void
    1.55 +NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
    1.56 +{
    1.57 +    SECOidTag kind;
    1.58 +
    1.59 +    kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    1.60 +    switch (kind) {
    1.61 +    case SEC_OID_PKCS7_ENVELOPED_DATA:
    1.62 +	NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
    1.63 +	break;
    1.64 +      case SEC_OID_PKCS7_SIGNED_DATA:
    1.65 +	NSS_CMSSignedData_Destroy(cinfo->content.signedData);
    1.66 +	break;
    1.67 +      case SEC_OID_PKCS7_ENCRYPTED_DATA:
    1.68 +	NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
    1.69 +	break;
    1.70 +      case SEC_OID_PKCS7_DIGESTED_DATA:
    1.71 +	NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
    1.72 +	break;
    1.73 +      default:
    1.74 +	NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData);
    1.75 +	/* XXX Anything else that needs to be "manually" freed/destroyed? */
    1.76 +	break;
    1.77 +    }
    1.78 +    if (cinfo->privateInfo) {
    1.79 +	nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
    1.80 +	cinfo->privateInfo = NULL;
    1.81 +    }
    1.82 +    if (cinfo->bulkkey) {
    1.83 +	PK11_FreeSymKey(cinfo->bulkkey);
    1.84 +    }
    1.85 +}
    1.86 +
    1.87 +/*
    1.88 + * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
    1.89 + */
    1.90 +NSSCMSContentInfo *
    1.91 +NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
    1.92 +{
    1.93 +    NSSCMSContentInfo * ccinfo  = NULL;
    1.94 +    SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    1.95 +    switch (tag) {
    1.96 +    case SEC_OID_PKCS7_SIGNED_DATA:
    1.97 +	if (cinfo->content.signedData != NULL) {
    1.98 +	    ccinfo = &(cinfo->content.signedData->contentInfo);
    1.99 +	}
   1.100 +	break;
   1.101 +    case SEC_OID_PKCS7_ENVELOPED_DATA:
   1.102 +	if (cinfo->content.envelopedData != NULL) {
   1.103 +	    ccinfo = &(cinfo->content.envelopedData->contentInfo);
   1.104 +	}
   1.105 +	break;
   1.106 +    case SEC_OID_PKCS7_DIGESTED_DATA:
   1.107 +	if (cinfo->content.digestedData != NULL) {
   1.108 +	    ccinfo = &(cinfo->content.digestedData->contentInfo);
   1.109 +	}
   1.110 +	break;
   1.111 +    case SEC_OID_PKCS7_ENCRYPTED_DATA:
   1.112 +	if (cinfo->content.encryptedData != NULL) {
   1.113 +	    ccinfo = &(cinfo->content.encryptedData->contentInfo);
   1.114 +	}
   1.115 +	break;
   1.116 +    case SEC_OID_PKCS7_DATA:
   1.117 +    default:
   1.118 +	if (NSS_CMSType_IsWrapper(tag)) {
   1.119 +	    if (cinfo->content.genericData != NULL) {
   1.120 +	       ccinfo = &(cinfo->content.genericData->contentInfo);
   1.121 +	    }
   1.122 +	}
   1.123 +	break;
   1.124 +    }
   1.125 +    if (ccinfo && !ccinfo->privateInfo) {
   1.126 +	NSS_CMSContentInfo_Private_Init(ccinfo);
   1.127 +    }
   1.128 +    return ccinfo;
   1.129 +}
   1.130 +
   1.131 +SECStatus
   1.132 +NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream)
   1.133 +{
   1.134 +   SECStatus rv;
   1.135 +
   1.136 +   rv = NSS_CMSContentInfo_Private_Init(cinfo);
   1.137 +   if (rv != SECSuccess) {
   1.138 +	/* default is streaming, failure to get ccinfo will not effect this */
   1.139 +	return dontStream ? SECFailure :  SECSuccess ;
   1.140 +   }
   1.141 +   cinfo->privateInfo->dontStream = dontStream;
   1.142 +   return SECSuccess;
   1.143 +}
   1.144 +
   1.145 +/*
   1.146 + * NSS_CMSContentInfo_SetContent - set content type & content
   1.147 + */
   1.148 +SECStatus
   1.149 +NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
   1.150 +{
   1.151 +    SECStatus rv;
   1.152 +
   1.153 +    cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
   1.154 +    if (cinfo->contentTypeTag == NULL)
   1.155 +	return SECFailure;
   1.156 +    
   1.157 +    /* do not copy the oid, just create a reference */
   1.158 +    rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
   1.159 +    if (rv != SECSuccess)
   1.160 +	return SECFailure;
   1.161 +
   1.162 +    cinfo->content.pointer = ptr;
   1.163 +
   1.164 +    if (NSS_CMSType_IsData(type) && ptr) {
   1.165 +	cinfo->rawContent = ptr;
   1.166 +    } else {
   1.167 +	/* as we always have some inner data,
   1.168 +	 * we need to set it to something, just to fool the encoder enough to work on it
   1.169 +	 * and get us into nss_cms_encoder_notify at that point */
   1.170 +	cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
   1.171 +	if (cinfo->rawContent == NULL) {
   1.172 +	    PORT_SetError(SEC_ERROR_NO_MEMORY);
   1.173 +	    return SECFailure;
   1.174 +	}
   1.175 +    }
   1.176 +
   1.177 +    return SECSuccess;
   1.178 +}
   1.179 +
   1.180 +/*
   1.181 + * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent
   1.182 + */
   1.183 +
   1.184 +/*
   1.185 + * data == NULL -> pass in data via NSS_CMSEncoder_Update
   1.186 + * data != NULL -> take this data
   1.187 + */
   1.188 +SECStatus
   1.189 +NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
   1.190 +{
   1.191 +    if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
   1.192 +	return SECFailure;
   1.193 +    if (detached) {
   1.194 +        cinfo->rawContent = NULL;
   1.195 +    }
   1.196 +	
   1.197 +    return SECSuccess;
   1.198 +}
   1.199 +
   1.200 +SECStatus
   1.201 +NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
   1.202 +{
   1.203 +    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
   1.204 +}
   1.205 +
   1.206 +SECStatus
   1.207 +NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
   1.208 +{
   1.209 +    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
   1.210 +}
   1.211 +
   1.212 +SECStatus
   1.213 +NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
   1.214 +{
   1.215 +    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
   1.216 +}
   1.217 +
   1.218 +SECStatus
   1.219 +NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
   1.220 +{
   1.221 +    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
   1.222 +}
   1.223 +
   1.224 +
   1.225 +/*
   1.226 + * NSS_CMSContentInfo_GetContent - get pointer to inner content
   1.227 + *
   1.228 + * needs to be casted...
   1.229 + */
   1.230 +void *
   1.231 +NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
   1.232 +{
   1.233 +    SECOidTag tag = (cinfo && cinfo->contentTypeTag) 
   1.234 +	                ? cinfo->contentTypeTag->offset 
   1.235 +	                : SEC_OID_UNKNOWN;
   1.236 +    switch (tag) {
   1.237 +    case SEC_OID_PKCS7_DATA:
   1.238 +    case SEC_OID_PKCS7_SIGNED_DATA:
   1.239 +    case SEC_OID_PKCS7_ENVELOPED_DATA:
   1.240 +    case SEC_OID_PKCS7_DIGESTED_DATA:
   1.241 +    case SEC_OID_PKCS7_ENCRYPTED_DATA:
   1.242 +	return cinfo->content.pointer;
   1.243 +    default:
   1.244 +	return NSS_CMSType_IsWrapper(tag) ? cinfo->content.pointer : (NSS_CMSType_IsData(tag) ? cinfo->rawContent : NULL);
   1.245 +    }
   1.246 +}
   1.247 +
   1.248 +/* 
   1.249 + * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
   1.250 + *
   1.251 + * this is typically only called by NSS_CMSMessage_GetContent()
   1.252 + */
   1.253 +
   1.254 +SECItem *
   1.255 +NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
   1.256 +{
   1.257 +    NSSCMSContentInfo *ccinfo;
   1.258 +    SECOidTag          tag;
   1.259 +    SECItem           *pItem = NULL;
   1.260 +
   1.261 +    tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
   1.262 +    if (NSS_CMSType_IsData(tag)) {
   1.263 +	pItem = cinfo->content.data; 
   1.264 +    } else if (NSS_CMSType_IsWrapper(tag)) {
   1.265 +	ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
   1.266 +	if (ccinfo != NULL) {
   1.267 +	    pItem = NSS_CMSContentInfo_GetContent(ccinfo);
   1.268 +	}
   1.269 +    } else {
   1.270 +	PORT_Assert(0);
   1.271 +    }
   1.272 +
   1.273 +    return pItem;
   1.274 +}
   1.275 +
   1.276 +
   1.277 +/*
   1.278 + * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
   1.279 + * for future reference) and return the inner content type.
   1.280 + */
   1.281 +SECOidTag
   1.282 +NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
   1.283 +{
   1.284 +    if (cinfo->contentTypeTag == NULL)
   1.285 +	cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
   1.286 +
   1.287 +    if (cinfo->contentTypeTag == NULL)
   1.288 +	return SEC_OID_UNKNOWN;
   1.289 +
   1.290 +    return cinfo->contentTypeTag->offset;
   1.291 +}
   1.292 +
   1.293 +SECItem *
   1.294 +NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
   1.295 +{
   1.296 +    if (cinfo->contentTypeTag == NULL)
   1.297 +	cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
   1.298 +
   1.299 +    if (cinfo->contentTypeTag == NULL)
   1.300 +	return NULL;
   1.301 +
   1.302 +    return &(cinfo->contentTypeTag->oid);
   1.303 +}
   1.304 +
   1.305 +/*
   1.306 + * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
   1.307 + * for future reference) and return the content encryption algorithm tag.
   1.308 + */
   1.309 +SECOidTag
   1.310 +NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
   1.311 +{
   1.312 +    if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
   1.313 +	cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
   1.314 +
   1.315 +    return cinfo->contentEncAlgTag;
   1.316 +}
   1.317 +
   1.318 +/*
   1.319 + * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
   1.320 + */
   1.321 +SECAlgorithmID *
   1.322 +NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
   1.323 +{
   1.324 +    return &(cinfo->contentEncAlg);
   1.325 +}
   1.326 +
   1.327 +SECStatus
   1.328 +NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
   1.329 +				    SECOidTag bulkalgtag, SECItem *parameters, int keysize)
   1.330 +{
   1.331 +    SECStatus rv;
   1.332 +
   1.333 +    rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
   1.334 +    if (rv != SECSuccess)
   1.335 +	return SECFailure;
   1.336 +    cinfo->keysize = keysize;
   1.337 +    return SECSuccess;
   1.338 +}
   1.339 +
   1.340 +SECStatus
   1.341 +NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
   1.342 +				    SECAlgorithmID *algid, int keysize)
   1.343 +{
   1.344 +    SECStatus rv;
   1.345 +
   1.346 +    rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
   1.347 +    if (rv != SECSuccess)
   1.348 +	return SECFailure;
   1.349 +    if (keysize >= 0)
   1.350 +	cinfo->keysize = keysize;
   1.351 +    return SECSuccess;
   1.352 +}
   1.353 +
   1.354 +void
   1.355 +NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
   1.356 +{
   1.357 +    cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
   1.358 +    cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
   1.359 +}
   1.360 +
   1.361 +PK11SymKey *
   1.362 +NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
   1.363 +{
   1.364 +    if (cinfo->bulkkey == NULL)
   1.365 +	return NULL;
   1.366 +
   1.367 +    return PK11_ReferenceSymKey(cinfo->bulkkey);
   1.368 +}
   1.369 +
   1.370 +int
   1.371 +NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo)
   1.372 +{
   1.373 +    return cinfo->keysize;
   1.374 +}

mercurial