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_ */