2 * Copyright (c) 2006-2018 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 <AvailabilityMacros.h>
47 #include <Security/SecBase.h>
50 #include <Security/cssmtype.h>
55 CF_ASSUME_NONNULL_BEGIN
58 * Opaque reference to a CMS encoder object.
59 * This is a CF object, with standard CF semantics; dispose of it
62 typedef struct CF_BRIDGED_TYPE(id
) _CMSEncoder
*CMSEncoderRef
;
64 CFTypeID
CMSEncoderGetTypeID(void)
65 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
68 * Create a CMSEncoder. Result must eventually be freed via CFRelease().
70 OSStatus
CMSEncoderCreate(CMSEncoderRef
* __nonnull CF_RETURNS_RETAINED cmsEncoderOut
) /* RETURNED */
71 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
73 extern const CFStringRef kCMSEncoderDigestAlgorithmSHA1
;
74 extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256
;
76 OSStatus
CMSEncoderSetSignerAlgorithm(
77 CMSEncoderRef cmsEncoder
,
78 CFStringRef digestAlgorithm
)
79 __API_AVAILABLE(macos(10.11)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
82 * Specify signers of the CMS message; implies that the message will be signed.
84 * -- Caller can pass in one signer, as a SecIdentityRef, or an array of
85 * signers, as a CFArray of SecIdentityRefs.
86 * -- Can be called multiple times.
87 * -- If the message is not to be signed, don't call this.
88 * -- If this is called, it must be called before the first call to
89 * CMSEncoderUpdateContent().
91 OSStatus
CMSEncoderAddSigners(
92 CMSEncoderRef cmsEncoder
,
93 CFTypeRef signerOrArray
)
94 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
97 * Obtain an array of signers as specified in CMSEncoderSetSigners().
98 * Returns a NULL signers array if CMSEncoderSetSigners() has not been called.
99 * Caller must CFRelease the result.
101 OSStatus
CMSEncoderCopySigners(
102 CMSEncoderRef cmsEncoder
,
103 CFArrayRef
* __nonnull CF_RETURNS_RETAINED signersOut
) /* RETURNED */
104 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
107 * Specify recipients of the message. Implies that the message will
110 * -- Caller can pass in one recipient, as a SecCertificateRef, or an
111 * array of recipients, as a CFArray of SecCertificateRefs.
112 * -- Can be called multiple times.
113 * -- If the message is not to be encrypted, don't call this.
114 * -- If this is called, it must be called before the first call to
115 * CMSEncoderUpdateContent().
117 OSStatus
CMSEncoderAddRecipients(
118 CMSEncoderRef cmsEncoder
,
119 CFTypeRef recipientOrArray
)
120 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
123 * Obtain an array of recipients as specified in CMSEncoderSetRecipients().
124 * Returns a NULL recipients array if CMSEncoderSetRecipients() has not been
126 * Caller must CFRelease the result.
128 OSStatus
CMSEncoderCopyRecipients(
129 CMSEncoderRef cmsEncoder
,
130 CFArrayRef
* __nonnull CF_RETURNS_RETAINED recipientsOut
) /* RETURNED */
131 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
134 * A signed message optionally includes the data to be signed. If the message
135 * is *not* to include the data to be signed, call this function with a value
136 * of TRUE for detachedContent. The default, if this function is not called,
137 * is detachedContent=FALSE, i.e., the message contains the data to be signed.
139 * -- Encrypted messages can not use detached content. (This restriction
140 * also applies to messages that are both signed and encrypted.)
141 * -- If this is called, it must be called before the first call to
142 * CMSEncoderUpdateContent().
144 OSStatus
CMSEncoderSetHasDetachedContent(
145 CMSEncoderRef cmsEncoder
,
146 Boolean detachedContent
)
147 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
150 * Obtain a Boolean indicating whether the current message will have detached
152 * Returns the value specified in CMSEncoderHasDetachedContent() if that
153 * function has been called; else returns the default FALSE.
155 OSStatus
CMSEncoderGetHasDetachedContent(
156 CMSEncoderRef cmsEncoder
,
157 Boolean
*detachedContentOut
) /* RETURNED */
158 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
162 * Optionally specify an eContentType OID for the inner EncapsulatedData for
163 * a signed message. The default eContentType, used if this function is not
164 * called, is id-data (which is the normal eContentType for applications such
167 * If this is called, it must be called before the first call to
168 * CMSEncoderUpdateContent().
170 * NOTE: This function is deprecated in Mac OS X 10.7 and later;
171 * please use CMSEncoderSetEncapsulatedContentTypeOID() instead.
173 OSStatus
CMSEncoderSetEncapsulatedContentType(
174 CMSEncoderRef cmsEncoder
,
175 const CSSM_OID
*eContentType
)
176 API_DEPRECATED_WITH_REPLACEMENT("CMSEncoderSetEncapsulatedContentTypeOID", macos(10.5, 10.7)) API_UNAVAILABLE(ios
, watchos
, tvos
, bridgeos
, macCatalyst
);
180 * Optionally specify an eContentType OID for the inner EncapsulatedData for
181 * a signed message. The default eContentTypeOID, used if this function is not
182 * called, is id-data (which is the normal eContentType for applications such
185 * The eContentTypeOID parameter may be specified as a CF string, e.g.:
186 * CFSTR("1.2.840.113549.1.7.1")
188 * If this is called, it must be called before the first call to
189 * CMSEncoderUpdateContent().
191 OSStatus
CMSEncoderSetEncapsulatedContentTypeOID(
192 CMSEncoderRef cmsEncoder
,
193 CFTypeRef eContentTypeOID
)
194 __API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
197 * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType().
198 * If CMSEncoderSetEncapsulatedContentType() has not been called this returns a
200 * The returned OID's data is in the same format as the data provided to
201 * CMSEncoderSetEncapsulatedContentType;, i.e., it's the encoded content of
202 * the OID, not including the tag and length bytes.
204 OSStatus
CMSEncoderCopyEncapsulatedContentType(
205 CMSEncoderRef cmsEncoder
,
206 CFDataRef
* __nonnull CF_RETURNS_RETAINED eContentTypeOut
) /* RETURNED */
207 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
210 * Signed CMS messages can contain arbitrary sets of certificates beyond those
211 * indicating the identity of the signer(s). This function provides a means of
212 * adding these other certs. For normal signed messages it is not necessary to
213 * call this; the signer cert(s) and the intermediate certs needed to verify the
214 * signer(s) will be included in the message implicitly.
216 * -- Caller can pass in one cert, as a SecCertificateRef, or an array of certs,
217 * as a CFArray of SecCertificateRefs.
218 * -- If this is called, it must be called before the first call to
219 * CMSEncoderUpdateContent().
220 * -- There is a "special case" use of CMS messages which involves neither
221 * signing nor encryption, but does include certificates. This is commonly
222 * used to transport "bags" of certificates. When constructing such a
223 * message, all an application needs to do is to create a CMSEncoderRef,
224 * call CMSEncoderAddSupportingCerts() one or more times, and then call
225 * CMSEncoderCopyEncodedContent() to get the resulting cert bag. No 'content'
226 * need be specified. (This is in fact the primary intended use for
229 OSStatus
CMSEncoderAddSupportingCerts(
230 CMSEncoderRef cmsEncoder
,
231 CFTypeRef certOrArray
)
232 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
235 * Obtain the SecCertificates provided in CMSEncoderAddSupportingCerts().
236 * If CMSEncoderAddSupportingCerts() has not been called this will return a
237 * NULL value for *certs.
238 * Caller must CFRelease the result.
240 OSStatus
CMSEncoderCopySupportingCerts(
241 CMSEncoderRef cmsEncoder
,
242 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certsOut
) /* RETURNED */
243 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
246 * Standard signed attributes, optionally specified in
247 * CMSEncoderAddSignedAttributes().
249 typedef CF_OPTIONS(uint32_t, CMSSignedAttributes
) {
250 kCMSAttrNone
= 0x0000,
252 * S/MIME Capabilities - identifies supported signature, encryption, and
255 kCMSAttrSmimeCapabilities
= 0x0001,
257 * Indicates that a cert is the preferred cert for S/MIME encryption.
259 kCMSAttrSmimeEncryptionKeyPrefs
= 0x0002,
261 * Same as kCMSSmimeEncryptionKeyPrefs, using an attribute OID preferred
264 kCMSAttrSmimeMSEncryptionKeyPrefs
= 0x0004,
266 * Include the signing time.
268 kCMSAttrSigningTime
= 0x0008,
270 * Include the Apple Codesigning Hash Agility.
272 kCMSAttrAppleCodesigningHashAgility
= 0x0010,
273 kCMSAttrAppleCodesigningHashAgilityV2
= 0x0020,
275 * Include the expiration time.
277 kCMSAttrAppleExpirationTime
= 0x0040,
281 * Optionally specify signed attributes. Only meaningful when creating a
282 * signed message. If this is called, it must be called before
283 * CMSEncoderUpdateContent().
285 OSStatus
CMSEncoderAddSignedAttributes(
286 CMSEncoderRef cmsEncoder
,
287 CMSSignedAttributes signedAttributes
)
288 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
291 * Specification of what certificates to include in a signed message.
293 typedef CF_ENUM(uint32_t, CMSCertificateChainMode
) {
294 kCMSCertificateNone
= 0, /* don't include any certificates */
295 kCMSCertificateSignerOnly
, /* only include signer certificate(s) */
296 kCMSCertificateChain
, /* signer certificate chain up to but not
297 * including root certiticate */
298 kCMSCertificateChainWithRoot
, /* signer certificate chain including root */
299 kCMSCertificateChainWithRootOrFail
, /* signer certificate chain including root
300 * and if chain not terminated by a self-signed cert,
301 * fail to create CMS */
305 * Optionally specify which certificates, if any, to include in a
306 * signed CMS message. The default, if this is not called, is
307 * kCMSCertificateChain, in which case the signer cert plus all CA
308 * certs needed to verify the signer cert, except for the root
309 * cert, are included.
310 * If this is called, it must be called before
311 * CMSEncoderUpdateContent().
313 OSStatus
CMSEncoderSetCertificateChainMode(
314 CMSEncoderRef cmsEncoder
,
315 CMSCertificateChainMode chainMode
)
316 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
319 * Obtain indication of which signer certs are to be included
320 * in a signed CMS message.
322 OSStatus
CMSEncoderGetCertificateChainMode(
323 CMSEncoderRef cmsEncoder
,
324 CMSCertificateChainMode
*chainModeOut
)
325 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
328 * Feed content bytes into the encoder.
329 * Can be called multiple times.
330 * No 'setter' routines can be called after this function has been called.
332 OSStatus
CMSEncoderUpdateContent(
333 CMSEncoderRef cmsEncoder
,
336 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
339 * Finish encoding the message and obtain the encoded result.
340 * Caller must CFRelease the result.
342 OSStatus
CMSEncoderCopyEncodedContent(
343 CMSEncoderRef cmsEncoder
,
344 CFDataRef
* __nonnull CF_RETURNS_RETAINED encodedContentOut
) /* RETURNED */
345 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
349 * High-level, one-shot encoder function.
351 * Inputs (all except for content optional, though at least one
352 * of {signers, recipients} must be non-NULL)
353 * ------------------------------------------------------------
354 * signers : signer identities. Either a SecIdentityRef, or a
356 * recipients : recipient certificates. Either a SecCertificateRef,
357 * or a CFArray of them.
358 * eContentType : contentType for inner EncapsulatedData.
359 * detachedContent : when true, do not include the signed data in the message.
360 * signedAttributes : Specifies which standard signed attributes are to be
361 * included in the message.
362 * content : raw content to be signed and/or encrypted.
366 * encodedContent : the result of the encoding.
368 * NOTE: This function is deprecated in Mac OS X 10.7 and later;
369 * please use CMSEncodeContent() instead.
372 CFTypeRef __nullable signers
,
373 CFTypeRef __nullable recipients
,
374 const CSSM_OID
* __nullable eContentType
,
375 Boolean detachedContent
,
376 CMSSignedAttributes signedAttributes
,
377 const void * content
,
379 CFDataRef
* __nonnull CF_RETURNS_RETAINED encodedContentOut
) /* RETURNED */
380 API_DEPRECATED_WITH_REPLACEMENT("CMSEncodeContent", macos(10.5, 10.7)) API_UNAVAILABLE(ios
, watchos
, tvos
, bridgeos
, macCatalyst
);
381 #endif // TARGET_OS_OSX
384 * High-level, one-shot encoder function.
386 * Inputs (all except for content optional, though at least one
387 * of {signers, recipients} must be non-NULL)
388 * ------------------------------------------------------------
389 * signers : signer identities. Either a SecIdentityRef, or a
391 * recipients : recipient certificates. Either a SecCertificateRef,
392 * or a CFArray of them.
393 * eContentTypeOID : contentType OID for inner EncapsulatedData, e.g.:
394 * CFSTR("1.2.840.113549.1.7.1")
395 * detachedContent : when true, do not include the signed data in the message.
396 * signedAttributes : Specifies which standard signed attributes are to be
397 * included in the message.
398 * content : raw content to be signed and/or encrypted.
402 * encodedContent : the result of the encoding.
404 OSStatus
CMSEncodeContent(
405 CFTypeRef __nullable signers
,
406 CFTypeRef __nullable recipients
,
407 CFTypeRef __nullable eContentTypeOID
,
408 Boolean detachedContent
,
409 CMSSignedAttributes signedAttributes
,
412 CFDataRef
* __nullable CF_RETURNS_RETAINED encodedContentOut
) /* RETURNED */
413 __API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
415 OSStatus
CMSEncoderCopySignerTimestamp(
416 CMSEncoderRef cmsEncoder
,
417 size_t signerIndex
, /* usually 0 */
418 CFAbsoluteTime
*timestamp
) /* RETURNED */
419 API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios
, watchos
, tvos
, bridgeos
, macCatalyst
);
421 OSStatus
CMSEncoderCopySignerTimestampWithPolicy(
422 CMSEncoderRef cmsEncoder
,
423 CFTypeRef __nullable timeStampPolicy
,
424 size_t signerIndex
, /* usually 0 */
425 CFAbsoluteTime
*timestamp
) /* RETURNED */
426 API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios
, watchos
, tvos
, bridgeos
, macCatalyst
);
428 CF_ASSUME_NONNULL_END
432 #endif /* _CMS_ENCODER_H_ */