2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * CMSEncoder.h - encode, sign, and/or encrypt messages in the Cryptographic
26 * Message Syntax (CMS), per RFC 3852.
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.
33 * In CMS terminology, this module performs encryption using the EnvelopedData
34 * ContentType and signing using the SignedData ContentType.
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.
41 #ifndef _CMS_ENCODER_H_
42 #define _CMS_ENCODER_H_
44 #include <CoreFoundation/CoreFoundation.h>
45 #include <Security/SecCmsEncoder.h>
46 #include <Security/SecCmsDecoder.h>
47 #include <Security/SecCmsMessage.h>
48 #include <AvailabilityMacros.h>
53 CF_ASSUME_NONNULL_BEGIN
56 * Opaque reference to a CMS encoder object.
57 * This is a CF object, with standard CF semantics; dispose of it
60 typedef struct CF_BRIDGED_TYPE(id
) _CMSEncoder
*CMSEncoderRef
;
62 CFTypeID
CMSEncoderGetTypeID(void)
63 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
66 * Create a CMSEncoder. Result must eventually be freed via CFRelease().
68 OSStatus
CMSEncoderCreate(CMSEncoderRef
* __nonnull CF_RETURNS_RETAINED cmsEncoderOut
) /* RETURNED */
69 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
71 extern const CFStringRef kCMSEncoderDigestAlgorithmSHA1
;
72 extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256
;
74 OSStatus
CMSEncoderSetSignerAlgorithm(
75 CMSEncoderRef cmsEncoder
,
76 CFStringRef digestAlgorithm
)
77 __OSX_AVAILABLE_STARTING(__MAC_10_11
, __IPHONE_11_0
);
80 * Specify signers of the CMS message; implies that the message will be signed.
82 * -- Caller can pass in one signer, as a SecIdentityRef, or an array of
83 * signers, as a CFArray of SecIdentityRefs.
84 * -- Can be called multiple times.
85 * -- If the message is not to be signed, don't call this.
86 * -- If this is called, it must be called before the first call to
87 * CMSEncoderUpdateContent().
89 OSStatus
CMSEncoderAddSigners(
90 CMSEncoderRef cmsEncoder
,
91 CFTypeRef signerOrArray
)
92 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
95 * Obtain an array of signers as specified in CMSEncoderSetSigners().
96 * Returns a NULL signers array if CMSEncoderSetSigners() has not been called.
97 * Caller must CFRelease the result.
99 OSStatus
CMSEncoderCopySigners(
100 CMSEncoderRef cmsEncoder
,
101 CFArrayRef
* __nonnull CF_RETURNS_RETAINED signersOut
) /* RETURNED */
102 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
105 * Specify recipients of the message. Implies that the message will
108 * -- Caller can pass in one recipient, as a SecCertificateRef, or an
109 * array of recipients, as a CFArray of SecCertificateRefs.
110 * -- Can be called multiple times.
111 * -- If the message is not to be encrypted, don't call this.
112 * -- If this is called, it must be called before the first call to
113 * CMSEncoderUpdateContent().
115 OSStatus
CMSEncoderAddRecipients(
116 CMSEncoderRef cmsEncoder
,
117 CFTypeRef recipientOrArray
)
118 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
121 * Obtain an array of recipients as specified in CMSEncoderSetRecipients().
122 * Returns a NULL recipients array if CMSEncoderSetRecipients() has not been
124 * Caller must CFRelease the result.
126 OSStatus
CMSEncoderCopyRecipients(
127 CMSEncoderRef cmsEncoder
,
128 CFArrayRef
* __nonnull CF_RETURNS_RETAINED recipientsOut
) /* RETURNED */
129 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
132 * A signed message optionally includes the data to be signed. If the message
133 * is *not* to include the data to be signed, call this function with a value
134 * of TRUE for detachedContent. The default, if this function is not called,
135 * is detachedContent=FALSE, i.e., the message contains the data to be signed.
137 * -- Encrypted messages can not use detached content. (This restriction
138 * also applies to messages that are both signed and encrypted.)
139 * -- If this is called, it must be called before the first call to
140 * CMSEncoderUpdateContent().
142 OSStatus
CMSEncoderSetHasDetachedContent(
143 CMSEncoderRef cmsEncoder
,
144 Boolean detachedContent
)
145 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
148 * Obtain a Boolean indicating whether the current message will have detached
150 * Returns the value specified in CMSEncoderHasDetachedContent() if that
151 * function has been called; else returns the default FALSE.
153 OSStatus
CMSEncoderGetHasDetachedContent(
154 CMSEncoderRef cmsEncoder
,
155 Boolean
*detachedContentOut
) /* RETURNED */
156 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
159 * Optionally specify an eContentType OID for the inner EncapsulatedData for
160 * a signed message. The default eContentTypeOID, used if this function is not
161 * called, is id-data (which is the normal eContentType for applications such
164 * The eContentTypeOID parameter may be specified as a CF string, e.g.:
165 * CFSTR("1.2.840.113549.1.7.1")
167 * If this is called, it must be called before the first call to
168 * CMSEncoderUpdateContent().
170 OSStatus
CMSEncoderSetEncapsulatedContentTypeOID(
171 CMSEncoderRef cmsEncoder
,
172 CFTypeRef eContentTypeOID
)
173 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_11_0
);
176 * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType().
177 * If CMSEncoderSetEncapsulatedContentType() has not been called this returns a
179 * The returned OID's data is in the same format as the data provided to
180 * CMSEncoderSetEncapsulatedContentType;, i.e., it's the encoded content of
181 * the OID, not including the tag and length bytes.
183 OSStatus
CMSEncoderCopyEncapsulatedContentType(
184 CMSEncoderRef cmsEncoder
,
185 CFDataRef
* __nonnull CF_RETURNS_RETAINED eContentTypeOut
) /* RETURNED */
186 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
189 * Signed CMS messages can contain arbitrary sets of certificates beyond those
190 * indicating the identity of the signer(s). This function provides a means of
191 * adding these other certs. For normal signed messages it is not necessary to
192 * call this; the signer cert(s) and the intermediate certs needed to verify the
193 * signer(s) will be included in the message implicitly.
195 * -- Caller can pass in one cert, as a SecCertificateRef, or an array of certs,
196 * as a CFArray of SecCertificateRefs.
197 * -- If this is called, it must be called before the first call to
198 * CMSEncoderUpdateContent().
199 * -- There is a "special case" use of CMS messages which involves neither
200 * signing nor encryption, but does include certificates. This is commonly
201 * used to transport "bags" of certificates. When constructing such a
202 * message, all an application needs to do is to create a CMSEncoderRef,
203 * call CMSEncoderAddSupportingCerts() one or more times, and then call
204 * CMSEncoderCopyEncodedContent() to get the resulting cert bag. No 'content'
205 * need be specified. (This is in fact the primary intended use for
208 OSStatus
CMSEncoderAddSupportingCerts(
209 CMSEncoderRef cmsEncoder
,
210 CFTypeRef certOrArray
)
211 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
214 * Obtain the SecCertificates provided in CMSEncoderAddSupportingCerts().
215 * If CMSEncoderAddSupportingCerts() has not been called this will return a
216 * NULL value for *certs.
217 * Caller must CFRelease the result.
219 OSStatus
CMSEncoderCopySupportingCerts(
220 CMSEncoderRef cmsEncoder
,
221 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certsOut
) /* RETURNED */
222 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
225 * Standard signed attributes, optionally specified in
226 * CMSEncoderAddSignedAttributes().
228 typedef CF_OPTIONS(uint32_t, CMSSignedAttributes
) {
229 kCMSAttrNone
= 0x0000,
231 * S/MIME Capabilities - identifies supported signature, encryption, and
234 kCMSAttrSmimeCapabilities
= 0x0001,
236 * Indicates that a cert is the preferred cert for S/MIME encryption.
238 kCMSAttrSmimeEncryptionKeyPrefs
= 0x0002,
240 * Same as kCMSSmimeEncryptionKeyPrefs, using an attribute OID preferred
243 kCMSAttrSmimeMSEncryptionKeyPrefs
= 0x0004,
245 * Include the signing time.
247 kCMSAttrSigningTime
= 0x0008,
249 * Include the Apple Codesigning Hash Agility.
251 kCMSAttrAppleCodesigningHashAgility
= 0x0010,
252 kCMSAttrAppleCodesigningHashAgilityV2
= 0x0020,
254 * Include the expiration time.
256 kCMSAttrAppleExpirationTime
= 0x0040,
260 * Optionally specify signed attributes. Only meaningful when creating a
261 * signed message. If this is called, it must be called before
262 * CMSEncoderUpdateContent().
264 OSStatus
CMSEncoderAddSignedAttributes(
265 CMSEncoderRef cmsEncoder
,
266 CMSSignedAttributes signedAttributes
)
267 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
270 * Specification of what certificates to include in a signed message.
272 typedef CF_ENUM(uint32_t, CMSCertificateChainMode
) {
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 */
281 * Optionally specify which certificates, if any, to include in a
282 * signed CMS message. The default, if this is not called, is
283 * kCMSCertificateChain, in which case the signer cert plus all CA
284 * certs needed to verify the signer cert, except for the root
285 * cert, are included.
286 * If this is called, it must be called before
287 * CMSEncoderUpdateContent().
289 OSStatus
CMSEncoderSetCertificateChainMode(
290 CMSEncoderRef cmsEncoder
,
291 CMSCertificateChainMode chainMode
)
292 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
295 * Obtain indication of which signer certs are to be included
296 * in a signed CMS message.
298 OSStatus
CMSEncoderGetCertificateChainMode(
299 CMSEncoderRef cmsEncoder
,
300 CMSCertificateChainMode
*chainModeOut
)
301 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
304 * Feed content bytes into the encoder.
305 * Can be called multiple times.
306 * No 'setter' routines can be called after this function has been called.
308 OSStatus
CMSEncoderUpdateContent(
309 CMSEncoderRef cmsEncoder
,
312 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
315 * Finish encoding the message and obtain the encoded result.
316 * Caller must CFRelease the result.
318 OSStatus
CMSEncoderCopyEncodedContent(
319 CMSEncoderRef cmsEncoder
,
320 CFDataRef
* __nonnull CF_RETURNS_RETAINED encodedContentOut
) /* RETURNED */
321 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
324 * High-level, one-shot encoder function.
326 * Inputs (all except for content optional, though at least one
327 * of {signers, recipients} must be non-NULL)
328 * ------------------------------------------------------------
329 * signers : signer identities. Either a SecIdentityRef, or a
331 * recipients : recipient certificates. Either a SecCertificateRef,
332 * or a CFArray of them.
333 * eContentTypeOID : contentType OID for inner EncapsulatedData, e.g.:
334 * CFSTR("1.2.840.113549.1.7.1")
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.
342 * encodedContent : the result of the encoding.
344 OSStatus
CMSEncodeContent(
345 CFTypeRef __nullable signers
,
346 CFTypeRef __nullable recipients
,
347 CFTypeRef __nullable eContentTypeOID
,
348 Boolean detachedContent
,
349 CMSSignedAttributes signedAttributes
,
352 CFDataRef
* __nullable CF_RETURNS_RETAINED encodedContentOut
) /* RETURNED */
353 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_11_0
);
355 #if TIMESTAMPING_SUPPORTED
356 OSStatus
CMSEncoderCopySignerTimestamp(
357 CMSEncoderRef cmsEncoder
,
358 size_t signerIndex
, /* usually 0 */
359 CFAbsoluteTime
*timestamp
) /* RETURNED */
360 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
362 OSStatus
CMSEncoderCopySignerTimestampWithPolicy(
363 CMSEncoderRef cmsEncoder
,
364 CFTypeRef __nullable timeStampPolicy
,
365 size_t signerIndex
, /* usually 0 */
366 CFAbsoluteTime
*timestamp
) /* RETURNED */
367 __OSX_AVAILABLE_STARTING(__MAC_10_10
, __IPHONE_NA
);
370 CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder
, CFTypeRef tsaContext
);
371 #endif // TIMESTAMPING_SUPPORTED
374 * Obtain the SecCmsMessageRef associated with a CMSEncoderRef. Intended
375 * to be called after (optionally) setting the encoder's various attributes
376 * via CMSEncoderAddSigners(), CMSEncoderAddRecipients(), etc. and before
377 * the first call to CMSEncoderUpdateContent(). The returned SecCmsMessageRef
378 * will be initialized per the previously specified attributes; the caller
379 * can manipulate the SecCmsMessageRef prior to proceeding with
380 * CMSEncoderUpdateContent() calls.
382 OSStatus
CMSEncoderGetCmsMessage(
383 CMSEncoderRef cmsEncoder
,
384 SecCmsMessageRef _Nullable
* _Nonnull cmsMessage
); /* RETURNED */
387 * Optionally specify a SecCmsEncoderRef to use with a CMSEncoderRef.
388 * If this is called, it must be called before the first call to
389 * CMSEncoderUpdateContent(). The CMSEncoderRef takes ownership of the
390 * incoming SecCmsEncoderRef.
392 OSStatus
CMSEncoderSetEncoder(
393 CMSEncoderRef cmsEncoder
,
394 SecCmsEncoderRef encoder
);
397 * Obtain the SecCmsEncoderRef associated with a CMSEncoderRef.
398 * Returns a NULL SecCmsEncoderRef if neither CMSEncoderSetEncoder nor
399 * CMSEncoderUpdateContent() has been called.
400 * The CMSEncoderRef retains ownership of the SecCmsEncoderRef.
402 OSStatus
CMSEncoderGetEncoder(
403 CMSEncoderRef cmsEncoder
,
404 SecCmsEncoderRef _Nullable
* _Nonnull encoder
); /* RETURNED */
407 * Set the signing time for a CMSEncoder.
408 * This is only used if the kCMSAttrSigningTime attribute is included.
410 OSStatus
CMSEncoderSetSigningTime(
411 CMSEncoderRef cmsEncoder
,
412 CFAbsoluteTime time
);
415 * Set the hash agility attribute for a CMSEncoder.
416 * This is only used if the kCMSAttrAppleCodesigningHashAgility attribute
419 OSStatus
CMSEncoderSetAppleCodesigningHashAgility(
420 CMSEncoderRef cmsEncoder
,
421 CFDataRef hashAgilityAttrValue
);
424 * Set the hash agility attribute for a CMSEncoder.
425 * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute
426 * is included. V2 encodes the hash agility values using DER.
427 * The dictionary should have CFNumberRef keys, corresponding to SECOidTags
428 * (from SecCmsBase.h) for digest algorithms, and CFDataRef values,
429 * corresponding to the digest value for that digest algorithm.
431 OSStatus
CMSEncoderSetAppleCodesigningHashAgilityV2(
432 CMSEncoderRef cmsEncoder
,
433 CFDictionaryRef hashAgilityV2AttrValues
);
436 * Set the expiration time for a CMSEncoder.
437 * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
439 OSStatus
CMSEncoderSetAppleExpirationTime(
440 CMSEncoderRef cmsEncoder
,
441 CFAbsoluteTime time
);
444 CF_ASSUME_NONNULL_END
448 #endif /* _CMS_ENCODER_H_ */