/ CMS / CMSEncoder.h
CMSEncoder.h
  1  /*
  2   * Copyright (c) 2006-2018 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 <AvailabilityMacros.h>
 46  #include <stdint.h>
 47  #include <Security/SecBase.h>
 48  
 49  #if SEC_OS_OSX
 50  #include <Security/cssmtype.h>
 51  #endif
 52  
 53  __BEGIN_DECLS
 54  
 55  CF_ASSUME_NONNULL_BEGIN
 56  
 57  /*
 58   * Opaque reference to a CMS encoder object.
 59   * This is a CF object, with standard CF semantics; dispose of it
 60   * with CFRelease().
 61   */
 62  typedef struct CF_BRIDGED_TYPE(id) _CMSEncoder *CMSEncoderRef;
 63  
 64  CFTypeID CMSEncoderGetTypeID(void)
 65      __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
 66  
 67  /*
 68   * Create a CMSEncoder. Result must eventually be freed via CFRelease().
 69   */
 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));
 72  
 73  extern const CFStringRef kCMSEncoderDigestAlgorithmSHA1;
 74  extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256;
 75  
 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));
 80  
 81  /*
 82   * Specify signers of the CMS message; implies that the message will be signed.
 83   *
 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().
 90   */
 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));
 95  
 96  /*
 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.
100   */
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));
105  
106  /*
107   * Specify recipients of the message. Implies that the message will
108   * be encrypted.
109   *
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().
116   */
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));
121  
122  /*
123   * Obtain an array of recipients as specified in CMSEncoderSetRecipients().
124   * Returns a NULL recipients array if CMSEncoderSetRecipients() has not been
125   * called.
126   * Caller must CFRelease the result.
127   */
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));
132  
133  /*
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.
138   *
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().
143   */
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));
148  
149  /*
150   * Obtain a Boolean indicating whether the current message will have detached
151   * content.
152   * Returns the value specified in CMSEncoderHasDetachedContent() if that
153   * function has been called; else returns the default FALSE.
154   */
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));
159  
160  #if SEC_OS_OSX
161  /*
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
165   * as SMIME).
166   *
167   * If this is called, it must be called before the first call to
168   * CMSEncoderUpdateContent().
169   *
170   * NOTE: This function is deprecated in Mac OS X 10.7 and later;
171   * please use CMSEncoderSetEncapsulatedContentTypeOID() instead.
172   */
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);
177  #endif // SEC_OS_OSX
178  
179  /*
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
183   * as SMIME).
184   *
185   * The eContentTypeOID parameter may be specified as a CF string, e.g.:
186   * CFSTR("1.2.840.113549.1.7.1")
187   *
188   * If this is called, it must be called before the first call to
189   * CMSEncoderUpdateContent().
190   */
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));
195  
196  /*
197   * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType().
198   * If CMSEncoderSetEncapsulatedContentType() has not been called this returns a
199   * NULL pointer.
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.
203   */
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));
208  
209  /*
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.
215   *
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
227   *    this function.)
228   */
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));
233  
234  /*
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.
239   */
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));
244  
245  /*
246   * Standard signed attributes, optionally specified in
247   * CMSEncoderAddSignedAttributes().
248   */
249  typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) {
250      kCMSAttrNone						= 0x0000,
251      /*
252       * S/MIME Capabilities - identifies supported signature, encryption, and
253       * digest algorithms.
254       */
255      kCMSAttrSmimeCapabilities			= 0x0001,
256      /*
257       * Indicates that a cert is the preferred cert for S/MIME encryption.
258       */
259      kCMSAttrSmimeEncryptionKeyPrefs		= 0x0002,
260      /*
261       * Same as kCMSSmimeEncryptionKeyPrefs, using an attribute OID preferred
262       * by Microsoft.
263       */
264      kCMSAttrSmimeMSEncryptionKeyPrefs	= 0x0004,
265      /*
266       * Include the signing time.
267       */
268      kCMSAttrSigningTime					= 0x0008,
269      /*
270       * Include the Apple Codesigning Hash Agility.
271       */
272      kCMSAttrAppleCodesigningHashAgility = 0x0010,
273      kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020,
274      /*
275       * Include the expiration time.
276       */
277      kCMSAttrAppleExpirationTime         = 0x0040,
278  };
279  
280  /*
281   * Optionally specify signed attributes. Only meaningful when creating a
282   * signed message. If this is called, it must be called before
283   * CMSEncoderUpdateContent().
284   */
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));
289  
290  /*
291   * Specification of what certificates to include in a signed message.
292   */
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 */
302  };
303  
304  /*
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().
312   */
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));
317  
318  /*
319   * Obtain indication of which signer certs are to be included
320   * in a signed CMS message.
321   */
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));
326  
327  /*
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.
331   */
332  OSStatus CMSEncoderUpdateContent(
333      CMSEncoderRef		cmsEncoder,
334      const void			*content,
335      size_t				contentLen)
336      __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0));
337  
338  /*
339   * Finish encoding the message and obtain the encoded result.
340   * Caller must CFRelease the result.
341   */
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));
346  
347  #if TARGET_OS_OSX
348  /*
349   * High-level, one-shot encoder function.
350   *
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
355   *                    CFArray of them.
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.
363   *
364   * Output
365   * ------
366   * encodedContent   : the result of the encoding.
367   *
368   * NOTE: This function is deprecated in Mac OS X 10.7 and later;
369   * please use CMSEncodeContent() instead.
370   */
371  OSStatus CMSEncode(
372      CFTypeRef __nullable        signers,
373      CFTypeRef __nullable        recipients,
374      const CSSM_OID * __nullable eContentType,
375      Boolean                     detachedContent,
376      CMSSignedAttributes         signedAttributes,
377      const void *                content,
378      size_t                      contentLen,
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
382  
383  /*
384   * High-level, one-shot encoder function.
385   *
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
390   *                    CFArray of them.
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.
399   *
400   * Output
401   * ------
402   * encodedContent   : the result of the encoding.
403   */
404  OSStatus CMSEncodeContent(
405      CFTypeRef __nullable    signers,
406      CFTypeRef __nullable    recipients,
407      CFTypeRef __nullable    eContentTypeOID,
408      Boolean                 detachedContent,
409      CMSSignedAttributes     signedAttributes,
410      const void              *content,
411      size_t                  contentLen,
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));
414  
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);
420  
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);
427  
428  CF_ASSUME_NONNULL_END
429  
430  __END_DECLS
431  
432  #endif	/* _CMS_ENCODER_H_ */
433