2  * Copyright (c) 2006-2013 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  * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the  
  26  *                                Cryptographic Message Syntax (CMS), per RFC 3852. 
  28  * See CMSEncoder.h for general information about CMS messages.  
  31 #ifndef _CMS_DECODER_H_ 
  32 #define _CMS_DECODER_H_ 
  34 #include <CoreFoundation/CoreFoundation.h> 
  35 #include <Security/SecCertificate.h> 
  36 #include <Security/SecTrust.h> 
  43 CF_ASSUME_NONNULL_BEGIN
 
  46  * Opaque reference to a CMS decoder object.  
  47  * This is a CF object, with standard CF semantics; dispose of it 
  50 typedef struct CF_BRIDGED_TYPE(id
) _CMSDecoder 
*CMSDecoderRef
; 
  52 CFTypeID 
CMSDecoderGetTypeID(void); 
  55  * Status of signature and signer information in a signed message. 
  57 typedef CF_ENUM(uint32_t, CMSSignerStatus
) { 
  58         kCMSSignerUnsigned 
= 0,                         /* message was not signed */ 
  59         kCMSSignerValid
,                                        /* message was signed and signature verify OK */ 
  60         kCMSSignerNeedsDetachedContent
,         /* message was signed but needs detached content  
  62         kCMSSignerInvalidSignature
,                     /* message was signed but had a signature error */ 
  63         kCMSSignerInvalidCert
,                          /* message was signed but an error occurred in verifying 
  64                                                                                  *   the signer's certificate */ 
  65         kCMSSignerInvalidIndex                          
/* specified signer index out of range */ 
  69  * Create a CMSDecoder. Result must eventually be freed via CFRelease(). 
  71 OSStatus 
CMSDecoderCreate( 
  72         CMSDecoderRef 
* __nonnull CF_RETURNS_RETAINED cmsDecoderOut
)    /* RETURNED */ 
  73     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
  76  * Feed raw bytes of the message to be decoded into the decoder. Can be called 
  78  * Returns errSecUnknownFormat upon detection of improperly formatted CMS 
  81 OSStatus 
CMSDecoderUpdateMessage( 
  82         CMSDecoderRef           cmsDecoder
, 
  85     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
  88  * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; 
  89  * finish decoding the message.  
  90  * Returns errSecUnknownFormat upon detection of improperly formatted CMS 
  93 OSStatus 
CMSDecoderFinalizeMessage( 
  94         CMSDecoderRef           cmsDecoder
) 
  95     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
  98  * A signed CMS message optionally includes the data which was signed. If the 
  99  * message does not include the signed data, caller specifies the signed data 
 100  * (the "detached content") here.  
 102  * This can be called either before or after the actual decoding of the message 
 103  * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only 
 104  * restriction is that, if detached content is required, this function must  
 105  * be called befoere successfully ascertaining the signature status via  
 106  * CMSDecoderCopySignerStatus(). 
 108 OSStatus 
CMSDecoderSetDetachedContent( 
 109         CMSDecoderRef           cmsDecoder
, 
 110         CFDataRef                       detachedContent
) 
 111     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 114  * Obtain the detached content specified in CMSDecoderSetDetachedContent(). 
 115  * Returns a NULL detachedContent if no detached content has been specified.  
 116  * Caller must CFRelease() the result. 
 118 OSStatus 
CMSDecoderCopyDetachedContent( 
 119         CMSDecoderRef           cmsDecoder
, 
 120         CFDataRef 
* __nonnull CF_RETURNS_RETAINED detachedContentOut
)   /* RETURNED */ 
 121     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 124  * Optionally specify a SecKeychainRef, or an array of them, containing 
 125  * intermediate certs to be used in verifying a signed message's signer 
 126  * certs. By default, the default keychain search list is used for this.  
 127  * Specify an empty CFArrayRef to search *no* keychains for intermediate 
 129  * If this is called, it must be called before CMSDecoderCopySignerStatus(). 
 131 OSStatus 
CMSDecoderSetSearchKeychain( 
 132         CMSDecoderRef           cmsDecoder
, 
 133         CFTypeRef                       keychainOrArray
) 
 134     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 137  * Obtain the number of signers of a message. A result of zero indicates that 
 138  * the message was not signed.  
 139  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 141 OSStatus 
CMSDecoderGetNumSigners( 
 142         CMSDecoderRef           cmsDecoder
, 
 143         size_t                          *numSignersOut
) /* RETURNED */ 
 144     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 147  * Obtain the status of a CMS message's signature. A CMS message can  
 148  * be signed my multiple signers; this function returns the status 
 149  * associated with signer 'n' as indicated by the signerIndex parameter.  
 151  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 153  * Note that signature and certificate verification of a decoded message 
 154  * does *not* occur until this routine is called.  
 156  * All returned values are optional - pass NULL if you don't need a 
 157  * particular parameter.  
 159  * Note that errors like "bad signature" and "bad cert" do NOT cause this  
 160  * routine to return a nonzero error status itself; such errors are reported 
 161  * in the various out parameters, listed below.  
 165  * cmsDecoder       : a CMSDecoder which has successfully performed a  
 166  *                    CMSDecoderFinalizeMessage(). 
 167  * signerIndex      : indicates which of 'n' signers is being examined. 
 168  *                    Range is 0...(numSigners-1). 
 169  * policyOrArray    : Either a SecPolicyRef or a CFArray of them. 
 170  *                    These policies are used to verify the signer's certificate.  
 171  * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the  
 172  *                    evaluation of the signer cert to actually be evaluated 
 173  *                    via SecTrustEvaluate(). When FALSE, the caller performs  
 174  *                    the SecTrustEvaluate() operation on the SecTrust object  
 175  *                    returned via the secTrust out parameter.  
 176  *                    NOTE: it is hazardous and not recommended to pass in FALSE 
 177  *                    for the evaluateSecTrust parameter as well as NULL for the 
 178  *                    secTrust out parameter, since no evaluation of the signer 
 179  *                    cert can occur in that situation. 
 183  *      signerStatusOut                 -- An enum indicating the overall status. 
 184  *              kCMSSignerUnsigned         : message was not signed. 
 185  *              kCMSSignerValid            : both signature and signer certificate verified OK. 
 186  *              kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent() 
 187  *                                                               is required to ascertain the signature status. 
 188  *              kCMSSignerInvalidSignature : bad signature. 
 189  *              kCMSSignerInvalidCert      : an error occurred verifying the signer's certificate. 
 190  *                                                               Further information available via the secTrust and  
 191  *                                                               certVerifyResultCode parameters. This will never be  
 192  *                                                                   returned if evaluateSecTrust is FALSE.  
 193  *              kCMSSignerInvalidIndex     : specified signerIndex is larger than the number of  
 196  *      secTrustOut                             -- The SecTrust object used to verify the signer's  
 197  *                                                         certificate. Caller must CFRelease this.  
 198  *      certVerifyResultCodeOut -- The result of the certificate verification. If  
 199  *                                                         the evaluateSecTrust argument is set to FALSE on  
 200  *                                                         input, this out parameter is undefined on return. 
 202  * The certVerifyResultCode value can indicate a large number of errors; some of  
 203  * the most common and interesting errors are: 
 205  * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a  
 206  *              self-signed (root) cert which was present in the message, but  
 207  *              that root cert is not a known, trusted root cert.  
 208  * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to  
 210  * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does 
 212  * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested  
 214  * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert.  
 215  * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of 
 217  * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at  
 218  *              the time of     verification. 
 220 OSStatus 
CMSDecoderCopySignerStatus( 
 221         CMSDecoderRef               cmsDecoder
, 
 223         CFTypeRef                   policyOrArray
, 
 224         Boolean                     evaluateSecTrust
, 
 225         CMSSignerStatus 
* __nullable signerStatusOut
,               /* optional; RETURNED */ 
 226         SecTrustRef 
* __nullable CF_RETURNS_RETAINED secTrustOut
,   /* optional; RETURNED */ 
 227     OSStatus 
* __nullable certVerifyResultCodeOut
)              /* optional; RETURNED */ 
 228     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 231  * Obtain the email address of signer 'signerIndex' of a CMS message, if 
 234  * Returns errSecParam if the CMS message was not signed or if signerIndex 
 235  * is greater than the number of signers of the message minus one.  
 237  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 239 OSStatus 
CMSDecoderCopySignerEmailAddress( 
 240         CMSDecoderRef           cmsDecoder
, 
 242         CFStringRef     
* __nonnull CF_RETURNS_RETAINED signerEmailAddressOut
)  /* RETURNED */ 
 243     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 246  * Obtain the certificate of signer 'signerIndex' of a CMS message, if 
 249  * Returns errSecParam if the CMS message was not signed or if signerIndex 
 250  * is greater than the number of signers of the message minus one.  
 252  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 254 OSStatus 
CMSDecoderCopySignerCert( 
 255         CMSDecoderRef           cmsDecoder
, 
 257         SecCertificateRef 
* __nonnull CF_RETURNS_RETAINED signerCertOut
)    /* RETURNED */ 
 258     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 261  * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. 
 262  * Note that if the message was encrypted, and the decoding succeeded, (i.e., 
 263  * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully 
 265  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 267 OSStatus 
CMSDecoderIsContentEncrypted( 
 268         CMSDecoderRef           cmsDecoder
, 
 269         Boolean                         
*isEncryptedOut
) 
 270     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 273  * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if  
 274  * present. If the message was not signed this will return NULL. 
 275  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 276  * The returned OID's data is in the same format as a CSSM_OID; i.e., it's 
 277  * the encoded content of the OID, not including the tag and length bytes.  
 279 OSStatus 
CMSDecoderCopyEncapsulatedContentType( 
 280         CMSDecoderRef           cmsDecoder
, 
 281         CFDataRef 
* __nonnull CF_RETURNS_RETAINED eContentTypeOut
)  /* RETURNED */ 
 282     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 285  * Obtain an array of all of the certificates in a message. Elements of the  
 286  * returned array are SecCertificateRefs. The caller must CFRelease the returned  
 287  * array. If a message does not contain any certificates (which is the case for 
 288  * a message which is encrypted but not signed), the returned *certs value  
 289  * is NULL. The function will return errSecSuccess in this case. 
 290  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 292 OSStatus 
CMSDecoderCopyAllCerts( 
 293         CMSDecoderRef           cmsDecoder
, 
 294         CFArrayRef 
* __nonnull CF_RETURNS_RETAINED certsOut
)    /* RETURNED */ 
 295     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 298  * Obtain the actual message content (payload), if any. If the message was 
 299  * signed with detached content this will return NULL. 
 300  * Caller must CFRelease the result.  
 301  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 303 OSStatus 
CMSDecoderCopyContent( 
 304         CMSDecoderRef           cmsDecoder
, 
 305         CFDataRef 
* __nonnull CF_RETURNS_RETAINED contentOut
)   /* RETURNED */ 
 306     __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
); 
 309  * Obtain the signing time of signer 'signerIndex' of a CMS message, if 
 310  * present. This is an unauthenticate time, although it is part of the 
 311  * signed attributes of the message. 
 313  * Returns errSecParam if the CMS message was not signed or if signerIndex 
 314  * is greater than the number of signers of the message minus one.  
 316  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 318 OSStatus 
CMSDecoderCopySignerSigningTime( 
 319         CMSDecoderRef           cmsDecoder
, 
 321         CFAbsoluteTime      
*signingTime
)                       /* RETURNED */ 
 322     __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
); 
 325  * Obtain the timestamp of signer 'signerIndex' of a CMS message, if 
 326  * present. This timestamp is an authenticated timestamp provided by 
 327  * a timestamping authority. 
 329  * Returns errSecParam if the CMS message was not signed or if signerIndex 
 330  * is greater than the number of signers of the message minus one.  
 332  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 334 OSStatus 
CMSDecoderCopySignerTimestamp( 
 335         CMSDecoderRef           cmsDecoder
, 
 337         CFAbsoluteTime      
*timestamp
)                 /* RETURNED */ 
 338     __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
); 
 341      * Obtain the timestamp of signer 'signerIndex' of a CMS message, if 
 342      * present. This timestamp is an authenticated timestamp provided by 
 343      * a timestamping authority. Use the policy provided as a parameter 
 345      * Returns errSecParam if the CMS message was not signed or if signerIndex 
 346      * is greater than the number of signers of the message minus one. 
 348      * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
 350 OSStatus 
