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