1/*
2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * CMSEncoder.h - encode, sign, and/or encrypt messages in the Cryptographic
26 *				  Message Syntax (CMS), per RFC 3852.
27 *
28 * A CMS message can be signed, encrypted, or both. A message can be signed by
29 * an arbitrary number of signers; in this module, signers are expressed as
30 * SecIdentityRefs. A message can be encrypted for an arbitrary number of
31 * recipients; recipients are expressed here as SecCertificateRefs.
32 *
33 * In CMS terminology, this module performs encryption using the EnvelopedData
34 * ContentType and signing using the SignedData ContentType.
35 *
36 * If the message is both signed and encrypted, it uses "nested ContentInfos"
37 * in CMS terminology; in this implementation, signed & encrypted messages
38 * are implemented as an EnvelopedData containing a SignedData.
39 */
40
41#ifndef _CMS_ENCODER_H_
42#define _CMS_ENCODER_H_
43
44#include <CoreFoundation/CoreFoundation.h>
45#include <Security/cssmtype.h>
46#include <stdint.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/*
53 * Opaque reference to a CMS encoder object.
54 * This is a CF object, with standard CF semantics; dispose of it
55 * with CFRelease().
56 */
57typedef struct _CMSEncoder *CMSEncoderRef;
58
59CFTypeID CMSEncoderGetTypeID(void)
60    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
61
62/*
63 * Create a CMSEncoder. Result must eventually be freed via CFRelease().
64 */
65OSStatus CMSEncoderCreate(
66	CMSEncoderRef		*cmsEncoderOut)	/* RETURNED */
67	__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
68
69/*
70 * Specify signers of the CMS message; implies that the message will be signed.
71 *
72 * -- Caller can pass in one signer, as a SecIdentityRef, or an array of
73 *    signers, as a CFArray of SecIdentityRefs.
74 * -- Can be called multiple times.
75 * -- If the message is not to be signed, don't call this.
76 * -- If this is called, it must be called before the first call to
77 *    CMSEncoderUpdateContent().
78 */
79OSStatus CMSEncoderAddSigners(
80	CMSEncoderRef		cmsEncoder,
81	CFTypeRef			signerOrArray)
82    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
83
84/*
85 * Obtain an array of signers as specified in CMSEncoderSetSigners().
86 * Returns a NULL signers array if CMSEncoderSetSigners() has not been called.
87 * Caller must CFRelease the result.
88 */
89OSStatus CMSEncoderCopySigners(
90	CMSEncoderRef		cmsEncoder,
91	CFArrayRef			*signersOut)		/* RETURNED */
92    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
93
94/*
95 * Specify recipients of the message. Implies that the message will
96 * be encrypted.
97 *
98 * -- Caller can pass in one recipient, as a SecCertificateRef, or an
99 *    array of recipients, as a CFArray of SecCertificateRefs.
100 * -- Can be called multiple times.
101 * -- If the message is not to be encrypted, don't call this.
102 * -- If this is called, it must be called before the first call to
103 *    CMSEncoderUpdateContent().
104 */
105OSStatus CMSEncoderAddRecipients(
106	CMSEncoderRef		cmsEncoder,
107	CFTypeRef			recipientOrArray)
108    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
109
110/*
111 * Obtain an array of recipients as specified in CMSEncoderSetRecipients().
112 * Returns a NULL recipients array if CMSEncoderSetRecipients() has not been
113 * called.
114 * Caller must CFRelease the result.
115 */
116OSStatus CMSEncoderCopyRecipients(
117	CMSEncoderRef		cmsEncoder,
118	CFArrayRef			*recipientsOut)	/* RETURNED */
119    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
120
121/*
122 * A signed message optionally includes the data to be signed. If the message
123 * is *not* to include the data to be signed, call this function with a value
124 * of TRUE for detachedContent. The default, if this function is not called,
125 * is detachedContent=FALSE, i.e., the message contains the data to be signed.
126 *
127 * -- Encrypted messages can not use detached content. (This restriction
128 *    also applies to messages that are both signed and encrypted.)
129 * -- If this is called, it must be called before the first call to
130 *    CMSEncoderUpdateContent().
131 */
132OSStatus CMSEncoderSetHasDetachedContent(
133	CMSEncoderRef		cmsEncoder,
134	Boolean			detachedContent)
135    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
136
137/*
138 * Obtain a Boolean indicating whether the current message will have detached
139 * content.
140 * Returns the value specified in CMSEncoderHasDetachedContent() if that
141 * function has been called; else returns the default FALSE.
142 */
143OSStatus CMSEncoderGetHasDetachedContent(
144	CMSEncoderRef		cmsEncoder,
145	Boolean			*detachedContentOut)	/* RETURNED */
146    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
147
148/*
149 * Optionally specify an eContentType OID for the inner EncapsulatedData for
150 * a signed message. The default eContentType, used if this function is not
151 * called, is id-data (which is the normal eContentType for applications such
152 * as SMIME).
153 *
154 * If this is called, it must be called before the first call to
155 * CMSEncoderUpdateContent().
156 *
157 * NOTE: This function is deprecated in Mac OS X 10.7 and later;
158 * please use CMSEncoderSetEncapsulatedContentTypeOID() instead.
159 */
160OSStatus CMSEncoderSetEncapsulatedContentType(
161	CMSEncoderRef		cmsEncoder,
162	const CSSM_OID	*eContentType)
163	/* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */
164    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
165
166/*
167 * Optionally specify an eContentType OID for the inner EncapsulatedData for
168 * a signed message. The default eContentTypeOID, used if this function is not
169 * called, is id-data (which is the normal eContentType for applications such
170 * as SMIME).
171 *
172 * The eContentTypeOID parameter may be specified as a CF string, e.g.:
173 * CFSTR("1.2.840.113549.1.7.1")
174 *
175 * If this is called, it must be called before the first call to
176 * CMSEncoderUpdateContent().
177 */
178OSStatus CMSEncoderSetEncapsulatedContentTypeOID(
179	CMSEncoderRef		cmsEncoder,
180	CFTypeRef			eContentTypeOID)
181    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
182
183/*
184 * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType().
185 * If CMSEncoderSetEncapsulatedContentType() has not been called this returns a
186 * NULL pointer.
187 * The returned OID's data is in the same format as the data provided to
188 * CMSEncoderSetEncapsulatedContentType;, i.e., it's the encoded content of
189 * the OID, not including the tag and length bytes.
190 */
191OSStatus CMSEncoderCopyEncapsulatedContentType(
192	CMSEncoderRef		cmsEncoder,
193	CFDataRef			*eContentTypeOut)		/* RETURNED */
194    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
195
196/*
197 * Signed CMS messages can contain arbitrary sets of certificates beyond those
198 * indicating the identity of the signer(s). This function provides a means of
199 * adding these other certs. For normal signed messages it is not necessary to
200 * call this; the signer cert(s) and the intermediate certs needed to verify the
201 * signer(s) will be included in the message implicitly.
202 *
203 * -- Caller can pass in one cert, as a SecCertificateRef, or an array of certs,
204 *    as a CFArray of SecCertificateRefs.
205 * -- If this is called, it must be called before the first call to
206 *    CMSEncoderUpdateContent().
207 * -- There is a "special case" use of CMS messages which involves neither
208 *    signing nor encryption, but does include certificates. This is commonly
209 *    used to transport "bags" of certificates. When constructing such a
210 *    message, all an application needs to do is to create a CMSEncoderRef,
211 *    call CMSEncoderAddSupportingCerts() one or more times, and then call
212 *    CMSEncoderCopyEncodedContent() to get the resulting cert bag. No 'content'
213 *    need be specified. (This is in fact the primary intended use for
214 *    this function.)
215 */
216OSStatus CMSEncoderAddSupportingCerts(
217	CMSEncoderRef		cmsEncoder,
218	CFTypeRef			certOrArray)
219    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
220
221/*
222 * Obtain the SecCertificates provided in CMSEncoderAddSupportingCerts().
223 * If CMSEncoderAddSupportingCerts() has not been called this will return a
224 * NULL value for *certs.
225 * Caller must CFRelease the result.
226 */
227OSStatus CMSEncoderCopySupportingCerts(
228	CMSEncoderRef		cmsEncoder,
229	CFArrayRef			*certsOut)			/* RETURNED */
230    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
231
232/*
233 * Standard signed attributes, optionally specified in
234 * CMSEncoderAddSignedAttributes().
235 */
236enum {
237	kCMSAttrNone						= 0x0000,
238    /*
239     * S/MIME Capabilities - identifies supported signature, encryption, and
240     * digest algorithms.
241     */
242    kCMSAttrSmimeCapabilities			= 0x0001,
243    /*
244     * Indicates that a cert is the preferred cert for S/MIME encryption.
245     */
246    kCMSAttrSmimeEncryptionKeyPrefs		= 0x0002,
247    /*
248     * Same as kCMSSmimeEncryptionKeyPrefs, using an attribute OID preferred
249     * by Microsoft.
250     */
251    kCMSAttrSmimeMSEncryptionKeyPrefs	= 0x0004,
252    /*
253     * Include the signing time.
254     */
255    kCMSAttrSigningTime					= 0x0008
256};
257typedef uint32_t CMSSignedAttributes;
258
259/*
260 * Optionally specify signed attributes. Only meaningful when creating a
261 * signed message. If this is called, it must be called before
262 * CMSEncoderUpdateContent().
263 */
264OSStatus CMSEncoderAddSignedAttributes(
265	CMSEncoderRef		cmsEncoder,
266	CMSSignedAttributes	signedAttributes)
267    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
268
269/*
270 * Specification of what certificates to include in a signed message.
271 */
272enum {
273	kCMSCertificateNone = 0,		/* don't include any certificates */
274	kCMSCertificateSignerOnly,		/* only include signer certificate(s) */
275	kCMSCertificateChain,			/* signer certificate chain up to but not
276									 *   including root certiticate */
277	kCMSCertificateChainWithRoot	/* signer certificate chain including root */
278};
279typedef uint32_t CMSCertificateChainMode;
280
281/*
282 * Optionally specify which certificates, if any, to include in a
283 * signed CMS message. The default, if this is not called, is
284 * kCMSCertificateChain, in which case the signer cert plus all CA
285 * certs needed to verify the signer cert, except for the root
286 * cert, are included.
287 * If this is called, it must be called before
288 * CMSEncoderUpdateContent().
289 */
290OSStatus CMSEncoderSetCertificateChainMode(
291	CMSEncoderRef			cmsEncoder,
292	CMSCertificateChainMode	chainMode)
293    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
294
295/*
296 * Obtain indication of which signer certs are to be included
297 * in a signed CMS message.
298 */
299OSStatus CMSEncoderGetCertificateChainMode(
300	CMSEncoderRef			cmsEncoder,
301	CMSCertificateChainMode	*chainModeOut)
302    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
303
304/*
305 * Feed content bytes into the encoder.
306 * Can be called multiple times.
307 * No 'setter' routines can be called after this function has been called.
308 */
309OSStatus CMSEncoderUpdateContent(
310	CMSEncoderRef		cmsEncoder,
311	const void			*content,
312	size_t				contentLen)
313    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
314
315/*
316 * Finish encoding the message and obtain the encoded result.
317 * Caller must CFRelease the result.
318 */
319OSStatus CMSEncoderCopyEncodedContent(
320	CMSEncoderRef		cmsEncoder,
321	CFDataRef			*encodedContentOut)	/* RETURNED */
322    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
323
324/*
325 * High-level, one-shot encoder function.
326 *
327 * Inputs (all except for content optional, though at least one
328 *         of {signers, recipients} must be non-NULL)
329 * ------------------------------------------------------------
330 * signers          : signer identities. Either a SecIdentityRef, or a
331 *                    CFArray of them.
332 * recipients       : recipient certificates. Either a SecCertificateRef,
333 *                    or a CFArray of them.
334 * eContentType     : contentType for inner EncapsulatedData.
335 * detachedContent  : when true, do not include the signed data in the message.
336 * signedAttributes : Specifies which standard signed attributes are to be
337 *                    included in the message.
338 * content          : raw content to be signed and/or encrypted.
339 *
340 * Output
341 * ------
342 * encodedContent   : the result of the encoding.
343 *
344 * NOTE: This function is deprecated in Mac OS X 10.7 and later;
345 * please use CMSEncodeContent() instead.
346 */
347OSStatus CMSEncode(
348	CFTypeRef			signers,
349	CFTypeRef			recipients,
350	const CSSM_OID		*eContentType,
351	Boolean				detachedContent,
352	CMSSignedAttributes	signedAttributes,
353	const void			*content,
354	size_t				contentLen,
355	CFDataRef			*encodedContentOut)	/* RETURNED */
356	/* DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; */
357    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
358
359
360/*
361 * High-level, one-shot encoder function.
362 *
363 * Inputs (all except for content optional, though at least one
364 *         of {signers, recipients} must be non-NULL)
365 * ------------------------------------------------------------
366 * signers          : signer identities. Either a SecIdentityRef, or a
367 *                    CFArray of them.
368 * recipients       : recipient certificates. Either a SecCertificateRef,
369 *                    or a CFArray of them.
370 * eContentTypeOID  : contentType OID for inner EncapsulatedData, e.g.:
371 *                    CFSTR("1.2.840.113549.1.7.1")
372 * detachedContent  : when true, do not include the signed data in the message.
373 * signedAttributes : Specifies which standard signed attributes are to be
374 *                    included in the message.
375 * content          : raw content to be signed and/or encrypted.
376 *
377 * Output
378 * ------
379 * encodedContent   : the result of the encoding.
380 */
381OSStatus CMSEncodeContent(
382	CFTypeRef			signers,
383	CFTypeRef			recipients,
384	CFTypeRef			eContentTypeOID,
385	Boolean				detachedContent,
386	CMSSignedAttributes	signedAttributes,
387	const void			*content,
388	size_t				contentLen,
389	CFDataRef			*encodedContentOut)	/* RETURNED */
390    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
391
392OSStatus CMSEncoderCopySignerTimestamp(
393	CMSEncoderRef		cmsEncoder,
394	size_t				signerIndex,        /* usually 0 */
395	CFAbsoluteTime      *timestamp)			/* RETURNED */
396    __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA);
397
398OSStatus CMSEncoderCopySignerTimestampWithPolicy(
399    CMSEncoderRef		cmsEncoder,
400    CFTypeRef            timeStampPolicy,
401    size_t				signerIndex,        /* usually 0 */
402    CFAbsoluteTime      *timestamp)			/* RETURNED */
403    __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA);
404
405#ifdef __cplusplus
406}
407#endif
408
409#endif	/* _CMS_ENCODER_H_ */
410
411