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