Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / smime / cmscinfo.c
blobb1f1d1df7b6ea974b7f93cecc38d3c1c9d837c39
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 * CMS contentInfo methods.
40 * $Id: cmscinfo.c,v 1.7 2004/04/25 15:03:16 gerv%gerv.net Exp $
43 #include "cmslocal.h"
45 #include "pk11func.h"
46 #include "secitem.h"
47 #include "secoid.h"
48 #include "secerr.h"
51 * NSS_CMSContentInfo_Create - create a content info
53 * version is set in the _Finalize procedures for each content type
57 * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
59 void
60 NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
62 SECOidTag kind;
64 kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
65 switch (kind) {
66 case SEC_OID_PKCS7_ENVELOPED_DATA:
67 NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
68 break;
69 case SEC_OID_PKCS7_SIGNED_DATA:
70 NSS_CMSSignedData_Destroy(cinfo->content.signedData);
71 break;
72 case SEC_OID_PKCS7_ENCRYPTED_DATA:
73 NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
74 break;
75 case SEC_OID_PKCS7_DIGESTED_DATA:
76 NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
77 break;
78 default:
79 /* XXX Anything else that needs to be "manually" freed/destroyed? */
80 break;
82 if (cinfo->digcx) {
83 /* must destroy digest objects */
84 NSS_CMSDigestContext_Cancel(cinfo->digcx);
85 cinfo->digcx = NULL;
87 if (cinfo->bulkkey)
88 PK11_FreeSymKey(cinfo->bulkkey);
90 if (cinfo->ciphcx) {
91 NSS_CMSCipherContext_Destroy(cinfo->ciphcx);
92 cinfo->ciphcx = NULL;
95 /* we live in a pool, so no need to worry about storage */
99 * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
101 NSSCMSContentInfo *
102 NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
104 void * ptr = NULL;
105 NSSCMSContentInfo * ccinfo = NULL;
106 SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
107 switch (tag) {
108 case SEC_OID_PKCS7_SIGNED_DATA:
109 ptr = (void *)cinfo->content.signedData;
110 ccinfo = &(cinfo->content.signedData->contentInfo);
111 break;
112 case SEC_OID_PKCS7_ENVELOPED_DATA:
113 ptr = (void *)cinfo->content.envelopedData;
114 ccinfo = &(cinfo->content.envelopedData->contentInfo);
115 break;
116 case SEC_OID_PKCS7_DIGESTED_DATA:
117 ptr = (void *)cinfo->content.digestedData;
118 ccinfo = &(cinfo->content.digestedData->contentInfo);
119 break;
120 case SEC_OID_PKCS7_ENCRYPTED_DATA:
121 ptr = (void *)cinfo->content.encryptedData;
122 ccinfo = &(cinfo->content.encryptedData->contentInfo);
123 break;
124 case SEC_OID_PKCS7_DATA:
125 default:
126 break;
128 return (ptr ? ccinfo : NULL);
132 * NSS_CMSContentInfo_SetContent - set content type & content
134 SECStatus
135 NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
137 SECStatus rv;
139 cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
140 if (cinfo->contentTypeTag == NULL)
141 return SECFailure;
143 /* do not copy the oid, just create a reference */
144 rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
145 if (rv != SECSuccess)
146 return SECFailure;
148 cinfo->content.pointer = ptr;
150 if (type != SEC_OID_PKCS7_DATA) {
151 /* as we always have some inner data,
152 * we need to set it to something, just to fool the encoder enough to work on it
153 * and get us into nss_cms_encoder_notify at that point */
154 cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
155 if (cinfo->rawContent == NULL) {
156 PORT_SetError(SEC_ERROR_NO_MEMORY);
157 return SECFailure;
161 return SECSuccess;
165 * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent
169 * data == NULL -> pass in data via NSS_CMSEncoder_Update
170 * data != NULL -> take this data
172 SECStatus
173 NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
175 if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
176 return SECFailure;
177 cinfo->rawContent = (detached) ?
178 NULL : (data) ?
179 data : SECITEM_AllocItem(cmsg->poolp, NULL, 1);
180 return SECSuccess;
183 SECStatus
184 NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
186 return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
189 SECStatus
190 NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
192 return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
195 SECStatus
196 NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
198 return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
201 SECStatus
202 NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
204 return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
208 * NSS_CMSContentInfo_GetContent - get pointer to inner content
210 * needs to be casted...
212 void *
213 NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
215 SECOidTag tag = (cinfo && cinfo->contentTypeTag)
216 ? cinfo->contentTypeTag->offset
217 : SEC_OID_UNKNOWN;
218 switch (tag) {
219 case SEC_OID_PKCS7_DATA:
220 case SEC_OID_PKCS7_SIGNED_DATA:
221 case SEC_OID_PKCS7_ENVELOPED_DATA:
222 case SEC_OID_PKCS7_DIGESTED_DATA:
223 case SEC_OID_PKCS7_ENCRYPTED_DATA:
224 return cinfo->content.pointer;
225 default:
226 return NULL;
231 * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
233 * this is typically only called by NSS_CMSMessage_GetContent()
235 SECItem *
236 NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
238 NSSCMSContentInfo *ccinfo;
239 SECOidTag tag;
240 SECItem *pItem = NULL;
242 tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
243 switch (tag) {
244 case SEC_OID_PKCS7_DATA:
245 /* end of recursion - every message has to have a data cinfo */
246 pItem = cinfo->content.data;
247 break;
248 case SEC_OID_PKCS7_DIGESTED_DATA:
249 case SEC_OID_PKCS7_ENCRYPTED_DATA:
250 case SEC_OID_PKCS7_ENVELOPED_DATA:
251 case SEC_OID_PKCS7_SIGNED_DATA:
252 ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
253 if (ccinfo != NULL)
254 pItem = NSS_CMSContentInfo_GetContent(ccinfo);
255 break;
256 default:
257 PORT_Assert(0);
258 break;
260 return pItem;
264 * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
265 * for future reference) and return the inner content type.
267 SECOidTag
268 NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
270 if (cinfo->contentTypeTag == NULL)
271 cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
273 if (cinfo->contentTypeTag == NULL)
274 return SEC_OID_UNKNOWN;
276 return cinfo->contentTypeTag->offset;
279 SECItem *
280 NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
282 if (cinfo->contentTypeTag == NULL)
283 cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
285 if (cinfo->contentTypeTag == NULL)
286 return NULL;
288 return &(cinfo->contentTypeTag->oid);
292 * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
293 * for future reference) and return the content encryption algorithm tag.
295 SECOidTag
296 NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
298 if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
299 cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
301 return cinfo->contentEncAlgTag;
305 * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
307 SECAlgorithmID *
308 NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
310 return &(cinfo->contentEncAlg);
313 SECStatus
314 NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
315 SECOidTag bulkalgtag, SECItem *parameters, int keysize)
317 SECStatus rv;
319 rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
320 if (rv != SECSuccess)
321 return SECFailure;
322 cinfo->keysize = keysize;
323 return SECSuccess;
326 SECStatus
327 NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
328 SECAlgorithmID *algid, int keysize)
330 SECStatus rv;
332 rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
333 if (rv != SECSuccess)
334 return SECFailure;
335 if (keysize >= 0)
336 cinfo->keysize = keysize;
337 return SECSuccess;
340 void
341 NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
343 cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
344 cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
347 PK11SymKey *
348 NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
350 if (cinfo->bulkkey == NULL)
351 return NULL;
353 return PK11_ReferenceSymKey(cinfo->bulkkey);
357 NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo)
359 return cinfo->keysize;