CMSDecoderCopySignerTimestampWithPolicy( 
 351                                                     CMSDecoderRef               cmsDecoder
, 
 352                                                     CFTypeRef __nullable timeStampPolicy
, 
 353                                                     size_t                              signerIndex
,        /* usually 0 */ 
 354                                                     CFAbsoluteTime      
*timestamp
)                     /* RETURNED */ 
 355     __OSX_AVAILABLE_STARTING(__MAC_10_10
, __IPHONE_NA
); 
 358  * Obtain an array of the certificates in a timestamp response. Elements of the  
 359  * returned array are SecCertificateRefs. The caller must CFRelease the returned 
 360  * array. This timestamp is an authenticated timestamp provided by 
 361  * a timestamping authority. 
 363  * Returns errSecParam if the CMS message was not signed or if signerIndex 
 364  * is greater than the number of signers of the message minus one. It returns 
 365  * errSecItemNotFound if no certificates were found. 
 367  * This cannot be called until after CMSDecoderFinalizeMessage() is called.  
 369 OSStatus 
CMSDecoderCopySignerTimestampCertificates( 
 370         CMSDecoderRef           cmsDecoder
, 
 371         size_t                          signerIndex
,                            /* usually 0 */ 
 372         CFArrayRef 
* __nonnull CF_RETURNS_RETAINED certificateRefs
) /* RETURNED */ 
 373     __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
); 
 375 CF_ASSUME_NONNULL_END
 
 381 #endif  /* _CMS_DECODER_H_ */